From d6c9cbc0727cc3875672ae280ec129514a9d8594 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 7 Sep 2021 18:01:49 +0200 Subject: [PATCH] ash: fix LINENO in functions From larger patch by Roberto A. Foglietta 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 --- 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(-) create mode 100644 shell/ash_test/ash-vars/var_LINENO2.right create mode 100755 shell/ash_test/ash-vars/var_LINENO2.tests create mode 100644 shell/hush_test/hush-vars/var_LINENO2.right create mode 100755 shell/hush_test/hush-vars/var_LINENO2.tests 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"