178acc472SPeter Tyser /* 278acc472SPeter Tyser * linux/lib/string.c 378acc472SPeter Tyser * 478acc472SPeter Tyser * Copyright (C) 1991, 1992 Linus Torvalds 578acc472SPeter Tyser */ 678acc472SPeter Tyser 778acc472SPeter Tyser /* 878acc472SPeter Tyser * stupid library routines.. The optimized versions should generally be found 978acc472SPeter Tyser * as inline code in <asm-xx/string.h> 1078acc472SPeter Tyser * 1178acc472SPeter Tyser * These are buggy as well.. 1278acc472SPeter Tyser * 1378acc472SPeter Tyser * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> 1478acc472SPeter Tyser * - Added strsep() which will replace strtok() soon (because strsep() is 1578acc472SPeter Tyser * reentrant and should be faster). Use only strsep() in new code, please. 1678acc472SPeter Tyser */ 1778acc472SPeter Tyser 1878acc472SPeter Tyser #include <linux/types.h> 1978acc472SPeter Tyser #include <linux/string.h> 2078acc472SPeter Tyser #include <linux/ctype.h> 2178acc472SPeter Tyser #include <malloc.h> 2278acc472SPeter Tyser 2378acc472SPeter Tyser 2478acc472SPeter Tyser /** 25b1f17bf5SSimon Glass * strncasecmp - Case insensitive, length-limited string comparison 2678acc472SPeter Tyser * @s1: One string 2778acc472SPeter Tyser * @s2: The other string 2878acc472SPeter Tyser * @len: the maximum number of characters to compare 2978acc472SPeter Tyser */ 30b1f17bf5SSimon Glass int strncasecmp(const char *s1, const char *s2, size_t len) 3178acc472SPeter Tyser { 3278acc472SPeter Tyser /* Yes, Virginia, it had better be unsigned */ 3378acc472SPeter Tyser unsigned char c1, c2; 3478acc472SPeter Tyser 3578acc472SPeter Tyser c1 = 0; c2 = 0; 3678acc472SPeter Tyser if (len) { 3778acc472SPeter Tyser do { 3878acc472SPeter Tyser c1 = *s1; c2 = *s2; 3978acc472SPeter Tyser s1++; s2++; 4078acc472SPeter Tyser if (!c1) 4178acc472SPeter Tyser break; 4278acc472SPeter Tyser if (!c2) 4378acc472SPeter Tyser break; 4478acc472SPeter Tyser if (c1 == c2) 4578acc472SPeter Tyser continue; 4678acc472SPeter Tyser c1 = tolower(c1); 4778acc472SPeter Tyser c2 = tolower(c2); 4878acc472SPeter Tyser if (c1 != c2) 4978acc472SPeter Tyser break; 5078acc472SPeter Tyser } while (--len); 5178acc472SPeter Tyser } 5278acc472SPeter Tyser return (int)c1 - (int)c2; 5378acc472SPeter Tyser } 54b1f17bf5SSimon Glass 55b1f17bf5SSimon Glass /** 56b1f17bf5SSimon Glass * strcasecmp - Case insensitive string comparison 57b1f17bf5SSimon Glass * @s1: One string 58b1f17bf5SSimon Glass * @s2: The other string 59b1f17bf5SSimon Glass */ 60b1f17bf5SSimon Glass int strcasecmp(const char *s1, const char *s2) 61b1f17bf5SSimon Glass { 62b1f17bf5SSimon Glass return strncasecmp(s1, s2, -1U); 63b1f17bf5SSimon Glass } 6478acc472SPeter Tyser 6578acc472SPeter Tyser char * ___strtok; 6678acc472SPeter Tyser 6778acc472SPeter Tyser #ifndef __HAVE_ARCH_STRCPY 6878acc472SPeter Tyser /** 6978acc472SPeter Tyser * strcpy - Copy a %NUL terminated string 7078acc472SPeter Tyser * @dest: Where to copy the string to 7178acc472SPeter Tyser * @src: Where to copy the string from 7278acc472SPeter Tyser */ 7378acc472SPeter Tyser char * strcpy(char * dest,const char *src) 7478acc472SPeter Tyser { 7578acc472SPeter Tyser char *tmp = dest; 7678acc472SPeter Tyser 7778acc472SPeter Tyser while ((*dest++ = *src++) != '\0') 7878acc472SPeter Tyser /* nothing */; 7978acc472SPeter Tyser return tmp; 8078acc472SPeter Tyser } 8178acc472SPeter Tyser #endif 8278acc472SPeter Tyser 8378acc472SPeter Tyser #ifndef __HAVE_ARCH_STRNCPY 8478acc472SPeter Tyser /** 8578acc472SPeter Tyser * strncpy - Copy a length-limited, %NUL-terminated string 8678acc472SPeter Tyser * @dest: Where to copy the string to 8778acc472SPeter Tyser * @src: Where to copy the string from 8878acc472SPeter Tyser * @count: The maximum number of bytes to copy 8978acc472SPeter Tyser * 9078acc472SPeter Tyser * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. 9178acc472SPeter Tyser * However, the result is not %NUL-terminated if the source exceeds 9278acc472SPeter Tyser * @count bytes. 9378acc472SPeter Tyser */ 9478acc472SPeter Tyser char * strncpy(char * dest,const char *src,size_t count) 9578acc472SPeter Tyser { 9678acc472SPeter Tyser char *tmp = dest; 9778acc472SPeter Tyser 9878acc472SPeter Tyser while (count-- && (*dest++ = *src++) != '\0') 9978acc472SPeter Tyser /* nothing */; 10078acc472SPeter Tyser 10178acc472SPeter Tyser return tmp; 10278acc472SPeter Tyser } 10378acc472SPeter Tyser #endif 10478acc472SPeter Tyser 10580d9ef8dSMasahiro Yamada #ifndef __HAVE_ARCH_STRLCPY 10680d9ef8dSMasahiro Yamada /** 10780d9ef8dSMasahiro Yamada * strlcpy - Copy a C-string into a sized buffer 10880d9ef8dSMasahiro Yamada * @dest: Where to copy the string to 10980d9ef8dSMasahiro Yamada * @src: Where to copy the string from 11080d9ef8dSMasahiro Yamada * @size: size of destination buffer 11180d9ef8dSMasahiro Yamada * 11280d9ef8dSMasahiro Yamada * Compatible with *BSD: the result is always a valid 11380d9ef8dSMasahiro Yamada * NUL-terminated string that fits in the buffer (unless, 11480d9ef8dSMasahiro Yamada * of course, the buffer size is zero). It does not pad 11580d9ef8dSMasahiro Yamada * out the result like strncpy() does. 11680d9ef8dSMasahiro Yamada */ 11780d9ef8dSMasahiro Yamada size_t strlcpy(char *dest, const char *src, size_t size) 11880d9ef8dSMasahiro Yamada { 11980d9ef8dSMasahiro Yamada size_t ret = strlen(src); 12080d9ef8dSMasahiro Yamada 12180d9ef8dSMasahiro Yamada if (size) { 12280d9ef8dSMasahiro Yamada size_t len = (ret >= size) ? size - 1 : ret; 12380d9ef8dSMasahiro Yamada memcpy(dest, src, len); 12480d9ef8dSMasahiro Yamada dest[len] = '\0'; 12580d9ef8dSMasahiro Yamada } 12680d9ef8dSMasahiro Yamada return ret; 12780d9ef8dSMasahiro Yamada } 12880d9ef8dSMasahiro Yamada #endif 12980d9ef8dSMasahiro Yamada 13078acc472SPeter Tyser #ifndef __HAVE_ARCH_STRCAT 13178acc472SPeter Tyser /** 13278acc472SPeter Tyser * strcat - Append one %NUL-terminated string to another 13378acc472SPeter Tyser * @dest: The string to be appended to 13478acc472SPeter Tyser * @src: The string to append to it 13578acc472SPeter Tyser */ 13678acc472SPeter Tyser char * strcat(char * dest, const char * src) 13778acc472SPeter Tyser { 13878acc472SPeter Tyser char *tmp = dest; 13978acc472SPeter Tyser 14078acc472SPeter Tyser while (*dest) 14178acc472SPeter Tyser dest++; 14278acc472SPeter Tyser while ((*dest++ = *src++) != '\0') 14378acc472SPeter Tyser ; 14478acc472SPeter Tyser 14578acc472SPeter Tyser return tmp; 14678acc472SPeter Tyser } 14778acc472SPeter Tyser #endif 14878acc472SPeter Tyser 14978acc472SPeter Tyser #ifndef __HAVE_ARCH_STRNCAT 15078acc472SPeter Tyser /** 15178acc472SPeter Tyser * strncat - Append a length-limited, %NUL-terminated string to another 15278acc472SPeter Tyser * @dest: The string to be appended to 15378acc472SPeter Tyser * @src: The string to append to it 15478acc472SPeter Tyser * @count: The maximum numbers of bytes to copy 15578acc472SPeter Tyser * 15678acc472SPeter Tyser * Note that in contrast to strncpy, strncat ensures the result is 15778acc472SPeter Tyser * terminated. 15878acc472SPeter Tyser */ 15978acc472SPeter Tyser char * strncat(char *dest, const char *src, size_t count) 16078acc472SPeter Tyser { 16178acc472SPeter Tyser char *tmp = dest; 16278acc472SPeter Tyser 16378acc472SPeter Tyser if (count) { 16478acc472SPeter Tyser while (*dest) 16578acc472SPeter Tyser dest++; 16678acc472SPeter Tyser while ((*dest++ = *src++)) { 16778acc472SPeter Tyser if (--count == 0) { 16878acc472SPeter Tyser *dest = '\0'; 16978acc472SPeter Tyser break; 17078acc472SPeter Tyser } 17178acc472SPeter Tyser } 17278acc472SPeter Tyser } 17378acc472SPeter Tyser 17478acc472SPeter Tyser return tmp; 17578acc472SPeter Tyser } 17678acc472SPeter Tyser #endif 17778acc472SPeter Tyser 17878acc472SPeter Tyser #ifndef __HAVE_ARCH_STRCMP 17978acc472SPeter Tyser /** 18078acc472SPeter Tyser * strcmp - Compare two strings 18178acc472SPeter Tyser * @cs: One string 18278acc472SPeter Tyser * @ct: Another string 18378acc472SPeter Tyser */ 18478acc472SPeter Tyser int strcmp(const char * cs,const char * ct) 18578acc472SPeter Tyser { 18678acc472SPeter Tyser register signed char __res; 18778acc472SPeter Tyser 18878acc472SPeter Tyser while (1) { 18978acc472SPeter Tyser if ((__res = *cs - *ct++) != 0 || !*cs++) 19078acc472SPeter Tyser break; 19178acc472SPeter Tyser } 19278acc472SPeter Tyser 19378acc472SPeter Tyser return __res; 19478acc472SPeter Tyser } 19578acc472SPeter Tyser #endif 19678acc472SPeter Tyser 19778acc472SPeter Tyser #ifndef __HAVE_ARCH_STRNCMP 19878acc472SPeter Tyser /** 19978acc472SPeter Tyser * strncmp - Compare two length-limited strings 20078acc472SPeter Tyser * @cs: One string 20178acc472SPeter Tyser * @ct: Another string 20278acc472SPeter Tyser * @count: The maximum number of bytes to compare 20378acc472SPeter Tyser */ 20478acc472SPeter Tyser int strncmp(const char * cs,const char * ct,size_t count) 20578acc472SPeter Tyser { 20678acc472SPeter Tyser register signed char __res = 0; 20778acc472SPeter Tyser 20878acc472SPeter Tyser while (count) { 20978acc472SPeter Tyser if ((__res = *cs - *ct++) != 0 || !*cs++) 21078acc472SPeter Tyser break; 21178acc472SPeter Tyser count--; 21278acc472SPeter Tyser } 21378acc472SPeter Tyser 21478acc472SPeter Tyser return __res; 21578acc472SPeter Tyser } 21678acc472SPeter Tyser #endif 21778acc472SPeter Tyser 21878acc472SPeter Tyser #ifndef __HAVE_ARCH_STRCHR 21978acc472SPeter Tyser /** 22078acc472SPeter Tyser * strchr - Find the first occurrence of a character in a string 22178acc472SPeter Tyser * @s: The string to be searched 22278acc472SPeter Tyser * @c: The character to search for 22378acc472SPeter Tyser */ 22478acc472SPeter Tyser char * strchr(const char * s, int c) 22578acc472SPeter Tyser { 22678acc472SPeter Tyser for(; *s != (char) c; ++s) 22778acc472SPeter Tyser if (*s == '\0') 22878acc472SPeter Tyser return NULL; 22978acc472SPeter Tyser return (char *) s; 23078acc472SPeter Tyser } 23178acc472SPeter Tyser #endif 23278acc472SPeter Tyser 2336b45ba45SSimon Glass const char *strchrnul(const char *s, int c) 2346b45ba45SSimon Glass { 2356b45ba45SSimon Glass for (; *s != (char)c; ++s) 2366b45ba45SSimon Glass if (*s == '\0') 2376b45ba45SSimon Glass break; 2386b45ba45SSimon Glass return s; 2396b45ba45SSimon Glass } 2406b45ba45SSimon Glass 24178acc472SPeter Tyser #ifndef __HAVE_ARCH_STRRCHR 24278acc472SPeter Tyser /** 24378acc472SPeter Tyser * strrchr - Find the last occurrence of a character in a string 24478acc472SPeter Tyser * @s: The string to be searched 24578acc472SPeter Tyser * @c: The character to search for 24678acc472SPeter Tyser */ 24778acc472SPeter Tyser char * strrchr(const char * s, int c) 24878acc472SPeter Tyser { 24978acc472SPeter Tyser const char *p = s + strlen(s); 25078acc472SPeter Tyser do { 25178acc472SPeter Tyser if (*p == (char)c) 25278acc472SPeter Tyser return (char *)p; 25378acc472SPeter Tyser } while (--p >= s); 25478acc472SPeter Tyser return NULL; 25578acc472SPeter Tyser } 25678acc472SPeter Tyser #endif 25778acc472SPeter Tyser 25878acc472SPeter Tyser #ifndef __HAVE_ARCH_STRLEN 25978acc472SPeter Tyser /** 26078acc472SPeter Tyser * strlen - Find the length of a string 26178acc472SPeter Tyser * @s: The string to be sized 26278acc472SPeter Tyser */ 26378acc472SPeter Tyser size_t strlen(const char * s) 26478acc472SPeter Tyser { 26578acc472SPeter Tyser const char *sc; 26678acc472SPeter Tyser 26778acc472SPeter Tyser for (sc = s; *sc != '\0'; ++sc) 26878acc472SPeter Tyser /* nothing */; 26978acc472SPeter Tyser return sc - s; 27078acc472SPeter Tyser } 27178acc472SPeter Tyser #endif 27278acc472SPeter Tyser 27378acc472SPeter Tyser #ifndef __HAVE_ARCH_STRNLEN 27478acc472SPeter Tyser /** 27578acc472SPeter Tyser * strnlen - Find the length of a length-limited string 27678acc472SPeter Tyser * @s: The string to be sized 27778acc472SPeter Tyser * @count: The maximum number of bytes to search 27878acc472SPeter Tyser */ 27978acc472SPeter Tyser size_t strnlen(const char * s, size_t count) 28078acc472SPeter Tyser { 28178acc472SPeter Tyser const char *sc; 28278acc472SPeter Tyser 28378acc472SPeter Tyser for (sc = s; count-- && *sc != '\0'; ++sc) 28478acc472SPeter Tyser /* nothing */; 28578acc472SPeter Tyser return sc - s; 28678acc472SPeter Tyser } 28778acc472SPeter Tyser #endif 28878acc472SPeter Tyser 289*a7d00210SSimon Glass #ifndef __HAVE_ARCH_STRCSPN 290*a7d00210SSimon Glass /** 291*a7d00210SSimon Glass * strcspn - Calculate the length of the initial substring of @s which does 292*a7d00210SSimon Glass * not contain letters in @reject 293*a7d00210SSimon Glass * @s: The string to be searched 294*a7d00210SSimon Glass * @reject: The string to avoid 295*a7d00210SSimon Glass */ 296*a7d00210SSimon Glass size_t strcspn(const char *s, const char *reject) 297*a7d00210SSimon Glass { 298*a7d00210SSimon Glass const char *p; 299*a7d00210SSimon Glass const char *r; 300*a7d00210SSimon Glass size_t count = 0; 301*a7d00210SSimon Glass 302*a7d00210SSimon Glass for (p = s; *p != '\0'; ++p) { 303*a7d00210SSimon Glass for (r = reject; *r != '\0'; ++r) { 304*a7d00210SSimon Glass if (*p == *r) 305*a7d00210SSimon Glass return count; 306*a7d00210SSimon Glass } 307*a7d00210SSimon Glass ++count; 308*a7d00210SSimon Glass } 309*a7d00210SSimon Glass return count; 310*a7d00210SSimon Glass } 311*a7d00210SSimon Glass #endif 312*a7d00210SSimon Glass 31378acc472SPeter Tyser #ifndef __HAVE_ARCH_STRDUP 31478acc472SPeter Tyser char * strdup(const char *s) 31578acc472SPeter Tyser { 31678acc472SPeter Tyser char *new; 31778acc472SPeter Tyser 31878acc472SPeter Tyser if ((s == NULL) || 31978acc472SPeter Tyser ((new = malloc (strlen(s) + 1)) == NULL) ) { 32078acc472SPeter Tyser return NULL; 32178acc472SPeter Tyser } 32278acc472SPeter Tyser 32378acc472SPeter Tyser strcpy (new, s); 32478acc472SPeter Tyser return new; 32578acc472SPeter Tyser } 32678acc472SPeter Tyser #endif 32778acc472SPeter Tyser 32878acc472SPeter Tyser #ifndef __HAVE_ARCH_STRSPN 32978acc472SPeter Tyser /** 33078acc472SPeter Tyser * strspn - Calculate the length of the initial substring of @s which only 33178acc472SPeter Tyser * contain letters in @accept 33278acc472SPeter Tyser * @s: The string to be searched 33378acc472SPeter Tyser * @accept: The string to search for 33478acc472SPeter Tyser */ 33578acc472SPeter Tyser size_t strspn(const char *s, const char *accept) 33678acc472SPeter Tyser { 33778acc472SPeter Tyser const char *p; 33878acc472SPeter Tyser const char *a; 33978acc472SPeter Tyser size_t count = 0; 34078acc472SPeter Tyser 34178acc472SPeter Tyser for (p = s; *p != '\0'; ++p) { 34278acc472SPeter Tyser for (a = accept; *a != '\0'; ++a) { 34378acc472SPeter Tyser if (*p == *a) 34478acc472SPeter Tyser break; 34578acc472SPeter Tyser } 34678acc472SPeter Tyser if (*a == '\0') 34778acc472SPeter Tyser return count; 34878acc472SPeter Tyser ++count; 34978acc472SPeter Tyser } 35078acc472SPeter Tyser 35178acc472SPeter Tyser return count; 35278acc472SPeter Tyser } 35378acc472SPeter Tyser #endif 35478acc472SPeter Tyser 35578acc472SPeter Tyser #ifndef __HAVE_ARCH_STRPBRK 35678acc472SPeter Tyser /** 35778acc472SPeter Tyser * strpbrk - Find the first occurrence of a set of characters 35878acc472SPeter Tyser * @cs: The string to be searched 35978acc472SPeter Tyser * @ct: The characters to search for 36078acc472SPeter Tyser */ 36178acc472SPeter Tyser char * strpbrk(const char * cs,const char * ct) 36278acc472SPeter Tyser { 36378acc472SPeter Tyser const char *sc1,*sc2; 36478acc472SPeter Tyser 36578acc472SPeter Tyser for( sc1 = cs; *sc1 != '\0'; ++sc1) { 36678acc472SPeter Tyser for( sc2 = ct; *sc2 != '\0'; ++sc2) { 36778acc472SPeter Tyser if (*sc1 == *sc2) 36878acc472SPeter Tyser return (char *) sc1; 36978acc472SPeter Tyser } 37078acc472SPeter Tyser } 37178acc472SPeter Tyser return NULL; 37278acc472SPeter Tyser } 37378acc472SPeter Tyser #endif 37478acc472SPeter Tyser 37578acc472SPeter Tyser #ifndef __HAVE_ARCH_STRTOK 37678acc472SPeter Tyser /** 37778acc472SPeter Tyser * strtok - Split a string into tokens 37878acc472SPeter Tyser * @s: The string to be searched 37978acc472SPeter Tyser * @ct: The characters to search for 38078acc472SPeter Tyser * 38178acc472SPeter Tyser * WARNING: strtok is deprecated, use strsep instead. 38278acc472SPeter Tyser */ 38378acc472SPeter Tyser char * strtok(char * s,const char * ct) 38478acc472SPeter Tyser { 38578acc472SPeter Tyser char *sbegin, *send; 38678acc472SPeter Tyser 38778acc472SPeter Tyser sbegin = s ? s : ___strtok; 38878acc472SPeter Tyser if (!sbegin) { 38978acc472SPeter Tyser return NULL; 39078acc472SPeter Tyser } 39178acc472SPeter Tyser sbegin += strspn(sbegin,ct); 39278acc472SPeter Tyser if (*sbegin == '\0') { 39378acc472SPeter Tyser ___strtok = NULL; 39478acc472SPeter Tyser return( NULL ); 39578acc472SPeter Tyser } 39678acc472SPeter Tyser send = strpbrk( sbegin, ct); 39778acc472SPeter Tyser if (send && *send != '\0') 39878acc472SPeter Tyser *send++ = '\0'; 39978acc472SPeter Tyser ___strtok = send; 40078acc472SPeter Tyser return (sbegin); 40178acc472SPeter Tyser } 40278acc472SPeter Tyser #endif 40378acc472SPeter Tyser 40478acc472SPeter Tyser #ifndef __HAVE_ARCH_STRSEP 40578acc472SPeter Tyser /** 40678acc472SPeter Tyser * strsep - Split a string into tokens 40778acc472SPeter Tyser * @s: The string to be searched 40878acc472SPeter Tyser * @ct: The characters to search for 40978acc472SPeter Tyser * 41078acc472SPeter Tyser * strsep() updates @s to point after the token, ready for the next call. 41178acc472SPeter Tyser * 41278acc472SPeter Tyser * It returns empty tokens, too, behaving exactly like the libc function 41378acc472SPeter Tyser * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. 41478acc472SPeter Tyser * Same semantics, slimmer shape. ;) 41578acc472SPeter Tyser */ 41678acc472SPeter Tyser char * strsep(char **s, const char *ct) 41778acc472SPeter Tyser { 41878acc472SPeter Tyser char *sbegin = *s, *end; 41978acc472SPeter Tyser 42078acc472SPeter Tyser if (sbegin == NULL) 42178acc472SPeter Tyser return NULL; 42278acc472SPeter Tyser 42378acc472SPeter Tyser end = strpbrk(sbegin, ct); 42478acc472SPeter Tyser if (end) 42578acc472SPeter Tyser *end++ = '\0'; 42678acc472SPeter Tyser *s = end; 42778acc472SPeter Tyser 42878acc472SPeter Tyser return sbegin; 42978acc472SPeter Tyser } 43078acc472SPeter Tyser #endif 43178acc472SPeter Tyser 43278acc472SPeter Tyser #ifndef __HAVE_ARCH_STRSWAB 43378acc472SPeter Tyser /** 43478acc472SPeter Tyser * strswab - swap adjacent even and odd bytes in %NUL-terminated string 43578acc472SPeter Tyser * s: address of the string 43678acc472SPeter Tyser * 43778acc472SPeter Tyser * returns the address of the swapped string or NULL on error. If 43878acc472SPeter Tyser * string length is odd, last byte is untouched. 43978acc472SPeter Tyser */ 44078acc472SPeter Tyser char *strswab(const char *s) 44178acc472SPeter Tyser { 44278acc472SPeter Tyser char *p, *q; 44378acc472SPeter Tyser 44478acc472SPeter Tyser if ((NULL == s) || ('\0' == *s)) { 44578acc472SPeter Tyser return (NULL); 44678acc472SPeter Tyser } 44778acc472SPeter Tyser 44878acc472SPeter Tyser for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) { 44978acc472SPeter Tyser char tmp; 45078acc472SPeter Tyser 45178acc472SPeter Tyser tmp = *p; 45278acc472SPeter Tyser *p = *q; 45378acc472SPeter Tyser *q = tmp; 45478acc472SPeter Tyser } 45578acc472SPeter Tyser 45678acc472SPeter Tyser return (char *) s; 45778acc472SPeter Tyser } 45878acc472SPeter Tyser #endif 45978acc472SPeter Tyser 46078acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMSET 46178acc472SPeter Tyser /** 46278acc472SPeter Tyser * memset - Fill a region of memory with the given value 46378acc472SPeter Tyser * @s: Pointer to the start of the area. 46478acc472SPeter Tyser * @c: The byte to fill the area with 46578acc472SPeter Tyser * @count: The size of the area. 46678acc472SPeter Tyser * 46778acc472SPeter Tyser * Do not use memset() to access IO space, use memset_io() instead. 46878acc472SPeter Tyser */ 46978acc472SPeter Tyser void * memset(void * s,int c,size_t count) 47078acc472SPeter Tyser { 47178acc472SPeter Tyser unsigned long *sl = (unsigned long *) s; 47278acc472SPeter Tyser char *s8; 473ab4458bdSSimon Glass 474ab4458bdSSimon Glass #if !CONFIG_IS_ENABLED(TINY_MEMSET) 475ab4458bdSSimon Glass unsigned long cl = 0; 47678acc472SPeter Tyser int i; 47778acc472SPeter Tyser 47878acc472SPeter Tyser /* do it one word at a time (32 bits or 64 bits) while possible */ 47978acc472SPeter Tyser if ( ((ulong)s & (sizeof(*sl) - 1)) == 0) { 48078acc472SPeter Tyser for (i = 0; i < sizeof(*sl); i++) { 48178acc472SPeter Tyser cl <<= 8; 48278acc472SPeter Tyser cl |= c & 0xff; 48378acc472SPeter Tyser } 48478acc472SPeter Tyser while (count >= sizeof(*sl)) { 48578acc472SPeter Tyser *sl++ = cl; 48678acc472SPeter Tyser count -= sizeof(*sl); 48778acc472SPeter Tyser } 48878acc472SPeter Tyser } 489ab4458bdSSimon Glass #endif /* fill 8 bits at a time */ 49078acc472SPeter Tyser s8 = (char *)sl; 49178acc472SPeter Tyser while (count--) 49278acc472SPeter Tyser *s8++ = c; 49378acc472SPeter Tyser 49478acc472SPeter Tyser return s; 49578acc472SPeter Tyser } 49678acc472SPeter Tyser #endif 49778acc472SPeter Tyser 49878acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMCPY 49978acc472SPeter Tyser /** 50078acc472SPeter Tyser * memcpy - Copy one area of memory to another 50178acc472SPeter Tyser * @dest: Where to copy to 50278acc472SPeter Tyser * @src: Where to copy from 50378acc472SPeter Tyser * @count: The size of the area. 50478acc472SPeter Tyser * 50578acc472SPeter Tyser * You should not use this function to access IO space, use memcpy_toio() 50678acc472SPeter Tyser * or memcpy_fromio() instead. 50778acc472SPeter Tyser */ 50878acc472SPeter Tyser void * memcpy(void *dest, const void *src, size_t count) 50978acc472SPeter Tyser { 51078acc472SPeter Tyser unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; 51178acc472SPeter Tyser char *d8, *s8; 51278acc472SPeter Tyser 513b038db85SMatthias Weisser if (src == dest) 514b038db85SMatthias Weisser return dest; 515b038db85SMatthias Weisser 51678acc472SPeter Tyser /* while all data is aligned (common case), copy a word at a time */ 51778acc472SPeter Tyser if ( (((ulong)dest | (ulong)src) & (sizeof(*dl) - 1)) == 0) { 51878acc472SPeter Tyser while (count >= sizeof(*dl)) { 51978acc472SPeter Tyser *dl++ = *sl++; 52078acc472SPeter Tyser count -= sizeof(*dl); 52178acc472SPeter Tyser } 52278acc472SPeter Tyser } 52378acc472SPeter Tyser /* copy the reset one byte at a time */ 52478acc472SPeter Tyser d8 = (char *)dl; 52578acc472SPeter Tyser s8 = (char *)sl; 52678acc472SPeter Tyser while (count--) 52778acc472SPeter Tyser *d8++ = *s8++; 52878acc472SPeter Tyser 52978acc472SPeter Tyser return dest; 53078acc472SPeter Tyser } 53178acc472SPeter Tyser #endif 53278acc472SPeter Tyser 53378acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMMOVE 53478acc472SPeter Tyser /** 53578acc472SPeter Tyser * memmove - Copy one area of memory to another 53678acc472SPeter Tyser * @dest: Where to copy to 53778acc472SPeter Tyser * @src: Where to copy from 53878acc472SPeter Tyser * @count: The size of the area. 53978acc472SPeter Tyser * 54078acc472SPeter Tyser * Unlike memcpy(), memmove() copes with overlapping areas. 54178acc472SPeter Tyser */ 54278acc472SPeter Tyser void * memmove(void * dest,const void *src,size_t count) 54378acc472SPeter Tyser { 54478acc472SPeter Tyser char *tmp, *s; 54578acc472SPeter Tyser 54678acc472SPeter Tyser if (dest <= src) { 547cb0eae8cSSimon Glass memcpy(dest, src, count); 548cb0eae8cSSimon Glass } else { 54978acc472SPeter Tyser tmp = (char *) dest + count; 55078acc472SPeter Tyser s = (char *) src + count; 55178acc472SPeter Tyser while (count--) 55278acc472SPeter Tyser *--tmp = *--s; 55378acc472SPeter Tyser } 55478acc472SPeter Tyser 55578acc472SPeter Tyser return dest; 55678acc472SPeter Tyser } 55778acc472SPeter Tyser #endif 55878acc472SPeter Tyser 55978acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMCMP 56078acc472SPeter Tyser /** 56178acc472SPeter Tyser * memcmp - Compare two areas of memory 56278acc472SPeter Tyser * @cs: One area of memory 56378acc472SPeter Tyser * @ct: Another area of memory 56478acc472SPeter Tyser * @count: The size of the area. 56578acc472SPeter Tyser */ 56678acc472SPeter Tyser int memcmp(const void * cs,const void * ct,size_t count) 56778acc472SPeter Tyser { 56878acc472SPeter Tyser const unsigned char *su1, *su2; 56978acc472SPeter Tyser int res = 0; 57078acc472SPeter Tyser 57178acc472SPeter Tyser for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 57278acc472SPeter Tyser if ((res = *su1 - *su2) != 0) 57378acc472SPeter Tyser break; 57478acc472SPeter Tyser return res; 57578acc472SPeter Tyser } 57678acc472SPeter Tyser #endif 57778acc472SPeter Tyser 57878acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMSCAN 57978acc472SPeter Tyser /** 58078acc472SPeter Tyser * memscan - Find a character in an area of memory. 58178acc472SPeter Tyser * @addr: The memory area 58278acc472SPeter Tyser * @c: The byte to search for 58378acc472SPeter Tyser * @size: The size of the area. 58478acc472SPeter Tyser * 58578acc472SPeter Tyser * returns the address of the first occurrence of @c, or 1 byte past 58678acc472SPeter Tyser * the area if @c is not found 58778acc472SPeter Tyser */ 58878acc472SPeter Tyser void * memscan(void * addr, int c, size_t size) 58978acc472SPeter Tyser { 59078acc472SPeter Tyser unsigned char * p = (unsigned char *) addr; 59178acc472SPeter Tyser 59278acc472SPeter Tyser while (size) { 59378acc472SPeter Tyser if (*p == c) 59478acc472SPeter Tyser return (void *) p; 59578acc472SPeter Tyser p++; 59678acc472SPeter Tyser size--; 59778acc472SPeter Tyser } 59878acc472SPeter Tyser return (void *) p; 59978acc472SPeter Tyser } 60078acc472SPeter Tyser #endif 60178acc472SPeter Tyser 60278acc472SPeter Tyser #ifndef __HAVE_ARCH_STRSTR 60378acc472SPeter Tyser /** 60478acc472SPeter Tyser * strstr - Find the first substring in a %NUL terminated string 60578acc472SPeter Tyser * @s1: The string to be searched 60678acc472SPeter Tyser * @s2: The string to search for 60778acc472SPeter Tyser */ 60878acc472SPeter Tyser char * strstr(const char * s1,const char * s2) 60978acc472SPeter Tyser { 61078acc472SPeter Tyser int l1, l2; 61178acc472SPeter Tyser 61278acc472SPeter Tyser l2 = strlen(s2); 61378acc472SPeter Tyser if (!l2) 61478acc472SPeter Tyser return (char *) s1; 61578acc472SPeter Tyser l1 = strlen(s1); 61678acc472SPeter Tyser while (l1 >= l2) { 61778acc472SPeter Tyser l1--; 61878acc472SPeter Tyser if (!memcmp(s1,s2,l2)) 61978acc472SPeter Tyser return (char *) s1; 62078acc472SPeter Tyser s1++; 62178acc472SPeter Tyser } 62278acc472SPeter Tyser return NULL; 62378acc472SPeter Tyser } 62478acc472SPeter Tyser #endif 62578acc472SPeter Tyser 62678acc472SPeter Tyser #ifndef __HAVE_ARCH_MEMCHR 62778acc472SPeter Tyser /** 62878acc472SPeter Tyser * memchr - Find a character in an area of memory. 62978acc472SPeter Tyser * @s: The memory area 63078acc472SPeter Tyser * @c: The byte to search for 63178acc472SPeter Tyser * @n: The size of the area. 63278acc472SPeter Tyser * 63378acc472SPeter Tyser * returns the address of the first occurrence of @c, or %NULL 63478acc472SPeter Tyser * if @c is not found 63578acc472SPeter Tyser */ 63678acc472SPeter Tyser void *memchr(const void *s, int c, size_t n) 63778acc472SPeter Tyser { 63878acc472SPeter Tyser const unsigned char *p = s; 63978acc472SPeter Tyser while (n-- != 0) { 64078acc472SPeter Tyser if ((unsigned char)c == *p++) { 64178acc472SPeter Tyser return (void *)(p-1); 64278acc472SPeter Tyser } 64378acc472SPeter Tyser } 64478acc472SPeter Tyser return NULL; 64578acc472SPeter Tyser } 64678acc472SPeter Tyser 64778acc472SPeter Tyser #endif 648dfe64e2cSSergey Lapin #ifndef __HAVE_ARCH_MEMCHR_INV 649dfe64e2cSSergey Lapin static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) 650dfe64e2cSSergey Lapin { 651dfe64e2cSSergey Lapin while (bytes) { 652dfe64e2cSSergey Lapin if (*start != value) 653dfe64e2cSSergey Lapin return (void *)start; 654dfe64e2cSSergey Lapin start++; 655dfe64e2cSSergey Lapin bytes--; 656dfe64e2cSSergey Lapin } 657dfe64e2cSSergey Lapin return NULL; 658dfe64e2cSSergey Lapin } 659dfe64e2cSSergey Lapin /** 660dfe64e2cSSergey Lapin * memchr_inv - Find an unmatching character in an area of memory. 661dfe64e2cSSergey Lapin * @start: The memory area 662dfe64e2cSSergey Lapin * @c: Find a character other than c 663dfe64e2cSSergey Lapin * @bytes: The size of the area. 664dfe64e2cSSergey Lapin * 665dfe64e2cSSergey Lapin * returns the address of the first character other than @c, or %NULL 666dfe64e2cSSergey Lapin * if the whole buffer contains just @c. 667dfe64e2cSSergey Lapin */ 668dfe64e2cSSergey Lapin void *memchr_inv(const void *start, int c, size_t bytes) 669dfe64e2cSSergey Lapin { 670dfe64e2cSSergey Lapin u8 value = c; 671dfe64e2cSSergey Lapin u64 value64; 672dfe64e2cSSergey Lapin unsigned int words, prefix; 673dfe64e2cSSergey Lapin 674dfe64e2cSSergey Lapin if (bytes <= 16) 675dfe64e2cSSergey Lapin return check_bytes8(start, value, bytes); 676dfe64e2cSSergey Lapin 677dfe64e2cSSergey Lapin value64 = value; 678dfe64e2cSSergey Lapin value64 |= value64 << 8; 679dfe64e2cSSergey Lapin value64 |= value64 << 16; 680dfe64e2cSSergey Lapin value64 |= value64 << 32; 681dfe64e2cSSergey Lapin 682dfe64e2cSSergey Lapin prefix = (unsigned long)start % 8; 683dfe64e2cSSergey Lapin if (prefix) { 684dfe64e2cSSergey Lapin u8 *r; 685dfe64e2cSSergey Lapin 686dfe64e2cSSergey Lapin prefix = 8 - prefix; 687dfe64e2cSSergey Lapin r = check_bytes8(start, value, prefix); 688dfe64e2cSSergey Lapin if (r) 689dfe64e2cSSergey Lapin return r; 690dfe64e2cSSergey Lapin start += prefix; 691dfe64e2cSSergey Lapin bytes -= prefix; 692dfe64e2cSSergey Lapin } 693dfe64e2cSSergey Lapin 694dfe64e2cSSergey Lapin words = bytes / 8; 695dfe64e2cSSergey Lapin 696dfe64e2cSSergey Lapin while (words) { 697dfe64e2cSSergey Lapin if (*(u64 *)start != value64) 698dfe64e2cSSergey Lapin return check_bytes8(start, value, 8); 699dfe64e2cSSergey Lapin start += 8; 700dfe64e2cSSergey Lapin words--; 701dfe64e2cSSergey Lapin } 702dfe64e2cSSergey Lapin 703dfe64e2cSSergey Lapin return check_bytes8(start, value, bytes % 8); 704dfe64e2cSSergey Lapin } 705dfe64e2cSSergey Lapin #endif 706