Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: module non-loading



This patch tries to make modules behave the same independent of the
way they are made available: linked in or dynamically loaded.

User-visible changes:

- There is only one zmodload builtin now, behaving the same in shells
  with and without dynamic loading.
- This also means that even if you have selected module to be linked
  in, you have to cal zmodload to get at the builtins and others tuff
  defined by the module. Unless the module defined theses things to be 
  autoloaded, then it will happen automatically as usual.
- The -e option of zmodload now only prints the `loaded' modules.
  I.e. the same ones shown by zmodload without arguments. In other
  words: -e is now only useful for testing if a modules is available.
  Maybe we should remove that option altogether and just use -i for
  such things?


Internal changes:

- DYNAMIC is used only in module.c now. And especially modules should
  not use it (nor MODULE), to ensure that they behave the same when
  loaded or linked in.
- Linked-in modules still call register_module() but that now also
  gives the four setup/cleanup functions. These are stored in a list
  and called directly when needed (instead of trying to do some symbol 
  lookup or whatever).
- The functions for the zsh module are now explicitly called in init.c.
- The cleanup and finish functions of all modules that were used are
  called when the shell exits. I've put that in a function that is
  called from zexit(), hope that's the right place.
  this means that modules can now rely on these functions being
  called, so if they have to ensure that something is done when the
  shell exits or the module is unloaded, they can now be sure that it
  will be executed.


Open questions:
- The zshxmods.h stuff may need some more looking-after. Maybe we can
  even remove it altogether?
- Of course I couldn't test it on systems like AIX and HPUX where we
  have special module-loading code. But I *did* test it with
  dynamically loaded and linked in modules both in a shell with and
  one without dynamic loading.


Even if it may not be perfect yet, I hope it's a step in the right
direction.


Bye
 Sven

diff -u -r oldsrc/Builtins/rlimits.c Src/Builtins/rlimits.c
--- oldsrc/Builtins/rlimits.c	Wed Nov 24 12:58:52 1999
+++ Src/Builtins/rlimits.c	Wed Nov 24 13:39:15 1999
@@ -637,8 +637,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_rlimits(Module m)
@@ -653,5 +651,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Builtins/sched.c Src/Builtins/sched.c
--- oldsrc/Builtins/sched.c	Wed Nov 24 12:58:52 1999
+++ Src/Builtins/sched.c	Wed Nov 24 13:39:32 1999
@@ -200,8 +200,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_sched(Module m)
@@ -224,5 +222,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/cap.c Src/Modules/cap.c
--- oldsrc/Modules/cap.c	Wed Nov 24 12:58:37 1999
+++ Src/Modules/cap.c	Wed Nov 24 13:39:47 1999
@@ -136,8 +136,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_cap(Module m)
@@ -152,5 +150,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/clone.c Src/Modules/clone.c
--- oldsrc/Modules/clone.c	Wed Nov 24 12:58:37 1999
+++ Src/Modules/clone.c	Wed Nov 24 13:39:56 1999
@@ -110,8 +110,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_clone(Module m)
@@ -126,5 +124,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/example.c Src/Modules/example.c
--- oldsrc/Modules/example.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/example.c	Wed Nov 24 13:40:10 1999
@@ -212,8 +212,6 @@
 	     !addwrapper(m, wrapper));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_example(Module m)
@@ -234,5 +232,3 @@
     fflush(stdout);
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/files.c Src/Modules/files.c
--- oldsrc/Modules/files.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/files.c	Wed Nov 24 13:40:22 1999
@@ -523,8 +523,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_files(Module m)
@@ -539,5 +537,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/mapfile.c Src/Modules/mapfile.c
--- oldsrc/Modules/mapfile.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/mapfile.c	Wed Nov 24 13:40:45 1999
@@ -346,8 +346,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_mapfile(Module m)
@@ -370,5 +368,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/mathfunc.c Src/Modules/mathfunc.c
--- oldsrc/Modules/mathfunc.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/mathfunc.c	Wed Nov 24 13:41:04 1999
@@ -462,8 +462,6 @@
     return !addmathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_mathfunc(Module m)
@@ -478,5 +476,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/parameter.c Src/Modules/parameter.c
--- oldsrc/Modules/parameter.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/parameter.c	Wed Nov 24 14:48:49 1999
@@ -901,18 +901,12 @@
 	pm->old = NULL;
 	pm->level = 0;
 
-	for (node = firstnode(bltinmodules); node; incnode(node))
-	    if (!strcmp(name, (char *) getdata(node))) {
-		type = "builtin";
-		break;
-	    }
-#ifdef DYNAMIC
 	if (!type) {
 	    Module m;
 
 	    for (node = firstnode(modules); node; incnode(node)) {
 		m = (Module) getdata(node);
-		if (m->handle && !(m->flags & MOD_UNLOAD) &&
+		if (m->u.handle && !(m->flags & MOD_UNLOAD) &&
 		    !strcmp(name, m->nam)) {
 		    type = "loaded";
 		    break;
@@ -937,7 +931,6 @@
 	    if (modpmfound)
 		type = "autoloaded";
 	}
-#endif
 	if (type)
 	    pm->u.str = dupstring(type);
 	else {
@@ -972,16 +965,10 @@
     pm.level = 0;
 
     pm.u.str = dupstring("builtin");
-    for (node = firstnode(bltinmodules); node; incnode(node)) {
-	pm.nam = (char *) getdata(node);
-	addlinknode(done, pm.nam);
-	func((HashNode) &pm, flags);
-    }
-#ifdef DYNAMIC
     pm.u.str = dupstring("loaded");
     for (node = firstnode(modules); node; incnode(node)) {
 	m = (Module) getdata(node);
-	if (m->handle && !(m->flags & MOD_UNLOAD)) {
+	if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
 	    pm.nam = m->nam;
 	    addlinknode(done, pm.nam);
 	    func((HashNode) &pm, flags);
@@ -1012,7 +999,6 @@
 		func((HashNode) &pm, flags);
 	    }
 	}
-#endif
 }
 
 /* Functions for the dirstack special parameter. */
@@ -1919,8 +1905,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_parameter(Module m)
@@ -1949,5 +1933,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/stat.c Src/Modules/stat.c
--- oldsrc/Modules/stat.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/stat.c	Wed Nov 24 13:41:24 1999
@@ -602,8 +602,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_stat(Module m)
@@ -618,5 +616,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Modules/zftp.c Src/Modules/zftp.c
--- oldsrc/Modules/zftp.c	Wed Nov 24 12:58:38 1999
+++ Src/Modules/zftp.c	Wed Nov 24 13:41:52 1999
@@ -3213,8 +3213,6 @@
     return !ret;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_zftp(Module m)
@@ -3249,5 +3247,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/compctl.c Src/Zle/compctl.c
--- oldsrc/Zle/compctl.c	Wed Nov 24 09:03:40 1999
+++ Src/Zle/compctl.c	Wed Nov 24 13:42:09 1999
@@ -3764,8 +3764,6 @@
     return (addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) != 1);
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_compctl(Module m)
@@ -3789,5 +3787,3 @@
     compctlreadptr = fallback_compctlread;
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/complete.c Src/Zle/complete.c
--- oldsrc/Zle/complete.c	Wed Nov 24 09:03:40 1999
+++ Src/Zle/complete.c	Wed Nov 24 15:45:42 1999
@@ -1389,8 +1389,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_complete(Module m)
@@ -1414,7 +1412,8 @@
 int
 finish_complete(Module m)
 {
-    freearray(compwords);
+    if (compwords)
+	freearray(compwords);
     zsfree(compprefix);
     zsfree(compsuffix);
     zsfree(compiprefix);
@@ -1446,5 +1445,3 @@
 
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/complist.c Src/Zle/complist.c
--- oldsrc/Zle/complist.c	Wed Nov 24 09:03:40 1999
+++ Src/Zle/complist.c	Wed Nov 24 13:42:31 1999
@@ -935,8 +935,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_complist(Module m)
@@ -957,5 +955,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/computil.c Src/Zle/computil.c
--- oldsrc/Zle/computil.c	Wed Nov 24 09:03:40 1999
+++ Src/Zle/computil.c	Wed Nov 24 13:42:44 1999
@@ -2837,8 +2837,6 @@
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_computil(Module m)
@@ -2865,5 +2863,3 @@
 
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/deltochar.c Src/Zle/deltochar.c
--- oldsrc/Zle/deltochar.c	Wed Nov 24 09:03:40 1999
+++ Src/Zle/deltochar.c	Wed Nov 24 13:42:55 1999
@@ -98,8 +98,6 @@
     return -1;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_deltochar(Module m)
@@ -115,5 +113,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/Zle/zle_hist.c Src/Zle/zle_hist.c
--- oldsrc/Zle/zle_hist.c	Wed Nov 24 09:03:41 1999
+++ Src/Zle/zle_hist.c	Wed Nov 24 13:43:22 1999
@@ -612,17 +612,11 @@
 static int max_spot = 0;
 
 /**/
-#ifdef MODULE
-
-/**/
 void
 free_isrch_spots(void)
 {
     zfree(isrch_spots, max_spot * sizeof(*isrch_spots));
 }
-
-/**/
-#endif /* MODULE */
 
 /**/
 static void
diff -u -r oldsrc/Zle/zle_keymap.c Src/Zle/zle_keymap.c
--- oldsrc/Zle/zle_keymap.c	Wed Nov 24 09:03:41 1999
+++ Src/Zle/zle_keymap.c	Wed Nov 24 13:43:38 1999
@@ -1000,8 +1000,6 @@
     lastnamed = refthingy(t_undefinedkey);
 }
 
-#ifdef MODULE
-
 /* cleanup entry point (for unloading the zle module) */
 
 /**/
@@ -1012,8 +1010,6 @@
     deletehashtable(keymapnamtab);
     zfree(keybuf, keybufsz);
 }
-
-#endif /* MODULE */
 
 /* Create the default keymaps.  For efficiency reasons, this function   *
  * assigns directly to the km->first array.  It knows that there are no *
diff -u -r oldsrc/Zle/zle_main.c Src/Zle/zle_main.c
--- oldsrc/Zle/zle_main.c	Wed Nov 24 09:03:41 1999
+++ Src/Zle/zle_main.c	Wed Nov 24 13:43:52 1999
@@ -1043,8 +1043,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_zle(Module m)
@@ -1093,5 +1091,3 @@
 
     return 0;
 }
-
-#endif /* MODULE */
diff -u -r oldsrc/Zle/zle_thingy.c Src/Zle/zle_thingy.c
--- oldsrc/Zle/zle_thingy.c	Wed Nov 24 09:03:42 1999
+++ Src/Zle/zle_thingy.c	Wed Nov 24 13:36:18 1999
@@ -286,8 +286,6 @@
     return w;
 }
 
-#ifdef DYNAMIC
-
 /* Delete an internal widget provided by a module.  Don't try to delete *
  * a widget from the fixed table -- it would be bad.  (Thanks, Egon.)   */
 
@@ -309,8 +307,6 @@
     }
 }
 
-#endif /* DYNAMIC */
-
 /***************/
 /* zle builtin */
 /***************/
@@ -550,18 +546,10 @@
     Thingy t;
     Widget w, cw;
 
-#ifdef DYNAMIC
     if (!require_module(name, "complete", 0, 0)) {
 	zerrnam(name, "can't load complete module", NULL, 0);
 	return 1;
     }
-#else
-    if (!module_linked("complete")) {
-	zerrnam(name, "complete module not available", NULL, 0);
-	return 1;
-    }
-#endif
-    
     t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1]));
     cw = t->widget;
     unrefthingy(t);
diff -u -r oldsrc/Zle/zleparameter.c Src/Zle/zleparameter.c
--- oldsrc/Zle/zleparameter.c	Wed Nov 24 09:03:42 1999
+++ Src/Zle/zleparameter.c	Wed Nov 24 13:44:04 1999
@@ -230,8 +230,6 @@
     return 0;
 }
 
-#ifdef MODULE
-
 /**/
 int
 cleanup_zleparameter(Module m)
@@ -255,5 +253,3 @@
 {
     return 0;
 }
-
-#endif
diff -u -r oldsrc/builtin.c Src/builtin.c
--- oldsrc/builtin.c	Wed Nov 24 09:03:35 1999
+++ Src/builtin.c	Wed Nov 24 15:59:15 1999
@@ -123,12 +123,7 @@
     BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsw", NULL),
     BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"),
     BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
-
-#ifdef DYNAMIC
     BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcfdipue", NULL),
-#else
-    BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ei", NULL),
-#endif
 };
 
 /****************************************/
@@ -229,14 +224,11 @@
 
     arg = (char *) ugetnode(args);
 
-#ifdef DYNAMIC
     if (!bn->handlerfunc) {
 	zwarnnam(name, "autoload failed", NULL, 0);
 	deletebuiltin(bn->nam);
 	return 1;
     }
-#endif
-
     /* get some information about the command */
     flags = bn->flags;
     optstr = bn->optstr;
@@ -3209,6 +3201,8 @@
 	if (in_exit++ && from_signal) {
 	    LASTALLOC_RETURN;
 	}
+	exit_modules();
+
 	if (isset(MONITOR)) {
 	    /* send SIGHUP to any jobs left running  */
 	    killrunjobs(from_signal);
diff -u -r oldsrc/exec.c Src/exec.c
--- oldsrc/exec.c	Wed Nov 24 09:03:36 1999
+++ Src/exec.c	Wed Nov 24 15:30:44 1999
@@ -1504,13 +1504,12 @@
 	    }
 	    if (!(hn->flags & BINF_PREFIX)) {
 		is_builtin = 1;
-#ifdef DYNAMIC
+
 		/* autoload the builtin if necessary */
 		if (!((Builtin) hn)->handlerfunc) {
 		    load_module(((Builtin) hn)->optstr);
 		    hn = builtintab->getnode(builtintab, cmdarg);
 		}
-#endif
 		assign = (hn->flags & BINF_MAGICEQUALS);
 		break;
 	    }
@@ -1619,13 +1618,12 @@
 	    }
 	    if (!(hn->flags & BINF_PREFIX)) {
 		is_builtin = 1;
-#ifdef DYNAMIC
+
 		/* autoload the builtin if necessary */
 		if (!((Builtin) hn)->handlerfunc) {
 		    load_module(((Builtin) hn)->optstr);
 		    hn = builtintab->getnode(builtintab, cmdarg);
 		}
-#endif
 		break;
 	    }
 	    cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
@@ -3072,11 +3070,11 @@
 	wrap->module->wrapper++;
 	cont = wrap->handler(list, wrap->next, name);
 	wrap->module->wrapper--;
-#ifdef DYNAMIC
+
 	if (!wrap->module->wrapper &&
 	    (wrap->module->flags & MOD_UNLOAD))
-	    unload_module(wrap->module, NULL);
-#endif
+	    unload_module(wrap->module, NULL, 0);
+
 	if (!cont)
 	    return;
 	wrap = wrap->next;
diff -u -r oldsrc/init.c Src/init.c
--- oldsrc/init.c	Wed Nov 24 09:03:36 1999
+++ Src/init.c	Wed Nov 24 16:38:01 1999
@@ -599,11 +599,9 @@
     mailpath = mkarray(NULL);
     watch    = mkarray(NULL);
     psvar    = mkarray(NULL);
-#ifdef DYNAMIC
     module_path = mkarray(ztrdup(MODULE_DIR));
     modules = newlinklist();
-#endif
-    bltinmodules = newlinklist();
+    linkedmodules = newlinklist();
 
     /* Set default prompts */
     if(unset(INTERACTIVE)) {
@@ -940,9 +938,10 @@
 void
 init_bltinmods(void)
 {
-    static struct module mod = { NULL, 0, NULL, NULL };
+
 #include "bltinmods.list"
-    mod.nam = NULL;
+
+    load_module("zsh");
 }
 
 /**/
@@ -969,13 +968,13 @@
 /**/
 ZleVoidFn trashzleptr = noop_function;
 /**/
-ZleVoidFn gotwordptr;
+ZleVoidFn gotwordptr = noop_function;
 /**/
-ZleVoidFn refreshptr;
+ZleVoidFn refreshptr = noop_function;
 /**/
-ZleVoidIntFn spaceinlineptr;
+ZleVoidIntFn spaceinlineptr = noop_function_int;
 /**/
-ZleReadFn zlereadptr;
+ZleReadFn zlereadptr = autoload_zleread;
 
 #else /* !LINKED_XMOD_zle */
 
@@ -989,11 +988,10 @@
 ZleReadFn zlereadptr = fallback_zleread;
 # endif /* !UNLINKED_XMOD_zle */
 
-/**/
-# ifdef UNLINKED_XMOD_zle
+#endif /* !LINKED_XMOD_zle */
 
 /**/
-static unsigned char *
+unsigned char *
 autoload_zleread(char *lp, char *rp, int ha)
 {
     zlereadptr = fallback_zleread;
@@ -1002,9 +1000,6 @@
 }
 
 /**/
-# endif /* UNLINKED_XMOD_zle */
-
-/**/
 unsigned char *
 fallback_zleread(char *lp, char *rp, int ha)
 {
@@ -1016,8 +1011,6 @@
     free(pptbuf);
     return (unsigned char *)shingetline();
 }
-
-#endif /* !LINKED_XMOD_zle */
 
 /* compctl entry point pointers.  Similar to the ZLE ones. */
 
diff -u -r oldsrc/mkbltnmlst.sh Src/mkbltnmlst.sh
--- oldsrc/mkbltnmlst.sh	Wed Nov 24 13:47:28 1999
+++ Src/mkbltnmlst.sh	Wed Nov 24 14:41:43 1999
@@ -4,6 +4,7 @@
 #
 # Written by Andrew Main
 #
+
 srcdir=${srcdir-`echo $0|sed 's%/[^/][^/]*$%%'`}
 test "x$srcdir" = "x$0" && srcdir=.
 test "x$srcdir" = "x"   && srcdir=.
@@ -18,40 +19,32 @@
 
 exec > $1
 
-echo "#ifdef DYNAMIC"
 for x_mod in $x_mods; do
-    case $bin_mods in
-	*" $x_mod "*) ;;
-	*)  echo "/* non-linked-in known module \`$x_mod' */"
-	    eval "loc=\$loc_$x_mod"
-	    unset moddeps autobins autoinfixconds autoprefixconds autoparams
-	    unset automathfuncs
-	    . $srcdir/../$loc/${x_mod}.mdd
-	    for bin in $autobins; do
-		echo "    add_autobin(\"$bin\", \"$x_mod\");"
-	    done
-	    for cond in $autoinfixconds; do
-		echo "    add_autocond(\"$cond\", 1, \"$x_mod\");"
-	    done
-	    for cond in $autoprefixconds; do
-		echo "    add_autocond(\"$cond\", 0, \"$x_mod\");"
-	    done
-	    for param in $autoparams; do
-		echo "    add_autoparam(\"$param\", \"$x_mod\");"
-	    done
-	    for mfunc in $automathfuncs; do
-		echo "    add_automath(\"$mfunc\", \"$x_mod\");"
-	    done
-	    for dep in $moddeps; do
-		case $bin_mods in
-		    *" $dep "*)
-			echo "    /* depends on \`$dep' */" ;;
-		    *)	echo "    add_dep(\"$x_mod\", \"$dep\");" ;;
-		esac
-	    done ;;
-    esac
+    echo "/* non-linked-in known module \`$x_mod' */"
+    eval "loc=\$loc_$x_mod"
+    unset moddeps autobins autoinfixconds autoprefixconds autoparams
+    unset automathfuncs
+    . $srcdir/../$loc/${x_mod}.mdd
+    for bin in $autobins; do
+	echo "    add_autobin(\"$bin\", \"$x_mod\");"
+    done
+    for cond in $autoinfixconds; do
+	echo "    add_autocond(\"$cond\", 1, \"$x_mod\");"
+    done
+    for cond in $autoprefixconds; do
+	echo "    add_autocond(\"$cond\", 0, \"$x_mod\");"
+    done
+    for param in $autoparams; do
+	echo "    add_autoparam(\"$param\", \"$x_mod\");"
+    done
+    for mfunc in $automathfuncs; do
+	echo "    add_automath(\"$mfunc\", \"$x_mod\");"
+    done
+    for dep in $moddeps; do
+	echo "    add_dep(\"$x_mod\", \"$dep\");"
+    done
 done
-echo "#endif /* DYNAMIC */"
+
 echo
 done_mods=" "
 for bin_mod in $bin_mods; do
@@ -68,6 +61,15 @@
 		exit 1 ;;
 	esac
     done
-    echo "    register_module(mod.nam = \"$bin_mod\"); setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
+    echo "    {"
+    echo "        extern int setup_${bin_mod} _((Module));"
+    echo "        extern int boot_${bin_mod} _((Module));"
+    echo "        extern int cleanup_${bin_mod} _((Module));"
+    echo "        extern int finish_${bin_mod} _((Module));"
+    echo
+    echo "        register_module(\"$bin_mod\","
+    echo "                        setup_${bin_mod}, boot_${bin_mod},"
+    echo "                        cleanup_${bin_mod}, finish_${bin_mod});"
+    echo "    }"
     done_mods="$done_mods$bin_mod "
 done
diff -u -r oldsrc/module.c Src/module.c
--- oldsrc/module.c	Wed Nov 24 09:41:48 1999
+++ Src/module.c	Wed Nov 24 16:25:29 1999
@@ -30,10 +30,10 @@
 #include "zsh.mdh"
 #include "module.pro"
 
-/* List of builtin modules. */
+/* List of linked-in modules. */
 
 /**/
-LinkList bltinmodules;
+LinkList linkedmodules;
 
 
 /* The `zsh' module contains all the base code that can't actually be built *
