projects/linux·blob master · refs

164 lines · 2.7 KiB

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 return __memset64(s, v, count * sizeof(v));
47}
48
49char *skip_spaces(const char *str)
50{
51 while (isspace(*str))
52 ++str;
53 return (char *)str;
54}
55
56char *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
76static 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
95unsigned 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
121long 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
129int 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}