[git commit] awk: evaluate all, even superfluous function args

Denys Vlasenko vda.linux at googlemail.com
Wed Jun 30 10:52:51 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=d7354df169603807fe2ac4f8a0f9f72c9703184f
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
evaluate                                            3128    3135      +7

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/awk.c       | 19 ++++++++++++-------
 testsuite/awk.tests |  8 +++++++-
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/editors/awk.c b/editors/awk.c
index 0fbca0433..47bbc10a6 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2910,7 +2910,7 @@ static var *evaluate(node *op, var *res)
 		case XC( OC_FUNC ): {
 			var *tv, *sv_fnargs;
 			const char *sv_progname;
-			int nargs1, i;
+			int nargs, i;
 
 			debug_printf_eval("FUNC\n");
 
@@ -2918,17 +2918,22 @@ static var *evaluate(node *op, var *res)
 				syntax_error(EMSG_UNDEF_FUNC);
 
 			/* The body might be empty, still has to eval the args */
-			nargs1 = op->r.f->nargs + 1;
-			tv = nvalloc(nargs1);
+			nargs = op->r.f->nargs;
+			tv = nvalloc(nargs);
 			i = 0;
 			while (op1) {
-//TODO: explain why one iteration is done even for the case p->r.f->nargs == 0
 				var *arg = evaluate(nextarg(&op1), v1);
+				if (i == nargs) {
+					/* call with more arguments than function takes.
+					 * (gawk warns: "warning: function 'f' called with more arguments than declared").
+					 * They are still evaluated, but discarded: */
+					clrvar(arg);
+					continue;
+				}
 				copyvar(&tv[i], arg);
 				tv[i].type |= VF_CHILD;
 				tv[i].x.parent = arg;
-				if (++i >= op->r.f->nargs)
-					break;
+				i++;
 			}
 
 			sv_fnargs = fnargs;
@@ -2936,7 +2941,7 @@ static var *evaluate(node *op, var *res)
 
 			fnargs = tv;
 			res = evaluate(op->r.f->body.first, res);
-			nvfree(fnargs, nargs1);
+			nvfree(fnargs, nargs);
 
 			g_progname = sv_progname;
 			fnargs = sv_fnargs;
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index 873cc3680..3c230393f 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -87,11 +87,17 @@ BEGIN {
   a=2
   print v (a)
 }'
-testing "'v (a)' is not a function call, it is a concatenation" \
+testing "awk 'v (a)' is not a function call, it is a concatenation" \
 	"awk '$prg' 2>&1" \
 	"12\n" \
 	"" ""
 
+prg='func f(){print"F"};func g(){print"G"};BEGIN{f(g(),g())}'
+testing "awk unused function args are evaluated" \
+	"awk '$prg' 2>&1" \
+	"G\nG\nF\n" \
+	"" ""
+
 
 optional DESKTOP
 testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n"


More information about the busybox-cvs mailing list