[PATCH] libpayload: Add a strtoul() function
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
This commit is contained in:
parent
ec6363dc48
commit
c53cdd782a
|
@ -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);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue