about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Zsh/Command/_zmodload78
-rw-r--r--Src/cond.c7
-rw-r--r--Src/exec.c9
-rw-r--r--Src/module.c23
-rw-r--r--Src/params.c2
6 files changed, 85 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 70974d76b..d8a5342ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2007-05-29  Peter Stephenson  <pws@csr.com>
 
+	* 23485: Completion/Zsh/Command/_zmodload, Src/cond.c,
+	Src/exec.c, Src/module.c, Src/params.c: completion for
+	zmodload -F; autoloading now requests a specific feature
+	from a module.
+
 	* 23482: Src/Modules/tcp.c, Src/Zle/complete.c: more typos.
 
 	* unposted: Doc/Zsh/mod_stat.yo: typo.
diff --git a/Completion/Zsh/Command/_zmodload b/Completion/Zsh/Command/_zmodload
index 02dce45b3..c11cf18eb 100644
--- a/Completion/Zsh/Command/_zmodload
+++ b/Completion/Zsh/Command/_zmodload
@@ -1,48 +1,70 @@
 #compdef zmodload
 
-local suf comp state line expl curcontext="$curcontext" ret=1
+local suf comp state line expl curcontext="$curcontext" ret=1 NORMARG
 typeset -A opt_args
 suf=()
 
-_arguments -C -A "-*" -s \
-  '(-d -e)-i[suppress error if command would do nothing]' \
+_arguments -n -C -A "-*" -s \
+  '(-i -u -d -a -b -c -I -p -f -e)-A[create module aliases]' \
   '-u[unload module]' \
-  '(-i)-d[list or specify module dependencies]' \
   '(-e)-a[autoload module]' \
   '(-c -I -p -f)-b[autoload module for builtins]' \
   '(-b -I -p -f)-c[autoload module for condition codes]' \
-  '(-b -c -p -f)-I[define infix condition names]' \
-  '(-b -c -I -f)-p[autoload module for parameters]' \
-  '(-b -c -I -p)-f[autoload module for math functions]' \
+  '(-i)-d[list or specify module dependencies]' \
   '(-i -u -d -a -b -c -p -f -L -A)-e[test if modules are loaded]' \
+  '(-b -c -I -p)-f[autoload module for math functions]' \
+  '(-u -b -c -p -f -A)-F[handle features]' \
+  '(-d -e)-i[suppress error if command would do nothing]' \
+  '(-b -c -p -f)-I[define infix condition names]' \
+  '(-u -b -c -p -f -A)-l[list features]' \
   '(-e -u)-L[output in the form of calls to zmodload]' \
-  '(-i -u -d -a -b -c -I -p -f -e)-A[create module aliases]' \
+  '(-b -c -I -f)-p[autoload module for parameters]' \
+  '(-u -b -c -p -f -A)-P[array param for features]:array name:_parameters' \
   '*:params:->params' && ret=0
 
 [[ $state = params ]] || return ret
 
 (( $+opt_args[-A] )) && compset -P '*=' || suf=( -S '=' )
 
-comp=( files aliases )
-if (( $+opt_args[-u] )); then
-  if (( $+opt_args[-b] || $+opt_args[-a] )); then
-    comp=( builtins )
+
+if (( $+opt_args[-F] && CURRENT > NORMARG )); then
+  local module=$words[NORMARG]
+  local -a features
+
+  if [[ $modules[$module] != loaded ]]; then
+    _message "features for unloaded module"
   else
