diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-10-25 09:34:23 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-10-25 09:34:23 +0000 |
commit | 1fe3b5622443f16f1d64a250a648db595090670a (patch) | |
tree | 8ae49f263de648900eb54ef85beeee410e18df22 /Src/builtin.c | |
parent | f2217a01887e63ad9239b9a0e53606e233550580 (diff) | |
download | zsh-1fe3b5622443f16f1d64a250a648db595090670a.tar.gz zsh-1fe3b5622443f16f1d64a250a648db595090670a.tar.xz zsh-1fe3b5622443f16f1d64a250a648db595090670a.zip |
zsh-workers/8404
Diffstat (limited to 'Src/builtin.c')
-rw-r--r-- | Src/builtin.c | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/Src/builtin.c b/Src/builtin.c index acefcd111..3df653dcc 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -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; } |