[git commit] ash: fix LINENO in functions

Denys Vlasenko vda.linux at googlemail.com
Tue Sep 7 16:01:49 UTC 2021


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

>From larger patch by Roberto A. Foglietta <roberto.foglietta at gmail.com>

function                                             old     new   delta
evalfun                                              348     369     +21
ash_main                                            1202    1218     +16
setinputstring                                        65      73      +8
lookupvar                                            116     106     -10
evaltree                                             772     753     -19
evalsubshell                                         192     173     -19
evalfor                                              175     156     -19
evalcase                                             273     254     -19
evalcommand                                         1560    1536     -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/6 up/down: 45/-110)           Total: -65 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c                                 | 18 ++++++------------
 shell/ash_test/ash-vars/var_LINENO2.right   |  3 +++
 shell/ash_test/ash-vars/var_LINENO2.tests   |  8 ++++++++
 shell/hush_test/hush-vars/var_LINENO2.right |  3 +++
 shell/hush_test/hush-vars/var_LINENO2.tests |  8 ++++++++
 5 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index c65f09782..79fa3adba 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2357,7 +2357,7 @@ lookupvar(const char *name)
 			v->var_func(NULL);
 #endif
 		if (!(v->flags & VUNSET)) {
-			if (v == &vlineno && v->var_text == linenovar) {
+			if (v->var_text == linenovar) {
 				fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
 			}
 			return var_end(v->var_text);
@@ -9322,8 +9322,6 @@ evaltree(union node *n, int flags)
 		goto setstatus;
 	case NREDIR:
 		errlinno = lineno = n->nredir.linno;
-		if (funcline)
-			lineno -= funcline - 1;
 		expredir(n->nredir.redirect);
 		pushredir(n->nredir.redirect);
 		status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
@@ -9502,8 +9500,6 @@ evalfor(union node *n, int flags)
 	int status = 0;
 
 	errlinno = lineno = n->ncase.linno;
-	if (funcline)
-		lineno -= funcline - 1;
 
 	arglist.list = NULL;
 	arglist.lastp = &arglist.list;
@@ -9534,8 +9530,6 @@ evalcase(union node *n, int flags)
 	int status = 0;
 
 	errlinno = lineno = n->ncase.linno;
-	if (funcline)
-		lineno -= funcline - 1;
 
 	arglist.list = NULL;
 	arglist.lastp = &arglist.list;
@@ -9569,8 +9563,6 @@ evalsubshell(union node *n, int flags)
 	int status;
 
 	errlinno = lineno = n->nredir.linno;
-	if (funcline)
-		lineno -= funcline - 1;
 
 	expredir(n->nredir.redirect);
 	if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
@@ -9898,6 +9890,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
 	struct jmploc *volatile savehandler;
 	struct jmploc jmploc;
 	int e;
+	int savelineno;
 	int savefuncline;
 	char *savetrap = NULL;
 
@@ -9905,6 +9898,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
 		savetrap = trap[NTRAP_ERR];
 		trap[NTRAP_ERR] = NULL;
 	}
+	savelineno = lineno;
 	saveparam = shellparam;
 	savefuncline = funcline;
 	savehandler = exception_handler;
@@ -9934,6 +9928,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
 			free(savetrap);
 	}
 	funcline = savefuncline;
+	lineno = savelineno;
 	freefunc(func);
 	freeparam(&shellparam);
 	shellparam = saveparam;
@@ -10322,8 +10317,6 @@ evalcommand(union node *cmd, int flags)
 	int vlocal;
 
 	errlinno = lineno = cmd->ncmd.linno;
-	if (funcline)
-		lineno -= funcline - 1;
 
 	/* First expand the arguments. */
 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
@@ -11201,7 +11194,7 @@ setinputstring(char *string)
 	g_parsefile->next_to_pgetc = string;
 	g_parsefile->left_in_line = strlen(string);
 	g_parsefile->buf = NULL;
-	g_parsefile->linno = 1;
+	g_parsefile->linno = lineno;
 	INT_ON;
 }
 
@@ -14705,6 +14698,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
 		// ^^ not necessary since now we special-case fd 0
 		// in save_fd_on_redirect()
 
+		lineno = 1;
 		// dash: evalstring(minusc, sflag ? 0 : EV_EXIT);
 		// The above makes
 		//  ash -sc 'echo $-'
diff --git a/shell/ash_test/ash-vars/var_LINENO2.right b/shell/ash_test/ash-vars/var_LINENO2.right
new file mode 100644
index 000000000..73656647c
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_LINENO2.right
@@ -0,0 +1,3 @@
+Start LINENO=6, calling function
+In function: LINENO=4
+After function: LINENO=8
diff --git a/shell/ash_test/ash-vars/var_LINENO2.tests b/shell/ash_test/ash-vars/var_LINENO2.tests
new file mode 100755
index 000000000..7036dbdc8
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_LINENO2.tests
@@ -0,0 +1,8 @@
+#skip lines: make "line number within function" differ from overall line number
+#skip lines
+f() {
+	echo "In function: LINENO=$LINENO"
+}
+echo "Start LINENO=$LINENO, calling function"
+f
+echo "After function: LINENO=$LINENO"
diff --git a/shell/hush_test/hush-vars/var_LINENO2.right b/shell/hush_test/hush-vars/var_LINENO2.right
new file mode 100644
index 000000000..73656647c
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_LINENO2.right
@@ -0,0 +1,3 @@
+Start LINENO=6, calling function
+In function: LINENO=4
+After function: LINENO=8
diff --git a/shell/hush_test/hush-vars/var_LINENO2.tests b/shell/hush_test/hush-vars/var_LINENO2.tests
new file mode 100755
index 000000000..7036dbdc8
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_LINENO2.tests
@@ -0,0 +1,8 @@
+#skip lines: make "line number within function" differ from overall line number
+#skip lines
+f() {
+	echo "In function: LINENO=$LINENO"
+}
+echo "Start LINENO=$LINENO, calling function"
+f
+echo "After function: LINENO=$LINENO"


More information about the busybox-cvs mailing list