regularize str -> num convertors
No binary (build failed)
—
(log yok)
| @@ -315,40 +315,7 @@ struct suffix_mult { | |
| const char *suffix; | |
| unsigned mult; | |
| }; | |
| - | unsigned long long xstrtoull(const char *numstr, int base); |
| - | unsigned long long xatoull(const char *numstr); |
| - | unsigned long xstrtoul_range_sfx(const char *numstr, int base, |
| - | unsigned long lower, |
| - | unsigned long upper, |
| - | const struct suffix_mult *suffixes); |
| - | unsigned long xstrtoul_range(const char *numstr, int base, |
| - | unsigned long lower, |
| - | unsigned long upper); |
| - | unsigned long xstrtoul_sfx(const char *numstr, int base, |
| - | const struct suffix_mult *suffixes); |
| - | unsigned long xstrtoul(const char *numstr, int base); |
| - | unsigned long xatoul_range_sfx(const char *numstr, |
| - | unsigned long lower, |
| - | unsigned long upper, |
| - | const struct suffix_mult *suffixes); |
| - | unsigned long xatoul_sfx(const char *numstr, |
| - | const struct suffix_mult *suffixes); |
| - | unsigned long xatoul_range(const char *numstr, |
| - | unsigned long lower, |
| - | unsigned long upper); |
| - | unsigned long xatoul(const char *numstr); |
| - | long xstrtol_range_sfx(const char *numstr, int base, |
| - | long lower, |
| - | long upper, |
| - | const struct suffix_mult *suffixes); |
| - | long xstrtol_range(const char *numstr, int base, long lower, long upper); |
| - | long xatol_range_sfx(const char *numstr, |
| - | long lower, |
| - | long upper, |
| - | const struct suffix_mult *suffixes); |
| - | long xatol_range(const char *numstr, long lower, long upper); |
| - | long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes); |
| - | long xatol(const char *numstr); |
| + | #include "xatonum.h" |
| /* Specialized: */ | |
| unsigned xatou_range(const char *numstr, unsigned lower, unsigned upper); | |
| unsigned xatou_sfx(const char *numstr, const struct suffix_mult *suffixes); | |
| @@ -0,0 +1,94 @@ | |
| + | /* vi: set sw=4 ts=4: */ |
| + | /* |
| + | * ascii-to-numbers implementations for busybox |
| + | * |
| + | * Copyright (C) 2003 Manuel Novoa III <[email protected]> |
| + | * |
| + | * Licensed under GPLv2, see file LICENSE in this tarball for details. |
| + | */ |
| + | |
| + | /* Provides extern declarations of functions */ |
| + | #define DECLARE_STR_CONV(type, T, UT) \ |
| + | \ |
| + | unsigned type xstrto##UT##_range_sfx(const char *str, int b, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \ |
| + | unsigned type xstrto##UT##_range(const char *str, int b, unsigned type l, unsigned type u); \ |
| + | unsigned type xstrto##UT##_sfx(const char *str, int b, const struct suffix_mult *sfx); \ |
| + | unsigned type xstrto##UT(const char *str, int b); \ |
| + | unsigned type xato##UT##_range_sfx(const char *str, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \ |
| + | unsigned type xato##UT##_range(const char *str, unsigned type l, unsigned type u); \ |
| + | unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx); \ |
| + | unsigned type xato##UT(const char *str); \ |
| + | type xstrto##T##_range_sfx(const char *str, int b, type l, type u, const struct suffix_mult *sfx) ;\ |
| + | type xstrto##T##_range(const char *str, int b, type l, type u); \ |
| + | type xato##T##_range_sfx(const char *str, type l, type u, const struct suffix_mult *sfx); \ |
| + | type xato##T##_range(const char *str, type l, type u); \ |
| + | type xato##T##_sfx(const char *str, const struct suffix_mult *sfx); \ |
| + | type xato##T(const char *str); \ |
| + | |
| + | /* Unsigned long long functions always exist */ |
| + | DECLARE_STR_CONV(long long, ll, ull) |
| + | |
| + | |
| + | /* Provides extern inline definitions of functions */ |
| + | /* (useful for mapping them to the type of the same width) */ |
| + | #define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \ |
| + | \ |
| + | extern inline \ |
| + | unsigned narrow xstrto##UN##_range_sfx(const char *str, int b, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
| + | { return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \ |
| + | extern inline \ |
| + | unsigned narrow xstrto##UN##_range(const char *str, int b, unsigned narrow l, unsigned narrow u) \ |
| + | { return xstrto##UW##_range(str, b, l, u); } \ |
| + | extern inline \ |
| + | unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \ |
| + | { return xstrto##UW##_sfx(str, b, sfx); } \ |
| + | extern inline \ |
| + | unsigned narrow xstrto##UN(const char *str, int b) \ |
| + | { return xstrto##UW(str, b); } \ |
| + | extern inline \ |
| + | unsigned narrow xato##UN##_range_sfx(const char *str, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
| + | { return xato##UW##_range_sfx(str, l, u, sfx); } \ |
| + | extern inline \ |
| + | unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \ |
| + | { return xato##UW##_range(str, l, u); } \ |
| + | extern inline \ |
| + | unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \ |
| + | { return xato##UW##_sfx(str, sfx); } \ |
| + | extern inline \ |
| + | unsigned narrow xato##UN(const char *str) \ |
| + | { return xato##UW(str); } \ |
| + | extern inline \ |
| + | narrow xstrto##N##_range_sfx(const char *str, int b, narrow l, narrow u, const struct suffix_mult *sfx) \ |
| + | { return xstrto##W##_range_sfx(str, b, l, u, sfx); } \ |
| + | extern inline \ |
| + | narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \ |
| + | { return xstrto##W##_range(str, b, l, u); } \ |
| + | extern inline \ |
| + | narrow xato##N##_range_sfx(const char *str, narrow l, narrow u, const struct suffix_mult *sfx) \ |
| + | { return xato##W##_range_sfx(str, l, u, sfx); } \ |
| + | extern inline \ |
| + | narrow xato##N##_range(const char *str, narrow l, narrow u) \ |
| + | { return xato##W##_range(str, l, u); } \ |
| + | extern inline \ |
| + | narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \ |
| + | { return xato##W##_sfx(str, sfx); } \ |
| + | extern inline \ |
| + | narrow xato##N(const char *str) \ |
| + | { return xato##W(str); } \ |
| + | |
| + | /* If long == long long, then just map them one-to-one */ |
| + | #if ULONG_MAX == ULLONG_MAX |
| + | DEFINE_EQUIV_STR_CONV(long, l, ll, ul, ull) |
| + | #else |
| + | /* Else provide extern defs */ |
| + | DECLARE_STR_CONV(long, l, ul) |
| + | #endif |
| + | |
| + | /* Same for int -> [long] long */ |
| + | #if UINT_MAX == ULLONG_MAX |
| + | DEFINE_EQUIV_STR_CONV(int, i, ll, u, ull) |
| + | #elif UINT_MAX == ULONG_MAX |
| + | DEFINE_EQUIV_STR_CONV(int, i, l, u, ul) |
| + | #else |
| + | DECLARE_STR_CONV(int, i, u) |
| + | #endif |
| @@ -87,7 +87,7 @@ lib-y += vperror_msg.o | |
| lib-y += warn_ignoring_args.o | |
| lib-y += wfopen.o | |
| lib-y += wfopen_input.o | |
| - | lib-y += xatol.o |
| + | lib-y += xatonum.o |
| lib-y += xconnect.o | |
| lib-y += xfuncs.o | |
| lib-y += xgetcwd.o | |
| @@ -1,236 +0,0 @@ | |
| - | /* vi: set sw=4 ts=4: */ |
| - | /* |
| - | * ascii-to-numbers implementations for busybox |
| - | * |
| - | * Copyright (C) 2003 Manuel Novoa III <[email protected]> |
| - | * |
| - | * Licensed under GPLv2, see file LICENSE in this tarball for details. |
| - | */ |
| - | |
| - | #include "libbb.h" |
| - | |
| - | unsigned long long xstrtoull(const char *numstr, int base) |
| - | { |
| - | unsigned long long r; |
| - | int old_errno; |
| - | char *e; |
| - | if ((*numstr == '-') || (isspace)(*numstr)) |
| - | bb_error_msg_and_die("invalid number '%s'", numstr); |
| - | old_errno = errno; |
| - | errno = 0; |
| - | r = strtoull(numstr, &e, base); |
| - | if (errno || (numstr == e) || *e) |
| - | /* Error / no digits / illegal trailing chars */ |
| - | bb_error_msg_and_die("invalid number '%s'", numstr); |
| - | /* No error. So restore errno. */ |
| - | errno = old_errno; |
| - | return r; |
| - | } |
| - | |
| - | unsigned long long xatoull(const char *numstr) |
| - | { |
| - | return xstrtoull(numstr, 10); |
| - | } |
| - | |
| - | unsigned long xstrtoul_range_sfx(const char *numstr, int base, |
| - | unsigned long lower, |
| - | unsigned long upper, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | unsigned long r; |
| - | int old_errno; |
| - | char *e; |
| - | |
| - | /* Disallow '-' and any leading whitespace. Speed isn't critical here |
| - | * since we're parsing commandline args. So make sure we get the |
| - | * actual isspace function rather than a lnumstrer macro implementaion. */ |
| - | if ((*numstr == '-') || (isspace)(*numstr)) |
| - | goto inval; |
| - | |
| - | /* Since this is a lib function, we're not allowed to reset errno to 0. |
| - | * Doing so could break an app that is deferring checking of errno. |
| - | * So, save the old value so that we can restore it if successful. */ |
| - | old_errno = errno; |
| - | errno = 0; |
| - | r = strtoul(numstr, &e, base); |
| - | /* Do the initial validity check. Note: The standards do not |
| - | * guarantee that errno is set if no digits were found. So we |
| - | * must test for this explicitly. */ |
| - | if (errno || (numstr == e)) |
| - | goto inval; /* error / no digits / illegal trailing chars */ |
| - | |
| - | errno = old_errno; /* Ok. So restore errno. */ |
| - | |
| - | /* Do optional suffix parsing. Allow 'empty' suffix tables. |
| - | * Note that we also allow nul suffixes with associated multipliers, |
| - | * to allow for scaling of the numstr by some default multiplier. */ |
| - | if (suffixes) { |
| - | while (suffixes->suffix) { |
| - | if (strcmp(suffixes->suffix, e) == 0) { |
| - | if (ULONG_MAX / suffixes->mult < r) |
| - | goto range; /* overflow! */ |
| - | ++e; |
| - | r *= suffixes->mult; |
| - | break; |
| - | } |
| - | ++suffixes; |
| - | } |
| - | } |
| - | |
| - | /* Note: trailing space is an error. |
| - | It would be easy enough to allow though if desired. */ |
| - | if (*e) |
| - | goto inval; |
| - | /* Finally, check for range limits. */ |
| - | if (r >= lower && r <= upper) |
| - | return r; |
| - | range: |
| - | bb_error_msg_and_die("number %s is not in %lu..%lu range", |
| - | numstr, lower, upper); |
| - | inval: |
| - | bb_error_msg_and_die("invalid number '%s'", numstr); |
| - | } |
| - | |
| - | unsigned long xstrtoul_range(const char *numstr, int base, |
| - | unsigned long lower, |
| - | unsigned long upper) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, base, lower, upper, NULL); |
| - | } |
| - | |
| - | unsigned long xstrtoul_sfx(const char *numstr, int base, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, base, 0, ULONG_MAX, suffixes); |
| - | } |
| - | |
| - | unsigned long xstrtoul(const char *numstr, int base) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, base, 0, ULONG_MAX, NULL); |
| - | } |
| - | |
| - | unsigned long xatoul_range_sfx(const char *numstr, |
| - | unsigned long lower, |
| - | unsigned long upper, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, 10, lower, upper, suffixes); |
| - | } |
| - | |
| - | unsigned long xatoul_sfx(const char *numstr, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, 10, 0, ULONG_MAX, suffixes); |
| - | } |
| - | |
| - | unsigned long xatoul_range(const char *numstr, |
| - | unsigned long lower, |
| - | unsigned long upper) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, 10, lower, upper, NULL); |
| - | } |
| - | |
| - | unsigned long xatoul(const char *numstr) |
| - | { |
| - | return xatoul_sfx(numstr, NULL); |
| - | } |
| - | |
| - | /* Signed ones */ |
| - | |
| - | long xstrtol_range_sfx(const char *numstr, int base, |
| - | long lower, |
| - | long upper, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | unsigned long u = LONG_MAX; |
| - | long r; |
| - | const char *p = numstr; |
| - | |
| - | if ((p[0] == '-') && (p[1] != '+')) { |
| - | ++p; |
| - | ++u; /* two's complement */ |
| - | } |
| - | |
| - | r = xstrtoul_range_sfx(p, base, 0, u, suffixes); |
| - | |
| - | if (*numstr == '-') { |
| - | r = -r; |
| - | } |
| - | |
| - | if (r < lower || r > upper) { |
| - | bb_error_msg_and_die("number %s is not in %ld..%ld range", |
| - | numstr, lower, upper); |
| - | } |
| - | |
| - | return r; |
| - | } |
| - | |
| - | long xstrtol_range(const char *numstr, int base, long lower, long upper) |
| - | { |
| - | return xstrtol_range_sfx(numstr, base, lower, upper, NULL); |
| - | } |
| - | |
| - | long xatol_range_sfx(const char *numstr, |
| - | long lower, |
| - | long upper, |
| - | const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtol_range_sfx(numstr, 10, lower, upper, suffixes); |
| - | } |
| - | |
| - | long xatol_range(const char *numstr, long lower, long upper) |
| - | { |
| - | return xstrtol_range_sfx(numstr, 10, lower, upper, NULL); |
| - | } |
| - | |
| - | long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, suffixes); |
| - | } |
| - | |
| - | long xatol(const char *numstr) |
| - | { |
| - | return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, NULL); |
| - | } |
| - | |
| - | /* Others */ |
| - | |
| - | unsigned xatou_range(const char *numstr, unsigned lower, unsigned upper) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, 10, lower, upper, NULL); |
| - | } |
| - | |
| - | unsigned xatou_sfx(const char *numstr, const struct suffix_mult *suffixes) |
| - | { |
| - | return xstrtoul_range_sfx(numstr, 10, 0, UINT_MAX, suffixes); |
| - | } |
| - | |
| - | unsigned xatou(const char *numstr) |
| - | { |
| - | return xatoul_range(numstr, 0, UINT_MAX); |
| - | } |
| - | |
| - | int xatoi_range(const char *numstr, int lower, int upper) |
| - | { |
| - | return xatol_range(numstr, lower, upper); |
| - | } |
| - | |
| - | int xatoi(const char *numstr) |
| - | { |
| - | return xatol_range(numstr, INT_MIN, INT_MAX); |
| - | } |
| - | |
| - | int xatoi_u(const char *numstr) |
| - | { |
| - | return xatoul_range(numstr, 0, INT_MAX); |
| - | } |
| - | |
| - | uint32_t xatou32(const char *numstr) |
| - | { |
| - | return xatoul_range(numstr, 0, 0xffffffff); |
| - | } |
| - | |
| - | uint16_t xatou16(const char *numstr) |
| - | { |
| - | return xatoul_range(numstr, 0, 0xffff); |
| - | } |
| @@ -0,0 +1,91 @@ | |
| + | /* vi: set sw=4 ts=4: */ |
| + | /* |
| + | * ascii-to-numbers implementations for busybox |
| + | * |
| + | * Copyright (C) 2003 Manuel Novoa III <[email protected]> |
| + | * |
| + | * Licensed under GPLv2, see file LICENSE in this tarball for details. |
| + | */ |
| + | |
| + | #include "libbb.h" |
| + | |
| + | #define type long long |
| + | #define xstrtou(rest) xstrtoull##rest |
| + | #define xstrto(rest) xstrtoll##rest |
| + | #define xatou(rest) xatoull##rest |
| + | #define xato(rest) xatoll##rest |
| + | #define XSTR_UTYPE_MAX ULLONG_MAX |
| + | #define XSTR_TYPE_MAX LLONG_MAX |
| + | #define XSTR_TYPE_MIN LLONG_MIN |
| + | #define XSTR_STRTOU strtoull |
| + | #include "xatonum_template.c" |
| + | #undef type |
| + | #undef xstrtou |
| + | #undef xstrto |
| + | #undef xatou |
| + | #undef xato |
| + | #undef XSTR_UTYPE_MAX |
| + | #undef XSTR_TYPE_MAX |
| + | #undef XSTR_TYPE_MIN |
| + | #undef XSTR_STRTOU |
| + | |
| + | #if ULONG_MAX != ULLONG_MAX |
| + | #define type long |
| + | #define xstrtou(rest) xstrtoul##rest |
| + | #define xstrto(rest) xstrtol##rest |
| + | #define xatou(rest) xatoul##rest |
| + | #define xato(rest) xatol##rest |
| + | #define XSTR_UTYPE_MAX ULONG_MAX |
| + | #define XSTR_TYPE_MAX LONG_MAX |
| + | #define XSTR_TYPE_MIN LONG_MIN |
| + | #define XSTR_STRTOU strtoul |
| + | #include "xatonum_template.c" |
| + | #undef type |
| + | #undef xstrtou |
| + | #undef xstrto |
| + | #undef xatou |
| + | #undef xato |
| + | #undef XSTR_UTYPE_MAX |
| + | #undef XSTR_TYPE_MAX |
| + | #undef XSTR_TYPE_MIN |
| + | #undef XSTR_STRTOU |
| + | #endif |
| + | |
| + | #if UINT_MAX != ULONG_MAX |
| + | #define type int |
| + | #define xstrtou(rest) xstrtou##rest |
| + | #define xstrto(rest) xstrtoi##rest |
| + | #define xatou(rest) xatou##rest |
| + | #define xato(rest) xatoi##rest |
| + | #define XSTR_UTYPE_MAX UINT_MAX |
| + | #define XSTR_TYPE_MAX INT_MAX |
| + | #define XSTR_TYPE_MIN INT_MIN |
| + | #define XSTR_STRTOU strtoul |
| + | #include "xatonum_template.c" |
| + | #undef type |
| + | #undef xstrtou |
| + | #undef xstrto |
| + | #undef xatou |
| + | #undef xato |
| + | #undef XSTR_UTYPE_MAX |
| + | #undef XSTR_TYPE_MAX |
| + | #undef XSTR_TYPE_MIN |
| + | #undef XSTR_STRTOU |
| + | #endif |
| + | |
| + | /* A few special cases */ |
| + | |
| + | int xatoi_u(const char *numstr) |
| + | { |
| + | return xatoul_range(numstr, 0, INT_MAX); |
| + | } |
| + | |
| + | uint32_t xatou32(const char *numstr) |
| + | { |
| + | return xatoul_range(numstr, 0, 0xffffffff); |
| + | } |
| + | |
| + | uint16_t xatou16(const char *numstr) |
| + | { |
| + | return xatoul_range(numstr, 0, 0xffff); |
| + | } |
| @@ -0,0 +1,175 @@ | |
| + | /* |
| + | You need to define the following (example): |
| + | |
| + | #define type long |
| + | #define xstrtou(rest) xstrtoul##rest |
| + | #define xstrto(rest) xstrtol##rest |
| + | #define xatou(rest) xatoul##rest |
| + | #define xato(rest) xatol##rest |
| + | #define XSTR_UTYPE_MAX ULONG_MAX |
| + | #define XSTR_TYPE_MAX LONG_MAX |
| + | #define XSTR_TYPE_MIN LONG_MIN |
| + | #define XSTR_STRTOU strtoul |
| + | */ |
| + | |
| + | unsigned type xstrtou(_range_sfx)(const char *numstr, int base, |
| + | unsigned type lower, |
| + | unsigned type upper, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | unsigned type r; |
| + | int old_errno; |
| + | char *e; |
| + | |
| + | /* Disallow '-' and any leading whitespace. Speed isn't critical here |
| + | * since we're parsing commandline args. So make sure we get the |
| + | * actual isspace function rather than a lnumstrer macro implementaion. */ |
| + | if ((*numstr == '-') || (isspace)(*numstr)) |
| + | goto inval; |
| + | |
| + | /* Since this is a lib function, we're not allowed to reset errno to 0. |
| + | * Doing so could break an app that is deferring checking of errno. |
| + | * So, save the old value so that we can restore it if successful. */ |
| + | old_errno = errno; |
| + | errno = 0; |
| + | r = XSTR_STRTOU(numstr, &e, base); |
| + | /* Do the initial validity check. Note: The standards do not |
| + | * guarantee that errno is set if no digits were found. So we |
| + | * must test for this explicitly. */ |
| + | if (errno || (numstr == e)) |
| + | goto inval; /* error / no digits / illegal trailing chars */ |
| + | |
| + | errno = old_errno; /* Ok. So restore errno. */ |
| + | |
| + | /* Do optional suffix parsing. Allow 'empty' suffix tables. |
| + | * Note that we also allow nul suffixes with associated multipliers, |
| + | * to allow for scaling of the numstr by some default multiplier. */ |
| + | if (suffixes) { |
| + | while (suffixes->suffix) { |
| + | if (strcmp(suffixes->suffix, e) == 0) { |
| + | if (XSTR_UTYPE_MAX / suffixes->mult < r) |
| + | goto range; /* overflow! */ |
| + | ++e; |
| + | r *= suffixes->mult; |
| + | break; |
| + | } |
| + | ++suffixes; |
| + | } |
| + | } |
| + | |
| + | /* Note: trailing space is an error. |
| + | It would be easy enough to allow though if desired. */ |
| + | if (*e) |
| + | goto inval; |
| + | /* Finally, check for range limits. */ |
| + | if (r >= lower && r <= upper) |
| + | return r; |
| + | range: |
| + | bb_error_msg_and_die("number %s is not in %llu..%llu range", |
| + | numstr, (unsigned long long)lower, |
| + | (unsigned long long)upper); |
| + | inval: |
| + | bb_error_msg_and_die("invalid number '%s'", numstr); |
| + | } |
| + | |
| + | unsigned type xstrtou(_range)(const char *numstr, int base, |
| + | unsigned type lower, |
| + | unsigned type upper) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL); |
| + | } |
| + | |
| + | unsigned type xstrtou(_sfx)(const char *numstr, int base, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes); |
| + | } |
| + | |
| + | unsigned type xstrtou()(const char *numstr, int base) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL); |
| + | } |
| + | |
| + | unsigned type xatou(_range_sfx)(const char *numstr, |
| + | unsigned type lower, |
| + | unsigned type upper, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes); |
| + | } |
| + | |
| + | unsigned type xatou(_range)(const char *numstr, |
| + | unsigned type lower, |
| + | unsigned type upper) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL); |
| + | } |
| + | |
| + | unsigned type xatou(_sfx)(const char *numstr, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes); |
| + | } |
| + | |
| + | unsigned type xatou()(const char *numstr) |
| + | { |
| + | return xatou(_sfx)(numstr, NULL); |
| + | } |
| + | |
| + | /* Signed ones */ |
| + | |
| + | type xstrto(_range_sfx)(const char *numstr, int base, |
| + | type lower, |
| + | type upper, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | unsigned type u = XSTR_TYPE_MAX; |
| + | type r; |
| + | const char *p = numstr; |
| + | |
| + | if ((p[0] == '-') && (p[1] != '+')) { |
| + | ++p; |
| + | ++u; /* two's complement */ |
| + | } |
| + | |
| + | r = xstrtou(_range_sfx)(p, base, 0, u, suffixes); |
| + | |
| + | if (*numstr == '-') { |
| + | r = -r; |
| + | } |
| + | |
| + | if (r < lower || r > upper) { |
| + | bb_error_msg_and_die("number %s is not in %lld..%lld range", |
| + | numstr, (long long)lower, (long long)upper); |
| + | } |
| + | |
| + | return r; |
| + | } |
| + | |
| + | type xstrto(_range)(const char *numstr, int base, type lower, type upper) |
| + | { |
| + | return xstrto(_range_sfx)(numstr, base, lower, upper, NULL); |
| + | } |
| + | |
| + | type xato(_range_sfx)(const char *numstr, |
| + | type lower, |
| + | type upper, |
| + | const struct suffix_mult *suffixes) |
| + | { |
| + | return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes); |
| + | } |
| + | |
| + | type xato(_range)(const char *numstr, type lower, type upper) |
| + | { |
| + | return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL); |
| + | } |
| + | |
| + | type xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes) |
| + | { |
| + | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes); |
| + | } |
| + | |
| + | type xato()(const char *numstr) |
| + | { |
| + | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); |
| + | } |