aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/vsprintf.c117
1 files changed, 68 insertions, 49 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0ddf928fe4d5..cceecb6a963d 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -135,7 +135,6 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
135 return simple_strtoull(cp, endp, base); 135 return simple_strtoull(cp, endp, base);
136} 136}
137 137
138
139/** 138/**
140 * strict_strtoul - convert a string to an unsigned long strictly 139 * strict_strtoul - convert a string to an unsigned long strictly
141 * @cp: The string to be converted 140 * @cp: The string to be converted
@@ -158,7 +157,27 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
158 * simple_strtoul just ignores the successive invalid characters and 157 * simple_strtoul just ignores the successive invalid characters and
159 * return the converted value of prefix part of the string. 158 * return the converted value of prefix part of the string.
160 */ 159 */
161int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); 160int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
161{
162 char *tail;
163 unsigned long val;
164 size_t len;
165
166 *res = 0;
167 len = strlen(cp);
168 if (len == 0)
169 return -EINVAL;
170
171 val = simple_strtoul(cp, &tail, base);
172 if ((*tail == '\0') ||
173 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
174 *res = val;
175 return 0;
176 }
177
178 return -EINVAL;
179}
180EXPORT_SYMBOL(strict_strtoul);
162 181
163/** 182/**
164 * strict_strtol - convert a string to a long strictly 183 * strict_strtol - convert a string to a long strictly
@@ -172,7 +191,20 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
172 * It returns 0 if conversion is successful and *res is set to the converted 191 * It returns 0 if conversion is successful and *res is set to the converted
173 * value, otherwise it returns -EINVAL and *res is set to 0. 192 * value, otherwise it returns -EINVAL and *res is set to 0.
174 */ 193 */
175int strict_strtol(const char *cp, unsigned int base, long *res); 194int strict_strtol(const char *cp, unsigned int base, long *res)
195{
196 int ret;
197 if (*cp == '-') {
198 ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
199 if (!ret)
200 *res = -(*res);
201 } else {
202 ret = strict_strtoul(cp, base, (unsigned long *)res);
203 }
204
205 return ret;
206}
207EXPORT_SYMBOL(strict_strtol);
176 208
177/** 209/**
178 * strict_strtoull - convert a string to an unsigned long long strictly 210 * strict_strtoull - convert a string to an unsigned long long strictly
@@ -196,7 +228,27 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
196 * simple_strtoull just ignores the successive invalid characters and 228 * simple_strtoull just ignores the successive invalid characters and
197 * return the converted value of prefix part of the string. 229 * return the converted value of prefix part of the string.
198 */ 230 */
199int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res); 231int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
232{
233 char *tail;
234 unsigned long long val;
235 size_t len;
236
237 *res = 0;
238 len = strlen(cp);
239 if (len == 0)
240 return -EINVAL;
241
242 val = simple_strtoull(cp, &tail, base);
243 if ((*tail == '\0') ||
244 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
245 *res = val;
246 return 0;
247 }
248
249 return -EINVAL;
250}
251EXPORT_SYMBOL(strict_strtoull);
200 252
201/** 253/**
202 * strict_strtoll - convert a string to a long long strictly 254 * strict_strtoll - convert a string to a long long strictly
@@ -210,53 +262,20 @@ int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
210 * It returns 0 if conversion is successful and *res is set to the converted 262 * It returns 0 if conversion is successful and *res is set to the converted
211 * value, otherwise it returns -EINVAL and *res is set to 0. 263 * value, otherwise it returns -EINVAL and *res is set to 0.
212 */ 264 */
213int strict_strtoll(const char *cp, unsigned int base, long long *res); 265int strict_strtoll(const char *cp, unsigned int base, long long *res)
214 266{
215#define define_strict_strtoux(type, valtype) \ 267 int ret;
216int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\ 268 if (*cp == '-') {
217{ \ 269 ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
218 char *tail; \ 270 if (!ret)
219 valtype val; \ 271 *res = -(*res);
220 size_t len; \ 272 } else {
221 \ 273 ret = strict_strtoull(cp, base, (unsigned long long *)res);
222 *res = 0; \ 274 }
223 len = strlen(cp); \
224 if (len == 0) \
225 return -EINVAL; \
226 \
227 val = simple_strtou##type(cp, &tail, base); \
228 if ((*tail == '\0') || \
229 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
230 *res = val; \
231 return 0; \
232 } \
233 \
234 return -EINVAL; \
235} \
236
237#define define_strict_strtox(type, valtype) \
238int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
239{ \
240 int ret; \
241 if (*cp == '-') { \
242 ret = strict_strtou##type(cp+1, base, res); \
243 if (!ret) \
244 *res = -(*res); \
245 } else \
246 ret = strict_strtou##type(cp, base, res); \
247 \
248 return ret; \
249} \
250
251define_strict_strtoux(l, unsigned long)
252define_strict_strtox(l, long)
253define_strict_strtoux(ll, unsigned long long)
254define_strict_strtox(ll, long long)
255 275
256EXPORT_SYMBOL(strict_strtoul); 276 return ret;
257EXPORT_SYMBOL(strict_strtol); 277}
258EXPORT_SYMBOL(strict_strtoll); 278EXPORT_SYMBOL(strict_strtoll);
259EXPORT_SYMBOL(strict_strtoull);
260 279
261static int skip_atoi(const char **s) 280static int skip_atoi(const char **s)
262{ 281{