-    comp=( loadedmodules aliases )
+    zmodload -lFP features $module
+    if compset -P -; then
+      # only enabled features needed
+      features=(${${features:#-*}##?})
+    elif compset -P +; then
+      # only disabled features needed
+      features=(${${features:#+*}##?})
+    fi
+    _wanted features expl feature compadd -a features
   fi
+else
+  comp=( files aliases )
+  if (( $+opt_args[-u] )); then
+    if (( $+opt_args[-b] || $+opt_args[-a] )); then
+      comp=( builtins )
+    else
+      comp=( loadedmodules aliases )
+    fi
+  fi
+  (( $+opt_args[-a] && CURRENT > 3 )) && comp=( builtins )
+
+  _tags "$comp[@]"
+  while _tags; do
+    _requested builtins expl 'builtin command' \
+      compadd "$@" -k builtins && ret=0
+    _requested loadedmodules expl 'loaded modules' \
+      compadd -k 'modules[(R)loaded]' && ret=0
+    _requested files expl 'module file' \
+      _files -W module_path -/g '*.(dll|s[ol])(:r)' && ret=0
+    _requested aliases expl 'module alias' \
+      compadd "$suf[@]" -k 'modules[(R)alias*]' && ret=0
+  done
+  return ret
 fi
-(( $+opt_args[-a] && CURRENT > 3 )) && comp=( builtins )
-
-_tags "$comp[@]"
-while _tags; do
-  _requested builtins expl 'builtin command' \
-    compadd "$@" -k builtins && ret=0
-  _requested loadedmodules expl 'loaded modules' \
-    compadd -k 'modules[(R)loaded]' && ret=0
-  _requested files expl 'module file' \
-    _files -W module_path -/g '*.(dll|s[ol])(:r)' && ret=0
-  _requested aliases expl 'module alias' \
-    compadd "$suf[@]" -k 'modules[(R)alias*]' && ret=0
-done
-
-return ret
diff --git a/Src/cond.c b/Src/cond.c
index a597587b6..4356e5d66 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -95,15 +95,12 @@ evalcond(Estate state, char *fromtest)
     case COND_REGEX:
 	{
 	    char *modname = isset(REMATCHPCRE) ? "zsh/pcre" : "zsh/regex";
-	    /*
-	     * TODO: we just need to load the appropriate condition.
-	     */
-	    if (load_module_silence(modname, NULL, 1) == 1) {
+	    sprintf(overridename = overridebuf, "-%s-match", modname+4);
+	    if (ensurefeature(modname, "c:", overridename+1)) {
 		zwarnnam(fromtest, "%s not available for regex",
 			 modname);
 		return 2;
 	    }
-	    sprintf(overridename = overridebuf, "-%s-match", modname+4);
 	    ctype = COND_MODI;
 	}
 	/*FALLTHROUGH*/
diff --git a/Src/exec.c b/Src/exec.c
index 751282127..ccba66bf8 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2012,7 +2012,12 @@ execcmd(Estate state, int input, int output, int how, int last1)
 
 		/* autoload the builtin if necessary */
 		if (!((Builtin) hn)->handlerfunc) {
-		    (void)load_module(((Builtin) hn)->optstr, NULL);
+		    /*
+		     * 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));
@@ -2229,7 +2234,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 
 		/* autoload the builtin if necessary */
 		if (!((Builtin) hn)->handlerfunc) {
-		    (void)load_module(((Builtin) hn)->optstr, NULL);
+		    (void)ensurefeature(((Builtin) hn)->optstr, "b:", cmdarg);
 		    hn = builtintab->getnode(builtintab, cmdarg);
 		}
 		break;
diff --git a/Src/module.c b/Src/module.c
index 8f5afca83..a6329850e 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -389,7 +389,7 @@ getconddef(int inf, char *name, int autol)
 	    /* This is a definition for an autoloaded condition, load the *
 	     * module if we haven't tried that already. */
 	    if (f) {
-		(void)load_module_silence(p->module, NULL, 0);
+		(void)ensurefeature(p->module, "c:", name);
 		f = 0;
 		p = NULL;
 	    } else {
@@ -907,7 +907,7 @@ getmathfunc(char *name, int autol)
 
 		removemathfunc(q, p);
 
-		(void)load_module_silence(n, NULL, 0);
+		(void)ensurefeature(n, "f:", name);
 
 		return getmathfunc(name, 0);
 	    }
@@ -2850,7 +2850,7 @@ setfeatureenables(char const *nam, Features f, int *e)
 	ret = 1;
     return ret;
 }
-	    
+
 /**/
 mod_export int
 handlefeatures(char *nam, Features f, int **enables)
@@ -2860,3 +2860,20 @@ handlefeatures(char *nam, Features f, int **enables)
     *enables = getfeatureenables(nam, f);
     return 0;
 }
+
+/*
+ * Ensure module "modname" is providing feature with "prefix"
+ * and "feature" (e.g. "b:", "limit").
+ */
+
+/**/
+mod_export int
+ensurefeature(char *modname, char *prefix, char *feature)
+{
+    char *f = dyncat(prefix, feature);
+    char *features[2];
+
+    features[0] = f;
+    features[1] = NULL;
+    return require_module(NULL, modname, features);
+}
diff --git a/Src/params.c b/Src/params.c
index 31a65811f..128d28e75 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -419,7 +419,7 @@ getparamnode(HashTable ht, char *nam)
     if (pm && pm->u.str && (pm->node.flags & PM_AUTOLOAD)) {
 	char *mn = dupstring(pm->u.str);
 
-	if (load_module(mn, NULL) == 1)
+	if (ensurefeature(mn, "p:", nam))
 	    return NULL;
 	hn = gethashnode2(ht, nam);
 	if (((Param) hn) == pm && (pm->node.flags & PM_AUTOLOAD)) {