Line data Source code
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 : */
37 17 : int 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 17 : if (!len)
43 : return 0;
44 :
45 : do {
46 26 : c1 = *s1++;
47 26 : c2 = *s2++;
48 26 : if (!c1 || !c2)
49 : break;
50 20 : if (c1 == c2)
51 9 : continue;
52 : c1 = tolower(c1);
53 : c2 = tolower(c2);
54 11 : if (c1 != c2)
55 : break;
56 9 : } while (--len);
57 17 : return (int)c1 - (int)c2;
58 : }
59 : EXPORT_SYMBOL(strncasecmp);
60 : #endif
61 : #ifndef __HAVE_ARCH_STRNICMP
62 : #undef strnicmp
63 0 : int strnicmp(const char *s1, const char *s2, size_t len)
64 : {
65 0 : return strncasecmp(s1, s2, len);
66 : }
67 : EXPORT_SYMBOL(strnicmp);
68 : #endif
69 :
70 : #ifndef __HAVE_ARCH_STRCASECMP
71 352 : int strcasecmp(const char *s1, const char *s2)
72 : {
73 : int c1, c2;
74 :
75 : do {
76 1556 : c1 = tolower(*s1++);
77 1556 : c2 = tolower(*s2++);
78 778 : } while (c1 == c2 && c1 != 0);
79 352 : return c1 - c2;
80 : }
81 : EXPORT_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
91 3443 : char *strcpy(char *dest, const char *src)
92 : {
93 : char *tmp = dest;
94 :
95 3443 : while ((*dest++ = *src++) != '\0')
96 : /* nothing */;
97 3443 : return tmp;
98 : }
99 : EXPORT_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 : */
116 8078 : char *strncpy(char *dest, const char *src, size_t count)
117 : {
118 : char *tmp = dest;
119 :
120 123232 : while (count) {
121 107076 : if ((*tmp = *src) != 0)
122 50159 : src++;
123 107076 : tmp++;
124 107076 : count--;
125 : }
126 8078 : return dest;
127 : }
128 : EXPORT_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 : */
143 31598 : size_t strlcpy(char *dest, const char *src, size_t size)
144 : {
145 : size_t ret = strlen(src);
146 :
147 31598 : if (size) {
148 31598 : size_t len = (ret >= size) ? size - 1 : ret;
149 31598 : memcpy(dest, src, len);
150 31598 : dest[len] = '\0';
151 : }
152 31598 : return ret;
153 : }
154 : EXPORT_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
164 1 : char *strcat(char *dest, const char *src)
165 : {
166 : char *tmp = dest;
167 :
168 2 : while (*dest)
169 0 : dest++;
170 13 : while ((*dest++ = *src++) != '\0')
171 : ;
172 1 : return tmp;
173 : }
174 : EXPORT_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 : */
187 0 : char *strncat(char *dest, const char *src, size_t count)
188 : {
189 : char *tmp = dest;
190 :
191 0 : if (count) {
192 0 : while (*dest)
193 0 : dest++;
194 0 : while ((*dest++ = *src++) != 0) {
195 0 : if (--count == 0) {
196 0 : *dest = '\0';
197 0 : break;
198 : }
199 : }
200 : }
201 0 : return tmp;
202 : }
203 : EXPORT_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 : */
213 17 : size_t strlcat(char *dest, const char *src, size_t count)
214 : {
215 : size_t dsize = strlen(dest);
216 : size_t len = strlen(src);
217 17 : size_t res = dsize + len;
218 :
219 : /* This would be a bug */
220 : BUG_ON(dsize >= count);
221 :
222 17 : dest += dsize;
223 17 : count -= dsize;
224 17 : if (len >= count)
225 0 : len = count-1;
226 17 : memcpy(dest, src, len);
227 17 : dest[len] = 0;
228 17 : return res;
229 : }
230 : EXPORT_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
240 884007 : int strcmp(const char *cs, const char *ct)
241 : {
242 : unsigned char c1, c2;
243 :
244 : while (1) {
245 22919537 : c1 = *cs++;
246 22919537 : c2 = *ct++;
247 22919537 : if (c1 != c2)
248 781141 : return c1 < c2 ? -1 : 1;
249 22138396 : if (!c1)
250 : break;
251 : }
252 : return 0;
253 : }
254 : EXPORT_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 : */
264 54276 : int strncmp(const char *cs, const char *ct, size_t count)
265 : {
266 : unsigned char c1, c2;
267 :
268 273064 : while (count) {
269 206065 : c1 = *cs++;
270 206065 : c2 = *ct++;
271 206065 : if (c1 != c2)
272 21463 : return c1 < c2 ? -1 : 1;
273 184602 : if (!c1)
274 : break;
275 164512 : count--;
276 : }
277 : return 0;
278 : }
279 : EXPORT_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 : */
288 : char *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 : }
295 : EXPORT_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 : */
307 21 : char *strchrnul(const char *s, int c)
308 : {
309 191 : while (*s && *s != (char)c)
310 149 : s++;
311 21 : return (char *)s;
312 : }
313 : EXPORT_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 : */
322 : char *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 : }
331 : EXPORT_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 : */
341 1 : char *strnchr(const char *s, size_t count, int c)
342 : {
343 4 : for (; count-- && *s != '\0'; ++s)
344 4 : if (*s == (char)c)
345 : return (char *)s;
346 : return NULL;
347 : }
348 : EXPORT_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 : */
357 239 : char *skip_spaces(const char *str)
358 : {
359 508 : while (isspace(*str))
360 16 : ++str;
361 239 : return (char *)str;
362 : }
363 : EXPORT_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 : */
373 14 : char *strim(char *s)
374 : {
375 : size_t size;
376 : char *end;
377 :
378 : size = strlen(s);
379 14 : if (!size)
380 : return s;
381 :
382 14 : end = s + size - 1;
383 39 : while (end >= s && isspace(*end))
384 11 : end--;
385 14 : *(end + 1) = '\0';
386 :
387 : return skip_spaces(s);
388 : }
389 : EXPORT_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 : */
396 132753 : size_t strlen(const char *s)
397 : {
398 : const char *sc;
399 :
400 289752 : for (sc = s; *sc != '\0'; ++sc)
401 : /* nothing */;
402 164403 : return sc - s;
403 : }
404 : EXPORT_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 : */
413 56045 : size_t strnlen(const char *s, size_t count)
414 : {
415 : const char *sc;
416 :
417 56045 : for (sc = s; count-- && *sc != '\0'; ++sc)
418 : /* nothing */;
419 56045 : return sc - s;
420 : }
421 : EXPORT_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 : */
430 0 : size_t strspn(const char *s, const char *accept)
431 : {
432 : const char *p;
433 : const char *a;
434 : size_t count = 0;
435 :
436 0 : for (p = s; *p != '\0'; ++p) {
437 0 : for (a = accept; *a != '\0'; ++a) {
438 0 : if (*p == *a)
439 : break;
440 : }
441 0 : if (*a == '\0')
442 : return count;
443 0 : ++count;
444 : }
445 : return count;
446 : }
447 :
448 : EXPORT_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 : */
457 48 : size_t strcspn(const char *s, const char *reject)
458 : {
459 : const char *p;
460 : const char *r;
461 : size_t count = 0;
462 :
463 386 : for (p = s; *p != '\0'; ++p) {
464 487 : for (r = reject; *r != '\0'; ++r) {
465 522 : if (*p == *r)
466 : return count;
467 : }
468 338 : ++count;
469 : }
470 : return count;
471 : }
472 : EXPORT_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 : */
481 0 : char *strpbrk(const char *cs, const char *ct)
482 : {
483 : const char *sc1, *sc2;
484 :
485 57 : for (sc1 = cs; *sc1 != '\0'; ++sc1) {
486 57 : for (sc2 = ct; *sc2 != '\0'; ++sc2) {
487 62 : if (*sc1 == *sc2)
488 : return (char *)sc1;
489 : }
490 : }
491 : return NULL;
492 : }
493 : EXPORT_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 : */
508 17 : char *strsep(char **s, const char *ct)
509 : {
510 17 : char *sbegin = *s;
511 : char *end;
512 :
513 17 : if (sbegin == NULL)
514 : return NULL;
515 :
516 : end = strpbrk(sbegin, ct);
517 10 : if (end)
518 5 : *end++ = '\0';
519 10 : *s = end;
520 10 : return sbegin;
521 : }
522 : EXPORT_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 : */
535 0 : bool sysfs_streq(const char *s1, const char *s2)
536 : {
537 0 : while (*s1 && *s1 == *s2) {
538 0 : s1++;
539 0 : s2++;
540 : }
541 :
542 0 : if (*s1 == *s2)
543 : return true;
544 0 : if (!*s1 && *s2 == '\n' && !s2[1])
545 : return true;
546 0 : if (*s1 == '\n' && !s1[1] && !*s2)
547 : return true;
548 0 : return false;
549 : }
550 : EXPORT_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 : */
561 0 : int strtobool(const char *s, bool *res)
562 : {
563 0 : switch (s[0]) {
564 : case 'y':
565 : case 'Y':
566 : case '1':
567 0 : *res = true;
568 0 : break;
569 : case 'n':
570 : case 'N':
571 : case '0':
572 0 : *res = false;
573 0 : break;
574 : default:
575 : return -EINVAL;
576 : }
577 : return 0;
578 : }
579 : EXPORT_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 : */
590 : void *memset(void *s, int c, size_t count)
591 : {
592 : char *xs = s;
593 :
594 : while (count--)
595 : *xs++ = c;
596 : return s;
597 : }
598 : EXPORT_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 : */
610 17071 : void memzero_explicit(void *s, size_t count)
611 : {
612 17071 : memset(s, 0, count);
613 17071 : OPTIMIZER_HIDE_VAR(s);
614 17071 : }
615 : EXPORT_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 : */
627 : void *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 : }
636 : EXPORT_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 : */
648 : void *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 : }
668 : EXPORT_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 : }
689 : EXPORT_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 : */
702 0 : void *memscan(void *addr, int c, size_t size)
703 : {
704 : unsigned char *p = addr;
705 :
706 0 : while (size) {
707 0 : if (*p == c)
708 : return (void *)p;
709 0 : p++;
710 0 : size--;
711 : }
712 : return (void *)p;
713 : }
714 : EXPORT_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 : */
723 2 : char *strstr(const char *s1, const char *s2)
724 : {
725 : size_t l1, l2;
726 :
727 : l2 = strlen(s2);
728 2 : if (!l2)
729 : return (char *)s1;
730 : l1 = strlen(s1);
731 444 : while (l1 >= l2) {
732 440 : l1--;
733 440 : if (!memcmp(s1, s2, l2))
734 : return (char *)s1;
735 440 : s1++;
736 : }
737 : return NULL;
738 : }
739 : EXPORT_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 : */
749 0 : char *strnstr(const char *s1, const char *s2, size_t len)
750 : {
751 : size_t l2;
752 :
753 : l2 = strlen(s2);
754 0 : if (!l2)
755 : return (char *)s1;
756 0 : while (len >= l2) {
757 0 : len--;
758 0 : if (!memcmp(s1, s2, l2))
759 : return (char *)s1;
760 0 : s1++;
761 : }
762 : return NULL;
763 : }
764 : EXPORT_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 : */
777 : void *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 : }
787 : EXPORT_SYMBOL(memchr);
788 : #endif
789 :
790 : static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
791 : {
792 0 : while (bytes) {
793 0 : if (*start != value)
794 : return (void *)start;
795 0 : start++;
796 0 : 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 : */
810 0 : void *memchr_inv(const void *start, int c, size_t bytes)
811 : {
812 0 : u8 value = c;
813 : u64 value64;
814 : unsigned int words, prefix;
815 :
816 0 : if (bytes <= 16)
817 0 : return check_bytes8(start, value, bytes);
818 :
819 0 : 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 0 : value64 |= value64 << 8;
827 0 : value64 |= value64 << 16;
828 0 : value64 |= value64 << 32;
829 : #endif
830 :
831 0 : prefix = (unsigned long)start % 8;
832 0 : if (prefix) {
833 : u8 *r;
834 :
835 0 : prefix = 8 - prefix;
836 : r = check_bytes8(start, value, prefix);
837 0 : if (r)
838 : return r;
839 0 : start += prefix;
840 0 : bytes -= prefix;
841 : }
842 :
843 0 : words = bytes / 8;
844 :
845 0 : while (words) {
846 0 : if (*(u64 *)start != value64)
847 0 : return check_bytes8(start, value, 8);
848 0 : start += 8;
849 0 : words--;
850 : }
851 :
852 0 : return check_bytes8(start, value, bytes % 8);
853 : }
854 : EXPORT_SYMBOL(memchr_inv);
|