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/kernel.h>
  26#include <linux/export.h>
  27#include <linux/bug.h>
  28#include <linux/errno.h>
  29
  30#ifndef __HAVE_ARCH_STRNCASECMP
  31/**
  32 * strncasecmp - Case insensitive, length-limited string comparison
  33 * @s1: One string
  34 * @s2: The other string
  35 * @len: the maximum number of characters to compare
  36 */
  37int strncasecmp(const char *s1, const char *s2, size_t len)
  38{
  39        /* Yes, Virginia, it had better be unsigned */
  40        unsigned char c1, c2;
  41
  42        if (!len)
  43                return 0;
  44
  45        do {
  46                c1 = *s1++;
  47                c2 = *s2++;
  48                if (!c1 || !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        return (int)c1 - (int)c2;
  58}
  59EXPORT_SYMBOL(strncasecmp);
  60#endif
  61#ifndef __HAVE_ARCH_STRNICMP
  62#undef strnicmp
  63int strnicmp(const char *s1, const char *s2, size_t len)
  64{
  65        return strncasecmp(s1, s2, len);
  66}
  67EXPORT_SYMBOL(strnicmp);
  68#endif
  69
  70#ifndef __HAVE_ARCH_STRCASECMP
  71int strcasecmp(const char *s1, const char *s2)
  72{
  73        int c1, c2;
  74
  75        do {
  76                c1 = tolower(*s1++);
  77                c2 = tolower(*s2++);
  78        } while (c1 == c2 && c1 != 0);
  79        return c1 - c2;
  80}
  81EXPORT_SYMBOL(strcasecmp);
  82#endif
  83
  84#ifndef __HAVE_ARCH_STRCPY
  85/**
  86 * strcpy - Copy a %NUL terminated string
  87 * @dest: Where to copy the string to
  88 * @src: Where to copy the string from
  89 */
  90#undef strcpy
  91char *strcpy(char *dest, const char *src)
  92{
  93        char *tmp = dest;
  94
  95        while ((*dest++ = *src++) != '\0')
  96                /* nothing */;
  97        return tmp;
  98}
  99EXPORT_SYMBOL(strcpy);
 100#endif
 101
 102#ifndef __HAVE_ARCH_STRNCPY
 103/**
 104 * strncpy - Copy a length-limited, C-string
 105 * @dest: Where to copy the string to
 106 * @src: Where to copy the string from
 107 * @count: The maximum number of bytes to copy
 108 *
 109 * The result is not %NUL-terminated if the source exceeds
 110 * @count bytes.
 111 *
 112 * In the case where the length of @src is less than  that  of
 113 * count, the remainder of @dest will be padded with %NUL.
 114 *
 115 */
 116char *strncpy(char *dest, const char *src, size_t count)
 117{
 118        char *tmp = dest;
 119
 120        while (count) {
 121                if ((*tmp = *src) != 0)
 122                        src++;
 123                tmp++;
 124                count--;
 125        }
 126        return dest;
 127}
 128EXPORT_SYMBOL(strncpy);
 129#endif
 130
 131#ifndef __HAVE_ARCH_STRLCPY
 132/**
 133 * strlcpy - Copy a C-string into a sized buffer
 134 * @dest: Where to copy the string to
 135 * @src: Where to copy the string from
 136 * @size: size of destination buffer
 137 *
 138 * Compatible with *BSD: the result is always a valid
 139 * NUL-terminated string that fits in the buffer (unless,
 140 * of course, the buffer size is zero). It does not pad
 141 * out the result like strncpy() does.
 142 */
 143size_t strlcpy(char *dest, const char *src, size_t size)
 144{
 145        size_t ret = strlen(src);
 146
 147        if (size) {
 148                size_t len = (ret >= size) ? size - 1 : ret;
 149                memcpy(dest, src, len);
 150                dest[len] = '\0';
 151        }
 152        return ret;
 153}
 154EXPORT_SYMBOL(strlcpy);
 155#endif
 156
 157#ifndef __HAVE_ARCH_STRCAT
 158/**
 159 * strcat - Append one %NUL-terminated string to another
 160 * @dest: The string to be appended to
 161 * @src: The string to append to it
 162 */
 163#undef strcat
 164char *strcat(char *dest, const char *src)
 165{
 166        char *tmp = dest;
 167
 168        while (*dest)
 169                dest++;
 170        while ((*dest++ = *src++) != '\0')
 171                ;
 172        return tmp;
 173}
 174EXPORT_SYMBOL(strcat);
 175#endif
 176
 177#ifndef __HAVE_ARCH_STRNCAT
 178/**
 179 * strncat - Append a length-limited, C-string to another
 180 * @dest: The string to be appended to
 181 * @src: The string to append to it
 182 * @count: The maximum numbers of bytes to copy
 183 *
 184 * Note that in contrast to strncpy(), strncat() ensures the result is
 185 * terminated.
 186 */
 187char *strncat(char *dest, const char *src, size_t count)
 188{
 189        char *tmp = dest;
 190
 191        if (count) {
 192                while (*dest)
 193                        dest++;
 194                while ((*dest++ = *src++) != 0) {
 195                        if (--count == 0) {
 196                                *dest = '\0';
 197                                break;
 198                        }
 199                }
 200        }
 201        return tmp;
 202}
 203EXPORT_SYMBOL(strncat);
 204#endif
 205
 206#ifndef __HAVE_ARCH_STRLCAT
 207/**
 208 * strlcat - Append a length-limited, C-string to another
 209 * @dest: The string to be appended to
 210 * @src: The string to append to it
 211 * @count: The size of the destination buffer.
 212 */
 213size_t strlcat(char *dest, const char *src, size_t count)
 214{
 215        size_t dsize = strlen(dest);
 216        size_t len = strlen(src);
 217        size_t res = dsize + len;
 218
 219        /* This would be a bug */
 220        BUG_ON(dsize >= count);
 221
 222        dest += dsize;
 223        count -= dsize;
 224        if (len >= count)
 225                len = count-1;
 226        memcpy(dest, src, len);
 227        dest[len] = 0;
 228        return res;
 229}
 230EXPORT_SYMBOL(strlcat);
 231#endif
 232
 233#ifndef __HAVE_ARCH_STRCMP
 234/**
 235 * strcmp - Compare two strings
 236 * @cs: One string
 237 * @ct: Another string
 238 */
 239#undef strcmp
 240int strcmp(const char *cs, const char *ct)
 241{
 242        unsigned char c1, c2;
 243
 244        while (1) {
 245                c1 = *cs++;
 246                c2 = *ct++;
 247                if (c1 != c2)
 248                        return c1 < c2 ? -1 : 1;
 249                if (!c1)
 250                        break;
 251        }
 252        return 0;
 253}
 254EXPORT_SYMBOL(strcmp);
 255#endif
 256
 257#ifndef __HAVE_ARCH_STRNCMP
 258/**
 259 * strncmp - Compare two length-limited strings
 260 * @cs: One string
 261 * @ct: Another string
 262 * @count: The maximum number of bytes to compare
 263 */
 264int strncmp(const char *cs, const char *ct, size_t count)
 265{
 266        unsigned char c1, c2;
 267
 268        while (count) {
 269                c1 = *cs++;
 270                c2 = *ct++;
 271                if (c1 != c2)
 272                        return c1 < c2 ? -1 : 1;
 273                if (!c1)
 274                        break;
 275                count--;
 276        }
 277        return 0;
 278}
 279EXPORT_SYMBOL(strncmp);
 280#endif
 281
 282#ifndef __HAVE_ARCH_STRCHR
 283/**
 284 * strchr - Find the first occurrence of a character in a string
 285 * @s: The string to be searched
 286 * @c: The character to search for
 287 */
 288char *strchr(const char *s, int c)
 289{
 290        for (; *s != (char)c; ++s)
 291                if (*s == '\0')
 292                        return NULL;
 293        return (char *)s;
 294}
 295EXPORT_SYMBOL(strchr);
 296#endif
 297
 298#ifndef __HAVE_ARCH_STRCHRNUL
 299/**
 300 * strchrnul - Find and return a character in a string, or end of string
 301 * @s: The string to be searched
 302 * @c: The character to search for
 303 *
 304 * Returns pointer to first occurrence of 'c' in s. If c is not found, then
 305 * return a pointer to the null byte at the end of s.
 306 */
 307char *strchrnul(const char *s, int c)
 308{
 309        while (*s && *s != (char)c)
 310                s++;
 311        return (char *)s;
 312}
 313EXPORT_SYMBOL(strchrnul);
 314#endif
 315
 316#ifndef __HAVE_ARCH_STRRCHR
 317/**
 318 * strrchr - Find the last occurrence of a character in a string
 319 * @s: The string to be searched
 320 * @c: The character to search for
 321 */
 322char *strrchr(const char *s, int c)
 323{
 324       const char *p = s + strlen(s);
 325       do {
 326           if (*p == (char)c)
 327               return (char *)p;
 328       } while (--p >= s);
 329       return NULL;
 330}
 331EXPORT_SYMBOL(strrchr);
 332#endif
 333
 334#ifndef __HAVE_ARCH_STRNCHR
 335/**
 336 * strnchr - Find a character in a length limited string
 337 * @s: The string to be searched
 338 * @count: The number of characters to be searched
 339 * @c: The character to search for
 340 */
 341char *strnchr(const char *s, size_t count, int c)
 342{
 343        for (; count-- && *s != '\0'; ++s)
 344                if (*s == (char)c)
 345                        return (char *)s;
 346        return NULL;
 347}
 348EXPORT_SYMBOL(strnchr);
 349#endif
 350
 351/**
 352 * skip_spaces - Removes leading whitespace from @str.
 353 * @str: The string to be stripped.
 354 *
 355 * Returns a pointer to the first non-whitespace character in @str.
 356 */
 357char *skip_spaces(const char *str)
 358{
 359        while (isspace(*str))
 360                ++str;
 361        return (char *)str;
 362}
 363EXPORT_SYMBOL(skip_spaces);
 364
 365/**
 366 * strim - Removes leading and trailing whitespace from @s.
 367 * @s: The string to be stripped.
 368 *
 369 * Note that the first trailing whitespace is replaced with a %NUL-terminator
 370 * in the given string @s. Returns a pointer to the first non-whitespace
 371 * character in @s.
 372 */
 373char *strim(char *s)
 374{
 375        size_t size;
 376        char *end;
 377
 378        size = strlen(s);
 379        if (!size)
 380                return s;
 381
 382        end = s + size - 1;
 383        while (end >= s && isspace(*end))
 384                end--;
 385        *(end + 1) = '\0';
 386
 387        return skip_spaces(s);
 388}
 389EXPORT_SYMBOL(strim);
 390
 391#ifndef __HAVE_ARCH_STRLEN
 392/**
 393 * strlen - Find the length of a string
 394 * @s: The string to be sized
 395 */
 396size_t strlen(const char *s)
 397{
 398        const char *sc;
 399
 400        for (sc = s; *sc != '\0'; ++sc)
 401                /* nothing */;
 402        return sc - s;
 403}
 404EXPORT_SYMBOL(strlen);
 405#endif
 406
 407#ifndef __HAVE_ARCH_STRNLEN
 408/**
 409 * strnlen - Find the length of a length-limited string
 410 * @s: The string to be sized
 411 * @count: The maximum number of bytes to search
 412 */
 413size_t strnlen(const char *s, size_t count)
 414{
 415        const char *sc;
 416
 417        for (sc = s; count-- && *sc != '\0'; ++sc)
 418                /* nothing */;
 419        return sc - s;
 420}
 421EXPORT_SYMBOL(strnlen);
 422#endif
 423
 424#ifndef __HAVE_ARCH_STRSPN
 425/**
 426 * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
 427 * @s: The string to be searched
 428 * @accept: The string to search for
 429 */
 430size_t strspn(const char *s, const char *accept)
 431{
 432        const char *p;
 433        const char *a;
 434        size_t count = 0;
 435
 436        for (p = s; *p != '\0'; ++p) {
 437                for (a = accept; *a != '\0'; ++a) {
 438                        if (*p == *a)
 439                                break;
 440                }
 441                if (*a == '\0')
 442                        return count;
 443                ++count;
 444        }
 445        return count;
 446}
 447
 448EXPORT_SYMBOL(strspn);
 449#endif
 450
 451#ifndef __HAVE_ARCH_STRCSPN
 452/**
 453 * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
 454 * @s: The string to be searched
 455 * @reject: The string to avoid
 456 */
 457size_t strcspn(const char *s, const char *reject)
 458{
 459        const char *p;
 460        const char *r;
 461        size_t count = 0;
 462
 463        for (p = s; *p != '\0'; ++p) {
 464                for (r = reject; *r != '\0'; ++r) {
 465                        if (*p == *r)
 466                                return count;
 467                }
 468                ++count;
 469        }
 470        return count;
 471}
 472EXPORT_SYMBOL(strcspn);
 473#endif
 474
 475#ifndef __HAVE_ARCH_STRPBRK
 476/**
 477 * strpbrk - Find the first occurrence of a set of characters
 478 * @cs: The string to be searched
 479 * @ct: The characters to search for
 480 */
 481char *strpbrk(const char *cs, const char *ct)
 482{
 483        const char *sc1, *sc2;
 484
 485        for (sc1 = cs; *sc1 != '\0'; ++sc1) {
 486                for (sc2 = ct; *sc2 != '\0'; ++sc2) {
 487                        if (*sc1 == *sc2)
 488                                return (char *)sc1;
 489                }
 490        }
 491        return NULL;
 492}
 493EXPORT_SYMBOL(strpbrk);
 494#endif
 495
 496#ifndef __HAVE_ARCH_STRSEP
 497/**
 498 * strsep - Split a string into tokens
 499 * @s: The string to be searched
 500 * @ct: The characters to search for
 501 *
 502 * strsep() updates @s to point after the token, ready for the next call.
 503 *
 504 * It returns empty tokens, too, behaving exactly like the libc function
 505 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
 506 * Same semantics, slimmer shape. ;)
 507 */
 508char *strsep(char **s, const char *ct)
 509{
 510        char *sbegin = *s;
 511        char *end;
 512
 513        if (sbegin == NULL)
 514                return NULL;
 515
 516        end = strpbrk(sbegin, ct);
 517        if (end)
 518                *end++ = '\0';
 519        *s = end;
 520        return sbegin;
 521}
 522EXPORT_SYMBOL(strsep);
 523#endif
 524
 525/**
 526 * sysfs_streq - return true if strings are equal, modulo trailing newline
 527 * @s1: one string
 528 * @s2: another string
 529 *
 530 * This routine returns true iff two strings are equal, treating both
 531 * NUL and newline-then-NUL as equivalent string terminations.  It's
 532 * geared for use with sysfs input strings, which generally terminate
 533 * with newlines but are compared against values without newlines.
 534 */
 535bool sysfs_streq(const char *s1, const char *s2)
 536{
 537        while (*s1 && *s1 == *s2) {
 538                s1++;
 539                s2++;
 540        }
 541
 542        if (*s1 == *s2)
 543                return true;
 544        if (!*s1 && *s2 == '\n' && !s2[1])
 545                return true;
 546        if (*s1 == '\n' && !s1[1] && !*s2)
 547                return true;
 548        return false;
 549}
 550EXPORT_SYMBOL(sysfs_streq);
 551
 552/**
 553 * strtobool - convert common user inputs into boolean values
 554 * @s: input string
 555 * @res: result
 556 *
 557 * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
 558 * Otherwise it will return -EINVAL.  Value pointed to by res is
 559 * updated upon finding a match.
 560 */
 561int strtobool(const char *s, bool *res)
 562{
 563        switch (s[0]) {
 564        case 'y':
 565        case 'Y':
 566        case '1':
 567                *res = true;
 568                break;
 569        case 'n':
 570        case 'N':
 571        case '0':
 572                *res = false;
 573                break;
 574        default:
 575                return -EINVAL;
 576        }
 577        return 0;
 578}
 579EXPORT_SYMBOL(strtobool);
 580
 581#ifndef __HAVE_ARCH_MEMSET
 582/**
 583 * memset - Fill a region of memory with the given value
 584 * @s: Pointer to the start of the area.
 585 * @c: The byte to fill the area with
 586 * @count: The size of the area.
 587 *
 588 * Do not use memset() to access IO space, use memset_io() instead.
 589 */
 590void *memset(void *s, int c, size_t count)
 591{
 592        char *xs = s;
 593
 594        while (count--)
 595                *xs++ = c;
 596        return s;
 597}
 598EXPORT_SYMBOL(memset);
 599#endif
 600
 601/**
 602 * memzero_explicit - Fill a region of memory (e.g. sensitive
 603 *                    keying data) with 0s.
 604 * @s: Pointer to the start of the area.
 605 * @count: The size of the area.
 606 *
 607 * memzero_explicit() doesn't need an arch-specific version as
 608 * it just invokes the one of memset() implicitly.
 609 */
 610void memzero_explicit(void *s, size_t count)
 611{
 612        memset(s, 0, count);
 613        OPTIMIZER_HIDE_VAR(s);
 614}
 615EXPORT_SYMBOL(memzero_explicit);
 616
 617#ifndef __HAVE_ARCH_MEMCPY
 618/**
 619 * memcpy - Copy one area of memory to another
 620 * @dest: Where to copy to
 621 * @src: Where to copy from
 622 * @count: The size of the area.
 623 *
 624 * You should not use this function to access IO space, use memcpy_toio()
 625 * or memcpy_fromio() instead.
 626 */
 627void *memcpy(void *dest, const void *src, size_t count)
 628{
 629        char *tmp = dest;
 630        const char *s = src;
 631
 632        while (count--)
 633                *tmp++ = *s++;
 634        return dest;
 635}
 636EXPORT_SYMBOL(memcpy);
 637#endif
 638
 639#ifndef __HAVE_ARCH_MEMMOVE
 640/**
 641 * memmove - Copy one area of memory to another
 642 * @dest: Where to copy to
 643 * @src: Where to copy from
 644 * @count: The size of the area.
 645 *
 646 * Unlike memcpy(), memmove() copes with overlapping areas.
 647 */
 648void *memmove(void *dest, const void *src, size_t count)
 649{
 650        char *tmp;
 651        const char *s;
 652
 653        if (dest <= src) {
 654                tmp = dest;
 655                s = src;
 656                while (count--)
 657                        *tmp++ = *s++;
 658        } else {
 659                tmp = dest;
 660                tmp += count;
 661                s = src;
 662                s += count;
 663                while (count--)
 664                        *--tmp = *--s;
 665        }
 666        return dest;
 667}
 668EXPORT_SYMBOL(memmove);
 669#endif
 670
 671#ifndef __HAVE_ARCH_MEMCMP
 672/**
 673 * memcmp - Compare two areas of memory
 674 * @cs: One area of memory
 675 * @ct: Another area of memory
 676 * @count: The size of the area.
 677 */
 678#undef memcmp
 679__visible int memcmp(const void *cs, const void *ct, size_t count)
 680{
 681        const unsigned char *su1, *su2;
 682        int res = 0;
 683
 684        for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
 685                if ((res = *su1 - *su2) != 0)
 686                        break;
 687        return res;
 688}
 689EXPORT_SYMBOL(memcmp);
 690#endif
 691
 692#ifndef __HAVE_ARCH_MEMSCAN
 693/**
 694 * memscan - Find a character in an area of memory.
 695 * @addr: The memory area
 696 * @c: The byte to search for
 697 * @size: The size of the area.
 698 *
 699 * returns the address of the first occurrence of @c, or 1 byte past
 700 * the area if @c is not found
 701 */
 702void *memscan(void *addr, int c, size_t size)
 703{
 704        unsigned char *p = addr;
 705
 706        while (size) {
 707                if (*p == c)
 708                        return (void *)p;
 709                p++;
 710                size--;
 711        }
 712        return (void *)p;
 713}
 714EXPORT_SYMBOL(memscan);
 715#endif
 716
 717#ifndef __HAVE_ARCH_STRSTR
 718/**
 719 * strstr - Find the first substring in a %NUL terminated string
 720 * @s1: The string to be searched
 721 * @s2: The string to search for
 722 */
 723char *strstr(const char *s1, const char *s2)
 724{
 725        size_t l1, l2;
 726
 727        l2 = strlen(s2);
 728        if (!l2)
 729                return (char *)s1;
 730        l1 = strlen(s1);
 731        while (l1 >= l2) {
 732                l1--;
 733                if (!memcmp(s1, s2, l2))
 734                        return (char *)s1;
 735                s1++;
 736        }
 737        return NULL;
 738}
 739EXPORT_SYMBOL(strstr);
 740#endif
 741
 742#ifndef __HAVE_ARCH_STRNSTR
 743/**
 744 * strnstr - Find the first substring in a length-limited string
 745 * @s1: The string to be searched
 746 * @s2: The string to search for
 747 * @len: the maximum number of characters to search
 748 */
 749char *strnstr(const char *s1, const char *s2, size_t len)
 750{
 751        size_t l2;
 752
 753        l2 = strlen(s2);
 754        if (!l2)
 755                return (char *)s1;
 756        while (len >= l2) {
 757                len--;
 758                if (!memcmp(s1, s2, l2))
 759                        return (char *)s1;
 760                s1++;
 761        }
 762        return NULL;
 763}
 764EXPORT_SYMBOL(strnstr);
 765#endif
 766
 767#ifndef __HAVE_ARCH_MEMCHR
 768/**
 769 * memchr - Find a character in an area of memory.
 770 * @s: The memory area
 771 * @c: The byte to search for
 772 * @n: The size of the area.
 773 *
 774 * returns the address of the first occurrence of @c, or %NULL
 775 * if @c is not found
 776 */
 777void *memchr(const void *s, int c, size_t n)
 778{
 779        const unsigned char *p = s;
 780        while (n-- != 0) {
 781                if ((unsigned char)c == *p++) {
 782                        return (void *)(p - 1);
 783                }
 784        }
 785        return NULL;
 786}
 787EXPORT_SYMBOL(memchr);
 788#endif
 789
 790static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
 791{
 792        while (bytes) {
 793                if (*start != value)
 794                        return (void *)start;
 795                start++;
 796                bytes--;
 797        }
 798        return NULL;
 799}
 800
 801/**
 802 * memchr_inv - Find an unmatching character in an area of memory.
 803 * @start: The memory area
 804 * @c: Find a character other than c
 805 * @bytes: The size of the area.
 806 *
 807 * returns the address of the first character other than @c, or %NULL
 808 * if the whole buffer contains just @c.
 809 */
 810void *memchr_inv(const void *start, int c, size_t bytes)
 811{
 812        u8 value = c;
 813        u64 value64;
 814        unsigned int words, prefix;
 815
 816        if (bytes <= 16)
 817                return check_bytes8(start, value, bytes);
 818
 819        value64 = value;
 820#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
 821        value64 *= 0x0101010101010101;
 822#elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER)
 823        value64 *= 0x01010101;
 824        value64 |= value64 << 32;
 825#else
 826        value64 |= value64 << 8;
 827        value64 |= value64 << 16;
 828        value64 |= value64 << 32;
 829#endif
 830
 831        prefix = (unsigned long)start % 8;
 832        if (prefix) {
 833                u8 *r;
 834
 835                prefix = 8 - prefix;
 836                r = check_bytes8(start, value, prefix);
 837                if (r)
 838                        return r;
 839                start += prefix;
 840                bytes -= prefix;
 841        }
 842
 843        words = bytes / 8;
 844
 845        while (words) {
 846                if (*(u64 *)start != value64)
 847                        return check_bytes8(start, value, 8);
 848                start += 8;
 849                words--;
 850        }
 851
 852        return check_bytes8(start, value, bytes % 8);
 853}
 854EXPORT_SYMBOL(memchr_inv);
 855
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.