about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-12-01 18:35:59 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-12-01 18:35:59 +0000
commita4e44197ae0f6e237f118e5b30c01eb12c460ec4 (patch)
treefb6a23f8a1eaaba1e97869ca54245e5bd986045e /Src
parent2c5eaba1971c212412eb212184ee724cf7d0ac70 (diff)
downloadzsh-a4e44197ae0f6e237f118e5b30c01eb12c460ec4.tar.gz
zsh-a4e44197ae0f6e237f118e5b30c01eb12c460ec4.tar.xz
zsh-a4e44197ae0f6e237f118e5b30c01eb12c460ec4.zip
zsh-workers/8843
Diffstat (limited to 'Src')
-rw-r--r--Src/.cvsignore1
-rw-r--r--Src/.distfiles2
-rw-r--r--Src/Builtins/.cvsignore1
-rw-r--r--Src/Makefile.in6
-rw-r--r--Src/Makemod.in.in2
-rw-r--r--Src/Modules/.cvsignore1
-rw-r--r--Src/Zle/.cvsignore1
-rw-r--r--Src/Zle/.distfiles4
-rw-r--r--Src/Zle/compcore.c70
-rw-r--r--Src/Zle/complete.c33
-rw-r--r--Src/Zle/complete.mdd2
-rw-r--r--Src/Zle/compmatch.c6
-rw-r--r--Src/Zle/compresult.c14
-rw-r--r--Src/Zle/zle.mdd2
-rw-r--r--Src/Zle/zle_bindings.c2
-rw-r--r--Src/Zle/zle_keymap.c16
-rw-r--r--Src/Zle/zle_main.c26
-rw-r--r--Src/Zle/zle_misc.c12
-rw-r--r--Src/Zle/zle_params.c2
-rw-r--r--Src/Zle/zle_refresh.c20
-rw-r--r--Src/Zle/zle_thingy.c6
-rw-r--r--Src/Zle/zle_tricky.c70
-rw-r--r--Src/Zle/zle_utils.c12
-rw-r--r--Src/builtin.c16
-rw-r--r--Src/compat.c6
-rw-r--r--Src/cond.c6
-rw-r--r--Src/exec.c38
-rw-r--r--Src/glob.c14
-rw-r--r--Src/hashtable.c32
-rw-r--r--Src/hist.c38
-rw-r--r--Src/init.c54
-rw-r--r--Src/input.c8
-rw-r--r--Src/jobs.c8
-rw-r--r--Src/lex.c43
-rw-r--r--Src/linklist.c18
-rw-r--r--Src/loop.c2
-rw-r--r--Src/makepro.awk7
-rw-r--r--Src/math.c2
-rw-r--r--Src/mem.c47
-rw-r--r--Src/mkmakemod.sh11
-rw-r--r--Src/module.c40
-rw-r--r--Src/options.c8
-rw-r--r--Src/params.c102
-rw-r--r--Src/parse.c8
-rw-r--r--Src/pattern.c6
-rw-r--r--Src/prompt.c8
-rw-r--r--Src/signals.c14
-rw-r--r--Src/signames2.awk2
-rw-r--r--Src/subst.c10
-rw-r--r--Src/text.c2
-rw-r--r--Src/utils.c132
-rw-r--r--Src/zsh.h6
52 files changed, 519 insertions, 480 deletions
diff --git a/Src/.cvsignore b/Src/.cvsignore
index bd828c33e..cc2153bb4 100644
--- a/Src/.cvsignore
+++ b/Src/.cvsignore
@@ -1,5 +1,6 @@
 Makefile
 Makemod.in Makemod
+*.export
 [_a-zA-Z0-9]*.pro
 *.epro
 *.syms
diff --git a/Src/.distfiles b/Src/.distfiles
index 3815b31c8..5b0ce9609 100644
--- a/Src/.distfiles
+++ b/Src/.distfiles
@@ -8,5 +8,5 @@ DISTFILES_SRC='
     math.c mem.c mkbltnmlst.sh mkmakemod.sh mkmodindex.sh
     module.c options.c params.c parse.c pattern.c prompt.c prototypes.h
     signals.c signals.h subst.c system.h text.c utils.c
-    watch.c xmods.conf zsh.h zsh.mdd ztype.h zsh.export
+    watch.c xmods.conf zsh.h zsh.mdd ztype.h
 '
diff --git a/Src/Builtins/.cvsignore b/Src/Builtins/.cvsignore
index f0498cb30..d7fecfc20 100644
--- a/Src/Builtins/.cvsignore
+++ b/Src/Builtins/.cvsignore
@@ -1,5 +1,6 @@
 Makefile
 Makefile.in
+*.export
 so_locations
 *.pro
 *.epro
diff --git a/Src/Makefile.in b/Src/Makefile.in
index 77f142262..3589e30ad 100644
--- a/Src/Makefile.in
+++ b/Src/Makefile.in
@@ -65,7 +65,7 @@ NLIST = `cat stamp-modobjs`
 LIBZSH = libzsh-$(VERSION).$(DL_EXT)
 NIBZSH =
 
-ZSH_EXPORT = $(EXPOPT)$(sdir)/zsh.export
+ZSH_EXPORT = $(EXPOPT)zsh.export
 ZSH_NXPORT =
 ENTRYOBJ   = modentry..o
 NNTRYOBJ   =
@@ -73,7 +73,7 @@ NNTRYOBJ   =
 LDRUNPATH = LD_RUN_PATH=$(libdir)/zsh
 NDRUNPATH =
 
-zsh: $(@L@IBZSH) $(@L@STMP) $(MAIN_OBJS)
+zsh: $(@L@IBZSH) $(@L@STMP) $(MAIN_OBJS) zsh.export
 	rm -f $@
 	$(@L@DRUNPATH) $(LINK) $(MAIN_OBJS) $(@L@LIST) $(ZSH_@E@XPORT) $(@L@IBZSH) $(LIBS)
 
@@ -218,7 +218,7 @@ mostlyclean-modules clean-modules distclean-modules realclean-modules: modules.i
 # ========== RECURSIVE MAKES ==========
 
 install.modules uninstall.modules \
-modobjs modules headers proto $(MAIN_OBJS): Makemod
+modobjs modules headers proto $(MAIN_OBJS) zsh.export: Makemod
 	@$(MAKE) -f Makemod $(MAKEDEFS) $@
 
 $(MAIN_OBJS): $(sdir)/zsh.h
diff --git a/Src/Makemod.in.in b/Src/Makemod.in.in
index 9aaa45308..050a0682e 100644
--- a/Src/Makemod.in.in
+++ b/Src/Makemod.in.in
@@ -148,7 +148,7 @@ uninstall.modules-here:
 @CLEAN_MK@
 
 mostlyclean-here:
-	rm -f *.o *.$(DL_EXT)
+	rm -f *.o *.export *.$(DL_EXT)
 
 clean-here:
 	rm -f *.o.c *.syms *.pro *.epro *.mdh *.mdhi *.mdhs *.mdh.tmp
diff --git a/Src/Modules/.cvsignore b/Src/Modules/.cvsignore
index 9e8213045..6157c934d 100644
--- a/Src/Modules/.cvsignore
+++ b/Src/Modules/.cvsignore
@@ -1,5 +1,6 @@
 Makefile
 Makefile.in
+*.export
 so_locations
 *.pro
 *.epro
diff --git a/Src/Zle/.cvsignore b/Src/Zle/.cvsignore
index 2eff53649..c5921cdc4 100644
--- a/Src/Zle/.cvsignore
+++ b/Src/Zle/.cvsignore
@@ -1,5 +1,6 @@
 Makefile
 Makefile.in
+*.export
 so_locations
 *.pro
 *.epro
diff --git a/Src/Zle/.distfiles b/Src/Zle/.distfiles
index 7045f7581..e280a0199 100644
--- a/Src/Zle/.distfiles
+++ b/Src/Zle/.distfiles
@@ -1,6 +1,6 @@
 DISTFILES_SRC='
     .cvsignore .distfiles .exrc
-    comp.h complete.mdd complete.c complete.export
+    comp.h complete.mdd complete.c
     compcore.c compmatch.c compresult.c
     compctl.mdd compctl.c compctl.h
     complist.mdd complist.c
@@ -10,5 +10,5 @@ DISTFILES_SRC='
     zle.mdd iwidgets.list zle.h zle_bindings.c zle_hist.c
     zle_keymap.c zle_main.c zle_misc.c zle_move.c zle_params.c
     zle_refresh.c zle_things.sed zle_thingy.c zle_tricky.c
-    zle_utils.c zle_vi.c zle_widget.sed zle_word.c zle.export
+    zle_utils.c zle_vi.c zle_widget.sed zle_word.c
 '
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 193da880e..875674023 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -59,12 +59,12 @@ int insmnum, insgnum, insgroup, insspace;
 /* Information about menucompletion. */
 
 /**/
-struct menuinfo minfo;
+mod_export struct menuinfo minfo;
 
 /* Number of matches accepted with accept-and-menu-complete */
 
 /**/
-int menuacc;
+mod_export int menuacc;
 
 /* Brace insertion stuff. */
 
@@ -74,7 +74,7 @@ int hasunqu, useqbr, brpcs, brscs;
 /* Flags saying in what kind of string we are. */
 
 /**/
-int ispar, linwhat;
+mod_export int ispar, linwhat;
 
 /* A parameter expansion prefix (like ${). */
 
@@ -89,7 +89,7 @@ int parflags;
 /* Match flags for all matches in this group. */
 
 /**/
-int mflags;
+mod_export int mflags;
 
 /* Flags saying how the parameter expression we are in is quoted. */
 
@@ -101,13 +101,15 @@ int parq, eparq;
  * isuf        -- the ignored suffix                                       */
 
 /**/
-char *ipre, *ripre, *isuf;
+mod_export char *ipre, *ripre, *isuf;
 
 /* The list of matches.  fmatches contains the matches we first ignore *
  * because of fignore.                                                 */
 
 /**/
-LinkList matches, fmatches;
+mod_export LinkList matches;
+/**/
+LinkList fmatches;
 
 /* This holds the list of matches-groups. lastmatches holds the last list of 
  * permanently allocated matches, pmatches is the same for the list
@@ -116,12 +118,12 @@ LinkList matches, fmatches;
  * lmatches/lastlmatches is a pointer to the last element in the lists. */
 
 /**/
-Cmgroup lastmatches, pmatches, amatches, lmatches, lastlmatches;
+mod_export Cmgroup lastmatches, pmatches, amatches, lmatches, lastlmatches;
 
 /* Non-zero if we have permanently allocated matches (old and new). */
 
 /**/
-int hasoldlist, hasperm;
+mod_export int hasoldlist, hasperm;
 
 /* Non-zero if we have newly added matches. */
 
@@ -136,27 +138,29 @@ int permmnum, permgnum, lastpermmnum, lastpermgnum;
 /* The total number of matches and the number of matches to be listed. */
 
 /**/
-int nmatches, smatches;
+mod_export int nmatches;
+/**/
+int smatches;
 
 /* != 0 if only explanation strings should be printed */
 
 /**/
-int onlyexpl;
+mod_export int onlyexpl;
 
 /* Information about the matches for listing. */
 
 /**/
-struct cldata listdat;
+mod_export struct cldata listdat;
 
 /* This flag is non-zero if we are completing a pattern (with globcomplete) */
 
 /**/
-int ispattern, haspattern;
+mod_export int ispattern, haspattern;
 
 /* Non-zero if at least one match was added without -U. */
 
 /**/
-int hasmatched;
+mod_export int hasmatched;
 
 /* The current group of matches. */
 
@@ -166,7 +170,7 @@ Cmgroup mgroup;
 /* Match counter: all matches. */
 
 /**/
-int mnum;
+mod_export int mnum;
 
 /* The match counter when unambig_data() was called. */
 
@@ -185,22 +189,22 @@ int maxmlen, minmlen;
 LinkList expls;
 
 /**/
-Cexpl curexpl;
+mod_export Cexpl curexpl;
 
 /* A stack of completion matchers to be used. */
 
 /**/
-Cmlist mstack;
+mod_export Cmlist mstack;
 
 /* The completion matchers used when building new stuff for the line. */
 
 /**/
-Cmlist bmatchers;
+mod_export Cmlist bmatchers;
 
 /* A list with references to all matchers we used. */
 
 /**/
-LinkList matchers;
+mod_export LinkList matchers;
 
 /* A heap of free Cline structures. */
 
@@ -215,7 +219,7 @@ Aminfo ainfo, fainfo;
 /* The memory heap to use for new style completion generation. */
 
 /**/
-Heap compheap;
+mod_export Heap compheap;
 
 /* A list of some data.
  *
@@ -223,7 +227,7 @@ Heap compheap;
  * conceptually we don't know anything about compctls here... */
 
 /**/
-LinkList allccs;
+mod_export LinkList allccs;
 
 /* This says what of the state the line is in when completion is started *
  * came from a previous completion. If the FC_LINE bit is set, the       *
@@ -917,7 +921,7 @@ makecomplist(char *s, int incmd, int lst)
 }
 
 /**/
