mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-13 23:31:08 +02:00
40440: Add $functions_source hash to zsh/parameter.
This allows you to find out where a function was loaded from.
This commit is contained in:
parent
ea7b4d4b2d
commit
34f70c5dc0
6 changed files with 162 additions and 10 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2017-01-28 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 40440: ../Doc/Zsh/mod_parameter.yo, Modules/parameter.c,
|
||||||
|
hashtable.c, ../Test/C04funcdef.ztst, ../Test/V06parameter.ztst:
|
||||||
|
Add $functions_source to zsh/parameter to help find where
|
||||||
|
functions where loaded from.
|
||||||
|
|
||||||
2017-01-27 Peter Stephenson <p.stephenson@samsung.com>
|
2017-01-27 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
* Zach Whaley: 40200: Completion/Unix/Command/_perforce: update
|
* Zach Whaley: 40200: Completion/Unix/Command/_perforce: update
|
||||||
|
|
|
@ -37,6 +37,30 @@ vindex(dis_functions)
|
||||||
item(tt(dis_functions))(
|
item(tt(dis_functions))(
|
||||||
Like tt(functions) but for disabled functions.
|
Like tt(functions) but for disabled functions.
|
||||||
)
|
)
|
||||||
|
vindex(functions_source)
|
||||||
|
item(tt(functions_source))(
|
||||||
|
This readonly associative array maps names of enabled functions to the
|
||||||
|
name of the file containing the source of the function.
|
||||||
|
|
||||||
|
For an autoloaded function that has already been loaded, or marked for
|
||||||
|
autoload with an absolute path, or that has had its path resolved with
|
||||||
|
`tt(functions -r)', this is the file found for autoloading, resolved
|
||||||
|
to an absolute path.
|
||||||
|
|
||||||
|
For a function defined within the body of a script or sourced file,
|
||||||
|
this is the name of that file. In this case, this is the exact path
|
||||||
|
originally used to that file, which may be a relative path.
|
||||||
|
|
||||||
|
For any other function, including any defined at an interactive prompt or
|
||||||
|
an autoload function whose path has not yet been resolved, this is
|
||||||
|
the empty string. However, the hash element is reported as defined
|
||||||
|
just so long as the function is present: the keys to this hash are
|
||||||
|
the same as those to tt($funcions).
|
||||||
|
)
|
||||||
|
vindex(dis_functions_source)
|
||||||
|
item(tt(dis_functions_source))(
|
||||||
|
Like tt(functions_source) but for disabled functions.
|
||||||
|
)
|
||||||
vindex(builtins)
|
vindex(builtins)
|
||||||
item(tt(builtins))(
|
item(tt(builtins))(
|
||||||
This associative array gives information about the builtin commands
|
This associative array gives information about the builtin commands
|
||||||
|
@ -202,10 +226,13 @@ 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
|
or `var(name) tt(LPAR()RPAR())' started. In the case of an autoloaded
|
||||||
function the line number is reported as zero.
|
function the line number is reported as zero.
|
||||||
The format of each element is var(filename)tt(:)var(lineno).
|
The format of each element is var(filename)tt(:)var(lineno).
|
||||||
|
|
||||||
For functions autoloaded from a file in native zsh format, where only the
|
For functions autoloaded from a file in native zsh format, where only the
|
||||||
body of the function occurs in the file, or for files that have been
|
body of the function occurs in the file, or for files that have been
|
||||||
executed by the tt(source) or `tt(.)' builtins, the trace information is
|
executed by the tt(source) or `tt(.)' builtins, the trace information is
|
||||||
shown as var(filename)tt(:)var(0), since the entire file is the definition.
|
shown as var(filename)tt(:)var(0), since the entire file is the
|
||||||
|
definition. The source file name is resolved to an absolute path when
|
||||||
|
the function is loaded or the path to it otherwise resolved.
|
||||||
|
|
||||||
Most users will be interested in the information in the
|
Most users will be interested in the information in the
|
||||||
tt(funcfiletrace) array instead.
|
tt(funcfiletrace) array instead.
|
||||||
|
|
|
@ -515,6 +515,98 @@ scanpmdisfunctions(HashTable ht, ScanFunc func, int flags)
|
||||||
scanfunctions(ht, func, flags, DISABLED);
|
scanfunctions(ht, func, flags, DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Functions for the functions_source special parameter. */
|
||||||
|
|
||||||
|
/* Retrieve the source file for a function by explicit name */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static HashNode
|
||||||
|
getfunction_source(UNUSED(HashTable ht), const char *name, int dis)
|
||||||
|
{
|
||||||
|
Shfunc shf;
|
||||||
|
Param pm = NULL;
|
||||||
|
|
||||||
|
pm = (Param) hcalloc(sizeof(struct param));
|
||||||
|
pm->node.nam = dupstring(name);
|
||||||
|
pm->node.flags = PM_SCALAR|PM_READONLY;
|
||||||
|
pm->gsu.s = dis ? &pmdisfunction_gsu : &pmfunction_gsu;
|
||||||
|
|
||||||
|
if ((shf = (Shfunc) shfunctab->getnode2(shfunctab, name)) &&
|
||||||
|
(dis ? (shf->node.flags & DISABLED) : !(shf->node.flags & DISABLED))) {
|
||||||
|
pm->u.str = getshfuncfile(shf);
|
||||||
|
if (!pm->u.str)
|
||||||
|
pm->u.str = dupstring("");
|
||||||
|
}
|
||||||
|
return &pm->node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve the source file for functions by scanning the table */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
scanfunctions_source(UNUSED(HashTable ht), ScanFunc func, int flags, int dis)
|
||||||
|
{
|
||||||
|
struct param pm;
|
||||||
|
int i;
|
||||||
|
HashNode hn;
|
||||||
|
|
||||||
|
memset((void *)&pm, 0, sizeof(struct param));
|
||||||
|
pm.node.flags = PM_SCALAR|PM_READONLY;
|
||||||
|
pm.gsu.s = dis ? &pmdisfunction_gsu : &pmfunction_gsu;
|
||||||
|
|
||||||
|
for (i = 0; i < shfunctab->hsize; i++) {
|
||||||
|
for (hn = shfunctab->nodes[i]; hn; hn = hn->next) {
|
||||||
|
if (dis ? (hn->flags & DISABLED) : !(hn->flags & DISABLED)) {
|
||||||
|
pm.node.nam = hn->nam;
|
||||||
|
if (func != scancountparams &&
|
||||||
|
((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
|
||||||
|
!(flags & SCANPM_WANTKEYS))) {
|
||||||
|
pm.u.str = getshfuncfile((Shfunc)hn);
|
||||||
|
if (!pm.u.str)
|
||||||
|
pm.u.str = dupstring("");
|
||||||
|
}
|
||||||
|
func(&pm.node, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Param table entry for retrieving functions_source element */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static HashNode
|
||||||
|
getpmfunction_source(HashTable ht, const char *name)
|
||||||
|
{
|
||||||
|
return getfunction_source(ht, name, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Param table entry for retrieving ds_functions_source element */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static HashNode
|
||||||
|
getpmdisfunction_source(HashTable ht, const char *name)
|
||||||
|
{
|
||||||
|
return getfunction_source(ht, name, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Param table entry for scanning functions_source table */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
scanpmfunction_source(HashTable ht, ScanFunc func, int flags)
|
||||||
|
{
|
||||||
|
scanfunctions_source(ht, func, flags, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Param table entry for scanning dis_functions_source table */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
scanpmdisfunction_source(HashTable ht, ScanFunc func, int flags)
|
||||||
|
{
|
||||||
|
scanfunctions_source(ht, func, flags, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Functions for the funcstack special parameter. */
|
/* Functions for the funcstack special parameter. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -2095,6 +2187,8 @@ static struct paramdef partab[] = {
|
||||||
NULL, getpmdisbuiltin, scanpmdisbuiltins),
|
NULL, getpmdisbuiltin, scanpmdisbuiltins),
|
||||||
SPECIALPMDEF("dis_functions", 0,
|
SPECIALPMDEF("dis_functions", 0,
|
||||||
&pmdisfunctions_gsu, getpmdisfunction, scanpmdisfunctions),
|
&pmdisfunctions_gsu, getpmdisfunction, scanpmdisfunctions),
|
||||||
|
SPECIALPMDEF("dis_functions_source", PM_READONLY, NULL,
|
||||||
|
getpmdisfunction_source, scanpmdisfunction_source),
|
||||||
SPECIALPMDEF("dis_galiases", 0,
|
SPECIALPMDEF("dis_galiases", 0,
|
||||||
&pmdisgaliases_gsu, getpmdisgalias, scanpmdisgaliases),
|
&pmdisgaliases_gsu, getpmdisgalias, scanpmdisgaliases),
|
||||||
SPECIALPMDEF("dis_patchars", PM_ARRAY|PM_READONLY,
|
SPECIALPMDEF("dis_patchars", PM_ARRAY|PM_READONLY,
|
||||||
|
@ -2111,6 +2205,8 @@ static struct paramdef partab[] = {
|
||||||
&funcstack_gsu, NULL, NULL),
|
&funcstack_gsu, NULL, NULL),
|
||||||
SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
|
SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
|
||||||
scanpmfunctions),
|
scanpmfunctions),
|
||||||
|
SPECIALPMDEF("functions_source", PM_READONLY, NULL,
|
||||||
|
getpmfunction_source, scanpmfunction_source),
|
||||||
SPECIALPMDEF("functrace", PM_ARRAY|PM_READONLY,
|
SPECIALPMDEF("functrace", PM_ARRAY|PM_READONLY,
|
||||||
&functrace_gsu, NULL, NULL),
|
&functrace_gsu, NULL, NULL),
|
||||||
SPECIALPMDEF("galiases", 0,
|
SPECIALPMDEF("galiases", 0,
|
||||||
|
|
|
@ -1565,6 +1565,15 @@ dircache_set(char **name, char *value)
|
||||||
zsfree(*name);
|
zsfree(*name);
|
||||||
*name = NULL;
|
*name = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* As the function path has been resolved to a particular
|
||||||
|
* location, we'll store it as an absolute path.
|
||||||
|
*/
|
||||||
|
if (*value != '/') {
|
||||||
|
value = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP),
|
||||||
|
"/", value);
|
||||||
|
value = xsymlink(value, 1);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* We'll maintain the cache at exactly the right size rather
|
* We'll maintain the cache at exactly the right size rather
|
||||||
* than overallocating. The rationale here is that typically
|
* than overallocating. The rationale here is that typically
|
||||||
|
|
|
@ -325,10 +325,10 @@
|
||||||
printf '%s\n' 'oops(){}' 'ninjas-earring(){}' 'oops "$@"' >oops
|
printf '%s\n' 'oops(){}' 'ninjas-earring(){}' 'oops "$@"' >oops
|
||||||
autoload oops
|
autoload oops
|
||||||
oops
|
oops
|
||||||
whence -v oops
|
whence -v oops | sed -e "s%$PWD%CURDIR%"
|
||||||
)
|
)
|
||||||
0:whence -v of zsh-style autoload
|
0:whence -v of zsh-style autoload
|
||||||
>oops is a shell function from ./oops
|
>oops is a shell function from CURDIR/oops
|
||||||
|
|
||||||
(
|
(
|
||||||
fpath=(.)
|
fpath=(.)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
%test
|
%test
|
||||||
|
|
||||||
print 'print In sourced file
|
print 'print In sourced file
|
||||||
print $LINENO + $functrace + $funcsourcetrace
|
print $LINENO + $functrace + ${funcsourcetrace/#$PWD/CURDIR}
|
||||||
' >sourcedfile
|
' >sourcedfile
|
||||||
print -r -- 'print Started functrace.zsh
|
print -r -- 'print Started functrace.zsh
|
||||||
module_path=(./Modules)
|
module_path=(./Modules)
|
||||||
print $LINENO + $functrace + $funcsourcetrace
|
print $LINENO + $functrace + ${funcsourcetrace/#$PWD/CURDIR}
|
||||||
:
|
:
|
||||||
fn() {
|
fn() {
|
||||||
print Inside function $0
|
print Inside function $0
|
||||||
print $LINENO + $functrace + $funcsourcetrace
|
print $LINENO + $functrace + ${funcsourcetrace/#$PWD/CURDIR}
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
fn
|
fn
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
fpath=(. $fpath)
|
fpath=(. $fpath)
|
||||||
:
|
:
|
||||||
echo '\''print Inside $0
|
echo '\''print Inside $0
|
||||||
print $LINENO + $functrace + $funcsourcetrace
|
print $LINENO + $functrace + ${funcsourcetrace/#$PWD/CURDIR}
|
||||||
'\'' >autofn
|
'\'' >autofn
|
||||||
:
|
:
|
||||||
autoload autofn
|
autoload autofn
|
||||||
|
@ -32,9 +32,9 @@
|
||||||
>Inside function fn
|
>Inside function fn
|
||||||
>2 + ./functrace.zsh:10 + ./functrace.zsh:5
|
>2 + ./functrace.zsh:10 + ./functrace.zsh:5
|
||||||
>Inside autofn
|
>Inside autofn
|
||||||
>2 + ./functrace.zsh:20 + ./autofn:0
|
>2 + ./functrace.zsh:20 + CURDIR/autofn:0
|
||||||
>Inside autofn
|
>Inside autofn
|
||||||
>2 + ./functrace.zsh:21 + ./autofn:0
|
>2 + ./functrace.zsh:21 + CURDIR/autofn:0
|
||||||
>In sourced file
|
>In sourced file
|
||||||
>2 + ./functrace.zsh:22 + ./sourcedfile:0
|
>2 + ./functrace.zsh:22 + ./sourcedfile:0
|
||||||
|
|
||||||
|
@ -66,6 +66,19 @@
|
||||||
>./rocky3.zsh:13 (eval):2
|
>./rocky3.zsh:13 (eval):2
|
||||||
>./rocky3.zsh:14 ./rocky3.zsh:14
|
>./rocky3.zsh:14 ./rocky3.zsh:14
|
||||||
|
|
||||||
|
(
|
||||||
|
fpath=($PWD)
|
||||||
|
print "print I have been autoloaded" >myfunc
|
||||||
|
autoload $PWD/myfunc
|
||||||
|
print ${functions_source[myfunc]/#$PWD/CURDIR}
|
||||||
|
myfunc
|
||||||
|
print ${functions_source[myfunc]/#$PWD/CURDIR}
|
||||||
|
)
|
||||||
|
0: $functions_source
|
||||||
|
>CURDIR/myfunc
|
||||||
|
>I have been autoloaded
|
||||||
|
>CURDIR/myfunc
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
|
|
||||||
rm -f autofn functrace.zsh rocky3.zsh sourcedfile
|
rm -f autofn functrace.zsh rocky3.zsh sourcedfile myfunc
|
||||||
|
|
Loading…
Reference in a new issue