1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-08 12:01:21 +02:00

zsh-workers/8404

This commit is contained in:
Tanaka Akira 1999-10-25 09:34:23 +00:00
parent f2217a0188
commit 1fe3b56224
6 changed files with 164 additions and 37 deletions

View file

@ -71,7 +71,24 @@ which no alias has been defined.
findex(autoload)
cindex(functions, autoloading)
cindex(autoloading functions)
alias(autoload)(functions -u)
item(tt(autoload) [ {tt(PLUS())|tt(-)}tt(UXmt) ] [ var(name) ... ])(
Equivalent to tt(functions -u), with the exception of tt(-X)/tt(+X).
The flag tt(-X) may be used only inside a shell function, and may not be
followed by a var(name). It causes the calling function to be marked for
autoloading and then immediately loaded and executed, with the current
array of positional parameters as arguments. This replaces the previous
definition of the function. If no function definition is found, an error
is printed and the function remains undefined and marked for autoloading.
The flag tt(+X) attempts to load each var(name) as an autoloaded function,
but does em(not) execute it. The exit status is zero (success) if the
function was not previously defined em(and) a definition for it was found.
This does em(not) replace any existing definition of the function. The
exit status is nonzero (failure) if the function was already defined or
when no definition was found. In the latter case the function remains
undefined and marked for autoloading.
)
findex(bg)
cindex(jobs, backgrounding)
xitem(tt(bg) [ var(job) ... ])
@ -353,7 +370,7 @@ Equivalent to tt(typeset -E), except that options irrelevant to floating
point numbers are not permitted.
)
findex(functions)
item(tt(functions) [ {tt(PLUS())|tt(-)}tt(tum) ] [ var(name) ... ])(
item(tt(functions) [ {tt(PLUS())|tt(-)}tt(UXmtu) ] [ var(name) ... ])(
Equivalent to tt(typeset -f).
)
findex(getln)
@ -1028,6 +1045,7 @@ item(tt(-U))(
For arrays (but not for associative arrays), keep only the first
occurrence of each duplicated value. This may also be set for
colon-separated special parameters like tt(PATH) or tt(FIGNORE), etc.
This flag has a different meaning when used with tt(-f); see below.
)
item(tt(-Z))(
Right justify and fill with leading zeros if the first non-blank
@ -1044,8 +1062,8 @@ shown.
)
item(tt(-f))(
The names refer to functions rather than parameters. No assignments
can be made, and the only other valid flags are tt(-t), tt(-u) and
tt(-U). The flag tt(-t) turns on execution tracing for this
can be made, and the only other valid flags are tt(-t), tt(-u), tt(-U),
tt(-X) and tt(+X). The flag tt(-t) turns on execution tracing for this
function. The tt(-u) and tt(-U) flags cause the function to be
marked for autoloading; tt(-U) also causes alias expansion to be
suppressed when the function is loaded. The tt(fpath) parameter
@ -1096,10 +1114,12 @@ The given var(name)s are marked readonly.
)
item(tt(-t))(
Tags the named parameters. Tags have no special meaning to the shell.
This flag has a different meaning when used with tt(-f); see above.
)
item(tt(-u))(
Convert the result to upper case whenever the parameter is expanded.
The value is em(not) converted when assigned.
This flag has a different meaning when used with tt(-f); see above.
)
item(tt(-x))(
Mark for automatic export to the environment of subsequently

View file

@ -74,6 +74,29 @@ and any subsequent calls. Without tt(KSH_AUTOLOAD) set, it will produce
the initialization message on the first call, and the other message on the
second and subsequent calls.
It is also possible to create a function that is not marked autoloaded,
yet loads its own definition by searching tt(fpath): `tt(autoload -X)',
when called from within a shell function tt(myfunc), is equivalent to:
example(unfunction myfunc
autoload myfunc
myfunc "$@")
In fact, the tt(functions) command outputs `tt(builtin autoload -X)' as
the body of an autoloaded function. A true autoloaded function can be
identifed by the presence of the comment `tt(# undefined)' in the body,
because all comments are discarded from defined functions. This is done
so that
example(eval "$(functions)")
produces a reasonable result.
To load the definition of an autoloaded function tt(myfunc) without
executing tt(myfunc), use:
example(autoload +X myfunc)
sect(Special Functions)
The following functions, if defined, have special meaning to
the shell:

View file

@ -424,7 +424,9 @@ getpmfunction(HashTable ht, char *name)
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, name))) {
if (shf->flags & PM_UNDEFINED)
pm->u.str = "undefined";
pm->u.str = tricat("builtin autoload -X",
((shf->flags & PM_UNALIASED)? "U" : ""),
((shf->flags & PM_TAGGED)? "t" : ""));
else {
char *t = getpermtext((void *) dupstruct((void *)
shf->funcdef)), *h;
@ -467,9 +469,12 @@ scanpmfunctions(HashTable ht, ScanFunc func, int flags)
if (!(hn->flags & DISABLED)) {
pm.nam = hn->nam;
if (func != scancountparams) {
if (((Shfunc) hn)->flags & PM_UNDEFINED)
pm.u.str = "undefined";
else {
if (((Shfunc) hn)->flags & PM_UNDEFINED) {
Shfunc shf = (Shfunc) hn;
pm.u.str = tricat("builtin autoload -X",
((shf->flags & PM_UNALIASED)? "U" : ""),
((shf->flags & PM_TAGGED)? "t" : ""));
} else {
char *t = getpermtext((void *)
dupstruct((void *) ((Shfunc) hn)->funcdef));
@ -779,7 +784,7 @@ dirssetfn(Param pm, char **x)
PERMALLOC {
freelinklist(dirstack, freestr);
dirstack = newlinklist();
while (*x)
while (x && *x)
addlinknode(dirstack, ztrdup(*x++));
} LASTALLOC;
}

View file

@ -43,7 +43,7 @@ static struct builtin builtins[] =
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmr", NULL),
BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "tU", "u"),
BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "tUX", "u"),
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
@ -1998,6 +1998,29 @@ bin_typeset(char *name, char **argv, char *ops, int func)
return returnval;
}
/* Helper for bin_functions() when run as "autoload -X" */
static int
eval_autoload(Shfunc shf, char *name, char *ops, int func)
{
if (!(shf->flags & PM_UNDEFINED))
return 1;
if (shf->funcdef)
freestruct(shf->funcdef);
if (ops['X'] == 1) {
char *fargv[3];
fargv[0] = name;
fargv[1] = "\"$@\"";
fargv[2] = 0;
shf->funcdef = mkautofn(shf);
return bin_eval(name, fargv, ops, func);
}
return loadautofn(shf);
}
/* Display or change the attributes of shell functions. *
* If called as autoload, it will define a new autoloaded *
* (undefined) shell function. */
@ -2012,10 +2035,10 @@ bin_functions(char *name, char **argv, char *ops, int func)
int on = 0, off = 0, pflags = 0;
/* Do we have any flags defined? */
if (ops['u'] == 1)
on |= PM_UNDEFINED;
else if (ops['u'] == 2)
if (ops['u'] == 2)
off |= PM_UNDEFINED;
else if (ops['u'] == 1 || ops['X'])
on |= PM_UNDEFINED;
if (ops['U'] == 1)
on |= PM_UNALIASED|PM_UNDEFINED;
else if (ops['U'] == 2)
@ -2025,7 +2048,8 @@ bin_functions(char *name, char **argv, char *ops, int func)
else if (ops['t'] == 2)
off |= PM_TAGGED;
if (off & PM_UNDEFINED) {
if ((off & PM_UNDEFINED) ||
(ops['X'] == 1 && (ops['m'] || *argv || !scriptname))) {
zwarnnam(name, "invalid option(s)", NULL, 0);
return 1;
}
@ -2037,10 +2061,22 @@ bin_functions(char *name, char **argv, char *ops, int func)
* are given, we will print only functions containing these *
* flags, else we'll print them all. */
if (!*argv) {
if (ops['U'] && !ops['u'])
on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags);
if (ops['X'] == 1) {
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) {
DPUTS(!shf->funcdef,
"BUG: Calling autoload from empty function");
} else {
shf = (Shfunc) zcalloc(sizeof *shf);
shfunctab->addnode(shfunctab, ztrdup(scriptname), shf);
}
shf->flags = on;
return eval_autoload(shf, scriptname, ops, func);
} else {
if (ops['U'] && !ops['u'])
on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags);
}
return 0;
}
@ -2061,8 +2097,14 @@ bin_functions(char *name, char **argv, char *ops, int func)
for (shf = (Shfunc) shfunctab->nodes[i]; shf;
shf = (Shfunc) shf->next)
if (pattry(pprog, shf->nam) &&
!(shf->flags & DISABLED))
shf->flags = (shf->flags | on) & (~off);
!(shf->flags & DISABLED)) {
shf->flags = (shf->flags |
(on & ~PM_UNDEFINED)) & ~off;
if (ops['X'] &&
eval_autoload(shf, shf->nam, ops, func)) {
returnval = 1;
}
}
}
}
} else {
@ -2078,10 +2120,12 @@ bin_functions(char *name, char **argv, char *ops, int func)
for (; *argv; argv++) {
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, *argv))) {
/* if any flag was given */
if (on|off)
if (on|off) {
/* turn on/off the given flags */
shf->flags = (shf->flags | (on & ~PM_UNDEFINED)) & ~off;
else
if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
returnval = 1;
} else
/* no flags, so just print */
shfunctab->printnode((HashNode) shf, pflags);
} else if (on & PM_UNDEFINED) {
@ -2091,6 +2135,8 @@ bin_functions(char *name, char **argv, char *ops, int func)
shf->flags = on;
shf->funcdef = mkautofn(shf);
shfunctab->addnode(shfunctab, ztrdup(*argv), shf);
if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
returnval = 1;
} else
returnval = 1;
}

View file

@ -2911,11 +2911,11 @@ execautofn(Cmd cmd, LinkList args, int flags)
l = getfpfunc(shf->nam);
noaliases = noalias;
if(l == &dummy_list) {
if (l == &dummy_list) {
zerr("%s: function definition file not found", shf->nam, 0);
return 1;
}
if(isset(KSHAUTOLOAD)) {
if (isset(KSHAUTOLOAD)) {
VARARR(char, n, strlen(shf->nam) + 1);
strcpy(n, shf->nam);
execlist(l, 1, 0);
@ -2935,6 +2935,31 @@ execautofn(Cmd cmd, LinkList args, int flags)
return lastval;
}
/**/
int
loadautofn(Shfunc shf)
{
/* Copied from execautofn() -- should consolidate someday */
int noalias = noaliases;
List l;
noaliases = (shf->flags & PM_UNALIASED);
l = getfpfunc(shf->nam);
noaliases = noalias;
if (l == &dummy_list) {
zerr("%s: function definition file not found", shf->nam, 0);
return 1;
}
PERMALLOC {
shf->funcdef = dupstruct(stripkshdef(l, shf->nam));
} LASTALLOC;
shf->flags &= ~PM_UNDEFINED;
return 0;
}
/* execute a shell function */
/**/

View file

@ -872,21 +872,29 @@ printshfuncnode(HashNode hn, int printflags)
}
if (f->flags & PM_UNDEFINED)
printf("undefined ");
if (f->flags & PM_TAGGED)
printf("traced ");
if ((f->flags & PM_UNDEFINED) || !f->funcdef) {
nicezputs(f->nam, stdout);
printf(" () { }\n");
return;
t = tricat("builtin autoload -X",
((f->flags & PM_UNALIASED)? "U" : ""),
((f->flags & PM_TAGGED)? "t" : ""));
else {
if (!f->funcdef)
t = 0;
else
t = getpermtext((void *) f->funcdef);
}
t = getpermtext((void *) f->funcdef);
quotedzputs(f->nam, stdout);
printf(" () {\n\t");
zputs(t, stdout);
printf("\n}\n");
zsfree(t);
if (t) {
printf(" () {\n\t");
if (f->flags & PM_UNDEFINED)
printf("%c undefined\n\t", hashchar);
if (f->flags & PM_TAGGED)
printf("%c traced\n\t", hashchar);
zputs(t, stdout);
printf("\n}\n");
zsfree(t);
} else {
printf(" () { }\n");
}
}
/**************************************/