-char *
+mod_export char *
 multiquote(char *s, int ign)
 {
     if (s) {
@@ -940,7 +944,7 @@ multiquote(char *s, int ign)
 }
 
 /**/
-char *
+mod_export char *
 tildequote(char *s, int ign)
 {
     if (s) {
@@ -961,7 +965,7 @@ tildequote(char *s, int ign)
 /* Check if we have to complete a parameter name. */
 
 /**/
-char *
+mod_export char *
 check_param(char *s, int set, int test)
 {
     char *p;
@@ -1086,7 +1090,7 @@ check_param(char *s, int set, int test)
 /* Copy the given string and remove backslashes from the copy and return it. */
 
 /**/
-char *
+mod_export char *
 rembslash(char *s)
 {
     char *t = s = dupstring(s);
@@ -1105,7 +1109,7 @@ rembslash(char *s)
 /* This should probably be moved into tokenize(). */
 
 /**/
-char *
+mod_export char *
 ctokenize(char *p)
 {
     char *r = p;
@@ -1131,7 +1135,7 @@ ctokenize(char *p)
 }
 
 /**/
-char *
+mod_export char *
 comp_str(int *ipl, int *pl, int untok)
 {
     char *p = dupstring(compprefix);
@@ -1396,7 +1400,7 @@ set_comp_sep(void)
 /* This stores the strings from the list in an array. */
 
 /**/
-void
+mod_export void
 set_list_array(char *name, LinkList l)
 {
     char **a, **p;
@@ -1413,7 +1417,7 @@ set_list_array(char *name, LinkList l)
 /* Get the words from a variable or a (list of words). */
 
 /**/
-char **
+mod_export char **
 get_user_var(char *nam)
 {
     if (!nam)
@@ -1842,7 +1846,7 @@ addmatches(Cadata dat, char **argv)
 /* This adds all the data we have for a match. */
 
 /**/
-Cmatch
+mod_export Cmatch
 add_match_data(int alt, char *str, Cline line,
 	       char *ipre, char *ripre, char *isuf,
 	       char *pre, char *prpre,
@@ -2170,7 +2174,7 @@ add_match_data(int alt, char *str, Cline line,
 /* This begins a new group of matches. */
 
 /**/
-void
+mod_export void
 begcmgroup(char *n, int flags)
 {
     if (n) {
@@ -2213,7 +2217,7 @@ begcmgroup(char *n, int flags)
 /* End the current group for now. */
 
 /**/
-void
+mod_export void
 endcmgroup(char **ylist)
 {
     mgroup->ylist = ylist;
@@ -2222,7 +2226,7 @@ endcmgroup(char **ylist)
 /* Add an explanation string to the current group, joining duplicates. */
 
 /**/
-void
+mod_export void
 addexpl(void)
 {
     LinkNode n;
@@ -2581,7 +2585,7 @@ freematch(Cmatch m, int nbeg, int nend)
 /* This frees the groups of matches. */
 
 /**/
-void
+mod_export void
 freematches(Cmgroup g)
 {
     Cmgroup n;
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 55a6e68f2..416ebfff7 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -33,41 +33,44 @@
 /* Global matcher. */
 
 /**/
-Cmlist cmatcher;
+mod_export Cmlist cmatcher;
 
 /* global variables for shell parameters in new style completion */
 
 /**/
-zlong compcurrent,
-      compmatcher,
+mod_export zlong compcurrent;
+/**/
+zlong compmatcher,
       compmatchertot,
       complistmax,
       complistlines;
 
 /**/
+mod_export
 char **compwords,
      *compprefix,
      *compsuffix,
-     *compiprefix,
      *compisuffix,
      *compqiprefix,
      *compqisuffix,
+     *compquote,
+     *compqstack,
+     *comppatmatch,
+     *complastprompt;
+/**/
+char *compiprefix,
      *compmatcherstr,
      *compcontext,
      *compparameter,
      *compredirect,
-     *compquote,
      *compquoting,
-     *compqstack,
      *comprestore,
      *complist,
      *compforcelist,
      *compinsert,
      *compexact,
      *compexactstr,
-     *comppatmatch,
      *comppatinsert,
-     *complastprompt,
      *comptoend,
      *compoldlist,
      *compoldins,
@@ -94,7 +97,7 @@ freecmlist(Cmlist l)
 }
 
 /**/
-void
+mod_export void
 freecmatcher(Cmatcher m)
 {
     Cmatcher n;
@@ -152,7 +155,7 @@ cpcmlist(Cmlist l)
 /* Copy a completion matcher list. */
 
 /**/
-Cmatcher
+mod_export Cmatcher
 cpcmatcher(Cmatcher m)
 {
     Cmatcher r = NULL, *p = &r, n;
@@ -202,7 +205,7 @@ cpcpattern(Cpattern o)
 /* Set the global match specs. */
 
 /**/
-int
+mod_export int
 set_gmatcher(char *name, char **argv)
 {
     Cmlist l = NULL, *q = &l, n;
@@ -229,7 +232,7 @@ set_gmatcher(char *name, char **argv)
 /* Parse a string for matcher control, containing multiple matchers. */
 
 /**/
-Cmatcher
+mod_export Cmatcher
 parse_cmatcher(char *name, char *s)
 {
     Cmatcher ret = NULL, r = NULL, n;
@@ -616,7 +619,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
 #define CVT_SUFPAT   5
 
 /**/
-void
+mod_export void
 ignore_prefix(int l)
 {
     if (l) {
@@ -640,7 +643,7 @@ ignore_prefix(int l)
 }
 
 /**/
-void
+mod_export void
 ignore_suffix(int l)
 {
     if (l) {
@@ -663,7 +666,7 @@ ignore_suffix(int l)
 }
 
 /**/
-void
+mod_export void
 restrict_range(int b, int e)
 {
     int wl = arrlen(compwords) - 1;
diff --git a/Src/Zle/complete.mdd b/Src/Zle/complete.mdd
index 3ea802065..70e275b4e 100644
--- a/Src/Zle/complete.mdd
+++ b/Src/Zle/complete.mdd
@@ -1,5 +1,3 @@
-hasexport=1
-
 moddeps="zle"
 
 autobins="compgen compadd compset"
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index d29595d62..b5ea5affe 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -68,7 +68,7 @@ cmp_cmatchers(Cmatcher a, Cmatcher b)
 /* Add the given matchers to the bmatcher list. */
 
 /**/
-void
+mod_export void
 add_bmatchers(Cmatcher m)
 {
     Cmlist old = bmatchers, *q = &bmatchers, n;
@@ -88,7 +88,7 @@ add_bmatchers(Cmatcher m)
  * ensure that the bmatchers list contains no matchers not in mstack. */
 
 /**/
-void
+mod_export void
 update_bmatchers(void)
 {
     Cmlist p = bmatchers, q = NULL, ms;
@@ -832,7 +832,7 @@ match_parts(char *l, char *w, int n, int part)
  * and the suffix don't match the word w. */
 
 /**/
-char *
+mod_export char *
 comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu,
 	   Brinfo *bpl, int bcp, Brinfo *bsl, int bcs, int *exact)
 {
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index c68657d79..bdafa3059 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -682,7 +682,7 @@ do_ambiguous(void)
  * (l)stat().                                                         */
 
 /**/
-int
+mod_export int
 ztat(char *nam, struct stat *buf, int ls)
 {
     char b[PATH_MAX], *p;
@@ -700,7 +700,7 @@ ztat(char *nam, struct stat *buf, int ls)
 /* Insert a single match in the command line. */
 
 /**/
-void
+mod_export void
 do_single(Cmatch m)
 {
     int l, sr = 0, scs;
@@ -891,7 +891,7 @@ do_single(Cmatch m)
  * insert the next completion.                                              */
 
 /**/
-void
+mod_export void
 do_menucmp(int lst)
 {
     /* Just list the matches if the list was requested. */
@@ -947,7 +947,7 @@ reverse_menu(Hookdef dummy, void *dummy2)
  * accept several selections from the list of matches.  */
 
 /**/
-int
+mod_export int
 accept_last(void)
 {
     if (!menuacc) {
@@ -1132,7 +1132,7 @@ skipnolist(Cmatch *p)
 }
 
 /**/
-void
+mod_export void
 calclist(void)
 {
     Cmgroup g;
@@ -1517,7 +1517,7 @@ int asklist(void)
 }
 
 /**/
-int
+mod_export int
 printlist(int over, CLPrintFunc printm)
 {
     Cmgroup g;
@@ -1800,7 +1800,7 @@ list_matches(Hookdef dummy, void *dummy2)
 /* Invalidate the completion list. */
 
 /**/
-int
+mod_export int
 invalidate_list(void)
 {
     if (showinglist == -2)
diff --git a/Src/Zle/zle.mdd b/Src/Zle/zle.mdd
index 3235c88a1..a5307084a 100644
--- a/Src/Zle/zle.mdd
+++ b/Src/Zle/zle.mdd
@@ -1,5 +1,3 @@
-hasexport=1
-
 autobins="bindkey vared zle"
 
 objects="zle_bindings.o zle_hist.o zle_keymap.o zle_main.o \
diff --git a/Src/Zle/zle_bindings.c b/Src/Zle/zle_bindings.c
index 940d578d9..e95061df2 100644
--- a/Src/Zle/zle_bindings.c
+++ b/Src/Zle/zle_bindings.c
@@ -69,7 +69,7 @@ widgets[] = {
  */
 
 /**/
-struct thingy thingies[] = {
+mod_export struct thingy thingies[] = {
 #define T(name, th_flags, w_idget, t_next) \
     { NULL, name, th_flags, 2, w_idget, t_next },
 #include "thingies.list"
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index ccfbd4043..28203655e 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -105,7 +105,7 @@ char *curkeymapname;
 /* the hash table of keymap names */
 
 /**/
-HashTable keymapnamtab;
+mod_export HashTable keymapnamtab;
 
 /* key sequence reading data */
 
@@ -217,7 +217,7 @@ freekeynode(HashNode hn)
 static HashTable copyto;
 
 /**/
-Keymap
+mod_export Keymap
 newkeymap(Keymap tocopy, char *kmname)
 {
     Keymap km = zcalloc(sizeof(*km));
@@ -323,7 +323,7 @@ openkeymap(char *name)
 }
 
 /**/
-int
+mod_export int
 unlinkkeymap(char *name, int ignm)
 {
     KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
@@ -336,7 +336,7 @@ unlinkkeymap(char *name, int ignm)
 }
 
 /**/
-int
+mod_export int
 linkkeymap(Keymap km, char *name, int imm)
 {
     KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
@@ -386,7 +386,7 @@ selectkeymap(char *name, int fb)
 /* Select a local key map. */
 
 /**/
-void
+mod_export void
 selectlocalmap(Keymap m)
 {
     localkeymap = m;
@@ -414,7 +414,7 @@ reselectkeymap(void)
  * back onto the input.                                                   */
 
 /**/
-int
+mod_export int
 bindkey(Keymap km, char *seq, Thingy bind, char *str)
 {
     Key k;
@@ -1204,7 +1204,7 @@ getkeybuf(int w)
  * Must be executed at most once after each getkeymapcmd().    */
 
 /**/
-void
+mod_export void
 ungetkeycmd(void)
 {
     ungetkeys(keybuf, keybuflen);
@@ -1213,7 +1213,7 @@ ungetkeycmd(void)
 /* read a command from the current keymap, with widgets */
 
 /**/
-Thingy
+mod_export Thingy
 getkeycmd(void)
 {
     Thingy func;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 4f5729818..420494a52 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -34,17 +34,17 @@
  * will work (i.e., the line is metafied, and the above word arrays are OK). */
 
 /**/
-int incompctlfunc;
+mod_export int incompctlfunc;
 
 /* != 0 if we are in a new style completion function */
 
 /**/
-int incompfunc;
+mod_export int incompfunc;
 
 /* != 0 if completion module is loaded */
 
 /**/
-int hascompmod;
+mod_export int hascompmod;
 
 /* != 0 if we're done editing */
 
@@ -64,7 +64,7 @@ int c;
 /* the bindings for the previous and for this key */
 
 /**/
-Thingy lbindk, bindk;
+mod_export Thingy lbindk, bindk;
 
 /* insert mode/overwrite mode flag */
 
@@ -83,10 +83,10 @@ static int baud;
 /* flags associated with last command */
 
 /**/
-int lastcmd;
+mod_export int lastcmd;
 
 /**/
-Widget compwidget;
+mod_export Widget compwidget;
 
 /* the status line, and its length */
 
@@ -109,7 +109,7 @@ int undoing;
 /* current modifier status */
 
 /**/
-struct modifier zmod;
+mod_export struct modifier zmod;
 
 /* Current command prefix status.  This is normally 0.  Prefixes set *
  * this to 1.  Each time round the main loop, this is checked: if it *
@@ -127,7 +127,7 @@ int prefixflag;
 int kungetct;
 
 /**/
-char *zlenoargs[1] = { NULL };
+mod_export char *zlenoargs[1] = { NULL };
 
 #ifdef FIONREAD
 static int delayzsetterm;
@@ -136,7 +136,7 @@ static int delayzsetterm;
 /* set up terminal */
 
 /**/
-void
+mod_export void
 zsetterm(void)
 {
     struct ttyinfo ti;
@@ -316,7 +316,7 @@ breakread(int fd, char *buf, int n)
 #endif
 
 /**/
-int
+mod_export int
 getkey(int keytmout)
 {
     char cc;
@@ -722,7 +722,7 @@ handleprefixes(void)
 /* this exports the argument we are currently vared'iting if != NULL */
 
 /**/
-char *varedarg;
+mod_export char *varedarg;
 
 /* vared: edit (literally) a parameter value */
 
@@ -952,7 +952,7 @@ whereis(char **args)
 }
 
 /**/
-void
+mod_export void
 trashzle(void)
 {
     if (zleactive) {
@@ -991,7 +991,7 @@ static struct builtin bintab[] = {
  * macros in zle.h */
 
 /**/
-struct hookdef zlehooks[] = {
+mod_export struct hookdef zlehooks[] = {
     HOOKDEF("list_matches", NULL, 0),
     HOOKDEF("complete", NULL, 0),
     HOOKDEF("before_complete", NULL, 0),
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 18e38ee3a..3e306da8a 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -833,7 +833,7 @@ executenamedcommand(char *prmt)
  * suffixlen[256] is the length to remove for non-insertion editing actions. */
 
 /**/
-int suffixlen[257];
+mod_export int suffixlen[257];
 
 /* Shell function to call to remove the suffix. */
 
@@ -844,7 +844,7 @@ static char *suffixfunc;
  * removed in the usual word end conditions.                        */
 
 /**/
-void
+mod_export void
 makesuffix(int n)
 {
     suffixlen[256] = suffixlen[' '] = suffixlen['\t'] = suffixlen['\n'] = 
@@ -858,7 +858,7 @@ makesuffix(int n)
  * characters that can only be used in braces are included.              */
 
 /**/
-void
+mod_export void
 makeparamsuffix(int br, int n)
 {
     if(br || unset(KSHARRAYS))
@@ -874,7 +874,7 @@ makeparamsuffix(int br, int n)
  * remove the suffix. */
 
 /**/
-void
+mod_export void
 makesuffixstr(char *f, char *s, int n)
 {
     if (f) {
@@ -920,7 +920,7 @@ makesuffixstr(char *f, char *s, int n)
 /* Remove suffix, if there is one, when inserting character c. */
 
 /**/
-void
+mod_export void
 iremovesuffix(int c, int keep)
 {
     if (suffixfunc) {
@@ -958,7 +958,7 @@ iremovesuffix(int c, int keep)
 /* Fix the suffix in place, if there is one, making it non-removable. */
 
 /**/
-void
+mod_export void
 fixsuffix(void)
 {
     memset(suffixlen, 0, sizeof(suffixlen));
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index aa62786f5..a6dc2bc67 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -79,7 +79,7 @@ static struct zleparam {
 };
 
 /**/
-void
+mod_export void
 makezleparams(int ro)
 {
     struct zleparam *zp;
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 97b7e8d03..4c5a0cdf8 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -43,7 +43,7 @@ unsigned pmpt_attr, rpmpt_attr;
 /* number of lines displayed */
 
 /**/
-int nlnct;
+mod_export int nlnct;
 
 /* Most lines of the buffer we've shown at once with the current list *
  * showing.  == 0 if there is no list.  == -1 if a new list has just  *
@@ -51,25 +51,25 @@ int nlnct;
  * list.                                                              */
 
 /**/
-int showinglist;
+mod_export int showinglist;
 
 /* > 0 if a completion list is displayed below the prompt,
  * < 0 if a list is displayed above the prompt. */
 
 /**/
-int listshown;
+mod_export int listshown;
 
 /* Non-zero if ALWAYS_LAST_PROMPT has been used, meaning that the *
  * screen below the buffer display should not be cleared by       *
  * zrefresh(), but should be by trashzle().                       */
 
 /**/
-int clearflag;
+mod_export int clearflag;
 
 /* Non-zero if zrefresh() should clear the list below the prompt. */
 
 /**/
-int clearlist;
+mod_export int clearlist;
 
 #ifdef HAVE_SELECT
 /* cost of last update */
@@ -243,7 +243,7 @@ static int cleareol,		/* clear to end-of-line (if can't cleareod) */
     numscrolls, onumscrolls;
 
 /**/
-void
+mod_export void
 zrefresh(void)
 {
     static int inlist;		/* avoiding recursion                        */
@@ -893,7 +893,7 @@ moveto(int ln, int cl)
 }
 
 /**/
-int
+mod_export int
 tcmultout(int cap, int multcap, int ct)
 {
     if (tccan(multcap) && (!tccan(cap) || tclen[multcap] <= tclen[cap] * ct)) {
@@ -989,7 +989,7 @@ tc_downcurs(int ct)
 }
 
 /**/
-void
+mod_export void
 tcout(int cap)
 {
     tputs(tcstr[cap], 1, putshout);
@@ -1008,7 +1008,7 @@ tcoutarg(int cap, int arg)
 }
 
 /**/
-int
+mod_export int
 clearscreen(char **args)
 {
     tcout(TCCLEARSCREEN);
@@ -1018,7 +1018,7 @@ clearscreen(char **args)
 }
 
 /**/
-int
+mod_export int
 redisplay(char **args)
 {
     moveto(0, 0);
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 1e0d483e2..3d8eb41b2 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -134,7 +134,7 @@ freethingynode(HashNode hn)
  * correctly.                                                          */
 
 /**/
-Thingy
+mod_export Thingy
 refthingy(Thingy th)
 {
     if(th)
@@ -261,7 +261,7 @@ freewidget(Widget w)
  * returned.                                                            */
 
 /**/
-Widget
+mod_export Widget
 addzlefunction(char *name, ZleIntFunc ifunc, int flags)
 {
     VARARR(char, dotn, strlen(name) + 2);
@@ -290,7 +290,7 @@ addzlefunction(char *name, ZleIntFunc ifunc, int flags)
  * a widget from the fixed table -- it would be bad.  (Thanks, Egon.)   */
 
 /**/
-void
+mod_export void
 deletezlefunction(Widget w)
 {
     Thingy p, n;
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index b85084355..6c8e6fd0a 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -47,27 +47,27 @@
 /* The line before completion was tried. */
 
 /**/
-char *origline;
+mod_export char *origline;
 /**/
-int origcs, origll;
+mod_export int origcs, origll;
 
 /* Words on the command line, for use in completion */
  
 /**/
-int clwsize, clwnum, clwpos;
+mod_export int clwsize, clwnum, clwpos;
 /**/
-char **clwords;
+mod_export char **clwords;
 
 /* wb and we hold the beginning/end position of the word we are completing. */
 
 /**/
-int wb, we;
+mod_export int wb, we;
 
 /* offs is the cursor position within the tokenized *
  * current word after removing nulargs.             */
 
 /**/
-int offs;
+mod_export int offs;
 
 /* These control the type of completion that will be done.  They are       *
  * affected by the choice of ZLE command and by relevant shell options.    *
@@ -75,34 +75,34 @@ int offs;
  * insert a match as if for menucompletion but without really starting it. */
 
 /**/
-int usemenu, useglob;
+mod_export int usemenu, useglob;
 
 /* != 0 if we are in the middle of a menu completion. May be == 2 to force *
  * menu completion even if using different widgets.                        */
 
 /**/
-int menucmp;
+mod_export int menucmp;
 
 /* Lists of brace-infos before/after cursor (first and last for each). */
 
 /**/
-Brinfo brbeg, lastbrbeg, brend, lastbrend;
+mod_export Brinfo brbeg, lastbrbeg, brend, lastbrend;
 
 /**/
-int nbrbeg, nbrend;
+mod_export int nbrbeg, nbrend;
 
 /**/
-char *lastprebr, *lastpostbr;
+mod_export char *lastprebr, *lastpostbr;
 
 /* !=0 if we have a valid completion list. */
 
 /**/
-int validlist;
+mod_export int validlist;
 
 /* Non-zero if we have to redisplay the list of matches. */
 
 /**/
-int showagain = 0;
+mod_export int showagain = 0;
 
 /* This holds the word we are completing in quoted from. */
 
@@ -112,13 +112,13 @@ static char *qword;
  * closing quote. */
 
 /**/
-char *qipre, *qisuf, *autoq;
+mod_export char *qipre, *qisuf, *autoq;
 
 /* This contains the name of the function to call if this is for a new  *
  * style completion. */
 
 /**/
-char *compfunc = NULL;
+mod_export char *compfunc = NULL;
 
 /* Non-zero if the last completion done was ambiguous (used to find   *
  * out if AUTOMENU should start).  More precisely, it's nonzero after *
@@ -132,14 +132,14 @@ char *compfunc = NULL;
  * lastambig == 2.                                                    */
 
 /**/
-int lastambig;
+mod_export int lastambig;
 
 /* Arguments for and return value of completion widget. */
 
 /**/
-char **cfargs;
+mod_export char **cfargs;
 /**/
-int cfret;
+mod_export int cfret;
 
 /* Find out if we have to insert a tab (instead of trying to complete). */
 
@@ -189,7 +189,7 @@ completeword(char **args)
 }
 
 /**/
-int
+mod_export int
 menucomplete(char **args)
 {
     usemenu = 1;
@@ -284,7 +284,7 @@ listexpand(char **args)
 }
 
 /**/
-int
+mod_export int
 reversemenucomplete(char **args)
 {
     if (!menucmp)
@@ -308,28 +308,28 @@ acceptandmenucomplete(char **args)
  * position, in a redirection, or in a parameter expansion.   */
 
 /**/
-int lincmd, linredir, linarr;
+mod_export int lincmd, linredir, linarr;
 
 /* The string for the redirection operator. */
 
 /**/
-char *rdstr;
+mod_export char *rdstr;
 
 /* This holds the name of the current command (used to find the right *
  * compctl).                                                          */
 
 /**/
-char *cmdstr;
+mod_export char *cmdstr;
 
 /* This hold the name of the variable we are working on. */
 
 /**/
-char *varname;
+mod_export char *varname;
 
 /* != 0 if we are in a subscript */
 
 /**/
-int insubscr;
+mod_export int insubscr;
 
 /* Parameter pointer for completing keys of an assoc array. */
 
@@ -339,7 +339,7 @@ Param keypm;
 /* 1 if we are completing in a quoted string (or inside `...`) */
 
 /**/
-int instring, inbackt;
+mod_export int instring, inbackt;
 
 /* Convenience macro for calling bslashquote() (formerly quotename()). *
  * This uses the instring variable above.                              */
@@ -802,7 +802,7 @@ addx(char **ptmp)
 /* Like dupstring, but add an extra space at the end of the string. */
 
 /**/
-char *
+mod_export char *
 dupstrspace(const char *str)
 {
     int len = strlen((char *)str);
@@ -820,7 +820,7 @@ dupstrspace(const char *str)
  * functions (there's one for each direction).                             */
 
 /**/
-void
+mod_export void
 metafy_line(void)
 {
     int len = ll;
@@ -836,7 +836,7 @@ metafy_line(void)
 }
 
 /**/
-void
+mod_export void
 unmetafy_line(void)
 {
     cs = ztrsub((char *) line + cs, (char *) line);
@@ -846,7 +846,7 @@ unmetafy_line(void)
 /* Free a brinfo list. */
 
 /**/
-void
+mod_export void
 freebrinfo(Brinfo p)
 {
     Brinfo n;
@@ -863,7 +863,7 @@ freebrinfo(Brinfo p)
 /* Duplicate a brinfo list. */
 
 /**/
-Brinfo
+mod_export Brinfo
 dupbrinfo(Brinfo p, Brinfo *last)
 {
     Brinfo ret = NULL, *q = &ret, n = NULL;
@@ -1572,7 +1572,7 @@ get_comp_string(void)
  * The last argument says if we should quote the string.                */
 
 /**/
-int
+mod_export int
 inststrlen(char *str, int move, int len)
 {
     if (!len || !str)
@@ -1683,7 +1683,7 @@ docompletion(char *s, int lst, int incmd)
 /* Return the length of the common prefix of s and t. */
 
 /**/
-int
+mod_export int
 pfxlen(char *s, char *t)
 {
     int i = 0;
@@ -1715,7 +1715,7 @@ sfxlen(char *s, char *t)
 /* This is strcmp with ignoring backslashes. */
 
 /**/
-int
+mod_export int
 strbpcmp(char **aa, char **bb)
 {
     char *a = *aa, *b = *bb;
@@ -1761,7 +1761,7 @@ strbpcmp(char **aa, char **bb)
  * It returns the number of lines printed.       */
 
 /**/
-int
+mod_export int
 printfmt(char *fmt, int n, int dopr, int doesc)
 {
     char *p = fmt, nc[DIGBUFSIZE];
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 2cd985124..772ad708a 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -73,7 +73,7 @@ sizeline(int sz)
 /* insert space for ct chars at cursor position */
 
 /**/
-void
+mod_export void
 spaceinline(int ct)
 {
     int i;
@@ -105,7 +105,7 @@ shiftchars(int to, int cnt)
 }
 
 /**/
-void
+mod_export void
 backkill(int ct, int dir)
 {
     int i = (cs -= ct);
@@ -115,7 +115,7 @@ backkill(int ct, int dir)
 }
 
 /**/
-void
+mod_export void
 forekill(int ct, int dir)
 {
     int i = cs;
@@ -191,14 +191,14 @@ cut(int i, int ct, int dir)
 }
 
 /**/
-void
+mod_export void
 backdel(int ct)
 {
     shiftchars(cs -= ct, ct);
 }
 
 /**/
-void
+mod_export void
 foredel(int ct)
 {
     shiftchars(cs, ct);
@@ -283,7 +283,7 @@ hstrnstr(char *haystack, int pos, char *needle, int len, int dir, int sens)
  * characters are read.  Case is folded.                        */
 
 /**/
-int
+mod_export int
 getzlequery(void)
 {
     int c;
diff --git a/Src/builtin.c b/Src/builtin.c
index 5d4b2be2c..27cbaa6d1 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -133,7 +133,7 @@ static struct builtin builtins[] =
 /* hash table containing builtin commands */
 
 /**/
-HashTable builtintab;
+mod_export HashTable builtintab;
  
 /**/
 void
@@ -573,7 +573,7 @@ bin_pwd(char *name, char **argv, char *ops, int func)
 /* the directory stack */
  
 /**/
-LinkList dirstack;
+mod_export LinkList dirstack;
  
 /* dirs: list the directory stack, or replace it with a provided list */
 
@@ -1139,7 +1139,7 @@ fixdir(char *src)
 }
 
 /**/
-void
+mod_export void
 printqt(char *str)
 {
     /* Print str, but turn any single quote into '\'' or ''. */
@@ -1151,7 +1151,7 @@ printqt(char *str)
 }
 
 /**/
-void
+mod_export void
 printif(char *str, int c)
 {
     /* If flag c has an argument, print that */
@@ -2699,7 +2699,7 @@ bin_false(char *name, char **argv, char *ops, int func)
 /* the zle buffer stack */
  
 /**/
-LinkList bufstack;
+mod_export LinkList bufstack;
 
 /* echo, print, pushln */
 
@@ -3149,7 +3149,7 @@ bin_break(char *name, char **argv, char *ops, int func)
 /* we have printed a 'you have stopped (running) jobs.' message */
  
 /**/
-int stopmsg;
+mod_export int stopmsg;
  
 /* check to see if user has jobs running/stopped */
 
@@ -3183,7 +3183,7 @@ checkjobs(void)
  * because of a signal.                                    */
 
 /**/
-void
+mod_export void
 zexit(int val, int from_signal)
 {
     static int in_exit;
@@ -4045,7 +4045,7 @@ bin_umask(char *nam, char **args, char *ops, int func)
 /* Generic builtin for facilities not available on this OS */
 
 /**/
-int
+mod_export int
 bin_notavail(char *nam, char **argv, char *ops, int func)
 {
     zwarnnam(nam, "not available on this system", NULL, 0);
diff --git a/Src/compat.c b/Src/compat.c
index 7af984799..a7e4069d8 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -106,7 +106,7 @@ strerror(int errnum)
 
 
 /**/
-char *
+mod_export char *
 zgetdir(struct dirsav *d)
 {
     char nbuf[PATH_MAX+3];
@@ -258,7 +258,7 @@ zgetcwd(void)
  * faliliure and -2 when chdir failed and the current directory is lost.  */
 
 /**/
-int
+mod_export int
 zchdir(char *dir)
 {
     char *s;
@@ -313,7 +313,7 @@ zchdir(char *dir)
 /**/
 #ifdef ZSH_64_BIT_TYPE
 /**/
-char *
+mod_export char *
 output64(zlong val)
 {
     static char llbuf[DIGBUFSIZE];
diff --git a/Src/cond.c b/Src/cond.c
index 0ee8fae7c..4a6144bb1 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -349,7 +349,7 @@ optison(char *s)
 }
 
 /**/
-char *
+mod_export char *
 cond_str(char **args, int num, int raw)
 {
     char *s = args[num];
@@ -362,7 +362,7 @@ cond_str(char **args, int num, int raw)
 }
 
 /**/
-zlong
+mod_export zlong
 cond_val(char **args, int num)
 {
     char *s = args[num];
@@ -374,7 +374,7 @@ cond_val(char **args, int num)
 }
 
 /**/
-int
+mod_export int
 cond_match(char **args, int num, char *str)
 {
     char *s = args[num];
diff --git a/Src/exec.c b/Src/exec.c
index 0bc8ff923..cda229c3a 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -38,7 +38,7 @@ int noerrexit;
 /* suppress error messages */
  
 /**/
-int noerrs;
+mod_export int noerrs;
  
 /* do not save history on exec and exit */
 
@@ -48,7 +48,7 @@ int nohistsave;
 /* error/break flag */
  
 /**/
-int errflag;
+mod_export int errflag;
  
 /* Status of return from a trap */
  
@@ -63,7 +63,7 @@ int subsh;
 /* != 0 if we have a return pending */
  
 /**/
-int retflag;
+mod_export int retflag;
 
 /**/
 long lastval2;
@@ -92,17 +92,17 @@ int max_zsh_fd;
 /* input fd from the coprocess */
 
 /**/
-int coprocin;
+mod_export int coprocin;
 
 /* output fd from the coprocess */
 
 /**/
-int coprocout;
+mod_export int coprocout;
 
 /* != 0 if the line editor is active */
 
 /**/
-int zleactive;
+mod_export int zleactive;
 
 /* pid of process undergoing 'process substitution' */
  
@@ -117,7 +117,7 @@ int cmdoutval;
 /* The context in which a shell function is called, see SFC_* in zsh.h. */ 
 
 /**/
-int sfcontext;
+mod_export int sfcontext;
 
 /* Stack to save some variables before executing a signal handler function */
 
@@ -132,7 +132,7 @@ static int doneps4;
 /* parse string into a list */
 
 /**/
-List
+mod_export List
 parse_string(char *s, int ln)
 {
     List l;
@@ -156,10 +156,10 @@ parse_string(char *s, int ln)
 /* the resource limits for the shell and its children */
 
 /**/
-struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS];
+mod_export struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS];
  
 /**/
-int
+mod_export int
 zsetlimit(int limnum, char *nam)
 {
     if (limits[limnum].rlim_max != current_limits[limnum].rlim_max ||
@@ -175,7 +175,7 @@ zsetlimit(int limnum, char *nam)
 }
 
 /**/
-int
+mod_export int
 setlimits(char *nam)
 {
     int limnum;
@@ -546,7 +546,7 @@ execute(Cmdnam not_used_yet, int dash)
  */
 
 /**/
-char *
+mod_export char *
 findcmd(char *arg0, int docopy)
 {
     char **pp;
@@ -644,7 +644,7 @@ isrelative(char *s)
 }
 
 /**/
-Cmdnam
+mod_export Cmdnam
 hashcmd(char *arg0, char **pp)
 {
     Cmdnam cn;
@@ -683,7 +683,7 @@ hashcmd(char *arg0, char **pp)
 /* execute a string */
 
 /**/
-void
+mod_export void
 execstring(char *s, int dont_change_job, int exiting)
 {
     List list;
@@ -1145,7 +1145,7 @@ makecline(LinkList list)
 }
 
 /**/
-void
+mod_export void
 untokenize(char *s)
 {
     if (*s) {
@@ -2309,7 +2309,7 @@ entersubsh(int how, int cl, int fake)
 /* close internal shell fds */
 
 /**/
-void
+mod_export void
 closem(int how)
 {
     int i;
@@ -2477,7 +2477,7 @@ getoutput(char *cmd, int qt)
 /* read output of command substitution */
 
 /**/
-LinkList
+mod_export LinkList
 readoutput(int in, int qt)
 {
     LinkList ret;
@@ -2961,7 +2961,7 @@ loadautofn(Shfunc shf)
 /* execute a shell function */
 
 /**/
-void
+mod_export void
 doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
 /* If noreturnval is nonzero, then reset the current return *
  * value (lastval) to its value before the shell function   *
@@ -3058,7 +3058,7 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
  * in turn has to call back this function with the arguments it gets.   */
 
 /**/
-void
+mod_export void
 runshfunc(List list, FuncWrap wrap, char *name)
 {
     int cont;
diff --git a/Src/glob.c b/Src/glob.c
index f55d8ea69..77729b45c 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -116,7 +116,7 @@ struct qual {
 /* Prefix, suffix for doing zle trickery */
 
 /**/
-char *glob_pre, *glob_suf;
+mod_export char *glob_pre, *glob_suf;
 
 /* struct to easily save/restore current state */
 
@@ -390,7 +390,7 @@ insert(char *s, int checked)
 /* Check to see if str is eligible for filename generation. */
 
 /**/
-int
+mod_export int
 haswilds(char *str)
 {
     /* `[' and `]' are legal even if bad patterns are usually not. */
@@ -1445,7 +1445,7 @@ notstrcmp(char **a, char **b)
 /* Return the trailing character for marking file types */
 
 /**/
-char
+mod_export char
 file_type(mode_t filemode)
 {
     if(S_ISBLK(filemode))
@@ -1620,7 +1620,7 @@ xpandredir(struct redir *fn, LinkList tab)
 /* concatenate s1 and s2 in dynamically allocated buffer */
 
 /**/
-char *
+mod_export char *
 dyncat(char *s1, char *s2)
 {
     /* This version always uses space from the current heap. */
@@ -1636,7 +1636,7 @@ dyncat(char *s1, char *s2)
 /* concatenate s1, s2, and s3 in dynamically allocated buffer */
 
 /**/
-char *
+mod_export char *
 tricat(char const *s1, char const *s2, char const *s3)
 {
     /* This version always uses permanently-allocated space. */
@@ -2252,7 +2252,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
 /* blindly turn a string into a tokenised expression without lexing */
 
 /**/
-void
+mod_export void
 tokenize(char *s)
 {
     char *t;
@@ -2314,7 +2314,7 @@ tokenize(char *s)
 /* remove unnecessary Nulargs */
 
 /**/
-void
+mod_export void
 remnulargs(char *s)
 {
     if (*s) {
diff --git a/Src/hashtable.c b/Src/hashtable.c
index 24c23e423..e9f33aa15 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -77,7 +77,7 @@ static HashTable firstht, lastht;
 /* Generic hash function */
 
 /**/
-unsigned
+mod_export unsigned
 hasher(char *str)
 {
     unsigned hashval = 0;
@@ -91,7 +91,7 @@ hasher(char *str)
 /* Get a new hash table */
 
 /**/
-HashTable
+mod_export HashTable
 newhashtable(int size, char const *name, PrintTableStats printinfo)
 {
     HashTable ht;
@@ -120,7 +120,7 @@ newhashtable(int size, char const *name, PrintTableStats printinfo)
  * existing pointers to the hash table are invalid.             */
 
 /**/
-void
+mod_export void
 deletehashtable(HashTable ht)
 {
     ht->emptytable(ht);
@@ -148,7 +148,7 @@ deletehashtable(HashTable ht)
  * the table is then expanded.                          */
 
 /**/
-void
+mod_export void
 addhashnode(HashTable ht, char *nam, void *nodeptr)
 {
     HashNode oldnode = addhashnode2(ht, nam, nodeptr);
@@ -222,7 +222,7 @@ addhashnode2(HashTable ht, char *nam, void *nodeptr)
  * or isn't found, it returns NULL        */
 
 /**/
-HashNode
+mod_export HashNode
 gethashnode(HashTable ht, char *nam)
 {
     unsigned hashval;
@@ -246,7 +246,7 @@ gethashnode(HashTable ht, char *nam)
  * it returns NULL.                       */
 
 /**/
-HashNode
+mod_export HashNode
 gethashnode2(HashTable ht, char *nam)
 {
     unsigned hashval;
@@ -266,7 +266,7 @@ gethashnode2(HashTable ht, char *nam)
  * is no such node, then it returns NULL        */
 
 /**/
-HashNode
+mod_export HashNode
 removehashnode(HashTable ht, char *nam)
 {
     unsigned hashval;
@@ -358,7 +358,7 @@ hnamcmp(const void *ap, const void *bp)
  */
 
 /**/
-void
+mod_export void
 scanhashtable(HashTable ht, int sorted, int flags1, int flags2, ScanFunc scanfunc, int scanflags)
 {
     struct scanstatus st;
@@ -509,7 +509,7 @@ resizehashtable(HashTable ht, int newsize)
 /* Generic method to empty a hash table */
 
 /**/
-void
+mod_export void
 emptyhashtable(HashTable ht)
 {
     resizehashtable(ht, ht->hsize);
@@ -578,12 +578,12 @@ bin_hashinfo(char *nam, char **args, char *ops, int func)
 /* hash table containing external commands */
  
 /**/
-HashTable cmdnamtab;
+mod_export HashTable cmdnamtab;
  
 /* how far we've hashed the PATH so far */
  
 /**/
-char **pathchecked;
+mod_export char **pathchecked;
  
 /* Create a new command hash table */
  
@@ -756,7 +756,7 @@ printcmdnamnode(HashNode hn, int printflags)
 /* hash table containing the shell functions */
 
 /**/
-HashTable shfunctab;
+mod_export HashTable shfunctab;
 
 /**/
 void
@@ -934,7 +934,7 @@ static struct reswd reswds[] = {
 /* hash table containing the reserved words */
 
 /**/
-HashTable reswdtab;
+mod_export HashTable reswdtab;
 
 /* Build the hash table containing zsh's reserved words. */
 
@@ -997,7 +997,7 @@ printreswdnode(HashNode hn, int printflags)
 /* hash table containing the aliases */
  
 /**/
-HashTable aliastab;
+mod_export HashTable aliastab;
  
 /* Create new hash table for aliases */
 
@@ -1028,7 +1028,7 @@ createaliastable(void)
 /* Create a new alias node */
 
 /**/
-Alias
+mod_export Alias
 createaliasnode(char *txt, int flags)
 {
     Alias al;
@@ -1133,7 +1133,7 @@ printaliasnode(HashNode hn, int printflags)
 /* hash table containing named directories */
 
 /**/
-HashTable nameddirtab;
+mod_export HashTable nameddirtab;
  
 /* != 0 if all the usernames have already been *
  * added to the named directory hash table.    */
diff --git a/Src/hist.c b/Src/hist.c
index d531923c0..9bb809747 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -34,7 +34,7 @@
  * word control. */
 
 /**/
-int (*hgetc) _((void));
+mod_export int (*hgetc) _((void));
 
 /**/
 void (*hungetc) _((int));
@@ -54,7 +54,7 @@ void (*addtoline) _((int));
 /* != 0 means history substitution is turned off */
  
 /**/
-int stophist;
+mod_export int stophist;
  
 /* this line began with a space, so junk it if HISTIGNORESPACE is on */
  
@@ -64,12 +64,12 @@ int spaceflag;
 /* if != 0, we are expanding the current line */
 
 /**/
-int expanding;
+mod_export int expanding;
 
 /* these are used to modify the cursor position during expansion */
 
 /**/
-int excs, exlast;
+mod_export int excs, exlast;
 
 /*
  * Current history event number
@@ -84,7 +84,7 @@ int excs, exlast;
  */
  
 /**/
-int curhist;
+mod_export int curhist;
 
 /**/
 struct histent curline;
@@ -99,7 +99,7 @@ int histlinect;
 /**/
 HashTable histtab;
 /**/
-Histent hist_ring;
+mod_export Histent hist_ring;
  
 /* capacity of history lists */
  
@@ -126,7 +126,7 @@ int hist_ignore_all_dups;
 /* What flags (if any) we should skip when moving through the history */
 
 /**/
-int hist_skip_flags;
+mod_export int hist_skip_flags;
 
 /* Bits of histactive variable */
 #define HA_ACTIVE	(1<<0)	/* History mechanism is active */
@@ -159,12 +159,12 @@ char *hsubr;
 /* pointer into the history line */
  
 /**/
-char *hptr;
+mod_export char *hptr;
  
 /* the current history line */
  
 /**/
-char *chline;
+mod_export char *chline;
 
 /* true if the last character returned by hgetc was an escaped bangchar *
  * if it is set and NOBANGHIST is unset hwaddc escapes bangchars        */
@@ -670,7 +670,7 @@ ihungetc(int c)
 /* begin reading a string */
 
 /**/
-void
+mod_export void
 strinbeg(int dohist)
 {
     strin++;
@@ -681,7 +681,7 @@ strinbeg(int dohist)
 /* done reading a string */
 
 /**/
-void
+mod_export void
 strinend(void)
 {
     hend();
@@ -798,7 +798,7 @@ histremovedups(void)
 }
 
 /**/
-int
+mod_export int
 addhistnum(int hl, int n, int xflags)
 {
     int dir = n < 0? -1 : n > 0? 1 : 0;
@@ -816,7 +816,7 @@ addhistnum(int hl, int n, int xflags)
 }
 
 /**/
-Histent
+mod_export Histent
 movehistent(Histent he, int n, int xflags)
 {
     while (n < 0) {
@@ -835,14 +835,14 @@ movehistent(Histent he, int n, int xflags)
 }
 
 /**/
-Histent
+mod_export Histent
 up_histent(Histent he)
 {
     return he->up == hist_ring? NULL : he->up;
 }
 
 /**/
-Histent
+mod_export Histent
 down_histent(Histent he)
 {
     return he == hist_ring? NULL : he->down;
@@ -1182,7 +1182,7 @@ hwrep(char *rep)
 /* Get the entire current line, deleting it in the history. */
 
 /**/
-char *
+mod_export char *
 hgetline(void)
 {
     /* Currently only used by pushlineoredit().
@@ -1329,7 +1329,7 @@ rembutext(char **junkptr)
 }
 
 /**/
-int
+mod_export int
 remlpaths(char **junkptr)
 {
     char *str = *junkptr, *remcut;
@@ -1434,7 +1434,7 @@ convamps(char *out, char *in, int inlen)
 }
 
 /**/
-Histent
+mod_export Histent
 quietgethistent(int ev, int nearmatch)
 {
     if (ev == curhist && (histactive & HA_ACTIVE)) {
@@ -1446,7 +1446,7 @@ quietgethistent(int ev, int nearmatch)
 }
 
 /**/
-Histent
+mod_export Histent
 quietgethist(int ev)
 {
     return quietgethistent(ev, GETHIST_EXACT);
diff --git a/Src/init.c b/Src/init.c
index 97627c4d6..c53c81622 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -53,38 +53,40 @@ int sourcelevel;
 /* the shell tty fd */
 
 /**/
-int SHTTY;
+mod_export int SHTTY;
 
 /* the FILE attached to the shell tty */
 
 /**/
-FILE *shout;
+mod_export FILE *shout;
 
 /* termcap strings */
  
 /**/
-char *tcstr[TC_COUNT];
+mod_export char *tcstr[TC_COUNT];
 
 /* lengths of each termcap string */
  
 /**/
-int tclen[TC_COUNT];
+mod_export int tclen[TC_COUNT];
 
 /* Values of the li, co and am entries */
 
 /**/
-int tclines, tccolumns, hasam;
+int tclines, tccolumns;
+/**/
+mod_export int hasam;
 
 /* Pointer to read-key function from zle */
 
 /**/
-int (*getkeyptr) _((int));
+mod_export int (*getkeyptr) _((int));
 
 #ifdef DEBUG
 /* depth of allocation type stack */
 
 /**/
-int alloc_stackp;
+mod_export int alloc_stackp;
 #endif
 
 /* keep executing lists until EOF found */
@@ -287,7 +289,7 @@ parseargs(char **argv)
 
 
 /**/
-void
+mod_export void
 init_io(void)
 {
     long ttpgrp;
@@ -412,7 +414,7 @@ init_io(void)
 }
 
 /**/
-void
+mod_export void
 init_shout(void)
 {
     static char shoutbuf[BUFSIZ];
@@ -446,7 +448,7 @@ static char *tccapnams[TC_COUNT] = {
 /* Initialise termcap */
 
 /**/
-int
+mod_export int
 init_term(void)
 {
 #ifndef TGETENT_ACCEPTS_NULL
@@ -945,14 +947,14 @@ init_bltinmods(void)
 }
 
 /**/
-void
+mod_export void
 noop_function(void)
 {
     /* do nothing */
 }
 
 /**/
-void
+mod_export void
 noop_function_int(int nothing)
 {
     /* do nothing */
@@ -966,26 +968,26 @@ noop_function_int(int nothing)
 #ifdef LINKED_XMOD_zle
 
 /**/
-ZleVoidFn trashzleptr = noop_function;
+mod_export ZleVoidFn trashzleptr = noop_function;
 /**/
-ZleVoidFn gotwordptr = noop_function;
+mod_export ZleVoidFn gotwordptr = noop_function;
 /**/
-ZleVoidFn refreshptr = noop_function;
+mod_export ZleVoidFn refreshptr = noop_function;
 /**/
-ZleVoidIntFn spaceinlineptr = noop_function_int;
+mod_export ZleVoidIntFn spaceinlineptr = noop_function_int;
 /**/
-ZleReadFn zlereadptr = autoload_zleread;
+mod_export ZleReadFn zlereadptr = autoload_zleread;
 
 #else /* !LINKED_XMOD_zle */
 
-ZleVoidFn trashzleptr = noop_function;
-ZleVoidFn gotwordptr = noop_function;
-ZleVoidFn refreshptr = noop_function;
-ZleVoidIntFn spaceinlineptr = noop_function_int;
+mod_export ZleVoidFn trashzleptr = noop_function;
+mod_export ZleVoidFn gotwordptr = noop_function;
+mod_export ZleVoidFn refreshptr = noop_function;
+mod_export ZleVoidIntFn spaceinlineptr = noop_function_int;
 # ifdef UNLINKED_XMOD_zle
-ZleReadFn zlereadptr = autoload_zleread;
+mod_export ZleReadFn zlereadptr = autoload_zleread;
 # else /* !UNLINKED_XMOD_zle */
-ZleReadFn zlereadptr = fallback_zleread;
+mod_export ZleReadFn zlereadptr = fallback_zleread;
 # endif /* !UNLINKED_XMOD_zle */
 
 #endif /* !LINKED_XMOD_zle */
@@ -1000,7 +1002,7 @@ autoload_zleread(char *lp, char *rp, int ha)
 }
 
 /**/
-unsigned char *
+mod_export unsigned char *
 fallback_zleread(char *lp, char *rp, int ha)
 {
     char *pptbuf;
@@ -1015,10 +1017,10 @@ fallback_zleread(char *lp, char *rp, int ha)
 /* compctl entry point pointers.  Similar to the ZLE ones. */
 
 /**/
-CompctlReadFn compctlreadptr = fallback_compctlread;
+mod_export CompctlReadFn compctlreadptr = fallback_compctlread;
 
 /**/
-int
+mod_export int
 fallback_compctlread(char *name, char **args, char *ops, char *reply)
 {
     zwarnnam(name, "option valid only in functions called from completion",
diff --git a/Src/input.c b/Src/input.c
index d05c75c0b..f90ac7b00 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -88,7 +88,7 @@ int strin;
 /* total # of characters waiting to be read. */
 
 /**/
-int inbufct;
+mod_export int inbufct;
 
 /* the flags controlling the input routines in input.c: see INP_* in zsh.h */
 
@@ -128,7 +128,7 @@ static int instacksz = INSTACK_INITIAL;
  * null characters to Meta c^32 character pairs. */
 
 /**/
-char *
+mod_export char *
 shingetline(void)
 {
     char *line = NULL;
@@ -444,7 +444,7 @@ inerrflush(void)
 /* Set some new input onto a new element of the input stack */
 
 /**/
-void
+mod_export void
 inpush(char *str, int flags, Alias inalias)
 {
     if (!instack) {
@@ -532,7 +532,7 @@ inpoptop(void)
 /* Remove the top element of the stack and all its continuations. */
 
 /**/
-void
+mod_export void
 inpop(void)
 {
     int remcont;
diff --git a/Src/jobs.c b/Src/jobs.c
index e2450cdc1..e66d3b3fd 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -33,12 +33,12 @@
 /* the process group of the shell */
 
 /**/
-pid_t mypgrp;
+mod_export pid_t mypgrp;
  
 /* the job we are working on */
  
 /**/
-int thisjob;
+mod_export int thisjob;
 
 /* the current job (+) */
  
@@ -53,7 +53,7 @@ int prevjob;
 /* the job table */
  
 /**/
-struct job jobtab[MAXJOB];
+mod_export struct job jobtab[MAXJOB];
  
 /* shell timings */
  
@@ -906,7 +906,7 @@ waitjobs(void)
 /* clear job table when entering subshells */
 
 /**/
-void
+mod_export void
 clearjobtab(void)
 {
     int i;
diff --git a/Src/lex.c b/Src/lex.c
index 2285208fc..092d977ed 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -33,24 +33,28 @@
 /* tokens */
 
 /**/
-char ztokens[] = "#$^*()$=|{}[]`<>?~`,'\"\\";
+mod_export char ztokens[] = "#$^*()$=|{}[]`<>?~`,'\"\\";
 
 /* parts of the current token */
 
 /**/
-char *yytext, *tokstr;
+char *yytext;
 /**/
-int tok, tokfd;
+mod_export char *tokstr;
+/**/
+mod_export int tok;
+/**/
+int tokfd;
 
 /* lexical analyzer error flag */
  
 /**/
-int lexstop;
+mod_export int lexstop;
 
 /* if != 0, this is the first line of the command */
  
 /**/
-int isfirstln;
+mod_export int isfirstln;
  
 /* if != 0, this is the first char of the command (not including white space) */
  
@@ -70,47 +74,48 @@ int nocorrect;
 /* the line buffer */
 
 /**/
-unsigned char *line;
+mod_export unsigned char *line;
 
 /* cursor position and line length */
+/* N.B.: must use the real names here, for the .export file */
 
 /**/
-int cs, ll;
+mod_export int zshcs, zshll;
 
 /* inwhat says what exactly we are in     *
  * (its value is one of the IN_* things). */
 
 /**/
-int inwhat;
+mod_export int inwhat;
 
 /* 1 if x added to complete in a blank between words */
 
 /**/
-int addedx;
+mod_export int addedx;
 
 /* 1 if aliases should not be expanded */
  
 /**/
-int noaliases;
+mod_export int noaliases;
 
 /* we are parsing a line sent to use by the editor */
  
 /**/
-int zleparse;
+mod_export int zleparse;
  
 /**/
-int wordbeg;
+mod_export int wordbeg;
  
 /**/
-int parbegin;
+mod_export int parbegin;
 
 /**/
-int parend;
+mod_export int parend;
  
 /* text of puctuation tokens */
 
 /**/
-char *tokstrings[WHILE + 1] = {
+mod_export char *tokstrings[WHILE + 1] = {
     NULL,	/* NULLTOK	  0  */
     ";",	/* SEPER	     */
     "\\n",	/* NEWLIN	     */
@@ -197,7 +202,7 @@ static struct lexstack *lstack = NULL;
 /* is this a hack or what? */
 
 /**/
-void
+mod_export void
 lexsave(void)
 {
     struct lexstack *ls;
@@ -250,7 +255,7 @@ lexsave(void)
 /* restore lexical state */
 
 /**/
-void
+mod_export void
 lexrestore(void)
 {
     struct lexstack *ln;
@@ -332,7 +337,7 @@ yylex(void)
 }
 
 /**/
-void
+mod_export void
 ctxtlex(void)
 {
     static int oldpos;
@@ -1351,7 +1356,7 @@ dquote_parse(char endchar, int sub)
  * quotes.  This is usually called before singsub().          */
 
 /**/
-int
+mod_export int
 parsestr(char *s)
 {
     int l = strlen(s), err;
diff --git a/Src/linklist.c b/Src/linklist.c
index e3cb4d626..9c8ed44be 100644
--- a/Src/linklist.c
+++ b/Src/linklist.c
@@ -33,7 +33,7 @@
 /* Get an empty linked list header */
 
 /**/
-LinkList
+mod_export LinkList
 newlinklist(void)
 {
     LinkList list;
@@ -47,7 +47,7 @@ newlinklist(void)
 /* Insert a node in a linked list after a given node */
 
 /**/
-LinkNode
+mod_export LinkNode
 insertlinknode(LinkList list, LinkNode node, void *dat)
 {
     LinkNode tmp, new;
@@ -67,7 +67,7 @@ insertlinknode(LinkList list, LinkNode node, void *dat)
 /* Insert an already-existing node into a linked list after a given node */
 
 /**/
-LinkNode
+mod_export LinkNode
 uinsertlinknode(LinkList list, LinkNode node, LinkNode new)
 {
     LinkNode tmp = node->next;
@@ -104,7 +104,7 @@ insertlinklist(LinkList l, LinkNode where, LinkList x)
 /* Get top node in a linked list */
 
 /**/
-void *
+mod_export void *
 getlinknode(LinkList list)
 {
     void *dat;
@@ -125,7 +125,7 @@ getlinknode(LinkList list)
 /* Get top node in a linked list without freeing */
 
 /**/
-void *
+mod_export void *
 ugetnode(LinkList list)
 {
     void *dat;
@@ -145,7 +145,7 @@ ugetnode(LinkList list)
 /* Remove a node from a linked list */
 
 /**/
-void *
+mod_export void *
 remnode(LinkList list, LinkNode nd)
 {
     void *dat;
@@ -164,7 +164,7 @@ remnode(LinkList list, LinkNode nd)
 /* Remove a node from a linked list without freeing */
 
 /**/
-void *
+mod_export void *
 uremnode(LinkList list, LinkNode nd)
 {
     void *dat;
@@ -181,7 +181,7 @@ uremnode(LinkList list, LinkNode nd)
 /* Free a linked list */
 
 /**/
-void
+mod_export void
 freelinklist(LinkList list, FreeFunc freefunc)
 {
     LinkNode node, next;
@@ -198,7 +198,7 @@ freelinklist(LinkList list, FreeFunc freefunc)
 /* Count the number of nodes in a linked list */
 
 /**/
-int
+mod_export int
 countlinknodes(LinkList list)
 {
     LinkNode nd;
diff --git a/Src/loop.c b/Src/loop.c
index b74de41ed..b81ce29aa 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -43,7 +43,7 @@ int contflag;
 /* # of break levels */
  
 /**/
-int breaks;
+mod_export int breaks;
 
 /**/
 int
diff --git a/Src/makepro.awk b/Src/makepro.awk
index 98167fcad..350b2f9c8 100644
--- a/Src/makepro.awk
+++ b/Src/makepro.awk
@@ -77,13 +77,14 @@ BEGIN {
 	    break
     }
     sub(/^ */, "", line)
-    match(line, /^((const|enum|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
+    match(line, /^((const|enum|mod_export|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
     dtype = substr(line, 1, RLENGTH)
     sub(/ *$/, "", dtype)
     if(" " dtype " " ~ / static /)
 	locality = "L"
     else
 	locality = "E"
+    exported = " " dtype " " ~ / mod_export /
     line = substr(line, RLENGTH+1) ","
     # Handle each declarator.
     while(match(line, /^[^,]*,/)) {
@@ -117,6 +118,10 @@ BEGIN {
 	    printf "%s# endif\n", locality
 	}
 
+	# If this is exported, add it to the exported symbol list.
+	if(exported)
+	    printf "X%s\n", dnam
+
 	# Format the declaration for output
 	dcl = dtype " " dcltor ";"
 	if(locality ~ /E/)
diff --git a/Src/math.c b/Src/math.c
index 1f073ba2e..5c63d290f 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -911,7 +911,7 @@ mathevall(char *s, int prek, char **ep)
 
 
 /**/
-mnumber
+mod_export mnumber
 matheval(char *s)
 {
     char *junk;
diff --git a/Src/mem.c b/Src/mem.c
index 9d0073cbc..11db94fe3 100644
--- a/Src/mem.c
+++ b/Src/mem.c
@@ -76,13 +76,13 @@
 /* != 0 if we are allocating in the heaplist */
  
 /**/
-int useheap;
+mod_export int useheap;
 
 /* Current allocation pointers.  ncalloc() is either zalloc() or zhalloc(); *
  * alloc() is either zcalloc() or hcalloc().                               */
 
 /**/
-void *(*ncalloc) _((size_t)), *(*alloc) _((size_t));
+mod_export void *(*ncalloc) _((size_t)), *(*alloc) _((size_t));
 
 #ifdef ZSH_MEM_WARNING
 # ifndef DEBUG
@@ -110,7 +110,7 @@ union mem_align {
 /* set default allocation to heap stack */
 
 /**/
-int
+mod_export int
 global_heapalloc(void)
 {
     int luh = useheap;
@@ -124,7 +124,7 @@ global_heapalloc(void)
 /* set default allocation to malloc() */
 
 /**/
-int
+mod_export int
 global_permalloc(void)
 {
     int luh = useheap;
@@ -146,7 +146,7 @@ static Heap fheap;
 /* Use new heaps from now on. This returns the old heap-list. */
 
 /**/
-Heap
+mod_export Heap
 new_heaps(void)
 {
     Heap h = heaps;
@@ -159,7 +159,7 @@ new_heaps(void)
 /* Re-install the old heaps again, freeing the new ones. */
 
 /**/
-void
+mod_export void
 old_heaps(Heap old)
 {
     Heap h, n;
@@ -176,7 +176,7 @@ old_heaps(Heap old)
 /* Temporarily switch to other heaps (or back again). */
 
 /**/
-Heap
+mod_export Heap
 switch_heaps(Heap new)
 {
     Heap h = heaps;
@@ -190,7 +190,7 @@ switch_heaps(Heap new)
 /* save states of zsh heaps */
 
 /**/
-void
+mod_export void
 pushheap(void)
 {
     Heap h;
@@ -212,7 +212,7 @@ pushheap(void)
 /* reset heaps to previous state */
 
 /**/
-void
+mod_export void
 freeheap(void)
 {
     Heap h, hn, hl = NULL;
@@ -244,7 +244,7 @@ freeheap(void)
 /* reset heap to previous state and destroy state information */
 
 /**/
-void
+mod_export void
 popheap(void)
 {
     Heap h, hn, hl = NULL;
@@ -280,7 +280,7 @@ popheap(void)
 /* allocate memory from the current memory pool */
 
 /**/
-void *
+mod_export void *
 zhalloc(size_t size)
 {
     Heap h;
@@ -337,7 +337,7 @@ zhalloc(size_t size)
 }
 
 /**/
-void *
+mod_export void *
 hrealloc(char *p, size_t old, size_t new)
 {
     Heap h, ph;
@@ -413,7 +413,7 @@ hrealloc(char *p, size_t old, size_t new)
 /* allocate memory from the current memory pool and clear it */
 
 /**/
-void *
+mod_export void *
 hcalloc(size_t size)
 {
     void *ptr;
@@ -426,7 +426,7 @@ hcalloc(size_t size)
 /* allocate permanent memory */
 
 /**/
-void *
+mod_export void *
 zalloc(size_t size)
 {
     void *ptr;
@@ -442,7 +442,7 @@ zalloc(size_t size)
 }
 
 /**/
-void *
+mod_export void *
 zcalloc(size_t size)
 {
     void *ptr;
@@ -465,7 +465,7 @@ zcalloc(size_t size)
  * POSIX compliant, but I'm not sure how to do that.                */
 
 /**/
-void *
+mod_export void *
 zrealloc(void *ptr, size_t size)
 {
     if (ptr) {
@@ -490,7 +490,7 @@ zrealloc(void *ptr, size_t size)
 }
 
 /**/
-char *
+mod_export char *
 dupstring(const char *s)
 {
     char *t;
@@ -503,7 +503,7 @@ dupstring(const char *s)
 }
 
 /**/
-char *
+mod_export char *
 ztrdup(const char *s)
 {
     char *t;
@@ -515,6 +515,7 @@ ztrdup(const char *s)
     return t;
 }
 
+/**/
 #ifdef ZSH_MEM
 
 /*
@@ -913,7 +914,7 @@ malloc(MALLOC_ARG_T size)
    0 for this parameter means: `don't know' */
 
 /**/
-void
+mod_export void
 zfree(void *p, int sz)
 {
     struct m_hdr *m = (struct m_hdr *)(((char *)p) - M_ISIZE), *mp, *mt = NULL;
@@ -1120,7 +1121,7 @@ free(FREE_ARG_T p)
    those that have a zero byte at the end) */
 
 /**/
-void
+mod_export void
 zsfree(char *p)
 {
     if (p)
@@ -1327,10 +1328,11 @@ bin_mem(char *name, char **argv, char *ops, int func)
 
 #endif
 
+/**/
 #else				/* not ZSH_MEM */
 
 /**/
-void
+mod_export void
 zfree(void *p, int sz)
 {
     if (p)
@@ -1338,11 +1340,12 @@ zfree(void *p, int sz)
 }
 
 /**/
-void
+mod_export void
 zsfree(char *p)
 {
     if (p)
 	free(p);
 }
 
+/**/
 #endif
diff --git a/Src/mkmakemod.sh b/Src/mkmakemod.sh
index eaf7026e5..aa7558452 100644
--- a/Src/mkmakemod.sh
+++ b/Src/mkmakemod.sh
@@ -185,7 +185,7 @@ if $first_stage; then
 	imports=
 	for dep in $moddeps; do
 	    eval "loc=\$loc_$dep"
-	    imports="$imports \$(IMPOPT)\$(sdir_top)/$loc/$dep.export"
+	    imports="$imports \$(IMPOPT)\$(dir_top)/$loc/$dep.export"
 	    case $the_subdir in
 		$loc)
 		    mdh="${dep}.mdh"
@@ -215,17 +215,20 @@ if $first_stage; then
 	echo "SYMS_${module} = $proto"
 	echo "EPRO_${module} = "`echo $proto '' | sed 's,\.syms ,.epro ,g'`
 	echo "INCS_${module} = \$(EPRO_${module}) $otherincs"
-	echo "EXPIMP_${module} = $imports ${hasexport+\$(EXPOPT)\$(sdir)/$module.export}"
+	echo "EXPIMP_${module} = $imports \$(EXPOPT)$module.export"
 	echo "NXPIMP_${module} ="
 	echo
-	echo "proto.${module}: \$(PRO_${module})"
+	echo "proto.${module}: \$(EPRO_${module})"
 	echo "\$(SYMS_${module}): \$(PROTODEPS)"
 	echo
+	echo "${module}.export: \$(SYMS_${module})"
+	echo "	( echo '#!'; cat \$(SYMS_${module}) | sed -n '/^X/{s/^X//;p;}' | sort -u ) > \$@"
+	echo
 	echo "modobjs.${module}: \$(MODOBJS_${module})"
 	echo "	echo '' \$(MODOBJS_${module}) $modobjs_sed>> \$(dir_src)/stamp-modobjs.tmp"
 	echo
 	if test -z "$alwayslink"; then
-	    echo "${module}.\$(DL_EXT): \$(MODDOBJS_${module})"
+	    echo "${module}.\$(DL_EXT): \$(MODDOBJS_${module}) ${module}.export"
 	    echo '	rm -f $@'
 	    echo "	\$(DLLINK) \$(@E@XPIMP_$module) \$(@E@NTRYOPT) \$(MODDOBJS_${module}) \$(LIBS)"
 	    echo
diff --git a/Src/module.c b/Src/module.c
index faa9d30ed..aa62a163d 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -134,7 +134,7 @@ addbuiltin(Builtin b)
  *  return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); */
 
 /**/
-int
+mod_export int
 addbuiltins(char const *nam, Builtin binl, int size)
 {
     int hads = 0, hadf = 0, n;
@@ -163,7 +163,7 @@ FuncWrap wrappers;
  * error and zero if all went fine. */
 
 /**/
-int
+mod_export int
 addwrapper(Module m, FuncWrap w)
 {
     FuncWrap p, q;
@@ -190,7 +190,7 @@ char **module_path;
 /* List of modules */
 
 /**/
-LinkList modules;
+mod_export LinkList modules;
 
 /* Define an autoloadable builtin.  It returns 0 on success, or 1 on *
  * failure.  The only possible cause of failure is that a builtin    *
@@ -232,7 +232,7 @@ deletebuiltin(char *nam)
  * wayward module had deleted our builtin without telling us.           */
 
 /**/
-int
+mod_export int
 deletebuiltins(char const *nam, Builtin binl, int size)
 {
     int hads = 0, hadf = 0, n;
@@ -255,7 +255,7 @@ deletebuiltins(char const *nam, Builtin binl, int size)
  * one in case of error and zero otherwise. */
 
 /**/
-int
+mod_export int
 deletewrapper(Module m, FuncWrap w)
 {
     FuncWrap p, q;
@@ -760,7 +760,7 @@ load_module(char const *name)
  * The return value is non-zero if the module was found or loaded. */
 
 /**/
-int
+mod_export int
 require_module(char *nam, char *module, int res, int test)
 {
     Module m = NULL;
@@ -1427,7 +1427,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
 /* The list of module-defined conditions. */
 
 /**/
-Conddef condtab;
+mod_export Conddef condtab;
 
 /* This gets a condition definition with the given name. The first        *
  * argument says if we have to look for an infix condition. The last      *
@@ -1488,7 +1488,7 @@ addconddef(Conddef c)
 /* This adds multiple condition definitions. This is like addbuiltins(). */
 
 /**/
-int
+mod_export int
 addconddefs(char const *nam, Conddef c, int size)
 {
     int hads = 0, hadf = 0;
@@ -1551,7 +1551,7 @@ addhookdef(Hookdef h)
 /* This adds multiple hook definitions. This is like addbuiltins(). */
 
 /**/
-int
+mod_export int
 addhookdefs(char const *nam, Hookdef h, int size)
 {
     int hads = 0, hadf = 0;
@@ -1589,7 +1589,7 @@ deletehookdef(Hookdef h)
 }
 
 /**/
-int
+mod_export int
 deletehookdefs(char const *nam, Hookdef h, int size)
 {
     while (size--) {
@@ -1612,7 +1612,7 @@ addhookdeffunc(Hookdef h, Hookfn f)
 }
 
 /**/
-int
+mod_export int
 addhookfunc(char *n, Hookfn f)
 {
     Hookdef h = gethookdef(n);
@@ -1639,7 +1639,7 @@ deletehookdeffunc(Hookdef h, Hookfn f)
 }
 
 /**/
-int
+mod_export int
 deletehookfunc(char *n, Hookfn f)
 {
     Hookdef h = gethookdef(n);
@@ -1652,7 +1652,7 @@ deletehookfunc(char *n, Hookfn f)
 /* Run the function(s) for a hook. */
 
 /**/
-int
+mod_export int
 runhookdef(Hookdef h, void *d)
 {
     if (empty(h->funcs)) {
@@ -1712,7 +1712,7 @@ addparamdef(Paramdef d)
 /* This adds multiple parameter definitions. This is like addbuiltins(). */
 
 /**/
-int
+mod_export int
 addparamdefs(char const *nam, Paramdef d, int size)
 {
     int hads = 0, hadf = 0;
@@ -1739,7 +1739,7 @@ deleteparamdef(Paramdef d)
 }
 
 /**/
-int
+mod_export int
 deleteparamdefs(char const *nam, Paramdef d, int size)
 {
     while (size--) {
@@ -1802,7 +1802,7 @@ deleteconddef(Conddef c)
 /* This removes multiple condition definitions (like deletebuiltins()). */
 
 /**/
-int
+mod_export int
 deleteconddefs(char const *nam, Conddef c, int size)
 {
     int hads = 0, hadf = 0;
@@ -1874,7 +1874,7 @@ getmathfunc(char *name, int autol)
 }
 
 /**/
-int
+mod_export int
 addmathfunc(MathFunc f)
 {
     MathFunc p;
@@ -1894,7 +1894,7 @@ addmathfunc(MathFunc f)
 }
 
 /**/
-int
+mod_export int
 addmathfuncs(char const *nam, MathFunc f, int size)
 {
     int hads = 0, hadf = 0;
@@ -1936,7 +1936,7 @@ add_automathfunc(char *nam, char *module)
 }
 
 /**/
-int
+mod_export int
 deletemathfunc(MathFunc f)
 {
     MathFunc p, q;
@@ -1962,7 +1962,7 @@ deletemathfunc(MathFunc f)
 }
 
 /**/
-int
+mod_export int
 deletemathfuncs(char const *nam, MathFunc f, int size)
 {
     int hads = 0, hadf = 0;
diff --git a/Src/options.c b/Src/options.c
index 2fd2ae373..1beee4b95 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -38,12 +38,12 @@ int emulation;
 /* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */
  
 /**/
-char opts[OPT_SIZE];
+mod_export char opts[OPT_SIZE];
  
 /* Option name hash table */
 
 /**/
-HashTable optiontab;
+mod_export HashTable optiontab;
  
 /* The canonical option name table */
 
@@ -559,7 +559,7 @@ bin_setopt(char *nam, char **args, char *ops, int isun)
 /* Identify an option name */
 
 /**/
-int
+mod_export int
 optlookup(char const *name)
 {
     char *s, *t;
@@ -622,7 +622,7 @@ static char *rparams[] = {
  * from the usual meaning of the option.                            */
 
 /**/
-int
+mod_export int
 dosetopt(int optno, int value, int force)
 {
     if(!optno)
diff --git a/Src/params.c b/Src/params.c
index c8778db3a..a34fb0733 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -35,58 +35,66 @@
 /* what level of localness we are at */
  
 /**/
-int locallevel;
+mod_export int locallevel;
  
 /* Variables holding values of special parameters */
  
 /**/
 char **pparams,		/* $argv        */
      **cdpath,		/* $cdpath      */
-     **fignore,		/* $fignore     */
      **fpath,		/* $fpath       */
      **mailpath,	/* $mailpath    */
      **manpath,		/* $manpath     */
-     **path,		/* $path        */
      **psvar,		/* $psvar       */
      **watch;		/* $watch       */
+/**/
+mod_export
+char **path,		/* $path        */
+     **fignore;		/* $fignore     */
  
 /**/
 char *argzero,		/* $0           */
      *home,		/* $HOME        */
      *hostnam,		/* $HOST        */
-     *ifs,		/* $IFS         */
      *nullcmd,		/* $NULLCMD     */
      *oldpwd,		/* $OLDPWD      */
      *zoptarg,		/* $OPTARG      */
-     *postedit,		/* $POSTEDIT    */
      *prompt,		/* $PROMPT      */
      *prompt2,		/* $PROMPT2     */
      *prompt3,		/* $PROMPT3     */
      *prompt4,		/* $PROMPT4     */
-     *pwd,		/* $PWD         */
      *readnullcmd,	/* $READNULLCMD */
      *rprompt,		/* $RPROMPT     */
      *sprompt,		/* $SPROMPT     */
      *term,		/* $TERM        */
-     *ttystrname,	/* $TTY         */
      *wordchars,	/* $WORDCHARS   */
      *zsh_name;		/* $ZSH_NAME    */
+/**/
+mod_export
+char *ifs,		/* $IFS         */
+     *postedit,		/* $POSTEDIT    */
+     *ttystrname,	/* $TTY         */
+     *pwd;		/* $PWD         */
 
 /**/
+mod_export
 zlong lastval,		/* $?           */
      mypid,		/* $$           */
      lastpid,		/* $!           */
      columns,		/* $COLUMNS     */
-     lineno,		/* $LINENO      */
      lines,		/* $LINES       */
+     ppid;		/* $PPID        */
+/**/
+zlong lineno,		/* $LINENO      */
      zoptind,		/* $OPTIND      */
-     ppid,		/* $PPID        */
      shlvl;		/* $SHLVL       */
 
 /* $histchars */
  
 /**/
-unsigned char bangchar, hatchar, hashchar;
+mod_export unsigned char bangchar;
+/**/
+unsigned char hatchar, hashchar;
  
 /* $SECONDS = time(NULL) - shtimer.tv_sec */
  
@@ -96,7 +104,7 @@ struct timeval shtimer;
 /* 0 if this $TERM setup is usable, otherwise it contains TERM_* flags */
 
 /**/
-int termflags;
+mod_export int termflags;
  
 /* Nodes for special parameters for parameter hash table */
 
@@ -248,10 +256,10 @@ static Param argvparam;
 /* hash table containing the parameters */
  
 /**/
-HashTable paramtab, realparamtab;
+mod_export HashTable paramtab, realparamtab;
 
 /**/
-HashTable
+mod_export HashTable
 newparamtable(int size, char const *name)
 {
     HashTable ht = newhashtable(size, name, NULL);
@@ -327,7 +335,7 @@ static int delunset;
 /* Function to delete a parameter table. */
 
 /**/
-void
+mod_export void
 deleteparamtable(HashTable t)
 {
     /* The parameters in the hash table need to be unset *
@@ -341,7 +349,7 @@ deleteparamtable(HashTable t)
 static unsigned numparamvals;
 
 /**/
-void
+mod_export void
 scancountparams(HashNode hn, int flags)
 {
     ++numparamvals;
@@ -586,7 +594,7 @@ assigngetset(Param pm)
  * created because it already exists, the PM_UNSET flag is cleared.        */
 
 /**/
-Param
+mod_export Param
 createparam(char *name, int flags)
 {
     Param pm, oldpm;
@@ -1162,14 +1170,14 @@ getindex(char **pptr, Value v)
 
 
 /**/
-Value
+mod_export Value
 getvalue(char **pptr, int bracks)
 {
   return fetchvalue(pptr, bracks, 0);
 }
 
 /**/
-Value
+mod_export Value
 fetchvalue(char **pptr, int bracks, int flags)
 {
     char *s, *t;
@@ -1265,7 +1273,7 @@ fetchvalue(char **pptr, int bracks, int flags)
 }
 
 /**/
-char *
+mod_export char *
 getstrvalue(Value v)
 {
     char *s, **ss;
@@ -1372,7 +1380,7 @@ getarrvalue(Value v)
 }
 
 /**/
-zlong
+mod_export zlong
 getintvalue(Value v)
 {
     if (!v || v->isarr)
@@ -1408,7 +1416,7 @@ getnumvalue(Value v)
 }
 
 /**/
-void
+mod_export void
 setstrvalue(Value v, char *val)
 {
     char buf[(sizeof(zlong) * 8) + 4];
@@ -1543,7 +1551,7 @@ setnumvalue(Value v, mnumber val)
 }
 
 /**/
-void
+mod_export void
 setarrvalue(Value v, char **val)
 {
     if (v->pm->flags & PM_READONLY) {
@@ -1611,7 +1619,7 @@ setarrvalue(Value v, char **val)
 /* Retrieve an integer parameter */
 
 /**/
-zlong
+mod_export zlong
 getiparam(char *s)
 {
     Value v;
@@ -1640,7 +1648,7 @@ getnparam(char *s)
 /* Retrieve a scalar (string) parameter */
 
 /**/
-char *
+mod_export char *
 getsparam(char *s)
 {
     Value v;
@@ -1653,7 +1661,7 @@ getsparam(char *s)
 /* Retrieve an array parameter */
 
 /**/
-char **
+mod_export char **
 getaparam(char *s)
 {
     Value v;
@@ -1667,7 +1675,7 @@ getaparam(char *s)
 /* Retrieve an assoc array parameter as an array */
 
 /**/
-char **
+mod_export char **
 gethparam(char *s)
 {
     Value v;
@@ -1679,7 +1687,7 @@ gethparam(char *s)
 }
 
 /**/
-Param
+mod_export Param
 setsparam(char *s, char *val)
 {
     Value v;
@@ -1717,7 +1725,7 @@ setsparam(char *s, char *val)
 }
 
 /**/
-Param
+mod_export Param
 setaparam(char *s, char **val)
 {
     Value v;
@@ -1761,7 +1769,7 @@ setaparam(char *s, char **val)
 }
 
 /**/
-Param
+mod_export Param
 sethparam(char *s, char **val)
 {
     Value v;
@@ -1856,7 +1864,7 @@ setnparam(char *s, mnumber val)
 /* Unset a parameter */
 
 /**/
-void
+mod_export void
 unsetparam(char *s)
 {
     Param pm;
@@ -1870,7 +1878,7 @@ unsetparam(char *s)
 /* Unset a parameter */
 
 /**/
-void
+mod_export void
 unsetparam_pm(Param pm, int altflag, int exp)
 {
     Param oldpm, altpm;
@@ -1933,7 +1941,7 @@ unsetparam_pm(Param pm, int altflag, int exp)
  * the specific set function.                                           */
 
 /**/
-void
+mod_export void
 stdunsetfn(Param pm, int exp)
 {
     switch (PM_TYPE(pm->flags)) {
@@ -1983,7 +1991,7 @@ floatsetfn(Param pm, double x)
 /* Function to get value of a scalar (string) parameter */
 
 /**/
-char *
+mod_export char *
 strgetfn(Param pm)
 {
     return pm->u.str ? pm->u.str : (char *) hcalloc(1);
@@ -2014,7 +2022,7 @@ arrgetfn(Param pm)
 /* Function to set value of an array parameter */
 
 /**/
-void
+mod_export void
 arrsetfn(Param pm, char **x)
 {
     if (pm->u.arr && pm->u.arr != x)
@@ -2030,7 +2038,7 @@ arrsetfn(Param pm, char **x)
 /* Function to get value of an association parameter */
 
 /**/
-HashTable
+mod_export HashTable
 hashgetfn(Param pm)
 {
     return pm->u.hash;
@@ -2039,7 +2047,7 @@ hashgetfn(Param pm)
 /* Function to set value of an association parameter */
 
 /**/
-void
+mod_export void
 hashsetfn(Param pm, HashTable x)
 {
     if (pm->u.hash && pm->u.hash != x)
@@ -2103,7 +2111,7 @@ nullsetfn(Param pm, char *x)
  * containing the integer value.                    */
 
 /**/
-zlong
+mod_export zlong
 intvargetfn(Param pm)
 {
     return *((zlong *)pm->u.data);
@@ -2114,7 +2122,7 @@ intvargetfn(Param pm)
  * where the value is to be stored.                 */
 
 /**/
-void
+mod_export void
 intvarsetfn(Param pm, zlong x)
 {
     *((zlong *)pm->u.data) = x;
@@ -2140,7 +2148,7 @@ zlevarsetfn(Param pm, zlong x)
  * representing the scalar (string).                  */
 
 /**/
-void
+mod_export void
 strvarsetfn(Param pm, char *x)
 {
     char **q = ((char **)pm->u.data);
@@ -2154,7 +2162,7 @@ strvarsetfn(Param pm, char *x)
  * representing the scalar (string).                  */
 
 /**/
-char *
+mod_export char *
 strvargetfn(Param pm)
 {
     char *s = *((char **)pm->u.data);
@@ -2170,7 +2178,7 @@ strvargetfn(Param pm)
  * of pointers).                                   */
 
 /**/
-char **
+mod_export char **
 arrvargetfn(Param pm)
 {
     return *((char ***)pm->u.data);
@@ -2183,7 +2191,7 @@ arrvargetfn(Param pm)
  * version of this array which will need to be updated.         */
 
 /**/
-void
+mod_export void
 arrvarsetfn(Param pm, char **x)
 {
     char ***dptr = (char ***)pm->u.data;
@@ -2688,7 +2696,7 @@ arrfixenv(char *s, char **t)
  * "foo=bar", and returns a pointer to the beginning of "bar" */
 
 /**/
-char *
+mod_export char *
 zgetenv(char *name)
 {
     char **ep, *s, *t;
@@ -2800,7 +2808,7 @@ delenv(char *x)
 }
 
 /**/
-void
+mod_export void
 convbase(char *s, zlong v, int base)
 {
     int digs = 0;
@@ -2888,7 +2896,7 @@ convfloat(double dval, int digits, int flags, FILE *fout)
 /* Start a parameter scope */
 
 /**/
-void
+mod_export void
 startparamscope(void)
 {
     locallevel++;
@@ -2897,7 +2905,7 @@ startparamscope(void)
 /* End a parameter scope: delete the parameters local to the scope. */
 
 /**/
-void
+mod_export void
 endparamscope(void)
 {
     locallevel--;
@@ -2980,7 +2988,7 @@ freeparamnode(HashNode hn)
 /* Print a parameter */
 
 /**/
-void
+mod_export void
 printparamnode(HashNode hn, int printflags)
 {
     Param p = (Param) hn;
diff --git a/Src/parse.c b/Src/parse.c
index e92eabf68..abaca9ece 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -33,17 +33,17 @@
 /* != 0 if we are about to read a command word */
  
 /**/
-int incmdpos;
+mod_export int incmdpos;
  
 /* != 0 if we are in the middle of a [[ ... ]] */
  
 /**/
-int incond;
+mod_export int incond;
  
 /* != 0 if we are after a redirection (for ctxtlex only) */
  
 /**/
-int inredir;
+mod_export int inredir;
  
 /* != 0 if we are about to read a case pattern */
  
@@ -68,7 +68,7 @@ struct heredocs *hdocs;
 /* used in arrays of lists instead of NULL pointers */
  
 /**/
-struct list dummy_list;
+mod_export struct list dummy_list;
 
 #define YYERROR  { tok = LEXERR; return NULL; }
 #define YYERRORV { tok = LEXERR; return; }
diff --git a/Src/pattern.c b/Src/pattern.c
index 6b503e36d..35e11161b 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -292,7 +292,7 @@ patcompstart(void)
 /* Top level pattern compilation subroutine */
 
 /**/
-Patprog
+mod_export Patprog
 patcompile(char *exp, int inflags, char **endexp)
 {
     int flags = 0, len = 0;
@@ -1280,7 +1280,7 @@ pattrystart(void)
 }
 
 /**/
-int
+mod_export int
 pattry(Patprog prog, char *string)
 {
     int i;
@@ -2212,7 +2212,7 @@ duppatprog(Patprog prog)
 /* Free a patprog. */
 
 /**/
-void
+mod_export void
 freepatprog(Patprog prog)
 {
     if (prog && prog != dummy_patprog1 && prog != dummy_patprog2)
diff --git a/Src/prompt.c b/Src/prompt.c
index 632383736..1b5cded10 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -38,7 +38,7 @@ unsigned txtattrmask;
 /* text change - attribute change made by prompts */
 
 /**/
-unsigned txtchange;
+mod_export unsigned txtchange;
 
 /* the command stack for use with %_ in prompts */
  
@@ -137,7 +137,7 @@ promptpath(char *p, int npath, int tilde)
  * `glitch' space.                                               */
 
 /**/
-char *
+mod_export char *
 promptexpand(char *s, int ns, char *rs, char *Rs)
 {
     if(!s)
@@ -628,7 +628,7 @@ stradd(char *d)
 /* tsetcap(), among other things, can write a termcap string into the buffer. */
 
 /**/
-void
+mod_export void
 tsetcap(int cap, int flag)
 {
     if (!(termflags & TERM_SHORT) && tcstr[cap]) {
@@ -688,7 +688,7 @@ putstr(int d)
  * newlines require nontrivial processing.                          */
 
 /**/
-void
+mod_export void
 countprompt(char *str, int *wp, int *hp, int overf)
 {
     int w = 0, h = 1;
diff --git a/Src/signals.c b/Src/signals.c
index 5a2d62c25..1a28bf6cd 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -34,12 +34,12 @@
  * 0 for the default action or some ZSIG_* flags ored together.   */
 
 /**/
-int sigtrapped[VSIGCOUNT];
+mod_export int sigtrapped[VSIGCOUNT];
 
 /* trap functions for each signal */
 
 /**/
-List sigfuncs[VSIGCOUNT];
+mod_export List sigfuncs[VSIGCOUNT];
 
 /* Variables used by signal queueing */
 
@@ -82,7 +82,7 @@ static sigset_t blocked_set;
  * system calls are not restarted.                    */
 
 /**/
-void
+mod_export void
 install_handler(int sig)
 {
 #ifdef POSIX_SIGNALS
@@ -122,7 +122,7 @@ install_handler(int sig)
 /* enable ^C interrupts */
  
 /**/
-void
+mod_export void
 intr(void)
 {
     if (interact)
@@ -143,7 +143,7 @@ nointr(void)
 /* temporarily block ^C interrupts */
  
 /**/
-void
+mod_export void
 holdintr(void)
 {
     if (interact)
@@ -153,7 +153,7 @@ holdintr(void)
 /* release ^C interrupts */
  
 /**/
-void
+mod_export void
 noholdintr(void)
 {
     if (interact)
@@ -682,7 +682,7 @@ dosavetrap(int sig, int level)
 }
 
 /**/
-int
+mod_export int
 settrap(int sig, List l)
 {
     if (sig == -1)
diff --git a/Src/signames2.awk b/Src/signames2.awk
index 51cda0f10..dbc7b71d0 100644
--- a/Src/signames2.awk
+++ b/Src/signames2.awk
@@ -63,7 +63,7 @@ END {
     printf "#include %czsh.mdh%c\n", 34, 34
     printf "\n"
     printf "/**/\n"
-    printf "char *sigmsg[SIGCOUNT+2] = {\n"
+    printf "mod_export char *sigmsg[SIGCOUNT+2] = {\n"
     printf "\t%c%s%c,\n", 34, "done", 34
 
     for (i = 1; i <= 0 + max; i++)
diff --git a/Src/subst.c b/Src/subst.c
index 00b22da28..6575dfbc7 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -46,7 +46,7 @@ char nulstring[] = {Nularg, '\0'};
  */
 
 /**/
-void
+mod_export void
 prefork(LinkList list, int flags)
 {
     LinkNode node;
@@ -211,7 +211,7 @@ stringsubst(LinkList list, LinkNode node, int ssub)
 }
 
 /**/
-void
+mod_export void
 globlist(LinkList list)
 {
     LinkNode node, next;
@@ -228,7 +228,7 @@ globlist(LinkList list)
 /* perform substitution on a single word */
 
 /**/
-void
+mod_export void
 singsub(char **s)
 {
     LinkList foo;
@@ -306,7 +306,7 @@ multsub(char **s, char ***a, int *isarr, char *sep)
  */
 
 /**/
-void
+mod_export void
 filesub(char **namptr, int assign)
 {
     char *sub = NULL, *str, *ptr;
@@ -341,7 +341,7 @@ filesub(char **namptr, int assign)
 }
 
 /**/
-int
+mod_export int
 filesubstr(char **namptr, int assign)
 {
 #define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
diff --git a/Src/text.c b/Src/text.c
index 0e7406970..fb1fdbb14 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -104,7 +104,7 @@ taddnl(void)
 /* get a permanent textual representation of n */
 
 /**/
-char *
+mod_export char *
 getpermtext(struct node *n)
 {
     tnewlins = 1;
diff --git a/Src/utils.c b/Src/utils.c
index 222fdbefe..ccf7ab94b 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -38,7 +38,7 @@ char *scriptname;
 /* Print an error */
  
 /**/
-void
+mod_export void
 zerr(const char *fmt, const char *str, int num)
 {
     if (errflag || noerrs) {
@@ -51,7 +51,7 @@ zerr(const char *fmt, const char *str, int num)
 }
 
 /**/
-void
+mod_export void
 zerrnam(const char *cmd, const char *fmt, const char *str, int num)
 {
     if (errflag || noerrs)
@@ -62,7 +62,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num)
 }
 
 /**/
-void
+mod_export void
 zwarn(const char *fmt, const char *str, int num)
 {
     if (errflag || noerrs)
@@ -81,7 +81,7 @@ zwarn(const char *fmt, const char *str, int num)
 }
 
 /**/
-void
+mod_export void
 zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
 {
     if (errflag || noerrs)
@@ -172,7 +172,7 @@ putraw(int c)
 /* Output a single character, for the termcap routines. */
 
 /**/
-int
+mod_export int
 putshout(int c)
 {
     putc(c, shout);
@@ -190,7 +190,7 @@ putshout(int c)
  * literal characters.                                                  */
 
 /**/
-char *
+mod_export char *
 nicechar(int c)
 {
     static char buf[6];
@@ -505,7 +505,7 @@ finddir(char *s)
 /* add a named directory */
 
 /**/
-void
+mod_export void
 adduserdir(char *s, char *t, int flags, int always)
 {
     Nameddir nd;
@@ -610,7 +610,7 @@ dircmp(char *s, char *t)
 /* extra functions to call before displaying the prompt */
 
 /**/
-LinkList prepromptfns;
+mod_export LinkList prepromptfns;
 
 /* the last time we checked mail */
  
@@ -806,7 +806,7 @@ printprompt4(void)
 }
 
 /**/
-void
+mod_export void
 freestr(void *a)
 {
     zsfree(a);
@@ -838,7 +838,7 @@ gettyinfo(struct ttyinfo *ti)
 }
 
 /**/
-void
+mod_export void
 settyinfo(struct ttyinfo *ti)
 {
     if (SHTTY != -1) {
@@ -870,18 +870,18 @@ settyinfo(struct ttyinfo *ti)
 /* the default tty state */
  
 /**/
-struct ttyinfo shttyinfo;
+mod_export struct ttyinfo shttyinfo;
 
 /* != 0 if we need to call resetvideo() */
 
 /**/
-int resetneeded;
+mod_export int resetneeded;
 
 #ifdef TIOCGWINSZ
 /* window size changed */
 
 /**/
-int winchanged;
+mod_export int winchanged;
 #endif
 
 static int
@@ -1017,7 +1017,7 @@ adjustwinsize(int from)
  * is already >= 10, it is not moved.  If it is invalid, -1 is returned. */
 
 /**/
-int
+mod_export int
 movefd(int fd)
 {
     if(fd != -1 && fd < 10) {
@@ -1043,7 +1043,7 @@ movefd(int fd)
 /* Move fd x to y.  If x == -1, fd y is closed. */
 
 /**/
-void
+mod_export void
 redup(int x, int y)
 {
     if(x < 0)
@@ -1061,7 +1061,7 @@ redup(int x, int y)
 /* Close the given fd, and clear it from fdtable. */
 
 /**/
-int
+mod_export int
 zclose(int fd)
 {
     if (fd >= 0) {
@@ -1080,7 +1080,7 @@ zclose(int fd)
  * is unique, for use as a temporary file.      */
  
 /**/
-char *
+mod_export char *
 gettempname(void)
 {
     char *s;
@@ -1094,7 +1094,7 @@ gettempname(void)
 /* Check if a string contains a token */
 
 /**/
-int
+mod_export int
 has_token(const char *s)
 {
     while(*s)
@@ -1106,7 +1106,7 @@ has_token(const char *s)
 /* Delete a character in a string */
  
 /**/
-void
+mod_export void
 chuck(char *str)
 {
     while ((str[0] = str[1]))
@@ -1114,7 +1114,7 @@ chuck(char *str)
 }
 
 /**/
-int
+mod_export int
 tulower(int c)
 {
     c &= 0xff;
@@ -1122,7 +1122,7 @@ tulower(int c)
 }
 
 /**/
-int
+mod_export int
 tuupper(int c)
 {
     c &= 0xff;
@@ -1143,7 +1143,7 @@ ztrncpy(char *s, char *t, int len)
 /* copy t into *s and update s */
 
 /**/
-void
+mod_export void
 strucpy(char **s, char *t)
 {
     char *u = *s;
@@ -1153,7 +1153,7 @@ strucpy(char **s, char *t)
 }
 
 /**/
-void
+mod_export void
 struncpy(char **s, char *t, int n)
 {
     char *u = *s;
@@ -1168,7 +1168,7 @@ struncpy(char **s, char *t, int n)
  * It doesn't count the NULL pointer at the end.          */
 
 /**/
-int
+mod_export int
 arrlen(char **s)
 {
     int count;
@@ -1180,7 +1180,7 @@ arrlen(char **s)
 /* Skip over a balanced pair of parenthesis. */
 
 /**/
-int
+mod_export int
 skipparens(char inpar, char outpar, char **s)
 {
     int level;
@@ -1202,7 +1202,7 @@ skipparens(char inpar, char outpar, char **s)
  * to be broken.                                                       */
 
 /**/
-zlong
+mod_export zlong
 zstrtol(const char *s, char **t, int base)
 {
     zlong ret = 0;
@@ -1384,7 +1384,7 @@ spscan(HashNode hn, int scanflags)
 /* fix s ; if hist is nonzero, fix the history list too */
 
 /**/
-void
+mod_export void
 spckword(char **s, int hist, int cmd, int ask)
 {
     char *t, *u;
@@ -1513,7 +1513,7 @@ spckword(char **s, int hist, int cmd, int ask)
 }
 
 /**/
-int
+mod_export int
 ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 {
     int hr12;
@@ -1613,7 +1613,7 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 }
 
 /**/
-char *
+mod_export char *
 zjoin(char **arr, int delim)
 {
     int len = 0;
@@ -1684,7 +1684,7 @@ skipwsep(char **s)
 }
 
 /**/
-char **
+mod_export char **
 spacesplit(char *s, int allownull)
 {
     char *t, **ret, **ptr;
@@ -1831,7 +1831,7 @@ wordcount(char *s, char *sep, int mul)
 }
 
 /**/
-char *
+mod_export char *
 sepjoin(char **s, char *sep)
 {
     char *r, *p, **t;
@@ -1890,7 +1890,7 @@ sepsplit(char *s, char *sep, int allownull)
 /* Get the definition of a shell function */
 
 /**/
-List
+mod_export List
 getshfunc(char *nam)
 {
     Shfunc shf;
@@ -1964,7 +1964,7 @@ allocnode(int type)
 /* duplicate a syntax tree */
 
 /**/
-void *
+mod_export void *
 dupstruct(void *a)
 {
     void **onodes, **nnodes, *ret, *n, *on;
@@ -2027,7 +2027,7 @@ dupstruct(void *a)
 static LinkList freeslist = NULL;
 
 /**/
-void
+mod_export void
 freestruct(void *a)
 {
     if (!a || ((List) a) == &dummy_list)
@@ -2171,7 +2171,7 @@ mkarray(char *s)
 }
 
 /**/
-void
+mod_export void
 zbeep(void)
 {
     char *vb;
@@ -2184,7 +2184,7 @@ zbeep(void)
 }
 
 /**/
-void
+mod_export void
 freearray(char **s)
 {
     char **t = s;
@@ -2212,7 +2212,7 @@ equalsplit(char *s, char **t)
 /* the ztypes table */
 
 /**/
-short int typtab[256];
+mod_export short int typtab[256];
 
 /* initialize the ztypes table */
 
@@ -2262,7 +2262,7 @@ inittyptab(void)
 }
 
 /**/
-char **
+mod_export char **
 arrdup(char **s)
 {
     char **x, **y;
@@ -2458,7 +2458,7 @@ setcbreak(void)
 /* give the tty to some process */
 
 /**/
-void
+mod_export void
 attachtty(pid_t pgrp)
 {
     static int ep = 0;
@@ -2638,7 +2638,7 @@ getbaudrate(struct ttyinfo *shttyinfo)
  *   META_HEAPDUP:  same as META_DUP, but uses the heap                      */
 
 /**/
-char *
+mod_export char *
 metafy(char *buf, int len, int heap)
 {
     int meta = 0;
@@ -2703,7 +2703,7 @@ metafy(char *buf, int len, int heap)
 }
 
 /**/
-char *
+mod_export char *
 unmetafy(char *s, int *len)
 {
     char *p, *t;
@@ -2721,7 +2721,7 @@ unmetafy(char *s, int *len)
  * unmetafied substring length.                                        */
 
 /**/
-int
+mod_export int
 metalen(const char *s, int len)
 {
     int mlen = len;
@@ -2741,7 +2741,7 @@ metalen(const char *s, int len)
  * 4 * PATH_MAX.                                                       */
 
 /**/
-char *
+mod_export char *
 unmeta(const char *file_name)
 {
     static char fn[4 * PATH_MAX];
@@ -2796,7 +2796,7 @@ ztrcmp(unsigned char const *s1, unsigned char const *s2)
  * 2 is r is the lowercase prefix of s and return 3 otherwise. */
 
 /**/
-int
+mod_export int
 metadiffer(char const *s, char const *r, int len)
 {
     int l = len;
@@ -2823,7 +2823,7 @@ metadiffer(char const *s, char const *r, int len)
 /* Return the unmetafied length of a metafied string. */
 
 /**/
-int
+mod_export int
 ztrlen(char const *s)
 {
     int l;
@@ -2843,7 +2843,7 @@ ztrlen(char const *s)
 /* Subtract two pointers in a metafied string. */
 
 /**/
-int
+mod_export int
 ztrsub(char const *t, char const *s)
 {
     int l = t - s;
@@ -2862,7 +2862,7 @@ ztrsub(char const *t, char const *s)
 }
 
 /**/
-char *
+mod_export char *
 zreaddir(DIR *dir, int ignoredots)
 {
     struct dirent *de;
@@ -2880,7 +2880,7 @@ zreaddir(DIR *dir, int ignoredots)
 /* Unmetafy and output a string.  Tokens are skipped. */
 
 /**/
-int
+mod_export int
 zputs(char const *s, FILE *stream)
 {
     int c;
@@ -2927,7 +2927,7 @@ nicedup(char const *s, int heap)
 }
 
 /**/
-char *
+mod_export char *
 niceztrdup(char const *s)
 {
     return nicedup(s, 0);
@@ -2943,7 +2943,7 @@ nicedupstring(char const *s)
 /* Unmetafy and output a string, displaying special characters readably. */
 
 /**/
-int
+mod_export int
 nicezputs(char const *s, FILE *stream)
 {
     int c;
@@ -2966,7 +2966,7 @@ nicezputs(char const *s, FILE *stream)
 /* Return the length of the visible representation of a metafied string. */
 
 /**/
-size_t
+mod_export size_t
 niceztrlen(char const *s)
 {
     size_t l = 0;
@@ -2989,7 +2989,7 @@ niceztrlen(char const *s)
 /* check for special characters in the string */
 
 /**/
-int
+mod_export int
 hasspecial(char const *s)
 {
     for (; *s; s++)
@@ -3007,7 +3007,7 @@ hasspecial(char const *s)
  * The string may be metafied and contain tokens.                           */
 
 /**/
-char *
+mod_export char *
 bslashquote(const char *s, char **e, int instring)
 {
     const char *u, *tt;
@@ -3118,7 +3118,7 @@ bslashquote(const char *s, char **e, int instring)
 /* Unmetafy and output a string, quoted if it contains special characters. */
 
 /**/
-int
+mod_export int
 quotedzputs(char const *s, FILE *stream)
 {
     int inquote = 0, c;
@@ -3193,7 +3193,7 @@ quotedzputs(char const *s, FILE *stream)
 /* Double-quote a metafied string. */
 
 /**/
-char *
+mod_export char *
 dquotedztrdup(char const *s)
 {
     int len = strlen(s) * 4 + 2;
@@ -3303,7 +3303,7 @@ dquotedzputs(char const *s, FILE *stream)
  */
 
 /**/
-char *
+mod_export char *
 getkeystring(char *s, int *len, int fromwhere, int *misc)
 {
     char *buf, tmp[1];
@@ -3460,7 +3460,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
 /* Return non-zero if s is a prefix of t. */
 
 /**/
-int
+mod_export int
 strpfx(char *s, char *t)
 {
     while (*s && *s == *t)
@@ -3471,7 +3471,7 @@ strpfx(char *s, char *t)
 /* Return non-zero if s is a suffix of t. */
 
 /**/
-int
+mod_export int
 strsfx(char *s, char *t)
 {
     int ls = strlen(s), lt = strlen(t);
@@ -3482,7 +3482,7 @@ strsfx(char *s, char *t)
 }
 
 /**/
-char *
+mod_export char *
 dupstrpfx(const char *s, int len)
 {
     char *r = ncalloc(len + 1);
@@ -3493,7 +3493,7 @@ dupstrpfx(const char *s, int len)
 }
 
 /**/
-char *
+mod_export char *
 ztrduppfx(const char *s, int len)
 {
     char *r = zalloc(len + 1);
@@ -3506,7 +3506,7 @@ ztrduppfx(const char *s, int len)
 /* Append a string to an allocated string, reallocating to make room. */
 
 /**/
-char *
+mod_export char *
 appstr(char *base, char const *append)
 {
     return strcat(realloc(base, strlen(base) + strlen(append) + 1), append);
@@ -3537,7 +3537,7 @@ upchdir(int n)
  * in an unwanted directory in case of failure.                            */
 
 /**/
-int
+mod_export int
 lchdir(char const *path, struct dirsav *d, int hard)
 {
     char const *pptr;
@@ -3660,7 +3660,7 @@ lchdir(char const *path, struct dirsav *d, int hard)
 }
 
 /**/
-int
+mod_export int
 restoredir(struct dirsav *d)
 {
     int err = 0;
@@ -3699,7 +3699,7 @@ restoredir(struct dirsav *d)
 /* Get a signal number from a string */
 
 /**/
-int
+mod_export int
 getsignum(char *s)
 {
     int x, i;
@@ -3753,7 +3753,7 @@ privasserted(void)
 #ifdef DEBUG
 
 /**/
-void
+mod_export void
 dputs(char *message)
 {
     fprintf(stderr, "%s\n", message);
@@ -3763,7 +3763,7 @@ dputs(char *message)
 #endif /* DEBUG */
 
 /**/
-int
+mod_export int
 mode_to_octal(mode_t mode)
 {
     int m = 0;
diff --git a/Src/zsh.h b/Src/zsh.h
index a9e8e00ed..d3f03c864 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1660,3 +1660,9 @@ typedef int (*CompctlReadFn) _((char *, char **, char *, char *));
 typedef void (*ZleVoidFn) _((void));
 typedef void (*ZleVoidIntFn) _((int));
 typedef unsigned char * (*ZleReadFn) _((char *, char *, int));
+
+/***************************************/
+/* Pseudo-keyword to mark exportedness */
+/***************************************/
+
+#define mod_export