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