summaryrefslogtreecommitdiff
path: root/Src/module.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-05-08 12:07:04 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-05-08 12:07:04 +0000
commitfbfbc7636ffefd65884c3010d9529fc456b7820f (patch)
tree5f208a510b931bedc0e3b24f625378c7aa609b7b /Src/module.c
parent16c03b4cbf467b53840f8dcac0e8354f0eab880d (diff)
downloadzsh-fbfbc7636ffefd65884c3010d9529fc456b7820f.tar.gz
zsh-fbfbc7636ffefd65884c3010d9529fc456b7820f.zip
24980: zmodload -mF
Diffstat (limited to 'Src/module.c')
-rw-r--r--Src/module.c136
1 files changed, 96 insertions, 40 deletions
diff --git a/Src/module.c b/Src/module.c
index a89010d74..c4fb95c78 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -1967,7 +1967,7 @@ finish_module(Module m)
/**/
static int
-do_module_features(Module m, char **enablesstr, int flags)
+do_module_features(Module m, Feature_enables enablesarr, int flags)
{
char **features;
int ret = 0;
@@ -2019,19 +2019,26 @@ do_module_features(Module m, char **enablesstr, int flags)
(void)autofeatures(NULL, m->node.nam, arg, 0,
FEAT_IGNORE|FEAT_REMOVE);
/*
- * don't want to try to enable *that*...
+ * 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)) {
+ if (enablesarr) {
+ Feature_enables fep;
+ for (fep = enablesarr; fep->str; fep++) {
+ char *str = fep->str;
+ if (*str == '+' || *str == '-')
+ str++;
+ if (fep->pat ? pattry(fep->pat, al) :
+ !strcmp(al, str)) {
/* can't enable it after all, so return 1 */
ret = 1;
- while (*ptr) {
- *ptr = ptr[1];
- ptr++;
+ while (fep->str) {
+ fep->str = fep[1].str;
+ fep->pat = fep[1].pat;
+ fep++;
}
- break;
+ if (!fep->pat)
+ break;
}
}
}
@@ -2039,11 +2046,11 @@ do_module_features(Module m, char **enablesstr, int flags)
}
}
- if (enablesstr) {
- char **ep;
- for (ep = enablesstr; *ep; ep++) {
- char **fp, *esp = *ep;
- int on = 1;
+ if (enablesarr) {
+ Feature_enables fep;
+ for (fep = enablesarr; fep->str; fep++) {
+ char **fp, *esp = fep->str;
+ int on = 1, found = 0;
if (*esp == '+')
esp++;
else if (*esp == '-') {
@@ -2051,13 +2058,17 @@ do_module_features(Module m, char **enablesstr, int flags)
esp++;
}
for (fp = features; *fp; fp++)
- if (!strcmp(*fp, esp)) {
+ if (fep->pat ? pattry(fep->pat, *fp) : !strcmp(*fp, esp)) {
enables[fp - features] = on;
- break;
+ found++;
+ if (!fep->pat)
+ break;
}
- if (!*fp) {
+ if (!found) {
if (!(flags & FEAT_IGNORE))
- zwarn("module `%s' has no such feature: `%s'",
+ zwarn(fep->pat ?
+ "module `%s' has no feature matching: `%s'" :
+ "module `%s' has no such feature: `%s'",
m->node.nam, esp);
return 1;
}
@@ -2075,7 +2086,7 @@ do_module_features(Module m, char **enablesstr, int flags)
if (enables_module(m, &enables))
return 2;
- } else if (enablesstr) {
+ } else if (enablesarr) {
if (!(flags & FEAT_IGNORE))
zwarn("module `%s' does not support features", m->node.nam);
return 1;
@@ -2097,9 +2108,9 @@ do_module_features(Module m, char **enablesstr, int flags)
/**/
static int
-do_boot_module(Module m, char **enablesstr, int silent)
+do_boot_module(Module m, Feature_enables enablesarr, int silent)
{
- int ret = do_module_features(m, enablesstr,
+ int ret = do_module_features(m, enablesarr,
silent ? FEAT_IGNORE|FEAT_CHECKAUTO :
FEAT_CHECKAUTO);
@@ -2159,7 +2170,7 @@ modname_ok(char const *p)
/**/
mod_export int
-load_module(char const *name, char **enablesstr, int silent)
+load_module(char const *name, Feature_enables enablesarr, int silent)
{
Module m;
void *handle = NULL;
@@ -2194,7 +2205,7 @@ load_module(char const *name, char **enablesstr, int silent)
modulestab->addnode(modulestab, ztrdup(name), m);
if ((set = setup_module(m)) ||
- (bootret = do_boot_module(m, enablesstr, silent)) == 1) {
+ (bootret = do_boot_module(m, enablesarr, silent)) == 1) {
if (!set)
do_cleanup_module(m);
finish_module(m);
@@ -2263,7 +2274,7 @@ load_module(char const *name, char **enablesstr, int silent)
m->node.flags |= MOD_INIT_S;
}
m->node.flags |= MOD_SETUP;
- if ((bootret = do_boot_module(m, enablesstr, silent)) == 1) {
+ if ((bootret = do_boot_module(m, enablesarr, silent)) == 1) {
do_cleanup_module(m);
finish_module(m);
if (m->node.flags & MOD_LINKED)
@@ -2301,7 +2312,7 @@ load_module(char const *name, char **enablesstr, int silent)
/**/
mod_export int
-require_module(const char *module, char **features)
+require_module(const char *module, Feature_enables features)
{
Module m = NULL;
int ret = 0;
@@ -2962,7 +2973,10 @@ bin_zmodload_load(char *nam, char **args, Options ops)
static int
bin_zmodload_features(const char *nam, char **args, Options ops)
{
+ int iarg;
char *modname = *args;
+ Patprog *patprogs;
+ Feature_enables features, fep;
if (modname)
args++;
@@ -2986,6 +3000,23 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
return 1;
}
+ if (OPT_ISSET(ops,'m')) {
+ char **argp;
+ Patprog *patprogp;
+
+ /* not NULL terminated */
+ patprogp = patprogs =
+ (Patprog *)zhalloc(arrlen(args)*sizeof(Patprog));
+ for (argp = args; *argp; argp++, patprogp++) {
+ char *arg = *argp;
+ if (*arg == '+' || *arg == '-')
+ arg++;
+ tokenize(arg);
+ *patprogp = patcompile(arg, 0, 0);
+ }
+ } else
+ patprogs = NULL;
+
if (OPT_ISSET(ops,'l') || OPT_ISSET(ops,'L') || OPT_ISSET(ops,'e')) {
/*
* With option 'l', list all features one per line with + or -.
@@ -3063,9 +3094,9 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
m->node.nam);
return 1;
}
- for (arrp = args; *arrp; arrp++) {
+ for (arrp = args, iarg = 0; *arrp; arrp++, iarg++) {
char *arg = *arrp;
- int on;
+ int on, found = 0;
if (*arg == '-') {
on = 0;
arg++;
@@ -3075,17 +3106,22 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
} else
on = -1;
for (fp = features, ep = enables; *fp; fp++, ep++) {
- if (!strcmp(arg, *fp)) {
+ if (patprogs ? pattry(patprogs[iarg], *fp) :
+ !strcmp(arg, *fp)) {
/* for -e, check given state, if any */
if (OPT_ISSET(ops,'e') && on != -1 &&
on != (*ep & 1))
return 1;
- break;
+ found++;
+ if (!patprogs)
+ break;
}
}
- if (!*fp) {
+ if (!found) {
if (!OPT_ISSET(ops,'e'))
- zwarnnam(nam, "module `%s' has no such feature: `%s'",
+ zwarnnam(nam, patprogs ?
+ "module `%s' has no feature matching: `%s'" :
+ "module `%s' has no such feature: `%s'",
*arrp);
return 1;
}
@@ -3100,12 +3136,13 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
continue;
if (*args) {
char **argp;
- for (argp = args; *argp; argp++) {
+ for (argp = args, iarg = 0; *argp; argp++, iarg++) {
char *arg = *argp;
/* ignore +/- for consistency */
if (*arg == '+' || *arg == '-')
arg++;
- if (!strcmp(*fp, arg))
+ if (patprogs ? pattry(patprogs[iarg], *fp) :
+ !strcmp(*fp, arg))
break;
}
if (!*argp)
@@ -3121,11 +3158,12 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
int term;
if (*args) {
char **argp;
- for (argp = args; *argp; argp++) {
+ for (argp = args, iarg = 0; *argp; argp++, iarg++) {
char *arg = *argp;
if (*arg == '+' || *arg == '-')
arg++;
- if (!strcmp(*fp, *argp))
+ if (patprogs ? pattry(patprogs[iarg], *fp) :
+ !strcmp(*fp, *argp))
break;
}
if (!*argp)
@@ -3161,6 +3199,10 @@ bin_zmodload_features(const 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')) {
+ if (OPT_ISSET(ops,'m')) {
+ zwarnnam(nam, "-m cannot be used with -a");
+ return 1;
+ }
/*
* With zmodload -aF, we always use the effect of -i.
* The thinking is that marking a feature for
@@ -3175,7 +3217,18 @@ bin_zmodload_features(const char *nam, char **args, Options ops)
return autofeatures(nam, modname, args, 0, FEAT_IGNORE);
}
- return require_module(modname, args);
+ fep = features =
+ (Feature_enables)zhalloc((arrlen(args)+1)*sizeof(*fep));
+
+ while (*args) {
+ fep->str = *args++;
+ fep->pat = patprogs ? *patprogs++ : NULL;
+ fep++;
+ }
+ fep->str = NULL;
+ fep->pat = NULL;
+
+ return require_module(modname, features);
}
@@ -3330,14 +3383,17 @@ handlefeatures(Module m, Features f, int **enables)
mod_export int
ensurefeature(const char *modname, const char *prefix, const char *feature)
{
- char *f, *features[2];
+ char *f;
+ struct feature_enables features[2];
if (!feature)
return require_module(modname, NULL);
f = dyncat(prefix, feature);
- features[0] = f;
- features[1] = NULL;
+ features[0].str = f;
+ features[0].pat = NULL;
+ features[1].str = NULL;
+ features[1].pat = NULL;
return require_module(modname, features);
}
@@ -3435,7 +3491,7 @@ autofeatures(const char *cmdnam, const char *module, char **features,
zwarnnam(cmdnam, "%s: `/' is illegal in a %s", fnam, typnam);
ret = 1;
continue;
- }
+ }
if (!module) {
/*