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