Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
Index: libpayload/include/libpayload.h
===================================================================
--- libpayload.orig/include/libpayload.h	2008-10-16 15:10:04.000000000 -0600
+++ libpayload/include/libpayload.h	2008-10-16 15:10:27.000000000 -0600
@@ -327,6 +327,8 @@
 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: libpayload/libc/string.c
===================================================================
--- libpayload.orig/libc/string.c	2008-10-16 15:03:53.000000000 -0600
+++ libpayload/libc/string.c	2008-10-16 15:10:27.000000000 -0600
@@ -271,3 +271,95 @@
 	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 nptr 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;
+}
+
+

-- 
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.



