forked from u-boot/u-boot
-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: split out strtoxxxx functions out of vsprintf.c
To allow the various string to number conversion functions to be used when using tiny-printf,split them out into their own file which gets build regardless of what printf implementation is used. Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
- Loading branch information
1 parent
2b22a99
commit e4c5383
Showing
3 changed files
with
177 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
/* | ||
* linux/lib/vsprintf.c | ||
* | ||
* Copyright (C) 1991, 1992 Linus Torvalds | ||
*/ | ||
|
||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ | ||
/* | ||
* Wirzenius wrote this portably, Torvalds fucked it up :-) | ||
*/ | ||
|
||
#include <common.h> | ||
#include <errno.h> | ||
#include <linux/ctype.h> | ||
|
||
unsigned long simple_strtoul(const char *cp, char **endp, | ||
unsigned int base) | ||
{ | ||
unsigned long result = 0; | ||
unsigned long value; | ||
|
||
if (*cp == '0') { | ||
cp++; | ||
if ((*cp == 'x') && isxdigit(cp[1])) { | ||
base = 16; | ||
cp++; | ||
} | ||
|
||
if (!base) | ||
base = 8; | ||
} | ||
|
||
if (!base) | ||
base = 10; | ||
|
||
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) | ||
? toupper(*cp) : *cp)-'A'+10) < base) { | ||
result = result*base + value; | ||
cp++; | ||
} | ||
|
||
if (endp) | ||
*endp = (char *)cp; | ||
|
||
return result; | ||
} | ||
|
||
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) | ||
{ | ||
char *tail; | ||
unsigned long val; | ||
size_t len; | ||
|
||
*res = 0; | ||
len = strlen(cp); | ||
if (len == 0) | ||
return -EINVAL; | ||
|
||
val = simple_strtoul(cp, &tail, base); | ||
if (tail == cp) | ||
return -EINVAL; | ||
|
||
if ((*tail == '\0') || | ||
((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { | ||
*res = val; | ||
return 0; | ||
} | ||
|
||
return -EINVAL; | ||
} | ||
|
||
long simple_strtol(const char *cp, char **endp, unsigned int base) | ||
{ | ||
if (*cp == '-') | ||
return -simple_strtoul(cp + 1, endp, base); | ||
|
||
return simple_strtoul(cp, endp, base); | ||
} | ||
|
||
unsigned long ustrtoul(const char *cp, char **endp, unsigned int base) | ||
{ | ||
unsigned long result = simple_strtoul(cp, endp, base); | ||
switch (**endp) { | ||
case 'G': | ||
result *= 1024; | ||
/* fall through */ | ||
case 'M': | ||
result *= 1024; | ||
/* fall through */ | ||
case 'K': | ||
case 'k': | ||
result *= 1024; | ||
if ((*endp)[1] == 'i') { | ||
if ((*endp)[2] == 'B') | ||
(*endp) += 3; | ||
else | ||
(*endp) += 2; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base) | ||
{ | ||
unsigned long long result = simple_strtoull(cp, endp, base); | ||
switch (**endp) { | ||
case 'G': | ||
result *= 1024; | ||
/* fall through */ | ||
case 'M': | ||
result *= 1024; | ||
/* fall through */ | ||
case 'K': | ||
case 'k': | ||
result *= 1024; | ||
if ((*endp)[1] == 'i') { | ||
if ((*endp)[2] == 'B') | ||
(*endp) += 3; | ||
else | ||
(*endp) += 2; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
unsigned long long simple_strtoull(const char *cp, char **endp, | ||
unsigned int base) | ||
{ | ||
unsigned long long result = 0, value; | ||
|
||
if (*cp == '0') { | ||
cp++; | ||
if ((*cp == 'x') && isxdigit(cp[1])) { | ||
base = 16; | ||
cp++; | ||
} | ||
|
||
if (!base) | ||
base = 8; | ||
} | ||
|
||
if (!base) | ||
base = 10; | ||
|
||
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' | ||
: (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) { | ||
result = result * base + value; | ||
cp++; | ||
} | ||
|
||
if (endp) | ||
*endp = (char *) cp; | ||
|
||
return result; | ||
} | ||
|
||
long trailing_strtoln(const char *str, const char *end) | ||
{ | ||
const char *p; | ||
|
||
if (!end) | ||
end = str + strlen(str); | ||
for (p = end - 1; p > str; p--) { | ||
if (!isdigit(*p)) | ||
return simple_strtoul(p + 1, NULL, 10); | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
long trailing_strtol(const char *str) | ||
{ | ||
return trailing_strtoln(str, NULL); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters