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