Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
16int 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
32ssize_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
44void *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
53char *skip_spaces(const char *str)
54{
55 while (isspace(*str))
56 ++str;
57 return (char *)str;
58}
59
60char *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
80static 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
99unsigned 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
125long 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
133int 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}