diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-09-05 14:48:59 +0200 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-09-06 00:06:50 -0700 |
commit | f96cc0af525dc6945164bda3e93b5f85c2929012 (patch) | |
tree | a05351c72d73aad75253438953e825b659fedb3f | |
parent | e803db81ccfa1376d6592eec54d270e959b40307 (diff) |
Implement strtoll() for 64 bit integer constants
-rw-r--r-- | orc/orcutils.c | 76 | ||||
-rw-r--r-- | orc/orcutils.h | 2 |
2 files changed, 78 insertions, 0 deletions
diff --git a/orc/orcutils.c b/orc/orcutils.c index ec51179..0f1f2a4 100644 --- a/orc/orcutils.c +++ b/orc/orcutils.c @@ -34,6 +34,7 @@ #include <fcntl.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> /** * SECTION:orcutils @@ -96,3 +97,78 @@ get_tag_value (char *s, const char *tag) return _strndup (colon, end-colon); } +orc_int64 +_strtoll (const char *nptr, char **endptr, int base) +{ + int neg = 0; + orc_int64 val = 0; + + /* Skip all spaces */ + while (isspace (*nptr)) + nptr++; + + if (!*nptr) + return val; + + /* Get sign */ + if (*nptr == '-') { + neg = 1; + nptr++; + } else if (*nptr == '+') { + nptr++; + } + + if (!*nptr) + return val; + + /* Try to detect the base if none was given */ + if (base == 0) { + if (*nptr == '0' && (*(nptr + 1) == 'x' || *(nptr + 1) == 'X')) { + base = 16; + nptr += 2; + } else if (*nptr == '0') { + base = 8; + nptr++; + } else { + base = 10; + } + } else if (base == 16) { + if (*nptr == '0' && (*(nptr + 1) == 'x' || *(nptr + 1) == 'X')) + nptr += 2; + } else if (base == 8) { + if (*nptr == '0') + nptr++; + } + + while (*nptr) { + int c = *nptr; + + if (c >= '0' && c <= '9') + c = c - '0'; + else if (c >= 'a' && c <= 'z') + c = 10 + c - 'a'; + else if (c >= 'A' && c <= 'Z') + c = 10 + c - 'A'; + else + break; + + if (c >= base) + break; + + if ((orc_uint64) val > 0xffffffffffffffffULL / base || + (orc_uint64) (val * base) > 0xffffffffffffffffULL - c) { + val = 0xffffffffffffffffULL; + break; + } + + val = val * base + c; + + nptr++; + } + + if (endptr) + *endptr = (char *) nptr; + + return (neg) ? - val : val; +} + diff --git a/orc/orcutils.h b/orc/orcutils.h index 9e4c9bc..0923120 100644 --- a/orc/orcutils.h +++ b/orc/orcutils.h @@ -159,6 +159,8 @@ char * _strndup (const char *s, int n); char ** strsplit (const char *s, char delimiter); char * get_tag_value (char *s, const char *tag); +orc_int64 _strtoll (const char *nptr, char **endptr, int base); + #endif ORC_END_DECLS |