@@ -54,30 +54,55 @@
     return 0;
 }
 
+/**/
+int
+cleanup_zsh(Module m)
+{
+    return 0;
+}
+
+/**/
+int
+finish_zsh(Module m)
+{
+    return 0;
+}
+
 /* This registers a builtin module.                                   */
 
 /**/
 void
-register_module(char *n)
+register_module(char *n, Module_func setup, Module_func boot,
+		Module_func cleanup, Module_func finish)
 {
+    Linkedmod m;
+
     PERMALLOC {
-	addlinknode(bltinmodules, n);
+	m = (Linkedmod) zalloc(sizeof(*m));
+
+	m->name = ztrdup(n);
+	m->setup = setup;
+	m->boot = boot;
+	m->cleanup = cleanup;
+	m->finish = finish;
+
+	addlinknode(linkedmodules, m);
     } LASTALLOC;
 }
 
 /* Check if a module is linked in. */
 
 /**/
-int
-module_linked(char *name)
+Linkedmod
+module_linked(char const *name)
 {
     LinkNode node;
 
-    for (node = firstnode(bltinmodules); node; incnode(node))
-	if (!strcmp((char *) getdata(node), name))
-	    return 1;
+    for (node = firstnode(linkedmodules); node; incnode(node))
+	if (!strcmp(((Linkedmod) getdata(node))->name, name))
+	    return (Linkedmod) getdata(node);
 
-    return 0;
+    return NULL;
 }
 
 /* addbuiltin() can be used to add a new builtin.  It returns zero on *
@@ -157,9 +182,6 @@
     return 0;
 }
 
-/**/
-#ifdef DYNAMIC
-
 /* $module_path ($MODULE_PATH) */
 
 /**/
