mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-05-25 17:36:16 +02:00
23606: make all module feature autoloads pass through one function
This commit is contained in:
parent
cc2867746a
commit
4be5febd94
|
@ -1,3 +1,8 @@
|
|||
2007-06-26 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 23606: Src/mkbltnmlst.sh, Src/module.c, Test/V01zmodload.ztst:
|
||||
make all module feature autoloads pass through one function.
|
||||
|
||||
2007-06-24 Clint Adams <clint@zsh.org>
|
||||
|
||||
* 23595: Completion/Unix/Command/_git: merge in git archive
|
||||
|
|
|
@ -48,7 +48,7 @@ for x_mod in $x_mods; do
|
|||
done
|
||||
echo " NULL"
|
||||
echo " }; "
|
||||
echo " autofeatures(\"zsh\", features, \"$x_mod\", 1);"
|
||||
echo " autofeatures(\"zsh\", \"$x_mod\", features, 0, 1);"
|
||||
echo " }"
|
||||
fi
|
||||
for dep in $moddeps; do
|
||||
|
|
575
Src/module.c
575
Src/module.c
|
@ -45,6 +45,35 @@ char **module_path;
|
|||
/**/
|
||||
mod_export LinkList modules;
|
||||
|
||||
/*
|
||||
* Bit flags passed as the "flags" argument of a autofeaturefn_t.
|
||||
*/
|
||||
enum {
|
||||
/* `-i' option: ignore errors pertaining to redefinitions */
|
||||
AUTOFEAT_IGNORE = 0x0001,
|
||||
/* If a condition, condition is infix rather than prefix */
|
||||
AUTOFEAT_INFIX = 0x0002
|
||||
};
|
||||
|
||||
/*
|
||||
* All functions to add or remove autoloadable features fit
|
||||
* the following prototype.
|
||||
*
|
||||
* "module" is the name of the module.
|
||||
*
|
||||
* "feature" is the name of the feature, minus any type prefix.
|
||||
*
|
||||
* "flags" is a set of the bits above.
|
||||
*
|
||||
* The return value is 0 for success, a negative value for failure with no
|
||||
* message needed, and one of the following to indicate the calling
|
||||
* function should print a message:
|
||||
*
|
||||
* 1: failed to add [type] `[feature]'
|
||||
* 2: [feature]: no such [type]
|
||||
* 3: [feature]: [type] is already defined
|
||||
*/
|
||||
typedef int (*autofeaturefn_t)(char *module, char *feature, int flags);
|
||||
|
||||
/************************************************************************
|
||||
* zsh/main standard module functions
|
||||
|
@ -196,25 +225,18 @@ addbuiltin(Builtin b)
|
|||
* with the specified name already exists. */
|
||||
|
||||
/**/
|
||||
int
|
||||
add_autobin(char *cmdnam, char *bnam, char *module, int opt_i)
|
||||
static int
|
||||
add_autobin(char *module, char *bnam, int flags)
|
||||
{
|
||||
Builtin bn;
|
||||
|
||||
if (strchr(bnam, '/')) {
|
||||
zwarnnam(cmdnam, "%s: `/' is illegal in a builtin", bnam);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bn = zshcalloc(sizeof(*bn));
|
||||
bn->node.nam = ztrdup(bnam);
|
||||
bn->optstr = ztrdup(module);
|
||||
if (addbuiltin(bn)) {
|
||||
builtintab->freenode(&bn->node);
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "failed to add builtin %s", bnam);
|
||||
if (!(flags & AUTOFEAT_IGNORE))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -239,17 +261,14 @@ deletebuiltin(char *nam)
|
|||
|
||||
/**/
|
||||
static int
|
||||
del_autobin(char *cmdnam, char *bnam, int opt_i)
|
||||
del_autobin(UNUSED(char *module), char *bnam, int flags)
|
||||
{
|
||||
Builtin bn = (Builtin) builtintab->getnode2(builtintab, bnam);
|
||||
if (!bn) {
|
||||
if(!opt_i) {
|
||||
zwarnnam(cmdnam, "%s: no such builtin", bnam);
|
||||
return 1;
|
||||
}
|
||||
if(!(flags & AUTOFEAT_IGNORE))
|
||||
return 2;
|
||||
} else if (bn->node.flags & BINF_ADDED) {
|
||||
zwarnnam(cmdnam, "%s: builtin is already defined", bnam);
|
||||
return 1;
|
||||
return 3;
|
||||
} else
|
||||
deletebuiltin(bnam);
|
||||
|
||||
|
@ -557,20 +576,15 @@ setconddefs(char const *nam, Conddef c, int size, int *e)
|
|||
/* This adds a definition for autoloading a module for a condition. */
|
||||
|
||||
/**/
|
||||
int
|
||||
add_autocond(char *cmdnam, char *cnam, int inf, char *module, int opt_i)
|
||||
static int
|
||||
add_autocond(char *module, char *cnam, int flags)
|
||||
{
|
||||
Conddef c;
|
||||
|
||||
if (strchr(cnam, '/')) {
|
||||
zwarnnam(cmdnam, "%s: `/' is illegal in a condition", cnam);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = (Conddef) zalloc(sizeof(*c));
|
||||
|
||||
c->name = ztrdup(cnam);
|
||||
c->flags = (inf ? CONDF_INFIX : 0);
|
||||
c->flags = ((flags & AUTOFEAT_INFIX) ? CONDF_INFIX : 0);
|
||||
c->module = ztrdup(module);
|
||||
|
||||
if (addconddef(c)) {
|
||||
|
@ -578,10 +592,8 @@ add_autocond(char *cmdnam, char *cnam, int inf, char *module, int opt_i)
|
|||
zsfree(c->module);
|
||||
zfree(c, sizeof(*c));
|
||||
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "failed to add condition `%s'", cnam);
|
||||
if (!(flags & AUTOFEAT_IGNORE))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -590,18 +602,16 @@ add_autocond(char *cmdnam, char *cnam, int inf, char *module, int opt_i)
|
|||
|
||||
/**/
|
||||
static int
|
||||
del_autocond(char *cmdnam, char *cnam, int infix, int opt_i)
|
||||
del_autocond(UNUSED(char *modnam), char *cnam, int flags)
|
||||
{
|
||||
Conddef cd = getconddef(infix, cnam, 0);
|
||||
Conddef cd = getconddef((flags & AUTOFEAT_INFIX) ? 1 : 0, cnam, 0);
|
||||
|
||||
if (!cd) {
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "%s: no such condition", cnam);
|
||||
return 1;
|
||||
if (!(flags & AUTOFEAT_IGNORE)) {
|
||||
return 2;
|
||||
}
|
||||
} else if (cd->flags & CONDF_ADDED) {
|
||||
zwarnnam(cmdnam, "%s: condition is already defined", cnam);
|
||||
return 1;
|
||||
return 3;
|
||||
} else
|
||||
deleteconddef(cd);
|
||||
|
||||
|
@ -959,29 +969,23 @@ setparamdefs(char const *nam, Paramdef d, int size, int *e)
|
|||
/* This adds a definition for autoloading a module for a parameter. */
|
||||
|
||||
/**/
|
||||
int
|
||||
add_autoparam(char *cmdnam, char *pnam, char *module, int opt_i)
|
||||
static int
|
||||
add_autoparam(char *module, char *pnam, int flags)
|
||||
{
|
||||
Param pm;
|
||||
int ret;
|
||||
|
||||
if (strchr(pnam, '/')) {
|
||||
zwarnnam(cmdnam, "%s: `/' is illegal in a parameter", pnam);
|
||||
return 1;
|
||||
}
|
||||
|
||||
queue_signals();
|
||||
if ((ret = checkaddparam(pnam, opt_i))) {
|
||||
if ((ret = checkaddparam(pnam, (flags & AUTOFEAT_IGNORE)))) {
|
||||
unqueue_signals();
|
||||
/*
|
||||
* checkaddparam() has already printed a message
|
||||
* if one was needed. If it wasn't because of -i,
|
||||
* ret is 2; for consistency with other add_auto*
|
||||
* functions we return status 0 to indicate there's
|
||||
* already such a parameter and we've been told not
|
||||
* to worry if so.
|
||||
* checkaddparam() has already printed a message if one was
|
||||
* needed. If it wasn't owing to the presence of -i, ret is 2;
|
||||
* for consistency with other add_auto* functions we return
|
||||
* status 0 to indicate there's already such a parameter and
|
||||
* we've been told not to worry if so.
|
||||
*/
|
||||
return ret == 2 ? 0 : 1;
|
||||
return ret == 2 ? 0 : -1;
|
||||
}
|
||||
|
||||
pm = setsparam(pnam, ztrdup(module));
|
||||
|
@ -996,18 +1000,15 @@ add_autoparam(char *cmdnam, char *pnam, char *module, int opt_i)
|
|||
|
||||
/**/
|
||||
static int
|
||||
del_autoparam(char *cmdnam, char *pnam, int opt_i)
|
||||
del_autoparam(UNUSED(char *modnam), char *pnam, int flags)
|
||||
{
|
||||
Param pm = (Param) gethashnode2(paramtab, pnam);
|
||||
|
||||
if (!pm) {
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "%s: no such parameter", pnam);
|
||||
return 1;
|
||||
}
|
||||
if (!(flags & AUTOFEAT_IGNORE))
|
||||
return 2;
|
||||
} else if (!(pm->node.flags & PM_AUTOLOAD)) {
|
||||
zwarnnam(cmdnam, "%s: parameter is already defined", pnam);
|
||||
return 1;
|
||||
return 3;
|
||||
} else
|
||||
unsetparam_pm(pm, 0, 1);
|
||||
|
||||
|
@ -1169,16 +1170,11 @@ setmathfuncs(char const *nam, MathFunc f, int size, int *e)
|
|||
/* Add an autoload definition for a math function. */
|
||||
|
||||
/**/
|
||||
int
|
||||
add_automathfunc(char *cmdnam, char *fnam, char *module, int opt_i)
|
||||
static int
|
||||
add_automathfunc(char *module, char *fnam, int flags)
|
||||
{
|
||||
MathFunc f;
|
||||
|
||||
if (strchr(fnam, '/')) {
|
||||
zwarnnam(cmdnam, "%s: `/' is illegal in a math function", fnam);
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = (MathFunc) zalloc(sizeof(*f));
|
||||
|
||||
f->name = ztrdup(fnam);
|
||||
|
@ -1190,10 +1186,8 @@ add_automathfunc(char *cmdnam, char *fnam, char *module, int opt_i)
|
|||
zsfree(f->module);
|
||||
zfree(f, sizeof(*f));
|
||||
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "failed to add math function `%s'", fnam);
|
||||
if (!(flags & AUTOFEAT_IGNORE))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1203,18 +1197,15 @@ add_automathfunc(char *cmdnam, char *fnam, char *module, int opt_i)
|
|||
|
||||
/**/
|
||||
static int
|
||||
del_automathfunc(char *cmdnam, char *fnam, int opt_i)
|
||||
del_automathfunc(UNUSED(char *modnam), char *fnam, int flags)
|
||||
{
|
||||
MathFunc f = getmathfunc(fnam, 0);
|
||||
|
||||
if (!f) {
|
||||
if (!opt_i) {
|
||||
zwarnnam(cmdnam, "%s: no such math function", fnam);
|
||||
return 1;
|
||||
}
|
||||
if (!(flags & AUTOFEAT_IGNORE))
|
||||
return 2;
|
||||
} else if (f->flags & MFF_ADDED) {
|
||||
zwarnnam(cmdnam, "%s: math function is already defined", fnam);
|
||||
return 1;
|
||||
return 3;
|
||||
} else
|
||||
deletemathfunc(f);
|
||||
|
||||
|
@ -1400,9 +1391,22 @@ do_load_module(char const *name, int silent)
|
|||
/**/
|
||||
#endif /* !DYNAMIC */
|
||||
|
||||
/* Bits in the second argument to find_module. */
|
||||
enum {
|
||||
/*
|
||||
* Resolve any aliases to the underlying module.
|
||||
*/
|
||||
FINDMOD_ALIASP = 0x0001,
|
||||
/*
|
||||
* Create an element for the module in the list if
|
||||
* it is not found.
|
||||
*/
|
||||
FINDMOD_CREATE = 0x0002,
|
||||
};
|
||||
|
||||
/*
|
||||
* Find a module in the list.
|
||||
* If aliasp is non-zero, resolve any aliases to the underlying module.
|
||||
* flags is a set of bits defined in the enum above.
|
||||
* If namep is set, this is set to point to the last alias value resolved,
|
||||
* even if that module was not loaded. or the module name if no aliases.
|
||||
* Hence this is always the physical module to load in a chain of aliases.
|
||||
|
@ -1415,7 +1419,7 @@ do_load_module(char const *name, int silent)
|
|||
*/
|
||||
/**/
|
||||
static LinkNode
|
||||
find_module(const char *name, int aliasp, const char **namep)
|
||||
find_module(const char *name, int flags, const char **namep)
|
||||
{
|
||||
Module m;
|
||||
LinkNode node;
|
||||
|
@ -1423,17 +1427,21 @@ find_module(const char *name, int aliasp, const char **namep)
|
|||
for (node = firstnode(modules); node; incnode(node)) {
|
||||
m = (Module) getdata(node);
|
||||
if (!strcmp(m->nam, name)) {
|
||||
if (aliasp && (m->flags & MOD_ALIAS)) {
|
||||
if ((flags & FINDMOD_ALIASP) && (m->flags & MOD_ALIAS)) {
|
||||
if (namep)
|
||||
*namep = m->u.alias;
|
||||
return find_module(m->u.alias, 1, namep);
|
||||
return find_module(m->u.alias, flags, namep);
|
||||
}
|
||||
if (namep)
|
||||
*namep = m->nam;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
if (!(flags & FINDMOD_CREATE))
|
||||
return NULL;
|
||||
m = zshcalloc(sizeof(*m));
|
||||
m->nam = ztrdup(name);
|
||||
return zaddlinknode(modules, m);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1468,7 +1476,7 @@ module_loaded(const char *name)
|
|||
LinkNode node;
|
||||
Module m;
|
||||
|
||||
return ((node = find_module(name, 1, NULL)) &&
|
||||
return ((node = find_module(name, FINDMOD_ALIASP, NULL)) &&
|
||||
(m = ((Module) getdata(node)))->u.handle &&
|
||||
!(m->flags & MOD_UNLOAD));
|
||||
}
|
||||
|
@ -1916,7 +1924,7 @@ load_module(char const *name, char **enablesstr, int silent)
|
|||
* is the right one.
|
||||
*/
|
||||
queue_signals();
|
||||
if (!(node = find_module(name, 1, &name))) {
|
||||
if (!(node = find_module(name, FINDMOD_ALIASP, &name))) {
|
||||
if (!(linked = module_linked(name)) &&
|
||||
!(handle = do_load_module(name, silent))) {
|
||||
unqueue_signals();
|
||||
|
@ -2082,12 +2090,7 @@ add_dep(const char *name, char *from)
|
|||
* Better make sure. (There's no problem making a an alias which
|
||||
* *points* to a module with dependencies, of course.)
|
||||
*/
|
||||
if (!(node = find_module(name, 1, &name))) {
|
||||
m = zshcalloc(sizeof(*m));
|
||||
m->nam = ztrdup(name);
|
||||
zaddlinknode(modules, m);
|
||||
} else
|
||||
m = (Module) getdata(node);
|
||||
m = getdata(find_module(name, FINDMOD_ALIASP|FINDMOD_CREATE, &name));
|
||||
if (!m->deps)
|
||||
m->deps = znewlinklist();
|
||||
for (node = firstnode(m->deps);
|
||||
|
@ -2146,7 +2149,7 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
|
|||
int ops_bcpf = OPT_ISSET(ops,'b') || OPT_ISSET(ops,'c') ||
|
||||
OPT_ISSET(ops,'p') || OPT_ISSET(ops,'f');
|
||||
int ops_au = OPT_ISSET(ops,'a') || OPT_ISSET(ops,'u');
|
||||
int ret = 1;
|
||||
int ret = 1, autoopts;
|
||||
/* options only allowed with -F */
|
||||
char *fonly = "lP", *fp;
|
||||
|
||||
|
@ -2195,20 +2198,17 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
|
|||
ret = bin_zmodload_exist(nam, args, ops);
|
||||
else if (OPT_ISSET(ops,'d'))
|
||||
ret = bin_zmodload_dep(nam, args, ops);
|
||||
else if ((OPT_ISSET(ops,'a') || OPT_ISSET(ops,'b')) &&
|
||||
!(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'p') || OPT_ISSET(ops,'f')))
|
||||
ret = bin_zmodload_auto(nam, args, ops);
|
||||
else if (OPT_ISSET(ops,'c') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'p')))
|
||||
ret = bin_zmodload_cond(nam, args, ops);
|
||||
else if (OPT_ISSET(ops,'f') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'p')))
|
||||
ret = bin_zmodload_math(nam, args, ops);
|
||||
else if (OPT_ISSET(ops,'p') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'c')))
|
||||
ret = bin_zmodload_param(nam, args, ops);
|
||||
else if (!(OPT_ISSET(ops,'a') || OPT_ISSET(ops,'b') ||
|
||||
OPT_ISSET(ops,'c') || OPT_ISSET(ops,'p')))
|
||||
else if ((autoopts = OPT_ISSET(ops, 'b') + OPT_ISSET(ops, 'c') +
|
||||
OPT_ISSET(ops, 'p') + OPT_ISSET(ops, 'f')) ||
|
||||
/* zmodload -a is equivalent to zmodload -ab, annoyingly */
|
||||
OPT_ISSET(ops, 'a')) {
|
||||
if (autoopts > 1) {
|
||||
zwarnnam(nam, "use only one of -b, -c, or -p");
|
||||
ret = 1;
|
||||
} else
|
||||
ret = bin_zmodload_auto(nam, args, ops);
|
||||
} else
|
||||
ret = bin_zmodload_load(nam, args, ops);
|
||||
else
|
||||
zwarnnam(nam, "use only one of -b, -c, or -p");
|
||||
unqueue_signals();
|
||||
|
||||
return ret;
|
||||
|
@ -2344,7 +2344,7 @@ bin_zmodload_exist(UNUSED(char *nam), char **args, Options ops)
|
|||
if (m->flags & MOD_ALIAS) {
|
||||
LinkNode node2;
|
||||
if (OPT_ISSET(ops,'A') &&
|
||||
(node2 = find_module(m->u.alias, 1, NULL)))
|
||||
(node2 = find_module(m->u.alias, FINDMOD_ALIASP, NULL)))
|
||||
m = (Module) getdata(node2);
|
||||
else
|
||||
continue;
|
||||
|
@ -2359,7 +2359,7 @@ bin_zmodload_exist(UNUSED(char *nam), char **args, Options ops)
|
|||
int ret = 0;
|
||||
|
||||
for (; !ret && *args; args++) {
|
||||
if (!(node = find_module(*args, 1, NULL))
|
||||
if (!(node = find_module(*args, FINDMOD_ALIASP, NULL))
|
||||
|| !(m = (Module) getdata(node))->u.handle
|
||||
|| (m->flags & MOD_UNLOAD))
|
||||
ret = 1;
|
||||
|
@ -2379,7 +2379,7 @@ bin_zmodload_dep(UNUSED(char *nam), char **args, Options ops)
|
|||
if (OPT_ISSET(ops,'u')) {
|
||||
/* remove dependencies, which can't pertain to aliases */
|
||||
const char *tnam = *args++;
|
||||
node = find_module(tnam, 1, &tnam);
|
||||
node = find_module(tnam, FINDMOD_ALIASP, &tnam);
|
||||
if (!node)
|
||||
return 0;
|
||||
m = (Module) getdata(node);
|
||||
|
@ -2443,133 +2443,6 @@ bin_zmodload_dep(UNUSED(char *nam), char **args, Options ops)
|
|||
}
|
||||
}
|
||||
|
||||
/* zmodload -ab */
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_auto(char *nam, char **args, Options ops)
|
||||
{
|
||||
int ret = 0;
|
||||
if (OPT_ISSET(ops,'u')) {
|
||||
/* removed autoloaded builtins */
|
||||
for (; *args; args++) {
|
||||
if (del_autobin(nam, *args, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
} else if(!*args) {
|
||||
/* list autoloaded builtins */
|
||||
scanhashtable(builtintab, 1, 0, 0,
|
||||
autoloadscan, OPT_ISSET(ops,'L') ? PRINT_LIST : 0);
|
||||
return 0;
|
||||
} else {
|
||||
/* add autoloaded builtins */
|
||||
char *modnam;
|
||||
modnam = *args++;
|
||||
do {
|
||||
char *bnam = *args ? *args++ : modnam;
|
||||
if (add_autobin(nam, bnam, modnam, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
} while(*args);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* zmodload -ac */
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_cond(char *nam, char **args, Options ops)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (OPT_ISSET(ops,'u')) {
|
||||
/* remove autoloaded conditions */
|
||||
for (; *args; args++) {
|
||||
if (del_autocond(nam, *args, OPT_ISSET(ops,'I'),
|
||||
OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
} else if (!*args) {
|
||||
/* list autoloaded conditions */
|
||||
Conddef p;
|
||||
|
||||
for (p = condtab; p; p = p->next) {
|
||||
if (p->module) {
|
||||
if (OPT_ISSET(ops,'L')) {
|
||||
fputs("zmodload -ac", stdout);
|
||||
if (p->flags & CONDF_INFIX)
|
||||
putchar('I');
|
||||
printf(" %s %s\n", p->module, p->name);
|
||||
} else {
|
||||
if (p->flags & CONDF_INFIX)
|
||||
fputs("infix ", stdout);
|
||||
else
|
||||
fputs("post ", stdout);
|
||||
printf("%s (%s)\n",p->name, p->module);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
/* add autoloaded conditions */
|
||||
char *modnam;
|
||||
|
||||
modnam = *args++;
|
||||
do {
|
||||
char *cnam = *args ? *args++ : modnam;
|
||||
if (add_autocond(nam, cnam, OPT_ISSET(ops, 'I'),
|
||||
modnam, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
} while(*args);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* zmodload -af */
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_math(char *nam, char **args, Options ops)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (OPT_ISSET(ops,'u')) {
|
||||
/* remove autoloaded math functions */
|
||||
for (; *args; args++) {
|
||||
if (del_automathfunc(nam, *args, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
} else if (!*args) {
|
||||
/* list autoloaded math functions */
|
||||
MathFunc p;
|
||||
|
||||
for (p = mathfuncs; p; p = p->next) {
|
||||
if (!(p->flags & MFF_USERFUNC) && p->module) {
|
||||
if (OPT_ISSET(ops,'L')) {
|
||||
fputs("zmodload -af", stdout);
|
||||
printf(" %s %s\n", p->module, p->name);
|
||||
} else
|
||||
printf("%s (%s)\n",p->name, p->module);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
/* add autoloaded math functions */
|
||||
char *modnam;
|
||||
|
||||
modnam = *args++;
|
||||
do {
|
||||
char *fnam = *args ? *args++ : modnam;
|
||||
if (add_automathfunc(nam, fnam, modnam, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
} while(*args);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function for scanning the parameter table to find and print
|
||||
* out autoloadable parameters.
|
||||
|
@ -2588,36 +2461,87 @@ printautoparams(HashNode hn, int lon)
|
|||
}
|
||||
}
|
||||
|
||||
/* zmodload -ap */
|
||||
/* zmodload -a/u [bcpf] */
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_param(char *nam, char **args, Options ops)
|
||||
bin_zmodload_auto(char *nam, char **args, Options ops)
|
||||
{
|
||||
int ret = 0;
|
||||
int fchar;
|
||||
char *modnam;
|
||||
|
||||
if (OPT_ISSET(ops,'c')) {
|
||||
if (!*args) {
|
||||
/* list autoloaded conditions */
|
||||
Conddef p;
|
||||
|
||||
for (p = condtab; p; p = p->next) {
|
||||
if (p->module) {
|
||||
if (OPT_ISSET(ops,'L')) {
|
||||
fputs("zmodload -ac", stdout);
|
||||
if (p->flags & CONDF_INFIX)
|
||||
putchar('I');
|
||||
printf(" %s %s\n", p->module, p->name);
|
||||
} else {
|
||||
if (p->flags & CONDF_INFIX)
|
||||
fputs("infix ", stdout);
|
||||
else
|
||||
fputs("post ", stdout);
|
||||
printf("%s (%s)\n",p->name, p->module);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fchar = OPT_ISSET(ops,'I') ? 'C' : 'c';
|
||||
} else if (OPT_ISSET(ops,'p')) {
|
||||
if (!*args) {
|
||||
/* list autoloaded parameters */
|
||||
scanhashtable(paramtab, 1, 0, 0, printautoparams,
|
||||
OPT_ISSET(ops,'L'));
|
||||
return 0;
|
||||
}
|
||||
fchar = 'p';
|
||||
} else if (OPT_ISSET(ops,'f')) {
|
||||
if (!*args) {
|
||||
/* list autoloaded math functions */
|
||||
MathFunc p;
|
||||
|
||||
for (p = mathfuncs; p; p = p->next) {
|
||||
if (!(p->flags & MFF_USERFUNC) && p->module) {
|
||||
if (OPT_ISSET(ops,'L')) {
|
||||
fputs("zmodload -af", stdout);
|
||||
printf(" %s %s\n", p->module, p->name);
|
||||
} else
|
||||
printf("%s (%s)\n",p->name, p->module);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fchar = 'f';
|
||||
} else {
|
||||
/* builtins are the default; zmodload -ab or just zmodload -a */
|
||||
if (!*args) {
|
||||
/* list autoloaded builtins */
|
||||
scanhashtable(builtintab, 1, 0, 0,
|
||||
autoloadscan, OPT_ISSET(ops,'L') ? PRINT_LIST : 0);
|
||||
return 0;
|
||||
}
|
||||
fchar = 'b';
|
||||
}
|
||||
|
||||
if (OPT_ISSET(ops,'u')) {
|
||||
/* remove autoloaded parameters */
|
||||
for (; *args; args++) {
|
||||
if (del_autoparam(nam, *args, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
} else if (!*args) {
|
||||
scanhashtable(paramtab, 1, 0, 0, printautoparams, OPT_ISSET(ops,'L'));
|
||||
return 0;
|
||||
/* remove autoload */
|
||||
fchar *= -1;
|
||||
modnam = NULL;
|
||||
} else {
|
||||
/* add autoloaded parameters */
|
||||
char *modnam;
|
||||
/* add autoload */
|
||||
modnam = *args;
|
||||
|
||||
modnam = *args++;
|
||||
do {
|
||||
char *pnam = *args ? *args++ : modnam;
|
||||
if (add_autoparam(nam, pnam, modnam, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
} while(*args);
|
||||
return ret;
|
||||
if (args[1])
|
||||
args++;
|
||||
}
|
||||
return autofeatures(nam, modnam, args, fchar, OPT_ISSET(ops,'i'));
|
||||
}
|
||||
|
||||
/* Backend handler for zmodload -u */
|
||||
|
@ -2630,7 +2554,7 @@ unload_module(Module m, LinkNode node)
|
|||
* Only unload the real module, so resolve aliases.
|
||||
*/
|
||||
if (m->flags & MOD_ALIAS) {
|
||||
LinkNode node = find_module(m->u.alias, 1, NULL);
|
||||
LinkNode node = find_module(m->u.alias, FINDMOD_ALIASP, NULL);
|
||||
if (!node)
|
||||
return 1;
|
||||
m = (Module) getdata(node);
|
||||
|
@ -2666,7 +2590,8 @@ unload_module(Module m, LinkNode node)
|
|||
LinkNode n;
|
||||
|
||||
for (n = firstnode(m->deps); n; incnode(n)) {
|
||||
LinkNode dn = find_module((char *) getdata(n), 1, NULL);
|
||||
LinkNode dn = find_module((char *) getdata(n),
|
||||
FINDMOD_ALIASP, NULL);
|
||||
Module dm;
|
||||
|
||||
if (dn && (dm = (Module) getdata(dn)) &&
|
||||
|
@ -2725,7 +2650,7 @@ unload_named_module(char *modname, char *nam, int silent)
|
|||
Module m;
|
||||
int ret = 0;
|
||||
|
||||
node = find_module(modname, 1, &mname);
|
||||
node = find_module(modname, FINDMOD_ALIASP, &mname);
|
||||
if (node) {
|
||||
LinkNode mn, dn;
|
||||
int del = 0;
|
||||
|
@ -2832,7 +2757,7 @@ bin_zmodload_features(char *nam, char **args, Options ops)
|
|||
int *enables = NULL, *ep;
|
||||
char *param = OPT_ARG_SAFE(ops,'P');
|
||||
|
||||
node = find_module(modname, 1, NULL);
|
||||
node = find_module(modname, FINDMOD_ALIASP, NULL);
|
||||
if (node)
|
||||
m = ((Module) getdata(node));
|
||||
if (!m || !m->u.handle || (m->flags & MOD_UNLOAD)) {
|
||||
|
@ -2949,7 +2874,7 @@ bin_zmodload_features(char *nam, char **args, Options ops)
|
|||
zwarnnam(nam, "-P can only be used with -l or -L");
|
||||
return 1;
|
||||
} else if (OPT_ISSET(ops,'a')) {
|
||||
return autofeatures(nam, args, modname, OPT_ISSET(ops,'i'));
|
||||
return autofeatures(nam, modname, args, 0, OPT_ISSET(ops,'i'));
|
||||
}
|
||||
|
||||
return require_module(modname, args);
|
||||
|
@ -3115,64 +3040,106 @@ ensurefeature(char *modname, char *prefix, char *feature)
|
|||
|
||||
/**/
|
||||
int
|
||||
autofeatures(char *cmdnam, char **features, char *module, int opt_i)
|
||||
autofeatures(char *cmdnam, char *module, char **features, int prefchar,
|
||||
int opt_i)
|
||||
{
|
||||
int ret = 0, infix;
|
||||
int ret = 0, subret;
|
||||
int defflags = opt_i ? AUTOFEAT_IGNORE : 0;
|
||||
|
||||
while (*features) {
|
||||
char *feature = *features, *fnam;
|
||||
int add;
|
||||
char *fnam, *typnam;
|
||||
int add, fchar, flags = defflags;
|
||||
autofeaturefn_t fn;
|
||||
|
||||
if (*feature == '-') {
|
||||
add = 0;
|
||||
feature ++;
|
||||
if (prefchar) {
|
||||
if (prefchar < 0) {
|
||||
add = 0;
|
||||
fchar = - prefchar;
|
||||
} else {
|
||||
add = 1;
|
||||
fchar = prefchar;
|
||||
}
|
||||
fnam = *features;
|
||||
} else {
|
||||
add = 1;
|
||||
if (*feature == '+')
|
||||
char *feature = *features;
|
||||
if (*feature == '-') {
|
||||
add = 0;
|
||||
feature++;
|
||||
}
|
||||
} else {
|
||||
add = 1;
|
||||
if (*feature == '+')
|
||||
feature++;
|
||||
}
|
||||
|
||||
if (!*feature || feature[1] != ':') {
|
||||
zwarnnam(cmdnam, "bad format for autoloadable feature: `%s'",
|
||||
feature);
|
||||
ret = 1;
|
||||
}
|
||||
fnam = feature + 2;
|
||||
switch (feature[0]) {
|
||||
case 'b':
|
||||
if (add ? add_autobin(cmdnam, fnam, module, opt_i) :
|
||||
del_autobin(cmdnam, fnam, opt_i));
|
||||
if (!*feature || feature[1] != ':') {
|
||||
zwarnnam(cmdnam, "bad format for autoloadable feature: `%s'",
|
||||
feature);
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
infix = (feature[0] == 'C');
|
||||
if (add ? add_autocond(cmdnam, fnam, infix, module, opt_i) :
|
||||
del_autocond(cmdnam, fnam, infix, opt_i))
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (add ? add_autoparam(cmdnam, fnam, module, opt_i) :
|
||||
del_autoparam(cmdnam, fnam, opt_i));
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (add ? add_automathfunc(cmdnam, fnam, module, opt_i) :
|
||||
del_automathfunc(cmdnam, fnam, opt_i))
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
zwarnnam(cmdnam, "bad autoloadable feature type: `%s'",
|
||||
feature);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
fnam = feature + 2;
|
||||
fchar = feature[0];
|
||||
}
|
||||
|
||||
features++;
|
||||
|
||||
switch (fchar) {
|
||||
case 'b':
|
||||
fn = add ? add_autobin : del_autobin;
|
||||
typnam = "builtin";
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
flags |= AUTOFEAT_INFIX;
|
||||
/* FALLTHROUGH */
|
||||
case 'c':
|
||||
fn = add ? add_autocond : del_autocond;
|
||||
typnam = "condition";
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
fn = add ? add_autoparam : del_autoparam;
|
||||
typnam = "parameter";
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fn = add ? add_automathfunc : del_automathfunc;
|
||||
typnam = "math function";
|
||||
break;
|
||||
|
||||
default:
|
||||
zwarnnam(cmdnam, "bad autoloadable feature type: `%c'",
|
||||
fchar);
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strchr(fnam, '/')) {
|
||||
zwarnnam(cmdnam, "%s: `/' is illegal in a %s", fnam, typnam);
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
subret = fn(module, fnam, flags);
|
||||
|
||||
if (subret != 0) {
|
||||
ret = 1;
|
||||
switch (subret) {
|
||||
case 1:
|
||||
zwarnnam(cmdnam, "failed to add %s `%s'", typnam, fnam);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
zwarnnam(cmdnam, "%s: no such %s", fnam, typnam);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
zwarnnam(cmdnam, "%s: %s is already defined", fnam, typnam);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* no (further) message needed */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -83,18 +83,34 @@
|
|||
zmodload -ub bogus
|
||||
0:Add/remove autoloaded builtin
|
||||
|
||||
zmodload -ub bogus
|
||||
1:Fail to remove unautoloaded builtin
|
||||
?(eval):zmodload:1: bogus: no such builtin
|
||||
|
||||
zmodload -ac bogus
|
||||
zmodload -uc bogus
|
||||
0:Add/remove autoloaded condition
|
||||
|
||||
zmodload -uc bogus
|
||||
1:Fail to remove unautoloaded condition
|
||||
?(eval):zmodload:1: bogus: no such condition
|
||||
|
||||
zmodload -ap bogus
|
||||
zmodload -up bogus
|
||||
0:Add/remove autoloaded parameter
|
||||
|
||||
zmodload -up bogus
|
||||
1:Fail to remove unautoloaded parameter
|
||||
?(eval):zmodload:1: bogus: no such parameter
|
||||
|
||||
zmodload -af bogus
|
||||
zmodload -uf bogus
|
||||
0:Add/remove autoloaded math function
|
||||
|
||||
zmodload -uf bogus
|
||||
1:Fail to remove unautoloaded math function
|
||||
?(eval):zmodload:1: bogus: no such math function
|
||||
|
||||
# If the "example" module is available, test various autoloading behavior.
|
||||
|
||||
if [[ $mods[(r)zsh/example] == zsh/example ]]; then
|
||||
|
|
Loading…
Reference in New Issue