diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-25 19:37:23 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-25 19:37:23 +0100 |
commit | 53e569c06b12ef2cb9ef2ceeff92f04cfbf113e3 (patch) | |
tree | 4409d271eac5d1777a34da84a92de65f024daead | |
parent | 2638454464b944f9c407326257851bab13c045ec (diff) | |
download | busybox-w32-53e569c06b12ef2cb9ef2ceeff92f04cfbf113e3.tar.gz busybox-w32-53e569c06b12ef2cb9ef2ceeff92f04cfbf113e3.tar.bz2 busybox-w32-53e569c06b12ef2cb9ef2ceeff92f04cfbf113e3.zip |
bc: fix interactive read()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 8b44d4425..79f981eaf 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -6753,6 +6753,7 @@ static BC_STATUS zbc_vm_process(const char *text) | |||
6753 | s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next() | 6753 | s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next() |
6754 | if (s) RETURN_STATUS(s); | 6754 | if (s) RETURN_STATUS(s); |
6755 | 6755 | ||
6756 | IF_BC(check_eof:) | ||
6756 | while (G.prs.l.lex != XC_LEX_EOF) { | 6757 | while (G.prs.l.lex != XC_LEX_EOF) { |
6757 | BcInstPtr *ip; | 6758 | BcInstPtr *ip; |
6758 | BcFunc *f; | 6759 | BcFunc *f; |
@@ -6760,34 +6761,34 @@ static BC_STATUS zbc_vm_process(const char *text) | |||
6760 | dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex); | 6761 | dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex); |
6761 | if (IS_BC) { | 6762 | if (IS_BC) { |
6762 | #if ENABLE_BC | 6763 | #if ENABLE_BC |
6764 | if (G.prs.l.lex == BC_LEX_SCOLON | ||
6765 | || G.prs.l.lex == XC_LEX_NLINE | ||
6766 | ) { | ||
6767 | s = zbc_lex_next(&G.prs.l); | ||
6768 | if (s) goto err; | ||
6769 | goto check_eof; | ||
6770 | } | ||
6771 | |||
6763 | s = zbc_parse_stmt_or_funcdef(&G.prs); | 6772 | s = zbc_parse_stmt_or_funcdef(&G.prs); |
6764 | if (s) goto err; | 6773 | if (s) goto err; |
6765 | 6774 | ||
6766 | // Check that next token is not bogus, and skip over | 6775 | // Check that next token is a correct stmt delimiter - |
6767 | // stmt delimiter(s) - newlines and semicolons | 6776 | // disallows "print 1 print 2" and such. |
6768 | s = 1; // s == 1 on first iteration only | 6777 | if (G.prs.l.lex != BC_LEX_SCOLON |
6769 | for (;;) { | 6778 | && G.prs.l.lex != XC_LEX_NLINE |
6770 | if (G.prs.l.lex == XC_LEX_EOF) | 6779 | && G.prs.l.lex != XC_LEX_EOF |
6771 | goto execute; // this goto avoids resetting 's' to zero | 6780 | ) { |
6772 | if (G.prs.l.lex != BC_LEX_SCOLON | 6781 | const char *err_at; |
6773 | && G.prs.l.lex != XC_LEX_NLINE | 6782 | //TODO: commonalize for other parse errors: |
6774 | ) { | 6783 | err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN"; |
6775 | const char *err_at; | 6784 | bc_error_fmt("bad statement terminator at '%.*s'", |
6776 | // Not newline and not semicolon | 6785 | (int)(strchrnul(err_at, '\n') - err_at), |
6777 | if (s == 0) // saw at least one NL/semicolon before it? | 6786 | err_at |
6778 | break; // yes, good | 6787 | ); |
6779 | //TODO: commolalize for other parse errors: | 6788 | goto err; |
6780 | err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN"; | ||
6781 | bc_error_fmt("bad statement terminator at '%.*s'", | ||
6782 | (int)(strchrnul(err_at, '\n') - err_at), | ||
6783 | err_at | ||
6784 | ); | ||
6785 | goto err; | ||
6786 | } | ||
6787 | // NL or semicolon: skip it, set s = 0, repeat | ||
6788 | s = zbc_lex_next(&G.prs.l); | ||
6789 | if (s) goto err; | ||
6790 | } | 6789 | } |
6790 | // The above logic is fragile. Check these examples: | ||
6791 | // - interative read() still works | ||
6791 | #endif | 6792 | #endif |
6792 | } else { | 6793 | } else { |
6793 | #if ENABLE_DC | 6794 | #if ENABLE_DC |
@@ -6807,7 +6808,7 @@ static BC_STATUS zbc_vm_process(const char *text) | |||
6807 | bc_parse_reset(&G.prs); // includes bc_program_reset() | 6808 | bc_parse_reset(&G.prs); // includes bc_program_reset() |
6808 | RETURN_STATUS(BC_STATUS_FAILURE); | 6809 | RETURN_STATUS(BC_STATUS_FAILURE); |
6809 | } | 6810 | } |
6810 | IF_BC(execute:) | 6811 | |
6811 | dbg_lex("%s:%d executing...", __func__, __LINE__); | 6812 | dbg_lex("%s:%d executing...", __func__, __LINE__); |
6812 | s = zbc_program_exec(); | 6813 | s = zbc_program_exec(); |
6813 | if (s) { | 6814 | if (s) { |