mirror of
https://git.busybox.net/busybox.git
synced 2024-11-23 13:43:28 +08:00
bc: fixes for multi-line if/while/for
function old new delta zbc_vm_process 561 589 +28 zbc_lex_next_and_skip_NLINE - 22 +22 zbc_parse_stmt_possibly_auto 2232 2253 +21 zbc_lex_skip_if_at_NLINE - 14 +14 zbc_lex_number 192 200 +8 zbc_num_divmod 150 156 +6 bc_vm_run 134 139 +5 bc_vm_init 757 760 +3 bc_num_printNewline 51 54 +3 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 7/0 up/down: 110/0) Total: 110 bytes text data bss dec hex filename 982138 485 7296 989919 f1adf busybox_old 982275 485 7296 990056 f1b68 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e9519e44a6
commit
202dd1943c
@ -3018,6 +3018,29 @@ static BC_STATUS zbc_lex_next(BcLex *l)
|
||||
# define zbc_lex_next(...) (zbc_lex_next(__VA_ARGS__), BC_STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
static BC_STATUS zbc_lex_skip_if_at_NLINE(BcLex *l)
|
||||
{
|
||||
if (l->t.t == BC_LEX_NLINE)
|
||||
RETURN_STATUS(zbc_lex_next(l));
|
||||
RETURN_STATUS(BC_STATUS_SUCCESS);
|
||||
}
|
||||
#if ERRORS_ARE_FATAL
|
||||
# define zbc_lex_skip_if_at_NLINE(...) (zbc_lex_skip_if_at_NLINE(__VA_ARGS__), BC_STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
static BC_STATUS zbc_lex_next_and_skip_NLINE(BcLex *l)
|
||||
{
|
||||
BcStatus s;
|
||||
s = zbc_lex_next(l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
// if(cond)<newline>stmt is accepted too (but not 2+ newlines)
|
||||
s = zbc_lex_skip_if_at_NLINE(l);
|
||||
RETURN_STATUS(s);
|
||||
}
|
||||
#if ERRORS_ARE_FATAL
|
||||
# define zbc_lex_next_and_skip_NLINE(...) (zbc_lex_next_and_skip_NLINE(__VA_ARGS__), BC_STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
static BC_STATUS zbc_lex_text_init(BcLex *l, const char *text)
|
||||
{
|
||||
l->buf = text;
|
||||
@ -4152,7 +4175,8 @@ static BC_STATUS zbc_parse_if(BcParse *p)
|
||||
if (s) RETURN_STATUS(s);
|
||||
|
||||
if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
|
||||
s = zbc_lex_next(&p->l);
|
||||
// if(cond)<newline>stmt is accepted too (but not 2+ newlines)
|
||||
s = zbc_lex_next_and_skip_NLINE(&p->l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
|
||||
bc_parse_push(p, BC_INST_JUMP_ZERO);
|
||||
@ -4216,12 +4240,15 @@ static BC_STATUS zbc_parse_while(BcParse *p)
|
||||
s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
|
||||
if (s) RETURN_STATUS(s);
|
||||
if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
|
||||
s = zbc_lex_next(&p->l);
|
||||
|
||||
// while(cond)<newline>stmt is accepted too
|
||||
s = zbc_lex_next_and_skip_NLINE(&p->l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
|
||||
bc_parse_push(p, BC_INST_JUMP_ZERO);
|
||||
bc_parse_pushIndex(p, ip.idx);
|
||||
|
||||
//TODO: diagnose "while(cond)<newline><newline>"? Now it is seen as "while() with empty body"
|
||||
s = zbc_parse_stmt(p);
|
||||
if (s) RETURN_STATUS(s);
|
||||
|
||||
@ -4321,7 +4348,9 @@ static BC_STATUS zbc_parse_for(BcParse *p)
|
||||
|
||||
bc_vec_push(&p->exits, &ip);
|
||||
bc_vec_push(&p->func->labels, &ip.idx);
|
||||
s = zbc_lex_next(&p->l);
|
||||
|
||||
// for(...)<newline>stmt is accepted as well
|
||||
s = zbc_lex_next_and_skip_NLINE(&p->l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
|
||||
s = zbc_parse_stmt(p);
|
||||
@ -4453,11 +4482,9 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
|
||||
if (p->l.t.t != BC_LEX_LBRACE)
|
||||
s = bc_POSIX_requires("the left brace be on the same line as the function header");
|
||||
|
||||
// Prevent "define z()<newline>" to be interpreted as function with empty stmt as body
|
||||
while (p->l.t.t == BC_LEX_NLINE) {
|
||||
s = zbc_lex_next(&p->l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
}
|
||||
// Prevent "define z()<newline>" from being interpreted as function with empty stmt as body
|
||||
s = zbc_lex_skip_if_at_NLINE(&p->l);
|
||||
if (s) RETURN_STATUS(s);
|
||||
//TODO: GNU bc requires a {} block even if function body has single stmt, enforce this?
|
||||
|
||||
p->in_funcdef++; // to determine whether "return" stmt is allowed, and such
|
||||
|
@ -56,6 +56,16 @@ testing "bc define with body on next line" \
|
||||
"8\n9\n" \
|
||||
"" "define w()\n{ auto z; return 8; }\nw()\n9"
|
||||
|
||||
testing "bc if(cond)<NL>" \
|
||||
"bc" \
|
||||
"9\n" \
|
||||
"" "if(0)\n3\n9"
|
||||
|
||||
testing "bc while(cond)<NL>" \
|
||||
"bc" \
|
||||
"8\n7\n6\n5\n4\n3\n2\n1\n9\n" \
|
||||
"" "i=9;while(--i)\ni\n9"
|
||||
|
||||
tar xJf bc_large.tar.xz
|
||||
|
||||
for f in bc*.bc; do
|
||||
|
Loading…
Reference in New Issue
Block a user