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 uint64_t *xs = s; 47 48 while (count--) 49 *xs++ = v; 50 return s; 51 } 52 53 char *skip_spaces(const char *str) 54 { 55 while (isspace(*str)) 56 ++str; 57 return (char *)str; 58 } 59 60 char *strim(char *s) 61 { 62 size_t size; 63 char *end; 64 65 size = strlen(s); 66 if (!size) 67 return s; 68 69 end = s + size - 1; 70 while (end >= s && isspace(*end)) 71 end--; 72 *(end + 1) = '\0'; 73 74 return skip_spaces(s); 75 } 76 77 /* Works only for digits and letters, but small and fast */ 78 #define TOLOWER(x) ((x) | 0x20) 79 80 static unsigned int simple_guess_base(const char *cp) 81 { 82 if (cp[0] == '0') { 83 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) 84 return 16; 85 else 86 return 8; 87 } else { 88 return 10; 89 } 90 } 91 92 /** 93 * simple_strtoull - convert a string to an unsigned long long 94 * @cp: The start of the string 95 * @endp: A pointer to the end of the parsed string will be placed here 96 * @base: The number base to use 97 */ 98 99 unsigned long long simple_strtoull(const char *cp, char **endp, 100 unsigned int base) 101 { 102 unsigned long long result = 0; 103 104 if (!base) 105 base = simple_guess_base(cp); 106 107 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') 108 cp += 2; 109 110 while (isxdigit(*cp)) { 111 unsigned int value; 112 113 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; 114 if (value >= base) 115 break; 116 result = result * base + value; 117 cp++; 118 } 119 if (endp) 120 *endp = (char *)cp; 121 122 return result; 123 } 124 125 long simple_strtol(const char *cp, char **endp, unsigned int base) 126 { 127 if (*cp == '-') 128 return -simple_strtoull(cp + 1, endp, base); 129 130 return simple_strtoull(cp, endp, base); 131 } 132 133 int kstrtobool(const char *s, bool *res) 134 { 135 if (!s) 136 return -EINVAL; 137 138 switch (s[0]) { 139 case 'y': 140 case 'Y': 141 case '1': 142 *res = true; 143 return 0; 144 case 'n': 145 case 'N': 146 case '0': 147 *res = false; 148 return 0; 149 case 'o': 150 case 'O': 151 switch (s[1]) { 152 case 'n': 153 case 'N': 154 *res = true; 155 return 0; 156 case 'f': 157 case 'F': 158 *res = false; 159 return 0; 160 default: 161 break; 162 } 163 default: 164 break; 165 } 166 167 return -EINVAL; 168 } 169