aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Howard <gavin@schedmd.com>2019-06-21 14:03:41 -0600
committerRob Landley <rob@landley.net>2019-06-21 21:12:57 -0500
commit10534db2f6145dac85689e773d53befa4ce91c7d (patch)
tree5a74757ad3d9cc660e5b5f870f701c2f7f0da85a
parent97057b2c299b1323318b66cc4f51257d4b60940e (diff)
downloadtoybox-10534db2f6145dac85689e773d53befa4ce91c7d.tar.gz
bc: fix a few bugs found in upstream
-rw-r--r--toys/pending/bc.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/toys/pending/bc.c b/toys/pending/bc.c
index 7698a66b..5d0e98e9 100644
--- a/toys/pending/bc.c
+++ b/toys/pending/bc.c
@@ -536,6 +536,7 @@ BcStatus bc_lex_token(BcLex *l);
BcStatus bc_parse_parse(BcParse *p);
BcStatus bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
+void bc_parse_noElse(BcParse *p);
#define BC_PROG_ONE_CAP (1)
@@ -677,7 +678,7 @@ char *bc_err_msgs[] = {
"negative number",
"non integer number",
- "overflow; %s",
+ "overflow",
"divide by zero",
"could not open file: %s",
@@ -3593,6 +3594,8 @@ static BcStatus bc_parse_endBody(BcParse *p, int brace) {
new_else = (p->l.t == BC_LEX_KEY_ELSE);
if (new_else) s = bc_parse_else(p);
+ else if (!has_brace && (!BC_PARSE_IF_END(p) || brace))
+ bc_parse_noElse(p);
}
if (brace && has_brace) brace = 0;
@@ -3602,6 +3605,15 @@ static BcStatus bc_parse_endBody(BcParse *p, int brace) {
if (!s && p->flags.len == 1 && brace)
s = bc_parse_err(p, BC_ERROR_PARSE_TOKEN);
+ else if (brace && BC_PARSE_BRACE(p)) {
+ uint16_t flags = BC_PARSE_TOP_FLAG(p);
+ if (!(flags & (BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_LOOP_INNER)) &&
+ !(flags & (BC_PARSE_FLAG_IF | BC_PARSE_FLAG_ELSE)) &&
+ !(flags & (BC_PARSE_FLAG_IF_END)))
+ {
+ bc_vec_pop(&p->flags);
+ }
+ }
return s;
}
@@ -3612,7 +3624,7 @@ static void bc_parse_startBody(BcParse *p, uint16_t flags) {
bc_vec_push(&p->flags, &flags);
}
-static void bc_parse_noElse(BcParse *p) {
+void bc_parse_noElse(BcParse *p) {
uint16_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
*flag_ptr = (*flag_ptr & ~(BC_PARSE_FLAG_IF_END));
bc_parse_setLabel(p);
@@ -3971,8 +3983,10 @@ static BcStatus bc_parse_body(BcParse *p, int brace) {
if (p->l.t == BC_LEX_NLINE) s = bc_lex_next(&p->l);
}
else {
+ size_t len = p->flags.len;
s = bc_parse_stmt(p);
- if (!s && !brace && !BC_PARSE_BODY(p)) s = bc_parse_endBody(p, 0);
+ if (!s && !brace && !BC_PARSE_BODY(p) && len <= p->flags.len)
+ s = bc_parse_endBody(p, 0);
}
return s;
@@ -4791,8 +4805,9 @@ static void bc_program_printString(char *str)
if ((idx = stridx("ab\\efnqrt", c = str[i+1])) >= 0) {
if (c == 'n') TT.nchars = SIZE_MAX;
c = "\a\b\\\\\f\n\"\r\t"[idx];
- i++;
}
+ else putchar('\\');
+ i++;
}
putchar(c);
@@ -5668,6 +5683,7 @@ static void bc_vm_clean()
static BcStatus bc_vm_process(char *text, int is_stdin) {
BcStatus s;
+ uint16_t *flags;
s = bc_parse_text(&BC_VM->prs, text);
if (s) goto err;
@@ -5677,6 +5693,11 @@ static BcStatus bc_vm_process(char *text, int is_stdin) {
if (s) goto err;
}
+ flags = BC_PARSE_TOP_FLAG_PTR(&BC_VM->prs);
+
+ if (!is_stdin && BC_VM->prs.flags.len == 1 && *flags == BC_PARSE_FLAG_IF_END)
+ bc_parse_noElse(&BC_VM->prs);
+
if (BC_PARSE_NO_EXEC(&BC_VM->prs)) goto err;
s = bc_program_exec(&BC_VM->prog);
@@ -5832,7 +5853,7 @@ void bc_main(void)
int i;
for (i = 0; !s && i < toys.optc; ++i) s = bc_vm_file(toys.optargs[i]);
- if (!s || s != BC_STATUS_QUIT) s = bc_vm_stdin();
+ if (!s) s = bc_vm_stdin();
}
if (CFG_TOYBOX_FREE) {