if (sbegin == NULL) return NULL; end = strpbrk(sbegin, ct); if (end) *end++ = '\0'; *s = end; return sbegin;}EXPORT_SYMBOL(strsep);#endif /** * sysfs_streq - return true if strings are equal, modulo trailing newline * @s1: one string * @s2: another string * * This routine returns true iff two strings are equal, treating both * NUL and newline-then-NUL as equivalent string terminations. It's * geared for use with sysfs input strings, which generally terminate * with newlines but are compared against values without newlines. */bool sysfs_streq(const char *s1, const char *s2){ while (*s1 && *s1 == *s2) { s1++; s2++; } if (*s1 == *s2) return true; if (!*s1 && *s2 == '\n' && !s2[1]) return true; if (*s1 == '\n' && !s1[1] && !*s2) return true; return false;}EXPORT_SYMBOL(sysfs_streq); /** * strtobool - convert common user inputs into boolean values * @s: input string * @res: result * * This routine returns 0 iff the first character is one of 'Yy1Nn0'. * Otherwise it will return -EINVAL. Value pointed to by res is * updated upon finding a match. */int strtobool(const char *s, bool *res){ switch (s[0]) { case 'y': case 'Y': case '1': *res = true; break; case 'n': case 'N': case '0': *res = false; break; default: return -EINVAL; } return 0;}EXPORT_SYMBOL(strtobool); #ifndef __HAVE_ARCH_MEMSET/** * memset - Fill a region of memory with the given value * @s: Pointer to the start of the area. * @c: The byte to fill the area with * @count: The size of the area. * * Do not use memset() to access IO space, use memset_io() instead. */void *memset(void *s, int c, size_t count){ char *xs = s; while (count--) *xs++ = c; return s;}EXPORT_SYMBOL(memset);#endif #ifndef __HAVE_ARCH_MEMCPY/** * memcpy - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */void *memcpy(void *dest, const void *src, size_t count){ char *tmp = dest; const char *s = src; while (count--) *tmp++ = *s++; return dest;}EXPORT_SYMBOL(memcpy);#endif #ifndef __HAVE_ARCH_MEMMOVE/** * memmove - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * Unlike memcpy(), memmove() copes with overlapping areas. */void *memmove(void *dest, const void *src, size_t count){ char *tmp; const char *s; if (dest <= src) { tmp = dest; s = src; while (count--) *tmp++ = *s++; } else { tmp = dest; tmp += count; s = src; s += count; while (count--) *--tmp = *--s; } return dest;}EXPORT_SYMBOL(memmove);#endif #ifndef __HAVE_ARCH_MEMCMP/** * memcmp - Compare two areas of memory * @cs: One area of memory * @ct: Another area of memory * @count: The size of the area. */#undef memcmpint memcmp(const void *cs, const void *ct, size_t count){ const unsigned char *su1, *su2; int res = 0; for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res;}EXPORT_SYMBOL(memcmp);#endif #ifndef __HAVE_ARCH_MEMSCAN/** * memscan - Find a character in an area of memory. * @addr: The memory area * @c: The byte to search for * @size: The size of the area. * * returns the address of the first occurrence of @c, or 1 byte past * the area if @c is not found */void *memscan(void *addr, int c, size_t size){ unsigned char *p = addr; while (size) { if (*p == c) return (void *)p; p++; size--; } return (void *)p;}EXPORT_SYMBOL(memscan);#endif #ifndef __HAVE_ARCH_STRSTR/** * strstr - Find the first substring in a %NUL terminated string * @s1: The string to be searched * @s2: The string to search for */char *strstr(const char *s1, const char *s2){ size_t l1, l2; l2 = strlen(s2); if (!l2) return (char *)s1; l1 = strlen(s1); while (l1 >= l2) { l1--; if (!memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL;}EXPORT_SYMBOL(strstr);#endif #ifndef __HAVE_ARCH_STRNSTR/** * strnstr - Find the first substring in a length-limited string * @s1: The string to be searched * @s2: The string to search for * @len: the maximum number of characters to search */char *strnstr(const char *s1, const char *s2, size_t len){ size_t l2; l2 = strlen(s2); if (!l2) return (char *)s1; while (len >= l2) { len--; if (!memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL;}EXPORT_SYMBOL(strnstr);#endif #ifndef __HAVE_ARCH_MEMCHR/** * memchr - Find a character in an area of memory. * @s: The memory area * @c: The byte to search for * @n: The size of the area. * * returns the address of the first occurrence of @c, or %NULL * if @c is not found */void *memchr(const void *s, int c, size_t n){ const unsigned char *p = s; while (n-- != 0) { if ((unsigned char)c == *p++) { return (void *)(p - 1); } } return NULL;}EXPORT_SYMBOL(memchr);#endif static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes){ while (bytes) { if (*start != value) return (void *)start; start++; bytes--; } return NULL;} /** * memchr_inv - Find an unmatching character in an area of memory. * @start: The memory area * @c: Find a character other than c * @bytes: The size of the area. * * returns the address of the first character other than @c, or %NULL * if the whole buffer contains just @c. */void *memchr_inv(const void *start, int c, size_t bytes){ u8 value = c; u64 value64; unsigned int words, prefix; if (bytes <= 16) return check_bytes8(start, value, bytes); value64 = value;#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 value64 *= 0x0101010101010101;#elif defined(ARCH_HAS_FAST_MULTIPLIER) value64 *= 0x01010101; value64 |= value64 << 32;#else value64 |= value64 << 8; value64 |= value64 << 16; value64 |= value64 << 32;#endif prefix = (unsigned long)start % 8; if (prefix) { u8 *r; prefix = 8 - prefix; r = check_bytes8(start, value, prefix); if (r) return r; start += prefix; bytes -= prefix; } words = bytes / 8; while (words) { if (*(u64 *)start != value64) return check_bytes8(start, value, 8); start += 8; words--; } return check_bytes8(start, value, bytes % 8);}EXPORT_SYMBOL(memchr_inv);Lines 501–826 of 826. Previous lines
if (sbegin == NULL) return NULL; end = strpbrk(sbegin, ct); if (end) *end++ = '\0'; *s = end; return sbegin; } EXPORT_SYMBOL(strsep); #endif /** * sysfs_streq - return true if strings are equal, modulo trailing newline * @s1: one string * @s2: another string * * This routine returns true iff two strings are equal, treating both * NUL and newline-then-NUL as equivalent string terminations. It's * geared for use with sysfs input strings, which generally terminate * with newlines but are compared against values without newlines. */ bool sysfs_streq(const char *s1, const char *s2) { while (*s1 && *s1 == *s2) { s1++; s2++; } if (*s1 == *s2) return true; if (!*s1 && *s2 == '\n' && !s2[1]) return true; if (*s1 == '\n' && !s1[1] && !*s2) return true; return false; } EXPORT_SYMBOL(sysfs_streq); /** * strtobool - convert common user inputs into boolean values * @s: input string * @res: result * * This routine returns 0 iff the first character is one of 'Yy1Nn0'. * Otherwise it will return -EINVAL. Value pointed to by res is * updated upon finding a match. */ int strtobool(const char *s, bool *res) { switch (s[0]) { case 'y': case 'Y': case '1': *res = true; break; case 'n': case 'N': case '0': *res = false; break; default: return -EINVAL; } return 0; } EXPORT_SYMBOL(strtobool); #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value * @s: Pointer to the start of the area. * @c: The byte to fill the area with * @count: The size of the area. * * Do not use memset() to access IO space, use memset_io() instead. */ void *memset(void *s, int c, size_t count) { char *xs = s; while (count--) *xs++ = c; return s; } EXPORT_SYMBOL(memset); #endif #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ void *memcpy(void *dest, const void *src, size_t count) { char *tmp = dest; const char *s = src; while (count--) *tmp++ = *s++; return dest; } EXPORT_SYMBOL(memcpy); #endif #ifndef __HAVE_ARCH_MEMMOVE /** * memmove - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * Unlike memcpy(), memmove() copes with overlapping areas. */ void *memmove(void *dest, const void *src, size_t count) { char *tmp; const char *s; if (dest <= src) { tmp = dest; s = src; while (count--) *tmp++ = *s++; } else { tmp = dest; tmp += count; s = src; s += count; while (count--) *--tmp = *--s; } return dest; } EXPORT_SYMBOL(memmove); #endif #ifndef __HAVE_ARCH_MEMCMP /** * memcmp - Compare two areas of memory * @cs: One area of memory * @ct: Another area of memory * @count: The size of the area. */ #undef memcmp int memcmp(const void *cs, const void *ct, size_t count) { const unsigned char *su1, *su2; int res = 0; for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res; } EXPORT_SYMBOL(memcmp); #endif #ifndef __HAVE_ARCH_MEMSCAN /** * memscan - Find a character in an area of memory. * @addr: The memory area * @c: The byte to search for * @size: The size of the area. * * returns the address of the first occurrence of @c, or 1 byte past * the area if @c is not found */ void *memscan(void *addr, int c, size_t size) { unsigned char *p = addr; while (size) { if (*p == c) return (void *)p; p++; size--; } return (void *)p; } EXPORT_SYMBOL(memscan); #endif #ifndef __HAVE_ARCH_STRSTR /** * strstr - Find the first substring in a %NUL terminated string * @s1: The string to be searched * @s2: The string to search for */ char *strstr(const char *s1, const char *s2) { size_t l1, l2; l2 = strlen(s2); if (!l2) return (char *)s1; l1 = strlen(s1); while (l1 >= l2) { l1--; if (!memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL; } EXPORT_SYMBOL(strstr); #endif #ifndef __HAVE_ARCH_STRNSTR /** * strnstr - Find the first substring in a length-limited string * @s1: The string to be searched * @s2: The string to search for * @len: the maximum number of characters to search */ char *strnstr(const char *s1, const char *s2, size_t len) { size_t l2; l2 = strlen(s2); if (!l2) return (char *)s1; while (len >= l2) { len--; if (!memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL; } EXPORT_SYMBOL(strnstr); #endif #ifndef __HAVE_ARCH_MEMCHR /** * memchr - Find a character in an area of memory. * @s: The memory area * @c: The byte to search for * @n: The size of the area. * * returns the address of the first occurrence of @c, or %NULL * if @c is not found */ void *memchr(const void *s, int c, size_t n) { const unsigned char *p = s; while (n-- != 0) { if ((unsigned char)c == *p++) { return (void *)(p - 1); } } return NULL; } EXPORT_SYMBOL(memchr); #endif static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) { while (bytes) { if (*start != value) return (void *)start; start++; bytes--; } return NULL; } /** * memchr_inv - Find an unmatching character in an area of memory. * @start: The memory area * @c: Find a character other than c * @bytes: The size of the area. * * returns the address of the first character other than @c, or %NULL * if the whole buffer contains just @c. */ void *memchr_inv(const void *start, int c, size_t bytes) { u8 value = c; u64 value64; unsigned int words, prefix; if (bytes <= 16) return check_bytes8(start, value, bytes); value64 = value; #if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 value64 *= 0x0101010101010101; #elif defined(ARCH_HAS_FAST_MULTIPLIER) value64 *= 0x01010101; value64 |= value64 << 32; #else value64 |= value64 << 8; value64 |= value64 << 16; value64 |= value64 << 32; #endif prefix = (unsigned long)start % 8; if (prefix) { u8 *r; prefix = 8 - prefix; r = check_bytes8(start, value, prefix); if (r) return r; start += prefix; bytes -= prefix; } words = bytes / 8; while (words) { if (*(u64 *)start != value64) return check_bytes8(start, value, 8); start += 8; words--; } return check_bytes8(start, value, bytes % 8); } EXPORT_SYMBOL(memchr_inv);