X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fstring.c;h=78bd65c41369cd5b0050b75013bc97bbc7b5bda5;hb=00a4280d776cd5b26bcdb3a9e0b600b5df0be4cd;hp=af17c16f616db4b8afc71cb55b31ad394457636b;hpb=430c166bcedd22e0ce93ce298747275f814b172f;p=platform%2Fkernel%2Fu-boot.git diff --git a/lib/string.c b/lib/string.c index af17c16..78bd65c 100644 --- a/lib/string.c +++ b/lib/string.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -114,17 +115,21 @@ char * strncpy(char * dest,const char *src,size_t count) * NUL-terminated string that fits in the buffer (unless, * of course, the buffer size is zero). It does not pad * out the result like strncpy() does. + * + * Return: the number of bytes copied */ size_t strlcpy(char *dest, const char *src, size_t size) { - size_t ret = strlen(src); - if (size) { - size_t len = (ret >= size) ? size - 1 : ret; + size_t srclen = strlen(src); + size_t len = (srclen >= size) ? size - 1 : srclen; + memcpy(dest, src, len); dest[len] = '\0'; + return len + 1; } - return ret; + + return 0; } #endif @@ -176,6 +181,25 @@ char * strncat(char *dest, const char *src, size_t count) } #endif +#ifndef __HAVE_ARCH_STRLCAT +/** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @size: The size of @dest + * + * Compatible with *BSD: the result is always a valid NUL-terminated string that + * fits in the buffer (unless, of course, the buffer size is zero). It does not + * write past @size like strncat() does. + */ +size_t strlcat(char *dest, const char *src, size_t size) +{ + size_t len = strnlen(dest, size); + + return len + strlcpy(dest + len, src, size - len); +} +#endif + #ifndef __HAVE_ARCH_STRCMP /** * strcmp - Compare two strings @@ -324,6 +348,29 @@ char * strdup(const char *s) strcpy (new, s); return new; } + +char * strndup(const char *s, size_t n) +{ + size_t len; + char *new; + + if (s == NULL) + return NULL; + + len = strlen(s); + + if (n < len) + len = n; + + new = malloc(len + 1); + if (new == NULL) + return NULL; + + strncpy(new, s, len); + new[len] = '\0'; + + return new; +} #endif #ifndef __HAVE_ARCH_STRSPN @@ -467,7 +514,7 @@ char *strswab(const char *s) * * Do not use memset() to access IO space, use memset_io() instead. */ -void * memset(void * s,int c,size_t count) +__used void * memset(void * s,int c,size_t count) { unsigned long *sl = (unsigned long *) s; char *s8; @@ -506,7 +553,7 @@ void * memset(void * s,int c,size_t count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void *dest, const void *src, size_t count) +__used void * memcpy(void *dest, const void *src, size_t count) { unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; char *d8, *s8; @@ -540,11 +587,23 @@ void * memcpy(void *dest, const void *src, size_t count) * * Unlike memcpy(), memmove() copes with overlapping areas. */ -void * memmove(void * dest,const void *src,size_t count) +__used void * memmove(void * dest,const void *src,size_t count) { char *tmp, *s; - if (dest <= src) { + if (dest <= src || (src + count) <= dest) { + /* + * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible: + * - when dest is before src (assuming that memcpy is doing forward-copying) + * - when destination don't overlap the source buffer (src + count <= dest) + * + * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined, + * __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific + * implementation is not doing a forward-copying. + * + * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32 + * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE. + */ memcpy(dest, src, count); } else { tmp = (char *) dest + count; @@ -564,7 +623,7 @@ void * memmove(void * dest,const void *src,size_t count) * @ct: Another area of memory * @count: The size of the area. */ -int memcmp(const void * cs,const void * ct,size_t count) +__used int memcmp(const void * cs,const void * ct,size_t count) { const unsigned char *su1, *su2; int res = 0; @@ -600,6 +659,19 @@ void * memscan(void * addr, int c, size_t size) } #endif +char *memdup(const void *src, size_t len) +{ + char *p; + + p = malloc(len); + if (!p) + return NULL; + + memcpy(p, src, len); + + return p; +} + #ifndef __HAVE_ARCH_STRSTR /** * strstr - Find the first substring in a %NUL terminated string