diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-22 01:34:10 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-22 01:34:10 +0100 |
commit | 8c1e72359626789b1b98aeac0225d73d1336bb59 (patch) | |
tree | 7c89877da4953bccddb88943e49def923c2d7a40 | |
parent | 1dc4de9d9bbdf3f60b76cecf94d756ef9394e25f (diff) | |
download | busybox-w32-8c1e72359626789b1b98aeac0225d73d1336bb59.tar.gz busybox-w32-8c1e72359626789b1b98aeac0225d73d1336bb59.tar.bz2 busybox-w32-8c1e72359626789b1b98aeac0225d73d1336bb59.zip |
bc: unbreak read(), remove checks for nested read()
function old new delta
zbc_parse_pushSTR - 65 +65
common_parse_expr - 32 +32
bc_error_nested_read_call 10 - -10
bc_parse_expr_empty_ok 1977 1963 -14
zdc_parse_expr 635 615 -20
zcommon_parse_expr 32 - -32
zbc_program_exec 4064 4023 -41
bc_parse_pushSTR 65 - -65
------------------------------------------------------------------------------
(add/remove: 2/3 grow/shrink: 0/3 up/down: 97/-182) Total: -85 bytes
text data bss dec hex filename
981661 485 7296 989442 f1902 busybox_old
981540 485 7296 989321 f1889 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 64 | ||||
-rwxr-xr-x | testsuite/bc.tests | 15 |
2 files changed, 41 insertions, 38 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index cac3cb734..1ba8427da 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -314,9 +314,9 @@ typedef enum BcInst { | |||
314 | #endif | 314 | #endif |
315 | 315 | ||
316 | BC_INST_POP, | 316 | BC_INST_POP, |
317 | #if ENABLE_DC | ||
317 | BC_INST_POP_EXEC, | 318 | BC_INST_POP_EXEC, |
318 | 319 | ||
319 | #if ENABLE_DC | ||
320 | BC_INST_MODEXP, | 320 | BC_INST_MODEXP, |
321 | BC_INST_DIVMOD, | 321 | BC_INST_DIVMOD, |
322 | 322 | ||
@@ -662,8 +662,7 @@ typedef struct BcLex { | |||
662 | #define BC_PARSE_REL (1 << 0) | 662 | #define BC_PARSE_REL (1 << 0) |
663 | #define BC_PARSE_PRINT (1 << 1) | 663 | #define BC_PARSE_PRINT (1 << 1) |
664 | #define BC_PARSE_NOCALL (1 << 2) | 664 | #define BC_PARSE_NOCALL (1 << 2) |
665 | #define BC_PARSE_NOREAD (1 << 3) | 665 | #define BC_PARSE_ARRAY (1 << 3) |
666 | #define BC_PARSE_ARRAY (1 << 4) | ||
667 | 666 | ||
668 | typedef struct BcParse { | 667 | typedef struct BcParse { |
669 | BcLex l; | 668 | BcLex l; |
@@ -766,7 +765,6 @@ typedef struct BcProgram { | |||
766 | struct globals { | 765 | struct globals { |
767 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) | 766 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) |
768 | IF_FEATURE_CLEAN_UP(smallint exiting;) | 767 | IF_FEATURE_CLEAN_UP(smallint exiting;) |
769 | smallint in_read; | ||
770 | 768 | ||
771 | BcParse prs; | 769 | BcParse prs; |
772 | BcProgram prog; | 770 | BcProgram prog; |
@@ -1022,10 +1020,6 @@ static ERRORFUNC int bc_error_variable_is_wrong_type(void) | |||
1022 | { | 1020 | { |
1023 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("variable is wrong type"); | 1021 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("variable is wrong type"); |
1024 | } | 1022 | } |
1025 | static ERRORFUNC int bc_error_nested_read_call(void) | ||
1026 | { | ||
1027 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("read() call inside of a read() call"); | ||
1028 | } | ||
1029 | #if ENABLE_BC | 1023 | #if ENABLE_BC |
1030 | static int bc_POSIX_requires(const char *msg) | 1024 | static int bc_POSIX_requires(const char *msg) |
1031 | { | 1025 | { |
@@ -3550,7 +3544,7 @@ static void bc_parse_pushJUMP_ZERO(BcParse *p, size_t idx) | |||
3550 | bc_parse_pushIndex(p, idx); | 3544 | bc_parse_pushIndex(p, idx); |
3551 | } | 3545 | } |
3552 | 3546 | ||
3553 | static BC_STATUS bc_parse_pushSTR(BcParse *p) | 3547 | static BC_STATUS zbc_parse_pushSTR(BcParse *p) |
3554 | { | 3548 | { |
3555 | char *str = xstrdup(p->l.t.v.v); | 3549 | char *str = xstrdup(p->l.t.v.v); |
3556 | 3550 | ||
@@ -3560,7 +3554,7 @@ static BC_STATUS bc_parse_pushSTR(BcParse *p) | |||
3560 | 3554 | ||
3561 | RETURN_STATUS(zbc_lex_next(&p->l)); | 3555 | RETURN_STATUS(zbc_lex_next(&p->l)); |
3562 | } | 3556 | } |
3563 | #define bc_parse_pushSTR(...) (bc_parse_pushSTR(__VA_ARGS__) COMMA_SUCCESS) | 3557 | #define zbc_parse_pushSTR(...) (zbc_parse_pushSTR(__VA_ARGS__) COMMA_SUCCESS) |
3564 | #endif | 3558 | #endif |
3565 | 3559 | ||
3566 | static void bc_parse_pushNUM(BcParse *p) | 3560 | static void bc_parse_pushNUM(BcParse *p) |
@@ -4083,7 +4077,7 @@ static BC_STATUS zbc_parse_print(BcParse *p) | |||
4083 | if (s) RETURN_STATUS(s); | 4077 | if (s) RETURN_STATUS(s); |
4084 | type = p->l.t.t; | 4078 | type = p->l.t.t; |
4085 | if (type == BC_LEX_STR) { | 4079 | if (type == BC_LEX_STR) { |
4086 | s = bc_parse_pushSTR(p); | 4080 | s = zbc_parse_pushSTR(p); |
4087 | } else { | 4081 | } else { |
4088 | s = zbc_parse_expr(p, 0); | 4082 | s = zbc_parse_expr(p, 0); |
4089 | } | 4083 | } |
@@ -4545,7 +4539,7 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed) | |||
4545 | s = zbc_parse_expr(p, BC_PARSE_PRINT); | 4539 | s = zbc_parse_expr(p, BC_PARSE_PRINT); |
4546 | break; | 4540 | break; |
4547 | case BC_LEX_STR: | 4541 | case BC_LEX_STR: |
4548 | s = bc_parse_pushSTR(p); | 4542 | s = zbc_parse_pushSTR(p); |
4549 | bc_parse_push(p, BC_INST_PRINT_STR); | 4543 | bc_parse_push(p, BC_INST_PRINT_STR); |
4550 | break; | 4544 | break; |
4551 | case BC_LEX_KEY_BREAK: | 4545 | case BC_LEX_KEY_BREAK: |
@@ -4645,6 +4639,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags) | |||
4645 | bin_last = true; | 4639 | bin_last = true; |
4646 | 4640 | ||
4647 | for (; !G_interrupt && !s && !done && bc_parse_exprs(t); t = p->l.t.t) { | 4641 | for (; !G_interrupt && !s && !done && bc_parse_exprs(t); t = p->l.t.t) { |
4642 | dbg_lex("%s:%d t:%d", __func__, __LINE__, t); | ||
4648 | switch (t) { | 4643 | switch (t) { |
4649 | case BC_LEX_OP_INC: | 4644 | case BC_LEX_OP_INC: |
4650 | case BC_LEX_OP_DEC: | 4645 | case BC_LEX_OP_DEC: |
@@ -4766,8 +4761,6 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags) | |||
4766 | case BC_LEX_KEY_READ: | 4761 | case BC_LEX_KEY_READ: |
4767 | if (BC_PARSE_LEAF(prev, rprn)) | 4762 | if (BC_PARSE_LEAF(prev, rprn)) |
4768 | return bc_error_bad_expression(); | 4763 | return bc_error_bad_expression(); |
4769 | else if (flags & BC_PARSE_NOREAD) | ||
4770 | s = bc_error_nested_read_call(); | ||
4771 | else | 4764 | else |
4772 | s = zbc_parse_read(p); | 4765 | s = zbc_parse_read(p); |
4773 | paren_expr = true; | 4766 | paren_expr = true; |
@@ -4912,7 +4905,7 @@ static BC_STATUS zdc_parse_cond(BcParse *p, uint8_t inst) | |||
4912 | } | 4905 | } |
4913 | #define zdc_parse_cond(...) (zdc_parse_cond(__VA_ARGS__) COMMA_SUCCESS) | 4906 | #define zdc_parse_cond(...) (zdc_parse_cond(__VA_ARGS__) COMMA_SUCCESS) |
4914 | 4907 | ||
4915 | static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | 4908 | static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t) |
4916 | { | 4909 | { |
4917 | BcStatus s = BC_STATUS_SUCCESS; | 4910 | BcStatus s = BC_STATUS_SUCCESS; |
4918 | uint8_t inst; | 4911 | uint8_t inst; |
@@ -4950,10 +4943,7 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | |||
4950 | get_token = true; | 4943 | get_token = true; |
4951 | break; | 4944 | break; |
4952 | case BC_LEX_KEY_READ: | 4945 | case BC_LEX_KEY_READ: |
4953 | if (flags & BC_PARSE_NOREAD) | 4946 | bc_parse_push(p, BC_INST_READ); |
4954 | s = bc_error_nested_read_call(); | ||
4955 | else | ||
4956 | bc_parse_push(p, BC_INST_READ); | ||
4957 | get_token = true; | 4947 | get_token = true; |
4958 | break; | 4948 | break; |
4959 | case BC_LEX_OP_ASSIGN: | 4949 | case BC_LEX_OP_ASSIGN: |
@@ -5005,7 +4995,7 @@ static BC_STATUS zdc_parse_expr(BcParse *p, uint8_t flags) | |||
5005 | s = zbc_lex_next(&p->l); | 4995 | s = zbc_lex_next(&p->l); |
5006 | } else { | 4996 | } else { |
5007 | dbg_lex("%s:%d", __func__, __LINE__); | 4997 | dbg_lex("%s:%d", __func__, __LINE__); |
5008 | s = zdc_parse_token(p, t, flags); | 4998 | s = zdc_parse_token(p, t); |
5009 | } | 4999 | } |
5010 | if (s) RETURN_STATUS(s); | 5000 | if (s) RETURN_STATUS(s); |
5011 | } | 5001 | } |
@@ -5038,7 +5028,12 @@ static BC_STATUS zdc_parse_parse(BcParse *p) | |||
5038 | 5028 | ||
5039 | #endif // ENABLE_DC | 5029 | #endif // ENABLE_DC |
5040 | 5030 | ||
5041 | static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags) | 5031 | #if !ENABLE_DC |
5032 | #define common_parse_expr(p,flags) \ | ||
5033 | common_parse_expr(p) | ||
5034 | #define flags 0 | ||
5035 | #endif | ||
5036 | static BC_STATUS common_parse_expr(BcParse *p, uint8_t flags) | ||
5042 | { | 5037 | { |
5043 | if (IS_BC) { | 5038 | if (IS_BC) { |
5044 | IF_BC(RETURN_STATUS(zbc_parse_expr(p, flags))); | 5039 | IF_BC(RETURN_STATUS(zbc_parse_expr(p, flags))); |
@@ -5046,7 +5041,7 @@ static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags) | |||
5046 | IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags))); | 5041 | IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags))); |
5047 | } | 5042 | } |
5048 | } | 5043 | } |
5049 | #define zcommon_parse_expr(...) (zcommon_parse_expr(__VA_ARGS__) COMMA_SUCCESS) | 5044 | #define zcommon_parse_expr(...) (common_parse_expr(__VA_ARGS__) COMMA_SUCCESS) |
5050 | 5045 | ||
5051 | static BcVec* bc_program_search(char *id, bool var) | 5046 | static BcVec* bc_program_search(char *id, bool var) |
5052 | { | 5047 | { |
@@ -5238,15 +5233,11 @@ static BC_STATUS zbc_program_read(void) | |||
5238 | BcInstPtr ip; | 5233 | BcInstPtr ip; |
5239 | BcFunc *f; | 5234 | BcFunc *f; |
5240 | 5235 | ||
5241 | if (G.in_read) | ||
5242 | RETURN_STATUS(bc_error_nested_read_call()); | ||
5243 | |||
5244 | f = bc_program_func(BC_PROG_READ); | 5236 | f = bc_program_func(BC_PROG_READ); |
5245 | bc_vec_pop_all(&f->code); | 5237 | bc_vec_pop_all(&f->code); |
5246 | 5238 | ||
5247 | sv_file = G.prog.file; | 5239 | sv_file = G.prog.file; |
5248 | G.prog.file = NULL; | 5240 | G.prog.file = NULL; |
5249 | G.in_read = 1; | ||
5250 | 5241 | ||
5251 | bc_char_vec_init(&buf); | 5242 | bc_char_vec_init(&buf); |
5252 | bc_read_line(&buf, stdin); | 5243 | bc_read_line(&buf, stdin); |
@@ -5256,7 +5247,7 @@ static BC_STATUS zbc_program_read(void) | |||
5256 | 5247 | ||
5257 | s = zbc_parse_text_init(&parse, buf.v); | 5248 | s = zbc_parse_text_init(&parse, buf.v); |
5258 | if (s) goto exec_err; | 5249 | if (s) goto exec_err; |
5259 | s = zcommon_parse_expr(&parse, BC_PARSE_NOREAD); | 5250 | s = zcommon_parse_expr(&parse, 0); |
5260 | if (s) goto exec_err; | 5251 | if (s) goto exec_err; |
5261 | 5252 | ||
5262 | if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) { | 5253 | if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) { |
@@ -5268,14 +5259,10 @@ static BC_STATUS zbc_program_read(void) | |||
5268 | ip.inst_idx = 0; | 5259 | ip.inst_idx = 0; |
5269 | IF_BC(ip.results_len_before_call = G.prog.results.len;) | 5260 | IF_BC(ip.results_len_before_call = G.prog.results.len;) |
5270 | 5261 | ||
5271 | // Update this pointer, just in case. | 5262 | bc_parse_push(&parse, BC_INST_RET); |
5272 | f = bc_program_func(BC_PROG_READ); | ||
5273 | |||
5274 | bc_vec_pushByte(&f->code, BC_INST_POP_EXEC); | ||
5275 | bc_vec_push(&G.prog.exestack, &ip); | 5263 | bc_vec_push(&G.prog.exestack, &ip); |
5276 | exec_err: | 5264 | exec_err: |
5277 | bc_parse_free(&parse); | 5265 | bc_parse_free(&parse); |
5278 | G.in_read = 0; | ||
5279 | G.prog.file = sv_file; | 5266 | G.prog.file = sv_file; |
5280 | bc_vec_free(&buf); | 5267 | bc_vec_free(&buf); |
5281 | RETURN_STATUS(s); | 5268 | RETURN_STATUS(s); |
@@ -6542,10 +6529,6 @@ static BC_STATUS zbc_program_exec(void) | |||
6542 | else | 6529 | else |
6543 | bc_vec_pop(&G.prog.results); | 6530 | bc_vec_pop(&G.prog.results); |
6544 | break; | 6531 | break; |
6545 | case BC_INST_POP_EXEC: | ||
6546 | dbg_exec("BC_INST_POP_EXEC:"); | ||
6547 | bc_vec_pop(&G.prog.exestack); | ||
6548 | goto read_updated_ip; | ||
6549 | case BC_INST_PRINT: | 6532 | case BC_INST_PRINT: |
6550 | case BC_INST_PRINT_POP: | 6533 | case BC_INST_PRINT_POP: |
6551 | case BC_INST_PRINT_STR: | 6534 | case BC_INST_PRINT_STR: |
@@ -6594,6 +6577,10 @@ static BC_STATUS zbc_program_exec(void) | |||
6594 | s = zbc_program_assign(inst); | 6577 | s = zbc_program_assign(inst); |
6595 | break; | 6578 | break; |
6596 | #if ENABLE_DC | 6579 | #if ENABLE_DC |
6580 | case BC_INST_POP_EXEC: | ||
6581 | dbg_exec("BC_INST_POP_EXEC:"); | ||
6582 | bc_vec_pop(&G.prog.exestack); | ||
6583 | goto read_updated_ip; | ||
6597 | case BC_INST_MODEXP: | 6584 | case BC_INST_MODEXP: |
6598 | s = zdc_program_modexp(); | 6585 | s = zdc_program_modexp(); |
6599 | break; | 6586 | break; |
@@ -7122,11 +7109,12 @@ static void bc_program_init(void) | |||
7122 | IF_BC(bc_vec_init(&G.prog.fn_map, sizeof(BcId), bc_id_free);) | 7109 | IF_BC(bc_vec_init(&G.prog.fn_map, sizeof(BcId), bc_id_free);) |
7123 | 7110 | ||
7124 | if (IS_BC) { | 7111 | if (IS_BC) { |
7125 | // Names are chosen simply to never match | 7112 | // Names are chosen simply to be distinct and never match |
7126 | // a valid function name (and be short) | 7113 | // a valid function name (and be short) |
7127 | IF_BC(bc_program_addFunc(xstrdup(""))); // func #0: main | 7114 | IF_BC(bc_program_addFunc(xstrdup(""))); // func #0: main |
7128 | IF_BC(bc_program_addFunc(xstrdup(""))); // func #1: for read() | 7115 | IF_BC(bc_program_addFunc(xstrdup("1"))); // func #1: for read() |
7129 | } else { | 7116 | } else { |
7117 | // in dc, functions have no names | ||
7130 | bc_program_add_fn(); | 7118 | bc_program_add_fn(); |
7131 | bc_program_add_fn(); | 7119 | bc_program_add_fn(); |
7132 | } | 7120 | } |
diff --git a/testsuite/bc.tests b/testsuite/bc.tests index b3ce894ee..c84a2987c 100755 --- a/testsuite/bc.tests +++ b/testsuite/bc.tests | |||
@@ -31,6 +31,21 @@ testing "bc string 1" \ | |||
31 | "STR\n" \ | 31 | "STR\n" \ |
32 | "" "\"STR\n\"" | 32 | "" "\"STR\n\"" |
33 | 33 | ||
34 | testing "bc read() 4<EOF>" \ | ||
35 | "bc input" \ | ||
36 | "4\n" \ | ||
37 | "read();halt" "4" | ||
38 | |||
39 | testing "bc read()^2" \ | ||
40 | "bc input" \ | ||
41 | "16\n" \ | ||
42 | "read()^2;halt" "4\n" | ||
43 | |||
44 | testing "bc read()*read()" \ | ||
45 | "bc input" \ | ||
46 | "20\n" \ | ||
47 | "read()*read();halt" "4\n5" | ||
48 | |||
34 | testing "bc if 0 else" \ | 49 | testing "bc if 0 else" \ |
35 | "bc" \ | 50 | "bc" \ |
36 | "2\n9\n" \ | 51 | "2\n9\n" \ |