mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-17 15:01:40 +02:00
25247 with further modifications: add $funcsourcetrace
This commit is contained in:
parent
2e485d60ff
commit
2853ca830a
14 changed files with 167 additions and 18 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2008-08-11 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 25247 with further modifications: Doc/Zsh/mod_parameter.yo,
|
||||||
|
Src/exec.c, Src/hashtable.c, Src/init.c, Src/parse.c,
|
||||||
|
Src/signals.c, Src/utils.c, Src/zsh.h, Src/Modules/parameter.c,
|
||||||
|
Src/Modules/parameter.mdd, Test/.distfiles,
|
||||||
|
Test/V01zmodload.ztst, Test/V06parameter.ztst: add
|
||||||
|
$funcsourcetrace parameter to zsh/parameter.
|
||||||
|
|
||||||
2008-08-11 Peter Stephenson <pws@csr.com>
|
2008-08-11 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
* unposted: Doc/Zsh/builtins.yo, Doc/Zsh/func.yo: prevent various
|
* unposted: Doc/Zsh/builtins.yo, Doc/Zsh/func.yo: prevent various
|
||||||
|
|
|
@ -164,6 +164,16 @@ item(tt(userdirs))(
|
||||||
This associative array maps user names to the pathnames of their home
|
This associative array maps user names to the pathnames of their home
|
||||||
directories.
|
directories.
|
||||||
)
|
)
|
||||||
|
vindex(funcsourcetrace)
|
||||||
|
item(tt(funcsourcetrace))(
|
||||||
|
This array contains the file names and line numbers of the
|
||||||
|
points where the functions currently being executed were
|
||||||
|
defined. The line number is the line where the `tt(function) var(name)'
|
||||||
|
or `var(name) tt(LPAR()RPAR())' started. In the case of an autoloaded
|
||||||
|
function in native zsh format where only the body of the function occurs
|
||||||
|
in the file the line number is reported as zero.
|
||||||
|
The format of each element is var(filename)tt(:)var(lineno).
|
||||||
|
)
|
||||||
vindex(funcstack)
|
vindex(funcstack)
|
||||||
item(tt(funcstack))(
|
item(tt(funcstack))(
|
||||||
This array contains the names of the functions currently being
|
This array contains the names of the functions currently being
|
||||||
|
@ -174,6 +184,6 @@ vindex(functrace)
|
||||||
item(tt(functrace))(
|
item(tt(functrace))(
|
||||||
This array contains the names and line numbers of the callers
|
This array contains the names and line numbers of the callers
|
||||||
corresponding to the functions currently being executed.
|
corresponding to the functions currently being executed.
|
||||||
The format of each element is name:lineno.
|
The format of each element is var(name)tt(:)var(lineno).
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
|
@ -286,7 +286,7 @@ setfunction(char *name, char *val, int dis)
|
||||||
zsfree(val);
|
zsfree(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
shf = (Shfunc) zalloc(sizeof(*shf));
|
shf = (Shfunc) zshcalloc(sizeof(*shf));
|
||||||
shf->funcdef = dupeprog(prog, 0);
|
shf->funcdef = dupeprog(prog, 0);
|
||||||
shf->node.flags = dis;
|
shf->node.flags = dis;
|
||||||
|
|
||||||
|
@ -529,7 +529,35 @@ functracegetfn(UNUSED(Param pm))
|
||||||
char *colonpair;
|
char *colonpair;
|
||||||
|
|
||||||
colonpair = zhalloc(strlen(f->caller) + (f->lineno > 9999 ? 24 : 6));
|
colonpair = zhalloc(strlen(f->caller) + (f->lineno > 9999 ? 24 : 6));
|
||||||
sprintf(colonpair, "%s:%d", f->caller, f->lineno);
|
sprintf(colonpair, "%s:%ld", f->caller, (long)f->lineno);
|
||||||
|
|
||||||
|
*p = colonpair;
|
||||||
|
}
|
||||||
|
*p = NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions for the funcsourcetrace special parameter. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static char **
|
||||||
|
funcsourcetracegetfn(UNUSED(Param pm))
|
||||||
|
{
|
||||||
|
Funcstack f;
|
||||||
|
int num;
|
||||||
|
char **ret, **p;
|
||||||
|
|
||||||
|
for (f = funcstack, num = 0; f; f = f->prev, num++);
|
||||||
|
|
||||||
|
ret = (char **) zhalloc((num + 1) * sizeof(char *));
|
||||||
|
|
||||||
|
for (f = funcstack, p = ret; f; f = f->prev, p++) {
|
||||||
|
char *colonpair;
|
||||||
|
char *fname = f->filename ? f->filename : "";
|
||||||
|
|
||||||
|
colonpair = zhalloc(strlen(fname) + (f->flineno > 9999 ? 24 : 6));
|
||||||
|
sprintf(colonpair, "%s:%ld", fname, (long)f->flineno);
|
||||||
|
|
||||||
*p = colonpair;
|
*p = colonpair;
|
||||||
}
|
}
|
||||||
|
@ -1773,6 +1801,8 @@ static const struct gsu_array funcstack_gsu =
|
||||||
{ funcstackgetfn, arrsetfn, stdunsetfn };
|
{ funcstackgetfn, arrsetfn, stdunsetfn };
|
||||||
static const struct gsu_array functrace_gsu =
|
static const struct gsu_array functrace_gsu =
|
||||||
{ functracegetfn, arrsetfn, stdunsetfn };
|
{ functracegetfn, arrsetfn, stdunsetfn };
|
||||||
|
static const struct gsu_array funcsourcetrace_gsu =
|
||||||
|
{ funcsourcetracegetfn, arrsetfn, stdunsetfn };
|
||||||
static const struct gsu_array reswords_gsu =
|
static const struct gsu_array reswords_gsu =
|
||||||
{ reswordsgetfn, arrsetfn, stdunsetfn };
|
{ reswordsgetfn, arrsetfn, stdunsetfn };
|
||||||
static const struct gsu_array disreswords_gsu =
|
static const struct gsu_array disreswords_gsu =
|
||||||
|
@ -1801,6 +1831,8 @@ static struct paramdef partab[] = {
|
||||||
&disreswords_gsu, NULL, NULL),
|
&disreswords_gsu, NULL, NULL),
|
||||||
SPECIALPMDEF("dis_saliases", 0,
|
SPECIALPMDEF("dis_saliases", 0,
|
||||||
&pmdissaliases_gsu, getpmdissalias, scanpmdissaliases),
|
&pmdissaliases_gsu, getpmdissalias, scanpmdissaliases),
|
||||||
|
SPECIALPMDEF("funcsourcetrace", PM_ARRAY|PM_READONLY,
|
||||||
|
&funcsourcetrace_gsu, NULL, NULL),
|
||||||
SPECIALPMDEF("funcstack", PM_ARRAY|PM_READONLY,
|
SPECIALPMDEF("funcstack", PM_ARRAY|PM_READONLY,
|
||||||
&funcstack_gsu, NULL, NULL),
|
&funcstack_gsu, NULL, NULL),
|
||||||
SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
|
SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
|
||||||
|
|
|
@ -2,6 +2,6 @@ name=zsh/parameter
|
||||||
link=either
|
link=either
|
||||||
load=yes
|
load=yes
|
||||||
|
|
||||||
autofeatures="p:parameters p:commands p:functions p:dis_functions p:funcstack p:functrace p:builtins p:dis_builtins p:reswords p:dis_reswords p:options p:modules p:dirstack p:history p:historywords p:jobtexts p:jobdirs p:jobstates p:nameddirs p:userdirs p:aliases p:dis_aliases p:galiases p:dis_galiases p:saliases p:dis_saliases"
|
autofeatures="p:parameters p:commands p:functions p:dis_functions p:funcsourcetrace p:funcstack p:functrace p:builtins p:dis_builtins p:reswords p:dis_reswords p:options p:modules p:dirstack p:history p:historywords p:jobtexts p:jobdirs p:jobstates p:nameddirs p:userdirs p:aliases p:dis_aliases p:galiases p:dis_galiases p:saliases p:dis_saliases"
|
||||||
|
|
||||||
objects="parameter.o"
|
objects="parameter.o"
|
||||||
|
|
41
Src/exec.c
41
Src/exec.c
|
@ -191,7 +191,7 @@ mod_export Eprog
|
||||||
parse_string(char *s)
|
parse_string(char *s)
|
||||||
{
|
{
|
||||||
Eprog p;
|
Eprog p;
|
||||||
int oldlineno = lineno;
|
zlong oldlineno = lineno;
|
||||||
|
|
||||||
lexsave();
|
lexsave();
|
||||||
inpush(s, INP_LINENO, NULL);
|
inpush(s, INP_LINENO, NULL);
|
||||||
|
@ -1016,7 +1016,8 @@ execlist(Estate state, int dont_change_job, int exiting)
|
||||||
Wordcode next;
|
Wordcode next;
|
||||||
wordcode code;
|
wordcode code;
|
||||||
int ret, cj, csp, ltype;
|
int ret, cj, csp, ltype;
|
||||||
int old_pline_level, old_list_pipe, oldlineno;
|
int old_pline_level, old_list_pipe;
|
||||||
|
zlong oldlineno;
|
||||||
/*
|
/*
|
||||||
* ERREXIT only forces the shell to exit if the last command in a &&
|
* ERREXIT only forces the shell to exit if the last command in a &&
|
||||||
* or || fails. This is the case even if an earlier command is a
|
* or || fails. This is the case even if an earlier command is a
|
||||||
|
@ -3961,6 +3962,8 @@ execfuncdef(Estate state, UNUSED(int do_exec))
|
||||||
shf = (Shfunc) zalloc(sizeof(*shf));
|
shf = (Shfunc) zalloc(sizeof(*shf));
|
||||||
shf->funcdef = prog;
|
shf->funcdef = prog;
|
||||||
shf->node.flags = 0;
|
shf->node.flags = 0;
|
||||||
|
shf->filename = ztrdup(scriptfilename);
|
||||||
|
shf->lineno = lineno;
|
||||||
|
|
||||||
if (!names) {
|
if (!names) {
|
||||||
/*
|
/*
|
||||||
|
@ -4059,15 +4062,24 @@ static int
|
||||||
execautofn(Estate state, UNUSED(int do_exec))
|
execautofn(Estate state, UNUSED(int do_exec))
|
||||||
{
|
{
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
char *oldscriptname;
|
char *oldscriptname, *oldscriptfilename;
|
||||||
|
|
||||||
if (!(shf = loadautofn(state->prog->shf, 1, 0)))
|
if (!(shf = loadautofn(state->prog->shf, 1, 0)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Probably we didn't know the filename where this function was
|
||||||
|
* defined yet.
|
||||||
|
*/
|
||||||
|
if (funcstack && !funcstack->filename)
|
||||||
|
funcstack->filename = dupstring(shf->filename);
|
||||||
|
|
||||||
oldscriptname = scriptname;
|
oldscriptname = scriptname;
|
||||||
scriptname = dupstring(shf->node.nam);
|
oldscriptfilename = scriptfilename;
|
||||||
|
scriptname = scriptfilename = dupstring(shf->node.nam);
|
||||||
execode(shf->funcdef, 1, 0);
|
execode(shf->funcdef, 1, 0);
|
||||||
scriptname = oldscriptname;
|
scriptname = oldscriptname;
|
||||||
|
scriptfilename = oldscriptfilename;
|
||||||
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
@ -4078,11 +4090,12 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
{
|
{
|
||||||
int noalias = noaliases, ksh = 1;
|
int noalias = noaliases, ksh = 1;
|
||||||
Eprog prog;
|
Eprog prog;
|
||||||
|
char *fname;
|
||||||
|
|
||||||
pushheap();
|
pushheap();
|
||||||
|
|
||||||
noaliases = (shf->node.flags & PM_UNALIASED);
|
noaliases = (shf->node.flags & PM_UNALIASED);
|
||||||
prog = getfpfunc(shf->node.nam, &ksh);
|
prog = getfpfunc(shf->node.nam, &ksh, &fname);
|
||||||
noaliases = noalias;
|
noaliases = noalias;
|
||||||
|
|
||||||
if (ksh == 1) {
|
if (ksh == 1) {
|
||||||
|
@ -4112,6 +4125,7 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
else
|
else
|
||||||
shf->funcdef = dupeprog(prog, 0);
|
shf->funcdef = dupeprog(prog, 0);
|
||||||
shf->node.flags &= ~PM_UNDEFINED;
|
shf->node.flags &= ~PM_UNDEFINED;
|
||||||
|
shf->filename = fname;
|
||||||
} else {
|
} else {
|
||||||
VARARR(char, n, strlen(shf->node.nam) + 1);
|
VARARR(char, n, strlen(shf->node.nam) + 1);
|
||||||
strcpy(n, shf->node.nam);
|
strcpy(n, shf->node.nam);
|
||||||
|
@ -4123,6 +4137,7 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
zwarn("%s: function not defined by file", n);
|
zwarn("%s: function not defined by file", n);
|
||||||
locallevel++;
|
locallevel++;
|
||||||
popheap();
|
popheap();
|
||||||
|
zsfree(fname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4133,6 +4148,7 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
else
|
else
|
||||||
shf->funcdef = dupeprog(stripkshdef(prog, shf->node.nam), 0);
|
shf->funcdef = dupeprog(stripkshdef(prog, shf->node.nam), 0);
|
||||||
shf->node.flags &= ~PM_UNDEFINED;
|
shf->node.flags &= ~PM_UNDEFINED;
|
||||||
|
shf->filename = fname;
|
||||||
}
|
}
|
||||||
popheap();
|
popheap();
|
||||||
|
|
||||||
|
@ -4172,6 +4188,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
|
||||||
#ifdef MAX_FUNCTION_DEPTH
|
#ifdef MAX_FUNCTION_DEPTH
|
||||||
static int funcdepth;
|
static int funcdepth;
|
||||||
#endif
|
#endif
|
||||||
|
Shfunc shf;
|
||||||
|
|
||||||
pushheap();
|
pushheap();
|
||||||
|
|
||||||
|
@ -4243,6 +4260,15 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
|
||||||
fstack.prev = funcstack;
|
fstack.prev = funcstack;
|
||||||
funcstack = &fstack;
|
funcstack = &fstack;
|
||||||
|
|
||||||
|
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, name))) {
|
||||||
|
fstack.flineno = shf->lineno;
|
||||||
|
fstack.filename = dupstring(shf->filename);
|
||||||
|
} else {
|
||||||
|
fstack.flineno = 0;
|
||||||
|
fstack.filename = dupstring(fstack.caller);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prog->flags & EF_RUN) {
|
if (prog->flags & EF_RUN) {
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
|
|
||||||
|
@ -4362,7 +4388,7 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
Eprog
|
Eprog
|
||||||
getfpfunc(char *s, int *ksh)
|
getfpfunc(char *s, int *ksh, char **fname)
|
||||||
{
|
{
|
||||||
char **pp, buf[PATH_MAX];
|
char **pp, buf[PATH_MAX];
|
||||||
off_t len;
|
off_t len;
|
||||||
|
@ -4397,6 +4423,9 @@ getfpfunc(char *s, int *ksh)
|
||||||
r = parse_string(d);
|
r = parse_string(d);
|
||||||
scriptname = oldscriptname;
|
scriptname = oldscriptname;
|
||||||
|
|
||||||
|
if (fname)
|
||||||
|
*fname = ztrdup(buf);
|
||||||
|
|
||||||
zfree(d, len + 1);
|
zfree(d, len + 1);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -852,6 +852,7 @@ freeshfuncnode(HashNode hn)
|
||||||
zsfree(shf->node.nam);
|
zsfree(shf->node.nam);
|
||||||
if (shf->funcdef)
|
if (shf->funcdef)
|
||||||
freeeprog(shf->funcdef);
|
freeeprog(shf->funcdef);
|
||||||
|
zsfree(shf->filename);
|
||||||
zfree(shf, sizeof(struct shfunc));
|
zfree(shf, sizeof(struct shfunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
Src/init.c
21
Src/init.c
|
@ -268,7 +268,7 @@ parseargs(char **argv)
|
||||||
/* -c command */
|
/* -c command */
|
||||||
cmd = *argv;
|
cmd = *argv;
|
||||||
opts[INTERACTIVE] &= 1;
|
opts[INTERACTIVE] &= 1;
|
||||||
scriptname = ztrdup("zsh");
|
scriptname = scriptfilename = ztrdup("zsh");
|
||||||
} else if (**argv == 'o') {
|
} else if (**argv == 'o') {
|
||||||
if (!*++*argv)
|
if (!*++*argv)
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -325,6 +325,7 @@ parseargs(char **argv)
|
||||||
}
|
}
|
||||||
opts[INTERACTIVE] &= 1;
|
opts[INTERACTIVE] &= 1;
|
||||||
argzero = *argv;
|
argzero = *argv;
|
||||||
|
scriptfilename = argzero;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
while (*argv)
|
while (*argv)
|
||||||
|
@ -1051,10 +1052,12 @@ mod_export int
|
||||||
source(char *s)
|
source(char *s)
|
||||||
{
|
{
|
||||||
Eprog prog;
|
Eprog prog;
|
||||||
int tempfd = -1, fd, cj, oldlineno;
|
int tempfd = -1, fd, cj;
|
||||||
|
zlong oldlineno;
|
||||||
int oldshst, osubsh, oloops;
|
int oldshst, osubsh, oloops;
|
||||||
FILE *obshin;
|
FILE *obshin;
|
||||||
char *old_scriptname = scriptname, *us;
|
char *old_scriptname = scriptname, *us;
|
||||||
|
char *old_scriptfilename = scriptfilename;
|
||||||
unsigned char *ocs;
|
unsigned char *ocs;
|
||||||
int ocsp;
|
int ocsp;
|
||||||
int otrap_return = trap_return, otrap_state = trap_state;
|
int otrap_return = trap_return, otrap_state = trap_state;
|
||||||
|
@ -1087,6 +1090,7 @@ source(char *s)
|
||||||
loops = 0;
|
loops = 0;
|
||||||
dosetopt(SHINSTDIN, 0, 1);
|
dosetopt(SHINSTDIN, 0, 1);
|
||||||
scriptname = s;
|
scriptname = s;
|
||||||
|
scriptfilename = s;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The special return behaviour of traps shouldn't
|
* The special return behaviour of traps shouldn't
|
||||||
|
@ -1096,6 +1100,17 @@ source(char *s)
|
||||||
trap_state = TRAP_STATE_INACTIVE;
|
trap_state = TRAP_STATE_INACTIVE;
|
||||||
|
|
||||||
sourcelevel++;
|
sourcelevel++;
|
||||||
|
/* { */
|
||||||
|
/* struct funcstack fstack; */
|
||||||
|
/* fstack.name = dupstring("source"); */
|
||||||
|
/* fstack.caller = dupstring(scriptfilename); */
|
||||||
|
/* fstack.flineno = oldlineno; */
|
||||||
|
/* fstack.lineno = oldlineno; */
|
||||||
|
/* fstack.filename = NULL; */
|
||||||
|
/* fstack.prev = funcstack; */
|
||||||
|
/* funcstack = &fstack; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
if (prog) {
|
if (prog) {
|
||||||
pushheap();
|
pushheap();
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
|
@ -1103,6 +1118,7 @@ source(char *s)
|
||||||
popheap();
|
popheap();
|
||||||
} else
|
} else
|
||||||
loop(0, 0); /* loop through the file to be sourced */
|
loop(0, 0); /* loop through the file to be sourced */
|
||||||
|
/* funcstack = funcstack->prev; */
|
||||||
sourcelevel--;
|
sourcelevel--;
|
||||||
|
|
||||||
trap_state = otrap_state;
|
trap_state = otrap_state;
|
||||||
|
@ -1126,6 +1142,7 @@ source(char *s)
|
||||||
if (!exit_pending)
|
if (!exit_pending)
|
||||||
retflag = 0;
|
retflag = 0;
|
||||||
scriptname = old_scriptname;
|
scriptname = old_scriptname;
|
||||||
|
scriptfilename = old_scriptfilename;
|
||||||
free(cmdstack);
|
free(cmdstack);
|
||||||
cmdstack = ocs;
|
cmdstack = ocs;
|
||||||
cmdsp = ocsp;
|
cmdsp = ocsp;
|
||||||
|
|
12
Src/parse.c
12
Src/parse.c
|
@ -720,7 +720,8 @@ par_sublist2(int *complex)
|
||||||
static int
|
static int
|
||||||
par_pline(int *complex)
|
par_pline(int *complex)
|
||||||
{
|
{
|
||||||
int p, line = lineno;
|
int p;
|
||||||
|
zlong line = lineno;
|
||||||
|
|
||||||
p = ecadd(0);
|
p = ecadd(0);
|
||||||
|
|
||||||
|
@ -1414,8 +1415,9 @@ par_subsh(int *complex)
|
||||||
static void
|
static void
|
||||||
par_funcdef(void)
|
par_funcdef(void)
|
||||||
{
|
{
|
||||||
int oecused = ecused, oldlineno = lineno, num = 0, onp, p, c = 0;
|
int oecused = ecused, num = 0, onp, p, c = 0;
|
||||||
int so, oecssub = ecssub;
|
int so, oecssub = ecssub;
|
||||||
|
zlong oldlineno = lineno;
|
||||||
|
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
nocorrect = 1;
|
nocorrect = 1;
|
||||||
|
@ -1646,7 +1648,8 @@ par_simple(int *complex, int nr)
|
||||||
p += nrediradd;
|
p += nrediradd;
|
||||||
sr += nrediradd;
|
sr += nrediradd;
|
||||||
} else if (tok == INOUTPAR) {
|
} else if (tok == INOUTPAR) {
|
||||||
int oldlineno = lineno, onp, so, oecssub = ecssub;
|
zlong oldlineno = lineno;
|
||||||
|
int onp, so, oecssub = ecssub;
|
||||||
|
|
||||||
*complex = c;
|
*complex = c;
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
|
@ -2860,7 +2863,8 @@ cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
noaliases = (shf->node.flags & PM_UNALIASED);
|
noaliases = (shf->node.flags & PM_UNALIASED);
|
||||||
if (!(prog = getfpfunc(shf->node.nam, NULL)) || prog == &dummy_eprog) {
|
if (!(prog = getfpfunc(shf->node.nam, NULL, NULL)) ||
|
||||||
|
prog == &dummy_eprog) {
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
zwarnnam(nam, "can't load function: %s", shf->node.nam);
|
zwarnnam(nam, "can't load function: %s", shf->node.nam);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -705,6 +705,7 @@ dosavetrap(int sig, int level)
|
||||||
newshf->node.nam = ztrdup(shf->node.nam);
|
newshf->node.nam = ztrdup(shf->node.nam);
|
||||||
newshf->node.flags = shf->node.flags;
|
newshf->node.flags = shf->node.flags;
|
||||||
newshf->funcdef = dupeprog(shf->funcdef, 0);
|
newshf->funcdef = dupeprog(shf->funcdef, 0);
|
||||||
|
newshf->filename = ztrdup(shf->filename);
|
||||||
if (shf->node.flags & PM_UNDEFINED)
|
if (shf->node.flags & PM_UNDEFINED)
|
||||||
newshf->funcdef->shf = newshf;
|
newshf->funcdef->shf = newshf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,10 @@
|
||||||
/* name of script being sourced */
|
/* name of script being sourced */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export char *scriptname;
|
mod_export char *scriptname; /* is sometimes a function name */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
mod_export char *scriptfilename;
|
||||||
|
|
||||||
#ifdef MULTIBYTE_SUPPORT
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
struct widechar_array {
|
struct widechar_array {
|
||||||
|
|
|
@ -1061,6 +1061,8 @@ struct cmdnam {
|
||||||
|
|
||||||
struct shfunc {
|
struct shfunc {
|
||||||
struct hashnode node;
|
struct hashnode node;
|
||||||
|
char *filename; /* Name of file located in */
|
||||||
|
int lineno; /* line number in above file */
|
||||||
Eprog funcdef; /* function definition */
|
Eprog funcdef; /* function definition */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1079,8 +1081,10 @@ struct shfunc {
|
||||||
struct funcstack {
|
struct funcstack {
|
||||||
Funcstack prev; /* previous in stack */
|
Funcstack prev; /* previous in stack */
|
||||||
char *name; /* name of function called */
|
char *name; /* name of function called */
|
||||||
|
char *filename; /* file function resides in */
|
||||||
char *caller; /* name of caller */
|
char *caller; /* name of caller */
|
||||||
int lineno; /* line number in file */
|
zlong flineno; /* line number in file */
|
||||||
|
zlong lineno; /* line offset from beginning of function */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* node in list of function call wrappers */
|
/* node in list of function call wrappers */
|
||||||
|
|
|
@ -33,6 +33,7 @@ V02zregexparse.ztst
|
||||||
V03mathfunc.ztst
|
V03mathfunc.ztst
|
||||||
V04features.ztst
|
V04features.ztst
|
||||||
V05styles.ztst
|
V05styles.ztst
|
||||||
|
V06parameter.ztst
|
||||||
Y01completion.ztst
|
Y01completion.ztst
|
||||||
Y02compmatch.ztst
|
Y02compmatch.ztst
|
||||||
Y03arguments.ztst
|
Y03arguments.ztst
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
>p:dis_galiases
|
>p:dis_galiases
|
||||||
>p:dis_reswords
|
>p:dis_reswords
|
||||||
>p:dis_saliases
|
>p:dis_saliases
|
||||||
|
>p:funcsourcetrace
|
||||||
>p:funcstack
|
>p:funcstack
|
||||||
>p:functions
|
>p:functions
|
||||||
>p:functrace
|
>p:functrace
|
||||||
|
|
37
Test/V06parameter.ztst
Normal file
37
Test/V06parameter.ztst
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
%prep
|
||||||
|
|
||||||
|
zmodload zsh/parameter
|
||||||
|
|
||||||
|
%test
|
||||||
|
|
||||||
|
print -r -- 'print Started functrace.zsh
|
||||||
|
:
|
||||||
|
print $LINENO + $functrace + $funcsourcetrace
|
||||||
|
:
|
||||||
|
fn() {
|
||||||
|
print Inside function $0
|
||||||
|
print $LINENO + $functrace + $funcsourcetrace
|
||||||
|
}
|
||||||
|
:
|
||||||
|
fn
|
||||||
|
:
|
||||||
|
fpath=(. $fpath)
|
||||||
|
:
|
||||||
|
echo '\''print Inside $0
|
||||||
|
print $LINENO + $functrace + $funcsourcetrace
|
||||||
|
'\'' >autofn
|
||||||
|
:
|
||||||
|
autoload autofn
|
||||||
|
:
|
||||||
|
autofn
|
||||||
|
autofn' >functrace.zsh
|
||||||
|
$ZTST_testdir/../Src/zsh +Z -f ./functrace.zsh
|
||||||
|
0:Function tracing
|
||||||
|
>Started functrace.zsh
|
||||||
|
>3 + +
|
||||||
|
>Inside function fn
|
||||||
|
>2 + ./functrace.zsh:10 + ./functrace.zsh:5
|
||||||
|
>Inside autofn
|
||||||
|
>2 + ./functrace.zsh:20 + ./autofn:0
|
||||||
|
>Inside autofn
|
||||||
|
>2 + ./functrace.zsh:21 + ./autofn:0
|
Loading…
Reference in a new issue