diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-09 13:21:54 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-09 13:21:54 +0100 |
| commit | 4a024c771992e274f46a8451647dc86f92a90999 (patch) | |
| tree | a63f28dec034f1ea5bea10fdd6a7397ed5e3bbd6 /miscutils | |
| parent | 3129f705fc630cf597abeaa97000f896d2813d52 (diff) | |
| download | busybox-w32-4a024c771992e274f46a8451647dc86f92a90999.tar.gz busybox-w32-4a024c771992e274f46a8451647dc86f92a90999.tar.bz2 busybox-w32-4a024c771992e274f46a8451647dc86f92a90999.zip | |
bc: simplify string-tonumber conversion code
function old new delta
bc_program_num 1108 983 -125
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-125) Total: -125 bytes
text data bss dec hex filename
985831 477 7296 993604 f2944 busybox_old
985706 477 7296 993479 f28c7 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 88 |
1 files changed, 43 insertions, 45 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 71b419d8f..c36486414 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
| @@ -2199,49 +2199,45 @@ static BcStatus bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale, | |||
| 2199 | static bool bc_num_strValid(const char *val, size_t base) | 2199 | static bool bc_num_strValid(const char *val, size_t base) |
| 2200 | { | 2200 | { |
| 2201 | BcDig b; | 2201 | BcDig b; |
| 2202 | bool small, radix = false; | 2202 | bool radix; |
| 2203 | size_t i, len = strlen(val); | ||
| 2204 | |||
| 2205 | if (!len) return true; | ||
| 2206 | |||
| 2207 | small = base <= 10; | ||
| 2208 | b = (BcDig)(small ? base + '0' : base - 10 + 'A'); | ||
| 2209 | |||
| 2210 | for (i = 0; i < len; ++i) { | ||
| 2211 | |||
| 2212 | BcDig c = val[i]; | ||
| 2213 | 2203 | ||
| 2204 | b = (BcDig)(base <= 10 ? base + '0' : base - 10 + 'A'); | ||
| 2205 | radix = false; | ||
| 2206 | for (;;) { | ||
| 2207 | BcDig c = *val++; | ||
| 2208 | if (c == '\0') | ||
| 2209 | break; | ||
| 2214 | if (c == '.') { | 2210 | if (c == '.') { |
| 2215 | |||
| 2216 | if (radix) return false; | 2211 | if (radix) return false; |
| 2217 | |||
| 2218 | radix = true; | 2212 | radix = true; |
| 2219 | continue; | 2213 | continue; |
| 2220 | } | 2214 | } |
| 2221 | 2215 | if (c < '0' || c >= b || (c > '9' && c < 'A')) | |
| 2222 | if (c < '0' || (small && c >= b) || (c > '9' && (c < 'A' || c >= b))) | ||
| 2223 | return false; | 2216 | return false; |
| 2224 | } | 2217 | } |
| 2225 | |||
| 2226 | return true; | 2218 | return true; |
| 2227 | } | 2219 | } |
| 2228 | 2220 | ||
| 2221 | // Note: n is already "bc_num_zero()"ed, | ||
| 2222 | // leading zeroes in "val" are removed | ||
| 2229 | static void bc_num_parseDecimal(BcNum *n, const char *val) | 2223 | static void bc_num_parseDecimal(BcNum *n, const char *val) |
| 2230 | { | 2224 | { |
| 2231 | size_t len, i; | 2225 | size_t len, i; |
| 2232 | const char *ptr; | 2226 | const char *ptr; |
| 2233 | bool zero = true; | 2227 | bool zero; |
| 2234 | 2228 | ||
| 2235 | for (i = 0; val[i] == '0'; ++i); | ||
| 2236 | |||
| 2237 | val += i; | ||
| 2238 | len = strlen(val); | 2229 | len = strlen(val); |
| 2239 | bc_num_zero(n); | 2230 | if (len == 0) |
| 2231 | return; | ||
| 2240 | 2232 | ||
| 2241 | if (len != 0) { | 2233 | zero = true; |
| 2242 | for (i = 0; zero && i < len; ++i) zero = val[i] == '0' || val[i] == '.'; | 2234 | for (i = 0; val[i]; ++i) { |
| 2243 | bc_num_expand(n, len); | 2235 | if (val[i] != '0' && val[i] != '.') { |
| 2236 | zero = false; | ||
| 2237 | break; | ||
| 2238 | } | ||
| 2244 | } | 2239 | } |
| 2240 | bc_num_expand(n, len); | ||
| 2245 | 2241 | ||
| 2246 | ptr = strchr(val, '.'); | 2242 | ptr = strchr(val, '.'); |
| 2247 | 2243 | ||
| @@ -2255,26 +2251,29 @@ static void bc_num_parseDecimal(BcNum *n, const char *val) | |||
| 2255 | } | 2251 | } |
| 2256 | } | 2252 | } |
| 2257 | 2253 | ||
| 2254 | // Note: n is already "bc_num_zero()"ed, | ||
| 2255 | // leading zeroes in "val" are removed | ||
| 2258 | static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base) | 2256 | static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base) |
| 2259 | { | 2257 | { |
| 2260 | BcStatus s; | 2258 | BcStatus s; |
| 2261 | BcNum temp, mult, result; | 2259 | BcNum temp, mult, result; |
| 2262 | BcDig c = '\0'; | 2260 | BcDig c = '\0'; |
| 2263 | bool zero = true; | ||
| 2264 | unsigned long v; | 2261 | unsigned long v; |
| 2265 | size_t i, digits, len = strlen(val); | 2262 | size_t i, digits; |
| 2266 | 2263 | ||
| 2267 | bc_num_zero(n); | 2264 | for (i = 0; ; ++i) { |
| 2268 | 2265 | if (val[i] == '\0') | |
| 2269 | for (i = 0; zero && i < len; ++i) zero = (val[i] == '.' || val[i] == '0'); | 2266 | return; |
| 2270 | if (zero) return; | 2267 | if (val[i] != '.' && val[i] != '0') |
| 2268 | break; | ||
| 2269 | } | ||
| 2271 | 2270 | ||
| 2272 | bc_num_init_DEF_SIZE(&temp); | 2271 | bc_num_init_DEF_SIZE(&temp); |
| 2273 | bc_num_init_DEF_SIZE(&mult); | 2272 | bc_num_init_DEF_SIZE(&mult); |
| 2274 | 2273 | ||
| 2275 | for (i = 0; i < len; ++i) { | 2274 | for (;;) { |
| 2276 | 2275 | c = *val++; | |
| 2277 | c = val[i]; | 2276 | if (c == '\0') goto int_err; |
| 2278 | if (c == '.') break; | 2277 | if (c == '.') break; |
| 2279 | 2278 | ||
| 2280 | v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10); | 2279 | v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10); |
| @@ -2286,19 +2285,15 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base) | |||
| 2286 | if (s) goto int_err; | 2285 | if (s) goto int_err; |
| 2287 | } | 2286 | } |
| 2288 | 2287 | ||
| 2289 | if (i == len) { | ||
| 2290 | c = val[i]; | ||
| 2291 | if (c == 0) goto int_err; | ||
| 2292 | } | ||
| 2293 | |||
| 2294 | bc_num_init(&result, base->len); | 2288 | bc_num_init(&result, base->len); |
| 2295 | //bc_num_zero(&result); - already is | 2289 | //bc_num_zero(&result); - already is |
| 2296 | bc_num_one(&mult); | 2290 | bc_num_one(&mult); |
| 2297 | 2291 | ||
| 2298 | for (i += 1, digits = 0; i < len; ++i, ++digits) { | 2292 | digits = 0; |
| 2299 | 2293 | for (;;) { | |
| 2300 | c = val[i]; | 2294 | c = *val++; |
| 2301 | if (c == 0) break; | 2295 | if (c == '\0') break; |
| 2296 | digits++; | ||
| 2302 | 2297 | ||
| 2303 | v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10); | 2298 | v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10); |
| 2304 | 2299 | ||
| @@ -2318,8 +2313,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base) | |||
| 2318 | 2313 | ||
| 2319 | if (n->len != 0) { | 2314 | if (n->len != 0) { |
| 2320 | if (n->rdx < digits) bc_num_extend(n, digits - n->rdx); | 2315 | if (n->rdx < digits) bc_num_extend(n, digits - n->rdx); |
| 2321 | } | 2316 | } else |
| 2322 | else | ||
| 2323 | bc_num_zero(n); | 2317 | bc_num_zero(n); |
| 2324 | 2318 | ||
| 2325 | err: | 2319 | err: |
| @@ -2498,6 +2492,9 @@ static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, | |||
| 2498 | if (!bc_num_strValid(val, base_t)) | 2492 | if (!bc_num_strValid(val, base_t)) |
| 2499 | return bc_error("bad number string"); | 2493 | return bc_error("bad number string"); |
| 2500 | 2494 | ||
| 2495 | bc_num_zero(n); | ||
| 2496 | while (*val == '0') val++; | ||
| 2497 | |||
| 2501 | if (base_t == 10) | 2498 | if (base_t == 10) |
| 2502 | bc_num_parseDecimal(n, val); | 2499 | bc_num_parseDecimal(n, val); |
| 2503 | else | 2500 | else |
| @@ -6387,7 +6384,7 @@ static BcStatus bc_program_asciify(void) | |||
| 6387 | { | 6384 | { |
| 6388 | BcStatus s; | 6385 | BcStatus s; |
| 6389 | BcResult *r, res; | 6386 | BcResult *r, res; |
| 6390 | BcNum *num = NULL, n; | 6387 | BcNum *num, n; |
| 6391 | char *str, *str2, c; | 6388 | char *str, *str2, c; |
| 6392 | size_t len = G.prog.strs.len, idx; | 6389 | size_t len = G.prog.strs.len, idx; |
| 6393 | unsigned long val; | 6390 | unsigned long val; |
| @@ -6396,6 +6393,7 @@ static BcStatus bc_program_asciify(void) | |||
| 6396 | return bc_error_stack_has_too_few_elements(); | 6393 | return bc_error_stack_has_too_few_elements(); |
| 6397 | r = bc_vec_top(&G.prog.results); | 6394 | r = bc_vec_top(&G.prog.results); |
| 6398 | 6395 | ||
| 6396 | num = NULL; // TODO: is this NULL needed? | ||
| 6399 | s = bc_program_num(r, &num, false); | 6397 | s = bc_program_num(r, &num, false); |
| 6400 | if (s) return s; | 6398 | if (s) return s; |
| 6401 | 6399 | ||
