[PATCH] libpayload: Add a strtoul() function
authorJordan Crouse <jordan.crouse@amd.com>
Mon, 20 Oct 2008 17:07:47 +0000 (17:07 +0000)
committerJordan Crouse <jordan.crouse@amd.com>
Mon, 20 Oct 2008 17:07:47 +0000 (17:07 +0000)
Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
Acked-by: Patrick Georgi <patrick.georgi@coresystems.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3676 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

payloads/libpayload/include/libpayload.h
payloads/libpayload/libc/string.c

index dd7fe9a29cb55e614aaf951b88e9d33119adf9e3..a098f0cc21b4a42f0f875fa8ccf1f79a9312fed9 100644 (file)
@@ -327,6 +327,8 @@ char *strchr(const char *s, int c);
 char *strdup(const char *s);
 char *strstr(const char *h, const char *n);
 char *strsep(char **stringp, const char *delim);
+unsigned int strtoul(const char *s, char **nptr, int base);
+
 /** @} */
 
 /**
index 9d196f2e094d06a515e147605e92f73bdb3540c9..9502acfa6ed6546e9a88684f71d8d42c64b691c4 100644 (file)
@@ -271,3 +271,95 @@ char *strsep(char **stringp, const char *delim)
        return token;
 }
 
+/* Check that a character is in the valid range for the
+   given base
+*/
+
+static int _valid(char ch, int base)
+{
+        char end = (base > 9) ? '9' : '0' + (base - 1);
+
+        /* all bases will be some subset of the 0-9 range */
+
+        if (ch >= '0' && ch <= end)
+                return 1;
+
+        /* Bases > 11 will also have to match in the a-z range */
+
+        if (base > 11) {
+                if (tolower(ch) >= 'a' &&
+                    tolower(ch) <= 'a' + (base - 11))
+                        return 1;
+        }
+
+        return 0;
+}
+
+/* Return the "value" of the character in the given base */
+
+static int _offset(char ch, int base)
+{
+        if (ch >= '0' && ch <= '9')
+                return ch - '0';
+        else
+                return tolower(ch) - 'a';
+}
+
+/**
+ * Convert the initial portion of a string into an unsigned int
+ * @param ptr A pointer to the string to convert
+ * @param endptr A pointer to the unconverted part of the string
+ * @param base The base of the number to convert, or 0 for auto
+ * @return An unsigned integer representation of the string
+ */
+
+unsigned int strtoul(const char *ptr, char **endptr, int base)
+{
+        int ret = 0;
+
+       if (endptr != NULL)
+               *endptr = (char *) ptr;
+
+        /* Purge whitespace */
+
+        for( ; *ptr && isspace(*ptr); ptr++);
+
+        if (!*ptr)
+                return 0;
+
+        /* Determine the base */
+
+        if (base == 0) {
+               if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
+                       base = 16;
+               else if (ptr[0] == '0') {
+                       base = 8;
+                       ptr++;
+               }
+               else
+                       base = 10;
+        }
+
+       /* Base 16 allows the 0x on front - so skip over it */
+
+       if (base == 16) {
+               if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
+                       ptr += 2;
+       }
+
+       /* If the first character isn't valid, then don't
+         * bother */
+
+        if (!*ptr || !_valid(*ptr, base))
+                return 0;
+
+        for( ; *ptr && _valid(*ptr, base); ptr++)
+                ret = (ret * base) + _offset(*ptr, base);
+
+       if (endptr != NULL)
+               *endptr = (char *) ptr;
+
+        return ret;
+}
+
+