aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c57
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
224typedef void (*BcNumDigitOp)(size_t, size_t, bool, size_t *);
225
224typedef BcStatus (*BcNumBinaryOp)(BcNum *, BcNum *, BcNum *, size_t); 226typedef BcStatus (*BcNumBinaryOp)(BcNum *, BcNum *, BcNum *, size_t);
225typedef void (*BcNumDigitOp)(size_t, size_t, bool, size_t *, size_t);
226 227
227static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale); 228static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale);
228static BcStatus bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale); 229static 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
2312static void bc_num_printNewline(size_t *nchars, size_t line_len) 2313static 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
2322static void bc_num_printChar(size_t num, size_t width, bool radix, 2323static 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
2331static void bc_num_printDigits(size_t num, size_t width, bool radix, 2332static 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
2353static void bc_num_printHex(size_t num, size_t width, bool radix, 2354static 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
2367static void bc_num_printDecimal(BcNum *n, size_t *nchars, size_t len) 2368static 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
2378static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width, 2379static 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
2442static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, 2443static 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
2471static BcStatus bc_num_stream(BcNum *n, BcNum *base, size_t *nchars, size_t len) 2472static 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
2491static BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, 2492static 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));