240 lines
4.4 KiB
C
240 lines
4.4 KiB
C
|
/* Copyright (C) 2004 David Decotigny (with INSA Rennes for vsnprintf)
|
||
|
Copyright (C) 2003 The KOS Team
|
||
|
Copyright (C) 1999 Free Software Foundation
|
||
|
|
||
|
This program 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; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program 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 this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||
|
USA.
|
||
|
*/
|
||
|
#include "string.h"
|
||
|
#include "libc.h"
|
||
|
|
||
|
/* For an optimized version, see BSD sources ;) */
|
||
|
void *memcpy(void *dst0, const void *src0, register unsigned int size)
|
||
|
{
|
||
|
char *dst;
|
||
|
const char *src;
|
||
|
for (dst = (char*)dst0, src = (const char*)src0 ;
|
||
|
size > 0 ;
|
||
|
dst++, src++, size--)
|
||
|
*dst = *src;
|
||
|
return dst0;
|
||
|
}
|
||
|
|
||
|
/* ditto */
|
||
|
void *memset(void *dst0, register int c, register unsigned int length)
|
||
|
{
|
||
|
char *dst;
|
||
|
for (dst = (char*) dst0 ;
|
||
|
length > 0 ;
|
||
|
dst++, length --)
|
||
|
*dst = (char)c;
|
||
|
return dst0;
|
||
|
}
|
||
|
|
||
|
int memcmp(const void *s1, const void *s2, size_t len)
|
||
|
{
|
||
|
const unsigned char *c1, *c2;
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i = 0, c1 = s1, c2 = s2; i < len; i++, c1++, c2++)
|
||
|
{
|
||
|
if(*c1 != *c2)
|
||
|
return *c1 - *c2;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned int strlen(register const char *str)
|
||
|
{
|
||
|
unsigned int retval = 0;
|
||
|
|
||
|
while (*str++)
|
||
|
retval++;
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned int strnlen(const char * s, size_t count)
|
||
|
{
|
||
|
const char *sc;
|
||
|
|
||
|
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||
|
/* nothing */continue;
|
||
|
|
||
|
return sc - s;
|
||
|
}
|
||
|
|
||
|
|
||
|
char *strzcpy(register char *dst, register const char *src, register int len)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (len <= 0)
|
||
|
return dst;
|
||
|
|
||
|
for (i = 0; i < len; i++)
|
||
|
{
|
||
|
dst[i] = src[i];
|
||
|
if(src[i] == '\0')
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
dst[len-1] = '\0';
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
|
||
|
char *strzcat (char *dest, const char *src, size_t n)
|
||
|
{
|
||
|
char *res = dest;
|
||
|
|
||
|
for ( ; *dest ; dest++);
|
||
|
|
||
|
for ( ; *src ; src++, dest++) {
|
||
|
*dest = *src;
|
||
|
n--;
|
||
|
if (n <= 0)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
*dest = '\0';
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
|
||
|
char *strndup(const char *s, size_t n)
|
||
|
{
|
||
|
char * result;
|
||
|
n = strnlen(s, n);
|
||
|
result = malloc(n+1);
|
||
|
if (! result)
|
||
|
return NULL;
|
||
|
|
||
|
strzcpy(result, s, n+1);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
char *strdup(const char *s)
|
||
|
{
|
||
|
char * result;
|
||
|
size_t n = strlen(s);
|
||
|
|
||
|
result = malloc(n+1);
|
||
|
if (! result)
|
||
|
return NULL;
|
||
|
|
||
|
strzcpy(result, s, n+1);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
int strcmp(register const char *s1, register const char *s2)
|
||
|
{
|
||
|
while (*s1 == *s2++)
|
||
|
if (*s1++ == 0)
|
||
|
return (0);
|
||
|
|
||
|
return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
|
||
|
}
|
||
|
|
||
|
|
||
|
int strncmp(register const char *s1, register const char *s2, register int len)
|
||
|
{
|
||
|
char c1 = '\0', c2 = '\0';
|
||
|
|
||
|
while (len > 0)
|
||
|
{
|
||
|
c1 = (unsigned char) *s1++;
|
||
|
c2 = (unsigned char) *s2++;
|
||
|
if (c1 == '\0' || c1 != c2)
|
||
|
return c1 - c2;
|
||
|
len--;
|
||
|
}
|
||
|
|
||
|
return c1 - c2;
|
||
|
}
|
||
|
|
||
|
|
||
|
long long int strtoll(const char *nptr, char **endptr, int base)
|
||
|
{
|
||
|
long long int result;
|
||
|
|
||
|
#define RETURN(res) ({ if (endptr) *endptr = (char*)nptr; return res; })
|
||
|
|
||
|
if (base > 36)
|
||
|
{
|
||
|
RETURN(0);
|
||
|
}
|
||
|
|
||
|
/* Skip leading spaces */
|
||
|
for ( ; *nptr != '\0' && isspace(*nptr) ; nptr++)
|
||
|
continue;
|
||
|
|
||
|
if (nptr[0] == '0')
|
||
|
{
|
||
|
if (nptr[1] == 'x')
|
||
|
{
|
||
|
base = 16;
|
||
|
nptr += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base = 8;
|
||
|
nptr ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
result = 0;
|
||
|
for ( ; *nptr != '\0' ; nptr ++)
|
||
|
{
|
||
|
int digit;
|
||
|
if (*nptr >= '0' && *nptr <= '9')
|
||
|
digit = *nptr - '0';
|
||
|
else if (*nptr >= 'a' && *nptr <= 'z')
|
||
|
digit = 10 + *nptr - 'a';
|
||
|
else if (*nptr >= 'A' && *nptr <= 'Z')
|
||
|
digit = 10 + *nptr - 'A';
|
||
|
else
|
||
|
RETURN(result);
|
||
|
if (digit >= base)
|
||
|
{
|
||
|
RETURN(result);
|
||
|
}
|
||
|
result *= base;
|
||
|
result += digit;
|
||
|
}
|
||
|
|
||
|
RETURN(result);
|
||
|
}
|
||
|
|
||
|
long int strtol(const char *nptr, char **endptr, int base)
|
||
|
{
|
||
|
return strtoll(nptr, endptr, base);
|
||
|
}
|
||
|
|
||
|
long long atoll(const char *nptr)
|
||
|
{
|
||
|
return strtoll(nptr, NULL, 10);
|
||
|
}
|
||
|
|
||
|
long atol(const char *nptr)
|
||
|
{
|
||
|
return strtol(nptr, NULL, 10);
|
||
|
}
|