summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-07-06 21:52:38 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-07-06 21:52:38 +0000
commit1b52f47cf285d5f3835bce7ad73f360bd327d4e8 (patch)
treeaf5f6637517084bc7914dacfc7fda0a5799f3220 /Src
parent018c9a2708808b83d5962786f759a931ab27511d (diff)
downloadzsh-1b52f47cf285d5f3835bce7ad73f360bd327d4e8.tar.gz
zsh-1b52f47cf285d5f3835bce7ad73f360bd327d4e8.zip
23665: autoloading of module features and related tweaks
Diffstat (limited to 'Src')
-rw-r--r--Src/Builtins/rlimits.c6
-rw-r--r--Src/Builtins/sched.c8
-rw-r--r--Src/Modules/cap.c6
-rw-r--r--Src/Modules/clone.c6
-rw-r--r--Src/Modules/datetime.c8
-rw-r--r--Src/Modules/example.c14
-rw-r--r--Src/Modules/files.c6
-rw-r--r--Src/Modules/langinfo.c19
-rw-r--r--Src/Modules/mapfile.c10
-rw-r--r--Src/Modules/mathfunc.c17
-rw-r--r--Src/Modules/parameter.c201
-rw-r--r--Src/Modules/pcre.c10
-rw-r--r--Src/Modules/regex.c6
-rw-r--r--Src/Modules/socket.c6
-rw-r--r--Src/Modules/stat.c6
-rw-r--r--Src/Modules/system.c12
-rw-r--r--Src/Modules/tcp.c6
-rw-r--r--Src/Modules/termcap.c24
-rw-r--r--Src/Modules/terminfo.c23
-rw-r--r--Src/Modules/zftp.c6
-rw-r--r--Src/Modules/zprof.c10
-rw-r--r--Src/Modules/zpty.c6
-rw-r--r--Src/Modules/zselect.c6
-rw-r--r--Src/Modules/zutil.c10
-rw-r--r--Src/Zle/compctl.c8
-rw-r--r--Src/Zle/complete.c14
-rw-r--r--Src/Zle/complist.c9
-rw-r--r--Src/Zle/computil.c14
-rw-r--r--Src/Zle/deltochar.c8
-rw-r--r--Src/Zle/zle_main.c13
-rw-r--r--Src/Zle/zleparameter.c14
-rw-r--r--Src/builtin.c2
-rw-r--r--Src/cond.c22
-rw-r--r--Src/exec.c53
-rw-r--r--Src/hashtable.c14
-rw-r--r--Src/init.c4
-rw-r--r--Src/jobs.c4
-rw-r--r--Src/mkbltnmlst.sh3
-rw-r--r--Src/module.c1239
-rw-r--r--Src/params.c16
-rw-r--r--Src/string.c2
-rw-r--r--Src/zsh.h47
42 files changed, 1169 insertions, 749 deletions
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c
index 8d55d022d..16ef276f2 100644
--- a/Src/Builtins/rlimits.c
+++ b/Src/Builtins/rlimits.c
@@ -908,7 +908,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -916,7 +916,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -930,7 +930,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
return 0;
}
diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c
index 21a2aad32..df4b9ecf9 100644
--- a/Src/Builtins/sched.c
+++ b/Src/Builtins/sched.c
@@ -381,8 +381,8 @@ static struct paramdef partab[] = {
static struct features module_features = {
bintab, sizeof(bintab)/sizeof(*bintab),
NULL, 0,
- partab, sizeof(partab)/sizeof(*partab),
NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};
@@ -397,7 +397,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -405,7 +405,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -430,7 +430,7 @@ cleanup_(Module m)
zfree(sch, sizeof(*sch));
}
delprepromptfn(&checksched);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/cap.c b/Src/Modules/cap.c
index 2886c42b4..9d41a4e90 100644
--- a/Src/Modules/cap.c
+++ b/Src/Modules/cap.c
@@ -141,7 +141,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -149,7 +149,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -163,7 +163,7 @@ boot_(UNUSED(Module m))
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c
index adab4cb59..6fdf534c0 100644
--- a/Src/Modules/clone.c
+++ b/Src/Modules/clone.c
@@ -128,7 +128,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -136,7 +136,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -150,7 +150,7 @@ boot_(UNUSED(Module m))
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index 06bf52046..169369d5f 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -161,8 +161,8 @@ static struct paramdef patab[] = {
static struct features module_features = {
bintab, sizeof(bintab)/sizeof(*bintab),
NULL, 0,
- patab, sizeof(patab)/sizeof(*patab),
NULL, 0,
+ patab, sizeof(patab)/sizeof(*patab),
0
};
@@ -177,7 +177,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -185,7 +185,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -199,7 +199,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/example.c b/Src/Modules/example.c
index 88e910814..fa86f260c 100644
--- a/Src/Modules/example.c
+++ b/Src/Modules/example.c
@@ -165,19 +165,19 @@ static struct builtin bintab[] = {
};
static struct conddef cotab[] = {
- CONDDEF("len", 0, cond_p_len, 1, 2, 0),
CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
+ CONDDEF("len", 0, cond_p_len, 1, 2, 0),
};
static struct paramdef patab[] = {
+ ARRPARAMDEF("exarr", &arrparam),
INTPARAMDEF("exint", &intparam),
STRPARAMDEF("exstr", &strparam),
- ARRPARAMDEF("exarr", &arrparam),
};
static struct mathfunc mftab[] = {
- NUMMATHFUNC("sum", math_sum, 1, -1, 0),
STRMATHFUNC("length", math_length, 0),
+ NUMMATHFUNC("sum", math_sum, 1, -1, 0),
};
static struct funcwrap wrapper[] = {
@@ -187,8 +187,8 @@ static struct funcwrap wrapper[] = {
static struct features module_features = {
bintab, sizeof(bintab)/sizeof(*bintab),
cotab, sizeof(cotab)/sizeof(*cotab),
- patab, sizeof(patab)/sizeof(*patab),
mftab, sizeof(mftab)/sizeof(*mftab),
+ patab, sizeof(patab)/sizeof(*patab),
0
};
@@ -205,7 +205,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -213,7 +213,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -234,7 +234,7 @@ int
cleanup_(Module m)
{
deletewrapper(m, wrapper);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index ba742cc50..0ce6d78d0 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -725,7 +725,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -733,7 +733,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -747,7 +747,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/langinfo.c b/Src/Modules/langinfo.c
index cfbdeed44..f10fdfef5 100644
--- a/Src/Modules/langinfo.c
+++ b/Src/Modules/langinfo.c
@@ -376,7 +376,7 @@ static nl_item nl_vals[] = {
};
static nl_item *
-liitem(char *name)
+liitem(const char *name)
{
char **element;
nl_item *nlcode;
@@ -393,16 +393,17 @@ liitem(char *name)
/**/
static HashNode
-getlanginfo(UNUSED(HashTable ht), char *name)
+getlanginfo(UNUSED(HashTable ht), const char *name)
{
int len, *elem;
- char *listr;
+ char *listr, *nameu;
Param pm = NULL;
- unmetafy(name, &len);
+ nameu = dupstring(name);
+ unmetafy(nameu, &len);
pm = (Param) hcalloc(sizeof(struct param));
- pm->node.nam = dupstring(name);
+ pm->node.nam = nameu;
pm->node.flags = PM_READONLY | PM_SCALAR;
pm->gsu.s = &nullsetscalar_gsu;
@@ -456,12 +457,12 @@ static struct paramdef partab[] = {
static struct features module_features = {
NULL, 0,
NULL, 0,
+ NULL, 0,
#ifdef HAVE_NL_LANGINFO
partab, sizeof(partab)/sizeof(*partab),
#else
NULL, 0,
#endif
- NULL, 0,
0
};
@@ -476,7 +477,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -484,7 +485,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -498,7 +499,7 @@ boot_(UNUSED(Module m))
int
cleanup_(UNUSED(Module m))
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index fb46df885..d825c7faa 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -213,7 +213,7 @@ static struct paramdef partab[] = {
/**/
static HashNode
-getpmmapfile(UNUSED(HashTable ht), char *name)
+getpmmapfile(UNUSED(HashTable ht), const char *name)
{
char *contents;
Param pm = NULL;
@@ -268,8 +268,8 @@ scanpmmapfile(UNUSED(HashTable ht), ScanFunc func, int flags)
static struct features module_features = {
NULL, 0,
NULL, 0,
- partab, sizeof(partab)/sizeof(*partab),
NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};
@@ -284,7 +284,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -292,7 +292,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -306,7 +306,7 @@ boot_(UNUSED(Module m))
int
cleanup_(UNUSED(Module m))
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c
index a473476e3..04483b555 100644
--- a/Src/Modules/mathfunc.c
+++ b/Src/Modules/mathfunc.c
@@ -125,12 +125,6 @@ enum {
static struct mathfunc mftab[] = {
- /* Functions taking string arguments */
-#ifdef HAVE_ERAND48
- /* here to avoid comma hassle */
- STRMATHFUNC("rand48", math_string, MS_RAND48),
-#endif
-
NUMMATHFUNC("abs", math_func, 1, 1, MF_ABS | BFLAG(BF_FRAC) |
TFLAG(TF_NOCONV|TF_NOASS)),
NUMMATHFUNC("acos", math_func, 1, 1, MF_ACOS | BFLAG(BF_FRAC)),
@@ -167,6 +161,9 @@ static struct mathfunc mftab[] = {
NUMMATHFUNC("log1p", math_func, 1, 1, MF_LOG1P | BFLAG(BF_GTRM1)),
NUMMATHFUNC("logb", math_func, 1, 1, MF_LOGB | BFLAG(BF_NONZ)),
NUMMATHFUNC("nextafter", math_func, 2, 2, MF_NEXTAFTER),
+#ifdef HAVE_ERAND48
+ STRMATHFUNC("rand48", math_string, MS_RAND48),
+#endif
NUMMATHFUNC("rint", math_func, 1, 1, MF_RINT),
NUMMATHFUNC("scalb", math_func, 2, 2, MF_SCALB | TFLAG(TF_INT2)),
#ifdef HAVE_SIGNGAM
@@ -564,8 +561,8 @@ math_string(UNUSED(char *name), char *arg, int id)
static struct features module_features = {
NULL, 0,
NULL, 0,
- NULL, 0,
mftab, sizeof(mftab)/sizeof(*mftab),
+ NULL, 0,
0
};
@@ -580,7 +577,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -588,7 +585,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -602,7 +599,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 9112e64f1..3c7264a09 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -93,7 +93,7 @@ paramtypestr(Param pm)
/**/
static HashNode
-getpmparameter(UNUSED(HashTable ht), char *name)
+getpmparameter(UNUSED(HashTable ht), const char *name)
{
Param rpm, pm = NULL;
@@ -199,7 +199,7 @@ static const struct gsu_scalar pmcommand_gsu =
/**/
static HashNode
-getpmcommand(UNUSED(HashTable ht), char *name)
+getpmcommand(UNUSED(HashTable ht), const char *name)
{
Cmdnam cmd;
Param pm = NULL;
@@ -372,7 +372,7 @@ static const struct gsu_scalar pmdisfunction_gsu =
/**/
static HashNode
-getfunction(UNUSED(HashTable ht), char *name, int dis)
+getfunction(UNUSED(HashTable ht), const char *name, int dis)
{
Shfunc shf;
Param pm = NULL;
@@ -416,14 +416,14 @@ getfunction(UNUSED(HashTable ht), char *name, int dis)
/**/
static HashNode
-getpmfunction(HashTable ht, char *name)
+getpmfunction(HashTable ht, const char *name)
{
return getfunction(ht, name, 0);
}
/**/
static HashNode
-getpmdisfunction(HashTable ht, char *name)
+getpmdisfunction(HashTable ht, const char *name)
{
return getfunction(ht, name, DISABLED);
}
@@ -542,7 +542,7 @@ functracegetfn(UNUSED(Param pm))
/**/
static HashNode
-getbuiltin(UNUSED(HashTable ht), char *name, int dis)
+getbuiltin(UNUSED(HashTable ht), const char *name, int dis)
{
Param pm = NULL;
Builtin bn;
@@ -566,14 +566,14 @@ getbuiltin(UNUSED(HashTable ht), char *name, int dis)
/**/
static HashNode
-getpmbuiltin(HashTable ht, char *name)
+getpmbuiltin(HashTable ht, const char *name)
{
return getbuiltin(ht, name, 0);
}
/**/
static HashNode
-getpmdisbuiltin(HashTable ht, char *name)
+getpmdisbuiltin(HashTable ht, const char *name)
{
return getbuiltin(ht, name, DISABLED);
}
@@ -721,7 +721,7 @@ static const struct gsu_scalar pmoption_gsu =
/**/
static HashNode
-getpmoption(UNUSED(HashTable ht), char *name)
+getpmoption(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
int n;
@@ -771,69 +771,29 @@ scanpmoptions(UNUSED(HashTable ht), ScanFunc func, int flags)
/* Functions for the modules special parameter. */
-static char *modpmname;
-static int modpmfound;
-
-/**/
-static void
-modpmbuiltinscan(HashNode hn, UNUSED(int dummy))
-{
- if (!(((Builtin) hn)->node.flags & BINF_ADDED) &&
- !strcmp(((Builtin) hn)->optstr, modpmname))
- modpmfound = 1;
-}
-
-/**/
-static void
-modpmparamscan(HashNode hn, UNUSED(int dummy))
-{
- if ((((Param) hn)->node.flags & PM_AUTOLOAD) &&
- !strcmp(((Param) hn)->u.str, modpmname))
- modpmfound = 1;
-}
-
/**/
static HashNode
-getpmmodule(UNUSED(HashTable ht), char *name)
+getpmmodule(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
char *type = NULL;
- LinkNode node;
+ Module m;
pm = (Param) hcalloc(sizeof(struct param));
pm->node.nam = dupstring(name);
pm->node.flags = PM_SCALAR | PM_READONLY;
pm->gsu.s = &nullsetscalar_gsu;
- if (!type) {
- Module m;
-
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (m->u.handle && !(m->flags & MOD_UNLOAD) &&
- !strcmp(name, m->nam)) {
- type = ((m->flags & MOD_ALIAS) ?
- dyncat("alias:", m->u.alias) : "loaded");
- break;
- }
- }
+ m = (Module)modulestab->getnode2(modulestab, name);
+
+ if (!m)
+ return NULL;
+ if (m->u.handle && !(m->node.flags & MOD_UNLOAD)) {
+ type = ((m->node.flags & MOD_ALIAS) ?
+ dyncat("alias:", m->u.alias) : "loaded");
}
- modpmname = name;
- modpmfound = 0;
if (!type) {
- scanhashtable(builtintab, 0, 0, 0, modpmbuiltinscan, 0);
- if (!modpmfound) {
- Conddef p;
-
- for (p = condtab; p; p = p->next)
- if (p->module && !strcmp(name, p->module)) {
- modpmfound = 1;
- break;
- }
- if (!modpmfound)
- scanhashtable(realparamtab, 0, 0, 0, modpmparamscan, 0);
- }
- if (modpmfound)
+ if (m->autoloads && firstnode(m->autoloads))
type = "autoloaded";
}
if (type)
@@ -853,7 +813,6 @@ scanpmmodules(UNUSED(HashTable ht), ScanFunc func, int flags)
int i;
HashNode hn;
LinkList done = newlinklist();
- LinkNode node;
Module m;
Conddef p;
char *loaded = dupstring("loaded");
@@ -862,14 +821,16 @@ scanpmmodules(UNUSED(HashTable ht), ScanFunc func, int flags)
pm.node.flags = PM_SCALAR | PM_READONLY;
pm.gsu.s = &nullsetscalar_gsu;
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
- pm.node.nam = m->nam;
- pm.u.str = ((m->flags & MOD_ALIAS) ?
- dyncat("alias:", m->u.alias) : loaded);
- addlinknode(done, pm.node.nam);
- func(&pm.node, flags);
+ for (i = 0; i < modulestab->hsize; i++) {
+ for (hn = modulestab->nodes[i]; hn; hn = hn->next) {
+ m = (Module) hn;
+ if (m->u.handle && !(m->node.flags & MOD_UNLOAD)) {
+ pm.node.nam = m->node.nam;
+ pm.u.str = ((m->node.flags & MOD_ALIAS) ?
+ dyncat("alias:", m->u.alias) : loaded);
+ addlinknode(done, pm.node.nam);
+ func(&pm.node, flags);
+ }
}
}
pm.u.str = dupstring("autoloaded");
@@ -928,11 +889,11 @@ dirsgetfn(UNUSED(Param pm))
/**/
static HashNode
-getpmhistory(UNUSED(HashTable ht), char *name)
+getpmhistory(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
Histent he;
- char *p;
+ const char *p;
int ok = 1;
pm = (Param) hcalloc(sizeof(struct param));
@@ -1042,7 +1003,7 @@ pmjobtext(int job)
/**/
static HashNode
-getpmjobtext(UNUSED(HashTable ht), char *name)
+getpmjobtext(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
int job;
@@ -1139,7 +1100,7 @@ pmjobstate(int job)
/**/
static HashNode
-getpmjobstate(UNUSED(HashTable ht), char *name)
+getpmjobstate(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
int job;
@@ -1201,7 +1162,7 @@ pmjobdir(int job)
/**/
static HashNode
-getpmjobdir(UNUSED(HashTable ht), char *name)
+getpmjobdir(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
int job;
@@ -1329,7 +1290,7 @@ static const struct gsu_scalar pmnamedir_gsu =
/**/
static HashNode
-getpmnameddir(UNUSED(HashTable ht), char *name)
+getpmnameddir(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
Nameddir nd;
@@ -1378,7 +1339,7 @@ scanpmnameddirs(UNUSED(HashTable ht), ScanFunc func, int flags)
/**/
static HashNode
-getpmuserdir(UNUSED(HashTable ht), char *name)
+getpmuserdir(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
Nameddir nd;
@@ -1631,7 +1592,7 @@ assignaliasdefs(Param pm, int flags)
/**/
static HashNode
-getalias(HashTable alht, UNUSED(HashTable ht), char *name, int flags)
+getalias(HashTable alht, UNUSED(HashTable ht), const char *name, int flags)
{
Param pm = NULL;
Alias al;
@@ -1653,45 +1614,45 @@ getalias(HashTable alht, UNUSED(HashTable ht), char *name, int flags)
/**/
static HashNode
-getpmralias(HashTable ht, char *name)
+getpmralias(HashTable ht, const char *name)
{
return getalias(aliastab, ht, name, 0);
}
/**/
static HashNode
-getpmdisralias(HashTable ht, char *name)
+getpmdisralias(HashTable ht, const char *name)
{
return getalias(aliastab, ht, name, DISABLED);
}
/**/
static HashNode
-getpmgalias(HashTable ht, char *name)
+getpmgalias(HashTable ht, const char *name)
{
return getalias(aliastab, ht, name, ALIAS_GLOBAL);
}
/**/
static HashNode
-getpmdisgalias(HashTable ht, char *name)
+getpmdisgalias(HashTable ht, const char *name)
{
return getalias(aliastab, ht, name, ALIAS_GLOBAL|DISABLED);
}
/**/
static HashNode
-getpmsalias(HashTable ht, char *name)
+getpmsalias(HashTable ht, const char *name)
{
return getalias(sufaliastab, ht, name, ALIAS_SUFFIX);
}
/**/
static HashNode
-getpmdissalias(HashTable ht, char *name)
+getpmdissalias(HashTable ht, const char *name)
{
return getalias(sufaliastab, ht, name, ALIAS_SUFFIX|DISABLED);
-}
+}
/**/
static void
@@ -1809,63 +1770,63 @@ static const struct gsu_array historywords_gsu =
{ histwgetfn, arrsetfn, stdunsetfn };
static struct paramdef partab[] = {
- SPECIALPMDEF("parameters", PM_READONLY,
- NULL, getpmparameter, scanpmparameters),
+ SPECIALPMDEF("aliases", 0,
+ &pmraliases_gsu, getpmralias, scanpmraliases),
+ SPECIALPMDEF("builtins", PM_READONLY, NULL, getpmbuiltin, scanpmbuiltins),
SPECIALPMDEF("commands", 0, &pmcommands_gsu, getpmcommand, scanpmcommands),
- SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
- scanpmfunctions),
+ SPECIALPMDEF("dirstack", PM_ARRAY,
+ &dirs_gsu, NULL, NULL),
+ SPECIALPMDEF("dis_aliases", 0,
+ &pmdisraliases_gsu, getpmdisralias, scanpmdisraliases),
+ SPECIALPMDEF("dis_builtins", PM_READONLY,
+ NULL, getpmdisbuiltin, scanpmdisbuiltins),
SPECIALPMDEF("dis_functions", 0,
&pmdisfunctions_gsu, getpmdisfunction, scanpmdisfunctions),
+ SPECIALPMDEF("dis_galiases", 0,
+ &pmdisgaliases_gsu, getpmdisgalias, scanpmdisgaliases),
+ SPECIALPMDEF("dis_reswords", PM_ARRAY|PM_READONLY,
+ &disreswords_gsu, NULL, NULL),
+ SPECIALPMDEF("dis_saliases", 0,
+ &pmdissaliases_gsu, getpmdissalias, scanpmdissaliases),
SPECIALPMDEF("funcstack", PM_ARRAY|PM_READONLY,
&funcstack_gsu, NULL, NULL),
+ SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction,
+ scanpmfunctions),
SPECIALPMDEF("functrace", PM_ARRAY|PM_READONLY,
&functrace_gsu, NULL, NULL),
- SPECIALPMDEF("builtins", PM_READONLY, NULL, getpmbuiltin, scanpmbuiltins),
- SPECIALPMDEF("dis_builtins", PM_READONLY,
- NULL, getpmdisbuiltin, scanpmdisbuiltins),
- SPECIALPMDEF("reswords", PM_ARRAY|PM_READONLY,
- &reswords_gsu, NULL, NULL),
- SPECIALPMDEF("dis_reswords", PM_ARRAY|PM_READONLY,
- &disreswords_gsu, NULL, NULL),
- SPECIALPMDEF("options", 0,
- &pmoptions_gsu, getpmoption, scanpmoptions),
- SPECIALPMDEF("modules", PM_READONLY,
- NULL, getpmmodule, scanpmmodules),
- SPECIALPMDEF("dirstack", PM_ARRAY,
- &dirs_gsu, NULL, NULL),
+ SPECIALPMDEF("galiases", 0,
+ &pmgaliases_gsu, getpmgalias, scanpmgaliases),
SPECIALPMDEF("history", PM_READONLY,
NULL, getpmhistory, scanpmhistory),
SPECIALPMDEF("historywords", PM_ARRAY|PM_READONLY,
&historywords_gsu, NULL, NULL),
- SPECIALPMDEF("jobtexts", PM_READONLY,
- NULL, getpmjobtext, scanpmjobtexts),
- SPECIALPMDEF("jobstates", PM_READONLY,
- NULL, getpmjobstate, scanpmjobstates),
SPECIALPMDEF("jobdirs", PM_READONLY,
NULL, getpmjobdir, scanpmjobdirs),
+ SPECIALPMDEF("jobstates", PM_READONLY,
+ NULL, getpmjobstate, scanpmjobstates),
+ SPECIALPMDEF("jobtexts", PM_READONLY,
+ NULL, getpmjobtext, scanpmjobtexts),
+ SPECIALPMDEF("modules", PM_READONLY,
+ NULL, getpmmodule, scanpmmodules),
SPECIALPMDEF("nameddirs", 0,
&pmnameddirs_gsu, getpmnameddir, scanpmnameddirs),
- SPECIALPMDEF("userdirs", PM_READONLY,
- NULL, getpmuserdir, scanpmuserdirs),
- SPECIALPMDEF("aliases", 0,
- &pmraliases_gsu, getpmralias, scanpmraliases),
- SPECIALPMDEF("galiases", 0,
- &pmgaliases_gsu, getpmgalias, scanpmgaliases),
+ SPECIALPMDEF("options", 0,
+ &pmoptions_gsu, getpmoption, scanpmoptions),
+ SPECIALPMDEF("parameters", PM_READONLY,
+ NULL, getpmparameter, scanpmparameters),
+ SPECIALPMDEF("reswords", PM_ARRAY|PM_READONLY,
+ &reswords_gsu, NULL, NULL),
SPECIALPMDEF("saliases", 0,
&pmsaliases_gsu, getpmsalias, scanpmsaliases),
- SPECIALPMDEF("dis_aliases", 0,
- &pmdisraliases_gsu, getpmdisralias, scanpmdisraliases),
- SPECIALPMDEF("dis_galiases", 0,
- &pmdisgaliases_gsu, getpmdisgalias, scanpmdisgaliases),
- SPECIALPMDEF("dis_saliases", 0,
- &pmdissaliases_gsu, getpmdissalias, scanpmdissaliases)
+ SPECIALPMDEF("userdirs", PM_READONLY,
+ NULL, getpmuserdir, scanpmuserdirs)
};
static struct features module_features = {
NULL, 0,
NULL, 0,
- partab, sizeof(partab)/sizeof(*partab),
NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};
@@ -1880,7 +1841,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -1894,7 +1855,7 @@ enables_(Module m, int **enables)
* on the main shell, so set the flag to indicate.
*/
incleanup = 1;
- ret = handlefeatures(m->nam, &module_features, enables);
+ ret = handlefeatures(m, &module_features, enables);
incleanup = 0;
return ret;
}
@@ -1912,7 +1873,7 @@ cleanup_(Module m)
{
int ret;
incleanup = 1;
- ret = setfeatureenables(m->nam, &module_features, NULL);
+ ret = setfeatureenables(m, &module_features, NULL);
incleanup = 0;
return ret;
}
diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c
index 45c38eba0..4f8daff80 100644
--- a/Src/Modules/pcre.c
+++ b/Src/Modules/pcre.c
@@ -290,8 +290,8 @@ static struct conddef cotab[] = {
static struct builtin bintab[] = {
BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimx", NULL),
- BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL),
- BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "a:v:", NULL)
+ BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "a:v:", NULL),
+ BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL)
};
@@ -319,7 +319,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -327,7 +327,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -341,7 +341,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/regex.c b/Src/Modules/regex.c
index a3d956055..00ed46b3b 100644
--- a/Src/Modules/regex.c
+++ b/Src/Modules/regex.c
@@ -152,7 +152,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -160,7 +160,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -174,7 +174,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/socket.c b/Src/Modules/socket.c
index 413625dcf..469568a11 100644
--- a/Src/Modules/socket.c
+++ b/Src/Modules/socket.c
@@ -276,7 +276,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -284,7 +284,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -298,7 +298,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 1d55317ea..a3e95bb59 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -643,7 +643,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -651,7 +651,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -665,7 +665,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index f8a188d42..4af464db0 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -365,7 +365,7 @@ static const struct gsu_array errnos_gsu =
/**/
static void
-fillpmsysparams(Param pm, char *name)
+fillpmsysparams(Param pm, const char *name)
{
char buf[DIGBUFSIZE];
int num;
@@ -390,7 +390,7 @@ fillpmsysparams(Param pm, char *name)
/**/
static HashNode
-getpmsysparams(UNUSED(HashTable ht), char *name)
+getpmsysparams(UNUSED(HashTable ht), const char *name)
{
Param pm;
@@ -423,8 +423,8 @@ static struct paramdef partab[] = {
static struct features module_features = {
bintab, sizeof(bintab)/sizeof(*bintab),
NULL, 0,
- partab, sizeof(partab)/sizeof(*partab),
NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};
@@ -441,7 +441,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -449,7 +449,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -464,7 +464,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c
index 1bf9b3776..d1d4e5002 100644
--- a/Src/Modules/tcp.c
+++ b/Src/Modules/tcp.c
@@ -696,7 +696,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -704,7 +704,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -722,7 +722,7 @@ cleanup_(Module m)
{
tcp_cleanup();
freelinklist(ztcp_sessions, (FreeFunc) ztcp_free_session);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c
index c19db4892..351324a68 100644
--- a/Src/Modules/termcap.c
+++ b/Src/Modules/termcap.c
@@ -164,10 +164,10 @@ static struct builtin bintab[] = {
/**/
static HashNode
-gettermcap(UNUSED(HashTable ht), char *name)
+gettermcap(UNUSED(HashTable ht), const char *name)
{
int len, num;
- char *tcstr, buf[2048], *u;
+ char *tcstr, buf[2048], *u, *nameu;
Param pm = NULL;
/* This depends on the termcap stuff in init.c */
@@ -176,16 +176,18 @@ gettermcap(UNUSED(HashTable ht), char *name)
if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term()))
return NULL;
- unmetafy(name, &len);
+
+ nameu = dupstring(name);
+ unmetafy(nameu, &len);
pm = (Param) hcalloc(sizeof(struct param));
- pm->node.nam = dupstring(name);
+ pm->node.nam = nameu;
pm->node.flags = PM_READONLY;
u = buf;
/* logic in the following cascade copied from echotc, above */
- if ((num = tgetnum(name)) != -1) {
+ if ((num = tgetnum(nameu)) != -1) {
pm->gsu.i = &nullsetinteger_gsu;
pm->u.val = num;
pm->node.flags |= PM_INTEGER;
@@ -193,7 +195,7 @@ gettermcap(UNUSED(HashTable ht), char *name)
}
pm->gsu.s = &nullsetscalar_gsu;
- switch (ztgetflag(name)) {
+ switch (ztgetflag(nameu)) {
case -1:
break;
case 0:
@@ -205,7 +207,7 @@ gettermcap(UNUSED(HashTable ht), char *name)
pm->node.flags |= PM_SCALAR;
return &pm->node;
}
- if ((tcstr = tgetstr(name, &u)) != NULL && tcstr != (char *)-1) {
+ if ((tcstr = tgetstr(nameu, &u)) != NULL && tcstr != (char *)-1) {
pm->u.str = dupstring(tcstr);
pm->node.flags |= PM_SCALAR;
} else {
@@ -324,12 +326,12 @@ static struct features module_features = {
NULL, 0,
#endif
NULL, 0,
+ NULL, 0,
#ifdef HAVE_TGETENT
partab, sizeof(partab)/sizeof(*partab),
#else
NULL, 0,
#endif
- NULL, 0,
0
};
@@ -344,7 +346,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -352,7 +354,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -371,7 +373,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c
index d324c3a6c..63cbd2abc 100644
--- a/Src/Modules/terminfo.c
+++ b/Src/Modules/terminfo.c
@@ -129,10 +129,10 @@ static struct builtin bintab[] = {
/**/
static HashNode
-getterminfo(UNUSED(HashTable ht), char *name)
+getterminfo(UNUSED(HashTable ht), const char *name)
{
int len, num;
- char *tistr;
+ char *tistr, *nameu;
Param pm = NULL;
/* This depends on the termcap stuff in init.c */
@@ -141,21 +141,22 @@ getterminfo(UNUSED(HashTable ht), char *name)
if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term()))
return NULL;
- unmetafy(name, &len);
+ nameu = dupstring(name);
+ unmetafy(nameu, &len);
pm = (Param) hcalloc(sizeof(struct param));
- pm->node.nam = dupstring(name);
+ pm->node.nam = nameu;
pm->node.flags = PM_READONLY;
- if (((num = tigetnum(name)) != -1) && (num != -2)) {
+ if (((num = tigetnum(nameu)) != -1) && (num != -2)) {
pm->u.val = num;
pm->node.flags |= PM_INTEGER;
pm->gsu.i = &nullsetinteger_gsu;
- } else if ((num = tigetflag(name)) != -1) {
+ } else if ((num = tigetflag(nameu)) != -1) {
pm->u.str = num ? dupstring("yes") : dupstring("no");
pm->node.flags |= PM_SCALAR;
pm->gsu.s = &nullsetscalar_gsu;
- } else if ((tistr = (char *)tigetstr(name)) != NULL && tistr != (char *)-1) {
+ } else if ((tistr = (char *)tigetstr(nameu)) != NULL && tistr != (char *)-1) {
pm->u.str = dupstring(tistr);
pm->node.flags |= PM_SCALAR;
pm->gsu.s = &nullsetscalar_gsu;
@@ -298,12 +299,12 @@ static struct features module_features = {
NULL, 0,
#endif
NULL, 0,
+ NULL, 0,
#ifdef USE_TERMINFO_MODULE
partab, sizeof(partab)/sizeof(*partab),
#else
NULL, 0,
#endif
- NULL, 0,
0
};
@@ -318,7 +319,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -326,7 +327,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -349,7 +350,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 5c8822cc5..af48e80aa 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -3181,7 +3181,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -3189,7 +3189,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -3221,7 +3221,7 @@ cleanup_(Module m)
{
deletehookfunc("exit", zftpexithook);
zftp_cleanup();
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/zprof.c b/Src/Modules/zprof.c
index b30e44432..bc97771c0 100644
--- a/Src/Modules/zprof.c
+++ b/Src/Modules/zprof.c
@@ -225,7 +225,7 @@ zprof_wrapper(Eprog prog, FuncWrap w, char *name)
struct timezone dummy;
double prev = 0, now;
- if (zprof_module && !(zprof_module->flags & MOD_UNLOAD)) {
+ if (zprof_module && !(zprof_module->node.flags & MOD_UNLOAD)) {
active = 1;
if (!(f = findpfunc(name))) {
f = (Pfunc) zalloc(sizeof(*f));
@@ -260,7 +260,7 @@ zprof_wrapper(Eprog prog, FuncWrap w, char *name)
}
runshfunc(prog, w, name);
if (active) {
- if (zprof_module && !(zprof_module->flags & MOD_UNLOAD)) {
+ if (zprof_module && !(zprof_module->node.flags & MOD_UNLOAD)) {
tv.tv_sec = tv.tv_usec = 0;
gettimeofday(&tv, &dummy);
@@ -315,7 +315,7 @@ setup_(Module m)
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -323,7 +323,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -345,7 +345,7 @@ cleanup_(Module m)
freepfuncs(calls);
freeparcs(arcs);
deletewrapper(m, wrapper);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 3280b8175..7e140102e 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -750,7 +750,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -758,7 +758,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -777,7 +777,7 @@ cleanup_(Module m)
{
deletehookfunc("exit", ptyhook);
deleteallptycmds();
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/zselect.c b/Src/Modules/zselect.c
index 3e71fa3bd..c02074646 100644
--- a/Src/Modules/zselect.c
+++ b/Src/Modules/zselect.c
@@ -294,7 +294,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -302,7 +302,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -317,7 +317,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 127509b01..76056308f 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1801,10 +1801,10 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
static struct builtin bintab[] = {
- BUILTIN("zstyle", 0, bin_zstyle, 0, -1, 0, NULL, NULL),
BUILTIN("zformat", 0, bin_zformat, 3, -1, 0, NULL, NULL),
- BUILTIN("zregexparse", 0, bin_zregexparse, 3, -1, 0, "c", NULL),
BUILTIN("zparseopts", 0, bin_zparseopts, 1, -1, 0, NULL, NULL),
+ BUILTIN("zregexparse", 0, bin_zregexparse, 3, -1, 0, "c", NULL),
+ BUILTIN("zstyle", 0, bin_zstyle, 0, -1, 0, NULL, NULL),
};
static struct features module_features = {
@@ -1828,7 +1828,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -1836,7 +1836,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -1850,7 +1850,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index bafbb2f68..143c93682 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -3938,8 +3938,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
static struct builtin bintab[] = {
- BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
BUILTIN("compcall", 0, bin_compcall, 0, 0, 0, "TD", NULL),
+ BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
};
static struct features module_features = {
@@ -3974,7 +3974,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -3982,7 +3982,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -4000,7 +4000,7 @@ cleanup_(Module m)
{
deletehookfunc("compctl_make", (Hookfn) ccmakehookfn);
deletehookfunc("compctl_cleanup", (Hookfn) cccleanuphookfn);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index a2af30c65..36c4c8a3d 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -1445,10 +1445,10 @@ static struct builtin bintab[] = {
};
static struct conddef cotab[] = {
+ CONDDEF("after", 0, cond_range, 1, 1, 0),
+ CONDDEF("between", 0, cond_range, 2, 2, 1),
CONDDEF("prefix", 0, cond_psfix, 1, 2, CVT_PREPAT),
CONDDEF("suffix", 0, cond_psfix, 1, 2, CVT_SUFPAT),
- CONDDEF("between", 0, cond_range, 2, 2, 1),
- CONDDEF("after", 0, cond_range, 1, 1, 0),
};
static struct funcwrap wrapper[] = {
@@ -1502,7 +1502,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -1510,7 +1510,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -1524,7 +1524,7 @@ boot_(Module m)
addhookfunc("reverse_menu", (Hookfn) reverse_menu);
addhookfunc("list_matches", (Hookfn) list_matches);
addhookfunc("invalidate_list", (Hookfn) invalidate_list);
- (void)addhookdefs(m->nam, comphooks, sizeof(comphooks)/sizeof(*comphooks));
+ (void)addhookdefs(m, comphooks, sizeof(comphooks)/sizeof(*comphooks));
return addwrapper(m, wrapper);
}
@@ -1539,10 +1539,10 @@ cleanup_(Module m)
deletehookfunc("reverse_menu", (Hookfn) reverse_menu);
deletehookfunc("list_matches", (Hookfn) list_matches);
deletehookfunc("invalidate_list", (Hookfn) invalidate_list);
- (void)deletehookdefs(m->nam, comphooks,
+ (void)deletehookdefs(m, comphooks,
sizeof(comphooks)/sizeof(*comphooks));
deletewrapper(m, wrapper);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 787b7b25c..64d7e50ce 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -3238,7 +3238,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -3246,7 +3246,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -3261,7 +3261,8 @@ boot_(Module m)
w_menuselect = addzlefunction("menu-select", menuselect,
ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP);
if (!w_menuselect) {
- zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'");
+ zwarnnam(m->node.nam,
+ "name clash when adding ZLE function `menu-select'");
return -1;
}
addhookfunc("comp_list_matches", (Hookfn) complistmatches);
@@ -3302,7 +3303,7 @@ cleanup_(Module m)
deletehookfunc("menu_start", (Hookfn) domenuselect);
unlinkkeymap("menuselect", 1);
unlinkkeymap("listscroll", 1);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index b9df1e418..9ba38101a 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -4544,14 +4544,14 @@ bin_compgroups(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
static struct builtin bintab[] = {
- BUILTIN("compdescribe", 0, bin_compdescribe, 3, -1, 0, NULL, NULL),
BUILTIN("comparguments", 0, bin_comparguments, 1, -1, 0, NULL, NULL),
- BUILTIN("compvalues", 0, bin_compvalues, 1, -1, 0, NULL, NULL),
+ BUILTIN("compdescribe", 0, bin_compdescribe, 3, -1, 0, NULL, NULL),
+ BUILTIN("compfiles", 0, bin_compfiles, 1, -1, 0, NULL, NULL),
+ BUILTIN("compgroups", 0, bin_compgroups, 1, -1, 0, NULL, NULL),
BUILTIN("compquote", 0, bin_compquote, 1, -1, 0, "p", NULL),
BUILTIN("comptags", 0, bin_comptags, 1, -1, 0, NULL, NULL),
BUILTIN("comptry", 0, bin_comptry, 0, -1, 0, NULL, NULL),
- BUILTIN("compfiles", 0, bin_compfiles, 1, -1, 0, NULL, NULL),
- BUILTIN("compgroups", 0, bin_compgroups, 1, -1, 0, NULL, NULL),
+ BUILTIN("compvalues", 0, bin_compvalues, 1, -1, 0, NULL, NULL)
};
static struct features module_features = {
@@ -4581,7 +4581,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -4589,7 +4589,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -4603,7 +4603,7 @@ boot_(Module m)
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/deltochar.c b/Src/Zle/deltochar.c
index 0c64cf18d..d56798687 100644
--- a/Src/Zle/deltochar.c
+++ b/Src/Zle/deltochar.c
@@ -95,7 +95,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -103,7 +103,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -119,7 +119,7 @@ boot_(Module m)
return 0;
deletezlefunction(w_deletetochar);
}
- zwarnnam(m->nam, "deltochar: name clash when adding ZLE functions");
+ zwarnnam(m->node.nam, "deltochar: name clash when adding ZLE functions");
return -1;
}
@@ -129,7 +129,7 @@ cleanup_(Module m)
{
deletezlefunction(w_deletetochar);
deletezlefunction(w_zaptochar);
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index d2a665188..463ff157f 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1827,7 +1827,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -1835,7 +1835,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -1844,7 +1844,7 @@ boot_(Module m)
{
addhookfunc("before_trap", (Hookfn) zlebeforetrap);
addhookfunc("after_trap", (Hookfn) zleaftertrap);
- (void)addhookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
+ (void)addhookdefs(m, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
return 0;
}
@@ -1853,13 +1853,14 @@ int
cleanup_(Module m)
{
if(zleactive) {
- zerrnam(m->nam, "can't unload the zle module while zle is active");
+ zerrnam(m->node.nam,
+ "can't unload the zle module while zle is active");
return 1;
}
deletehookfunc("before_trap", (Hookfn) zlebeforetrap);
deletehookfunc("after_trap", (Hookfn) zleaftertrap);
- (void)deletehookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
- return setfeatureenables(m->nam, &module_features, NULL);
+ (void)deletehookdefs(m, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/Zle/zleparameter.c b/Src/Zle/zleparameter.c
index 1b84fdff7..ab988d6df 100644
--- a/Src/Zle/zleparameter.c
+++ b/Src/Zle/zleparameter.c
@@ -56,7 +56,7 @@ widgetstr(Widget w)
/**/
static HashNode
-getpmwidgets(UNUSED(HashTable ht), char *name)
+getpmwidgets(UNUSED(HashTable ht), const char *name)
{
Param pm = NULL;
Thingy th;
@@ -129,16 +129,16 @@ static const struct gsu_array keymaps_gsu =
{ keymapsgetfn, arrsetfn, stdunsetfn };
static struct paramdef partab[] = {
- SPECIALPMDEF("widgets", PM_READONLY,
- &zlestdhash_gsu, getpmwidgets, scanpmwidgets),
SPECIALPMDEF("keymaps", PM_ARRAY|PM_READONLY, &keymaps_gsu, NULL, NULL),
+ SPECIALPMDEF("widgets", PM_READONLY,
+ &zlestdhash_gsu, getpmwidgets, scanpmwidgets)
};
static struct features module_features = {
NULL, 0,
NULL, 0,
- partab, sizeof(partab)/sizeof(*partab),
NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};
@@ -153,7 +153,7 @@ setup_(UNUSED(Module m))
int
features_(Module m, char ***features)
{
- *features = featuresarray(m->nam, &module_features);
+ *features = featuresarray(m, &module_features);
return 0;
}
@@ -161,7 +161,7 @@ features_(Module m, char ***features)
int
enables_(Module m, int **enables)
{
- return handlefeatures(m->nam, &module_features, enables);
+ return handlefeatures(m, &module_features, enables);
}
/**/
@@ -175,7 +175,7 @@ boot_(UNUSED(Module m))
int
cleanup_(Module m)
{
- return setfeatureenables(m->nam, &module_features, NULL);
+ return setfeatureenables(m, &module_features, NULL);
}
/**/
diff --git a/Src/builtin.c b/Src/builtin.c
index 20bc37c21..7420ed887 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -250,7 +250,7 @@ execbuiltin(LinkList args, Builtin bn)
name = (char *) ugetnode(args);
if (!bn->handlerfunc) {
- zwarnnam(name, "autoload failed");
+ DPUTS(1, "Missing builtin detected too late");
deletebuiltin(bn->node.nam);
return 1;
}
diff --git a/Src/cond.c b/Src/cond.c
index 4356e5d66..e455882bb 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -96,11 +96,7 @@ evalcond(Estate state, char *fromtest)
{
char *modname = isset(REMATCHPCRE) ? "zsh/pcre" : "zsh/regex";
sprintf(overridename = overridebuf, "-%s-match", modname+4);
- if (ensurefeature(modname, "c:", overridename+1)) {
- zwarnnam(fromtest, "%s not available for regex",
- modname);
- return 2;
- }
+ (void)ensurefeature(modname, "c:", overridename+1);
ctype = COND_MODI;
}
/*FALLTHROUGH*/
@@ -129,7 +125,7 @@ evalcond(Estate state, char *fromtest)
if ((cd = getconddef((ctype == COND_MODI), name + 1, 1))) {
if (ctype == COND_MOD &&
(l < cd->min || (cd->max >= 0 && l > cd->max))) {
- zwarnnam(fromtest, "unrecognized condition: `%s'", name);
+ zwarnnam(fromtest, "unknown condition: -%s", name);
return 2;
}
if (tracingcond)
@@ -139,13 +135,23 @@ evalcond(Estate state, char *fromtest)
else {
char *s = strs[0];
+ if (overridename) {
+ /*
+ * Standard regex function not available: this
+ * is a hard error.
+ */
+ zerrnam(fromtest, "%s not available for regex",
+ overridename);
+ return 2;
+ }
+
strs[0] = dupstring(name);
name = s;
if (name && name[0] == '-' &&
(cd = getconddef(0, name + 1, 1))) {
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
- zwarnnam(fromtest, "unrecognized condition: `%s'",
+ zwarnnam(fromtest, "unknown condition: -%s",
name);
return 2;
}
@@ -154,7 +160,7 @@ evalcond(Estate state, char *fromtest)
return !cd->handler(strs, cd->condid);
} else {
zwarnnam(fromtest,
- "unrecognized condition: `%s'",
+ "unknown condition: -%s",
name ? name : "<null>");
}
}
diff --git a/Src/exec.c b/Src/exec.c
index 0aee2d6a9..015753a83 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -871,7 +871,7 @@ execlist(Estate state, int dont_change_job, int exiting)
/* Loop over all sets of comands separated by newline, *
* semi-colon or ampersand (`sublists'). */
code = *state->pc++;
- while (wc_code(code) == WC_LIST && !breaks && !retflag) {
+ while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) {
int donedebug;
ltype = WC_LIST_TYPE(code);
@@ -1915,6 +1915,34 @@ execsubst(LinkList strs)
}
}
+/*
+ * Check if a builtin requires an autoload and if so
+ * deal with it. This may return NULL.
+ */
+
+/**/
+static HashNode
+resolvebuiltin(const char *cmdarg, HashNode hn)
+{
+ if (!((Builtin) hn)->handlerfunc) {
+ /*
+ * Ensure the module is loaded and the
+ * feature corresponding to the builtin
+ * is enabled.
+ */
+ (void)ensurefeature(((Builtin) hn)->optstr, "b:",
+ (hn->flags & BINF_AUTOALL) ? NULL :
+ hn->nam);
+ hn = builtintab->getnode(builtintab, cmdarg);
+ if (!hn) {
+ lastval = 1;
+ zerr("unknown builtin: %s");
+ return NULL;
+ }
+ }
+ return hn;
+}
+
/**/
static void
execcmd(Estate state, int input, int output, int how, int last1)
@@ -2011,16 +2039,9 @@ execcmd(Estate state, int input, int output, int how, int last1)
is_builtin = 1;
/* autoload the builtin if necessary */
- if (!((Builtin) hn)->handlerfunc) {
- /*
- * Ensure the module is loaded and the
- * feature corresponding to the builtin
- * is enabled.
- */
- (void)ensurefeature(((Builtin) hn)->optstr, "b:", hn->nam);
- hn = builtintab->getnode(builtintab, cmdarg);
- }
- assign = (hn && (hn->flags & BINF_MAGICEQUALS));
+ if (!(hn = resolvebuiltin(cmdarg, hn)))
+ return;
+ assign = (hn->flags & BINF_MAGICEQUALS);
break;
}
cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
@@ -2233,10 +2254,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
is_builtin = 1;
/* autoload the builtin if necessary */
- if (!((Builtin) hn)->handlerfunc) {
- (void)ensurefeature(((Builtin) hn)->optstr, "b:", cmdarg);
- hn = builtintab->getnode(builtintab, cmdarg);
- }
+ if (!(hn = resolvebuiltin(cmdarg, hn)))
+ return;
break;
}
cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
@@ -4104,8 +4123,8 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
wrap->module->wrapper--;
if (!wrap->module->wrapper &&
- (wrap->module->flags & MOD_UNLOAD))
- unload_module(wrap->module, NULL);
+ (wrap->module->node.flags & MOD_UNLOAD))
+ unload_module(wrap->module);
if (!cont)
return;
diff --git a/Src/hashtable.c b/Src/hashtable.c
index 669990566..d820c4fd4 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -78,7 +78,7 @@ static HashTable firstht, lastht;
/**/
mod_export unsigned
-hasher(char *str)
+hasher(const char *str)
{
unsigned hashval = 0, c;
@@ -223,7 +223,7 @@ addhashnode2(HashTable ht, char *nam, void *nodeptr)
/**/
mod_export HashNode
-gethashnode(HashTable ht, char *nam)
+gethashnode(HashTable ht, const char *nam)
{
unsigned hashval;
HashNode hp;
@@ -247,7 +247,7 @@ gethashnode(HashTable ht, char *nam)
/**/
mod_export HashNode
-gethashnode2(HashTable ht, char *nam)
+gethashnode2(HashTable ht, const char *nam)
{
unsigned hashval;
HashNode hp;
@@ -267,7 +267,7 @@ gethashnode2(HashTable ht, char *nam)
/**/
mod_export HashNode
-removehashnode(HashTable ht, char *nam)
+removehashnode(HashTable ht, const char *nam)
{
unsigned hashval;
HashNode hp, hq;
@@ -795,7 +795,7 @@ createshfunctable(void)
/**/
static HashNode
-removeshfuncnode(UNUSED(HashTable ht), char *nam)
+removeshfuncnode(UNUSED(HashTable ht), const char *nam)
{
HashNode hn;
int signum;
@@ -1378,7 +1378,7 @@ addnameddirnode(HashTable ht, char *nam, void *nodeptr)
/**/
static HashNode
-removenameddirnode(HashTable ht, char *nam)
+removenameddirnode(HashTable ht, const char *nam)
{
HashNode hn = removehashnode(ht, nam);
@@ -1453,7 +1453,7 @@ createhisttable(void)
/**/
unsigned
-histhasher(char *str)
+histhasher(const char *str)
{
unsigned hashval = 0;
diff --git a/Src/init.c b/Src/init.c
index 13078ea2e..e885c79b6 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -701,7 +701,7 @@ setupvals(void)
close(tmppipe[1]);
}
- (void)addhookdefs(argzero, zshhooks, sizeof(zshhooks)/sizeof(*zshhooks));
+ (void)addhookdefs(NULL, zshhooks, sizeof(zshhooks)/sizeof(*zshhooks));
init_eprog();
@@ -769,7 +769,7 @@ setupvals(void)
watch = mkarray(NULL);
psvar = mkarray(NULL);
module_path = mkarray(ztrdup(MODULE_DIR));
- modules = znewlinklist();
+ modulestab = newmoduletable(17, "modules");
linkedmodules = znewlinklist();
/* Set default prompts */
diff --git a/Src/jobs.c b/Src/jobs.c
index b02922a03..129da7d57 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -2147,7 +2147,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
/**/
mod_export int
-getsignum(char *s)
+getsignum(const char *s)
{
int x, i;
@@ -2205,7 +2205,7 @@ gettrapnode(int sig, int ignoredisable)
{
char fname[20];
HashNode hn;
- HashNode (*getptr)(HashTable ht, char *name);
+ HashNode (*getptr)(HashTable ht, const char *name);
int i;
if (ignoredisable)
getptr = shfunctab->getnode2;
diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh
index d636550ac..005e2ef81 100644
--- a/Src/mkbltnmlst.sh
+++ b/Src/mkbltnmlst.sh
@@ -37,8 +37,7 @@ for x_mod in $x_mods; do
echo "/* non-linked-in known module \`$x_mod' */"
linked=no
esac
- unset moddeps autobins autoinfixconds autoprefixconds autoparams
- unset automathfuncs
+ unset moddeps autofeatures
. $srcdir/../$modfile
if test "x$autofeatures" != x; then
echo " if (emulation == EMULATE_ZSH) {"
diff --git a/Src/module.c b/Src/module.c
index c82d77373..765f7c941 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -24,13 +24,16 @@
* provided hereunder is on an "as is" basis, and Zoltán Hidvégi and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
- *
*/
#include "zsh.mdh"
#include "module.pro"
-/* List of linked-in modules. */
+/*
+ * List of linked-in modules.
+ * This is set up at boot and remains for the life of the shell;
+ * entries do not appear in "zmodload" listings.
+ */
/**/
LinkList linkedmodules;
@@ -40,19 +43,42 @@ LinkList linkedmodules;
/**/
char **module_path;
-/* List of modules */
+/* Hash of modules */
/**/
-mod_export LinkList modules;
+mod_export HashTable modulestab;
/*
* Bit flags passed as the "flags" argument of a autofeaturefn_t.
+ * Used in other places, such as the final argument to
+ * do_module_features().
*/
enum {
- /* `-i' option: ignore errors pertaining to redefinitions */
- AUTOFEAT_IGNORE = 0x0001,
+ /*
+ * `-i' option: ignore errors pertaining to redefinitions,
+ * or indicate to do_module_features() that it should be
+ * silent.
+ */
+ FEAT_IGNORE = 0x0001,
/* If a condition, condition is infix rather than prefix */
- AUTOFEAT_INFIX = 0x0002
+ FEAT_INFIX = 0x0002,
+ /*
+ * Enable all features in the module when autoloading.
+ * This is the traditional zmodload -a behaviour;
+ * zmodload -Fa only enables features explicitly marked for
+ * autoloading.
+ */
+ FEAT_AUTOALL = 0x0004,
+ /*
+ * Remove feature: alternative to "-X:NAME" used if
+ * X is passed separately from NAME.
+ */
+ FEAT_REMOVE = 0x0008,
+ /*
+ * For do_module_features(). Check that any autoloads
+ * for the module are actually provided.
+ */
+ FEAT_CHECKAUTO = 0x0010
};
/*
@@ -65,7 +91,7 @@ enum {
*
* "flags" is a set of the bits above.
*
- * The return value is 0 for success, a negative value for failure with no
+ * The return value is 0 for success, -1 for failure with no
* message needed, and one of the following to indicate the calling
* function should print a message:
*
@@ -73,7 +99,199 @@ enum {
* 2: [feature]: no such [type]
* 3: [feature]: [type] is already defined
*/
-typedef int (*autofeaturefn_t)(char *module, char *feature, int flags);
+typedef int (*autofeaturefn_t)(const char *module, const char *feature,
+ int flags);
+
+/* 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,
+};
+
+static void
+freemodulenode(HashNode hn)
+{
+ Module m = (Module) hn;
+
+ if (m->node.flags & MOD_ALIAS)
+ zsfree(m->u.alias);
+ zsfree(m->node.nam);
+ if (m->autoloads)
+ freelinklist(m->autoloads, freestr);
+ if (m->deps)
+ freelinklist(m->deps, freestr);
+ zfree(m, sizeof(*m));
+}
+
+/* flags argument to printmodulenode */
+enum {
+ /* -L flag, output zmodload commands */
+ PRINTMOD_LIST = 0x0001,
+ /* -e flag */
+ PRINTMOD_EXIST = 0x0002,
+ /* -A flag */
+ PRINTMOD_ALIAS = 0x0004,
+ /* -d flag */
+ PRINTMOD_DEPS = 0x0008,
+ /* -F flag */
+ PRINTMOD_FEATURES = 0x0010,
+ /* -l flag in combination with -L flag */
+ PRINTMOD_LISTALL = 0x0020,
+ /* -a flag */
+ PRINTMOD_AUTO = 0x0040
+};
+
+/* Scan function for printing module details */
+
+static void
+printmodulenode(HashNode hn, int flags)
+{
+ Module m = (Module)hn;
+ /*
+ * If we check for a module loaded under an alias, we
+ * need the name of the alias. We can use it in other
+ * cases, too.
+ */
+ const char *modname = m->node.nam;
+
+ if (flags & PRINTMOD_DEPS) {
+ /*
+ * Print the module's dependencies.
+ */
+ LinkNode n;
+
+ if (!m->deps)
+ return;
+
+ if (flags & PRINTMOD_LIST) {
+ printf("zmodload -d ");
+ if (modname[0] == '-')
+ fputs("-- ", stdout);
+ quotedzputs(modname, stdout);
+ } else {
+ nicezputs(modname, stdout);
+ putchar(':');
+ }
+ for (n = firstnode(m->deps); n; incnode(n)) {
+ putchar(' ');
+ if (flags & PRINTMOD_LIST)
+ quotedzputs((char *) getdata(n), stdout);
+ else
+ nicezputs((char *) getdata(n), stdout);
+ }
+ } else if (flags & PRINTMOD_EXIST) {
+ /*
+ * Just print the module name, provided the module is
+ * present under an alias or otherwise.
+ */
+ if (m->node.flags & MOD_ALIAS) {
+ if (!(flags & PRINTMOD_ALIAS) ||
+ !(m = find_module(m->u.alias, FINDMOD_ALIASP, NULL)))
+ return;
+ }
+ if (!m->u.handle || (m->node.flags & MOD_UNLOAD))
+ return;
+ nicezputs(modname, stdout);
+ } else if (m->node.flags & MOD_ALIAS) {
+ /*
+ * Normal listing, but for aliases.
+ */
+ if (flags & PRINTMOD_LIST) {
+ printf("zmodload -A ");
+ if (modname[0] == '-')
+ fputs("-- ", stdout);
+ quotedzputs(modname, stdout);
+ putchar('=');
+ quotedzputs(m->u.alias, stdout);
+ } else {
+ nicezputs(modname, stdout);
+ fputs(" -> ", stdout);
+ nicezputs(m->u.alias, stdout);
+ }
+ } else if (m->u.handle) {
+ /*
+ * Loaded module.
+ */
+ if (flags & PRINTMOD_LIST) {
+ /*
+ * List with -L format. Possibly we are printing
+ * features, either enables or autoloads.
+ */
+ char **features = NULL;
+ int *enables = NULL;
+ if (flags & PRINTMOD_AUTO) {
+ if (!m->autoloads || !firstnode(m->autoloads))
+ return;
+ } else if (flags & PRINTMOD_FEATURES) {
+ if (features_module(m, &features) ||
+ enables_module(m, &enables) ||
+ !*features)
+ return;
+ }
+ printf("zmodload ");
+ if (flags & PRINTMOD_AUTO) {
+ fputs("-Fa ", stdout);
+ } else if (features)
+ fputs("-F ", stdout);
+ if(modname[0] == '-')
+ fputs("-- ", stdout);
+ quotedzputs(modname, stdout);
+ if (flags & PRINTMOD_AUTO) {
+ LinkNode an;
+ for (an = firstnode(m->autoloads); an; incnode(an)) {
+ putchar(' ');
+ quotedzputs((char *)getdata(an), stdout);
+ }
+ } else if (features) {
+ const char *f;
+ while ((f = *features++)) {
+ int on = *enables++;
+ if (flags & PRINTMOD_LISTALL)
+ printf(" %s", on ? "+" : "-");
+ else if (!on)
+ continue;
+ else
+ putchar(' ');
+ quotedzputs(f, stdout);
+ }
+ }
+ } else /* -l */
+ nicezputs(modname, stdout);
+ } else
+ return;
+ putchar('\n');
+}
+
+/**/
+HashTable
+newmoduletable(int size, char const *name)
+{
+ HashTable ht;
+ ht = newhashtable(size, name, NULL);
+
+ ht->hash = hasher;
+ ht->emptytable = emptyhashtable;
+ ht->filltable = NULL;
+ ht->cmpnodes = strcmp;
+ ht->addnode = addhashnode;
+ /* DISABLED is not supported */
+ ht->getnode = gethashnode2;
+ ht->getnode2 = gethashnode2;
+ ht->removenode = removehashnode;
+ ht->disablenode = NULL;
+ ht->enablenode = NULL;
+ ht->freenode = freemodulenode;
+ ht->printnode = printmodulenode;
+
+ return ht;
+}
/************************************************************************
* zsh/main standard module functions
@@ -160,27 +378,6 @@ register_module(char *n, Module_void_func setup,
zaddlinknode(linkedmodules, m);
}
-/* Print an alias. */
-
-/**/
-static void
-printmodalias(Module m, Options ops)
-{
- if (OPT_ISSET(ops,'L')) {
- printf("zmodload -A ");
- if (m->nam[0] == '-')
- fputs("-- ", stdout);
- quotedzputs(m->nam, stdout);
- putchar('=');
- quotedzputs(m->u.alias, stdout);
- } else {
- nicezputs(m->nam, stdout);
- fputs(" -> ", stdout);
- nicezputs(m->u.alias, stdout);
- }
- putchar('\n');
-}
-
/* Check if a module is linked in. */
/**/
@@ -208,7 +405,7 @@ module_linked(char const *name)
* builtin can be replaced using this function. */
/**/
-int
+static int
addbuiltin(Builtin b)
{
Builtin bn = (Builtin) builtintab->getnode2(builtintab, b->node.nam);
@@ -226,16 +423,19 @@ addbuiltin(Builtin b)
/**/
static int
-add_autobin(char *module, char *bnam, int flags)
+add_autobin(const char *module, const char *bnam, int flags)
{
Builtin bn;
+ int ret;
bn = zshcalloc(sizeof(*bn));
bn->node.nam = ztrdup(bnam);
bn->optstr = ztrdup(module);
- if (addbuiltin(bn)) {
+ if (flags & FEAT_AUTOALL)
+ bn->node.flags |= BINF_AUTOALL;
+ if ((ret = addbuiltin(bn))) {
builtintab->freenode(&bn->node);
- if (!(flags & AUTOFEAT_IGNORE))
+ if (!(flags & FEAT_IGNORE))
return 1;
}
return 0;
@@ -246,7 +446,7 @@ add_autobin(char *module, char *bnam, int flags)
/**/
int
-deletebuiltin(char *nam)
+deletebuiltin(const char *nam)
{
Builtin bn;
@@ -261,14 +461,15 @@ deletebuiltin(char *nam)
/**/
static int
-del_autobin(UNUSED(char *module), char *bnam, int flags)
+del_autobin(UNUSED(const char *module), const char *bnam, int flags)
{
Builtin bn = (Builtin) builtintab->getnode2(builtintab, bnam);
if (!bn) {
- if(!(flags & AUTOFEAT_IGNORE))
+ if(!(flags & FEAT_IGNORE))
return 2;
} else if (bn->node.flags & BINF_ADDED) {
- return 3;
+ if (!(flags & FEAT_IGNORE))
+ return 3;
} else
deletebuiltin(bnam);
@@ -383,7 +584,7 @@ addwrapper(Module m, FuncWrap w)
* happen since we usually add wrappers when a real module is
* loaded.
*/
- if (m->flags & MOD_ALIAS)
+ if (m->node.flags & MOD_ALIAS)
return 1;
if (w->flags & WRAPF_ADDED)
@@ -409,7 +610,7 @@ deletewrapper(Module m, FuncWrap w)
{
FuncWrap p, q;
- if (m->flags & MOD_ALIAS)
+ if (m->node.flags & MOD_ALIAS)
return 1;
if (w->flags & WRAPF_ADDED) {
@@ -444,7 +645,7 @@ mod_export Conddef condtab;
/**/
Conddef
-getconddef(int inf, char *name, int autol)
+getconddef(int inf, const char *name, int autol)
{
Conddef p;
int f = 1;
@@ -462,8 +663,8 @@ getconddef(int inf, char *name, int autol)
*/
if (f) {
(void)ensurefeature(p->module,
- (p->flags & CONDF_INFIX) ?
- "C:" : "c:", name);
+ (p->flags & CONDF_INFIX) ? "C:" : "c:",
+ (p->flags & CONDF_AUTOALL) ? NULL : name);
f = 0;
p = NULL;
} else {
@@ -577,14 +778,16 @@ setconddefs(char const *nam, Conddef c, int size, int *e)
/**/
static int
-add_autocond(char *module, char *cnam, int flags)
+add_autocond(const char *module, const char *cnam, int flags)
{
Conddef c;
c = (Conddef) zalloc(sizeof(*c));
c->name = ztrdup(cnam);
- c->flags = ((flags & AUTOFEAT_INFIX) ? CONDF_INFIX : 0);
+ c->flags = ((flags & FEAT_INFIX) ? CONDF_INFIX : 0);
+ if (flags & FEAT_AUTOALL)
+ c->flags |= CONDF_AUTOALL;
c->module = ztrdup(module);
if (addconddef(c)) {
@@ -592,7 +795,7 @@ add_autocond(char *module, char *cnam, int flags)
zsfree(c->module);
zfree(c, sizeof(*c));
- if (!(flags & AUTOFEAT_IGNORE))
+ if (!(flags & FEAT_IGNORE))
return 1;
}
return 0;
@@ -602,16 +805,17 @@ add_autocond(char *module, char *cnam, int flags)
/**/
static int
-del_autocond(UNUSED(char *modnam), char *cnam, int flags)
+del_autocond(UNUSED(const char *modnam), const char *cnam, int flags)
{
- Conddef cd = getconddef((flags & AUTOFEAT_INFIX) ? 1 : 0, cnam, 0);
+ Conddef cd = getconddef((flags & FEAT_INFIX) ? 1 : 0, cnam, 0);
if (!cd) {
- if (!(flags & AUTOFEAT_IGNORE)) {
+ if (!(flags & FEAT_IGNORE)) {
return 2;
}
} else if (cd->flags & CONDF_ADDED) {
- return 3;
+ if (!(flags & FEAT_IGNORE))
+ return 3;
} else
deleteconddef(cd);
@@ -658,17 +862,21 @@ addhookdef(Hookdef h)
return 0;
}
-/* This adds multiple hook definitions. This is like addbuiltins(). */
+/*
+ * This adds multiple hook definitions. This is like addbuiltins().
+ * This allows a NULL module because we call it from init.c.
+ */
/**/
mod_export int
-addhookdefs(char const *nam, Hookdef h, int size)
+addhookdefs(Module m, Hookdef h, int size)
{
int ret = 0;
while (size--) {
if (addhookdef(h)) {
- zwarnnam(nam, "name clash when adding hook `%s'", h->name);
+ zwarnnam(m ? m->node.nam : NULL,
+ "name clash when adding hook `%s'", h->name);
ret = 1;
}
h++;
@@ -701,7 +909,7 @@ deletehookdef(Hookdef h)
/**/
mod_export int
-deletehookdefs(UNUSED(char const *nam), Hookdef h, int size)
+deletehookdefs(UNUSED(Module m), Hookdef h, int size)
{
int ret = 0;
@@ -804,7 +1012,7 @@ runhookdef(Hookdef h, void *d)
*/
static int
-checkaddparam(char *nam, int opt_i)
+checkaddparam(const char *nam, int opt_i)
{
Param pm;
@@ -970,13 +1178,13 @@ setparamdefs(char const *nam, Paramdef d, int size, int *e)
/**/
static int
-add_autoparam(char *module, char *pnam, int flags)
+add_autoparam(const char *module, const char *pnam, int flags)
{
Param pm;
int ret;
queue_signals();
- if ((ret = checkaddparam(pnam, (flags & AUTOFEAT_IGNORE)))) {
+ if ((ret = checkaddparam(pnam, (flags & FEAT_IGNORE)))) {
unqueue_signals();
/*
* checkaddparam() has already printed a message if one was
@@ -988,9 +1196,11 @@ add_autoparam(char *module, char *pnam, int flags)
return ret == 2 ? 0 : -1;
}
- pm = setsparam(pnam, ztrdup(module));
+ pm = setsparam(dupstring(pnam), ztrdup(module));
pm->node.flags |= PM_AUTOLOAD;
+ if (flags & FEAT_AUTOALL)
+ pm->node.flags |= PM_AUTOALL;
unqueue_signals();
return 0;
@@ -1000,15 +1210,16 @@ add_autoparam(char *module, char *pnam, int flags)
/**/
static int
-del_autoparam(UNUSED(char *modnam), char *pnam, int flags)
+del_autoparam(UNUSED(const char *modnam), const char *pnam, int flags)
{
Param pm = (Param) gethashnode2(paramtab, pnam);
if (!pm) {
- if (!(flags & AUTOFEAT_IGNORE))
+ if (!(flags & FEAT_IGNORE))
return 2;
} else if (!(pm->node.flags & PM_AUTOLOAD)) {
- return 3;
+ if (!(flags & FEAT_IGNORE))
+ return 3;
} else
unsetparam_pm(pm, 0, 1);
@@ -1047,7 +1258,7 @@ removemathfunc(MathFunc previous, MathFunc current)
/**/
MathFunc
-getmathfunc(char *name, int autol)
+getmathfunc(const char *name, int autol)
{
MathFunc p, q = NULL;
@@ -1058,7 +1269,8 @@ getmathfunc(char *name, int autol)
removemathfunc(q, p);
- (void)ensurefeature(n, "f:", name);
+ (void)ensurefeature(n, "f:", (p->flags & MFF_AUTOALL) ? NULL :
+ name);
return getmathfunc(name, 0);
}
@@ -1171,7 +1383,7 @@ setmathfuncs(char const *nam, MathFunc f, int size, int *e)
/**/
static int
-add_automathfunc(char *module, char *fnam, int flags)
+add_automathfunc(const char *module, const char *fnam, int flags)
{
MathFunc f;
@@ -1186,7 +1398,7 @@ add_automathfunc(char *module, char *fnam, int flags)
zsfree(f->module);
zfree(f, sizeof(*f));
- if (!(flags & AUTOFEAT_IGNORE))
+ if (!(flags & FEAT_IGNORE))
return 1;
}
@@ -1197,15 +1409,16 @@ add_automathfunc(char *module, char *fnam, int flags)
/**/
static int
-del_automathfunc(UNUSED(char *modnam), char *fnam, int flags)
+del_automathfunc(UNUSED(const char *modnam), const char *fnam, int flags)
{
MathFunc f = getmathfunc(fnam, 0);
if (!f) {
- if (!(flags & AUTOFEAT_IGNORE))
+ if (!(flags & FEAT_IGNORE))
return 2;
} else if (f->flags & MFF_ADDED) {
- return 3;
+ if (!(flags & FEAT_IGNORE))
+ return 3;
} else
deletemathfunc(f);
@@ -1233,13 +1446,15 @@ load_and_bind(const char *fn)
void *ret = (void *) load((char *) fn, L_NOAUTODEFER, NULL);
if (ret) {
- LinkNode node;
- int err = loadbind(0, (void *) addbuiltin, ret);
- for (node = firstnode(modules); !err && node; incnode(node)) {
- Module m = (Module) getdata(node);
- if (!(m->flags & MOD_ALIAS) &&
- m->u.handle && !(m->flags & MOD_LINKED))
- err |= loadbind(0, m->u.handle, ret);
+ Module m;
+ int i, err = loadbind(0, (void *) addbuiltin, ret);
+ for (i = 0; i < modulestab->hsize && !err; i++) {
+ for (m = (Module)modulestab->nodes[i]; m && !err;
+ m = m->node.next) {
+ if (!(m->flags & MOD_ALIAS) &&
+ m->u.handle && !(m->flags & MOD_LINKED))
+ err |= loadbind(0, m->u.handle, ret);
+ }
}
if (err) {
@@ -1256,6 +1471,9 @@ load_and_bind(const char *fn)
#define dlopen(X,Y) load_and_bind(X)
#define dlclose(X) unload(X)
#define dlerror() (dlerrstr[0])
+#ifndef HAVE_DLERROR
+# define HAVE_DLERROR 1
+#endif
/**/
#else
@@ -1294,7 +1512,9 @@ hpux_dlsym(void *handle, char *name)
}
# define dlsym(handle,name) hpux_dlsym(handle,name)
-# define dlerror() 0
+# ifdef HAVE_DLERROR /* paranoia */
+# undef HAVE_DLERROR
+# endif
#else
# ifndef HAVE_DLCLOSE
# define dlclose(X) ((X), 0)
@@ -1366,8 +1586,13 @@ do_load_module(char const *name, int silent)
void *ret;
ret = try_load_module(name);
- if (!ret && !silent)
+ if (!ret && !silent) {
+#ifdef HAVE_DLERROR
+ zwarn("failed to load module `%s': %s", name, dlerror());
+#else
zwarn("failed to load module: %s", name);
+#endif
+ }
return ret;
}
@@ -1391,19 +1616,6 @@ 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.
* flags is a set of bits defined in the enum above.
@@ -1413,35 +1625,29 @@ enum {
* Return NULL if the module named is not stored as a structure, or if we were
* resolving aliases and the final module named is not stored as a
* structure.
- *
- * TODO: now we have aliases, there may be some merit in using a hash
- * table instead of a linked list.
*/
/**/
-static LinkNode
+static Module
find_module(const char *name, int flags, const char **namep)
{
Module m;
- LinkNode node;
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (!strcmp(m->nam, name)) {
- if ((flags & FINDMOD_ALIASP) && (m->flags & MOD_ALIAS)) {
- if (namep)
- *namep = m->u.alias;
- return find_module(m->u.alias, flags, namep);
- }
+ m = (Module)modulestab->getnode2(modulestab, name);
+ if (m) {
+ if ((flags & FINDMOD_ALIASP) && (m->node.flags & MOD_ALIAS)) {
if (namep)
- *namep = m->nam;
- return node;
+ *namep = m->u.alias;
+ return find_module(m->u.alias, flags, namep);
}
+ if (namep)
+ *namep = m->node.nam;
+ return m;
}
if (!(flags & FINDMOD_CREATE))
return NULL;
m = zshcalloc(sizeof(*m));
- m->nam = ztrdup(name);
- return zaddlinknode(modules, m);
+ modulestab->addnode(modulestab, ztrdup(name), m);
+ return m;
}
/*
@@ -1450,16 +1656,11 @@ find_module(const char *name, int flags, const char **namep)
/**/
static void
-delete_module(LinkNode node)
+delete_module(Module m)
{
- Module m = (Module) remnode(modules, node);
+ modulestab->removenode(modulestab, m->node.nam);
- if (m->flags & MOD_ALIAS)
- zsfree(m->u.alias);
- zsfree(m->nam);
- if (m->deps)
- freelinklist(m->deps, freestr);
- zfree(m, sizeof(*m));
+ modulestab->freenode(&m->node);
}
/*
@@ -1473,12 +1674,11 @@ delete_module(LinkNode node)
mod_export int
module_loaded(const char *name)
{
- LinkNode node;
Module m;
- return ((node = find_module(name, FINDMOD_ALIASP, NULL)) &&
- (m = ((Module) getdata(node)))->u.handle &&
- !(m->flags & MOD_UNLOAD));
+ return ((m = find_module(name, FINDMOD_ALIASP, NULL)) &&
+ m->u.handle &&
+ !(m->node.flags & MOD_UNLOAD));
}
/*
@@ -1575,7 +1775,7 @@ dyn_setup_module(Module m)
if (fn)
return fn(m);
- zwarnnam(m->nam, "no setup function");
+ zwarnnam(m->node.nam, "no setup function");
return 1;
}
@@ -1612,7 +1812,7 @@ dyn_boot_module(Module m)
if(fn)
return fn(m);
- zwarnnam(m->nam, "no boot function");
+ zwarnnam(m->node.nam, "no boot function");
return 1;
}
@@ -1624,7 +1824,7 @@ dyn_cleanup_module(Module m)
if(fn)
return fn(m);
- zwarnnam(m->nam, "no cleanup function");
+ zwarnnam(m->node.nam, "no cleanup function");
return 1;
}
@@ -1641,7 +1841,7 @@ dyn_finish_module(Module m)
if (fn)
r = fn(m);
else {
- zwarnnam(m->nam, "no finish function");
+ zwarnnam(m->node.nam, "no finish function");
r = 1;
}
dlclose(m->u.handle);
@@ -1655,7 +1855,7 @@ dyn_finish_module(Module m)
static int
setup_module(Module m)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->setup)(m) : dyn_setup_module(m));
}
@@ -1663,7 +1863,7 @@ setup_module(Module m)
static int
features_module(Module m, char ***features)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->features)(m, features) :
dyn_features_module(m, features));
}
@@ -1672,7 +1872,7 @@ features_module(Module m, char ***features)
static int
enables_module(Module m, int **enables)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->enables)(m, enables) :
dyn_enables_module(m, enables));
}
@@ -1681,7 +1881,7 @@ enables_module(Module m, int **enables)
static int
boot_module(Module m)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->boot)(m) : dyn_boot_module(m));
}
@@ -1689,7 +1889,7 @@ boot_module(Module m)
static int
cleanup_module(Module m)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->cleanup)(m) : dyn_cleanup_module(m));
}
@@ -1697,7 +1897,7 @@ cleanup_module(Module m)
static int
finish_module(Module m)
{
- return ((m->flags & MOD_LINKED) ?
+ return ((m->node.flags & MOD_LINKED) ?
(m->u.linked->finish)(m) : dyn_finish_module(m));
}
@@ -1708,14 +1908,14 @@ finish_module(Module m)
static int
setup_module(Module m)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->setup)(m) : 1);
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->setup)(m) : 1);
}
/**/
static int
features_module(Module m, char ***features)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->features)(m, features)
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->features)(m, features)
: 1);
}
@@ -1723,7 +1923,7 @@ features_module(Module m, char ***features)
static int
enables_module(Module m, int **enables)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->enables)(m, enables)
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->enables)(m, enables)
: 1);
}
@@ -1731,21 +1931,21 @@ enables_module(Module m, int **enables)
static int
boot_module(Module m)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->boot)(m) : 1);
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->boot)(m) : 1);
}
/**/
static int
cleanup_module(Module m)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->cleanup)(m) : 1);
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->cleanup)(m) : 1);
}
/**/
static int
finish_module(Module m)
{
- return ((m->flags & MOD_LINKED) ? (m->u.linked->finish)(m) : 1);
+ return ((m->node.flags & MOD_LINKED) ? (m->u.linked->finish)(m) : 1);
}
/**/
@@ -1761,14 +1961,16 @@ finish_module(Module m)
* by now (though may not be fully set up).
*
* Return 0 for success, 1 for failure, 2 if some features
- * couldn't be set.
+ * couldn't be set by the module itself (non-existent features
+ * are tested here and cause 1 to be returned).
*/
/**/
static int
-do_module_features(Module m, char **enablesstr, int silent)
+do_module_features(Module m, char **enablesstr, int flags)
{
char **features;
+ int ret = 0;
if (features_module(m, &features) == 0) {
/*
@@ -1781,12 +1983,62 @@ do_module_features(Module m, char **enablesstr, int silent)
int *enables = NULL;
if (enables_module(m, &enables)) {
/* If features are supported, enables should be, too */
- if (!silent)
+ if (!(flags & FEAT_IGNORE))
zwarn("error getting enabled features for module `%s'",
- m->nam);
+ m->node.nam);
return 1;
}
+ if ((flags & FEAT_CHECKAUTO) && m->autoloads) {
+ /*
+ * Check autoloads are available. Since these
+ * have been requested at some other point, they
+ * don't affect the return status unless something
+ * in enablesstr doesn't work.
+ */
+ LinkNode an, nextn;
+ for (an = firstnode(m->autoloads); an; an = nextn) {
+ char *al = (char *)getdata(an), **ptr;
+ /* careful, we can delete the current node */
+ nextn = nextnode(an);
+ for (ptr = features; *ptr; ptr++)
+ if (!strcmp(al, *ptr))
+ break;
+ if (!*ptr) {
+ char *arg[2];
+ if (!(flags & FEAT_IGNORE))
+ zwarn(
+ "module `%s' has no such feature: `%s': autoload cancelled",
+ m->node.nam, al);
+ /*
+ * This shouldn't happen, so it's not worth optimising
+ * the call to autofeatures...
+ */
+ arg[0] = al = dupstring(al);
+ arg[1] = NULL;
+ (void)autofeatures(NULL, m->node.nam, arg, 0,
+ FEAT_IGNORE|FEAT_REMOVE);
+ /*
+ * don't want to try to enable *that*...
+ * expunge it from the enable string.
+ */
+ if (enablesstr) {
+ for (ptr = enablesstr; *ptr; ptr++) {
+ if (!strcmp(al, *ptr)) {
+ /* can't enable it after all, so return 1 */
+ ret = 1;
+ while (*ptr) {
+ *ptr = ptr[1];
+ ptr++;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
if (enablesstr) {
char **ep;
for (ep = enablesstr; *ep; ep++) {
@@ -1804,9 +2056,9 @@ do_module_features(Module m, char **enablesstr, int silent)
break;
}
if (!*fp) {
- if (!silent)
- zwarn("module `%s' has no such feature: %s",
- m->nam, esp);
+ if (!(flags & FEAT_IGNORE))
+ zwarn("module `%s' has no such feature: `%s'",
+ m->node.nam, esp);
return 1;
}
}
@@ -1824,13 +2076,13 @@ do_module_features(Module m, char **enablesstr, int silent)
if (enables_module(m, &enables))
return 2;
} else if (enablesstr) {
- if (!silent)
- zwarn("module `%s' does not support features", m->nam);
+ if (!(flags & FEAT_IGNORE))
+ zwarn("module `%s' does not support features", m->node.nam);
return 1;
}
/* Else it doesn't support features but we don't care. */
- return 0;
+ return ret;
}
/*
@@ -1847,7 +2099,9 @@ do_module_features(Module m, char **enablesstr, int silent)
static int
do_boot_module(Module m, char **enablesstr, int silent)
{
- int ret = do_module_features(m, enablesstr, silent);
+ int ret = do_module_features(m, enablesstr,
+ silent ? FEAT_IGNORE|FEAT_CHECKAUTO :
+ FEAT_CHECKAUTO);
if (ret == 1)
return 1;
@@ -1865,7 +2119,7 @@ do_boot_module(Module m, char **enablesstr, int silent)
static int
do_cleanup_module(Module m)
{
- return (m->flags & MOD_LINKED) ?
+ return (m->node.flags & MOD_LINKED) ?
(m->u.linked && m->u.linked->cleanup(m)) :
(m->u.handle && cleanup_module(m));
}
@@ -1910,7 +2164,6 @@ load_module(char const *name, char **enablesstr, int silent)
Module m;
void *handle = NULL;
Linkedmod linked;
- LinkNode node, n;
int set, bootret;
if (!modname_ok(name)) {
@@ -1924,66 +2177,65 @@ load_module(char const *name, char **enablesstr, int silent)
* is the right one.
*/
queue_signals();
- if (!(node = find_module(name, FINDMOD_ALIASP, &name))) {
+ if (!(m = find_module(name, FINDMOD_ALIASP, &name))) {
if (!(linked = module_linked(name)) &&
!(handle = do_load_module(name, silent))) {
unqueue_signals();
return 1;
}
m = zshcalloc(sizeof(*m));
- m->nam = ztrdup(name);
if (handle) {
m->u.handle = handle;
- m->flags |= MOD_SETUP;
+ m->node.flags |= MOD_SETUP;
} else {
m->u.linked = linked;
- m->flags |= MOD_SETUP | MOD_LINKED;
+ m->node.flags |= MOD_SETUP | MOD_LINKED;
}
- node = zaddlinknode(modules, m);
+ modulestab->addnode(modulestab, ztrdup(name), m);
if ((set = setup_module(m)) ||
(bootret = do_boot_module(m, enablesstr, silent)) == 1) {
- if (!set) {
+ if (!set)
do_cleanup_module(m);
- finish_module(m);
- }
- delete_module(node);
+ finish_module(m);
+ delete_module(m);
unqueue_signals();
return 1;
}
- m->flags |= MOD_INIT_S | MOD_INIT_B;
- m->flags &= ~MOD_SETUP;
+ m->node.flags |= MOD_INIT_S | MOD_INIT_B;
+ m->node.flags &= ~MOD_SETUP;
unqueue_signals();
return bootret;
}
- m = (Module) getdata(node);
- if (m->flags & MOD_SETUP) {
+ if (m->node.flags & MOD_SETUP) {
unqueue_signals();
return 0;
}
- if (m->flags & MOD_UNLOAD)
- m->flags &= ~MOD_UNLOAD;
- else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle) {
+ if (m->node.flags & MOD_UNLOAD)
+ m->node.flags &= ~MOD_UNLOAD;
+ else if ((m->node.flags & MOD_LINKED) ? m->u.linked : m->u.handle) {
unqueue_signals();
return 0;
}
- if (m->flags & MOD_BUSY) {
- zerr("circular dependencies for module %s", name);
+ if (m->node.flags & MOD_BUSY) {
+ zerr("circular dependencies for module ;%s", name);
return 1;
}
- m->flags |= MOD_BUSY;
+ m->node.flags |= MOD_BUSY;
/*
* TODO: shouldn't we unload the module if one of
* its dependencies fails?
*/
- if (m->deps)
+ if (m->deps) {
+ LinkNode n;
for (n = firstnode(m->deps); n; incnode(n))
if (load_module((char *) getdata(n), NULL, silent) == 1) {
- m->flags &= ~MOD_BUSY;
+ m->node.flags &= ~MOD_BUSY;
unqueue_signals();
return 1;
}
- m->flags &= ~MOD_BUSY;
+ }
+ m->node.flags &= ~MOD_BUSY;
if (!m->u.handle) {
handle = NULL;
if (!(linked = module_linked(name)) &&
@@ -1993,36 +2245,37 @@ load_module(char const *name, char **enablesstr, int silent)
}
if (handle) {
m->u.handle = handle;
- m->flags |= MOD_SETUP;
+ m->node.flags |= MOD_SETUP;
} else {
m->u.linked = linked;
- m->flags |= MOD_SETUP | MOD_LINKED;
+ m->node.flags |= MOD_SETUP | MOD_LINKED;
}
if (setup_module(m)) {
+ finish_module(m);
if (handle)
m->u.handle = NULL;
else
m->u.linked = NULL;
- m->flags &= ~MOD_SETUP;
+ m->node.flags &= ~MOD_SETUP;
unqueue_signals();
return 1;
}
- m->flags |= MOD_INIT_S;
+ m->node.flags |= MOD_INIT_S;
}
- m->flags |= MOD_SETUP;
+ m->node.flags |= MOD_SETUP;
if ((bootret = do_boot_module(m, enablesstr, silent)) == 1) {
do_cleanup_module(m);
finish_module(m);
- if (m->flags & MOD_LINKED)
+ if (m->node.flags & MOD_LINKED)
m->u.linked = NULL;
else
m->u.handle = NULL;
- m->flags &= ~MOD_SETUP;
+ m->node.flags &= ~MOD_SETUP;
unqueue_signals();
return 1;
}
- m->flags |= MOD_INIT_B;
- m->flags &= ~MOD_SETUP;
+ m->node.flags |= MOD_INIT_B;
+ m->node.flags &= ~MOD_SETUP;
unqueue_signals();
return bootret;
}
@@ -2030,7 +2283,8 @@ load_module(char const *name, char **enablesstr, int silent)
/* This ensures that the module with the name given as the first argument
* is loaded.
* The other argument is the array of features to set. If this is NULL
- * and the module needs to be loaded, all features are enabled.
+ * all features are enabled (even if the module was already loaded).
+ *
* If this is non-NULL the module features are set accordingly
* whether or not the module is loaded; it is an error if the
* module does not support the features passed (even if the feature
@@ -2050,14 +2304,13 @@ mod_export int
require_module(const char *module, char **features)
{
Module m = NULL;
- LinkNode node;
int ret = 0;
/* Resolve aliases and actual loadable module as for load_module */
queue_signals();
- node = find_module(module, 1, &module);
- if (!node || !(m = ((Module) getdata(node)))->u.handle ||
- (m->flags & MOD_UNLOAD))
+ m = find_module(module, FINDMOD_ALIASP, &module);
+ if (!m || !m->u.handle ||
+ (m->node.flags & MOD_UNLOAD))
ret = load_module(module, features, 0);
else
ret = do_module_features(m, features, 0);
@@ -2090,7 +2343,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.)
*/
- m = getdata(find_module(name, FINDMOD_ALIASP|FINDMOD_CREATE, &name));
+ m = find_module(name, FINDMOD_ALIASP|FINDMOD_CREATE, &name);
if (!m->deps)
m->deps = znewlinklist();
for (node = firstnode(m->deps);
@@ -2179,7 +2432,8 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
return 1;
}
if (OPT_ISSET(ops,'e') && (OPT_ISSET(ops,'I') || OPT_ISSET(ops,'L') ||
- OPT_ISSET(ops,'a') || OPT_ISSET(ops,'d') ||
+ (OPT_ISSET(ops,'a') && !OPT_ISSET(ops,'F'))
+ || OPT_ISSET(ops,'d') ||
OPT_ISSET(ops,'i') || OPT_ISSET(ops,'u'))) {
zwarnnam(nam, "-e cannot be combined with other options");
/* except -F ... */
@@ -2233,7 +2487,6 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
* suppose other names are aliased to the same file? It might be
* kettle of fish best left unwormed.
*/
- LinkNode node;
Module m;
if (!*args) {
@@ -2241,11 +2494,9 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
zwarnnam(nam, "no module alias to remove");
return 1;
}
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (m->flags & MOD_ALIAS)
- printmodalias(m, ops);
- }
+ scanhashtable(modulestab, 1, MOD_ALIAS, 0,
+ modulestab->printnode,
+ OPT_ISSET(ops,'L') ? PRINTMOD_LIST : 0);
return 0;
}
@@ -2264,14 +2515,13 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
*args);
return 1;
}
- node = find_module(*args, 0, NULL);
- if (node) {
- m = (Module) getdata(node);
- if (!(m->flags & MOD_ALIAS)) {
+ m = find_module(*args, 0, NULL);
+ if (m) {
+ if (!(m->node.flags & MOD_ALIAS)) {
zwarnnam(nam, "module is not an alias: %s", *args);
return 1;
}
- delete_module(node);
+ delete_module(m);
} else {
zwarnnam(nam, "no such module alias: %s", *args);
return 1;
@@ -2289,29 +2539,28 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
*args);
return 1;
}
- } while ((node = find_module(mname, 0, NULL))
- && ((m = (Module) getdata(node))->flags & MOD_ALIAS)
+ } while ((m = find_module(mname, 0, NULL))
+ && (m->node.flags & MOD_ALIAS)
&& (mname = m->u.alias));
- node = find_module(*args, 0, NULL);
- if (node) {
- m = (Module) getdata(node);
- if (!(m->flags & MOD_ALIAS)) {
+ m = find_module(*args, 0, NULL);
+ if (m) {
+ if (!(m->node.flags & MOD_ALIAS)) {
zwarnnam(nam, "module is not an alias: %s", *args);
return 1;
}
zsfree(m->u.alias);
} else {
m = (Module) zshcalloc(sizeof(*m));
- m->nam = ztrdup(*args);
- m->flags = MOD_ALIAS;
- zaddlinknode(modules, m);
+ m->node.flags = MOD_ALIAS;
+ modulestab->addnode(modulestab, ztrdup(*args), m);
}
m->u.alias = ztrdup(aliasname);
} else {
- if ((node = find_module(*args, 0, NULL))) {
- m = (Module) getdata(node);
- if (m->flags & MOD_ALIAS)
- printmodalias(m, ops);
+ if ((m = find_module(*args, 0, NULL))) {
+ if (m->node.flags & MOD_ALIAS)
+ modulestab->printnode(&m->node,
+ OPT_ISSET(ops,'L') ?
+ PRINTMOD_LIST : 0);
else {
zwarnnam(nam, "module is not an alias: %s", *args);
return 1;
@@ -2333,35 +2582,20 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
static int
bin_zmodload_exist(UNUSED(char *nam), char **args, Options ops)
{
- LinkNode node;
Module m;
- char *modname;
if (!*args) {
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- modname = m->nam;
- if (m->flags & MOD_ALIAS) {
- LinkNode node2;
- if (OPT_ISSET(ops,'A') &&
- (node2 = find_module(m->u.alias, FINDMOD_ALIASP, NULL)))
- m = (Module) getdata(node2);
- else
- continue;
- }
- if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
- nicezputs(modname, stdout);
- putchar('\n');
- }
- }
+ scanhashtable(modulestab, 1, 0, 0, modulestab->printnode,
+ OPT_ISSET(ops,'A') ? PRINTMOD_EXIST|PRINTMOD_ALIAS :
+ PRINTMOD_EXIST);
return 0;
} else {
int ret = 0;
for (; !ret && *args; args++) {
- if (!(node = find_module(*args, FINDMOD_ALIASP, NULL))
- || !(m = (Module) getdata(node))->u.handle
- || (m->flags & MOD_UNLOAD))
+ if (!(m = find_module(*args, FINDMOD_ALIASP, NULL))
+ || !m->u.handle
+ || (m->node.flags & MOD_UNLOAD))
ret = 1;
}
return ret;
@@ -2374,15 +2608,13 @@ bin_zmodload_exist(UNUSED(char *nam), char **args, Options ops)
static int
bin_zmodload_dep(UNUSED(char *nam), char **args, Options ops)
{
- LinkNode node;
Module m;
if (OPT_ISSET(ops,'u')) {
/* remove dependencies, which can't pertain to aliases */
const char *tnam = *args++;
- node = find_module(tnam, FINDMOD_ALIASP, &tnam);
- if (!node)
+ m = find_module(tnam, FINDMOD_ALIASP, &tnam);
+ if (!m)
return 0;
- m = (Module) getdata(node);
if (*args && m->deps) {
do {
LinkNode dnode;
@@ -2404,32 +2636,18 @@ bin_zmodload_dep(UNUSED(char *nam), char **args, Options ops)
}
}
if (!m->deps && !m->u.handle)
- delete_module(node);
+ delete_module(m);
return 0;
} else if (!args[0] || !args[1]) {
/* list dependencies */
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (m->deps && (!args[0] || !strcmp(args[0], m->nam))) {
- LinkNode n;
- if (OPT_ISSET(ops,'L')) {
- printf("zmodload -d ");
- if(m->nam[0] == '-')
- fputs("-- ", stdout);
- quotedzputs(m->nam, stdout);
- } else {
- nicezputs(m->nam, stdout);
- putchar(':');
- }
- for (n = firstnode(m->deps); n; incnode(n)) {
- putchar(' ');
- if(OPT_ISSET(ops,'L'))
- quotedzputs((char *) getdata(n), stdout);
- else
- nicezputs((char *) getdata(n), stdout);
- }
- putchar('\n');
- }
+ int depflags = OPT_ISSET(ops,'L') ?
+ PRINTMOD_DEPS|PRINTMOD_LIST : PRINTMOD_DEPS;
+ if (args[0]) {
+ if ((m = (Module)modulestab->getnode2(modulestab, args[0])))
+ modulestab->printnode(&m->node, depflags);
+ } else {
+ scanhashtable(modulestab, 1, 0, 0, modulestab->printnode,
+ depflags);
}
return 0;
} else {
@@ -2467,7 +2685,7 @@ printautoparams(HashNode hn, int lon)
static int
bin_zmodload_auto(char *nam, char **args, Options ops)
{
- int fchar;
+ int fchar, flags;
char *modnam;
if (OPT_ISSET(ops,'c')) {
@@ -2530,9 +2748,12 @@ bin_zmodload_auto(char *nam, char **args, Options ops)
fchar = 'b';
}
+ flags = FEAT_AUTOALL;
+ if (OPT_ISSET(ops,'i'))
+ flags |= FEAT_IGNORE;
if (OPT_ISSET(ops,'u')) {
/* remove autoload */
- fchar *= -1;
+ flags |= FEAT_REMOVE;
modnam = NULL;
} else {
/* add autoload */
@@ -2541,94 +2762,113 @@ bin_zmodload_auto(char *nam, char **args, Options ops)
if (args[1])
args++;
}
- return autofeatures(nam, modnam, args, fchar, OPT_ISSET(ops,'i'));
+ return autofeatures(nam, modnam, args, fchar, flags);
}
/* Backend handler for zmodload -u */
/**/
int
-unload_module(Module m, LinkNode node)
+unload_module(Module m)
{
+ int del;
+
/*
* Only unload the real module, so resolve aliases.
*/
- if (m->flags & MOD_ALIAS) {
- LinkNode node = find_module(m->u.alias, FINDMOD_ALIASP, NULL);
- if (!node)
+ if (m->node.flags & MOD_ALIAS) {
+ m = find_module(m->u.alias, FINDMOD_ALIASP, NULL);
+ if (!m)
return 1;
- m = (Module) getdata(node);
}
- if ((m->flags & MOD_INIT_S) &&
- !(m->flags & MOD_UNLOAD) &&
+ /*
+ * We may need to clean up the module any time setup_ has been
+ * called. After cleanup_ is successful we are no longer in the
+ * booted state (because features etc. are deregistered), so remove
+ * MOD_INIT_B, and also MOD_INIT_S since we won't need to cleanup
+ * again if this succeeded.
+ */
+ if ((m->node.flags & MOD_INIT_S) &&
+ !(m->node.flags & MOD_UNLOAD) &&
do_cleanup_module(m))
return 1;
- else {
- int del = (m->flags & MOD_UNLOAD);
+ m->node.flags &= ~(MOD_INIT_B|MOD_INIT_S);
- if (m->wrapper) {
- m->flags |= MOD_UNLOAD;
- return 0;
+ del = (m->node.flags & MOD_UNLOAD);
+
+ if (m->wrapper) {
+ m->node.flags |= MOD_UNLOAD;
+ return 0;
+ }
+ m->node.flags &= ~MOD_UNLOAD;
+
+ /*
+ * We always need to finish the module (and unload it)
+ * if it is present.
+ */
+ if (m->node.flags & MOD_LINKED) {
+ if (m->u.linked) {
+ m->u.linked->finish(m);
+ m->u.linked = NULL;
}
- m->flags &= ~MOD_UNLOAD;
- if (m->flags & MOD_INIT_B) {
- if (m->flags & MOD_LINKED) {
- if (m->u.linked) {
- m->u.linked->finish(m);
- m->u.linked = NULL;
- }
- } else {
- if (m->u.handle) {
- finish_module(m);
- m->u.handle = NULL;
- }
- }
+ } else {
+ if (m->u.handle) {
+ finish_module(m);
+ m->u.handle = NULL;
}
- if (del && m->deps) {
- /* The module was unloaded delayed, unload all modules *
- * on which it depended. */
- LinkNode n;
-
- for (n = firstnode(m->deps); n; incnode(n)) {
- LinkNode dn = find_module((char *) getdata(n),
- FINDMOD_ALIASP, NULL);
- Module dm;
-
- if (dn && (dm = (Module) getdata(dn)) &&
- (dm->flags & MOD_UNLOAD)) {
- /* See if this is the only module depending on it. */
-
- LinkNode an;
- Module am;
- int du = 1;
-
- for (an = firstnode(modules); du && an; incnode(an)) {
- am = (Module) getdata(an);
- if (am != m && am->deps &&
- ((am->flags & MOD_LINKED) ?
- am->u.linked : am->u.handle)) {
- LinkNode sn;
-
- for (sn = firstnode(am->deps); du && sn;
- incnode(sn)) {
- if (!strcmp((char *) getdata(sn), dm->nam))
- du = 0;
- }
+ }
+
+ if (del && m->deps) {
+ /* The module was unloaded delayed, unload all modules *
+ * on which it depended. */
+ LinkNode n;
+
+ for (n = firstnode(m->deps); n; incnode(n)) {
+ Module dm = find_module((char *) getdata(n),
+ FINDMOD_ALIASP, NULL);
+
+ if (dm &&
+ (dm->node.flags & MOD_UNLOAD)) {
+ /* See if this is the only module depending on it. */
+ Module am;
+ int du = 1, i;
+ /* Scan hash table the hard way */
+ for (i = 0; du && i < modulestab->hsize; i++) {
+ for (am = (Module)modulestab->nodes[i]; du && am;
+ am = (Module)am->node.next) {
+ LinkNode sn;
+ /*
+ * Don't scan the module we're unloading;
+ * ignore if no dependencies.
+ */
+ if (am == m || !am->deps)
+ continue;
+ /* Don't scan if not loaded nor linked */
+ if ((am->node.flags & MOD_LINKED) ?
+ !am->u.linked : !am->u.handle)
+ continue;
+ for (sn = firstnode(am->deps); du && sn;
+ incnode(sn)) {
+ if (!strcmp((char *) getdata(sn),
+ dm->node.nam))
+ du = 0;
}
}
- if (du)
- unload_module(dm, NULL);
}
+ if (du)
+ unload_module(dm);
}
}
- if(!m->deps) {
- if (!node) {
- node = linknodebydatum(modules, m);
- if (!node)
- return 1;
- }
- delete_module(node);
- }
+ }
+ if (m->autoloads && firstnode(m->autoloads)) {
+ /*
+ * Module has autoloadable features. Restore them
+ * so that the module will be reloaded when needed.
+ */
+ autofeatures("zsh", m->node.nam,
+ hlinklist2array(m->autoloads, 0), 0, FEAT_IGNORE);
+ } else if (!m->deps) {
+ delete_module(m);
}
return 0;
}
@@ -2644,32 +2884,35 @@ int
unload_named_module(char *modname, char *nam, int silent)
{
const char *mname;
- LinkNode node;
Module m;
int ret = 0;
- node = find_module(modname, FINDMOD_ALIASP, &mname);
- if (node) {
- LinkNode mn, dn;
- int del = 0;
+ m = find_module(modname, FINDMOD_ALIASP, &mname);
+ if (m) {
+ int i, del = 0;
+ Module dm;
- for (mn = firstnode(modules); mn; incnode(mn)) {
- m = (Module) getdata(mn);
- if (m->deps && m->u.handle)
- for (dn = firstnode(m->deps); dn; incnode(dn))
+ for (i = 0; i < modulestab->hsize; i++) {
+ for (dm = (Module)modulestab->nodes[i]; dm;
+ dm = (Module)dm->node.next) {
+ LinkNode dn;
+ if (!dm->deps || !dm->u.handle)
+ continue;
+ for (dn = firstnode(dm->deps); dn; incnode(dn)) {
if (!strcmp((char *) getdata(dn), mname)) {
- if (m->flags & MOD_UNLOAD)
+ if (dm->node.flags & MOD_UNLOAD)
del = 1;
else {
zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname);
return 1;
}
}
+ }
+ }
}
- m = (Module) getdata(node);
if (del)
m->wrapper++;
- if (unload_module(m, node))
+ if (unload_module(m))
ret = 1;
if (del)
m->wrapper--;
@@ -2687,8 +2930,6 @@ unload_named_module(char *modname, char *nam, int silent)
static int
bin_zmodload_load(char *nam, char **args, Options ops)
{
- LinkNode node;
- Module m;
int ret = 0;
if(OPT_ISSET(ops,'u')) {
/* unload modules */
@@ -2699,19 +2940,9 @@ bin_zmodload_load(char *nam, char **args, Options ops)
return ret;
} else if(!*args) {
/* list modules */
- for (node = firstnode(modules); node; incnode(node)) {
- m = (Module) getdata(node);
- if (m->u.handle && !(m->flags & (MOD_UNLOAD|MOD_ALIAS))) {
- if(OPT_ISSET(ops,'L')) {
- printf("zmodload ");
- if(m->nam[0] == '-')
- fputs("-- ", stdout);
- quotedzputs(m->nam, stdout);
- } else
- nicezputs(m->nam, stdout);
- putchar('\n');
- }
- }
+ scanhashtable(modulestab, 1, 0, MOD_UNLOAD|MOD_ALIAS,
+ modulestab->printnode,
+ OPT_ISSET(ops,'L') ? PRINTMOD_LIST : 0);
return 0;
} else {
/* load modules */
@@ -2729,15 +2960,31 @@ bin_zmodload_load(char *nam, char **args, Options ops)
/**/
static int
-bin_zmodload_features(char *nam, char **args, Options ops)
+bin_zmodload_features(const char *nam, char **args, Options ops)
{
char *modname = *args;
+ if (modname)
+ args++;
+ else if (OPT_ISSET(ops,'L')) {
+ int printflags = PRINTMOD_LIST|PRINTMOD_FEATURES;
+ if (OPT_ISSET(ops,'P')) {
+ zwarnnam(nam, "-P is only allowed with a module name");
+ return 1;
+ }
+ if (OPT_ISSET(ops,'l'))
+ printflags |= PRINTMOD_LISTALL;
+ if (OPT_ISSET(ops,'a'))
+ printflags |= PRINTMOD_AUTO;
+ scanhashtable(modulestab, 1, 0, MOD_ALIAS,
+ modulestab->printnode, printflags);
+ return 0;
+ }
+
if (!modname) {
zwarnnam(nam, "-F requires a module name");
return 1;
}
- args++;
if (OPT_ISSET(ops,'l') || OPT_ISSET(ops,'L') || OPT_ISSET(ops,'e')) {
/*
@@ -2746,32 +2993,74 @@ bin_zmodload_features(char *nam, char **args, Options ops)
* only options turned on.
* With both options, list as zmodload showing options
* to be turned both on and off.
- *
- * TODO: handle -a, list only autoloads.
*/
- LinkNode node;
- Module m = NULL;
+ Module m;
char **features, **fp, **arrset = NULL, **arrp = NULL;
int *enables = NULL, *ep;
char *param = OPT_ARG_SAFE(ops,'P');
- node = find_module(modname, FINDMOD_ALIASP, NULL);
- if (node)
- m = ((Module) getdata(node));
- if (!m || !m->u.handle || (m->flags & MOD_UNLOAD)) {
+ m = find_module(modname, FINDMOD_ALIASP, NULL);
+ if (OPT_ISSET(ops,'a')) {
+ LinkNode ln;
+ /*
+ * If there are no autoloads defined, return status 1.
+ */
+ if (!m || !m->autoloads)
+ return 1;
+ if (OPT_ISSET(ops,'e')) {
+ for (fp = args; *fp; fp++) {
+ char *fstr = *fp;
+ int sense = 1;
+ if (*fstr == '+')
+ fstr++;
+ else if (*fstr == '-') {
+ fstr++;
+ sense = 0;
+ }
+ if ((linknodebystring(m->autoloads, fstr) != NULL) !=
+ sense)
+ return 1;
+ }
+ return 0;
+ }
+ if (param) {
+ arrp = arrset = (char **)zalloc(sizeof(char*) *
+ (countlinknodes(m->autoloads)+1));
+ } else if (OPT_ISSET(ops,'L')) {
+ printf("zmodload -aF %s%c", m->node.nam,
+ m->autoloads && firstnode(m->autoloads) ? ' ' : '\n');
+ arrp = NULL;
+ }
+ for (ln = firstnode(m->autoloads); ln; incnode(ln)) {
+ char *al = (char *)getdata(ln);
+ if (param)
+ *arrp++ = ztrdup(al);
+ else
+ printf("%s%c", al,
+ OPT_ISSET(ops,'L') && nextnode(ln) ? ' ' : '\n');
+ }
+ if (param) {
+ *arrp = NULL;
+ if (!setaparam(param, arrset))
+ return 1;
+ }
+ return 0;
+ }
+ if (!m || !m->u.handle || (m->node.flags & MOD_UNLOAD)) {
if (!OPT_ISSET(ops,'e'))
zwarnnam(nam, "module `%s' is not yet loaded", modname);
return 1;
}
if (features_module(m, &features)) {
if (!OPT_ISSET(ops,'e'))
- zwarnnam(nam, "module `%s' does not support features", m->nam);
+ zwarnnam(nam, "module `%s' does not support features",
+ m->node.nam);
return 1;
}
if (enables_module(m, &enables)) {
/* this shouldn't ever happen, so don't silence this error */
zwarnnam(nam, "error getting enabled features for module `%s'",
- m->nam);
+ m->node.nam);
return 1;
}
for (arrp = args; *arrp; arrp++) {
@@ -2796,14 +3085,14 @@ bin_zmodload_features(char *nam, char **args, Options ops)
}
if (!*fp) {
if (!OPT_ISSET(ops,'e'))
- zwarnnam(nam, "module `%s' has no such feature: %s",
+ zwarnnam(nam, "module `%s' has no such feature: `%s'",
*arrp);
return 1;
}
}
if (OPT_ISSET(ops,'e')) /* yep, everything we want exists */
return 0;
- if (OPT_ISSET(ops,'P')) {
+ if (param) {
int arrlen = 0;
for (fp = features, ep = enables; *fp; fp++, ep++) {
if (OPT_ISSET(ops, 'L') && !OPT_ISSET(ops, 'l') &&
@@ -2826,7 +3115,7 @@ bin_zmodload_features(char *nam, char **args, Options ops)
}
arrp = arrset = zalloc(sizeof(char *) * (arrlen+1));
} else if (OPT_ISSET(ops, 'L'))
- printf("zmodload -F %s ", m->nam);
+ printf("zmodload -F %s ", m->node.nam);
for (fp = features, ep = enables; *fp; fp++, ep++) {
char *onoff;
int term;
@@ -2872,7 +3161,18 @@ 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, modname, args, 0, OPT_ISSET(ops,'i'));
+ /*
+ * With zmodload -aF, we always use the effect of -i.
+ * The thinking is that marking a feature for
+ * autoload is separate from enabling or disabling it.
+ * Arguably we could do this with the zmodload -ab method
+ * but I've kept it there for old time's sake.
+ * The decoupling has meant FEAT_IGNORE/-i also
+ * suppresses an error for attempting to remove an
+ * autoload when the feature is enabled, which used
+ * to be a hard error before.
+ */
+ return autofeatures(nam, modname, args, 0, FEAT_IGNORE);
}
return require_module(modname, args);
@@ -2894,15 +3194,15 @@ bin_zmodload_features(char *nam, char **args, Options ops)
/**/
mod_export char **
-featuresarray(char const *nam, Features f)
+featuresarray(UNUSED(Module m), Features f)
{
int bn_size = f->bn_size, cd_size = f->cd_size;
- int pd_size = f->pd_size, mf_size = f->mf_size;
+ int mf_size = f->mf_size, pd_size = f->pd_size;
int features_size = bn_size + cd_size + pd_size + mf_size + f->n_abstract;
Builtin bnp = f->bn_list;
Conddef cdp = f->cd_list;
- Paramdef pdp = f->pd_list;
MathFunc mfp = f->mf_list;
+ Paramdef pdp = f->pd_list;
char **features = (char **)zhalloc((features_size + 1) * sizeof(char *));
char **featurep = features;
@@ -2913,10 +3213,10 @@ featuresarray(char const *nam, Features f)
cdp->name);
cdp++;
}
- while (pd_size--)
- *featurep++ = dyncat("p:", (pdp++)->name);
while (mf_size--)
*featurep++ = dyncat("f:", (mfp++)->name);
+ while (pd_size--)
+ *featurep++ = dyncat("p:", (pdp++)->name);
features[features_size] = NULL;
return features;
@@ -2929,15 +3229,15 @@ featuresarray(char const *nam, Features f)
*/
/**/
mod_export int *
-getfeatureenables(char const *nam, Features f)
+getfeatureenables(UNUSED(Module m), Features f)
{
int bn_size = f->bn_size, cd_size = f->cd_size;
- int pd_size = f->pd_size, mf_size = f->mf_size;
- int features_size = bn_size + cd_size + pd_size + mf_size + f->n_abstract;
+ int mf_size = f->mf_size, pd_size = f->pd_size;
+ int features_size = bn_size + cd_size + mf_size + pd_size + f->n_abstract;
Builtin bnp = f->bn_list;
Conddef cdp = f->cd_list;
- Paramdef pdp = f->pd_list;
MathFunc mfp = f->mf_list;
+ Paramdef pdp = f->pd_list;
int *enables = zhalloc(sizeof(int) * features_size);
int *enablep = enables;
@@ -2945,10 +3245,10 @@ getfeatureenables(char const *nam, Features f)
*enablep++ = ((bnp++)->node.flags & BINF_ADDED) ? 1 : 0;
while (cd_size--)
*enablep++ = ((cdp++)->flags & CONDF_ADDED) ? 1 : 0;
- while (pd_size--)
- *enablep++ = (pdp++)->pm ? 1 : 0;
while (mf_size--)
*enablep++ = ((mfp++)->flags & MFF_ADDED) ? 1 : 0;
+ while (pd_size--)
+ *enablep++ = (pdp++)->pm ? 1 : 0;
return enables;
}
@@ -2965,32 +3265,32 @@ getfeatureenables(char const *nam, Features f)
/**/
mod_export int
-setfeatureenables(char const *nam, Features f, int *e)
+setfeatureenables(Module m, Features f, int *e)
{
int ret = 0;
if (f->bn_size) {
- if (setbuiltins(nam, f->bn_list, f->bn_size, e))
+ if (setbuiltins(m->node.nam, f->bn_list, f->bn_size, e))
ret = 1;
if (e)
e += f->bn_size;
}
if (f->cd_size) {
- if (setconddefs(nam, f->cd_list, f->cd_size, e))
+ if (setconddefs(m->node.nam, f->cd_list, f->cd_size, e))
ret = 1;
if (e)
e += f->cd_size;
}
+ if (f->mf_size) {
+ if (setmathfuncs(m->node.nam, f->mf_list, f->mf_size, e))
+ ret = 1;
+ }
if (f->pd_size) {
- if (setparamdefs(nam, f->pd_list, f->pd_size, e))
+ if (setparamdefs(m->node.nam, f->pd_list, f->pd_size, e))
ret = 1;
if (e)
e += f->pd_size;
}
- if (f->mf_size) {
- if (setmathfuncs(nam, f->mf_list, f->mf_size, e))
- ret = 1;
- }
return ret;
}
@@ -3001,31 +3301,40 @@ setfeatureenables(char const *nam, Features f, int *e)
/**/
mod_export int
-handlefeatures(char *nam, Features f, int **enables)
+handlefeatures(Module m, Features f, int **enables)
{
if (!enables || *enables)
- return setfeatureenables(nam, f, *enables);
- *enables = getfeatureenables(nam, f);
+ return setfeatureenables(m, f, *enables);
+ *enables = getfeatureenables(m, f);
return 0;
}
/*
* Ensure module "modname" is providing feature with "prefix"
- * and "feature" (e.g. "b:", "limit").
+ * and "feature" (e.g. "b:", "limit"). If feature is NULL,
+ * ensure all features are loaded (used for compatibility
+ * with the pre-feature autoloading behaviour).
*
* This will usually be called from the main shell to handle
* loading of an autoloadable feature.
*
* Returns 0 on success, 1 for error in module, 2 for error
- * setting the feature.
+ * setting the feature. However, this isn't actually all
+ * that useful for testing immediately on an autoload since
+ * it could be a failure to autoload a different feature
+ * from the one we want. We could fix this but it's
+ * possible to test other ways.
*/
/**/
mod_export int
-ensurefeature(char *modname, char *prefix, char *feature)
+ensurefeature(const char *modname, const char *prefix, const char *feature)
{
- char *f = dyncat(prefix, feature);
- char *features[2];
+ char *f, *features[2];
+
+ if (!feature)
+ return require_module(modname, NULL);
+ f = dyncat(prefix, feature);
features[0] = f;
features[1] = NULL;
@@ -3038,28 +3347,38 @@ ensurefeature(char *modname, char *prefix, char *feature)
/**/
int
-autofeatures(char *cmdnam, char *module, char **features, int prefchar,
- int opt_i)
+autofeatures(const char *cmdnam, const char *module, char **features,
+ int prefchar, int defflags)
{
int ret = 0, subret;
- int defflags = opt_i ? AUTOFEAT_IGNORE : 0;
+ Module defm, m;
+ char **modfeatures = NULL;
+ if (module) {
+ defm = (Module)find_module(module,
+ FINDMOD_ALIASP|FINDMOD_CREATE, NULL);
+ if ((defm->node.flags & MOD_LINKED) ? defm->u.linked :
+ defm->u.handle)
+ (void)features_module(defm, &modfeatures);
+ } else
+ defm = NULL;
- while (*features) {
- char *fnam, *typnam;
+ for (; *features; features++) {
+ char *fnam, *typnam, *feature;
int add, fchar, flags = defflags;
autofeaturefn_t fn;
if (prefchar) {
- if (prefchar < 0) {
- add = 0;
- fchar = - prefchar;
- } else {
- add = 1;
- fchar = prefchar;
- }
+ /*
+ * "features" is list of bare features with no
+ * type prefix; prefchar gives type character.
+ */
+ add = 1; /* unless overridden by flag */
+ fchar = prefchar;
fnam = *features;
+ feature = zhalloc(strlen(fnam) + 3);
+ sprintf(feature, "%c:%s", fchar, fnam);
} else {
- char *feature = *features;
+ feature = *features;
if (*feature == '-') {
add = 0;
feature++;
@@ -3073,12 +3392,13 @@ autofeatures(char *cmdnam, char *module, char **features, int prefchar,
zwarnnam(cmdnam, "bad format for autoloadable feature: `%s'",
feature);
ret = 1;
+ continue;
}
fnam = feature + 2;
fchar = feature[0];
}
-
- features++;
+ if (flags & FEAT_REMOVE)
+ add = 0;
switch (fchar) {
case 'b':
@@ -3087,23 +3407,23 @@ autofeatures(char *cmdnam, char *module, char **features, int prefchar,
break;
case 'C':
- flags |= AUTOFEAT_INFIX;
+ flags |= FEAT_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;
+ case 'p':
+ fn = add ? add_autoparam : del_autoparam;
+ typnam = "parameter";
+ break;
+
default:
zwarnnam(cmdnam, "bad autoloadable feature type: `%c'",
fchar);
@@ -3116,10 +3436,91 @@ autofeatures(char *cmdnam, char *module, char **features, int prefchar,
ret = 1;
continue;
}
- subret = fn(module, fnam, flags);
+
+ if (!module) {
+ /*
+ * Traditional un-autoload syntax doesn't tell us
+ * which module this came from.
+ */
+ int i;
+ for (i = 0, m = NULL; !m && i < modulestab->hsize; i++) {
+ for (m = (Module)modulestab->nodes[i]; m;
+ m = (Module)m->node.next) {
+ if (m->autoloads &&
+ linknodebystring(m->autoloads, feature))
+ break;
+ }
+ }
+ if (!m) {
+ if (!(flags & FEAT_IGNORE)) {
+ ret = 1;
+ zwarnnam(cmdnam, "%s: no such %s", fnam, typnam);
+ }
+ continue;
+ }
+ } else
+ m = defm;
+
+ subret = 0;
+ if (add) {
+ char **ptr;
+ if (modfeatures) {
+ /*
+ * If the module is already available, check that
+ * it does in fact provide the necessary feature.
+ */
+ for (ptr = modfeatures; *ptr; ptr++)
+ if (!strcmp(*ptr, feature))
+ break;
+ if (!*ptr) {
+ zwarnnam(cmdnam, "module `%s' has no such feature: `%s'",
+ m->node.nam, feature);
+ ret = 1;
+ continue;
+ }
+ }
+ if (!m->autoloads) {
+ m->autoloads = znewlinklist();
+ zaddlinknode(m->autoloads, ztrdup(feature));
+ } else {
+ /* Insert in lexical order */
+ LinkNode ln, prev = (LinkNode)m->autoloads;
+ while ((ln = nextnode(prev))) {
+ int cmp = strcmp(feature, (char *)getdata(ln));
+ if (cmp == 0) {
+ /* Already there. Never an error. */
+ break;
+ }
+ if (cmp < 0) {
+ zinsertlinknode(m->autoloads, prev,
+ ztrdup(feature));
+ break;
+ }
+ prev = ln;
+ }
+ if (!ln)
+ zaddlinknode(m->autoloads, ztrdup(feature));
+ }
+ } else if (m->autoloads) {
+ LinkNode ln;
+ if ((ln = linknodebystring(m->autoloads, feature)))
+ zsfree((char *)remnode(m->autoloads, ln));
+ else {
+ /*
+ * With -i (or zmodload -Fa), removing an autoload
+ * that's not there is not an error.
+ */
+ subret = (flags & FEAT_IGNORE) ? -2 : 2;
+ }
+ }
+
+ if (subret == 0)
+ subret = fn(module, fnam, flags);
if (subret != 0) {
- ret = 1;
+ /* -2 indicates not an error, just skip running fn() */
+ if (subret != -2)
+ ret = 1;
switch (subret) {
case 1:
zwarnnam(cmdnam, "failed to add %s `%s'", typnam, fnam);
diff --git a/Src/params.c b/Src/params.c
index 5609437a2..46da87580 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -411,7 +411,7 @@ newparamtable(int size, char const *name)
/**/
static HashNode
-getparamnode(HashTable ht, char *nam)
+getparamnode(HashTable ht, const char *nam)
{
HashNode hn = gethashnode2(ht, nam);
Param pm = (Param) hn;
@@ -419,12 +419,16 @@ getparamnode(HashTable ht, char *nam)
if (pm && pm->u.str && (pm->node.flags & PM_AUTOLOAD)) {
char *mn = dupstring(pm->u.str);
- if (ensurefeature(mn, "p:", nam))
- return NULL;
+ (void)ensurefeature(mn, "p:", (pm->node.flags & PM_AUTOALL) ? NULL :
+ nam);
hn = gethashnode2(ht, nam);
- if (((Param) hn) == pm && (pm->node.flags & PM_AUTOLOAD)) {
- pm->node.flags &= ~PM_AUTOLOAD;
- zwarnnam(nam, "autoload failed");
+ if (!hn) {
+ /*
+ * This used to be a warning, but surely if we allow
+ * stuff to go ahead with the autoload stub with
+ * no error status we're in for all sorts of mayhem?
+ */
+ zerr("unknown parameter: %s", nam);
}
}
return hn;
diff --git a/Src/string.c b/Src/string.c
index 190ca2d57..2bd1baea3 100644
--- a/Src/string.c
+++ b/Src/string.c
@@ -109,7 +109,7 @@ zhtricat(char const *s1, char const *s2, char const *s3)
/**/
mod_export char *
-dyncat(char *s1, char *s2)
+dyncat(const char *s1, const char *s2)
{
/* This version always uses space from the current heap. */
char *ptr;
diff --git a/Src/zsh.h b/Src/zsh.h
index 4f11b19ad..5354e9663 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -92,6 +92,8 @@ struct mathfunc {
#define MFF_ADDED 2
/* Math function is implemented by a shell function */
#define MFF_USERFUNC 4
+/* When autoloading, enable all features in module */
+#define MFF_AUTOALL 8
#define NUMMATHFUNC(name, func, min, max, id) \
@@ -538,8 +540,12 @@ struct conddef {
char *module; /* module to autoload */
};
-#define CONDF_INFIX 1
-#define CONDF_ADDED 2
+/* Condition is an infix */
+#define CONDF_INFIX 1
+/* Condition has been loaded from library */
+#define CONDF_ADDED 2
+/* When autoloading, enable all features in library */
+#define CONDF_AUTOALL 4
#define CONDDEF(name, flags, handler, min, max, condid) \
{ NULL, name, flags, handler, min, max, condid, NULL }
@@ -928,11 +934,16 @@ struct dirsav {
typedef void *(*VFunc) _((void *));
typedef void (*FreeFunc) _((void *));
-typedef unsigned (*HashFunc) _((char *));
+typedef unsigned (*HashFunc) _((const char *));
typedef void (*TableFunc) _((HashTable));
+/*
+ * Note that this is deliberately "char *", not "const char *",
+ * since the AddNodeFunc is passed a pointer to a string that
+ * will be stored and later freed.
+ */
typedef void (*AddNodeFunc) _((HashTable, char *, void *));
-typedef HashNode (*GetNodeFunc) _((HashTable, char *));
-typedef HashNode (*RemoveNodeFunc) _((HashTable, char *));
+typedef HashNode (*GetNodeFunc) _((HashTable, const char *));
+typedef HashNode (*RemoveNodeFunc) _((HashTable, const char *));
typedef void (*FreeNodeFunc) _((HashNode));
typedef int (*CompareFunc) _((const char *, const char *));
@@ -1152,25 +1163,37 @@ struct builtin {
#define BINF_SKIPDASH (1<<14) /* Treat `-' as argument (maybe `+') */
#define BINF_DASHDASHVALID (1<<15) /* Handle `--' even if SKIPINVALD */
#define BINF_CLEARENV (1<<16) /* new process started with cleared env */
+#define BINF_AUTOALL (1<<17) /* autoload all features at once */
struct module {
- char *nam;
- int flags;
+ struct hashnode node;
union {
void *handle;
Linkedmod linked;
char *alias;
} u;
+ LinkList autoloads;
LinkList deps;
int wrapper;
};
+/* We are in the process of loading the module */
#define MOD_BUSY (1<<0)
+/*
+ * We are in the process of unloading the module.
+ * Note this is not needed to indicate a module is actually
+ * unloaded: for that, the handle (or linked pointer) is set to NULL.
+ */
#define MOD_UNLOAD (1<<1)
+/* We are in the process of setting up the module */
#define MOD_SETUP (1<<2)
+/* Module is statically linked into the main binary */
#define MOD_LINKED (1<<3)
+/* Module setup has been carried out (and module has not been finished) */
#define MOD_INIT_S (1<<4)
+/* Module boot has been carried out (and module has not been finished) */
#define MOD_INIT_B (1<<5)
+/* Module record is an alias */
#define MOD_ALIAS (1<<6)
typedef int (*Module_generic_func) _((void));
@@ -1199,12 +1222,12 @@ struct features {
/* List of conditions provided by the module and the size thereof */
Conddef cd_list;
int cd_size;
- /* List of parameters provided by the module and the size thereof */
- Paramdef pd_list;
- int pd_size;
/* List of math functions provided by the module and the size thereof */
MathFunc mf_list;
int mf_size;
+ /* List of parameters provided by the module and the size thereof */
+ Paramdef pd_list;
+ int pd_size;
/* Number of abstract features */
int n_abstract;
};
@@ -1408,6 +1431,10 @@ struct tieddata {
#define PM_REMOVABLE (1<<26) /* special can be removed from paramtab */
#define PM_AUTOLOAD (1<<27) /* autoloaded from module */
#define PM_NORESTORE (1<<28) /* do not restore value of local special */
+#define PM_AUTOALL (1<<28) /* autoload all features in module
+ * when loading: valid only if PM_AUTOLOAD
+ * is also present.
+ */
#define PM_HASHELEM (1<<29) /* is a hash-element */
#define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */