diff options
Diffstat (limited to 'roms/u-boot/lib/strto.c')
-rw-r--r-- | roms/u-boot/lib/strto.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/roms/u-boot/lib/strto.c b/roms/u-boot/lib/strto.c new file mode 100644 index 000000000..c00bb5895 --- /dev/null +++ b/roms/u-boot/lib/strto.c @@ -0,0 +1,173 @@ +/* + * 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> + +/* from lib/kstrtox.c */ +static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) +{ + if (*base == 0) { + if (s[0] == '0') { + if (tolower(s[1]) == 'x' && isxdigit(s[2])) + *base = 16; + else + *base = 8; + } else + *base = 10; + } + if (*base == 16 && s[0] == '0' && tolower(s[1]) == 'x') + s += 2; + return s; +} + +unsigned long simple_strtoul(const char *cp, char **endp, + unsigned int base) +{ + unsigned long result = 0; + unsigned long value; + + cp = _parse_integer_fixup_radix(cp, &base); + + 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 (tolower(**endp)) { + case 'g': + result *= 1024; + /* fall through */ + case 'm': + result *= 1024; + /* fall through */ + case 'k': + result *= 1024; + (*endp)++; + if (**endp == 'i') + (*endp)++; + if (**endp == 'B') + (*endp)++; + } + return result; +} + +unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base) +{ + unsigned long long result = simple_strtoull(cp, endp, base); + switch (tolower(**endp)) { + case 'g': + result *= 1024; + /* fall through */ + case 'm': + result *= 1024; + /* fall through */ + case 'k': + result *= 1024; + (*endp)++; + if (**endp == 'i') + (*endp)++; + if (**endp == 'B') + (*endp)++; + } + return result; +} + +unsigned long long simple_strtoull(const char *cp, char **endp, + unsigned int base) +{ + unsigned long long result = 0, value; + + cp = _parse_integer_fixup_radix(cp, &base); + + 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); + if (isdigit(end[-1])) { + 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); +} + +void str_to_upper(const char *in, char *out, size_t len) +{ + for (; len > 0 && *in; len--) + *out++ = toupper(*in++); + if (len) + *out = '\0'; +} |