@@ -255,6 +277,9 @@
 }
 
 /**/
+#ifdef DYNAMIC
+
+/**/
 #ifdef AIXDYNAMIC
 
 #include <sys/ldr.h>
@@ -271,8 +296,8 @@
 	int err = loadbind(0, (void *) addbuiltin, ret);
 	for (node = firstnode(modules); !err && node; incnode(node)) {
 	    Module m = (Module) getdata(node);
-	    if (m->handle)
-		err |= loadbind(0, m->handle, ret);
+	    if (m->u.handle)
+		err |= loadbind(0, m->u.handle, ret);
 	}
 
 	if (err) {
@@ -361,8 +386,6 @@
 # define RTLD_GLOBAL 0
 #endif
 
-typedef int (*Module_func) _((Module));
-
 /**/
 static void *
 try_load_module(char const *name)
@@ -415,6 +438,19 @@
 }
 
 /**/
+#else /* !DYNAMIC */
+
+/**/
+static void *
+do_load_module(char const *name)
+{
+    return NULL;
+}
+
+/**/
+#endif /* !DYNAMIC */
+
+/**/
 static LinkNode
 find_module(const char *name)
 {
@@ -430,34 +466,37 @@
 }
 
 /**/
+#ifdef DYNAMIC
+
+/**/
 #ifdef AIXDYNAMIC
 
 /**/
 static int
