diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-25 14:44:13 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-25 14:44:13 +0000 |
| commit | ed836cdc30642ddbecc286b279d461ca44135cbb (patch) | |
| tree | 70735d4bd1e34de43aa3f8092446caf460bd2540 /libbb | |
| parent | 809a6e310443d0b5010c8b293cab0160608c1b02 (diff) | |
| download | busybox-w32-ed836cdc30642ddbecc286b279d461ca44135cbb.tar.gz busybox-w32-ed836cdc30642ddbecc286b279d461ca44135cbb.tar.bz2 busybox-w32-ed836cdc30642ddbecc286b279d461ca44135cbb.zip | |
regularize str -> num convertors
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/Kbuild | 2 | ||||
| -rw-r--r-- | libbb/xatol.c | 236 | ||||
| -rw-r--r-- | libbb/xatonum.c | 91 | ||||
| -rw-r--r-- | libbb/xatonum_template.c | 175 |
4 files changed, 267 insertions, 237 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild index fc4798bf3..1ddec9a8d 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
| @@ -87,7 +87,7 @@ lib-y += vperror_msg.o | |||
| 87 | lib-y += warn_ignoring_args.o | 87 | lib-y += warn_ignoring_args.o |
| 88 | lib-y += wfopen.o | 88 | lib-y += wfopen.o |
| 89 | lib-y += wfopen_input.o | 89 | lib-y += wfopen_input.o |
| 90 | lib-y += xatol.o | 90 | lib-y += xatonum.o |
| 91 | lib-y += xconnect.o | 91 | lib-y += xconnect.o |
| 92 | lib-y += xfuncs.o | 92 | lib-y += xfuncs.o |
| 93 | lib-y += xgetcwd.o | 93 | lib-y += xgetcwd.o |
diff --git a/libbb/xatol.c b/libbb/xatol.c deleted file mode 100644 index cce8ad3eb..000000000 --- a/libbb/xatol.c +++ /dev/null | |||
| @@ -1,236 +0,0 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * ascii-to-numbers implementations for busybox | ||
| 4 | * | ||
| 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
| 6 | * | ||
| 7 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include "libbb.h" | ||
| 11 | |||
| 12 | unsigned long long xstrtoull(const char *numstr, int base) | ||
| 13 | { | ||
| 14 | unsigned long long r; | ||
| 15 | int old_errno; | ||
| 16 | char *e; | ||
| 17 | if ((*numstr == '-') || (isspace)(*numstr)) | ||
| 18 | bb_error_msg_and_die("invalid number '%s'", numstr); | ||
| 19 | old_errno = errno; | ||
| 20 | errno = 0; | ||
| 21 | r = strtoull(numstr, &e, base); | ||
| 22 | if (errno || (numstr == e) || *e) | ||
| 23 | /* Error / no digits / illegal trailing chars */ | ||
| 24 | bb_error_msg_and_die("invalid number '%s'", numstr); | ||
| 25 | /* No error. So restore errno. */ | ||
| 26 | errno = old_errno; | ||
| 27 | return r; | ||
| 28 | } | ||
| 29 | |||
| 30 | unsigned long long xatoull(const char *numstr) | ||
| 31 | { | ||
| 32 | return xstrtoull(numstr, 10); | ||
| 33 | } | ||
| 34 | |||
| 35 | unsigned long xstrtoul_range_sfx(const char *numstr, int base, | ||
| 36 | unsigned long lower, | ||
| 37 | unsigned long upper, | ||
| 38 | const struct suffix_mult *suffixes) | ||
| 39 | { | ||
| 40 | unsigned long r; | ||
| 41 | int old_errno; | ||
| 42 | char *e; | ||
| 43 | |||
| 44 | /* Disallow '-' and any leading whitespace. Speed isn't critical here | ||
| 45 | * since we're parsing commandline args. So make sure we get the | ||
| 46 | * actual isspace function rather than a lnumstrer macro implementaion. */ | ||
| 47 | if ((*numstr == '-') || (isspace)(*numstr)) | ||
| 48 | goto inval; | ||
| 49 | |||
| 50 | /* Since this is a lib function, we're not allowed to reset errno to 0. | ||
| 51 | * Doing so could break an app that is deferring checking of errno. | ||
| 52 | * So, save the old value so that we can restore it if successful. */ | ||
| 53 | old_errno = errno; | ||
| 54 | errno = 0; | ||
| 55 | r = strtoul(numstr, &e, base); | ||
| 56 | /* Do the initial validity check. Note: The standards do not | ||
| 57 | * guarantee that errno is set if no digits were found. So we | ||
| 58 | * must test for this explicitly. */ | ||
| 59 | if (errno || (numstr == e)) | ||
| 60 | goto inval; /* error / no digits / illegal trailing chars */ | ||
| 61 | |||
| 62 | errno = old_errno; /* Ok. So restore errno. */ | ||
| 63 | |||
| 64 | /* Do optional suffix parsing. Allow 'empty' suffix tables. | ||
| 65 | * Note that we also allow nul suffixes with associated multipliers, | ||
| 66 | * to allow for scaling of the numstr by some default multiplier. */ | ||
| 67 | if (suffixes) { | ||
| 68 | while (suffixes->suffix) { | ||
| 69 | if (strcmp(suffixes->suffix, e) == 0) { | ||
| 70 | if (ULONG_MAX / suffixes->mult < r) | ||
| 71 | goto range; /* overflow! */ | ||
| 72 | ++e; | ||
| 73 | r *= suffixes->mult; | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | ++suffixes; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | /* Note: trailing space is an error. | ||
| 81 | It would be easy enough to allow though if desired. */ | ||
| 82 | if (*e) | ||
| 83 | goto inval; | ||
| 84 | /* Finally, check for range limits. */ | ||
| 85 | if (r >= lower && r <= upper) | ||
| 86 | return r; | ||
| 87 | range: | ||
| 88 | bb_error_msg_and_die("number %s is not in %lu..%lu range", | ||
| 89 | numstr, lower, upper); | ||
| 90 | inval: | ||
| 91 | bb_error_msg_and_die("invalid number '%s'", numstr); | ||
| 92 | } | ||
| 93 | |||
| 94 | unsigned long xstrtoul_range(const char *numstr, int base, | ||
| 95 | unsigned long lower, | ||
| 96 | unsigned long upper) | ||
| 97 | { | ||
| 98 | return xstrtoul_range_sfx(numstr, base, lower, upper, NULL); | ||
| 99 | } | ||
| 100 | |||
| 101 | unsigned long xstrtoul_sfx(const char *numstr, int base, | ||
| 102 | const struct suffix_mult *suffixes) | ||
| 103 | { | ||
| 104 | return xstrtoul_range_sfx(numstr, base, 0, ULONG_MAX, suffixes); | ||
| 105 | } | ||
| 106 | |||
| 107 | unsigned long xstrtoul(const char *numstr, int base) | ||
| 108 | { | ||
| 109 | return xstrtoul_range_sfx(numstr, base, 0, ULONG_MAX, NULL); | ||
| 110 | } | ||
| 111 | |||
| 112 | unsigned long xatoul_range_sfx(const char *numstr, | ||
| 113 | unsigned long lower, | ||
| 114 | unsigned long upper, | ||
| 115 | const struct suffix_mult *suffixes) | ||
| 116 | { | ||
| 117 | return xstrtoul_range_sfx(numstr, 10, lower, upper, suffixes); | ||
| 118 | } | ||
| 119 | |||
| 120 | unsigned long xatoul_sfx(const char *numstr, | ||
| 121 | const struct suffix_mult *suffixes) | ||
| 122 | { | ||
| 123 | return xstrtoul_range_sfx(numstr, 10, 0, ULONG_MAX, suffixes); | ||
| 124 | } | ||
| 125 | |||
| 126 | unsigned long xatoul_range(const char *numstr, | ||
| 127 | unsigned long lower, | ||
| 128 | unsigned long upper) | ||
| 129 | { | ||
| 130 | return xstrtoul_range_sfx(numstr, 10, lower, upper, NULL); | ||
| 131 | } | ||
| 132 | |||
| 133 | unsigned long xatoul(const char *numstr) | ||
| 134 | { | ||
| 135 | return xatoul_sfx(numstr, NULL); | ||
| 136 | } | ||
| 137 | |||
| 138 | /* Signed ones */ | ||
| 139 | |||
| 140 | long xstrtol_range_sfx(const char *numstr, int base, | ||
| 141 | long lower, | ||
| 142 | long upper, | ||
| 143 | const struct suffix_mult *suffixes) | ||
| 144 | { | ||
| 145 | unsigned long u = LONG_MAX; | ||
| 146 | long r; | ||
| 147 | const char *p = numstr; | ||
| 148 | |||
| 149 | if ((p[0] == '-') && (p[1] != '+')) { | ||
| 150 | ++p; | ||
| 151 | ++u; /* two's complement */ | ||
| 152 | } | ||
| 153 | |||
| 154 | r = xstrtoul_range_sfx(p, base, 0, u, suffixes); | ||
| 155 | |||
| 156 | if (*numstr == '-') { | ||
| 157 | r = -r; | ||
| 158 | } | ||
| 159 | |||
| 160 | if (r < lower || r > upper) { | ||
| 161 | bb_error_msg_and_die("number %s is not in %ld..%ld range", | ||
| 162 | numstr, lower, upper); | ||
| 163 | } | ||
| 164 | |||
| 165 | return r; | ||
| 166 | } | ||
| 167 | |||
| 168 | long xstrtol_range(const char *numstr, int base, long lower, long upper) | ||
| 169 | { | ||
| 170 | return xstrtol_range_sfx(numstr, base, lower, upper, NULL); | ||
| 171 | } | ||
| 172 | |||
| 173 | long xatol_range_sfx(const char *numstr, | ||
| 174 | long lower, | ||
| 175 | long upper, | ||
| 176 | const struct suffix_mult *suffixes) | ||
| 177 | { | ||
| 178 | return xstrtol_range_sfx(numstr, 10, lower, upper, suffixes); | ||
| 179 | } | ||
| 180 | |||
| 181 | long xatol_range(const char *numstr, long lower, long upper) | ||
| 182 | { | ||
| 183 | return xstrtol_range_sfx(numstr, 10, lower, upper, NULL); | ||
| 184 | } | ||
| 185 | |||
| 186 | long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes) | ||
| 187 | { | ||
| 188 | return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, suffixes); | ||
| 189 | } | ||
| 190 | |||
| 191 | long xatol(const char *numstr) | ||
| 192 | { | ||
| 193 | return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, NULL); | ||
| 194 | } | ||
| 195 | |||
| 196 | /* Others */ | ||
| 197 | |||
| 198 | unsigned xatou_range(const char *numstr, unsigned lower, unsigned upper) | ||
| 199 | { | ||
| 200 | return xstrtoul_range_sfx(numstr, 10, lower, upper, NULL); | ||
| 201 | } | ||
| 202 | |||
| 203 | unsigned xatou_sfx(const char *numstr, const struct suffix_mult *suffixes) | ||
| 204 | { | ||
| 205 | return xstrtoul_range_sfx(numstr, 10, 0, UINT_MAX, suffixes); | ||
| 206 | } | ||
| 207 | |||
| 208 | unsigned xatou(const char *numstr) | ||
| 209 | { | ||
| 210 | return xatoul_range(numstr, 0, UINT_MAX); | ||
| 211 | } | ||
| 212 | |||
| 213 | int xatoi_range(const char *numstr, int lower, int upper) | ||
| 214 | { | ||
| 215 | return xatol_range(numstr, lower, upper); | ||
| 216 | } | ||
| 217 | |||
| 218 | int xatoi(const char *numstr) | ||
| 219 | { | ||
| 220 | return xatol_range(numstr, INT_MIN, INT_MAX); | ||
| 221 | } | ||
| 222 | |||
| 223 | int xatoi_u(const char *numstr) | ||
| 224 | { | ||
| 225 | return xatoul_range(numstr, 0, INT_MAX); | ||
| 226 | } | ||
| 227 | |||
| 228 | uint32_t xatou32(const char *numstr) | ||
| 229 | { | ||
| 230 | return xatoul_range(numstr, 0, 0xffffffff); | ||
| 231 | } | ||
| 232 | |||
| 233 | uint16_t xatou16(const char *numstr) | ||
| 234 | { | ||
| 235 | return xatoul_range(numstr, 0, 0xffff); | ||
| 236 | } | ||
diff --git a/libbb/xatonum.c b/libbb/xatonum.c new file mode 100644 index 000000000..910667c14 --- /dev/null +++ b/libbb/xatonum.c | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * ascii-to-numbers implementations for busybox | ||
| 4 | * | ||
| 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
| 6 | * | ||
| 7 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include "libbb.h" | ||
| 11 | |||
| 12 | #define type long long | ||
| 13 | #define xstrtou(rest) xstrtoull##rest | ||
| 14 | #define xstrto(rest) xstrtoll##rest | ||
| 15 | #define xatou(rest) xatoull##rest | ||
| 16 | #define xato(rest) xatoll##rest | ||
| 17 | #define XSTR_UTYPE_MAX ULLONG_MAX | ||
| 18 | #define XSTR_TYPE_MAX LLONG_MAX | ||
| 19 | #define XSTR_TYPE_MIN LLONG_MIN | ||
| 20 | #define XSTR_STRTOU strtoull | ||
| 21 | #include "xatonum_template.c" | ||
| 22 | #undef type | ||
| 23 | #undef xstrtou | ||
| 24 | #undef xstrto | ||
| 25 | #undef xatou | ||
| 26 | #undef xato | ||
| 27 | #undef XSTR_UTYPE_MAX | ||
| 28 | #undef XSTR_TYPE_MAX | ||
| 29 | #undef XSTR_TYPE_MIN | ||
| 30 | #undef XSTR_STRTOU | ||
| 31 | |||
| 32 | #if ULONG_MAX != ULLONG_MAX | ||
| 33 | #define type long | ||
| 34 | #define xstrtou(rest) xstrtoul##rest | ||
| 35 | #define xstrto(rest) xstrtol##rest | ||
| 36 | #define xatou(rest) xatoul##rest | ||
| 37 | #define xato(rest) xatol##rest | ||
| 38 | #define XSTR_UTYPE_MAX ULONG_MAX | ||
| 39 | #define XSTR_TYPE_MAX LONG_MAX | ||
| 40 | #define XSTR_TYPE_MIN LONG_MIN | ||
| 41 | #define XSTR_STRTOU strtoul | ||
| 42 | #include "xatonum_template.c" | ||
| 43 | #undef type | ||
| 44 | #undef xstrtou | ||
| 45 | #undef xstrto | ||
| 46 | #undef xatou | ||
| 47 | #undef xato | ||
| 48 | #undef XSTR_UTYPE_MAX | ||
| 49 | #undef XSTR_TYPE_MAX | ||
| 50 | #undef XSTR_TYPE_MIN | ||
| 51 | #undef XSTR_STRTOU | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #if UINT_MAX != ULONG_MAX | ||
| 55 | #define type int | ||
| 56 | #define xstrtou(rest) xstrtou##rest | ||
| 57 | #define xstrto(rest) xstrtoi##rest | ||
| 58 | #define xatou(rest) xatou##rest | ||
| 59 | #define xato(rest) xatoi##rest | ||
| 60 | #define XSTR_UTYPE_MAX UINT_MAX | ||
| 61 | #define XSTR_TYPE_MAX INT_MAX | ||
| 62 | #define XSTR_TYPE_MIN INT_MIN | ||
| 63 | #define XSTR_STRTOU strtoul | ||
| 64 | #include "xatonum_template.c" | ||
| 65 | #undef type | ||
| 66 | #undef xstrtou | ||
| 67 | #undef xstrto | ||
| 68 | #undef xatou | ||
| 69 | #undef xato | ||
| 70 | #undef XSTR_UTYPE_MAX | ||
| 71 | #undef XSTR_TYPE_MAX | ||
| 72 | #undef XSTR_TYPE_MIN | ||
| 73 | #undef XSTR_STRTOU | ||
| 74 | #endif | ||
| 75 | |||
| 76 | /* A few special cases */ | ||
| 77 | |||
| 78 | int xatoi_u(const char *numstr) | ||
| 79 | { | ||
| 80 | return xatoul_range(numstr, 0, INT_MAX); | ||
| 81 | } | ||
| 82 | |||
| 83 | uint32_t xatou32(const char *numstr) | ||
| 84 | { | ||
| 85 | return xatoul_range(numstr, 0, 0xffffffff); | ||
| 86 | } | ||
| 87 | |||
| 88 | uint16_t xatou16(const char *numstr) | ||
| 89 | { | ||
| 90 | return xatoul_range(numstr, 0, 0xffff); | ||
| 91 | } | ||
diff --git a/libbb/xatonum_template.c b/libbb/xatonum_template.c new file mode 100644 index 000000000..245586a5a --- /dev/null +++ b/libbb/xatonum_template.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | You need to define the following (example): | ||
| 3 | |||
| 4 | #define type long | ||
| 5 | #define xstrtou(rest) xstrtoul##rest | ||
| 6 | #define xstrto(rest) xstrtol##rest | ||
| 7 | #define xatou(rest) xatoul##rest | ||
| 8 | #define xato(rest) xatol##rest | ||
| 9 | #define XSTR_UTYPE_MAX ULONG_MAX | ||
| 10 | #define XSTR_TYPE_MAX LONG_MAX | ||
| 11 | #define XSTR_TYPE_MIN LONG_MIN | ||
| 12 | #define XSTR_STRTOU strtoul | ||
| 13 | */ | ||
| 14 | |||
| 15 | unsigned type xstrtou(_range_sfx)(const char *numstr, int base, | ||
| 16 | unsigned type lower, | ||
| 17 | unsigned type upper, | ||
| 18 | const struct suffix_mult *suffixes) | ||
| 19 | { | ||
| 20 | unsigned type r; | ||
| 21 | int old_errno; | ||
| 22 | char *e; | ||
| 23 | |||
| 24 | /* Disallow '-' and any leading whitespace. Speed isn't critical here | ||
| 25 | * since we're parsing commandline args. So make sure we get the | ||
| 26 | * actual isspace function rather than a lnumstrer macro implementaion. */ | ||
| 27 | if ((*numstr == '-') || (isspace)(*numstr)) | ||
| 28 | goto inval; | ||
| 29 | |||
| 30 | /* Since this is a lib function, we're not allowed to reset errno to 0. | ||
| 31 | * Doing so could break an app that is deferring checking of errno. | ||
| 32 | * So, save the old value so that we can restore it if successful. */ | ||
| 33 | old_errno = errno; | ||
| 34 | errno = 0; | ||
| 35 | r = XSTR_STRTOU(numstr, &e, base); | ||
| 36 | /* Do the initial validity check. Note: The standards do not | ||
| 37 | * guarantee that errno is set if no digits were found. So we | ||
| 38 | * must test for this explicitly. */ | ||
| 39 | if (errno || (numstr == e)) | ||
| 40 | goto inval; /* error / no digits / illegal trailing chars */ | ||
| 41 | |||
| 42 | errno = old_errno; /* Ok. So restore errno. */ | ||
| 43 | |||
| 44 | /* Do optional suffix parsing. Allow 'empty' suffix tables. | ||
| 45 | * Note that we also allow nul suffixes with associated multipliers, | ||
| 46 | * to allow for scaling of the numstr by some default multiplier. */ | ||
| 47 | if (suffixes) { | ||
| 48 | while (suffixes->suffix) { | ||
| 49 | if (strcmp(suffixes->suffix, e) == 0) { | ||
| 50 | if (XSTR_UTYPE_MAX / suffixes->mult < r) | ||
| 51 | goto range; /* overflow! */ | ||
| 52 | ++e; | ||
| 53 | r *= suffixes->mult; | ||
| 54 | break; | ||
| 55 | } | ||
| 56 | ++suffixes; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Note: trailing space is an error. | ||
| 61 | It would be easy enough to allow though if desired. */ | ||
| 62 | if (*e) | ||
| 63 | goto inval; | ||
| 64 | /* Finally, check for range limits. */ | ||
| 65 | if (r >= lower && r <= upper) | ||
| 66 | return r; | ||
| 67 | range: | ||
| 68 | bb_error_msg_and_die("number %s is not in %llu..%llu range", | ||
| 69 | numstr, (unsigned long long)lower, | ||
| 70 | (unsigned long long)upper); | ||
| 71 | inval: | ||
| 72 | bb_error_msg_and_die("invalid number '%s'", numstr); | ||
| 73 | } | ||
| 74 | |||
| 75 | unsigned type xstrtou(_range)(const char *numstr, int base, | ||
| 76 | unsigned type lower, | ||
| 77 | unsigned type upper) | ||
| 78 | { | ||
| 79 | return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL); | ||
| 80 | } | ||
| 81 | |||
| 82 | unsigned type xstrtou(_sfx)(const char *numstr, int base, | ||
| 83 | const struct suffix_mult *suffixes) | ||
| 84 | { | ||
| 85 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes); | ||
| 86 | } | ||
| 87 | |||
| 88 | unsigned type xstrtou()(const char *numstr, int base) | ||
| 89 | { | ||
| 90 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL); | ||
| 91 | } | ||
| 92 | |||
| 93 | unsigned type xatou(_range_sfx)(const char *numstr, | ||
| 94 | unsigned type lower, | ||
| 95 | unsigned type upper, | ||
| 96 | const struct suffix_mult *suffixes) | ||
| 97 | { | ||
| 98 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes); | ||
| 99 | } | ||
| 100 | |||
| 101 | unsigned type xatou(_range)(const char *numstr, | ||
| 102 | unsigned type lower, | ||
| 103 | unsigned type upper) | ||
| 104 | { | ||
| 105 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL); | ||
| 106 | } | ||
| 107 | |||
| 108 | unsigned type xatou(_sfx)(const char *numstr, | ||
| 109 | const struct suffix_mult *suffixes) | ||
| 110 | { | ||
| 111 | return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes); | ||
| 112 | } | ||
| 113 | |||
| 114 | unsigned type xatou()(const char *numstr) | ||
| 115 | { | ||
| 116 | return xatou(_sfx)(numstr, NULL); | ||
| 117 | } | ||
| 118 | |||
| 119 | /* Signed ones */ | ||
| 120 | |||
| 121 | type xstrto(_range_sfx)(const char *numstr, int base, | ||
| 122 | type lower, | ||
| 123 | type upper, | ||
| 124 | const struct suffix_mult *suffixes) | ||
| 125 | { | ||
| 126 | unsigned type u = XSTR_TYPE_MAX; | ||
| 127 | type r; | ||
| 128 | const char *p = numstr; | ||
| 129 | |||
| 130 | if ((p[0] == '-') && (p[1] != '+')) { | ||
| 131 | ++p; | ||
| 132 | ++u; /* two's complement */ | ||
| 133 | } | ||
| 134 | |||
| 135 | r = xstrtou(_range_sfx)(p, base, 0, u, suffixes); | ||
| 136 | |||
| 137 | if (*numstr == '-') { | ||
| 138 | r = -r; | ||
| 139 | } | ||
| 140 | |||
| 141 | if (r < lower || r > upper) { | ||
| 142 | bb_error_msg_and_die("number %s is not in %lld..%lld range", | ||
| 143 | numstr, (long long)lower, (long long)upper); | ||
| 144 | } | ||
| 145 | |||
| 146 | return r; | ||
| 147 | } | ||
| 148 | |||
| 149 | type xstrto(_range)(const char *numstr, int base, type lower, type upper) | ||
| 150 | { | ||
| 151 | return xstrto(_range_sfx)(numstr, base, lower, upper, NULL); | ||
| 152 | } | ||
| 153 | |||
| 154 | type xato(_range_sfx)(const char *numstr, | ||
| 155 | type lower, | ||
| 156 | type upper, | ||
| 157 | const struct suffix_mult *suffixes) | ||
| 158 | { | ||
| 159 | return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes); | ||
| 160 | } | ||
| 161 | |||
| 162 | type xato(_range)(const char *numstr, type lower, type upper) | ||
| 163 | { | ||
| 164 | return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL); | ||
| 165 | } | ||
| 166 | |||
| 167 | type xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes) | ||
| 168 | { | ||
| 169 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes); | ||
| 170 | } | ||
| 171 | |||
| 172 | type xato()(const char *numstr) | ||
| 173 | { | ||
| 174 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); | ||
| 175 | } | ||
