149698745SVasily Gorbik // SPDX-License-Identifier: GPL-2.0 249698745SVasily Gorbik #include <linux/ctype.h> 349698745SVasily Gorbik #include <linux/kernel.h> 4d58106c3SVasily Gorbik #include <linux/errno.h> 57e0d92f0SVasily Gorbik #undef CONFIG_KASAN 649698745SVasily Gorbik #include "../lib/string.c" 749698745SVasily Gorbik 849698745SVasily Gorbik int strncmp(const char *cs, const char *ct, size_t count) 949698745SVasily Gorbik { 1049698745SVasily Gorbik unsigned char c1, c2; 1149698745SVasily Gorbik 1249698745SVasily Gorbik while (count) { 1349698745SVasily Gorbik c1 = *cs++; 1449698745SVasily Gorbik c2 = *ct++; 1549698745SVasily Gorbik if (c1 != c2) 1649698745SVasily Gorbik return c1 < c2 ? -1 : 1; 1749698745SVasily Gorbik if (!c1) 1849698745SVasily Gorbik break; 1949698745SVasily Gorbik count--; 2049698745SVasily Gorbik } 2149698745SVasily Gorbik return 0; 2249698745SVasily Gorbik } 2349698745SVasily Gorbik 2449698745SVasily Gorbik char *skip_spaces(const char *str) 2549698745SVasily Gorbik { 2649698745SVasily Gorbik while (isspace(*str)) 2749698745SVasily Gorbik ++str; 2849698745SVasily Gorbik return (char *)str; 2949698745SVasily Gorbik } 3049698745SVasily Gorbik 3149698745SVasily Gorbik char *strim(char *s) 3249698745SVasily Gorbik { 3349698745SVasily Gorbik size_t size; 3449698745SVasily Gorbik char *end; 3549698745SVasily Gorbik 3649698745SVasily Gorbik size = strlen(s); 3749698745SVasily Gorbik if (!size) 3849698745SVasily Gorbik return s; 3949698745SVasily Gorbik 4049698745SVasily Gorbik end = s + size - 1; 4149698745SVasily Gorbik while (end >= s && isspace(*end)) 4249698745SVasily Gorbik end--; 4349698745SVasily Gorbik *(end + 1) = '\0'; 4449698745SVasily Gorbik 4549698745SVasily Gorbik return skip_spaces(s); 4649698745SVasily Gorbik } 4749698745SVasily Gorbik 4849698745SVasily Gorbik /* Works only for digits and letters, but small and fast */ 4949698745SVasily Gorbik #define TOLOWER(x) ((x) | 0x20) 5049698745SVasily Gorbik 5149698745SVasily Gorbik static unsigned int simple_guess_base(const char *cp) 5249698745SVasily Gorbik { 5349698745SVasily Gorbik if (cp[0] == '0') { 5449698745SVasily Gorbik if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) 5549698745SVasily Gorbik return 16; 5649698745SVasily Gorbik else 5749698745SVasily Gorbik return 8; 5849698745SVasily Gorbik } else { 5949698745SVasily Gorbik return 10; 6049698745SVasily Gorbik } 6149698745SVasily Gorbik } 6249698745SVasily Gorbik 6349698745SVasily Gorbik /** 6449698745SVasily Gorbik * simple_strtoull - convert a string to an unsigned long long 6549698745SVasily Gorbik * @cp: The start of the string 6649698745SVasily Gorbik * @endp: A pointer to the end of the parsed string will be placed here 6749698745SVasily Gorbik * @base: The number base to use 6849698745SVasily Gorbik */ 6949698745SVasily Gorbik 7049698745SVasily Gorbik unsigned long long simple_strtoull(const char *cp, char **endp, 7149698745SVasily Gorbik unsigned int base) 7249698745SVasily Gorbik { 7349698745SVasily Gorbik unsigned long long result = 0; 7449698745SVasily Gorbik 7549698745SVasily Gorbik if (!base) 7649698745SVasily Gorbik base = simple_guess_base(cp); 7749698745SVasily Gorbik 7849698745SVasily Gorbik if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') 7949698745SVasily Gorbik cp += 2; 8049698745SVasily Gorbik 8149698745SVasily Gorbik while (isxdigit(*cp)) { 8249698745SVasily Gorbik unsigned int value; 8349698745SVasily Gorbik 8449698745SVasily Gorbik value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; 8549698745SVasily Gorbik if (value >= base) 8649698745SVasily Gorbik break; 8749698745SVasily Gorbik result = result * base + value; 8849698745SVasily Gorbik cp++; 8949698745SVasily Gorbik } 9049698745SVasily Gorbik if (endp) 9149698745SVasily Gorbik *endp = (char *)cp; 9249698745SVasily Gorbik 9349698745SVasily Gorbik return result; 9449698745SVasily Gorbik } 9549698745SVasily Gorbik 9649698745SVasily Gorbik long simple_strtol(const char *cp, char **endp, unsigned int base) 9749698745SVasily Gorbik { 9849698745SVasily Gorbik if (*cp == '-') 9949698745SVasily Gorbik return -simple_strtoull(cp + 1, endp, base); 10049698745SVasily Gorbik 10149698745SVasily Gorbik return simple_strtoull(cp, endp, base); 10249698745SVasily Gorbik } 103d58106c3SVasily Gorbik 104d58106c3SVasily Gorbik int kstrtobool(const char *s, bool *res) 105d58106c3SVasily Gorbik { 106d58106c3SVasily Gorbik if (!s) 107d58106c3SVasily Gorbik return -EINVAL; 108d58106c3SVasily Gorbik 109d58106c3SVasily Gorbik switch (s[0]) { 110d58106c3SVasily Gorbik case 'y': 111d58106c3SVasily Gorbik case 'Y': 112d58106c3SVasily Gorbik case '1': 113d58106c3SVasily Gorbik *res = true; 114d58106c3SVasily Gorbik return 0; 115d58106c3SVasily Gorbik case 'n': 116d58106c3SVasily Gorbik case 'N': 117d58106c3SVasily Gorbik case '0': 118d58106c3SVasily Gorbik *res = false; 119d58106c3SVasily Gorbik return 0; 120d58106c3SVasily Gorbik case 'o': 121d58106c3SVasily Gorbik case 'O': 122d58106c3SVasily Gorbik switch (s[1]) { 123d58106c3SVasily Gorbik case 'n': 124d58106c3SVasily Gorbik case 'N': 125d58106c3SVasily Gorbik *res = true; 126d58106c3SVasily Gorbik return 0; 127d58106c3SVasily Gorbik case 'f': 128d58106c3SVasily Gorbik case 'F': 129d58106c3SVasily Gorbik *res = false; 130d58106c3SVasily Gorbik return 0; 131d58106c3SVasily Gorbik default: 132d58106c3SVasily Gorbik break; 133d58106c3SVasily Gorbik } 134d58106c3SVasily Gorbik default: 135d58106c3SVasily Gorbik break; 136d58106c3SVasily Gorbik } 137d58106c3SVasily Gorbik 138d58106c3SVasily Gorbik return -EINVAL; 139d58106c3SVasily Gorbik } 140