aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-02 14:35:32 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 15:43:35 +0100
commit5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603 (patch)
tree28f89868eec58b749cb3bae7e86aeb466996536d
parent00d7779a356f9827c0776ebbbe91c35f278b9a4c (diff)
downloadbusybox-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.c105
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
251typedef void (*BcVecFree)(void *); 251typedef void (*BcVecFree)(void *);
252typedef int (*BcVecCmp)(const void *, const void *);
253 252
254typedef struct BcVec { 253typedef 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
694BcStatus bc_main(int argc, char *argv[]);
695
696typedef struct BcLexKeyword { 693typedef 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
728BcStatus dc_main(int argc, char *argv[]);
729
730static BcStatus dc_lex_token(BcLex *l); 725static BcStatus dc_lex_token(BcLex *l);
731 726
732static void dc_parse_init(BcParse *p, struct BcProgram *prog, size_t func); 727static 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
866static void bc_vm_info(void); 861static void bc_vm_info(void);
867static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe,
868 const char *env_len);
869 862
870static BcGlobals bcg; 863static BcGlobals bcg;
871 864
872#if ENABLE_BC
873# if ENABLE_FEATURE_BC_SIGNALS
874static 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
880static const char dc_sig_msg[] = "\ninterrupt (type \"q\" to exit)\n";
881# endif
882#endif
883
884static const char* const bc_args_env_name = "BC_ENV_ARGS"; 865static const char* const bc_args_env_name = "BC_ENV_ARGS";
885 866
886static const char bc_err_fmt[] = "\n%s error: %s\n"; 867static 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 1422static void bc_args(int argc, char *argv[], uint32_t *flags, BcVec *files)
1445static 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
1455static const char bc_args_opt[] ALIGN1 = "xwvsqli";
1456
1457static 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
1480static void bc_num_setToZero(BcNum *n, size_t scale) 1450static 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
7060static BcStatus bc_vm_envArgs(BcVm *vm) 7030static 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
7308static BcStatus bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) 7275static 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
7340static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, 7304static 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
7365exit:
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
7371BcStatus bc_main(int argc, char *argv[]) 7332int bc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7333int 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
7388BcStatus dc_main(int argc, char *argv[]) 7350int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7351int 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;