/*
 * string.c - User level <string> library implementation.
 * 
 * Author     Alain Greiner (2016,2017,2018)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <string.h>
#include <stdio.h>

///////////////////////////////////////
unsigned int strlen( const char * str )
{
	register const char * ptr = str;

	while (* ptr) ptr++;

	return (ptr - str);
}

///////////////////////////////////////
unsigned int strnlen( const char * str,
                      unsigned int     maxlen )
{
	register const char *ptr = str;

	while (*ptr && (maxlen-- > 0)) ptr++;

	return (ptr - str);
}

////////////////////////////
int strcmp( const char * s1,
            const char * s2 )
{

	while (*s1 && *s1 == *s2)
	{
		s1 ++;
		s2 ++;
	}

	return (*s1 - *s2);
}

//////////////////////////////
int strncmp( const char   * s1,
             const char   * s2,
             unsigned int   n )
{ 
	if (n == 0)
		return s1 - s2;    // pseudo random result...

	while (*s1 && (*s1 == *s2) && (n > 1))
	{
		s1 ++;
		s2 ++;
		n--;
	}

	return (*s1 - *s2);
}



//////////////////////////
char * strcpy (char * dst,
               char * src )
{
	while( *src )
    {
        *(dst) = *(src);
        dst++;
        src++;
    }
        
    // set NUL terminating character
	*dst = 0;

	return dst;
}

///////////////////////////////////
char * strncpy( char         * dst,
                char         * src,
                unsigned int   count )
{
	unsigned int i;

    // copy at most count characters
	for (i = 0 ; (i < count) && (src[i] != '\0') ; i++) dst[i] = src[i];

    // complete with NUL characters
	for ( ; i < count ; i++) dst[i] = '\0';

	return dst;
}

//////////////////////////////
char * strstr( char       * s,
               const char * find )
{
    char     sc;
    char     c;
    unsigned int len;

    if ((c = *find++) != 0) 
    {
        len = strlen( find );
        do 
        {
            do 
            {
                if ((sc = *s++) == 0) return NULL;
            } 
            while (sc != c);
        } 
        while (strncmp(s, find, len) != 0);
        s--;
    }
    return s;
}

//////////////////////////////
char * strchr( const char * s,
               int          c )
{
	while(*s && *s != (char) c) s++;

	if(*s == (char) c) return (char*)s;

	return NULL;
}

///////////////////////////////
char * strrchr( const char * t,
                int          c )
{
	register char         ch;
	register const char * l = 0;

	ch = c;
	for (;;) 
    {
		if (*t == ch) l=t;
		if (!*t) return (char*)l;
		++t;
	}
	return (char*)l;
}

///////////////////////////////////////////////////////////////
void * memcpy(void *_dst, const void * _src, unsigned int size) 
{
    unsigned int * dst = _dst;
    const unsigned int * src = _src;
    if (!((unsigned int) dst & 3) && !((unsigned int) src & 3) )
    {
        while (size > 3) 
        {
            *dst++ = *src++;
            size -= 4;
        }
    }

    unsigned char *cdst = (unsigned char*)dst;
    unsigned char *csrc = (unsigned char*)src;

    while (size--) 
    {
        *cdst++ = *csrc++;
    }
    return _dst;
}

//////////////////////////////////////////////////////////
inline void * memset(void * dst, int s, unsigned int size) 
{
    char * a = (char *) dst;
    while (size--)
    {
        *a++ = (char)s;
    }
    return dst;
}


