diff options
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/bc.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 772696a15..a3702756d 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -221,8 +221,9 @@ typedef struct BcNum { | |||
221 | 221 | ||
222 | #define BC_NUM_KARATSUBA_LEN (32) | 222 | #define BC_NUM_KARATSUBA_LEN (32) |
223 | 223 | ||
224 | typedef void (*BcNumDigitOp)(size_t, size_t, bool, size_t *); | ||
225 | |||
224 | typedef BcStatus (*BcNumBinaryOp)(BcNum *, BcNum *, BcNum *, size_t); | 226 | typedef BcStatus (*BcNumBinaryOp)(BcNum *, BcNum *, BcNum *, size_t); |
225 | typedef void (*BcNumDigitOp)(size_t, size_t, bool, size_t *, size_t); | ||
226 | 227 | ||
227 | static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale); | 228 | static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale); |
228 | static BcStatus bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale); | 229 | static BcStatus bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale); |
@@ -2309,9 +2310,9 @@ int_err: | |||
2309 | bc_num_free(&temp); | 2310 | bc_num_free(&temp); |
2310 | } | 2311 | } |
2311 | 2312 | ||
2312 | static void bc_num_printNewline(size_t *nchars, size_t line_len) | 2313 | static void bc_num_printNewline(size_t *nchars) |
2313 | { | 2314 | { |
2314 | if (*nchars == line_len - 1) { | 2315 | if (*nchars == G.prog.len - 1) { |
2315 | bb_putchar('\\'); | 2316 | bb_putchar('\\'); |
2316 | bb_putchar('\n'); | 2317 | bb_putchar('\n'); |
2317 | *nchars = 0; | 2318 | *nchars = 0; |
@@ -2320,30 +2321,30 @@ static void bc_num_printNewline(size_t *nchars, size_t line_len) | |||
2320 | 2321 | ||
2321 | #if ENABLE_DC | 2322 | #if ENABLE_DC |
2322 | static void bc_num_printChar(size_t num, size_t width, bool radix, | 2323 | static void bc_num_printChar(size_t num, size_t width, bool radix, |
2323 | size_t *nchars, size_t line_len) | 2324 | size_t *nchars) |
2324 | { | 2325 | { |
2325 | (void) radix, (void) line_len; | 2326 | (void) radix; |
2326 | bb_putchar((char) num); | 2327 | bb_putchar((char) num); |
2327 | *nchars = *nchars + width; | 2328 | *nchars = *nchars + width; |
2328 | } | 2329 | } |
2329 | #endif | 2330 | #endif |
2330 | 2331 | ||
2331 | static void bc_num_printDigits(size_t num, size_t width, bool radix, | 2332 | static void bc_num_printDigits(size_t num, size_t width, bool radix, |
2332 | size_t *nchars, size_t line_len) | 2333 | size_t *nchars) |
2333 | { | 2334 | { |
2334 | size_t exp, pow; | 2335 | size_t exp, pow; |
2335 | 2336 | ||
2336 | bc_num_printNewline(nchars, line_len); | 2337 | bc_num_printNewline(nchars); |
2337 | bb_putchar(radix ? '.' : ' '); | 2338 | bb_putchar(radix ? '.' : ' '); |
2338 | ++(*nchars); | 2339 | ++(*nchars); |
2339 | 2340 | ||
2340 | bc_num_printNewline(nchars, line_len); | 2341 | bc_num_printNewline(nchars); |
2341 | for (exp = 0, pow = 1; exp < width - 1; ++exp, pow *= 10) | 2342 | for (exp = 0, pow = 1; exp < width - 1; ++exp, pow *= 10) |
2342 | continue; | 2343 | continue; |
2343 | 2344 | ||
2344 | for (exp = 0; exp < width; pow /= 10, ++(*nchars), ++exp) { | 2345 | for (exp = 0; exp < width; pow /= 10, ++(*nchars), ++exp) { |
2345 | size_t dig; | 2346 | size_t dig; |
2346 | bc_num_printNewline(nchars, line_len); | 2347 | bc_num_printNewline(nchars); |
2347 | dig = num / pow; | 2348 | dig = num / pow; |
2348 | num -= dig * pow; | 2349 | num -= dig * pow; |
2349 | bb_putchar(((char) dig) + '0'); | 2350 | bb_putchar(((char) dig) + '0'); |
@@ -2351,20 +2352,20 @@ static void bc_num_printDigits(size_t num, size_t width, bool radix, | |||
2351 | } | 2352 | } |
2352 | 2353 | ||
2353 | static void bc_num_printHex(size_t num, size_t width, bool radix, | 2354 | static void bc_num_printHex(size_t num, size_t width, bool radix, |
2354 | size_t *nchars, size_t line_len) | 2355 | size_t *nchars) |
2355 | { | 2356 | { |
2356 | if (radix) { | 2357 | if (radix) { |
2357 | bc_num_printNewline(nchars, line_len); | 2358 | bc_num_printNewline(nchars); |
2358 | bb_putchar('.'); | 2359 | bb_putchar('.'); |
2359 | *nchars += 1; | 2360 | *nchars += 1; |
2360 | } | 2361 | } |
2361 | 2362 | ||
2362 | bc_num_printNewline(nchars, line_len); | 2363 | bc_num_printNewline(nchars); |
2363 | bb_putchar(bb_hexdigits_upcase[num]); | 2364 | bb_putchar(bb_hexdigits_upcase[num]); |
2364 | *nchars = *nchars + width; | 2365 | *nchars = *nchars + width; |
2365 | } | 2366 | } |
2366 | 2367 | ||
2367 | static void bc_num_printDecimal(BcNum *n, size_t *nchars, size_t len) | 2368 | static void bc_num_printDecimal(BcNum *n, size_t *nchars) |
2368 | { | 2369 | { |
2369 | size_t i, rdx = n->rdx - 1; | 2370 | size_t i, rdx = n->rdx - 1; |
2370 | 2371 | ||
@@ -2372,11 +2373,11 @@ static void bc_num_printDecimal(BcNum *n, size_t *nchars, size_t len) | |||
2372 | (*nchars) += n->neg; | 2373 | (*nchars) += n->neg; |
2373 | 2374 | ||
2374 | for (i = n->len - 1; i < n->len; --i) | 2375 | for (i = n->len - 1; i < n->len; --i) |
2375 | bc_num_printHex((size_t) n->num[i], 1, i == rdx, nchars, len); | 2376 | bc_num_printHex((size_t) n->num[i], 1, i == rdx, nchars); |
2376 | } | 2377 | } |
2377 | 2378 | ||
2378 | static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, | 2379 | static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, |
2379 | size_t *nchars, size_t len, BcNumDigitOp print) | 2380 | size_t *nchars, BcNumDigitOp print) |
2380 | { | 2381 | { |
2381 | BcStatus s; | 2382 | BcStatus s; |
2382 | BcVec stack; | 2383 | BcVec stack; |
@@ -2386,7 +2387,7 @@ static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, | |||
2386 | bool radix; | 2387 | bool radix; |
2387 | 2388 | ||
2388 | if (n->len == 0) { | 2389 | if (n->len == 0) { |
2389 | print(0, width, false, nchars, len); | 2390 | print(0, width, false, nchars); |
2390 | return BC_STATUS_SUCCESS; | 2391 | return BC_STATUS_SUCCESS; |
2391 | } | 2392 | } |
2392 | 2393 | ||
@@ -2412,7 +2413,7 @@ static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, | |||
2412 | 2413 | ||
2413 | for (i = 0; i < stack.len; ++i) { | 2414 | for (i = 0; i < stack.len; ++i) { |
2414 | ptr = bc_vec_item_rev(&stack, i); | 2415 | ptr = bc_vec_item_rev(&stack, i); |
2415 | print(*ptr, width, false, nchars, len); | 2416 | print(*ptr, width, false, nchars); |
2416 | } | 2417 | } |
2417 | 2418 | ||
2418 | if (!n->rdx) goto err; | 2419 | if (!n->rdx) goto err; |
@@ -2425,7 +2426,7 @@ static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, | |||
2425 | bc_num_ulong2num(&intp, dig); | 2426 | bc_num_ulong2num(&intp, dig); |
2426 | s = bc_num_sub(&fracp, &intp, &fracp, 0); | 2427 | s = bc_num_sub(&fracp, &intp, &fracp, 0); |
2427 | if (s) goto err; | 2428 | if (s) goto err; |
2428 | print(dig, width, radix, nchars, len); | 2429 | print(dig, width, radix, nchars); |
2429 | s = bc_num_mul(&frac_len, base, &frac_len, 0); | 2430 | s = bc_num_mul(&frac_len, base, &frac_len, 0); |
2430 | if (s) goto err; | 2431 | if (s) goto err; |
2431 | } | 2432 | } |
@@ -2440,7 +2441,7 @@ err: | |||
2440 | } | 2441 | } |
2441 | 2442 | ||
2442 | static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, | 2443 | static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, |
2443 | size_t *nchars, size_t line_len) | 2444 | size_t *nchars) |
2444 | { | 2445 | { |
2445 | BcStatus s; | 2446 | BcStatus s; |
2446 | size_t width, i; | 2447 | size_t width, i; |
@@ -2461,16 +2462,16 @@ static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, | |||
2461 | print = bc_num_printDigits; | 2462 | print = bc_num_printDigits; |
2462 | } | 2463 | } |
2463 | 2464 | ||
2464 | s = bc_num_printNum(n, base, width, nchars, line_len, print); | 2465 | s = bc_num_printNum(n, base, width, nchars, print); |
2465 | n->neg = neg; | 2466 | n->neg = neg; |
2466 | 2467 | ||
2467 | return s; | 2468 | return s; |
2468 | } | 2469 | } |
2469 | 2470 | ||
2470 | #if ENABLE_DC | 2471 | #if ENABLE_DC |
2471 | static BcStatus bc_num_stream(BcNum *n, BcNum *base, size_t *nchars, size_t len) | 2472 | static BcStatus bc_num_stream(BcNum *n, BcNum *base, size_t *nchars) |
2472 | { | 2473 | { |
2473 | return bc_num_printNum(n, base, 1, nchars, len, bc_num_printChar); | 2474 | return bc_num_printNum(n, base, 1, nchars, bc_num_printChar); |
2474 | } | 2475 | } |
2475 | #endif | 2476 | #endif |
2476 | 2477 | ||
@@ -2489,20 +2490,20 @@ static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, | |||
2489 | } | 2490 | } |
2490 | 2491 | ||
2491 | static BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, | 2492 | static BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, |
2492 | size_t *nchars, size_t line_len) | 2493 | size_t *nchars) |
2493 | { | 2494 | { |
2494 | BcStatus s = BC_STATUS_SUCCESS; | 2495 | BcStatus s = BC_STATUS_SUCCESS; |
2495 | 2496 | ||
2496 | bc_num_printNewline(nchars, line_len); | 2497 | bc_num_printNewline(nchars); |
2497 | 2498 | ||
2498 | if (n->len == 0) { | 2499 | if (n->len == 0) { |
2499 | bb_putchar('0'); | 2500 | bb_putchar('0'); |
2500 | ++(*nchars); | 2501 | ++(*nchars); |
2501 | } | 2502 | } |
2502 | else if (base_t == 10) | 2503 | else if (base_t == 10) |
2503 | bc_num_printDecimal(n, nchars, line_len); | 2504 | bc_num_printDecimal(n, nchars); |
2504 | else | 2505 | else |
2505 | s = bc_num_printBase(n, base, base_t, nchars, line_len); | 2506 | s = bc_num_printBase(n, base, base_t, nchars); |
2506 | 2507 | ||
2507 | if (newline) { | 2508 | if (newline) { |
2508 | bb_putchar('\n'); | 2509 | bb_putchar('\n'); |
@@ -5719,7 +5720,7 @@ static BcStatus bc_program_print(char inst, size_t idx) | |||
5719 | if (s) return s; | 5720 | if (s) return s; |
5720 | 5721 | ||
5721 | if (BC_PROG_NUM(r, num)) { | 5722 | if (BC_PROG_NUM(r, num)) { |
5722 | s = bc_num_print(num, &G.prog.ob, G.prog.ob_t, !pop, &G.prog.nchars, G.prog.len); | 5723 | s = bc_num_print(num, &G.prog.ob, G.prog.ob_t, !pop, &G.prog.nchars); |
5723 | if (!s) bc_num_copy(&G.prog.last, num); | 5724 | if (!s) bc_num_copy(&G.prog.last, num); |
5724 | } | 5725 | } |
5725 | else { | 5726 | else { |
@@ -6450,7 +6451,7 @@ static BcStatus bc_program_printStream(void) | |||
6450 | if (s) return s; | 6451 | if (s) return s; |
6451 | 6452 | ||
6452 | if (BC_PROG_NUM(r, n)) | 6453 | if (BC_PROG_NUM(r, n)) |
6453 | s = bc_num_stream(n, &G.prog.strmb, &G.prog.nchars, G.prog.len); | 6454 | s = bc_num_stream(n, &G.prog.strmb, &G.prog.nchars); |
6454 | else { | 6455 | else { |
6455 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; | 6456 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; |
6456 | str = *((char **) bc_vec_item(&G.prog.strs, idx)); | 6457 | str = *((char **) bc_vec_item(&G.prog.strs, idx)); |