diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-30 23:13:42 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:42:52 +0100 |
commit | 00d7779a356f9827c0776ebbbe91c35f278b9a4c (patch) | |
tree | eafafa5f267b24b2067a0d916e833b971b90d58a | |
parent | ef869ec7283180e3733948ae31d1016ad9da4c0d (diff) | |
download | busybox-w32-00d7779a356f9827c0776ebbbe91c35f278b9a4c.tar.gz busybox-w32-00d7779a356f9827c0776ebbbe91c35f278b9a4c.tar.bz2 busybox-w32-00d7779a356f9827c0776ebbbe91c35f278b9a4c.zip |
bc: simplify, stop testing for IO errors on every output
function old new delta
bc_read_line 297 342 +45
bc_vm_run 2601 2608 +7
bc_program_reset 178 182 +4
bc_args 125 123 -2
dc_name 3 - -3
bc_name 3 - -3
bc_program_printStream 176 172 -4
bcg 48 40 -8
dc_main 97 80 -17
bc_main 97 80 -17
bc_vm_fflush 21 - -21
bc_vm_puts 23 - -23
bc_vm_printf 36 - -36
bc_vm_putchar 46 - -46
bc_vm_exit 46 - -46
bc_vm_process 361 312 -49
bc_vm_info 76 19 -57
bc_copyright 155 - -155
------------------------------------------------------------------------------
(add/remove: 0/8 grow/shrink: 3/7 up/down: 56/-487) Total: -431 bytes
text data bss dec hex filename
989722 485 7344 997551 f38af busybox_old
989491 485 7336 997312 f37c0 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 203 |
1 files changed, 81 insertions, 122 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 4cbef4da6..f36534c36 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -165,7 +165,7 @@ typedef enum BcStatus { | |||
165 | BC_STATUS_SUCCESS, | 165 | BC_STATUS_SUCCESS, |
166 | 166 | ||
167 | BC_STATUS_ALLOC_ERR, | 167 | BC_STATUS_ALLOC_ERR, |
168 | BC_STATUS_IO_ERR, | 168 | BC_STATUS_INPUT_EOF, |
169 | BC_STATUS_BIN_FILE, | 169 | BC_STATUS_BIN_FILE, |
170 | BC_STATUS_PATH_IS_DIR, | 170 | BC_STATUS_PATH_IS_DIR, |
171 | 171 | ||
@@ -719,9 +719,9 @@ static BcStatus bc_lex_token(BcLex *l); | |||
719 | static BcStatus bc_parse_parse(BcParse *p); | 719 | static BcStatus bc_parse_parse(BcParse *p); |
720 | static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next); | 720 | static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next); |
721 | 721 | ||
722 | #endif | 722 | #endif // ENABLE_BC |
723 | 723 | ||
724 | #ifdef ENABLE_DC | 724 | #if ENABLE_DC |
725 | 725 | ||
726 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) | 726 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) |
727 | 727 | ||
@@ -849,51 +849,38 @@ typedef struct BcGlobals { | |||
849 | long warn; | 849 | long warn; |
850 | long exreg; | 850 | long exreg; |
851 | 851 | ||
852 | const char *name; | ||
853 | #if ENABLE_FEATURE_BC_SIGNALS | 852 | #if ENABLE_FEATURE_BC_SIGNALS |
854 | const char *sig_msg; | 853 | const char *sig_msg; |
855 | #endif | 854 | #endif |
856 | const char *help; | 855 | const char *help; |
857 | bool bc; | ||
858 | 856 | ||
859 | } BcGlobals; | 857 | } BcGlobals; |
860 | 858 | ||
859 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) | ||
860 | |||
861 | #if ENABLE_BC | 861 | #if ENABLE_BC |
862 | static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | 862 | static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, |
863 | const char *msg); | 863 | const char *msg); |
864 | #endif | 864 | #endif |
865 | 865 | ||
866 | static void bc_vm_exit(BcStatus s); | 866 | static void bc_vm_info(void); |
867 | static void bc_vm_printf(FILE *restrict f, const char *fmt, ...); | ||
868 | static void bc_vm_puts(const char *str, FILE *restrict f); | ||
869 | static void bc_vm_putchar(int c); | ||
870 | static void bc_vm_fflush(FILE *restrict f); | ||
871 | |||
872 | static void bc_vm_info(const char *const help); | ||
873 | static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | 867 | static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, |
874 | const char *env_len); | 868 | const char *env_len); |
875 | 869 | ||
876 | static BcGlobals bcg; | 870 | static BcGlobals bcg; |
877 | 871 | ||
878 | #if ENABLE_BC | 872 | #if ENABLE_BC |
879 | static const char bc_name[] = "bc"; | ||
880 | # if ENABLE_FEATURE_BC_SIGNALS | 873 | # if ENABLE_FEATURE_BC_SIGNALS |
881 | static const char bc_sig_msg[] = "\ninterrupt (type \"quit\" to exit)\n"; | 874 | static const char bc_sig_msg[] = "\ninterrupt (type \"quit\" to exit)\n"; |
882 | # endif | 875 | # endif |
883 | #endif | 876 | #endif |
884 | 877 | ||
885 | #if ENABLE_DC | 878 | #if ENABLE_DC |
886 | static const char dc_name[] = "dc"; | ||
887 | # if ENABLE_FEATURE_BC_SIGNALS | 879 | # if ENABLE_FEATURE_BC_SIGNALS |
888 | static const char dc_sig_msg[] = "\ninterrupt (type \"q\" to exit)\n"; | 880 | static const char dc_sig_msg[] = "\ninterrupt (type \"q\" to exit)\n"; |
889 | # endif | 881 | # endif |
890 | #endif | 882 | #endif |
891 | 883 | ||
892 | static const char bc_copyright[] = | ||
893 | "Copyright (c) 2018 Gavin D. Howard and contributors\n" | ||
894 | "Report bugs at: https://github.com/gavinhoward/bc\n\n" | ||
895 | "This is free software with ABSOLUTELY NO WARRANTY.\n"; | ||
896 | |||
897 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; | 884 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; |
898 | 885 | ||
899 | static const char bc_err_fmt[] = "\n%s error: %s\n"; | 886 | static const char bc_err_fmt[] = "\n%s error: %s\n"; |
@@ -1386,18 +1373,22 @@ static size_t bc_map_index(const BcVec *v, const void *ptr) | |||
1386 | static BcStatus bc_read_line(BcVec *vec, const char *prompt) | 1373 | static BcStatus bc_read_line(BcVec *vec, const char *prompt) |
1387 | { | 1374 | { |
1388 | int i; | 1375 | int i; |
1389 | signed char c = 0; | 1376 | signed char c; |
1390 | 1377 | ||
1391 | if (bcg.ttyin && !bcg.posix) { | 1378 | if (bcg.ttyin && !bcg.posix) { |
1392 | bc_vm_puts(prompt, stderr); | 1379 | fputs(prompt, stderr); |
1393 | bc_vm_fflush(stderr); | 1380 | fflush(stderr); |
1394 | } | 1381 | } |
1395 | 1382 | ||
1396 | bc_vec_npop(vec, vec->len); | 1383 | bc_vec_npop(vec, vec->len); |
1397 | 1384 | ||
1398 | while (c != '\n') { | 1385 | do { |
1386 | if (ferror(stdout) || ferror(stderr)) | ||
1387 | bb_perror_msg_and_die("output error"); | ||
1399 | 1388 | ||
1400 | i = fgetc(stdin); | 1389 | i = fgetc(stdin); |
1390 | if (ferror(stdin)) | ||
1391 | bb_perror_msg_and_die("input error"); | ||
1401 | 1392 | ||
1402 | if (i == EOF) { | 1393 | if (i == EOF) { |
1403 | 1394 | ||
@@ -1408,22 +1399,22 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt) | |||
1408 | bcg.signe = 0; | 1399 | bcg.signe = 0; |
1409 | 1400 | ||
1410 | if (bcg.ttyin) { | 1401 | if (bcg.ttyin) { |
1411 | bc_vm_puts(bc_program_ready_msg, stderr); | 1402 | fputs(bc_program_ready_msg, stderr); |
1412 | if (!bcg.posix) bc_vm_puts(prompt, stderr); | 1403 | if (!bcg.posix) fputs(prompt, stderr); |
1413 | bc_vm_fflush(stderr); | 1404 | fflush(stderr); |
1414 | } | 1405 | } |
1415 | 1406 | ||
1416 | continue; | 1407 | continue; |
1417 | } | 1408 | } |
1418 | #endif | 1409 | #endif |
1419 | 1410 | ||
1420 | return BC_STATUS_IO_ERR; | 1411 | return BC_STATUS_INPUT_EOF; |
1421 | } | 1412 | } |
1422 | 1413 | ||
1423 | c = (signed char) i; | 1414 | c = (signed char) i; |
1424 | if (i > UCHAR_MAX || BC_READ_BIN_CHAR(c)) return BC_STATUS_BIN_FILE; | 1415 | if (i > UCHAR_MAX || BC_READ_BIN_CHAR(c)) return BC_STATUS_BIN_FILE; |
1425 | bc_vec_push(vec, &c); | 1416 | bc_vec_push(vec, &c); |
1426 | } | 1417 | } while (c != '\n'); |
1427 | 1418 | ||
1428 | bc_vec_pushByte(vec, '\0'); | 1419 | bc_vec_pushByte(vec, '\0'); |
1429 | 1420 | ||
@@ -1477,7 +1468,7 @@ static BcStatus bc_args(int argc, char *argv[], uint32_t *flags, BcVec *files) | |||
1477 | *flags = getopt32(argv, bc_args_opt); | 1468 | *flags = getopt32(argv, bc_args_opt); |
1478 | #endif | 1469 | #endif |
1479 | 1470 | ||
1480 | if ((*flags) & BC_FLAG_V) bc_vm_info(NULL); | 1471 | if ((*flags) & BC_FLAG_V) bc_vm_info(); |
1481 | if (do_exit) exit((int) s); | 1472 | if (do_exit) exit((int) s); |
1482 | if (argv[optind] && !strcmp(argv[optind], "--")) ++optind; | 1473 | if (argv[optind] && !strcmp(argv[optind], "--")) ++optind; |
1483 | 1474 | ||
@@ -2329,8 +2320,8 @@ int_err: | |||
2329 | static void bc_num_printNewline(size_t *nchars, size_t line_len) | 2320 | static void bc_num_printNewline(size_t *nchars, size_t line_len) |
2330 | { | 2321 | { |
2331 | if (*nchars == line_len - 1) { | 2322 | if (*nchars == line_len - 1) { |
2332 | bc_vm_putchar('\\'); | 2323 | bb_putchar('\\'); |
2333 | bc_vm_putchar('\n'); | 2324 | bb_putchar('\n'); |
2334 | *nchars = 0; | 2325 | *nchars = 0; |
2335 | } | 2326 | } |
2336 | } | 2327 | } |
@@ -2340,7 +2331,7 @@ static void bc_num_printChar(size_t num, size_t width, bool radix, | |||
2340 | size_t *nchars, size_t line_len) | 2331 | size_t *nchars, size_t line_len) |
2341 | { | 2332 | { |
2342 | (void) radix, (void) line_len; | 2333 | (void) radix, (void) line_len; |
2343 | bc_vm_putchar((char) num); | 2334 | bb_putchar((char) num); |
2344 | *nchars = *nchars + width; | 2335 | *nchars = *nchars + width; |
2345 | } | 2336 | } |
2346 | #endif | 2337 | #endif |
@@ -2351,7 +2342,7 @@ static void bc_num_printDigits(size_t num, size_t width, bool radix, | |||
2351 | size_t exp, pow; | 2342 | size_t exp, pow; |
2352 | 2343 | ||
2353 | bc_num_printNewline(nchars, line_len); | 2344 | bc_num_printNewline(nchars, line_len); |
2354 | bc_vm_putchar(radix ? '.' : ' '); | 2345 | bb_putchar(radix ? '.' : ' '); |
2355 | ++(*nchars); | 2346 | ++(*nchars); |
2356 | 2347 | ||
2357 | bc_num_printNewline(nchars, line_len); | 2348 | bc_num_printNewline(nchars, line_len); |
@@ -2363,7 +2354,7 @@ static void bc_num_printDigits(size_t num, size_t width, bool radix, | |||
2363 | bc_num_printNewline(nchars, line_len); | 2354 | bc_num_printNewline(nchars, line_len); |
2364 | dig = num / pow; | 2355 | dig = num / pow; |
2365 | num -= dig * pow; | 2356 | num -= dig * pow; |
2366 | bc_vm_putchar(((char) dig) + '0'); | 2357 | bb_putchar(((char) dig) + '0'); |
2367 | } | 2358 | } |
2368 | } | 2359 | } |
2369 | 2360 | ||
@@ -2372,12 +2363,12 @@ static void bc_num_printHex(size_t num, size_t width, bool radix, | |||
2372 | { | 2363 | { |
2373 | if (radix) { | 2364 | if (radix) { |
2374 | bc_num_printNewline(nchars, line_len); | 2365 | bc_num_printNewline(nchars, line_len); |
2375 | bc_vm_putchar('.'); | 2366 | bb_putchar('.'); |
2376 | *nchars += 1; | 2367 | *nchars += 1; |
2377 | } | 2368 | } |
2378 | 2369 | ||
2379 | bc_num_printNewline(nchars, line_len); | 2370 | bc_num_printNewline(nchars, line_len); |
2380 | bc_vm_putchar(bb_hexdigits_upcase[num]); | 2371 | bb_putchar(bb_hexdigits_upcase[num]); |
2381 | *nchars = *nchars + width; | 2372 | *nchars = *nchars + width; |
2382 | } | 2373 | } |
2383 | 2374 | ||
@@ -2385,7 +2376,7 @@ static void bc_num_printDecimal(BcNum *n, size_t *nchars, size_t len) | |||
2385 | { | 2376 | { |
2386 | size_t i, rdx = n->rdx - 1; | 2377 | size_t i, rdx = n->rdx - 1; |
2387 | 2378 | ||
2388 | if (n->neg) bc_vm_putchar('-'); | 2379 | if (n->neg) bb_putchar('-'); |
2389 | (*nchars) += n->neg; | 2380 | (*nchars) += n->neg; |
2390 | 2381 | ||
2391 | for (i = n->len - 1; i < n->len; --i) | 2382 | for (i = n->len - 1; i < n->len; --i) |
@@ -2465,7 +2456,7 @@ static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, | |||
2465 | BcNumDigitOp print; | 2456 | BcNumDigitOp print; |
2466 | bool neg = n->neg; | 2457 | bool neg = n->neg; |
2467 | 2458 | ||
2468 | if (neg) bc_vm_putchar('-'); | 2459 | if (neg) bb_putchar('-'); |
2469 | (*nchars) += neg; | 2460 | (*nchars) += neg; |
2470 | 2461 | ||
2471 | n->neg = false; | 2462 | n->neg = false; |
@@ -2546,7 +2537,7 @@ static BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, | |||
2546 | bc_num_printNewline(nchars, line_len); | 2537 | bc_num_printNewline(nchars, line_len); |
2547 | 2538 | ||
2548 | if (n->len == 0) { | 2539 | if (n->len == 0) { |
2549 | bc_vm_putchar('0'); | 2540 | bb_putchar('0'); |
2550 | ++(*nchars); | 2541 | ++(*nchars); |
2551 | } | 2542 | } |
2552 | else if (base_t == 10) | 2543 | else if (base_t == 10) |
@@ -2555,7 +2546,7 @@ static BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, | |||
2555 | s = bc_num_printBase(n, base, base_t, nchars, line_len); | 2546 | s = bc_num_printBase(n, base, base_t, nchars, line_len); |
2556 | 2547 | ||
2557 | if (newline) { | 2548 | if (newline) { |
2558 | bc_vm_putchar('\n'); | 2549 | bb_putchar('\n'); |
2559 | *nchars = 0; | 2550 | *nchars = 0; |
2560 | } | 2551 | } |
2561 | 2552 | ||
@@ -5577,7 +5568,7 @@ static void bc_program_printString(const char *str, size_t *nchars) | |||
5577 | 5568 | ||
5578 | #if ENABLE_DC | 5569 | #if ENABLE_DC |
5579 | if (len == 0) { | 5570 | if (len == 0) { |
5580 | bc_vm_putchar('\0'); | 5571 | bb_putchar('\0'); |
5581 | return; | 5572 | return; |
5582 | } | 5573 | } |
5583 | #endif | 5574 | #endif |
@@ -5587,7 +5578,7 @@ static void bc_program_printString(const char *str, size_t *nchars) | |||
5587 | int c = str[i]; | 5578 | int c = str[i]; |
5588 | 5579 | ||
5589 | if (c != '\\' || i == len - 1) | 5580 | if (c != '\\' || i == len - 1) |
5590 | bc_vm_putchar(c); | 5581 | bb_putchar(c); |
5591 | else { | 5582 | else { |
5592 | 5583 | ||
5593 | c = str[++i]; | 5584 | c = str[++i]; |
@@ -5596,60 +5587,60 @@ static void bc_program_printString(const char *str, size_t *nchars) | |||
5596 | 5587 | ||
5597 | case 'a': | 5588 | case 'a': |
5598 | { | 5589 | { |
5599 | bc_vm_putchar('\a'); | 5590 | bb_putchar('\a'); |
5600 | break; | 5591 | break; |
5601 | } | 5592 | } |
5602 | 5593 | ||
5603 | case 'b': | 5594 | case 'b': |
5604 | { | 5595 | { |
5605 | bc_vm_putchar('\b'); | 5596 | bb_putchar('\b'); |
5606 | break; | 5597 | break; |
5607 | } | 5598 | } |
5608 | 5599 | ||
5609 | case '\\': | 5600 | case '\\': |
5610 | case 'e': | 5601 | case 'e': |
5611 | { | 5602 | { |
5612 | bc_vm_putchar('\\'); | 5603 | bb_putchar('\\'); |
5613 | break; | 5604 | break; |
5614 | } | 5605 | } |
5615 | 5606 | ||
5616 | case 'f': | 5607 | case 'f': |
5617 | { | 5608 | { |
5618 | bc_vm_putchar('\f'); | 5609 | bb_putchar('\f'); |
5619 | break; | 5610 | break; |
5620 | } | 5611 | } |
5621 | 5612 | ||
5622 | case 'n': | 5613 | case 'n': |
5623 | { | 5614 | { |
5624 | bc_vm_putchar('\n'); | 5615 | bb_putchar('\n'); |
5625 | *nchars = SIZE_MAX; | 5616 | *nchars = SIZE_MAX; |
5626 | break; | 5617 | break; |
5627 | } | 5618 | } |
5628 | 5619 | ||
5629 | case 'r': | 5620 | case 'r': |
5630 | { | 5621 | { |
5631 | bc_vm_putchar('\r'); | 5622 | bb_putchar('\r'); |
5632 | break; | 5623 | break; |
5633 | } | 5624 | } |
5634 | 5625 | ||
5635 | case 'q': | 5626 | case 'q': |
5636 | { | 5627 | { |
5637 | bc_vm_putchar('"'); | 5628 | bb_putchar('"'); |
5638 | break; | 5629 | break; |
5639 | } | 5630 | } |
5640 | 5631 | ||
5641 | case 't': | 5632 | case 't': |
5642 | { | 5633 | { |
5643 | bc_vm_putchar('\t'); | 5634 | bb_putchar('\t'); |
5644 | break; | 5635 | break; |
5645 | } | 5636 | } |
5646 | 5637 | ||
5647 | default: | 5638 | default: |
5648 | { | 5639 | { |
5649 | // Just print the backslash and following character. | 5640 | // Just print the backslash and following character. |
5650 | bc_vm_putchar('\\'); | 5641 | bb_putchar('\\'); |
5651 | ++(*nchars); | 5642 | ++(*nchars); |
5652 | bc_vm_putchar(c); | 5643 | bb_putchar(c); |
5653 | break; | 5644 | break; |
5654 | } | 5645 | } |
5655 | } | 5646 | } |
@@ -5684,14 +5675,14 @@ static BcStatus bc_program_print(BcProgram *p, char inst, size_t idx) | |||
5684 | if (inst == BC_INST_PRINT_STR) { | 5675 | if (inst == BC_INST_PRINT_STR) { |
5685 | for (i = 0, len = strlen(str); i < len; ++i) { | 5676 | for (i = 0, len = strlen(str); i < len; ++i) { |
5686 | char c = str[i]; | 5677 | char c = str[i]; |
5687 | bc_vm_putchar(c); | 5678 | bb_putchar(c); |
5688 | if (c == '\n') p->nchars = SIZE_MAX; | 5679 | if (c == '\n') p->nchars = SIZE_MAX; |
5689 | ++p->nchars; | 5680 | ++p->nchars; |
5690 | } | 5681 | } |
5691 | } | 5682 | } |
5692 | else { | 5683 | else { |
5693 | bc_program_printString(str, &p->nchars); | 5684 | bc_program_printString(str, &p->nchars); |
5694 | if (inst == BC_INST_PRINT) bc_vm_putchar('\n'); | 5685 | if (inst == BC_INST_PRINT) bb_putchar('\n'); |
5695 | } | 5686 | } |
5696 | } | 5687 | } |
5697 | 5688 | ||
@@ -6392,7 +6383,7 @@ static BcStatus bc_program_printStream(BcProgram *p) | |||
6392 | else { | 6383 | else { |
6393 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; | 6384 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; |
6394 | str = *((char **) bc_vec_item(&p->strs, idx)); | 6385 | str = *((char **) bc_vec_item(&p->strs, idx)); |
6395 | bc_vm_printf(stdout, "%s", str); | 6386 | printf("%s", str); |
6396 | } | 6387 | } |
6397 | 6388 | ||
6398 | return s; | 6389 | return s; |
@@ -6685,8 +6676,8 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s) | |||
6685 | 6676 | ||
6686 | if (!s || s == BC_STATUS_EXEC_SIGNAL) { | 6677 | if (!s || s == BC_STATUS_EXEC_SIGNAL) { |
6687 | if (bcg.ttyin) { | 6678 | if (bcg.ttyin) { |
6688 | bc_vm_puts(bc_program_ready_msg, stderr); | 6679 | fputs(bc_program_ready_msg, stderr); |
6689 | bc_vm_fflush(stderr); | 6680 | fflush(stderr); |
6690 | s = BC_STATUS_SUCCESS; | 6681 | s = BC_STATUS_SUCCESS; |
6691 | } | 6682 | } |
6692 | else | 6683 | else |
@@ -7029,20 +7020,22 @@ static void bc_vm_sig(int sig) | |||
7029 | } | 7020 | } |
7030 | #endif | 7021 | #endif |
7031 | 7022 | ||
7032 | static void bc_vm_info(const char *const help) | 7023 | static void bc_vm_info(void) |
7033 | { | 7024 | { |
7034 | bc_vm_printf(stdout, "%s %s\n", bcg.name, "1.1"); | 7025 | printf("%s "BB_VER"\n" |
7035 | bc_vm_puts(bc_copyright, stdout); | 7026 | "Copyright (c) 2018 Gavin D. Howard and contributors\n" |
7036 | if (help) bc_vm_printf(stdout, help, bcg.name); | 7027 | "Report bugs at: https://github.com/gavinhoward/bc\n\n" |
7028 | "This is free software with ABSOLUTELY NO WARRANTY\n" | ||
7029 | , applet_name); | ||
7037 | } | 7030 | } |
7038 | 7031 | ||
7039 | static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line) | 7032 | static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line) |
7040 | { | 7033 | { |
7041 | if (!s || s > BC_STATUS_VEC_ITEM_EXISTS) return s; | 7034 | if (!s || s > BC_STATUS_VEC_ITEM_EXISTS) return s; |
7042 | 7035 | ||
7043 | bc_vm_printf(stderr, bc_err_fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]); | 7036 | fprintf(stderr, bc_err_fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]); |
7044 | bc_vm_printf(stderr, " %s", file); | 7037 | fprintf(stderr, " %s", file); |
7045 | bc_vm_printf(stderr, bc_err_line + 4 * !line, line); | 7038 | fprintf(stderr, bc_err_line + 4 * !line, line); |
7046 | 7039 | ||
7047 | return s * (!bcg.ttyin || !!strcmp(file, bc_program_stdin_name)); | 7040 | return s * (!bcg.ttyin || !!strcmp(file, bc_program_stdin_name)); |
7048 | } | 7041 | } |
@@ -7056,10 +7049,10 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | |||
7056 | 7049 | ||
7057 | if (!(p || w) || s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS; | 7050 | if (!(p || w) || s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS; |
7058 | 7051 | ||
7059 | bc_vm_printf(stderr, fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]); | 7052 | fprintf(stderr, fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]); |
7060 | if (msg) bc_vm_printf(stderr, " %s\n", msg); | 7053 | if (msg) fprintf(stderr, " %s\n", msg); |
7061 | bc_vm_printf(stderr, " %s", file); | 7054 | fprintf(stderr, " %s", file); |
7062 | bc_vm_printf(stderr, bc_err_line + 4 * !line, line); | 7055 | fprintf(stderr, bc_err_line + 4 * !line, line); |
7063 | 7056 | ||
7064 | return s * (!bcg.ttyin && !!p); | 7057 | return s * (!bcg.ttyin && !!p); |
7065 | } | 7058 | } |
@@ -7117,39 +7110,6 @@ static size_t bc_vm_envLen(const char *var) | |||
7117 | return len; | 7110 | return len; |
7118 | } | 7111 | } |
7119 | 7112 | ||
7120 | static void bc_vm_exit(BcStatus s) | ||
7121 | { | ||
7122 | bc_vm_printf(stderr, bc_err_fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]); | ||
7123 | exit((int) s); | ||
7124 | } | ||
7125 | |||
7126 | static void bc_vm_printf(FILE *restrict f, const char *fmt, ...) | ||
7127 | { | ||
7128 | va_list args; | ||
7129 | bool bad; | ||
7130 | |||
7131 | va_start(args, fmt); | ||
7132 | bad = vfprintf(f, fmt, args) < 0; | ||
7133 | va_end(args); | ||
7134 | |||
7135 | if (bad) bc_vm_exit(BC_STATUS_IO_ERR); | ||
7136 | } | ||
7137 | |||
7138 | static void bc_vm_puts(const char *str, FILE *restrict f) | ||
7139 | { | ||
7140 | if (fputs(str, f) == EOF) bc_vm_exit(BC_STATUS_IO_ERR); | ||
7141 | } | ||
7142 | |||
7143 | static void bc_vm_putchar(int c) | ||
7144 | { | ||
7145 | if (putchar(c) == EOF) bc_vm_exit(BC_STATUS_IO_ERR); | ||
7146 | } | ||
7147 | |||
7148 | static void bc_vm_fflush(FILE *restrict f) | ||
7149 | { | ||
7150 | if (fflush(f) == EOF) bc_vm_exit(BC_STATUS_IO_ERR); | ||
7151 | } | ||
7152 | |||
7153 | static BcStatus bc_vm_process(BcVm *vm, const char *text) | 7113 | static BcStatus bc_vm_process(BcVm *vm, const char *text) |
7154 | { | 7114 | { |
7155 | BcStatus s = bc_parse_text(&vm->prs, text); | 7115 | BcStatus s = bc_parse_text(&vm->prs, text); |
@@ -7163,16 +7123,16 @@ static BcStatus bc_vm_process(BcVm *vm, const char *text) | |||
7163 | 7123 | ||
7164 | if (s == BC_STATUS_LIMITS) { | 7124 | if (s == BC_STATUS_LIMITS) { |
7165 | 7125 | ||
7166 | bc_vm_putchar('\n'); | 7126 | bb_putchar('\n'); |
7167 | bc_vm_printf(stdout, "BC_BASE_MAX = %lu\n", BC_MAX_OBASE); | 7127 | printf("BC_BASE_MAX = %lu\n", BC_MAX_OBASE); |
7168 | bc_vm_printf(stdout, "BC_DIM_MAX = %lu\n", BC_MAX_DIM); | 7128 | printf("BC_DIM_MAX = %lu\n", BC_MAX_DIM); |
7169 | bc_vm_printf(stdout, "BC_SCALE_MAX = %lu\n", BC_MAX_SCALE); | 7129 | printf("BC_SCALE_MAX = %lu\n", BC_MAX_SCALE); |
7170 | bc_vm_printf(stdout, "BC_STRING_MAX = %lu\n", BC_MAX_STRING); | 7130 | printf("BC_STRING_MAX = %lu\n", BC_MAX_STRING); |
7171 | bc_vm_printf(stdout, "BC_NAME_MAX = %lu\n", BC_MAX_NAME); | 7131 | printf("BC_NAME_MAX = %lu\n", BC_MAX_NAME); |
7172 | bc_vm_printf(stdout, "BC_NUM_MAX = %lu\n", BC_MAX_NUM); | 7132 | printf("BC_NUM_MAX = %lu\n", BC_MAX_NUM); |
7173 | bc_vm_printf(stdout, "Max Exponent = %lu\n", BC_MAX_EXP); | 7133 | printf("Max Exponent = %lu\n", BC_MAX_EXP); |
7174 | bc_vm_printf(stdout, "Number of Vars = %lu\n", BC_MAX_VARS); | 7134 | printf("Number of Vars = %lu\n", BC_MAX_VARS); |
7175 | bc_vm_putchar('\n'); | 7135 | bb_putchar('\n'); |
7176 | 7136 | ||
7177 | s = BC_STATUS_SUCCESS; | 7137 | s = BC_STATUS_SUCCESS; |
7178 | } | 7138 | } |
@@ -7185,7 +7145,7 @@ static BcStatus bc_vm_process(BcVm *vm, const char *text) | |||
7185 | 7145 | ||
7186 | if (BC_PARSE_CAN_EXEC(&vm->prs)) { | 7146 | if (BC_PARSE_CAN_EXEC(&vm->prs)) { |
7187 | s = bc_program_exec(&vm->prog); | 7147 | s = bc_program_exec(&vm->prog); |
7188 | if (!s && bcg.tty) bc_vm_fflush(stdout); | 7148 | if (!s && bcg.tty) fflush(stdout); |
7189 | if (s && s != BC_STATUS_QUIT) | 7149 | if (s && s != BC_STATUS_QUIT) |
7190 | s = bc_vm_error(bc_program_reset(&vm->prog, s), vm->prs.l.f, 0); | 7150 | s = bc_vm_error(bc_program_reset(&vm->prog, s), vm->prs.l.f, 0); |
7191 | } | 7151 | } |
@@ -7290,7 +7250,8 @@ static BcStatus bc_vm_stdin(BcVm *vm) | |||
7290 | 7250 | ||
7291 | // I/O error will always happen when stdin is | 7251 | // I/O error will always happen when stdin is |
7292 | // closed. It's not a problem in that case. | 7252 | // closed. It's not a problem in that case. |
7293 | s = s == BC_STATUS_IO_ERR || s == BC_STATUS_QUIT ? BC_STATUS_SUCCESS : s; | 7253 | if (s == BC_STATUS_INPUT_EOF || s == BC_STATUS_QUIT) |
7254 | s = BC_STATUS_SUCCESS; | ||
7294 | 7255 | ||
7295 | if (str) | 7256 | if (str) |
7296 | s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, vm->prs.l.f, | 7257 | s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, vm->prs.l.f, |
@@ -7328,10 +7289,12 @@ static BcStatus bc_vm_exec(BcVm *vm) | |||
7328 | s = bc_vm_file(vm, *((char **) bc_vec_item(&vm->files, i))); | 7289 | s = bc_vm_file(vm, *((char **) bc_vec_item(&vm->files, i))); |
7329 | if (s && s != BC_STATUS_QUIT) return s; | 7290 | if (s && s != BC_STATUS_QUIT) return s; |
7330 | 7291 | ||
7331 | if (bcg.bc || !vm->files.len) s = bc_vm_stdin(vm); | 7292 | if (IS_BC || !vm->files.len) s = bc_vm_stdin(vm); |
7332 | if (!s && !BC_PARSE_CAN_EXEC(&vm->prs)) s = bc_vm_process(vm, ""); | 7293 | if (!s && !BC_PARSE_CAN_EXEC(&vm->prs)) s = bc_vm_process(vm, ""); |
7333 | 7294 | ||
7334 | return s == BC_STATUS_QUIT ? BC_STATUS_SUCCESS : s; | 7295 | if (s == BC_STATUS_QUIT) |
7296 | s = BC_STATUS_SUCCESS; | ||
7297 | return s; | ||
7335 | } | 7298 | } |
7336 | 7299 | ||
7337 | static void bc_vm_free(BcVm *vm) | 7300 | static void bc_vm_free(BcVm *vm) |
@@ -7364,8 +7327,8 @@ static BcStatus bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) | |||
7364 | bc_vec_init(&vm->files, sizeof(char *), NULL); | 7327 | bc_vec_init(&vm->files, sizeof(char *), NULL); |
7365 | 7328 | ||
7366 | #if ENABLE_BC | 7329 | #if ENABLE_BC |
7367 | vm->flags |= BC_FLAG_S * bcg.bc * (getenv("POSIXLY_CORRECT") != NULL); | 7330 | vm->flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL); |
7368 | if (bcg.bc) s = bc_vm_envArgs(vm); | 7331 | if (IS_BC) s = bc_vm_envArgs(vm); |
7369 | #endif | 7332 | #endif |
7370 | 7333 | ||
7371 | bc_program_init(&vm->prog, len, exe.init, exe.exp); | 7334 | bc_program_init(&vm->prog, len, exe.init, exe.exp); |
@@ -7396,7 +7359,7 @@ static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | |||
7396 | bcg.exreg = vm.flags & BC_FLAG_X; | 7359 | bcg.exreg = vm.flags & BC_FLAG_X; |
7397 | #endif | 7360 | #endif |
7398 | 7361 | ||
7399 | if (bcg.ttyin && !(vm.flags & BC_FLAG_Q)) bc_vm_info(NULL); | 7362 | if (bcg.ttyin && !(vm.flags & BC_FLAG_Q)) bc_vm_info(); |
7400 | st = bc_vm_exec(&vm); | 7363 | st = bc_vm_exec(&vm); |
7401 | 7364 | ||
7402 | exit: | 7365 | exit: |
@@ -7409,8 +7372,6 @@ BcStatus bc_main(int argc, char *argv[]) | |||
7409 | { | 7372 | { |
7410 | BcVmExe exec; | 7373 | BcVmExe exec; |
7411 | 7374 | ||
7412 | bcg.bc = true; | ||
7413 | bcg.name = bc_name; | ||
7414 | # if ENABLE_FEATURE_BC_SIGNALS | 7375 | # if ENABLE_FEATURE_BC_SIGNALS |
7415 | bcg.sig_msg = bc_sig_msg; | 7376 | bcg.sig_msg = bc_sig_msg; |
7416 | # endif | 7377 | # endif |
@@ -7428,8 +7389,6 @@ BcStatus dc_main(int argc, char *argv[]) | |||
7428 | { | 7389 | { |
7429 | BcVmExe exec; | 7390 | BcVmExe exec; |
7430 | 7391 | ||
7431 | bcg.bc = false; | ||
7432 | bcg.name = dc_name; | ||
7433 | # if ENABLE_FEATURE_BC_SIGNALS | 7392 | # if ENABLE_FEATURE_BC_SIGNALS |
7434 | bcg.sig_msg = dc_sig_msg; | 7393 | bcg.sig_msg = dc_sig_msg; |
7435 | # endif | 7394 | # endif |