"Das U-Boot" Source Tree
at jcs/rk3128 804 lines 16 kB view raw
1/* 2 * linux/lib/string.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7/* 8 * stupid library routines.. The optimized versions should generally be found 9 * as inline code in <asm-xx/string.h> 10 * 11 * These are buggy as well.. 12 * 13 * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> 14 * - Added strsep() which will replace strtok() soon (because strsep() is 15 * reentrant and should be faster). Use only strsep() in new code, please. 16 */ 17 18#include <asm/sections.h> 19#include <config.h> 20#include <limits.h> 21#include <linux/compiler.h> 22#include <linux/ctype.h> 23#include <linux/string.h> 24#include <linux/types.h> 25#include <malloc.h> 26 27/** 28 * strncasecmp - Case insensitive, length-limited string comparison 29 * @s1: One string 30 * @s2: The other string 31 * @len: the maximum number of characters to compare 32 */ 33int strncasecmp(const char *s1, const char *s2, size_t len) 34{ 35 /* Yes, Virginia, it had better be unsigned */ 36 unsigned char c1, c2; 37 38 c1 = 0; c2 = 0; 39 if (len) { 40 do { 41 c1 = *s1; c2 = *s2; 42 s1++; s2++; 43 if (!c1) 44 break; 45 if (!c2) 46 break; 47 if (c1 == c2) 48 continue; 49 c1 = tolower(c1); 50 c2 = tolower(c2); 51 if (c1 != c2) 52 break; 53 } while (--len); 54 } 55 return (int)c1 - (int)c2; 56} 57 58/** 59 * strcasecmp - Case insensitive string comparison 60 * @s1: One string 61 * @s2: The other string 62 */ 63int strcasecmp(const char *s1, const char *s2) 64{ 65 return strncasecmp(s1, s2, -1U); 66} 67 68char * ___strtok; 69 70#ifndef __HAVE_ARCH_STRCPY 71/** 72 * strcpy - Copy a %NUL terminated string 73 * @dest: Where to copy the string to 74 * @src: Where to copy the string from 75 */ 76char * strcpy(char * dest,const char *src) 77{ 78 char *tmp = dest; 79 80 while ((*dest++ = *src++) != '\0') 81 /* nothing */; 82 return tmp; 83} 84#endif 85 86#ifndef __HAVE_ARCH_STRNCPY 87/** 88 * strncpy - Copy a length-limited, %NUL-terminated string 89 * @dest: Where to copy the string to 90 * @src: Where to copy the string from 91 * @count: The maximum number of bytes to copy 92 * 93 * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. 94 * However, the result is not %NUL-terminated if the source exceeds 95 * @count bytes. 96 */ 97char * strncpy(char * dest,const char *src,size_t count) 98{ 99 char *tmp = dest; 100 101 while (count-- && (*dest++ = *src++) != '\0') 102 /* nothing */; 103 104 return tmp; 105} 106#endif 107 108#ifndef __HAVE_ARCH_STRLCPY 109/** 110 * strlcpy - Copy a C-string into a sized buffer 111 * @dest: Where to copy the string to 112 * @src: Where to copy the string from 113 * @size: size of destination buffer 114 * 115 * Compatible with *BSD: the result is always a valid 116 * NUL-terminated string that fits in the buffer (unless, 117 * of course, the buffer size is zero). It does not pad 118 * out the result like strncpy() does. 119 * 120 * Return: strlen(src) 121 */ 122size_t strlcpy(char *dest, const char *src, size_t size) 123{ 124 size_t ret = strlen(src); 125 126 if (size) { 127 size_t len = (ret >= size) ? size - 1 : ret; 128 memcpy(dest, src, len); 129 dest[len] = '\0'; 130 } 131 return ret; 132} 133#endif 134 135#ifndef __HAVE_ARCH_STRCAT 136/** 137 * strcat - Append one %NUL-terminated string to another 138 * @dest: The string to be appended to 139 * @src: The string to append to it 140 */ 141char * strcat(char * dest, const char * src) 142{ 143 char *tmp = dest; 144 145 while (*dest) 146 dest++; 147 while ((*dest++ = *src++) != '\0') 148 ; 149 150 return tmp; 151} 152#endif 153 154#ifndef __HAVE_ARCH_STRNCAT 155/** 156 * strncat - Append a length-limited, %NUL-terminated string to another 157 * @dest: The string to be appended to 158 * @src: The string to append to it 159 * @count: The maximum numbers of bytes to copy 160 * 161 * Note that in contrast to strncpy, strncat ensures the result is 162 * terminated. 163 */ 164char * strncat(char *dest, const char *src, size_t count) 165{ 166 char *tmp = dest; 167 168 if (count) { 169 while (*dest) 170 dest++; 171 while ((*dest++ = *src++)) { 172 if (--count == 0) { 173 *dest = '\0'; 174 break; 175 } 176 } 177 } 178 179 return tmp; 180} 181#endif 182 183#ifndef __HAVE_ARCH_STRLCAT 184/** 185 * strlcat - Append a length-limited, %NUL-terminated string to another 186 * @dest: The string to be appended to 187 * @src: The string to append to it 188 * @size: The size of @dest 189 * 190 * Compatible with *BSD: the result is always a valid NUL-terminated string that 191 * fits in the buffer (unless, of course, the buffer size is zero). It does not 192 * write past @size like strncat() does. 193 * 194 * Return: min(strlen(dest), size) + strlen(src) 195 */ 196size_t strlcat(char *dest, const char *src, size_t size) 197{ 198 size_t len = strnlen(dest, size); 199 200 return len + strlcpy(dest + len, src, size - len); 201} 202#endif 203 204#ifndef __HAVE_ARCH_STRCMP 205/** 206 * strcmp - Compare two strings 207 * @cs: One string 208 * @ct: Another string 209 */ 210int strcmp(const char *cs, const char *ct) 211{ 212 int ret; 213 214 while (1) { 215 unsigned char a = *cs++; 216 unsigned char b = *ct++; 217 218 ret = a - b; 219 if (ret || !b) 220 break; 221 } 222 223 return ret; 224} 225#endif 226 227#ifndef __HAVE_ARCH_STRNCMP 228/** 229 * strncmp - Compare two length-limited strings 230 * @cs: One string 231 * @ct: Another string 232 * @count: The maximum number of bytes to compare 233 */ 234int strncmp(const char *cs, const char *ct, size_t count) 235{ 236 int ret = 0; 237 238 while (count--) { 239 unsigned char a = *cs++; 240 unsigned char b = *ct++; 241 242 ret = a - b; 243 if (ret || !b) 244 break; 245 } 246 247 return ret; 248} 249#endif 250 251#ifndef __HAVE_ARCH_STRCHR 252/** 253 * strchr - Find the first occurrence of a character in a string 254 * @s: The string to be searched 255 * @c: The character to search for 256 */ 257char * strchr(const char * s, int c) 258{ 259 for(; *s != (char) c; ++s) 260 if (*s == '\0') 261 return NULL; 262 return (char *) s; 263} 264#endif 265 266const char *strchrnul(const char *s, int c) 267{ 268 for (; *s != (char)c; ++s) 269 if (*s == '\0') 270 break; 271 return s; 272} 273 274#ifndef __HAVE_ARCH_STRRCHR 275/** 276 * strrchr - Find the last occurrence of a character in a string 277 * @s: The string to be searched 278 * @c: The character to search for 279 */ 280char * strrchr(const char * s, int c) 281{ 282 const char *p = s + strlen(s); 283 do { 284 if (*p == (char)c) 285 return (char *)p; 286 } while (--p >= s); 287 return NULL; 288} 289#endif 290 291#ifndef __HAVE_ARCH_STRLEN 292/** 293 * strlen - Find the length of a string 294 * @s: The string to be sized 295 */ 296size_t strlen(const char * s) 297{ 298 const char *sc; 299 300 for (sc = s; *sc != '\0'; ++sc) 301 /* nothing */; 302 return sc - s; 303} 304#endif 305 306#ifndef __HAVE_ARCH_STRNLEN 307/** 308 * strnlen - Find the length of a length-limited string 309 * @s: The string to be sized 310 * @count: The maximum number of bytes to search 311 */ 312size_t strnlen(const char * s, size_t count) 313{ 314 const char *sc; 315 316 for (sc = s; count-- && *sc != '\0'; ++sc) 317 /* nothing */; 318 return sc - s; 319} 320#endif 321 322#ifndef __HAVE_ARCH_STRCSPN 323/** 324 * strcspn - Calculate the length of the initial substring of @s which does 325 * not contain letters in @reject 326 * @s: The string to be searched 327 * @reject: The string to avoid 328 */ 329size_t strcspn(const char *s, const char *reject) 330{ 331 const char *p; 332 const char *r; 333 size_t count = 0; 334 335 for (p = s; *p != '\0'; ++p) { 336 for (r = reject; *r != '\0'; ++r) { 337 if (*p == *r) 338 return count; 339 } 340 ++count; 341 } 342 return count; 343} 344#endif 345 346#ifndef __HAVE_ARCH_STRDUP 347char * strdup(const char *s) 348{ 349 char *new; 350 351 if ((s == NULL) || 352 ((new = malloc (strlen(s) + 1)) == NULL) ) { 353 return NULL; 354 } 355 356 strcpy (new, s); 357 return new; 358} 359 360char * strndup(const char *s, size_t n) 361{ 362 size_t len; 363 char *new; 364 365 if (s == NULL) 366 return NULL; 367 368 len = strlen(s); 369 370 if (n < len) 371 len = n; 372 373 new = malloc(len + 1); 374 if (new == NULL) 375 return NULL; 376 377 strncpy(new, s, len); 378 new[len] = '\0'; 379 380 return new; 381} 382#endif 383 384#ifndef __HAVE_ARCH_STRSPN 385/** 386 * strspn - Calculate the length of the initial substring of @s which only 387 * contain letters in @accept 388 * @s: The string to be searched 389 * @accept: The string to search for 390 */ 391size_t strspn(const char *s, const char *accept) 392{ 393 const char *p; 394 const char *a; 395 size_t count = 0; 396 397 for (p = s; *p != '\0'; ++p) { 398 for (a = accept; *a != '\0'; ++a) { 399 if (*p == *a) 400 break; 401 } 402 if (*a == '\0') 403 return count; 404 ++count; 405 } 406 407 return count; 408} 409#endif 410 411#ifndef __HAVE_ARCH_STRPBRK 412/** 413 * strpbrk - Find the first occurrence of a set of characters 414 * @cs: The string to be searched 415 * @ct: The characters to search for 416 */ 417char * strpbrk(const char * cs,const char * ct) 418{ 419 const char *sc1,*sc2; 420 421 for( sc1 = cs; *sc1 != '\0'; ++sc1) { 422 for( sc2 = ct; *sc2 != '\0'; ++sc2) { 423 if (*sc1 == *sc2) 424 return (char *) sc1; 425 } 426 } 427 return NULL; 428} 429#endif 430 431#ifndef __HAVE_ARCH_STRTOK 432/** 433 * strtok - Split a string into tokens 434 * @s: The string to be searched 435 * @ct: The characters to search for 436 * 437 * WARNING: strtok is deprecated, use strsep instead. 438 */ 439char * strtok(char * s,const char * ct) 440{ 441 char *sbegin, *send; 442 443 sbegin = s ? s : ___strtok; 444 if (!sbegin) { 445 return NULL; 446 } 447 sbegin += strspn(sbegin,ct); 448 if (*sbegin == '\0') { 449 ___strtok = NULL; 450 return( NULL ); 451 } 452 send = strpbrk( sbegin, ct); 453 if (send && *send != '\0') 454 *send++ = '\0'; 455 ___strtok = send; 456 return (sbegin); 457} 458#endif 459 460#ifndef __HAVE_ARCH_STRSEP 461/** 462 * strsep - Split a string into tokens 463 * @s: The string to be searched 464 * @ct: The characters to search for 465 * 466 * strsep() updates @s to point after the token, ready for the next call. 467 * 468 * It returns empty tokens, too, behaving exactly like the libc function 469 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. 470 * Same semantics, slimmer shape. ;) 471 */ 472char * strsep(char **s, const char *ct) 473{ 474 char *sbegin = *s, *end; 475 476 if (sbegin == NULL) 477 return NULL; 478 479 end = strpbrk(sbegin, ct); 480 if (end) 481 *end++ = '\0'; 482 *s = end; 483 484 return sbegin; 485} 486#endif 487 488#ifndef __HAVE_ARCH_STRSWAB 489/** 490 * strswab - swap adjacent even and odd bytes in %NUL-terminated string 491 * s: address of the string 492 * 493 * returns the address of the swapped string or NULL on error. If 494 * string length is odd, last byte is untouched. 495 */ 496char *strswab(const char *s) 497{ 498 char *p, *q; 499 500 if ((NULL == s) || ('\0' == *s)) { 501 return (NULL); 502 } 503 504 for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) { 505 char tmp; 506 507 tmp = *p; 508 *p = *q; 509 *q = tmp; 510 } 511 512 return (char *) s; 513} 514#endif 515 516#ifndef __HAVE_ARCH_MEMSET 517/** 518 * memset - Fill a region of memory with the given value 519 * @s: Pointer to the start of the area. 520 * @c: The byte to fill the area with 521 * @count: The size of the area. 522 * 523 * Do not use memset() to access IO space, use memset_io() instead. 524 */ 525__used void * memset(void * s,int c,size_t count) 526{ 527 unsigned long *sl = (unsigned long *) s; 528 char *s8; 529 530#if !CONFIG_IS_ENABLED(TINY_MEMSET) 531 unsigned long cl = 0; 532 int i; 533 534 /* do it one word at a time (32 bits or 64 bits) while possible */ 535 if ( ((ulong)s & (sizeof(*sl) - 1)) == 0) { 536 for (i = 0; i < sizeof(*sl); i++) { 537 cl <<= 8; 538 cl |= c & 0xff; 539 } 540 while (count >= sizeof(*sl)) { 541 *sl++ = cl; 542 count -= sizeof(*sl); 543 } 544 } 545#endif /* fill 8 bits at a time */ 546 s8 = (char *)sl; 547 while (count--) 548 *s8++ = c; 549 550 return s; 551} 552#endif 553 554#ifndef __HAVE_ARCH_MEMCPY 555/** 556 * memcpy - Copy one area of memory to another 557 * @dest: Where to copy to 558 * @src: Where to copy from 559 * @count: The size of the area. 560 * 561 * You should not use this function to access IO space, use memcpy_toio() 562 * or memcpy_fromio() instead. 563 */ 564__rcode __used void *memcpy(void *dest, const void *src, size_t count) 565{ 566 unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; 567 char *d8, *s8; 568 569 if (src == dest) 570 return dest; 571 572 /* while all data is aligned (common case), copy a word at a time */ 573 if ( (((ulong)dest | (ulong)src) & (sizeof(*dl) - 1)) == 0) { 574 while (count >= sizeof(*dl)) { 575 *dl++ = *sl++; 576 count -= sizeof(*dl); 577 } 578 } 579 /* copy the reset one byte at a time */ 580 d8 = (char *)dl; 581 s8 = (char *)sl; 582 while (count--) 583 *d8++ = *s8++; 584 585 return dest; 586} 587#endif 588 589#ifndef __HAVE_ARCH_MEMMOVE 590/** 591 * memmove - Copy one area of memory to another 592 * @dest: Where to copy to 593 * @src: Where to copy from 594 * @count: The size of the area. 595 * 596 * Unlike memcpy(), memmove() copes with overlapping areas. 597 */ 598__rcode __used void *memmove(void *dest, const void *src, size_t count) 599{ 600 char *tmp, *s; 601 602 if (dest <= src || (src + count) <= dest) { 603 /* 604 * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible: 605 * - when dest is before src (assuming that memcpy is doing forward-copying) 606 * - when destination don't overlap the source buffer (src + count <= dest) 607 * 608 * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined, 609 * __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific 610 * implementation is not doing a forward-copying. 611 * 612 * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32 613 * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE. 614 */ 615 memcpy(dest, src, count); 616 } else { 617 tmp = (char *) dest + count; 618 s = (char *) src + count; 619 while (count--) 620 *--tmp = *--s; 621 } 622 623 return dest; 624} 625#endif 626 627#ifndef __HAVE_ARCH_MEMCMP 628/** 629 * memcmp - Compare two areas of memory 630 * @cs: One area of memory 631 * @ct: Another area of memory 632 * @count: The size of the area. 633 */ 634__used int memcmp(const void * cs,const void * ct,size_t count) 635{ 636 const unsigned char *su1, *su2; 637 int res = 0; 638 639 for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 640 if ((res = *su1 - *su2) != 0) 641 break; 642 return res; 643} 644#endif 645 646#ifndef __HAVE_ARCH_MEMSCAN 647/** 648 * memscan - Find a character in an area of memory. 649 * @addr: The memory area 650 * @c: The byte to search for 651 * @size: The size of the area. 652 * 653 * returns the address of the first occurrence of @c, or 1 byte past 654 * the area if @c is not found 655 */ 656void * memscan(void * addr, int c, size_t size) 657{ 658 unsigned char * p = (unsigned char *) addr; 659 660 while (size) { 661 if (*p == c) 662 return (void *) p; 663 p++; 664 size--; 665 } 666 return (void *) p; 667} 668#endif 669 670char *memdup(const void *src, size_t len) 671{ 672 char *p; 673 674 p = malloc(len); 675 if (!p) 676 return NULL; 677 678 memcpy(p, src, len); 679 680 return p; 681} 682 683#ifndef __HAVE_ARCH_STRNSTR 684/** 685 * strnstr() - find the first substring occurrence in a NUL terminated string 686 * 687 * @s1: string to be searched 688 * @s2: string to search for 689 * @len: maximum number of characters in s2 to consider 690 * 691 * Return: pointer to the first occurrence or NULL 692 */ 693char *strnstr(const char *s1, const char *s2, size_t len) 694{ 695 size_t l1, l2; 696 697 l1 = strnlen(s1, len); 698 l2 = strlen(s2); 699 700 for (; l1 >= l2; --l1, ++s1) { 701 if (!memcmp(s1, s2, l2)) 702 return (char *) s1; 703 } 704 705 return NULL; 706} 707#endif 708 709#ifndef __HAVE_ARCH_STRSTR 710/** 711 * strstr() - find the first substring occurrence in a NUL terminated string 712 * 713 * @s1: string to be searched 714 * @s2: string to search for 715 * @len: maximum number of characters in s2 to consider 716 * 717 * Return: pointer to the first occurrence or NULL 718 */ 719char *strstr(const char *s1, const char *s2) 720{ 721 return strnstr(s1, s2, SIZE_MAX); 722} 723#endif 724 725#ifndef __HAVE_ARCH_MEMCHR 726/** 727 * memchr - Find a character in an area of memory. 728 * @s: The memory area 729 * @c: The byte to search for 730 * @n: The size of the area. 731 * 732 * returns the address of the first occurrence of @c, or %NULL 733 * if @c is not found 734 */ 735void *memchr(const void *s, int c, size_t n) 736{ 737 const unsigned char *p = s; 738 while (n-- != 0) { 739 if ((unsigned char)c == *p++) { 740 return (void *)(p-1); 741 } 742 } 743 return NULL; 744} 745 746#endif 747#ifndef __HAVE_ARCH_MEMCHR_INV 748static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) 749{ 750 while (bytes) { 751 if (*start != value) 752 return (void *)start; 753 start++; 754 bytes--; 755 } 756 return NULL; 757} 758/** 759 * memchr_inv - Find an unmatching character in an area of memory. 760 * @start: The memory area 761 * @c: Find a character other than c 762 * @bytes: The size of the area. 763 * 764 * returns the address of the first character other than @c, or %NULL 765 * if the whole buffer contains just @c. 766 */ 767void *memchr_inv(const void *start, int c, size_t bytes) 768{ 769 u8 value = c; 770 u64 value64; 771 unsigned int words, prefix; 772 773 if (bytes <= 16) 774 return check_bytes8(start, value, bytes); 775 776 value64 = value; 777 value64 |= value64 << 8; 778 value64 |= value64 << 16; 779 value64 |= value64 << 32; 780 781 prefix = (unsigned long)start % 8; 782 if (prefix) { 783 u8 *r; 784 785 prefix = 8 - prefix; 786 r = check_bytes8(start, value, prefix); 787 if (r) 788 return r; 789 start += prefix; 790 bytes -= prefix; 791 } 792 793 words = bytes / 8; 794 795 while (words) { 796 if (*(u64 *)start != value64) 797 return check_bytes8(start, value, 8); 798 start += 8; 799 words--; 800 } 801 802 return check_bytes8(start, value, bytes % 8); 803} 804#endif