-setup_module(Module m)
+dyn_setup_module(Module m)
 {
-    return ((int (*)_((int,Module))) m->handle)(0, m);
+    return ((int (*)_((int,Module))) m->u.handle)(0, m);
 }
 
 /**/
 static int
-init_module(Module m)
+dyn_boot_module(Module m)
 {
-    return ((int (*)_((int,Module))) m->handle)(1, m);
+    return ((int (*)_((int,Module))) m->u.handle)(1, m);
 }
 
 /**/
 static int
-cleanup_module(Module m)
+dyn_cleanup_module(Module m)
 {
-    return ((int (*)_((int,Module))) m->handle)(2, m);
+    return ((int (*)_((int,Module))) m->u.handle)(2, m);
 }
 
 /**/
 static int
-finish_module(Module m)
+dyn_finish_module(Module m)
 {
-    return ((int (*)_((int,Module))) m->handle)(3, m);
+    return ((int (*)_((int,Module))) m->u.handle)(3, m);
 }
 
 /**/
@@ -480,19 +519,19 @@
     if ((t = strrchr(s, '.')))
 	*t = '\0';
 #ifdef DYNAMIC_NAME_CLASH_OK
-    fn = (Module_func) dlsym(m->handle, name);
+    fn = (Module_func) dlsym(m->u.handle, name);
 #else /* !DYNAMIC_NAME_CLASH_OK */
     if (strlen(s) + 6 > PATH_MAX)
 	return NULL;
     sprintf(buf, name_s, s);
