]> Git Repo - u-boot.git/blobdiff - lib/strto.c
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-mpc85xx
[u-boot.git] / lib / strto.c
index a6c01574dac3f6994cc3121f5d15082ad44e5155..6462d4fddf1a71fef6231d3ffa8b73fe2f91031e 100644 (file)
 #include <errno.h>
 #include <linux/ctype.h>
 
-unsigned long simple_strtoul(const char *cp, char **endp,
-                               unsigned int base)
+/* from lib/kstrtox.c */
+static const char *_parse_integer_fixup_radix(const char *s, uint *basep)
 {
-       unsigned long result = 0;
-       unsigned long value;
-
-       if (*cp == '0') {
-               cp++;
-               if ((*cp == 'x') && isxdigit(cp[1])) {
-                       base = 16;
-                       cp++;
+       /* 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)
-                       base = 8;
        }
 
-       if (!base)
-               base = 10;
+       /* Use decimal by default */
+       if (!*basep)
+               *basep = 10;
+
+       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);
 
-       while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
-           ? toupper(*cp) : *cp)-'A'+10) < base) {
-               result = result*base + value;
+       return ch <= '9' ? ch - '0' : ch - 'a' + 0xa;
+}
+
+ulong simple_strtoul(const char *cp, char **endp, uint base)
+{
+       ulong result = 0;
+       uint value;
+
+       cp = _parse_integer_fixup_radix(cp, &base);
+
+       while (value = decode_digit(*cp), value < base) {
+               result = result * base + value;
                cp++;
        }
 
@@ -45,6 +72,16 @@ unsigned long simple_strtoul(const char *cp, char **endp,
        return result;
 }
 
+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;
@@ -80,22 +117,20 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
 unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
        unsigned long result = simple_strtoul(cp, endp, base);
-       switch (**endp) {
-       case 'G':
+       switch (tolower(**endp)) {
+       case 'g':
                result *= 1024;
                /* fall through */
-       case 'M':
+       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;
-               }
+               (*endp)++;
+               if (**endp == 'i')
+                       (*endp)++;
+               if (**endp == 'B')
+                       (*endp)++;
        }
        return result;
 }
@@ -103,22 +138,20 @@ unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 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':
+       switch (tolower(**endp)) {
+       case 'g':
                result *= 1024;
                /* fall through */
-       case 'M':
+       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;
-               }
+               (*endp)++;
+               if (**endp == 'i')
+                       (*endp)++;
+               if (**endp == 'B')
+                       (*endp)++;
        }
        return result;
 }
@@ -126,24 +159,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;
 
-       if (*cp == '0') {
-               cp++;
-               if ((*cp == 'x') && isxdigit(cp[1])) {
-                       base = 16;
-                       cp++;
-               }
+       cp = _parse_integer_fixup_radix(cp, &base);
 
-               if (!base)
-                       base = 8;
-       }
-
-       if (!base)
-               base = 10;
-
-       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++;
        }
@@ -154,21 +175,50 @@ unsigned long long simple_strtoull(const char *cp, char **endp,
        return result;
 }
 
-long trailing_strtoln(const char *str, const char *end)
+long long simple_strtoll(const char *cp, char **endp, unsigned int base)
+{
+       if (*cp == '-')
+               return -simple_strtoull(cp + 1, endp, base);
+
+       return simple_strtoull(cp, endp, base);
+}
+
+long trailing_strtoln_end(const char *str, const char *end, char const **endp)
 {
        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);
+       p = end - 1;
+       if (p > str && isdigit(*p)) {
+               do {
+                       if (!isdigit(p[-1])) {
+                               if (endp)
+                                       *endp = p;
+                               return dectoul(p, NULL);
+                       }
+               } while (--p > str);
        }
+       if (endp)
+               *endp = end;
 
        return -1;
 }
 
+long trailing_strtoln(const char *str, const char *end)
+{
+       return trailing_strtoln_end(str, end, NULL);
+}
+
 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';
+}
This page took 0.034633 seconds and 4 git commands to generate.