^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #undef CONFIG_KASAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #undef CONFIG_KASAN_GENERIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "../lib/string.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) int strncmp(const char *cs, const char *ct, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) unsigned char c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) c1 = *cs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) c2 = *ct++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) if (c1 != c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) return c1 < c2 ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) if (!c1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) char *skip_spaces(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) while (isspace(*str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ++str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return (char *)str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char *strim(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) size = strlen(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (!size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) end = s + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) while (end >= s && isspace(*end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) end--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *(end + 1) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return skip_spaces(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Works only for digits and letters, but small and fast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TOLOWER(x) ((x) | 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static unsigned int simple_guess_base(const char *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (cp[0] == '0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * simple_strtoull - convert a string to an unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @cp: The start of the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @endp: A pointer to the end of the parsed string will be placed here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @base: The number base to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned long long simple_strtoull(const char *cp, char **endp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned long long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) base = simple_guess_base(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) cp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) while (isxdigit(*cp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (value >= base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) result = result * base + value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) cp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (endp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *endp = (char *)cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) long simple_strtol(const char *cp, char **endp, unsigned int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (*cp == '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return -simple_strtoull(cp + 1, endp, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return simple_strtoull(cp, endp, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int kstrtobool(const char *s, bool *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) switch (s[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case 'y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case 'Y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case '0':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case 'O':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) switch (s[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }