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