aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-22 18:04:08 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-22 18:10:50 +0100
commitbadf683b0aa693de9b1a7c1634ad20665463c503 (patch)
treec0d98441715a00b73971743e49f4c82c90beaf9b /miscutils
parent5daa1a0adfe08bae588e5293686a84ab3649a2aa (diff)
downloadbusybox-w32-badf683b0aa693de9b1a7c1634ad20665463c503.tar.gz
busybox-w32-badf683b0aa693de9b1a7c1634ad20665463c503.tar.bz2
busybox-w32-badf683b0aa693de9b1a7c1634ad20665463c503.zip
dc: unbreak interactive mode - was trying to get next tokens instead of executing
function old new delta zbc_program_read - 268 +268 zdc_program_printStream - 146 +146 zbc_program_exec 4046 4182 +136 zdc_program_execStr 472 512 +40 zdc_parse_exprs_until_eof - 26 +26 zbc_vm_process 740 765 +25 zbc_lex_next 2225 2240 +15 zdc_parse_expr 569 535 -34 zbc_program_pushArray 147 - -147 zdc_program_asciify 370 - -370 ------------------------------------------------------------------------------ (add/remove: 3/2 grow/shrink: 4/1 up/down: 656/-551) Total: 105 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/bc.c96
1 files changed, 66 insertions, 30 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 5d5449efa..d8fbb6ed7 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -3431,6 +3431,17 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3431// l->t.t = BC_LEX_EOF; 3431// l->t.t = BC_LEX_EOF;
3432// break; 3432// break;
3433 case '\n': 3433 case '\n':
3434 // '\n' is BC_LEX_NLINE, not BC_LEX_WHITESPACE
3435 // (and "case '\n'" is not just empty here)
3436 // only to allow interactive dc have a way to exit
3437 // "parse" stage of "parse,execute" loop
3438 // on '\n', not on _next_ token (which would mean
3439 // command are not executed on pressing <enter>).
3440 // IOW: typing "1p<enter>" should print "1" _at once_,
3441 // not after some more input.
3442 l->t.t = BC_LEX_NLINE;
3443 l->newline = true;
3444 break;
3434 case '\t': 3445 case '\t':
3435 case '\v': 3446 case '\v':
3436 case '\f': 3447 case '\f':
@@ -4861,12 +4872,16 @@ static BC_STATUS zdc_parse_cond(BcParse *p, uint8_t inst)
4861 s = zbc_lex_next(&p->l); 4872 s = zbc_lex_next(&p->l);
4862 if (s) RETURN_STATUS(s); 4873 if (s) RETURN_STATUS(s);
4863 4874
4875 // Note that 'else' part can not be on the next line:
4876 // echo -e '[1p]sa [2p]sb 2 1>a eb' | dc - OK, prints "2"
4877 // echo -e '[1p]sa [2p]sb 2 1>a\neb' | dc - parse error
4864 if (p->l.t.t == BC_LEX_ELSE) { 4878 if (p->l.t.t == BC_LEX_ELSE) {
4865 s = zdc_parse_register(p); 4879 s = zdc_parse_register(p);
4866 if (s) RETURN_STATUS(s); 4880 if (s) RETURN_STATUS(s);
4867 s = zbc_lex_next(&p->l); 4881 s = zbc_lex_next(&p->l);
4868 } else 4882 } else {
4869 bc_parse_push(p, BC_PARSE_STREND); 4883 bc_parse_push(p, BC_PARSE_STREND);
4884 }
4870 4885
4871 RETURN_STATUS(s); 4886 RETURN_STATUS(s);
4872} 4887}
@@ -4945,33 +4960,32 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
4945 4960
4946static BC_STATUS zdc_parse_expr(BcParse *p) 4961static BC_STATUS zdc_parse_expr(BcParse *p)
4947{ 4962{
4948 BcLexType t; 4963 BcInst inst;
4949 4964 BcStatus s;
4950 dbg_lex_enter("%s:%d entered, p->l.t.t:%d", __func__, __LINE__, p->l.t.t);
4951 for (;;) {
4952 BcInst inst;
4953 BcStatus s;
4954 4965
4955 t = p->l.t.t; 4966 inst = dc_parse_insts[p->l.t.t];
4956 dbg_lex("%s:%d p->l.t.t:%d", __func__, __LINE__, p->l.t.t); 4967 if (inst != BC_INST_INVALID) {
4957 if (t == BC_LEX_EOF) break; 4968 bc_parse_push(p, inst);
4969 s = zbc_lex_next(&p->l);
4970 } else {
4971 s = zdc_parse_token(p, p->l.t.t);
4972 }
4973 RETURN_STATUS(s);
4974}
4975#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS)
4958 4976
4959 inst = dc_parse_insts[t]; 4977static BC_STATUS zdc_parse_exprs_until_eof(BcParse *p)
4960 if (inst != BC_INST_INVALID) { 4978{
4961 dbg_lex("%s:%d", __func__, __LINE__); 4979 dbg_lex_enter("%s:%d entered, p->l.t.t:%d", __func__, __LINE__, p->l.t.t);
4962 bc_parse_push(p, inst); 4980 while (p->l.t.t != BC_LEX_EOF) {
4963 s = zbc_lex_next(&p->l); 4981 BcStatus s = zdc_parse_expr(p);
4964 } else {
4965 dbg_lex("%s:%d", __func__, __LINE__);
4966 s = zdc_parse_token(p, t);
4967 }
4968 if (s) RETURN_STATUS(s); 4982 if (s) RETURN_STATUS(s);
4969 } 4983 }
4970 4984
4971 dbg_lex_done("%s:%d done", __func__, __LINE__); 4985 dbg_lex_done("%s:%d done", __func__, __LINE__);
4972 RETURN_STATUS(BC_STATUS_SUCCESS); 4986 RETURN_STATUS(BC_STATUS_SUCCESS);
4973} 4987}
4974#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS) 4988#define zdc_parse_exprs_until_eof(...) (zdc_parse_exprs_until_eof(__VA_ARGS__) COMMA_SUCCESS)
4975 4989
4976#endif // ENABLE_DC 4990#endif // ENABLE_DC
4977 4991
@@ -5182,7 +5196,7 @@ static BC_STATUS zbc_program_read(void)
5182 if (IS_BC) { 5196 if (IS_BC) {
5183 IF_BC(s = zbc_parse_expr(&parse, 0)); 5197 IF_BC(s = zbc_parse_expr(&parse, 0));
5184 } else { 5198 } else {
5185 IF_DC(s = zdc_parse_expr(&parse)); 5199 IF_DC(s = zdc_parse_exprs_until_eof(&parse));
5186 } 5200 }
5187 if (s) goto exec_err; 5201 if (s) goto exec_err;
5188 5202
@@ -6304,6 +6318,7 @@ static BC_STATUS zdc_program_execStr(char *code, size_t *bgn, bool cond)
6304 f = bc_program_func(fidx); 6318 f = bc_program_func(fidx);
6305 6319
6306 if (f->code.len == 0) { 6320 if (f->code.len == 0) {
6321 FILE *sv_input_fp;
6307 BcParse prs; 6322 BcParse prs;
6308 char *str; 6323 char *str;
6309 6324
@@ -6311,7 +6326,12 @@ static BC_STATUS zdc_program_execStr(char *code, size_t *bgn, bool cond)
6311 str = *bc_program_str(sidx); 6326 str = *bc_program_str(sidx);
6312 s = zbc_parse_text_init(&prs, str); 6327 s = zbc_parse_text_init(&prs, str);
6313 if (s) goto err; 6328 if (s) goto err;
6314 s = zdc_parse_expr(&prs); 6329
6330 sv_input_fp = G.input_fp;
6331 G.input_fp = NULL; // "do not read from input file when <EOL> reached"
6332 s = zdc_parse_exprs_until_eof(&prs);
6333 G.input_fp = sv_input_fp;
6334
6315 if (s) goto err; 6335 if (s) goto err;
6316 if (prs.l.t.t != BC_LEX_EOF) { 6336 if (prs.l.t.t != BC_LEX_EOF) {
6317 s = bc_error_bad_expression(); 6337 s = bc_error_bad_expression();
@@ -6439,12 +6459,15 @@ static BC_STATUS zbc_program_exec(void)
6439 s = zbc_program_pushArray(code, &ip->inst_idx, inst); 6459 s = zbc_program_pushArray(code, &ip->inst_idx, inst);
6440 break; 6460 break;
6441 case BC_INST_LAST: 6461 case BC_INST_LAST:
6462//TODO: this can't happen on dc, right?
6463 dbg_exec("BC_INST_LAST:");
6442 r.t = BC_RESULT_LAST; 6464 r.t = BC_RESULT_LAST;
6443 bc_vec_push(&G.prog.results, &r); 6465 bc_vec_push(&G.prog.results, &r);
6444 break; 6466 break;
6445 case BC_INST_IBASE: 6467 case BC_INST_IBASE:
6446 case BC_INST_SCALE: 6468 case BC_INST_SCALE:
6447 case BC_INST_OBASE: 6469 case BC_INST_OBASE:
6470 dbg_exec("BC_INST_internalvar:");
6448 bc_program_pushGlobal(inst); 6471 bc_program_pushGlobal(inst);
6449 break; 6472 break;
6450 case BC_INST_SCALE_FUNC: 6473 case BC_INST_SCALE_FUNC:
@@ -6519,17 +6542,21 @@ static BC_STATUS zbc_program_exec(void)
6519 bc_vec_pop(&G.prog.exestack); 6542 bc_vec_pop(&G.prog.exestack);
6520 goto read_updated_ip; 6543 goto read_updated_ip;
6521 case BC_INST_MODEXP: 6544 case BC_INST_MODEXP:
6545 dbg_exec("BC_INST_MODEXP:");
6522 s = zdc_program_modexp(); 6546 s = zdc_program_modexp();
6523 break; 6547 break;
6524 case BC_INST_DIVMOD: 6548 case BC_INST_DIVMOD:
6549 dbg_exec("BC_INST_DIVMOD:");
6525 s = zdc_program_divmod(); 6550 s = zdc_program_divmod();
6526 break; 6551 break;
6527 case BC_INST_EXECUTE: 6552 case BC_INST_EXECUTE:
6528 case BC_INST_EXEC_COND: 6553 case BC_INST_EXEC_COND:
6554 dbg_exec("BC_INST_EXEC[_COND]:");
6529 s = zdc_program_execStr(code, &ip->inst_idx, inst == BC_INST_EXEC_COND); 6555 s = zdc_program_execStr(code, &ip->inst_idx, inst == BC_INST_EXEC_COND);
6530 goto read_updated_ip; 6556 goto read_updated_ip;
6531 case BC_INST_PRINT_STACK: { 6557 case BC_INST_PRINT_STACK: {
6532 size_t idx; 6558 size_t idx;
6559 dbg_exec("BC_INST_PRINT_STACK:");
6533 for (idx = 0; idx < G.prog.results.len; ++idx) { 6560 for (idx = 0; idx < G.prog.results.len; ++idx) {
6534 s = zbc_program_print(BC_INST_PRINT, idx); 6561 s = zbc_program_print(BC_INST_PRINT, idx);
6535 if (s) break; 6562 if (s) break;
@@ -6537,12 +6564,15 @@ static BC_STATUS zbc_program_exec(void)
6537 break; 6564 break;
6538 } 6565 }
6539 case BC_INST_CLEAR_STACK: 6566 case BC_INST_CLEAR_STACK:
6567 dbg_exec("BC_INST_CLEAR_STACK:");
6540 bc_vec_pop_all(&G.prog.results); 6568 bc_vec_pop_all(&G.prog.results);
6541 break; 6569 break;
6542 case BC_INST_STACK_LEN: 6570 case BC_INST_STACK_LEN:
6571 dbg_exec("BC_INST_STACK_LEN:");
6543 dc_program_stackLen(); 6572 dc_program_stackLen();
6544 break; 6573 break;
6545 case BC_INST_DUPLICATE: 6574 case BC_INST_DUPLICATE:
6575 dbg_exec("BC_INST_DUPLICATE:");
6546 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) 6576 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0))
6547 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 6577 RETURN_STATUS(bc_error_stack_has_too_few_elements());
6548 ptr = bc_vec_top(&G.prog.results); 6578 ptr = bc_vec_top(&G.prog.results);
@@ -6551,6 +6581,7 @@ static BC_STATUS zbc_program_exec(void)
6551 break; 6581 break;
6552 case BC_INST_SWAP: { 6582 case BC_INST_SWAP: {
6553 BcResult *ptr2; 6583 BcResult *ptr2;
6584 dbg_exec("BC_INST_SWAP:");
6554 if (!STACK_HAS_MORE_THAN(&G.prog.results, 1)) 6585 if (!STACK_HAS_MORE_THAN(&G.prog.results, 1))
6555 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 6586 RETURN_STATUS(bc_error_stack_has_too_few_elements());
6556 ptr = bc_vec_item_rev(&G.prog.results, 0); 6587 ptr = bc_vec_item_rev(&G.prog.results, 0);
@@ -6561,9 +6592,11 @@ static BC_STATUS zbc_program_exec(void)
6561 break; 6592 break;
6562 } 6593 }
6563 case BC_INST_ASCIIFY: 6594 case BC_INST_ASCIIFY:
6595 dbg_exec("BC_INST_ASCIIFY:");
6564 s = zdc_program_asciify(); 6596 s = zdc_program_asciify();
6565 break; 6597 break;
6566 case BC_INST_PRINT_STREAM: 6598 case BC_INST_PRINT_STREAM:
6599 dbg_exec("BC_INST_STREAM:");
6567 s = zdc_program_printStream(); 6600 s = zdc_program_printStream();
6568 break; 6601 break;
6569 case BC_INST_LOAD: 6602 case BC_INST_LOAD:
@@ -6585,6 +6618,7 @@ static BC_STATUS zbc_program_exec(void)
6585 bc_vec_npop(&G.prog.exestack, 2); 6618 bc_vec_npop(&G.prog.exestack, 2);
6586 goto read_updated_ip; 6619 goto read_updated_ip;
6587 case BC_INST_NQUIT: 6620 case BC_INST_NQUIT:
6621 dbg_exec("BC_INST_NQUIT:");
6588 s = zdc_program_nquit(); 6622 s = zdc_program_nquit();
6589 //goto read_updated_ip; - just fall through to it 6623 //goto read_updated_ip; - just fall through to it
6590#endif // ENABLE_DC 6624#endif // ENABLE_DC
@@ -6629,25 +6663,20 @@ static BC_STATUS zbc_vm_process(const char *text)
6629 BcStatus s; 6663 BcStatus s;
6630 6664
6631 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 6665 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
6632 s = zbc_parse_text_init(&G.prs, text); 6666 s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next()
6633 if (s) RETURN_STATUS(s); 6667 if (s) RETURN_STATUS(s);
6634 6668
6635 while (G.prs.l.t.t != BC_LEX_EOF) { 6669 while (G.prs.l.t.t != BC_LEX_EOF) {
6636 dbg_lex("%s:%d G.prs.l.t.t:%d, parsing...", __func__, __LINE__, G.prs.l.t.t); 6670 dbg_lex("%s:%d G.prs.l.t.t:%d, parsing...", __func__, __LINE__, G.prs.l.t.t);
6637 if (IS_BC) { 6671 if (IS_BC) {
6638// FIXME: "eating" of stmt delemiters is coded inconsistently 6672// FIXME: "eating" of stmt delimiters is coded inconsistently
6639// (sometimes zbc_parse_stmt() eats the delimiter, sometimes don't), 6673// (sometimes zbc_parse_stmt() eats the delimiter, sometimes don't),
6640// which causes bugs such as "print 1 print 2" erroneously accepted, 6674// which causes bugs such as "print 1 print 2" erroneously accepted,
6641// or "print 1 else 2" detecting parse error only after executing 6675// or "print 1 else 2" detecting parse error only after executing
6642// "print 1" part. 6676// "print 1" part.
6643 IF_BC(s = zbc_parse_stmt_or_funcdef(&G.prs)); 6677 IF_BC(s = zbc_parse_stmt_or_funcdef(&G.prs));
6644 } else { 6678 } else {
6645#if ENABLE_DC 6679 IF_DC(s = zdc_parse_expr(&G.prs));
6646 if (G.prs.l.t.t == BC_LEX_EOF)
6647 s = bc_error("end of file");
6648 else
6649 s = zdc_parse_expr(&G.prs);
6650#endif
6651 } 6680 }
6652 if (s || G_interrupt) { 6681 if (s || G_interrupt) {
6653 bc_parse_reset(&G.prs); // includes bc_program_reset() 6682 bc_parse_reset(&G.prs); // includes bc_program_reset()
@@ -6689,6 +6718,13 @@ static BC_STATUS zbc_vm_process(const char *text)
6689 ip->inst_idx = 0; 6718 ip->inst_idx = 0;
6690 IF_BC(bc_vec_pop_all(&f->strs);) 6719 IF_BC(bc_vec_pop_all(&f->strs);)
6691 IF_BC(bc_vec_pop_all(&f->consts);) 6720 IF_BC(bc_vec_pop_all(&f->consts);)
6721 } else {
6722 // Most of dc parsing assumes all whitespace,
6723 // including '\n', is eaten.
6724 if (G.prs.l.t.t == BC_LEX_NLINE) {
6725 s = zbc_lex_next(&G.prs.l);
6726 if (s) RETURN_STATUS(s);
6727 }
6692 } 6728 }
6693 } 6729 }
6694 6730