diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-30 12:23:51 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-30 12:23:51 +0200 |
commit | d1507101695f6bad35a61c4770b7d3913597ac16 (patch) | |
tree | 6e729dc87d81a0e8a5f9c41718f48bcd913540c7 | |
parent | 86fc2872b33224cfa5442700c2a8abd020cbf900 (diff) | |
download | busybox-w32-d1507101695f6bad35a61c4770b7d3913597ac16.tar.gz busybox-w32-d1507101695f6bad35a61c4770b7d3913597ac16.tar.bz2 busybox-w32-d1507101695f6bad35a61c4770b7d3913597ac16.zip |
awk: allow empty fuinctions with no arguments, disallow function redefinitions
function old new delta
.rodata 103681 103700 +19
parse_program 303 307 +4
evaluate 3145 3141 -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 23/-4) Total: 19 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 11 | ||||
-rwxr-xr-x | testsuite/awk.tests | 10 |
2 files changed, 17 insertions, 4 deletions
diff --git a/editors/awk.c b/editors/awk.c index 1115085da..c05d5d651 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -139,6 +139,7 @@ typedef struct chain_s { | |||
139 | /* Function */ | 139 | /* Function */ |
140 | typedef struct func_s { | 140 | typedef struct func_s { |
141 | unsigned nargs; | 141 | unsigned nargs; |
142 | smallint defined; | ||
142 | struct chain_s body; | 143 | struct chain_s body; |
143 | } func; | 144 | } func; |
144 | 145 | ||
@@ -1662,9 +1663,11 @@ static void parse_program(char *p) | |||
1662 | debug_printf_parse("%s: TC_FUNCDECL\n", __func__); | 1663 | debug_printf_parse("%s: TC_FUNCDECL\n", __func__); |
1663 | next_token(TC_FUNCTION); | 1664 | next_token(TC_FUNCTION); |
1664 | f = newfunc(t_string); | 1665 | f = newfunc(t_string); |
1665 | //FIXME: dup check: functions can't be redefined, this is not ok: awk 'func f(){}; func f(){}' | 1666 | if (f->defined) |
1666 | f->body.first = NULL; | 1667 | syntax_error("Duplicate function"); |
1667 | f->nargs = 0; | 1668 | f->defined = 1; |
1669 | //f->body.first = NULL; - already is | ||
1670 | //f->nargs = 0; - already is | ||
1668 | /* func arg list: comma sep list of args, and a close paren */ | 1671 | /* func arg list: comma sep list of args, and a close paren */ |
1669 | for (;;) { | 1672 | for (;;) { |
1670 | if (next_token(TC_VARIABLE | TC_RPAREN) == TC_RPAREN) { | 1673 | if (next_token(TC_VARIABLE | TC_RPAREN) == TC_RPAREN) { |
@@ -2912,7 +2915,7 @@ static var *evaluate(node *op, var *res) | |||
2912 | 2915 | ||
2913 | debug_printf_eval("FUNC\n"); | 2916 | debug_printf_eval("FUNC\n"); |
2914 | 2917 | ||
2915 | if (op->r.f->nargs == 0 && !op->r.f->body.first) | 2918 | if (!op->r.f->defined) |
2916 | syntax_error(EMSG_UNDEF_FUNC); | 2919 | syntax_error(EMSG_UNDEF_FUNC); |
2917 | 2920 | ||
2918 | /* The body might be empty, still has to eval the args */ | 2921 | /* The body might be empty, still has to eval the args */ |
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 6e35d33dd..873cc3680 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -45,6 +45,16 @@ testing "awk handles empty function f(arg){}" \ | |||
45 | "" "" | 45 | "" "" |
46 | 46 | ||
47 | prg=' | 47 | prg=' |
48 | function empty_fun(){} | ||
49 | END {empty_fun() | ||
50 | print "Ok" | ||
51 | }' | ||
52 | testing "awk handles empty function f(){}" \ | ||
53 | "awk '$prg'" \ | ||
54 | "Ok\n" \ | ||
55 | "" "" | ||
56 | |||
57 | prg=' | ||
48 | function outer_fun() { | 58 | function outer_fun() { |
49 | return 1 | 59 | return 1 |
50 | } | 60 | } |