aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-30 12:23:51 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-30 12:23:51 +0200
commitd1507101695f6bad35a61c4770b7d3913597ac16 (patch)
tree6e729dc87d81a0e8a5f9c41718f48bcd913540c7
parent86fc2872b33224cfa5442700c2a8abd020cbf900 (diff)
downloadbusybox-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.c11
-rwxr-xr-xtestsuite/awk.tests10
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 */
140typedef struct func_s { 140typedef 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
47prg=' 47prg='
48function empty_fun(){}
49END {empty_fun()
50 print "Ok"
51}'
52testing "awk handles empty function f(){}" \
53 "awk '$prg'" \
54 "Ok\n" \
55 "" ""
56
57prg='
48function outer_fun() { 58function outer_fun() {
49 return 1 59 return 1
50} 60}