summaryrefslogtreecommitdiff
path: root/Src/builtin.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-09-03 09:08:18 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-09-03 09:08:18 +0000
commit0cba5ef62ad8e98924c2bd9367f9c7c7e72e2fd0 (patch)
treeaff6e4b164bdd8dd1ad12c921ee774405a5ea244 /Src/builtin.c
parentae79d264a3fd989713f6c7413c5096151413f284 (diff)
downloadzsh-0cba5ef62ad8e98924c2bd9367f9c7c7e72e2fd0.tar.gz
zsh-0cba5ef62ad8e98924c2bd9367f9c7c7e72e2fd0.zip
25595: fix line numbers with EVAL_LINENO,
try to fix oddities with funcstack and sourced files, simplify use of caller element of funcstack
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index 654665bfc..69f0aaa6e 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4712,15 +4712,53 @@ bin_eval(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
{
Eprog prog;
char *oscriptname = scriptname;
- int oineval = ineval;
+ int oineval = ineval, fpushed;
+ struct funcstack fstack;
+
/*
* If EVALLINENO is not set, we use the line number of the
* environment and must flag this up to exec.c. Otherwise,
* we use a special script name to indicate the special line number.
*/
ineval = !isset(EVALLINENO);
- if (!ineval)
+ if (!ineval) {
scriptname = "(eval)";
+ fstack.prev = funcstack;
+ fstack.name = scriptname;
+ fstack.caller = funcstack ? funcstack->name : dupstring(argzero);
+ fstack.lineno = lineno;
+ fstack.tp = FS_EVAL;
+
+ /*
+ * To get file line numbers, we need to know if parent is
+ * the original script/shell or a sourced file, in which
+ * case we use the line number raw, or a function or eval,
+ * in which case we need to deduce where that came from.
+ *
+ * This replicates the logic for working out the information
+ * for $funcfiletrace---eval is similar to an inlined function
+ * call from a tracing perspective.
+ */
+ if (!funcstack || funcstack->tp == FS_SOURCE) {
+ fstack.flineno = fstack.lineno;
+ fstack.filename = fstack.caller;
+ } else {
+ fstack.flineno = funcstack->flineno + lineno;
+ /*
+ * Line numbers in eval start from 1, not zero,
+ * so offset by one to get line in file.
+ */
+ if (funcstack->tp == FS_EVAL)
+ fstack.flineno--;
+ fstack.filename = funcstack->filename;
+ if (!fstack.filename)
+ fstack.filename = "";
+ }
+ funcstack = &fstack;
+
+ fpushed = 1;
+ } else
+ fpushed = 0;
prog = parse_string(zjoin(argv, ' ', 1));
if (prog) {
@@ -4737,6 +4775,9 @@ bin_eval(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
lastval = 1;
}
+ if (fpushed)
+ funcstack = funcstack->prev;
+
errflag = 0;
scriptname = oscriptname;
ineval = oineval;