From 7e5f460ec457fe310156e399198a41eb0ce1e98c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Jul 2021 09:03:29 -0600 Subject: global: Convert simple_strtoul() with hex to hextoul() It is a pain to have to specify the value 16 in each call. Add a new hextoul() function and update the code to use it. Add a proper comment to simple_strtoul() while we are here. Signed-off-by: Simon Glass --- lib/net_utils.c | 2 +- lib/strto.c | 12 ++++++++---- lib/uuid.c | 14 +++++++------- lib/vsprintf.c | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/net_utils.c b/lib/net_utils.c index 0a8a557319c..f596c8f280c 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -52,7 +52,7 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr) return; for (i = 0; i < 6; ++i) { - enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0; + enetaddr[i] = addr ? hextoul(addr, &end) : 0; if (addr) addr = (*end) ? end + 1 : end; } diff --git a/lib/strto.c b/lib/strto.c index f8b53d846b3..57d62163da4 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -30,11 +30,10 @@ static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) return s; } -unsigned long simple_strtoul(const char *cp, char **endp, - unsigned int base) +ulong simple_strtoul(const char *cp, char **endp, uint base) { - unsigned long result = 0; - unsigned long value; + ulong result = 0; + ulong value; cp = _parse_integer_fixup_radix(cp, &base); @@ -50,6 +49,11 @@ unsigned long simple_strtoul(const char *cp, char **endp, return result; } +ulong hextoul(const char *cp, char **endp) +{ + return simple_strtoul(cp, endp, 16); +} + int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) { char *tail; diff --git a/lib/uuid.c b/lib/uuid.c index 5bc68674d02..67267c66a3c 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -164,26 +164,26 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, } if (str_format == UUID_STR_FORMAT_STD) { - tmp32 = cpu_to_be32(simple_strtoul(uuid_str, NULL, 16)); + tmp32 = cpu_to_be32(hextoul(uuid_str, NULL)); memcpy(uuid_bin, &tmp32, 4); - tmp16 = cpu_to_be16(simple_strtoul(uuid_str + 9, NULL, 16)); + tmp16 = cpu_to_be16(hextoul(uuid_str + 9, NULL)); memcpy(uuid_bin + 4, &tmp16, 2); - tmp16 = cpu_to_be16(simple_strtoul(uuid_str + 14, NULL, 16)); + tmp16 = cpu_to_be16(hextoul(uuid_str + 14, NULL)); memcpy(uuid_bin + 6, &tmp16, 2); } else { - tmp32 = cpu_to_le32(simple_strtoul(uuid_str, NULL, 16)); + tmp32 = cpu_to_le32(hextoul(uuid_str, NULL)); memcpy(uuid_bin, &tmp32, 4); - tmp16 = cpu_to_le16(simple_strtoul(uuid_str + 9, NULL, 16)); + tmp16 = cpu_to_le16(hextoul(uuid_str + 9, NULL)); memcpy(uuid_bin + 4, &tmp16, 2); - tmp16 = cpu_to_le16(simple_strtoul(uuid_str + 14, NULL, 16)); + tmp16 = cpu_to_le16(hextoul(uuid_str + 14, NULL)); memcpy(uuid_bin + 6, &tmp16, 2); } - tmp16 = cpu_to_be16(simple_strtoul(uuid_str + 19, NULL, 16)); + tmp16 = cpu_to_be16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2); tmp64 = cpu_to_be64(simple_strtoull(uuid_str + 24, NULL, 16)); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c14176dd393..d7ee35b4773 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -858,7 +858,7 @@ bool str2long(const char *p, ulong *num) { char *endptr; - *num = simple_strtoul(p, &endptr, 16); + *num = hextoul(p, &endptr); return *p != '\0' && *endptr == '\0'; } -- cgit v1.2.3 From 0b1284eb52578e15ec611adc5fee1a9ae68dadea Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Jul 2021 09:03:30 -0600 Subject: global: Convert simple_strtoul() with decimal to dectoul() It is a pain to have to specify the value 10 in each call. Add a new dectoul() function and update the code to use it. Signed-off-by: Simon Glass --- lib/dhry/cmd_dhry.c | 2 +- lib/fdtdec.c | 2 +- lib/net_utils.c | 2 +- lib/strto.c | 7 ++++++- 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/dhry/cmd_dhry.c b/lib/dhry/cmd_dhry.c index d55ab54df97..77b52a23003 100644 --- a/lib/dhry/cmd_dhry.c +++ b/lib/dhry/cmd_dhry.c @@ -16,7 +16,7 @@ static int do_dhry(struct cmd_tbl *cmdtp, int flag, int argc, int iterations = 1000000; if (argc > 1) - iterations = simple_strtoul(argv[1], NULL, 10); + iterations = dectoul(argv[1], NULL); start = get_timer(0); dhry(iterations); diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4b097fb588e..07c7ebe74d8 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -405,7 +405,7 @@ int fdtdec_add_aliases_for_id(const void *blob, const char *name, continue; /* Get the alias number */ - number = simple_strtoul(path + name_len, NULL, 10); + number = dectoul(path + name_len, NULL); if (number < 0 || number >= maxcount) { debug("%s: warning: alias '%s' is out of range\n", __func__, path); diff --git a/lib/net_utils.c b/lib/net_utils.c index f596c8f280c..72a3b098a70 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -23,7 +23,7 @@ struct in_addr string_to_ip(const char *s) return addr; for (addr.s_addr = 0, i = 0; i < 4; ++i) { - ulong val = s ? simple_strtoul(s, &e, 10) : 0; + ulong val = s ? dectoul(s, &e) : 0; if (val > 255) { addr.s_addr = 0; return addr; diff --git a/lib/strto.c b/lib/strto.c index 57d62163da4..72903a57c07 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -54,6 +54,11 @@ ulong hextoul(const char *cp, char **endp) return simple_strtoul(cp, endp, 16); } +ulong dectoul(const char *cp, char **endp) +{ + return simple_strtoul(cp, endp, 10); +} + int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) { char *tail; @@ -164,7 +169,7 @@ long trailing_strtoln(const char *str, const char *end) if (isdigit(end[-1])) { for (p = end - 1; p > str; p--) { if (!isdigit(*p)) - return simple_strtoul(p + 1, NULL, 10); + return dectoul(p + 1, NULL); } } -- cgit v1.2.3 From 96b23440c1b74cd95022e3ebb08a60fedb04f3b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Jul 2021 09:03:32 -0600 Subject: lib: Drop unnecessary check for hex digit If we see 0x then we can assume this is the start of a hex value. It does not seem necessary to check for a hex digit after that since it will happen when parsing the value anyway. Drop this check to simplify the code and reduce size. Add a few more test cases for when a 0x prefix is used. Signed-off-by: Simon Glass --- lib/strto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/strto.c b/lib/strto.c index 72903a57c07..53886722138 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -18,7 +18,7 @@ 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])) + if (tolower(s[1]) == 'x') *base = 16; else *base = 8; -- cgit v1.2.3 From 5a94546e1cb302842aa0f65be0bb3585fd010ccd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Jul 2021 09:03:35 -0600 Subject: lib: Move common digit-parsing code into a function The code to convert a character into a digit is repeated twice in this file. Factor it out into a separate function. This also makes the code a little easier to read. Signed-off-by: Simon Glass --- lib/strto.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/strto.c b/lib/strto.c index 53886722138..b056b205c85 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -30,16 +30,33 @@ static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) return s; } +/** + * decode_digit() - Decode a single character into its numeric digit value + * + * This ignore case + * + * @ch: Character to convert (expects '0'..'9', 'a'..'f' or 'A'..'F') + * @return value of digit (0..0xf) or 255 if the character is invalid + */ +static uint decode_digit(int ch) +{ + if (!isxdigit(ch)) + return 256; + + ch = tolower(ch); + + return ch <= '9' ? ch - '0' : ch - 'a' + 0xa; +} + ulong simple_strtoul(const char *cp, char **endp, uint base) { ulong result = 0; - ulong value; + uint 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; + while (value = decode_digit(*cp), value < base) { + result = result * base + value; cp++; } @@ -136,12 +153,12 @@ unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base) unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) { - unsigned long long result = 0, value; + unsigned long long result = 0; + uint value; cp = _parse_integer_fixup_radix(cp, &base); - while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' - : (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) { + while (value = decode_digit(*cp), value < base) { result = result * base + value; cp++; } -- cgit v1.2.3 From e6951139c0544116330b12e287fe45e30bbab11c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Jul 2021 09:03:38 -0600 Subject: lib: Allow using 0x when a decimal value is requested U-Boot mostly uses hex for value input, largely because addresses are much easier to understand in hex. But in some cases a decimal value is requested, such as where the value is small or hex does not make sense in the context. In these cases it is sometimes useful to be able to provide a hex value in any case, if only to resolve any ambiguity. Add this functionality, for increased flexibility. Signed-off-by: Simon Glass --- lib/strto.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/strto.c b/lib/strto.c index b056b205c85..7bba1e3e549 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -14,19 +14,25 @@ #include /* from lib/kstrtox.c */ -static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) +static const char *_parse_integer_fixup_radix(const char *s, uint *basep) { - if (*base == 0) { - if (s[0] == '0') { - if (tolower(s[1]) == 'x') - *base = 16; - else - *base = 8; - } else - *base = 10; + /* Look for a 0x prefix */ + if (s[0] == '0') { + int ch = tolower(s[1]); + + if (ch == 'x') { + *basep = 16; + s += 2; + } else if (!*basep) { + /* Only select octal if we don't have a base */ + *basep = 8; + } } - if (*base == 16 && s[0] == '0' && tolower(s[1]) == 'x') - s += 2; + + /* Use decimal by default */ + if (!*basep) + *basep = 10; + return s; } -- cgit v1.2.3