From 7c59c953f28026559325473ba53be0dd3a661109 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 25 Jan 2016 16:23:16 +0000 Subject: 37765: Use FS_FUNC on fucstack to find autoload -X target. This is better than scriptname which can be updated due to e.g. intervening "eval". --- ChangeLog | 3 +++ Src/builtin.c | 32 +++++++++++++++++++++++++------- Test/C04funcdef.ztst | 13 +++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a8077ab4..fb75a1e43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-01-25 Peter Stephenson + * 37765: Src/builtin.c, Test/C04funcdef.ztst: Use FS_FUNC on + funcstack to find autoload -X target rather than scriptname. + * 37776: Src/utils.c: set errflag before calling zwarning() to avoid recursive error messages. diff --git a/Src/builtin.c b/Src/builtin.c index 98ecb09e8..63f964d3d 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3142,15 +3142,33 @@ bin_functions(char *name, char **argv, Options ops, int func) queue_signals(); if (OPT_MINUS(ops,'X')) { - if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) { - DPUTS(!shf->funcdef, - "BUG: Calling autoload from empty function"); + Funcstack fs; + char *funcname = NULL; + for (fs = funcstack; fs; fs = fs->prev) { + if (fs->tp == FS_FUNC) { + /* + * dupstring here is paranoia but unlikely to be + * problematic + */ + funcname = dupstring(fs->name); + break; + } + } + if (!funcname) + { + zerrnam(name, "bad autoload"); + ret = 1; } else { - shf = (Shfunc) zshcalloc(sizeof *shf); - shfunctab->addnode(shfunctab, ztrdup(scriptname), shf); + if ((shf = (Shfunc) shfunctab->getnode(shfunctab, funcname))) { + DPUTS(!shf->funcdef, + "BUG: Calling autoload from empty function"); + } else { + shf = (Shfunc) zshcalloc(sizeof *shf); + shfunctab->addnode(shfunctab, ztrdup(funcname), shf); + } + shf->node.flags = on; + ret = eval_autoload(shf, funcname, ops, func); } - shf->node.flags = on; - ret = eval_autoload(shf, scriptname, ops, func); } else { if (OPT_ISSET(ops,'U') && !OPT_ISSET(ops,'u')) on &= ~PM_UNDEFINED; diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 0951e2cde..496577f6c 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -308,6 +308,19 @@ ?(eval):6: command not found: firstfn1 ?(eval):7: command not found: secondfn1 + ( + fpath=(.) + print "print oops was successfully autoloaded" >oops + oops() { eval autoload -X } + oops + which -x2 oops + ) +0:autoload containing eval +>oops was successfully autoloaded +>oops () { +> print oops was successfully autoloaded +>} + %clean rm -f file.in file.out -- cgit 1.4.1