123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * linux/tools/lib/string.c
- *
- * Copied from linux/lib/string.c, where it is:
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * More specifically, the first copied function was strtobool, which
- * was introduced by:
- *
- * d0f1fed29e6e ("Add a strtobool function matching semantics of existing in kernel equivalents")
- * Author: Jonathan Cameron <[email protected]>
- */
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <linux/string.h>
- #include <linux/ctype.h>
- #include <linux/compiler.h>
- /**
- * memdup - duplicate region of memory
- *
- * @src: memory region to duplicate
- * @len: memory region length
- */
- void *memdup(const void *src, size_t len)
- {
- void *p = malloc(len);
- if (p)
- memcpy(p, src, len);
- return p;
- }
- /**
- * 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', or
- * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value
- * pointed to by res is updated upon finding a match.
- */
- int strtobool(const char *s, bool *res)
- {
- if (!s)
- return -EINVAL;
- switch (s[0]) {
- case 'y':
- case 'Y':
- case '1':
- *res = true;
- return 0;
- case 'n':
- case 'N':
- case '0':
- *res = false;
- return 0;
- case 'o':
- case 'O':
- switch (s[1]) {
- case 'n':
- case 'N':
- *res = true;
- return 0;
- case 'f':
- case 'F':
- *res = false;
- return 0;
- default:
- break;
- }
- default:
- break;
- }
- return -EINVAL;
- }
- /**
- * strlcpy - Copy a C-string into a sized buffer
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- * @size: size of destination buffer
- *
- * Compatible with *BSD: the result is always a valid
- * NUL-terminated string that fits in the buffer (unless,
- * of course, the buffer size is zero). It does not pad
- * out the result like strncpy() does.
- *
- * If libc has strlcpy() then that version will override this
- * implementation:
- */
- #ifdef __clang__
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wignored-attributes"
- #endif
- size_t __weak strlcpy(char *dest, const char *src, size_t size)
- {
- size_t ret = strlen(src);
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
- memcpy(dest, src, len);
- dest[len] = '\0';
- }
- return ret;
- }
- #ifdef __clang__
- #pragma clang diagnostic pop
- #endif
- /**
- * skip_spaces - Removes leading whitespace from @str.
- * @str: The string to be stripped.
- *
- * Returns a pointer to the first non-whitespace character in @str.
- */
- char *skip_spaces(const char *str)
- {
- while (isspace(*str))
- ++str;
- return (char *)str;
- }
- /**
- * strim - Removes leading and trailing whitespace from @s.
- * @s: The string to be stripped.
- *
- * Note that the first trailing whitespace is replaced with a %NUL-terminator
- * in the given string @s. Returns a pointer to the first non-whitespace
- * character in @s.
- */
- char *strim(char *s)
- {
- size_t size;
- char *end;
- size = strlen(s);
- if (!size)
- return s;
- end = s + size - 1;
- while (end >= s && isspace(*end))
- end--;
- *(end + 1) = '\0';
- return skip_spaces(s);
- }
- /**
- * strreplace - Replace all occurrences of character in string.
- * @s: The string to operate on.
- * @old: The character being replaced.
- * @new: The character @old is replaced with.
- *
- * Returns pointer to the nul byte at the end of @s.
- */
- char *strreplace(char *s, char old, char new)
- {
- for (; *s; ++s)
- if (*s == old)
- *s = new;
- return s;
- }
- 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;
- value64 |= value64 << 8;
- value64 |= value64 << 16;
- value64 |= value64 << 32;
- 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);
- }
|