-    fn = (Module_func) dlsym(m->handle, buf);
+    fn = (Module_func) dlsym(m->u.handle, buf);
 #endif /* !DYNAMIC_NAME_CLASH_OK */
     return fn;
 }
 
 /**/
 static int
-setup_module(Module m)
+dyn_setup_module(Module m)
 {
     Module_func fn = module_func(m, STR_SETUP, STR_SETUP_S);
 
@@ -504,7 +543,7 @@
 
 /**/
 static int
-init_module(Module m)
+dyn_boot_module(Module m)
 {
     Module_func fn = module_func(m, STR_BOOT, STR_BOOT_S);
 
@@ -516,7 +555,7 @@
 
 /**/
 static int
-cleanup_module(Module m)
+dyn_cleanup_module(Module m)
 {
     Module_func fn = module_func(m, STR_CLEANUP, STR_CLEANUP_S);
 
@@ -531,7 +570,7 @@
 
 /**/
 static int
-finish_module(Module m)
+dyn_finish_module(Module m)
 {
     Module_func fn = module_func(m, STR_FINISH, STR_FINISH_S);
     int r;
@@ -542,7 +581,7 @@
 	zwarnnam(m->nam, "no finish function", NULL, 0);
 	r = 1;
     }
-    dlclose(m->handle);
+    dlclose(m->u.handle);
     return r;
 }
 
@@ -550,34 +589,107 @@
 #endif /* !AIXDYNAMIC */
 
 /**/
+static int
+setup_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ?
+	    (m->u.linked->setup)(m) : dyn_setup_module(m));
+}
+
+/**/
+static int
+boot_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ?
+	    (m->u.linked->boot)(m) : dyn_boot_module(m));
+}
+
+/**/
+static int
+cleanup_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ?
+	    (m->u.linked->cleanup)(m) : dyn_cleanup_module(m));
+}
+
+/**/
+static int
+finish_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ?
+	    (m->u.linked->finish)(m) : dyn_finish_module(m));
+}
+
+/**/
+#else /* !DYNAMIC */
+
+/**/
+static int
+setup_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ? (m->u.linked->setup)(m) : 1);
+}
+
+/**/
+static int
+boot_module(Module m)
+{
+    return ((m->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);
+}
+
+/**/
+static int
+finish_module(Module m)
+{
+    return ((m->flags & MOD_LINKED) ? (m->u.linked->finish)(m) : 1);
+}
+
+/**/
+#endif /* !DYNAMIC */
+
+/**/
 int
 load_module(char const *name)
 {
     Module m;
-    void *handle;
+    void *handle = NULL;
+    Linkedmod linked;
     LinkNode node, n;
-
-    if (module_linked(name))
-	return 1;
+    int set;
 
     if (!(node = find_module(name))) {
-	if (!(handle = do_load_module(name)))
-	    return NULL;
+	if (!(linked = module_linked(name)) &&
+	    !(handle = do_load_module(name)))
+	    return 0;
 	m = zcalloc(sizeof(*m));
 	m->nam = ztrdup(name);
-	m->handle = handle;
-	m->flags |= MOD_SETUP;
+	if (handle) {
+	    m->u.handle = handle;
+	    m->flags |= MOD_SETUP;
+	} else {
+	    m->u.linked = linked;
+	    m->flags |= MOD_SETUP | MOD_LINKED;
+	}
 	PERMALLOC {
 	    node = addlinknode(modules, m);
 	} LASTALLOC;
-	if (setup_module(m) || init_module(m)) {
-	    finish_module(m);
+	if ((set = setup_module(m)) || boot_module(m)) {
+	    if (!set)
+		finish_module(m);
 	    remnode(modules, node);
 	    zsfree(m->nam);
 	    zfree(m, sizeof(*m));
 	    m->flags &= ~MOD_SETUP;
-	    return NULL;
+	    return 0;
 	}
+	m->flags |= MOD_INIT_S | MOD_INIT_B;
 	m->flags &= ~MOD_SETUP;
 	return 1;
     } 
@@ -586,7 +698,7 @@
 	return 1;
     if (m->flags & MOD_UNLOAD)
 	m->flags &= ~MOD_UNLOAD;
-    else if (m->handle)
+    else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle)
 	return 1;
     if (m->flags & MOD_BUSY) {
 	zerr("circular dependencies for module %s", name, 0);
@@ -600,24 +712,39 @@
 		return 0;
 	    }
     m->flags &= ~MOD_BUSY;
-    if (!m->handle) {
-	if (!(m->handle = do_load_module(name)))
+    if (!m->u.handle) {
+	handle = NULL;
+	if (!(linked = module_linked(name)) &&
+	    !(handle = do_load_module(name)))
 	    return 0;
-	m->flags |= MOD_SETUP;
+	if (handle) {
+	    m->u.handle = handle;
+	    m->flags |= MOD_SETUP;
+	} else {
+	    m->u.linked = linked;
+	    m->flags |= MOD_SETUP | MOD_LINKED;
+	}
 	if (setup_module(m)) {
-	    finish_module(m->handle);
-	    m->handle = NULL;
+	    if (handle)
+		m->u.handle = NULL;
+	    else
+		m->u.linked = NULL;
 	    m->flags &= ~MOD_SETUP;
 	    return 0;
 	}
+	m->flags |= MOD_INIT_S;
     }
     m->flags |= MOD_SETUP;
-    if (init_module(m)) {
-	finish_module(m->handle);
-	m->handle = NULL;
+    if (boot_module(m)) {
+	finish_module(m);
+	if (m->flags & MOD_LINKED)
+	    m->u.linked = NULL;
+	else
+	    m->u.handle = NULL;
 	m->flags &= ~MOD_SETUP;
 	return 0;
     }
+    m->flags |= MOD_INIT_B;
     m->flags &= ~MOD_SETUP;
     return 1;
 }
@@ -638,12 +765,12 @@
     LinkNode node;
 
     /* First see if the module is linked in. */
-    for (node = firstnode(bltinmodules); node; incnode(node)) {
+    for (node = firstnode(linkedmodules); node; incnode(node)) {
 	if (!strcmp((char *) getdata(node), nam))
 	    return 1;
     }
     node = find_module(module);
-    if (node && (m = ((Module) getdata(node)))->handle &&
+    if (node && (m = ((Module) getdata(node)))->u.handle &&
 	!(m->flags & MOD_UNLOAD)) {
 	if (test) {
 	    zwarnnam(nam, "module %s already loaded.", module, 0);
@@ -710,6 +837,47 @@
     putchar('\n');
 }
 
+/* Cleanup and finish all modules. */
+
+/**/
+void
+exit_modules(void)
+{
+    Module m;
+    char *name;
+    LinkNode node, next, mn, dn;
+    int del, used;
+
+    while (nonempty(modules)) {
+	for (node = firstnode(modules); (next = node); node = next) {
+	    incnode(next);
+	    del = used = 0;
+	    name = ((Module) getdata(node))->nam;
+	    for (mn = firstnode(modules); !used && mn; incnode(mn)) {
+		m = (Module) getdata(mn);
+		if (m->deps && m->u.handle)
+		    for (dn = firstnode(m->deps); dn; incnode(dn))
+			if (!strcmp((char *) getdata(dn), name)) {
+			    if (m->flags & MOD_UNLOAD)
+				del = 1;
+			    else {
+				used = 1;
+				break;
+			    }
+			}
+	    }
+	    if (!used) {
+		m = (Module) getdata(node);
+		if (del)
+		    m->wrapper++;
+		unload_module(m, NULL, 1);
+		if (del)
+		    m->wrapper--;
+	    }
+	}
+    }
+}
+
 /**/
 int
 bin_zmodload(char *nam, char **args, char *ops, int func)
@@ -761,13 +929,9 @@
     Module m;
 
     if (!*args) {
-	for (node = firstnode(bltinmodules); node; incnode(node)) {
-	    nicezputs((char *) getdata(node), stdout);
-	    putchar('\n');
-	}
 	for (node = firstnode(modules); node; incnode(node)) {
 	    m = (Module) getdata(node);
-	    if (m->handle && !(m->flags & MOD_UNLOAD)) {
+	    if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
 		nicezputs(m->nam, stdout);
 		putchar('\n');
 	    }
@@ -778,13 +942,10 @@
 
 	for (; !ret && *args; args++) {
 	    f = 0;
-	    for (node = firstnode(bltinmodules);
-		 !f && node; incnode(node))
-		f = !strcmp(*args, (char *) getdata(node));
 	    for (node = firstnode(modules);
 		 !f && node; incnode(node)) {
 		m = (Module) getdata(node);
-		if (m->handle && !(m->flags & MOD_UNLOAD))
+		if (m->u.handle && !(m->flags & MOD_UNLOAD))
 		    f = !strcmp(*args, m->nam);
 	    }
 	    ret = !f;
@@ -825,7 +986,7 @@
 		m->deps = NULL;
 	    }
 	}
-	if (!m->deps && !m->handle) {
+	if (!m->deps && !m->u.handle) {
 	    remnode(modules, node);
 	    zsfree(m->nam);
 	    zfree(m, sizeof(*m));
@@ -1111,9 +1272,13 @@
 
 /**/
 int
-unload_module(Module m, LinkNode node)
+unload_module(Module m, LinkNode node, int force)
 {
-    if (m->handle && !(m->flags & MOD_UNLOAD) && cleanup_module(m))
+    if ((m->flags & MOD_INIT_S) &&
+	!(m->flags & MOD_UNLOAD) &&
+	((m->flags & MOD_LINKED) ?
+	 (m->u.linked && m->u.linked->cleanup(m)) :
+	 (m->u.handle && cleanup_module(m))))
 	return 1;
     else {
 	int del = (m->flags & MOD_UNLOAD);
@@ -1123,9 +1288,19 @@
 	    return 0;
 	}
 	m->flags &= ~MOD_UNLOAD;
-	if (m->handle)
-	    finish_module(m);
-	m->handle = NULL;
+	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;
+		}
+	    }
+	}
 	if (del && m->deps) {
 	    /* The module was unloaded delayed, unload all modules *
 	     * on which it depended. */
@@ -1145,7 +1320,9 @@
 
 		    for (an = firstnode(modules); du && an; incnode(an)) {
 			am = (Module) getdata(an);
-			if (am != m && am->handle && am->deps) {
+			if (am != m && am->deps &&
+			    ((am->flags & MOD_LINKED) ?
+			     am->u.linked : am->u.handle)) {
 			    LinkNode sn;
 
 			    for (sn = firstnode(am->deps); du && sn;
@@ -1156,11 +1333,11 @@
 			}
 		    }
 		    if (du)
-			unload_module(dm, NULL);
+			unload_module(dm, NULL, 0);
 		}
 	    }
 	}
-	if(!m->deps) {
+	if(!m->deps || force) {
 	    if (!node) {
 		for (node = firstnode(modules); node; incnode(node))
 		    if (m == (Module) getdata(node))
@@ -1193,7 +1370,7 @@
 
 		for (mn = firstnode(modules); mn; incnode(mn)) {
 		    m = (Module) getdata(mn);
-		    if (m->deps && m->handle)
+		    if (m->deps && m->u.handle)
 			for (dn = firstnode(m->deps); dn; incnode(dn))
 			    if (!strcmp((char *) getdata(dn), *args)) {
 				if (m->flags & MOD_UNLOAD)
@@ -1208,7 +1385,7 @@
 		m = (Module) getdata(node);
 		if (del)
 		    m->wrapper++;
-		if (unload_module(m, node))
+		if (unload_module(m, node, 0))
 		    ret = 1;
 		if (del)
 		    m->wrapper--;
@@ -1223,7 +1400,7 @@
 	/* list modules */
 	for (node = firstnode(modules); node; incnode(node)) {
 	    m = (Module) getdata(node);
-	    if (m->handle && !(m->flags & MOD_UNLOAD)) {
+	    if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
 		if(ops['L']) {
 		    printf("zmodload ");
 		    if(m->nam[0] == '-')
@@ -1245,46 +1422,6 @@
     }
 }
 
-/**/
-#else /* DYNAMIC */
-
-/* This is the version for shells without dynamic linking. */
-
-/**/
-int
-bin_zmodload(char *nam, char **args, char *ops, int func)
-{
-    /* We understand only the -e option (and ignore -i). */
-
-    if (ops['e'] || *args) {
-	LinkNode node;
-
-	if (!*args) {
-	    for (node = firstnode(bltinmodules); node; incnode(node)) {
-		nicezputs((char *) getdata(node), stdout);
-		putchar('\n');
-	    }
-	} else {
-	    for (; *args; args++) {
-		for (node = firstnode(bltinmodules); node; incnode(node))
-		    if (!strcmp(*args, (char *) getdata(node)))
-			break;
-		if (!node) {
-		    if (!ops['e'])
-			zerrnam(nam, "cannot load module: `%s'", *args, 0);
-		    return 1;
-		}
-	    }
-	}
-	return 0;
-    }
-    /* Otherwise we return 1 -- different from the dynamic version. */
-    return 1;
-}
-
-/**/
-#endif /* DYNAMIC */
-
 /* The list of module-defined conditions. */
 
 /**/
@@ -1299,9 +1436,7 @@
 getconddef(int inf, char *name, int autol)
 {
     Conddef p;
-#ifdef DYNAMIC
     int f = 1;
-#endif
 
     do {
 	for (p = condtab; p; p = p->next) {
@@ -1309,7 +1444,6 @@
 		!strcmp(name, p->name))
 		break;
 	}
-#ifdef DYNAMIC
 	if (autol && p && p->module) {
 	    /* This is a definition for an autoloaded condition, load the *
 	     * module if we haven't tried that already. */
@@ -1322,7 +1456,6 @@
 		return NULL;
 	    }
 	} else
-#endif
 	    break;
     } while (!p);
     return p;
@@ -1341,11 +1474,9 @@
     if (p) {
 	if (!p->module || (p->flags & CONDF_ADDED))
 	    return 1;
-#ifdef DYNAMIC
 	/* There is an autoload definition. */
 
 	deleteconddef(p);
-#endif
     }
     c->next = condtab;
     condtab = c;
@@ -1616,9 +1747,6 @@
     return 1;
 }
 
-/**/
-#ifdef DYNAMIC
-
 /* This adds a definition for autoloading a module for a condition. */
 
 /**/
@@ -1709,9 +1837,6 @@
     pm->flags |= PM_AUTOLOAD;
 }
 
-/**/
-#endif
-
 /* List of math functions. */
 
 /**/
@@ -1725,7 +1850,6 @@
 
     for (p = mathfuncs; p; q = p, p = p->next)
 	if (!strcmp(name, p->name)) {
-#ifdef DYNAMIC
 	    if (autol && p->module) {
 		char *n = dupstring(p->module);
 
@@ -1741,7 +1865,6 @@
 
 		return getmathfunc(name, 0);
 	    }
-#endif
 	    return p;
 	}
 
@@ -1790,8 +1913,6 @@
     return hadf ? hads : 1;
 }
 
-#ifdef DYNAMIC
-
 /**/
 int
 add_automathfunc(char *nam, char *module)
@@ -1859,5 +1980,3 @@
     }
     return hadf ? hads : 1;
 }
-
-#endif /* DYNAMIC */
diff -u -r oldsrc/params.c Src/params.c
--- oldsrc/params.c	Wed Nov 24 09:03:37 1999
+++ Src/params.c	Wed Nov 24 14:47:36 1999
@@ -203,10 +203,8 @@
 IPDEF8("PATH", &path, "path", PM_RESTRICTED),
 IPDEF8("PSVAR", &psvar, "psvar", 0),
 
-#ifdef DYNAMIC
 /* MODULE_PATH is not imported for security reasons */
 IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED),
-#endif
 
 #define IPDEF9F(A,B,C,D) {NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT,BR((void *)B),SFN(arrvarsetfn),GFN(arrvargetfn),stdunsetfn,0,NULL,C,NULL,0}
 #define IPDEF9(A,B,C) IPDEF9F(A,B,C,0)
@@ -234,9 +232,7 @@
 IPDEF9("psvar", &psvar, "PSVAR"),
 IPDEF9("watch", &watch, "WATCH"),
 
-#ifdef DYNAMIC
 IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED),
-#endif
 IPDEF9F("path", &path, "PATH", PM_RESTRICTED),
 
 {NULL, NULL}
@@ -254,10 +250,6 @@
 /**/
 HashTable paramtab, realparamtab;
 
-#ifndef DYNAMIC
-#define getparamnode gethashnode2
-#endif /* DYNAMIC */
-
 /**/
 HashTable
 newparamtable(int size, char const *name)
@@ -281,8 +273,6 @@
 }
 
 /**/
-#ifdef DYNAMIC
-/**/
 static HashNode
 getparamnode(HashTable ht, char *nam)
 {
@@ -302,8 +292,6 @@
     }
     return hn;
 }
-/**/
-#endif /* DYNAMIC */
 
 /* Copy a parameter hash table */
 
diff -u -r oldsrc/zsh.h Src/zsh.h
--- oldsrc/zsh.h	Wed Nov 24 09:03:39 1999
+++ Src/zsh.h	Wed Nov 24 15:34:29 1999
@@ -300,6 +300,7 @@
 typedef struct builtin   *Builtin;
 typedef struct nameddir  *Nameddir;
 typedef struct module    *Module;
+typedef struct linkedmod *Linkedmod;
 
 typedef struct patprog   *Patprog;
 typedef struct process   *Process;
@@ -917,7 +918,10 @@
 struct module {
     char *nam;
     int flags;
-    void *handle;
+    union {
+	void *handle;
+	Linkedmod linked;
+    } u;
     LinkList deps;
     int wrapper;
 };
@@ -925,6 +929,19 @@
 #define MOD_BUSY    (1<<0)
 #define MOD_UNLOAD  (1<<1)
 #define MOD_SETUP   (1<<2)
+#define MOD_LINKED  (1<<3)
+#define MOD_INIT_S  (1<<4)
+#define MOD_INIT_B  (1<<5)
+
+typedef int (*Module_func) _((Module));
+
+struct linkedmod {
+    char *name;
+    Module_func setup;
+    Module_func boot;
+    Module_func cleanup;
+    Module_func finish;
+};
 
 /* C-function hooks */
 
diff -u olddoc/Zsh/builtins.yo Doc/Zsh/builtins.yo
--- olddoc/Zsh/builtins.yo	Wed Nov 24 09:04:30 1999
+++ Doc/Zsh/builtins.yo	Wed Nov 24 15:57:47 1999
@@ -1390,20 +1390,20 @@
 Equivalent to tt(-ab) and tt(-ub).
 )
 item(tt(zmodload -e) [ var(string) ... ])(
-The tt(-e) option without arguments lists all modules loaded or linked 
-into the shell. With arguments only the return status is set to zero
-if all var(string)s given as arguments are names of modules loaded or
-linked in and to one if at least on var(string) is not the name of a
-module loaded or linked. This can be used to test for the availability 
+The tt(-e) option without arguments lists all loaded modules loaded.
+With arguments only the return status is set to zero
+if all var(string)s given as arguments are names of loaded modules
+and to one if at least on var(string) is not the name of a
+loaded module. This can be used to test for the availability 
 of things implemented by modules.
 )
 enditem()
 
-In a shell without dynamic loading only the tt(-e) option is
-supported and the tt(-i) option is ignored. In such a shell the return
-status of tt(zmodload) without arguments or options is one whereas in
-a shell with dynamic loading the return status without arguments or
-options is always zero. This can be used to test if the shell supports
-dynamic loading of modules or not.
+Note that tt(zsh) makes no difference between modules that were linked 
+into the shell and modules that are loaded dynamically. In both cases
+this builtin command has to be used to make available the builtins and
+other things defined by modules (unless the module is autoloaded on
+these definitions). This is even true for systems that don't support
+dynamic loading of modules.
 )
 enditem()
--- Etc/zsh-development-guide.old	Wed Nov 24 15:52:17 1999
+++ Etc/zsh-development-guide	Wed Nov 24 15:52:45 1999
@@ -151,9 +151,7 @@
 user tries to unload a module and should de-register the builtins
 etc. The last function, `finish_foo' is called when the module is
 actually unloaded and should finalize all the data initialized in the 
-`setup'-function. Since the last two functions are only executed when
-the module is used as an dynamically loaded module you can surround
-it with `#ifdef MODULE' and `#endif'.
+`setup'-function.
 In short, the `cleanup'-function should undo what the `boot'-function
 did, and the `finish'-function should undo what the `setup'-function
 did.

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author