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