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