diff options
Diffstat (limited to 'lib/libutil/expand_number.c')
-rw-r--r-- | lib/libutil/expand_number.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/lib/libutil/expand_number.c b/lib/libutil/expand_number.c index f4c19d7867a3..a3313ba39d98 100644 --- a/lib/libutil/expand_number.c +++ b/lib/libutil/expand_number.c @@ -37,13 +37,12 @@ #include <stdbool.h> #include <stdint.h> -int -expand_number(const char *buf, int64_t *num) +static int +expand_impl(const char *buf, uint64_t *num, bool *neg) { char *endptr; uintmax_t number; unsigned int shift; - bool neg; int serrno; /* @@ -52,10 +51,10 @@ expand_number(const char *buf, int64_t *num) while (isspace((unsigned char)*buf)) buf++; if (*buf == '-') { - neg = true; + *neg = true; buf++; } else { - neg = false; + *neg = false; if (*buf == '+') buf++; } @@ -127,6 +126,22 @@ expand_number(const char *buf, int64_t *num) } number <<= shift; + *num = number; + return (0); +} + +int +(expand_number)(const char *buf, int64_t *num) +{ + uint64_t number; + bool neg; + + /* + * Parse the number. + */ + if (expand_impl(buf, &number, &neg) != 0) + return (-1); + /* * Apply the sign and check for overflow. */ @@ -146,3 +161,27 @@ expand_number(const char *buf, int64_t *num) return (0); } + +int +expand_unsigned(const char *buf, uint64_t *num) +{ + uint64_t number; + bool neg; + + /* + * Parse the number. + */ + if (expand_impl(buf, &number, &neg) != 0) + return (-1); + + /* + * Negative numbers are out of range. + */ + if (neg && number > 0) { + errno = ERANGE; + return (-1); + } + + *num = number; + return (0); +} |