diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-02 14:35:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | 5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603 (patch) | |
tree | 28f89868eec58b749cb3bae7e86aeb466996536d | |
parent | 00d7779a356f9827c0776ebbbe91c35f278b9a4c (diff) | |
download | busybox-w32-5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603.tar.gz busybox-w32-5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603.tar.bz2 busybox-w32-5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603.zip |
bc: simplify, and restore ^C, fix ^D handling
^D used to enter infinite loop
function old new delta
bc_read_line 342 359 +17
bc_args_opt 8 - -8
dc_sig_msg 31 - -31
bc_sig_msg 34 - -34
bc_vm_run 2608 2569 -39
bc_args 123 83 -40
bc_args_lopt 81 - -81
------------------------------------------------------------------------------
(add/remove: 0/4 grow/shrink: 1/2 up/down: 17/-233) Total: -216 bytes
text data bss dec hex filename
989491 485 7336 997312 f37c0 busybox_old
989425 485 7336 997246 f377e busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 105 |
1 files changed, 34 insertions, 71 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index f36534c36..d5f577598 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -249,7 +249,6 @@ typedef enum BcStatus { | |||
249 | #define BC_VEC_START_CAP (1 << 5) | 249 | #define BC_VEC_START_CAP (1 << 5) |
250 | 250 | ||
251 | typedef void (*BcVecFree)(void *); | 251 | typedef void (*BcVecFree)(void *); |
252 | typedef int (*BcVecCmp)(const void *, const void *); | ||
253 | 252 | ||
254 | typedef struct BcVec { | 253 | typedef struct BcVec { |
255 | char *v; | 254 | char *v; |
@@ -691,8 +690,6 @@ typedef struct BcParse { | |||
691 | 690 | ||
692 | #if ENABLE_BC | 691 | #if ENABLE_BC |
693 | 692 | ||
694 | BcStatus bc_main(int argc, char *argv[]); | ||
695 | |||
696 | typedef struct BcLexKeyword { | 693 | typedef struct BcLexKeyword { |
697 | const char name[9]; | 694 | const char name[9]; |
698 | const char len; | 695 | const char len; |
@@ -725,8 +722,6 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next); | |||
725 | 722 | ||
726 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) | 723 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) |
727 | 724 | ||
728 | BcStatus dc_main(int argc, char *argv[]); | ||
729 | |||
730 | static BcStatus dc_lex_token(BcLex *l); | 725 | static BcStatus dc_lex_token(BcLex *l); |
731 | 726 | ||
732 | static void dc_parse_init(BcParse *p, struct BcProgram *prog, size_t func); | 727 | static void dc_parse_init(BcParse *p, struct BcProgram *prog, size_t func); |
@@ -864,23 +859,9 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | |||
864 | #endif | 859 | #endif |
865 | 860 | ||
866 | static void bc_vm_info(void); | 861 | static void bc_vm_info(void); |
867 | static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | ||
868 | const char *env_len); | ||
869 | 862 | ||
870 | static BcGlobals bcg; | 863 | static BcGlobals bcg; |
871 | 864 | ||
872 | #if ENABLE_BC | ||
873 | # if ENABLE_FEATURE_BC_SIGNALS | ||
874 | static const char bc_sig_msg[] = "\ninterrupt (type \"quit\" to exit)\n"; | ||
875 | # endif | ||
876 | #endif | ||
877 | |||
878 | #if ENABLE_DC | ||
879 | # if ENABLE_FEATURE_BC_SIGNALS | ||
880 | static const char dc_sig_msg[] = "\ninterrupt (type \"q\" to exit)\n"; | ||
881 | # endif | ||
882 | #endif | ||
883 | |||
884 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; | 865 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; |
885 | 866 | ||
886 | static const char bc_err_fmt[] = "\n%s error: %s\n"; | 867 | static const char bc_err_fmt[] = "\n%s error: %s\n"; |
@@ -1386,28 +1367,25 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt) | |||
1386 | if (ferror(stdout) || ferror(stderr)) | 1367 | if (ferror(stdout) || ferror(stderr)) |
1387 | bb_perror_msg_and_die("output error"); | 1368 | bb_perror_msg_and_die("output error"); |
1388 | 1369 | ||
1370 | errno = 0; | ||
1389 | i = fgetc(stdin); | 1371 | i = fgetc(stdin); |
1390 | if (ferror(stdin)) | ||
1391 | bb_perror_msg_and_die("input error"); | ||
1392 | 1372 | ||
1393 | if (i == EOF) { | 1373 | if (i == EOF) { |
1394 | |||
1395 | #if ENABLE_FEATURE_BC_SIGNALS | 1374 | #if ENABLE_FEATURE_BC_SIGNALS |
1396 | if (errno == EINTR) { | 1375 | if (errno == EINTR) { |
1397 | |||
1398 | bcg.sigc = bcg.sig; | 1376 | bcg.sigc = bcg.sig; |
1399 | bcg.signe = 0; | 1377 | bcg.signe = 0; |
1400 | |||
1401 | if (bcg.ttyin) { | 1378 | if (bcg.ttyin) { |
1402 | fputs(bc_program_ready_msg, stderr); | 1379 | fputs(bc_program_ready_msg, stderr); |
1403 | if (!bcg.posix) fputs(prompt, stderr); | 1380 | if (!bcg.posix) fputs(prompt, stderr); |
1404 | fflush(stderr); | 1381 | fflush(stderr); |
1405 | } | 1382 | } |
1406 | 1383 | clearerr(stdin); | |
1407 | continue; | 1384 | continue; |
1408 | } | 1385 | } |
1386 | if (ferror(stdin)) | ||
1387 | bb_perror_msg_and_die("input error"); | ||
1409 | #endif | 1388 | #endif |
1410 | |||
1411 | return BC_STATUS_INPUT_EOF; | 1389 | return BC_STATUS_INPUT_EOF; |
1412 | } | 1390 | } |
1413 | 1391 | ||
@@ -1441,40 +1419,32 @@ read_err: | |||
1441 | return s; | 1419 | return s; |
1442 | } | 1420 | } |
1443 | 1421 | ||
1444 | #if ENABLE_FEATURE_BC_LONG_OPTIONS | 1422 | static void bc_args(int argc, char *argv[], uint32_t *flags, BcVec *files) |
1445 | static const char bc_args_lopt[] ALIGN1 = | ||
1446 | "extended-register\0"No_argument"x" | ||
1447 | "warn\0"No_argument"w" | ||
1448 | "version\0"No_argument"v" | ||
1449 | "standard\0"No_argument"s" | ||
1450 | "quiet\0"No_argument"q" | ||
1451 | "mathlib\0"No_argument"l" | ||
1452 | "interactive\0"No_argument"i"; | ||
1453 | #endif | ||
1454 | |||
1455 | static const char bc_args_opt[] ALIGN1 = "xwvsqli"; | ||
1456 | |||
1457 | static BcStatus bc_args(int argc, char *argv[], uint32_t *flags, BcVec *files) | ||
1458 | { | 1423 | { |
1459 | BcStatus s = BC_STATUS_SUCCESS; | ||
1460 | int i; | 1424 | int i; |
1461 | bool do_exit = false; | 1425 | bool do_exit = false; |
1462 | 1426 | ||
1463 | i = optind = 0; | 1427 | GETOPT_RESET(); |
1464 | |||
1465 | #if ENABLE_FEATURE_BC_LONG_OPTIONS | 1428 | #if ENABLE_FEATURE_BC_LONG_OPTIONS |
1466 | *flags = getopt32long(argv, bc_args_opt, bc_args_lopt); | 1429 | *flags = getopt32long(argv, "xwvsqli", |
1430 | "extended-register\0" No_argument "x" | ||
1431 | "warn\0" No_argument "w" | ||
1432 | "version\0" No_argument "v" | ||
1433 | "standard\0" No_argument "s" | ||
1434 | "quiet\0" No_argument "q" | ||
1435 | "mathlib\0" No_argument "l" | ||
1436 | "interactive\0" No_argument "i" | ||
1437 | ); | ||
1467 | #else | 1438 | #else |
1468 | *flags = getopt32(argv, bc_args_opt); | 1439 | *flags = getopt32(argv, "xwvsqli"); |
1469 | #endif | 1440 | #endif |
1470 | 1441 | ||
1471 | if ((*flags) & BC_FLAG_V) bc_vm_info(); | 1442 | if ((*flags) & BC_FLAG_V) bc_vm_info(); |
1472 | if (do_exit) exit((int) s); | 1443 | if (do_exit) exit(0); |
1473 | if (argv[optind] && !strcmp(argv[optind], "--")) ++optind; | 1444 | // should not be necessary, getopt32() handles this?? |
1445 | //if (argv[optind] && !strcmp(argv[optind], "--")) ++optind; | ||
1474 | 1446 | ||
1475 | for (i = optind; i < argc; ++i) bc_vec_push(files, argv + i); | 1447 | for (i = optind; i < argc; ++i) bc_vec_push(files, argv + i); |
1476 | |||
1477 | return s; | ||
1478 | } | 1448 | } |
1479 | 1449 | ||
1480 | static void bc_num_setToZero(BcNum *n, size_t scale) | 1450 | static void bc_num_setToZero(BcNum *n, size_t scale) |
@@ -7024,7 +6994,7 @@ static void bc_vm_info(void) | |||
7024 | { | 6994 | { |
7025 | printf("%s "BB_VER"\n" | 6995 | printf("%s "BB_VER"\n" |
7026 | "Copyright (c) 2018 Gavin D. Howard and contributors\n" | 6996 | "Copyright (c) 2018 Gavin D. Howard and contributors\n" |
7027 | "Report bugs at: https://github.com/gavinhoward/bc\n\n" | 6997 | "Report bugs at: https://github.com/gavinhoward/bc\n" |
7028 | "This is free software with ABSOLUTELY NO WARRANTY\n" | 6998 | "This is free software with ABSOLUTELY NO WARRANTY\n" |
7029 | , applet_name); | 6999 | , applet_name); |
7030 | } | 7000 | } |
@@ -7057,13 +7027,12 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | |||
7057 | return s * (!bcg.ttyin && !!p); | 7027 | return s * (!bcg.ttyin && !!p); |
7058 | } | 7028 | } |
7059 | 7029 | ||
7060 | static BcStatus bc_vm_envArgs(BcVm *vm) | 7030 | static void bc_vm_envArgs(BcVm *vm) |
7061 | { | 7031 | { |
7062 | BcStatus s = BC_STATUS_SUCCESS; | ||
7063 | BcVec v; | 7032 | BcVec v; |
7064 | char *env_args = getenv(bc_args_env_name), *buf; | 7033 | char *env_args = getenv(bc_args_env_name), *buf; |
7065 | 7034 | ||
7066 | if (!env_args) return s; | 7035 | if (!env_args) return; |
7067 | 7036 | ||
7068 | vm->env_args = xstrdup(env_args); | 7037 | vm->env_args = xstrdup(env_args); |
7069 | buf = vm->env_args; | 7038 | buf = vm->env_args; |
@@ -7081,11 +7050,9 @@ static BcStatus bc_vm_envArgs(BcVm *vm) | |||
7081 | ++buf; | 7050 | ++buf; |
7082 | } | 7051 | } |
7083 | 7052 | ||
7084 | s = bc_args((int) v.len, (char **) v.v, &vm->flags, &vm->files); | 7053 | bc_args((int) v.len, (char **) v.v, &vm->flags, &vm->files); |
7085 | 7054 | ||
7086 | bc_vec_free(&v); | 7055 | bc_vec_free(&v); |
7087 | |||
7088 | return s; | ||
7089 | } | 7056 | } |
7090 | #endif // ENABLE_BC | 7057 | #endif // ENABLE_BC |
7091 | 7058 | ||
@@ -7248,7 +7215,7 @@ static BcStatus bc_vm_stdin(BcVm *vm) | |||
7248 | 7215 | ||
7249 | if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, vm->prs.l.f, 0); | 7216 | if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, vm->prs.l.f, 0); |
7250 | 7217 | ||
7251 | // I/O error will always happen when stdin is | 7218 | // INPUT_EOF will always happen when stdin is |
7252 | // closed. It's not a problem in that case. | 7219 | // closed. It's not a problem in that case. |
7253 | if (s == BC_STATUS_INPUT_EOF || s == BC_STATUS_QUIT) | 7220 | if (s == BC_STATUS_INPUT_EOF || s == BC_STATUS_QUIT) |
7254 | s = BC_STATUS_SUCCESS; | 7221 | s = BC_STATUS_SUCCESS; |
@@ -7305,9 +7272,8 @@ static void bc_vm_free(BcVm *vm) | |||
7305 | free(vm->env_args); | 7272 | free(vm->env_args); |
7306 | } | 7273 | } |
7307 | 7274 | ||
7308 | static BcStatus bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) | 7275 | static void bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) |
7309 | { | 7276 | { |
7310 | BcStatus s = BC_STATUS_SUCCESS; | ||
7311 | size_t len = bc_vm_envLen(env_len); | 7277 | size_t len = bc_vm_envLen(env_len); |
7312 | #if ENABLE_FEATURE_BC_SIGNALS | 7278 | #if ENABLE_FEATURE_BC_SIGNALS |
7313 | struct sigaction sa; | 7279 | struct sigaction sa; |
@@ -7328,13 +7294,11 @@ static BcStatus bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) | |||
7328 | 7294 | ||
7329 | #if ENABLE_BC | 7295 | #if ENABLE_BC |
7330 | vm->flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL); | 7296 | vm->flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL); |
7331 | if (IS_BC) s = bc_vm_envArgs(vm); | 7297 | if (IS_BC) bc_vm_envArgs(vm); |
7332 | #endif | 7298 | #endif |
7333 | 7299 | ||
7334 | bc_program_init(&vm->prog, len, exe.init, exe.exp); | 7300 | bc_program_init(&vm->prog, len, exe.init, exe.exp); |
7335 | exe.init(&vm->prs, &vm->prog, BC_PROG_MAIN); | 7301 | exe.init(&vm->prs, &vm->prog, BC_PROG_MAIN); |
7336 | |||
7337 | return s; | ||
7338 | } | 7302 | } |
7339 | 7303 | ||
7340 | static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | 7304 | static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, |
@@ -7343,10 +7307,8 @@ static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | |||
7343 | BcStatus st; | 7307 | BcStatus st; |
7344 | BcVm vm; | 7308 | BcVm vm; |
7345 | 7309 | ||
7346 | st = bc_vm_init(&vm, exe, env_len); | 7310 | bc_vm_init(&vm, exe, env_len); |
7347 | if (st) goto exit; | 7311 | bc_args(argc, argv, &vm.flags, &vm.files); |
7348 | st = bc_args(argc, argv, &vm.flags, &vm.files); | ||
7349 | if (st) goto exit; | ||
7350 | 7312 | ||
7351 | bcg.ttyin = isatty(0); | 7313 | bcg.ttyin = isatty(0); |
7352 | bcg.tty = bcg.ttyin || (vm.flags & BC_FLAG_I) || isatty(1); | 7314 | bcg.tty = bcg.ttyin || (vm.flags & BC_FLAG_I) || isatty(1); |
@@ -7362,18 +7324,18 @@ static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, | |||
7362 | if (bcg.ttyin && !(vm.flags & BC_FLAG_Q)) bc_vm_info(); | 7324 | if (bcg.ttyin && !(vm.flags & BC_FLAG_Q)) bc_vm_info(); |
7363 | st = bc_vm_exec(&vm); | 7325 | st = bc_vm_exec(&vm); |
7364 | 7326 | ||
7365 | exit: | ||
7366 | bc_vm_free(&vm); | 7327 | bc_vm_free(&vm); |
7367 | return st; | 7328 | return st; |
7368 | } | 7329 | } |
7369 | 7330 | ||
7370 | #if ENABLE_BC | 7331 | #if ENABLE_BC |
7371 | BcStatus bc_main(int argc, char *argv[]) | 7332 | int bc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
7333 | int bc_main(int argc, char **argv) | ||
7372 | { | 7334 | { |
7373 | BcVmExe exec; | 7335 | BcVmExe exec; |
7374 | 7336 | ||
7375 | # if ENABLE_FEATURE_BC_SIGNALS | 7337 | # if ENABLE_FEATURE_BC_SIGNALS |
7376 | bcg.sig_msg = bc_sig_msg; | 7338 | bcg.sig_msg = "\ninterrupt (type \"quit\" to exit)\n"; |
7377 | # endif | 7339 | # endif |
7378 | 7340 | ||
7379 | exec.init = bc_parse_init; | 7341 | exec.init = bc_parse_init; |
@@ -7385,12 +7347,13 @@ BcStatus bc_main(int argc, char *argv[]) | |||
7385 | #endif | 7347 | #endif |
7386 | 7348 | ||
7387 | #if ENABLE_DC | 7349 | #if ENABLE_DC |
7388 | BcStatus dc_main(int argc, char *argv[]) | 7350 | int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
7351 | int dc_main(int argc, char **argv) | ||
7389 | { | 7352 | { |
7390 | BcVmExe exec; | 7353 | BcVmExe exec; |
7391 | 7354 | ||
7392 | # if ENABLE_FEATURE_BC_SIGNALS | 7355 | # if ENABLE_FEATURE_BC_SIGNALS |
7393 | bcg.sig_msg = dc_sig_msg; | 7356 | bcg.sig_msg = "\ninterrupt (type \"q\" to exit)\n"; |
7394 | # endif | 7357 | # endif |
7395 | 7358 | ||
7396 | exec.init = dc_parse_init; | 7359 | exec.init = dc_parse_init; |