about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-05-31 17:10:12 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-05-31 17:10:12 +0000
commitf42e3fa8e6152e145251e8f16f4c61c23dec1f59 (patch)
tree9a7b104b910ae53f6a49cb4e35c3dedc737e907b
parent4fec788fa5f6e7c9723e02e3d0b57068ce9785aa (diff)
downloadzsh-f42e3fa8e6152e145251e8f16f4c61c23dec1f59.tar.gz
zsh-f42e3fa8e6152e145251e8f16f4c61c23dec1f59.tar.xz
zsh-f42e3fa8e6152e145251e8f16f4c61c23dec1f59.zip
-rw-r--r--Completion/Core/compinstall3
-rw-r--r--Config/.cvsignore0
-rw-r--r--Config/.distfiles2
-rw-r--r--Config/defs.mk.in80
-rw-r--r--Config/version.mk4
-rw-r--r--Doc/Makefile.in15
-rw-r--r--Doc/Zsh/.distfiles14
-rw-r--r--Doc/Zsh/compwid.yo7
-rw-r--r--Doc/Zsh/files.yo26
-rw-r--r--Doc/Zsh/mod_files.yo2
-rw-r--r--Doc/Zsh/mod_mapfile.yo46
-rw-r--r--Doc/Zsh/mod_parameter.yo2
-rw-r--r--Doc/Zsh/modules.yo5
-rw-r--r--Etc/FAQ.yo181
-rw-r--r--Etc/Makefile.in15
-rw-r--r--Makefile.in15
-rw-r--r--Src/Makefile.in15
-rw-r--r--Src/Makemod.in.in13
-rw-r--r--Src/Modules/mapfile.c369
-rw-r--r--Src/Modules/mapfile.mdd3
-rw-r--r--Src/Modules/parameter.c25
-rw-r--r--Src/Zle/compctl.c1
-rw-r--r--Src/Zle/zle_tricky.c31
-rw-r--r--Src/builtin.c3
-rw-r--r--Src/exec.c2
-rw-r--r--Src/init.c21
-rw-r--r--Src/options.c4
-rw-r--r--Src/params.c36
-rw-r--r--Src/subst.c8
-rw-r--r--Src/zsh.export2
-rw-r--r--Src/zsh.h2
-rw-r--r--configure.in40
-rw-r--r--patchlist.txt39
33 files changed, 844 insertions, 187 deletions
diff --git a/Completion/Core/compinstall b/Completion/Core/compinstall
index d494ba302..5086cc7d2 100644
--- a/Completion/Core/compinstall
+++ b/Completion/Core/compinstall
@@ -141,6 +141,9 @@ or insult your system manager for incompetence."
 else
   print "Keeping existing completion directiory $_ci_fdir"
 fi
+if [[ ${~_ci_fdir} != /* ]]; then
+  _ci_fdir=$(cd $_ci_fdir;builtin pwd)
+fi
 
 # Check if this is in fpath already, else put it there (with ~'s expanded).
 _ci_f=${~_ci_fdir}
diff --git a/Config/.cvsignore b/Config/.cvsignore
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Config/.cvsignore
diff --git a/Config/.distfiles b/Config/.distfiles
index ac024c171..eb59d5ee3 100644
--- a/Config/.distfiles
+++ b/Config/.distfiles
@@ -1,4 +1,4 @@
 DISTFILES_SRC='
     .distfiles
-    clean.mk config.mk defs.mk version.mk
+    clean.mk config.mk defs.mk.in version.mk
 '
diff --git a/Config/defs.mk.in b/Config/defs.mk.in
new file mode 100644
index 000000000..3394123d5
--- /dev/null
+++ b/Config/defs.mk.in
@@ -0,0 +1,80 @@
+#
+# Basic Makefile definitions
+#
+# Copyright (c) 1995-1997 Richard Coleman
+# All rights reserved.
+#
+# Permission is hereby granted, without written agreement and without
+# license or royalty fees, to use, copy, modify, and distribute this
+# software and to distribute modified versions of this software for any
+# purpose, provided that the above copyright notice and the following
+# two paragraphs appear in all copies of this software.
+#
+# In no event shall Richard Coleman or the Zsh Development Group be liable
+# to any party for direct, indirect, special, incidental, or consequential
+# damages arising out of the use of this software and its documentation,
+# even if Richard Coleman and the Zsh Development Group have been advised of
+# the possibility of such damage.
+#
+# Richard Coleman and the Zsh Development Group specifically disclaim any
+# warranties, including, but not limited to, the implied warranties of
+# merchantability and fitness for a particular purpose.  The software
+# provided hereunder is on an "as is" basis, and Richard Coleman and the
+# Zsh Development Group have no obligation to provide maintenance,
+# support, updates, enhancements, or modifications.
+#
+
+# fundamentals
+SHELL = /bin/sh
+@SET_MAKE@
+
+# installation directories
+prefix          = @prefix@
+exec_prefix     = @exec_prefix@
+bindir          = @bindir@
+libdir          = @libdir@
+MODDIR          = $(libdir)/zsh/$(VERSION)
+infodir         = @infodir@
+mandir          = @mandir@
+
+# compilation
+CC              = @CC@
+CPP             = @CPP@
+CPPFLAGS        = @CPPFLAGS@
+DEFS            = @DEFS@
+CFLAGS          = @CFLAGS@
+LDFLAGS         = @LDFLAGS@
+EXTRA_LDFLAGS   = @EXTRA_LDFLAGS@
+DLCFLAGS        = @DLCFLAGS@
+DLLDFLAGS       = @DLLDFLAGS@
+LIBLDFLAGS      = @LIBLDFLAGS@
+EXELDFLAGS      = @EXELDFLAGS@
+LIBS            = @LIBS@
+DL_EXT          = @DL_EXT@
+DLLD            = @DLLD@
+EXPOPT          = @EXPOPT@
+IMPOPT          = @IMPOPT@
+
+# utilities
+AWK             = @AWK@
+YODL            = @YODL@
+YODL2TXT        = $(YODL)2txt
+YODL2HTML       = $(YODL)2html
+
+# install utility
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA    = @INSTALL_DATA@
+
+# flags passed to recursive makes in subdirectories
+MAKEDEFS = \
+prefix='$(prefix)' exec_prefix='$(exec_prefix)' bindir='$(bindir)' \
+libdir='$(libdir)' MODDIR='$(MODDIR)' infodir='$(infodir)' mandir='$(mandir)' \
+CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' DEFS='$(DEFS)' CFLAGS='$(CFLAGS)' \
+LDFLAGS='$(LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
+DLCFLAGS='$(DLCFLAGS)' DLLDFLAGS='$(DLLDFLAGS)' \
+LIBLDFLAGS='$(LIBLDFLAGS)' EXELDFLAGS='$(EXELDFLAGS)' \
+LIBS='$(LIBS)' DL_EXT='$(DL_EXT)' DLLD='$(DLLD)' \
+AWK='$(AWK)' YODL='$(YODL)' YODL2TXT='$(YODL2TXT)' YODL2HTML='$(YODL2HTML)'
+
+# override built-in suffix list
+.SUFFIXES:
diff --git a/Config/version.mk b/Config/version.mk
index 4bbbe660a..cd9e33110 100644
--- a/Config/version.mk
+++ b/Config/version.mk
@@ -27,5 +27,5 @@
 # This must also serve as a shell script, so do not add spaces around the
 # `=' signs.
 
-VERSION=3.1.5-pws-19
-VERSION_DATE='May 19, 1999'
+VERSION=3.1.5-pws-20
+VERSION_DATE='May 25, 1999'
diff --git a/Doc/Makefile.in b/Doc/Makefile.in
index 7d4d4745c..f7dbf3866 100644
--- a/Doc/Makefile.in
+++ b/Doc/Makefile.in
@@ -27,8 +27,15 @@
 subdir = Doc
 dir_top = ..
 
-@@version.mk@@
-@@defs.mk@@
+@VERSION_MK@
+
+# source/build directories
+VPATH           = @srcdir@
+sdir            = @srcdir@
+sdir_top        = @top_srcdir@
+INSTALL         = @INSTALL@
+
+@DEFS_MK@
 
 MAKEINFO = makeinfo
 TEXI2DVI = texi2dvi
@@ -195,7 +202,7 @@ uninstall.info:
 
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
-@@clean.mk@@
+@CLEAN_MK@
 
 clean-here:
 	rm -f *.html *.info* *.dvi *.ps
@@ -210,4 +217,4 @@ realclean-here:
 
 # ========== DEPENDENCIES FOR MAINTENANCE ==========
 
-@@config.mk@@
+@CONFIG_MK@
diff --git a/Doc/Zsh/.distfiles b/Doc/Zsh/.distfiles
index 785febb16..f3e7352a5 100644
--- a/Doc/Zsh/.distfiles
+++ b/Doc/Zsh/.distfiles
@@ -1,10 +1,10 @@
 DISTFILES_SRC='
     .distfiles
-    arith.yo builtins.yo compat.yo compctl.yo compsys.yo compwid.yo
-    cond.yo exec.yo expn.yo filelist.yo files.yo func.yo grammar.yo
-    guide.yo index.yo intro.yo invoke.yo jobs.yo metafaq.yo mod_cap.yo
-    mod_clone.yo mod_comp1.yo mod_compctl.yo mod_deltochar.yo
-    mod_example.yo mod_files.yo mod_parameter.yo mod_sched.yo
-    mod_stat.yo mod_zftp.yo mod_zle.yo modules.yo options.yo params.yo
-    prompt.yo redirect.yo restricted.yo seealso.yo zftpsys.yo zle.yo
+    arith.yo builtins.yo compat.yo compctl.yo compwid.yo cond.yo exec.yo
+    expn.yo filelist.yo files.yo func.yo grammar.yo guide.yo index.yo intro.yo
+    invoke.yo jobs.yo metafaq.yo mod_cap.yo mod_clone.yo mod_comp1.yo
+    mod_compctl.yo mod_deltochar.yo mod_example.yo mod_files.yo
+    mod_mapfile.yo mod_sched.yo mod_stat.yo mod_zftp.yo mod_zle.yo
+    modules.yo options.yo params.yo 
+    prompt.yo redirect.yo restricted.yo seealso.yo zle.yo
 '
diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo
index 79577d13d..d74054a9c 100644
--- a/Doc/Zsh/compwid.yo
+++ b/Doc/Zsh/compwid.yo
@@ -424,7 +424,8 @@ is the same character.
 )
 item(tt(-r) var(remove-chars))(
 This is a more versatile form of the tt(-q) option.
-The suffix given with tt(-S) will be automatically removed if
+The suffix given with tt(-S) or the slash automatically added after
+completing directories will be automatically removed if
 the next character typed inserts one of the characters given in the
 var(remove-chars).  This string is parsed as a characters class and
 understands the backslash sequences used by the tt(print) command.  For
@@ -436,8 +437,8 @@ all characters that insert nothing. Thus `tt(-S "=" -q)' is the same
 as `tt(-S "=" -r "= \t\n\-")'.
 )
 item(tt(-R) var(remove-func))(
-This is another form of the tt(-r) option. When a suffix given with the
-tt(-S) option has been inserted and the completion accepted, the function
+This is another form of the tt(-r) option. When a suffix 
+has been inserted and the completion accepted, the function
 var(remove-func) will be called after the next character typed.  It is
 passed the length of the suffix as an argument and can use the special
 parameters available in ordinary (non-completion) zle widgets (see
diff --git a/Doc/Zsh/files.yo b/Doc/Zsh/files.yo
index 6eb6c202e..9ff59fe19 100644
--- a/Doc/Zsh/files.yo
+++ b/Doc/Zsh/files.yo
@@ -6,12 +6,17 @@ cindex(startup files)
 cindex(files, shutdown)
 cindex(shutdown files)
 pindex(NO_RCS, use of)
-Commands are first read from tt(/etc/zshenv).
-If the tt(RCS) option is unset
-within tt(/etc/zshenv), all other
-initialization files are skipped.
-Otherwise, commands are read
-from tt($ZDOTDIR/.zshenv).
+pindex(NO_GLOBAL_RCS, use of)
+Commands are first read from tt(/etc/zshenv); this cannot be overridden.
+If the tt(RCS) option is unset, no further files are read; changing this
+option after this point has no effect on initialization files, but may
+affect behaviour on logout.  Subsequent behaviour is also modified by the
+option tt(GLOBAL_RCS).  If it is unset at any point during initialisation,
+later files in the tt(/etc) directory will not be read.  It is also
+possible for a file in tt($ZDOTDIR) to re-enable tt(GLOBAL_RCS). Both
+tt(RCS) and tt(GLOBAL_RCS) are set by default.
+
+Commands are then read from tt($ZDOTDIR/.zshenv).
 pindex(LOGIN, use of)
 If the shell is a login shell, commands
 are read from tt(/etc/zprofile) and then tt($ZDOTDIR/.zprofile).
@@ -20,20 +25,15 @@ commands are read from tt(/etc/zshrc) and then tt($ZDOTDIR/.zshrc).
 Finally, if the shell is a login shell, tt(/etc/zlogin) and
 tt($ZDOTDIR/.zlogin) are read.
 
-If the option tt(GLOBAL_RCS_FIRST) is set when the shell is invoked or in
-the file tt(/etc/zshenv), then all the applicable global startup files are
-read before all the users', so that the order becomes tt(/etc/zshenv)
-... tt(/etc/zlogin), tt($ZDOTDIR/.zshenv) ... tt($ZDOTDIR/.zlogin).
-After tt(/etc/zshenv) has been read, changing the option has no further
-effect.
-
 When a login shell exits, the files tt($ZDOTDIR/.zlogout) and then
 tt(/etc/zlogout) are read.  This happens with either an explicit exit
 via the tt(exit) or tt(logout) commands, or an implict exit by reading
 end-of-file from the terminal.  However, if the shell terminates due
 to tt(exec)'ing another process, the logout files are not read.
+These are also affected by the tt(RCS) and tt(GLOBAL_RCS) options.
 
 If tt(ZDOTDIR) is unset, tt(HOME) is used instead.
 Those files listed above as being in tt(/etc) may be in another
 directory, depending on the installation.
 ifnzman(includefile(Zsh/filelist.yo))
+
diff --git a/Doc/Zsh/mod_files.yo b/Doc/Zsh/mod_files.yo
index 160473fba..932d8583c 100644
--- a/Doc/Zsh/mod_files.yo
+++ b/Doc/Zsh/mod_files.yo
@@ -1,4 +1,4 @@
-texinode(The files Module)(The parameter Module)(The example Module)(Zsh Modules)
+texinode(The files Module)(The mapfile Module)(The example Module)(Zsh Modules)
 sect(The files Module)
 cindex(files, manipulating)
 The tt(files) module makes some standard commands available as builtins:
diff --git a/Doc/Zsh/mod_mapfile.yo b/Doc/Zsh/mod_mapfile.yo
new file mode 100644
index 000000000..6d0475711
--- /dev/null
+++ b/Doc/Zsh/mod_mapfile.yo
@@ -0,0 +1,46 @@
+texinode(The mapfile Module)(The parameter Module)(The files Module)(Zsh Modules)
+sect(The mapfile Module)
+cindex(parameter, file access via)
+The tt(mapfile) module provides one special associative array parameter of
+the same name.
+
+startitem()
+vindex(mapfile)
+item(tt(mapfile))(
+This associative array takes as keys the names of files; the resulting
+value is the content of the file.  The value is treated identically to any
+other text coming from a parameter.  The value may also be assigned to, in
+which case the file in question is written (whether or not it originally
+existed); or an element may be unset, which will delete the file in
+question.  For example, `tt(vared mapfile[myfile])' works as expected,
+editing the file `tt(myfile)'.
+
+When the array is accessed as a whole, the keys are the names of files in
+the current directory, and the values are empty (to save a huge overhead in
+memory).  Thus tt(${(k)mapfile}) has the same affect as the glob operator
+tt(*(D)), since files beginning with a dot are not special.  Care must be
+taken with expressions such as tt(rm ${(k)mapfile}), which will delete
+every file in the current directory without the usual `tt(rm *)' test.
+
+The parameter tt(mapfile) may be made read-only; in that case, files
+referenced may not be written or deleted.
+)
+enditem()
+
+subsect(Limitations)
+
+Although reading and writing of the file in question is efficiently
+handled, zsh's internal memory management may be arbitrarily baroque.  Thus
+it should not automatically be assumed that use of tt(mapfile) represents a
+gain in efficiency over use of other mechanisms.  Note in particular that
+the whole contents of the file will always reside physically in memory when
+accessed (possibly multiple times, due to standard parameter subsitution
+operations).
+
+No errors are printed or flagged for non-existent, unreadable, or
+unwriteable files, as the parameter mechanism is too low in the shell
+execution hierarchy to make this convenient.
+
+It is unfortunate that the mechanism for loading modules does not yet allow
+the user to specify the name of the shell parameter to be given the special
+behaviour.
diff --git a/Doc/Zsh/mod_parameter.yo b/Doc/Zsh/mod_parameter.yo
index c84dd18eb..4fe537c6d 100644
--- a/Doc/Zsh/mod_parameter.yo
+++ b/Doc/Zsh/mod_parameter.yo
@@ -1,4 +1,4 @@
-texinode(The parameter Module)(The sched Module)(The files Module)(Zsh Modules)
+texinode(The parameter Module)(The sched Module)(The mapfile Module)(Zsh Modules)
 sect(The parameter Module)
 cindex(parameters, special)
 The tt(parameter) module gives access to some of the internal hash
diff --git a/Doc/Zsh/modules.yo b/Doc/Zsh/modules.yo
index a7c528951..0b487f673 100644
--- a/Doc/Zsh/modules.yo
+++ b/Doc/Zsh/modules.yo
@@ -31,6 +31,9 @@ An example of how to write a module.
 item(tt(files))(
 Some basic file manipulation commands as builtins.
 )
+item(tt(mapfile))(
+Access to external files via a special associative array.
+)
 item(tt(parameter))(
 Access to internal hash tables via special associative arrays.
 )
@@ -55,6 +58,7 @@ menu(The compctl Module)
 menu(The deltochar Module)
 menu(The example Module)
 menu(The files Module)
+menu(The mapfile Module)
 menu(The parameter Module)
 menu(The sched Module)
 menu(The stat Module)
@@ -68,6 +72,7 @@ includefile(Zsh/mod_compctl.yo)
 includefile(Zsh/mod_deltochar.yo)
 includefile(Zsh/mod_example.yo)
 includefile(Zsh/mod_files.yo)
+includefile(Zsh/mod_mapfile.yo)
 includefile(Zsh/mod_parameter.yo)
 includefile(Zsh/mod_sched.yo)
 includefile(Zsh/mod_stat.yo)
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index 97bec171e..0ba251f92 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -43,17 +43,28 @@ whenlatex(report(ARG1)(ARG2)(ARG3))\
 whenman(report(ARG1)(ARG2)(ARG3))\
 whenms(report(ARG1)(ARG2)(ARG3))\
 whensgml(report(ARG1)(ARG2)(ARG3)))
-myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(1999/04/23)
+myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(1999/05/24)
 COMMENT(-- the following are for Usenet and must appear first)\
 description(
 mydit(Archive-Name:) unix-faq/shell/zsh
-mydit(Last-Modified:) 1999/04/23
+mydit(Last-Modified:) 1999/05/24
 mydit(Submitted-By:) email(pws@ibmth.df.unipi.it (Peter Stephenson))
-mydit(Version:) $Id: FAQ.yo,v 1.1.1.3 1999/04/25 15:43:54 akr Exp $
+mydit(Version:) $Id: FAQ.yo,v 1.1.1.4 1999/05/31 17:10:29 akr Exp $
 mydit(Posting-Frequency:) Monthly
 mydit(Copyright:) (C) P.W. Stephenson, 1995--1999 (see end of document)
 )
 
+bf(Changes since issue posted April 1999:)
+description(
+mydit(*.*)  Orthography for option names standardised.
+mydit(1.4)  don't change config.h.in, change acconfig.h
+mydit(1.6)  email zefram@zsh.org
+mydit(2.4)  new widget version of tcsh run-fg-editor
+mydit(3.7)  should have mentioned tt(PRINT_EIGHT_BIT) is new in 3.1
+mydit(3.23) new: describe tt(PROMPT_CR) option.
+mydit(5.1)  Description of tt(LIST_AMBIGUOUS) corrected.
+)
+
 This document contains a list of frequently-asked (or otherwise
 significant) questions concerning the Z-shell, a command interpreter
 for many UNIX systems which is freely available to anyone with FTP
@@ -113,6 +124,7 @@ Chapter 3:  How to get various things to work
 3.20. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work?
 3.21. Why is my history not being saved?
 3.22. How do I get a variable's value to be evaluated as another variable?
+3.23. How do I prevent the prompt overwriting output when there is no newline?
 
 Chapter 4:  The mysteries of completion
 4.1. What is completion?
@@ -271,7 +283,7 @@ sect(On what machines will it run?)
 
   If you need to change something to support a new machine, it would be
   appreciated if you could add any necessary preprocessor code and
-  alter configure.in and config.h.in to configure zsh automatically,
+  alter configure.in and acconfig.h to configure zsh automatically,
   then send the required context diffs to the list (see question
   link(5.2)(52)).  Changes based on version 2.5 are very unlikely to
   be useful.
@@ -314,7 +326,7 @@ sect(What's the latest version?)
 sect(Where do I get it?)
 label(16)
 
-  The archive is now run by email(Andrew Main <zefram@tao.co.uk>).
+  The archive is now run by email(Andrew Main <zefram@zsh.org>).
   The following are known mirrors (kept frequently up to date); the
   first is the official archive site, currently in Australia.  All are
   available by anonymous FTP.  The major sites keep test versions in
@@ -516,18 +528,21 @@ label(21)
   The classic difference is word splitting, discussed in link(3.1)(31); this
   catches out very many beginning zsh users.  As explained there, this
   is actually a bug in every other shell.  The answer is to set
-  SH_WORD_SPLIT for backward compatibility.  The next most classic
+  tt(SH_WORD_SPLIT) for backward compatibility.  The next most classic
   difference is that unmatched glob patterns cause the command to
-  abort; set NO_NOMATCH for those.
+  abort; set tt(NO_NOMATCH) for those.
 
   Here is a list of various options which will increase ksh
   compatibility, though maybe decrease zsh's abilities: see the manual
-  entries for GLOB_SUBST, IGNORE_BRACES (though brace expansion occurs
-  in some versions of ksh), KSH_ARRAYS, KSH_GLOB, KSH_OPTION_PRINT,
-  LOCAL_OPTIONS, NO_BAD_PATTERN, NO_BANG_HIST, NO_EQUALS, NO_HUP,
-  NO_NOMATCH, NO_RCS, NO_SHORT_LOOPS, PROMPT_SUBST, RM_STAR_SILENT,
-  POSIX_BUILTINS, SH_FILE_EXPANSION, SH_GLOB, SH_OPTION_LETTERS,
-  SH_WORD_SPLIT (see question link(3.1)(31)) and SINGLE_LINE_ZLE.
+  entries for tt(GLOB_SUBST), tt(IGNORE_BRACES) (though brace expansion occurs
+  in some versions of ksh), tt(KSH_ARRAYS), tt(KSH_GLOB), tt(KSH_OPTION_PRINT),
+  tt(LOCAL_OPTIONS), tt(NO_BAD_PATTERN), tt(NO_BANG_HIST), tt(NO_EQUALS), \
+tt(NO_HUP,)
+  tt(NO_NOMATCH), tt(NO_RCS), tt(NO_SHORT_LOOPS), tt(PROMPT_SUBST), \
+tt(RM_STAR_SILENT),
+  tt(POSIX_BUILTINS), tt(SH_FILE_EXPANSION), tt(SH_GLOB), \
+tt(SH_OPTION_LETTERS),
+  tt(SH_WORD_SPLIT) (see question link(3.1)(31)) and tt(SINGLE_LINE_ZLE).
   Note that you can also disable any built-in commands which get in
   your way.  If invoked as `ksh', the shell will try and set suitable
   options.
@@ -548,7 +563,7 @@ label(21)
         subscripts start at 1, not 0; tt(array[0]) refers to tt(array[1]);
         mytt($array) refers to the whole array, not tt($array[0]);
         braces are unnecessary: tt($a[1] == ${a[1]}), etc.
-        The KSH_ARRAYS option is now available.
+        The tt(KSH_ARRAYS) option is now available.
     it()  Coprocesses are established by mytt(coproc); mytt(|&) behaves like
         csh.  Handling of coprocess file descriptors is also different.
     it()  In mytt(cmd1 && cmd2 &), only mytt(cmd2) instead of the whole
@@ -558,10 +573,10 @@ label(21)
   it() Command line substitutions, globbing etc.:
   itemize(
     it()* Failure to match a globbing pattern causes an error (use
-        NO_NOMATCH).
+        tt(NO_NOMATCH)).
     it()* The results of parameter substitutions are treated as plain text:
-        mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh.
-        (GLOB_SUBST has been added to fix this.)
+        mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh
+        (uset tt(GLOB_SUBST)).
     it()  The backslash in tt($(echo '\$x')) is treated differently:  in \
 ksh, it
         is not stripped, in zsh it is.  (The tt(`...`) form gives the same in
@@ -583,9 +598,9 @@ PROMPT_SUBST).
 ----------------------------------------------------------------------
       )
       The mytt(^), mytt(~) and mytt(#) (but not mytt(|))forms require \
-EXTENDED_GLOB.
+tt(EXTENDED_GLOB).
       From version 3.1.3, the ksh forms are fully supported when the
-      option KSH_GLOB is in effect; for previous versions you
+      option tt(KSH_GLOB) is in effect; for previous versions you
       must use the table above.
 
       [1] Note that mytt(~) is the only globbing operator to have a lower
@@ -681,7 +696,7 @@ sect(Similarities with csh)
   it()  tt(*rc) file for interactive shells.
   it()  Directory stacks.
   it()  tt(cshjunkie*), tt(ignoreeof) options.
-  it()  The CSH_NULL_GLOB option.
+  it()  The tt(CSH_NULL_GLOB) option.
   it()  tt(>&), tt(|&) etc. redirection.
       (Note that mytt(>file 2>&1) is the standard Bourne shell command for
       csh's mytt(>&file).)
@@ -765,7 +780,7 @@ label(23)
      heavy csh alias junkies:
 
   myeit() Mapping from csh alias "parameter referencing" into zsh function
-     (assuming shwordsplit and ksharrays are NOT set in zsh):
+     (assuming tt(SH_WORD_SPLIT) and tt(KSH_ARRAYS) are NOT set in zsh):
        verb(
       csh             zsh
      =====         ==========
@@ -848,7 +863,17 @@ sect(Similarities with tcsh)
   verb(
     bindkey '\eq' push-input
   )
-  to save the entire buffer.
+  to save the entire buffer.  In recent versions of zsh 3.1, you have
+  the following more sophisticated option,
+  verb(
+    run-fg-editor() {
+      zle push-input
+      BUFFER="fg %$EDITOR:t"
+      zle accept-line
+    }
+    zle -N run-fg-editor
+  )
+  and can now bind tt(run-fg-editor) just like any other editor function.
 
 
 sect(Similarities with bash)
@@ -872,7 +897,7 @@ sect(Shouldn't zsh be more/less like ksh/(t)csh?)
   would have features familiar to csh users.  For a long time, csh was
   the preferred interactive shell and there is a strong resistance to
   changing to something unfamiliar, hence the additional syntax and
-  CSH_JUNKIE options.  This argument still holds.  On the other hand,
+  tt(CSH_JUNKIE) options.  This argument still holds.  On the other hand,
   the arguments for having what is close to a plug-in replacement for ksh
   are, if anything, even more powerful:  the deficiencies of csh as a
   programming language are well known (look in any Usenet FAQ archive, e.g.
@@ -900,8 +925,8 @@ label(31)
   )
   are split into words when passed to a command or used in a mytt(for foo in
   $var) loop.  By default, zsh does not have that behaviour: the
-  variable remains intact.  (This is not a bug!  See below.)  An option
-  (SHWORDSPLIT) exists to provide compatibility.
+  variable remains intact.  (This is not a bug!  See below.)  The option
+  tt(SH_WORD_SPLIT) exists to provide compatibility.
 
   For example, defining the function args to show the number of its
   arguments:
@@ -935,7 +960,7 @@ label(31)
   verb(
     args $array
   )
-  produces the output `4', regardless of the setting of SHWORDSPLIT.
+  produces the output `4', regardless of the setting of tt(SH_WORD_SPLIT).
   Arrays are also much more versatile than single strings.  Probably
   if this mechanism had always been available there would never have
   been automatic word splitting in scalars, which is a sort of
@@ -954,22 +979,22 @@ label(31)
   after which $words is an array with the words of $sentence (note
   characters special to the shell, such as the mytt(') in this example,
   must already be quoted), or, less standard but more reliable,
-  turning on SHWORDSPLIT for one variable only:
+  turning on tt(SH_WORD_SPLIT) for one variable only:
   verb(
     args ${=sentence}
   )
   always returns 8 with the above definition of mytt(args).  (In older
-  versions of zsh, tt(${=foo}) toggled SHWORDSPLIT; now it forces it on.)
+  versions of zsh, tt(${=foo}) toggled tt(SH_WORD_SPLIT); now it forces it on.)
 
   Note also the tt("$@") method of word splitting is always available in zsh
   functions and scripts (though strictly this does array splitting, not
   word splitting).  This is more portable than the tt($*), since it
-  will work regardless of the SHWORDSPLIT setting; the other
+  will work regardless of the tt(SH_WORD_SPLIT) setting; the other
   difference is that tt($*) removes empty arguments from the array.
   You can fix the first half of that objection by using tt(${==*}),
-  which turns off SHWORDSPLIT for the duration of the expansion.
+  which turns off tt(SH_WORD_SPLIT) for the duration of the expansion.
 
-  SHWORDSPLIT is set when zsh is invoked with the names `ksh' or `sh',
+  tt(SH_WORD_SPLIT) is set when zsh is invoked with the names `ksh' or `sh',
   or (entirely equivalent) when mytt(emulate ksh) or mytt(emulate sh) is in
   effect.
 
@@ -1004,7 +1029,7 @@ sect(In which startup file do I put...?)
   you use the tt(-f) option) is tt(.zshenv), so this is a good place to \
   put
   things you want even if the shell is non-interactive: options for
-  changing the the syntax, like EXTENDED_GLOB, any changes to set with
+  changing the the syntax, like tt(EXTENDED_GLOB), any changes to set with
   mytt(limit), any more variables you want to make sure are set as for
   example tt($fpath) to find functions.  You almost certainly do not
   want tt(.zshenv) to produce any output.  Some people prefer not to
@@ -1025,7 +1050,7 @@ sect(In which startup file do I put...?)
   to save your history.
 
 
-sect(What is the difference between `export' and the ALL_EXPORT option?)
+sect(What is the difference between `export' and the tt(ALL_EXPORT) option?)
 
   Normally, you would put a variable into the environment by using
   mytt(export var).  The command mytt(setopt allexport) causes all
@@ -1045,7 +1070,7 @@ sect(What is the difference between `export' and the ALL_EXPORT option?)
      meaning to a command.  Since all shell variables are visible to
      commands, there is no protection against this.
   )
-  For these reasons it is usually best to avoid ALL_EXPORT unless you
+  For these reasons it is usually best to avoid tt(ALL_EXPORT) unless you
   have a specific use for it.  One safe use is to set it before
   creating a list of variables in an initialisation file, then unset
   it immediately afterwards.  Only those variables will be automatically
@@ -1130,12 +1155,15 @@ sect(How do I automatically display the directory in my xterm title bar?)
 
 sect(How do I make the completion list use eight bit characters?)
 
-  If you are sure your terminal handles this, the easiest way is to
-  set the option PRINT_EIGHT_BIT.  In principle, this will work
-  automatically if your computer uses the `locale' system and your
-  locale variables are set properly, as zsh understands this.
-  However, it is quite complicated, so if it isn't already set up,
-  trying the option is a lot easier.
+  If you are sure your terminal handles this, the easiest way from version
+  3.1 of the shell is to set the option tt(PRINT_EIGHT_BIT).  In principle,
+  this will work automatically if your computer uses the `locale' system
+  and your locale variables are set properly, as zsh understands this.
+  However, it is quite complicated, so if it isn't already set up, trying
+  the option is a lot easier.  For 3.0, you are stuck with trying to
+  understand locales, see the tt(setlocale(3)) and tt(zshparam(1)) manual
+  pages:  the simplest possibility may be to set tt(LC_ALL=en_US).  For older
+  versions of the shell, there is no easy way out.
 
 
 sect(Why do the cursor (arrow) keys not work?)
@@ -1267,7 +1295,7 @@ sect(Why do my autoloaded functions not autoload [the first time]?)
   incompatible with the old zsh behaviour which allowed you to
   redefine the function when you called it.
 
-  From version 3.1, there is an option KSHAUTOLOAD to allow full ksh
+  From version 3.1, there is an option tt(KSH_AUTOLOAD) to allow full ksh
   compatiblity, i.e. the function myem(must) be in the second form
   above.  If that is not set, zsh tries to guess which form you are
   using:  if the file contains only a complete definition of the
@@ -1323,6 +1351,7 @@ sect(How does base arithmetic work?)
 
 
 sect(How do I get a newline in my prompt?)
+label(313)
 
   You can place a literal newline in quotes, i.e.
   verb(
@@ -1359,7 +1388,7 @@ sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?)
   settings.)  In other words, tt(\C-s) stops all output to the terminal,
   while tt(\C-q) resumes it.
 
-  There is an option NO_FLOW_CONTROL to stop zsh from allowing flow
+  There is an option tt(NO_FLOW_CONTROL) to stop zsh from allowing flow
   control and hence restoring the use of the keys: put mytt(setopt
   noflowcontrol) in your tt(.zshrc) file.
 
@@ -1381,7 +1410,7 @@ sect(Why do history substitutions with single bangs do something funny?)
   If you have a command like "tt(echo !-2:$ !$)", the first history
   substitution then sets a default to which later history substitutions
   with single unqualified bangs refer, so that !$ becomes equivalent to
-  tt(!-2:$).  The option CSH_JUNKIE_HISTORY makes all single bangs refer
+  tt(!-2:$).  The option tt(CSH_JUNKIE_HISTORY) makes all single bangs refer
   to the last command.
 
 
@@ -1522,6 +1551,24 @@ sect(How do I get a variable's value to be evaluated as another variable?)
   actually does nothing.
 
 
+sect(How do I prevent the prompt overwriting output when there is no newline?)
+
+  The problem is, for example,
+  verb(
+    % echo -n foo
+    % 
+  )
+  and the tt(foo) has been overwritten by the prompt tt(%).  The answer is
+  simple:  put tt(unsetopt promptcr) in your tt(.zshrc).  The option \
+  tt(PROMPT_CR),
+  to print a carriage return before a new prompt, is set by default because
+  a prompt at the right hand side (mytt($RPROMPT), mytt($RPS1)) will not appear
+  in the right place, and multi-line editing will be confused about the line
+  position, unless the line starts in the left hand column.  Apart from
+  tt(PROMPT_CR), you can force this to happen by putting a newline in the
+  prompt (see question link(3.13)(313) for that).
+
+
 chapter(The mysteries of completion)
 
 Programmable completion using the `compctl' command is one of the most
@@ -1630,25 +1677,26 @@ sect(How does zsh deal with ambiguous completions?)
   delete the next character and you have to use tt(ESC-\C-D).)  This can be
   changed by the following options, among others:
   itemize(
-   it() with nobeep set, that annoying beep goes away
-   it() with nolistbeep, beeping is only turned off for ambiguous completions
-   it() with autolist set, when the completion is ambiguous you get a
+   it() with tt(NO_BEEP) set, that annoying beep goes away
+   it() with tt(NO_LIST_BEEP), beeping is only turned off for ambiguous
+      completions
+   it() with tt(AUTO_LIST) set, when the completion is ambiguous you get a
       list without having to type tt(\C-D)
-   it() with listambigous, this is modified so that nothing is listed if
+   it() with tt(LIST_AMBIGOUS), this is modified so that nothing is listed if
       there is an unambiguous prefix or suffix to be inserted
-   it() with menucomplete set, one completion is always inserted
+   it() with tt(MENU_COMPLETE) set, one completion is always inserted
       completely, then when you hit TAB it changes to the next, and so
       on until you get back to where you started
-   it() with automenu, you only get the menu behaviour when you hit TAB
+   it() with tt(AUTO_MENU), you only get the menu behaviour when you hit TAB
       again on the ambiguous completion.
    it() Finally, although it affects all completion lists, including
-      those explicitly requested, note also alwayslastprompt, which
+      those explicitly requested, note also tt(ALWAYS_LAST_PROMPT), which
       causes the cursor to return to the line you were editing after
       printing the list, provided that is short enough.
   )
-  Combinations of these are possible; for example, autolist and
-  automenu together give an intuitive combination.  Note that
-  from version 3.1 listambiguous is set by default; if you use
+  Combinations of these are possible; for example, tt(AUTO_LIST) and
+  tt(AUTO_MENU) together give an intuitive combination.  Note that
+  from version 3.1 tt(LIST_AMBIGUOUS) is set by default; if you use
   autolist, you may well want to `unsetopt listambiguous'.
 
 
@@ -1681,7 +1729,7 @@ sect(How do I complete in the middle of words / just what's before the cursor?)
   )
   then in the example you can move to just after mytt(/usr/loc), hit
   whatever key you've just bound, move to the end, and hit tab.
-  (Note that AUTO_REMOVE_SLASH behaviour applies here, see the manual.)
+  (Note that tt(AUTO_REMOVE_SLASH) behaviour applies here, see the manual.)
 
   Even that doesn't exhaust the possibilities.  Included with the
   source distribution is the file tt(Functions/multicomp), a function
@@ -1862,11 +1910,12 @@ this applies
 
   Changes after zsh 3.0 (3.1.x is still currently in beta):
   itemize(
-  it() The options ALWAYS_LAST_PROMPT (return to the line you were
-     editing after displaying completion lists) and LIST_AMBIGUOUS
-     (show matching files when there are several) are now set by
-     default.  This is in response to complaints that too many zsh
-     features are never noticed by many users.  To turn them off,
+  it() The options tt(ALWAYS_LAST_PROMPT) (return to the line you were
+     editing after displaying completion lists) and tt(LIST_AMBIGUOUS)
+     (don't do tt(AUTO_LIST) if there was an unambiguous prefix that could be
+     inserted, i.e. only list if it is ambiguous what to insert next) are
+     now set by default.  This is in response to complaints that too many
+     zsh features are never noticed by many users.  To turn them off,
      just put mytt(unsetopt alwayslastprompt listambiguous) in your
      tt(.zshrc) file.
   it() tt(history-search-{forward,backward}) now only find previous
@@ -1903,20 +1952,20 @@ this applies
      the environment of the caller, as in ksh, instead of as a new
      function level.  Traps established as functions (e.g. mytt(TRAPINT()
      {...})) work as before.
-  it() The NO_CLOBBER option is now -C and PRINT_EXIT_VALUE -1; they used
-     to be the other way around.  (Use of names rather than letters is
+  it() The tt(NO_CLOBBER) option is now -C and tt(PRINT_EXIT_VALUE) -1; they
+     used to be the other way around.  (Use of names rather than letters is
      generally recommended.)
   it() mytt([[) is a reserved word, hence must be separated from
      other characters by whitespace; mytt({) and mytt(}) are also reserved
-     words if the IGNORE_BRACES option is set.
-  it() The option CSH_JUNKIE_PAREN has been removed:  csh-like code now
+     words if the tt(IGNORE_BRACES) option is set.
+  it() The option tt(CSH_JUNKIE_PAREN) has been removed:  csh-like code now
      always does what it looks like it does, so mytt(if ( ... ) ...)
      executes the code in parentheses in a subshell.  To make this
      useful, the syntax expected after an mytt(if), etc., is less strict
      than in other shells.
   it() mytt(foo=*) does not perform globbing immediately on the right
      hand side of the assignment; the old behaviour now requires the
-     option GLOB_ASSIGN.  (mytt(foo=(*)) is and has always been the
+     option tt(GLOB_ASSIGN).  (mytt(foo=(*)) is and has always been the
      consistent way of doing this.)
   it() tt(<>) performs redirection of input and output to the specified file.
      For numeric globs, you now need tt(<->).
@@ -1931,7 +1980,7 @@ this applies
      instead of tt(=)'s.  This is for consistency:  all other directory
      substitution (tt(~user), tt(~name), tt(~+), ...) used a tilde, while
      tt(=<number>) caused problems with tt(=program) substitution.
-  it() The `HISTLIT' option was broken in various ways and has been removed:
+  it() The tt(HISTLIT) option was broken in various ways and has been removed:
      the rewritten history mechanism doesn't alter history lines, making
      the option unnecessary.
   it() History expansion is disabled in single-quoted strings, like other
@@ -1939,7 +1988,7 @@ this applies
      backslashed.
   it() The mytt($HISTCHARS) variable is now mytt($histchars).  Currently both
      are tied together for compatibility.
-  it() The PROMPT_SUBST option now performs backquote expansion -- hence
+  it() The tt(PROMPT_SUBST) option now performs backquote expansion -- hence
      you should quote these in prompts.  (SPROMPT has changed as a result.)
   it() Quoting in prompts has changed: close parentheses inside ternary
      expressions should be quoted with a tt(%); history is now tt(%!), not
diff --git a/Etc/Makefile.in b/Etc/Makefile.in
index bdb9234fd..b6743a7ec 100644
--- a/Etc/Makefile.in
+++ b/Etc/Makefile.in
@@ -28,8 +28,15 @@ subdir = Etc
 dir_top = ..
 SUBDIRS =
 
-@@version.mk@@
-@@defs.mk@@
+@VERSION_MK@
+
+# source/build directories
+VPATH           = @srcdir@
+sdir            = @srcdir@
+sdir_top        = @top_srcdir@
+INSTALL         = @INSTALL@
+
+@DEFS_MK@
 
 # ========== DEPENDENCIES FOR BUILDING ==========
 
@@ -43,7 +50,7 @@ FAQ.html: FAQ.yo
 
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
-@@clean.mk@@
+@CLEAN_MK@
 
 mostlyclean-here:
 	rm -f FAQ.html
@@ -56,4 +63,4 @@ realclean-here:
 
 # ========== DEPENDENCIES FOR MAINTENANCE ==========
 
-@@config.mk@@
+@CONFIG_MK@
diff --git a/Makefile.in b/Makefile.in
index 498e3bfd9..cd5420dbf 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -28,8 +28,15 @@ subdir = .
 dir_top = .
 SUBDIRS = Doc Etc Src
 
-@@version.mk@@
-@@defs.mk@@
+@VERSION_MK@
+
+# source/build directories
+VPATH           = @srcdir@
+sdir            = @srcdir@
+sdir_top        = @top_srcdir@
+INSTALL         = @INSTALL@
+
+@DEFS_MK@
 
 # ========== DEPENDENCIES FOR BUILDING ==========
 
@@ -81,7 +88,7 @@ install.html uninstall.html:
 
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
-@@clean.mk@@
+@CLEAN_MK@
 
 distclean-here:
 	rm -f Makefile config.h config.status config.log config.cache stamp-h
@@ -91,7 +98,7 @@ realclean-here:
 
 # ========== DEPENDENCIES FOR MAINTENANCE ==========
 
-@@config.mk@@
+@CONFIG_MK@
 
 config: config.h
 
diff --git a/Src/Makefile.in b/Src/Makefile.in
index 0babdf47b..dd96aaf90 100644
--- a/Src/Makefile.in
+++ b/Src/Makefile.in
@@ -28,8 +28,15 @@ subdir = Src
 dir_top = ..
 SUBDIRS =
 
-@@version.mk@@
-@@defs.mk@@
+@VERSION_MK@
+
+# source/build directories
+VPATH           = @srcdir@
+sdir            = @srcdir@
+sdir_top        = @top_srcdir@
+INSTALL         = @INSTALL@
+
+@DEFS_MK@
 
 sdir_src      = $(sdir)
 dir_src       = .
@@ -85,7 +92,7 @@ modobjs: headers rm-modobjs-tmp
 rm-modobjs-tmp:
 	rm -f stamp-modobjs.tmp
 
-@@config.mk@@
+@CONFIG_MK@
 
 Makemod modules.index prep: modules-bltin $(CONFIG_INCS)
 	( cd $(sdir_top) && $(SHELL) $(subdir)/mkmodindex.sh $(subdir) ) \
@@ -201,7 +208,7 @@ realclean: realclean-modules
 mostlyclean-modules clean-modules distclean-modules realclean-modules: Makemod
 	@$(MAKE) -f Makemod $(MAKEDEFS) `echo $@ | sed 's/-modules//'`
 
-@@clean.mk@@
+@CLEAN_MK@
 
 # ========== RECURSIVE MAKES ==========
 
diff --git a/Src/Makemod.in.in b/Src/Makemod.in.in
index a5c760eb4..42cfc0401 100644
--- a/Src/Makemod.in.in
+++ b/Src/Makemod.in.in
@@ -30,8 +30,15 @@
 # dir_top is done by mkmakemod.sh
 # SUBDIRS is done by mkmakemod.sh
 
-@@version.mk@@
-@@defs.mk@@
+@VERSION_MK@
+
+# source/build directories
+VPATH           = @srcdir@
+sdir            = @srcdir@
+sdir_top        = @top_srcdir@
+INSTALL         = @INSTALL@
+
+@DEFS_MK@
 
 sdir_src      = $(sdir_top)/Src
 dir_src       = $(dir_top)/Src
@@ -134,7 +141,7 @@ uninstall.modules-here:
 
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
-@@clean.mk@@
+@CLEAN_MK@
 
 mostlyclean-here:
 	rm -f *.o *.$(DL_EXT)
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
new file mode 100644
index 000000000..e98da7889
--- /dev/null
+++ b/Src/Modules/mapfile.c
@@ -0,0 +1,369 @@
+/*
+ * mapfile.c - associative array interface to external files
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1999 Sven Wischnowsky, Peter Stephenson
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Sven Wischnowsky, Peter Stephenson or the Zsh Development
+ * Group be liable to any party for direct, indirect, special, incidental, or
+ * consequential damages arising out of the use of this software and its
+ * documentation, even if Peter Stephenson, Sven Wischnowsky and the Zsh
+ * Development Group have been advised of the possibility of such damage.
+ *
+ * Peter Stephenson, Sven Wischnowsky and the Zsh Development Group
+ * specifically disclaim any warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose.
+ * The softwareprovided hereunder is on an "as is" basis, and Peter
+ * Stephenson, Sven Wischnowsky and the Zsh Development Group have no
+ * obligation to provide maintenance, support, updates, enhancements, or
+ * modifications. 
+ *
+ */
+
+/*
+ * To do:  worry about when keys of associative arrays get unmeta'd.
+ */
+#include "mapfile.mdh"
+#include "mapfile.pro"
+
+/*
+ * Make sure we have all the bits I'm using for memory mapping, otherwise
+ * I don't know what I'm doing.
+ */
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_FTRUNCATE)
+#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(HAVE_MSYNC)
+#define USE_MMAP 1
+
+#include <sys/mman.h>
+
+#if !defined(MAP_VARIABLE)
+#define MAP_VARIABLE 0
+#endif
+#if !defined(MAP_FILE)
+#define MAP_FILE 0
+#endif
+#if !defined(MAP_NORESERVE)
+#define MAP_NORESERVE 0
+#endif
+#define MMAP_ARGS (MAP_FILE | MAP_VARIABLE | MAP_SHARED | MAP_NORESERVE)
+
+#endif /* HAVE_MMAP && HAVE_MUNMAP && HAVE_MSYNC */
+#endif /* HAVE_SYS_MMAN_H &&  HAVE_FTRUNCATE */
+
+/*
+ * Name of the special parameter.  If zmodload took arguments,
+ * we could make this selectable.
+ */
+static char mapfile_nam[] = "mapfile";
+
+static Param mapfile_pm;
+
+/* Empty dummy function for special hash parameters. */
+
+/**/
+static void
+shempty(void)
+{
+}
+
+/* Create the special hash parameter. */
+
+/**/
+static Param
+createmapfilehash()
+{
+    Param pm;
+    HashTable ht;
+
+    unsetparam(mapfile_nam);
+    mapfile_pm = NULL;
+
+    if (!(pm = createparam(mapfile_nam, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
+	return NULL;
+
+    pm->level = pm->old ? locallevel : 0;
+    pm->gets.hfn = hashgetfn;
+    pm->sets.hfn = setpmmapfiles;
+    pm->unsetfn = stdunsetfn;
+    pm->u.hash = ht = newhashtable(7, mapfile_nam, NULL);
+
+    ht->hash        = hasher;
+    ht->emptytable  = (TableFunc) shempty;
+    ht->filltable   = NULL;
+    ht->addnode     = (AddNodeFunc) shempty;
+    ht->getnode     = ht->getnode2 = getpmmapfile;
+    ht->removenode  = (RemoveNodeFunc) shempty;
+    ht->disablenode = NULL;
+    ht->enablenode  = NULL;
+    ht->freenode    = (FreeNodeFunc) shempty;
+    ht->printnode   = printparamnode;
+    ht->scantab     = scanpmmapfile;
+
+    return (mapfile_pm = pm);
+}
+
+/* Functions for the options special parameter. */
+
+/**/
+static void
+setpmmapfile(Param pm, char *value)
+{
+    int fd = -1, len;
+    char *name = ztrdup(pm->nam);
+#ifdef USE_MMAP
+    caddr_t mmptr;
+#else
+    FILE *fout;
+#endif
+
+    /*
+     * First unmetafy the value, and the name since we don't
+     * where it's been.
+     */
+    unmetafy(name, &len);
+    unmetafy(value, &len);
+
+    /* Open the file for writing */
+#ifdef USE_MMAP
+    if (!(pm->flags & PM_READONLY) &&
+	(fd = open(name, O_RDWR|O_CREAT|O_NOCTTY, 0666)) >= 0 &&
+	(mmptr = (caddr_t)mmap((caddr_t)0, len, PROT_READ | PROT_WRITE,
+			       MMAP_ARGS, fd, (off_t)0)) != (caddr_t)-1) {
+	/*
+	 * First we need to make sure the file is long enough for
+	 * when we msync.  On AIX, at least, we just get zeroes otherwise.
+	 */
+	ftruncate(fd, len);
+	memcpy(mmptr, value, len);
+	msync(mmptr, len, MS_SYNC);
+	/*
+	 * Then we need to truncate again, since mmap() always maps complete
+	 * pages.  Honestly, I tried it without, and you need both.
+	 */
+	ftruncate(fd, len);
+    }
+#else /* don't USE_MMAP */
+    /* can't be bothered to do anything too clever here */
+    if ((fout = fopen(name, "w"))) {
+	while (len--)
+	    putc(*value++, fout);
+	fclose(fout);
+    }
+#endif /* USE_MMAP */
+    if (fd >= 0)
+	close(fd);
+    free(name);
+    free(value);
+}
+
+/**/
+static void
+unsetpmmapfile(Param pm, int exp)
+{
+    /* Unlink the file given by pm->nam */
+    char *fname = ztrdup(pm->nam);
+    int dummy;
+    unmetafy(fname, &dummy);
+
+    if (!(pm->flags & PM_READONLY))
+	unlink(fname);
+
+    free(fname);
+}
+
+/**/
+static void
+setpmmapfiles(Param pm, HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    /* just to see if I've understood what's happening */
+    DPUTS(pm != mapfile_pm, "BUG: setpmmapfiles called for wrong param");
+
+    if (!ht)
+	return;
+
+    if (!(pm->flags & PM_READONLY))
+	for (i = 0; i < ht->hsize; i++)
+	    for (hn = ht->nodes[i]; hn; hn = hn->next) {
+		struct value v;
+
+		v.isarr = v.inv = v.a = 0;
+		v.b = -1;
+		v.arr = NULL;
+		v.pm = (Param) hn;
+
+		setpmmapfile(v.pm, ztrdup(getstrvalue(&v)));
+	    }
+    deleteparamtable(ht);
+}
+
+/**/
+static char *
+get_contents(char *fname)
+{
+    int fd;
+#ifdef USE_MMAP
+    caddr_t mmptr;
+    struct stat sbuf;
+#endif
+    char *val;
+    unmetafy(fname = ztrdup(fname), &fd);
+
+#ifdef USE_MMAP
+    if ((fd = open(fname, O_RDONLY | O_NOCTTY)) < 0 ||
+	fstat(fd, &sbuf) ||
+	(mmptr = (caddr_t)mmap((caddr_t)0, sbuf.st_size, PROT_READ,
+			       MMAP_ARGS, fd, (off_t)0)) == (caddr_t)-1) {
+	if (fd >= 0)
+	    close(fd);
+	free(fname);
+	return NULL;
+    }
+
+    /*
+     * Sadly, we need to copy the thing even if metafying doesn't
+     * change it.  We just don't know when we might get a chance to
+     * munmap it, otherwise.
+     */
+    val = metafy((char *)mmptr, sbuf.st_size, META_HEAPDUP);
+
+    munmap(mmptr, sbuf.st_size);
+    close(fd);
+#else /* don't USE_MMAP */
+    val = NULL;
+    if ((fd = open(fname, O_RDONLY | O_NOCTTY)) >= 0) {
+	LinkList ll;
+	MUSTUSEHEAP("mapfile:get_contents");
+	if ((ll = readoutput(fd, 1)))
+	    val = peekfirst(ll);
+    }
+#endif /* USE_MMAP */
+    free(fname);
+    return val;
+}
+
+/**/
+static HashNode
+getpmmapfile(HashTable ht, char *name)
+{
+    char *contents;
+    Param pm = NULL;
+
+    HEAPALLOC {
+	pm = (Param) zhalloc(sizeof(struct param));
+	pm->nam = dupstring(name);
+	pm->flags = PM_SCALAR;
+	pm->sets.cfn = setpmmapfile;
+	pm->gets.cfn = strgetfn;
+	pm->unsetfn = unsetpmmapfile;
+	pm->ct = 0;
+	pm->env = NULL;
+	pm->ename = NULL;
+	pm->old = NULL;
+	pm->level = 0;
+
+	pm->flags |= (mapfile_pm->flags & PM_READONLY);
+
+	/* Set u.str to contents of file given by name */
+	if ((contents = get_contents(pm->nam)))
+	    pm->u.str = contents;
+	else {
+	    pm->u.str = "";
+	    pm->flags |= PM_UNSET;
+	}
+    } LASTALLOC;
+
+    return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmmapfile(HashTable ht, ScanFunc func, int flags)
+{
+    struct param pm;
+    DIR *dir;
+
+    if (!(dir = opendir(".")))
+	return;
+
+    pm.flags = PM_SCALAR;
+    pm.sets.cfn = setpmmapfile;
+    pm.gets.cfn = strgetfn;
+    pm.unsetfn = unsetpmmapfile;
+    pm.ct = 0;
+    pm.env = NULL;
+    pm.ename = NULL;
+    pm.old = NULL;
+    pm.level = 0;
+
+    pm.flags |= (mapfile_pm->flags & PM_READONLY);
+
+    /* Here we scan the current directory, calling func() for each file */
+    while ((pm.nam = zreaddir(dir, 1))) {
+	/*
+	 * Hmmm, it's rather wasteful always to read the contents.
+	 * In fact, it's grotesequely wasteful, since that would mean
+	 * we always read the entire contents of every single file
+	 * in the directory into memory.  Hence just leave it empty.
+	 */
+	pm.u.str = "";
+	func((HashNode) &pm, flags);
+    }
+    closedir(dir);
+}
+
+/**/
+int
+setup_mapfile(Module m)
+{
+    return 0;
+}
+
+/**/
+int
+boot_mapfile(Module m)
+{
+    /* Create the special associative array. */
+
+    if (!createmapfilehash())
+	return 1;
+
+    return 0;
+}
+
+#ifdef MODULE
+
+/**/
+int
+cleanup_mapfile(Module m)
+{
+    Param pm;
+
+    /* Remove the special parameter if it is still the same. */
+
+    if ((pm = (Param) paramtab->getnode(paramtab, mapfile_nam)) &&
+	pm == mapfile_pm) {
+	pm->flags &= ~PM_READONLY;
+	unsetparam_pm(pm, 0, 1);
+    }
+    return 0;
+}
+
+/**/
+int
+finish_mapfile(Module m)
+{
+    return 0;
+}
+
+#endif
diff --git a/Src/Modules/mapfile.mdd b/Src/Modules/mapfile.mdd
new file mode 100644
index 000000000..9adb36162
--- /dev/null
+++ b/Src/Modules/mapfile.mdd
@@ -0,0 +1,3 @@
+autoparams="mapfile"
+
+objects="mapfile.o"
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 2257933f5..4cb7b0aba 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -184,7 +184,7 @@ setpmcommand(Param pm, char *value)
 	Cmdnam cn = zcalloc(sizeof(*cn));
 
 	cn->flags = HASHED;
-	cn->u.cmd = ztrdup(value);
+	cn->u.cmd = value;
 
 	cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn);
     }
@@ -207,6 +207,9 @@ setpmcommands(Param pm, HashTable ht)
     int i;
     HashNode hn;
 
+    if (!ht)
+	return;
+
     for (i = 0; i < ht->hsize; i++)
 	for (hn = ht->nodes[i]; hn; hn = hn->next) {
 	    Cmdnam cn = zcalloc(sizeof(*cn));
@@ -222,6 +225,7 @@ setpmcommands(Param pm, HashTable ht)
 
 	    cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn);
 	}
+    deleteparamtable(ht);
 }
 
 /**/
@@ -312,14 +316,13 @@ scanpmcommands(HashTable ht, ScanFunc func, int flags)
 
 /**/
 static void
-setfunction(char *name, char *value)
+setfunction(char *name, char *val)
 {
-    char *val;
+    char *value = dupstring(val);
     Shfunc shf;
     List list;
     int sn;
 
-    val = ztrdup(value);
     val = metafy(val, strlen(val), META_REALLOC);
 
     HEAPALLOC {
@@ -327,7 +330,7 @@ setfunction(char *name, char *value)
     } LASTALLOC;
 
     if (!list || list == &dummy_list) {
-	zwarnnam(NULL, "invalid function definition", val, 0);
+	zwarnnam(NULL, "invalid function definition", value, 0);
 	zsfree(val);
 	return;
     }
@@ -348,7 +351,6 @@ setfunction(char *name, char *value)
 	}
 	shfunctab->addnode(shfunctab, ztrdup(name), shf);
     } LASTALLOC;
-
     zsfree(val);
 }
 
@@ -376,6 +378,9 @@ setpmfunctions(Param pm, HashTable ht)
     int i;
     HashNode hn;
 
+    if (!ht)
+	return;
+
     for (i = 0; i < ht->hsize; i++)
 	for (hn = ht->nodes[i]; hn; hn = hn->next) {
 	    struct value v;
@@ -385,8 +390,9 @@ setpmfunctions(Param pm, HashTable ht)
 	    v.arr = NULL;
 	    v.pm = (Param) hn;
 
-	    setfunction(hn->nam, getstrvalue(&v));
+	    setfunction(hn->nam, ztrdup(getstrvalue(&v)));
 	}
+    deleteparamtable(ht);
 }
 
 /**/
@@ -483,6 +489,7 @@ setpmoption(Param pm, char *value)
 	zwarnnam(NULL, "no such option: %s", pm->nam, 0);
     else if (dosetopt(n, (value && strcmp(value, "off")), 0))
 	zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
+    zsfree(value);
 }
 
 /**/
@@ -504,6 +511,9 @@ setpmoptions(Param pm, HashTable ht)
     int i;
     HashNode hn;
 
+    if (!ht)
+	return;
+
     for (i = 0; i < ht->hsize; i++)
 	for (hn = ht->nodes[i]; hn; hn = hn->next) {
 	    struct value v;
@@ -521,6 +531,7 @@ setpmoptions(Param pm, HashTable ht)
 			      (val && strcmp(val, "off")), 0))
 		zwarnnam(NULL, "can't change option: %s", hn->nam, 0);
 	}
+    deleteparamtable(ht);
 }
 
 /**/
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 217678c00..f644dfc38 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -2279,6 +2279,7 @@ set_compstate(Param pm, HashTable ht)
 
 		    break;
 		}
+    deleteparamtable(ht);
 }
 
 /**/
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index aadbaec6c..41ea12e77 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -751,6 +751,7 @@ check_param(char *s, int set)
 	    wb = cs - offs;
 	    we = wb + e - b;
 	    ispar = (br >= 2 ? 2 : 1);
+	    b[we-wb] = '\0';
 	    return b;
 	}
     }
@@ -2327,7 +2328,7 @@ match_str(char *l, char *w, int *bp, int *rwlp, int sfx, int test)
 		    }
 		    ow = w;
 
-		    if (!ict)
+		    if (!llen && !alen)
 			lm = mp;
 		    else
 			lm = NULL;
@@ -3596,15 +3597,22 @@ addmatches(Cadata dat, char **argv)
 	    /* Get the contents of the completion variables if we have
 	     * to perform matching. */
 	    if (dat->aflags & CAF_MATCH) {
-		lipre = dupstring(compiprefix);
-		lisuf = dupstring(compisuffix);
+		if (dat->aflags & CAF_QUOTE) {
+		    lipre = dupstring(compiprefix);
+		    lisuf = dupstring(compisuffix);
+		} else {
+		    lipre = quotename(compiprefix, NULL);
+		    lisuf = quotename(compisuffix, NULL);
+		}
 		lpre = dupstring(compprefix);
 		lsuf = dupstring(compsuffix);
 		llpl = strlen(lpre);
 		llsl = strlen(lsuf);
 		/* Test if there is an existing -P prefix. */
 		if (dat->pre && *dat->pre) {
-		    pl = pfxlen(dat->pre, lpre);
+		    char *dp = rembslash(dat->pre);
+
+		    pl = pfxlen(dp, lpre);
 		    llpl -= pl;
 		    lpre += pl;
 		}
@@ -5324,10 +5332,11 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
 	int pl = 0;
 
 	if (*s) {
+	    char *dp = rembslash(cc->prefix);
 	    /* First find out how much of the prefix is already on the line. */
 	    sd = dupstring(s);
 	    untokenize(sd);
-	    pl = pfxlen(cc->prefix, sd);
+	    pl = pfxlen(dp, sd);
 	    s += pl;
 	    sd += pl;
 	    offs -= pl;
@@ -5335,7 +5344,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
     }
     /* Does this compctl have a suffix (compctl -S)? */
     if (cc->suffix) {
-	char *sdup = dupstring(cc->suffix);
+	char *sdup = rembslash(cc->suffix);
 	int sl = strlen(sdup), suffixll;
 
 	/* Ignore trailing spaces. */
@@ -7112,9 +7121,13 @@ do_single(Cmatch m)
 		menuinsc++;
 		if (menuwe)
 		    menuend++;
-		if ((!menucmp || menuwe) && isset(AUTOREMOVESLASH)) {
-		    makesuffix(1);
-		    suffixlen['/'] = 1;
+		if (!menucmp || menuwe) {
+		    if (m->remf || m->rems)
+			makesuffixstr(m->remf, m->rems, 1);
+		    else if (isset(AUTOREMOVESLASH)) {
+			makesuffix(1);
+			suffixlen['/'] = 1;
+		    }
 		}
 	    }
 	}
diff --git a/Src/builtin.c b/Src/builtin.c
index a90d59cae..4c9b159dd 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2962,7 +2962,8 @@ zexit(int val, int from_signal)
 	    if (islogin && !subsh) {
 		sourcehome(".zlogout");
 #ifdef GLOBAL_ZLOGOUT
-		source(GLOBAL_ZLOGOUT);
+		if (isset(RCS) && isset(GLOBALRCS))
+		    source(GLOBAL_ZLOGOUT);
 #endif
 	    }
 	}
diff --git a/Src/exec.c b/Src/exec.c
index 7d15facfd..952dfbb78 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2342,7 +2342,7 @@ getoutput(char *cmd, int qt)
 /* read output of command substitution */
 
 /**/
-static LinkList
+LinkList
 readoutput(int in, int qt)
 {
     LinkList ret;
diff --git a/Src/init.c b/Src/init.c
index 86d5aa505..7f1b2153a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -759,26 +759,11 @@ run_init_scripts(void)
 	source(GLOBAL_ZSHENV);
 #endif
 	if (isset(RCS)) {
-	    int globalfirst = isset(GLOBALRCSFIRST);
-	    if (globalfirst) {
-#ifdef GLOBAL_ZPROFILE
-		if (islogin)
-		    source(GLOBAL_ZPROFILE);
-#endif
-#ifdef GLOBAL_ZSHRC
-		if (interact)
-		    source(GLOBAL_ZSHRC);
-#endif
-#ifdef GLOBAL_ZLOGIN
-		if (islogin)
-		    source(GLOBAL_ZLOGIN);
-#endif
-	    }
 	    if (unset(PRIVILEGED))
 		sourcehome(".zshenv");
 	    if (islogin) {
 #ifdef GLOBAL_ZPROFILE
-		if (!globalfirst)
+		if (isset(GLOBALRCS))
 		    source(GLOBAL_ZPROFILE);
 #endif
 		if (unset(PRIVILEGED))
@@ -786,7 +771,7 @@ run_init_scripts(void)
 	    }
 	    if (interact) {
 #ifdef GLOBAL_ZSHRC
-		if (!globalfirst)
+		if (isset(GLOBALRCS))
 		    source(GLOBAL_ZSHRC);
 #endif
 		if (unset(PRIVILEGED))
@@ -794,7 +779,7 @@ run_init_scripts(void)
 	    }
 	    if (islogin) {
 #ifdef GLOBAL_ZLOGIN
-		if (!globalfirst)
+		if (isset(GLOBALRCS))
 		    source(GLOBAL_ZLOGIN);
 #endif
 		if (unset(PRIVILEGED))
diff --git a/Src/options.c b/Src/options.c
index 36030f516..5725d27c0 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -109,7 +109,7 @@ static struct optname optns[] = {
 {NULL, "flowcontrol",	      OPT_ALL,			 FLOWCONTROL},
 {NULL, "functionargzero",     OPT_EMULATE|OPT_NONBOURNE, FUNCTIONARGZERO},
 {NULL, "glob",		      OPT_ALL,			 GLOBOPT},
-{NULL, "globalrcsfirst",      0,			 GLOBALRCSFIRST},
+{NULL, "globalrcs",           OPT_ALL,			 GLOBALRCS},
 {NULL, "globassign",	      OPT_EMULATE|OPT_CSH,	 GLOBASSIGN},
 {NULL, "globcomplete",	      0,			 GLOBCOMPLETE},
 {NULL, "globdots",	      0,			 GLOBDOTS},
@@ -265,7 +265,7 @@ static short zshletters[LAST_OPT - FIRST_OPT + 1] = {
     /* a */  ALLEXPORT,
     /* b */  0,			/* in non-Bourne shells, end of options */
     /* c */  0,			/* command follows */
-    /* d */  GLOBALRCSFIRST,
+    /* d */ -GLOBALRCS,
     /* e */  ERREXIT,
     /* f */ -RCS,
     /* g */  HISTIGNORESPACE,
diff --git a/Src/params.c b/Src/params.c
index e10fbda93..75910c6fd 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -331,6 +331,24 @@ copyparamtable(HashTable ht, char *name)
     return nht;
 }
 
+/* Flag to freeparamnode to unset the struct */
+
+static int delunset;
+
+/* Function to delete a parameter table. */
+
+/**/
+void
+deleteparamtable(HashTable t)
+{
+    /* The parameters in the hash table need to be unset *
+     * before being deleted.                             */
+    int odelunset = delunset;
+    delunset = 1;
+    deletehashtable(t);
+    delunset = odelunset;
+}
+
 static unsigned numparamvals;
 
 /**/
@@ -426,7 +444,7 @@ createparamtable(void)
     Param ip, pm;
     char **new_environ, **envp, **envp2, **sigptr, **t;
     char buf[50], *str, *iname;
-    int num_env;
+    int num_env, oae = opts[ALLEXPORT];
 
     paramtab = realparamtab = newparamtable(151, "paramtab");
 
@@ -446,6 +464,7 @@ createparamtable(void)
 	 * be initialized before we copy the environment variables. *
 	 * We don't want to override whatever values the users has  *
 	 * given them in the environment.                           */
+	opts[ALLEXPORT] = 0;
 	setiparam("MAILCHECK", 60);
 	setiparam("LOGCHECK", 60);
 	setiparam("KEYTIMEOUT", 40);
@@ -491,6 +510,7 @@ createparamtable(void)
 	    }
 	}
 	environ = new_environ;
+	opts[ALLEXPORT] = oae;
 
 	pm = (Param) paramtab->getnode(paramtab, "HOME");
 	if (!(pm->flags & PM_EXPORTED)) {
@@ -1867,24 +1887,14 @@ hashgetfn(Param pm)
     return pm->u.hash;
 }
 
-/* Flag to freeparamnode to unset the struct */
-
-static int delunset;
-
 /* Function to set value of an association parameter */
 
 /**/
 void
 hashsetfn(Param pm, HashTable x)
 {
-    if (pm->u.hash && pm->u.hash != x) {
-	/* The parameters in the hash table need to be unset *
-	 * before being deleted.                             */
-	int odelunset = delunset;
-	delunset = 1;
-	deletehashtable(pm->u.hash);
-	delunset = odelunset;
-    }
+    if (pm->u.hash && pm->u.hash != x)
+	deleteparamtable(pm->u.hash);
     pm->u.hash = x;
 }
 
diff --git a/Src/subst.c b/Src/subst.c
index 3030218d6..47b59e793 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -279,7 +279,7 @@ multsub(char **s, char ***a, int *isarr, char *sep)
 	*p = NULL;
 	if (a && mult_isarr) {
 	    *a = r;
-	    *isarr = 1;
+	    *isarr = SCANPM_MATCHMANY;
 	    mult_isarr = omi;
 	    return 0;
 	}
@@ -976,7 +976,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		zerr("bad substitution", NULL, 0);
 		return NULL;
 	    }
-	} else
+	} else if (INULL(*s))
+	    s++;
+	else
 	    break;
     }
     globsubst = globsubst && !qt;
@@ -999,6 +1001,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	    idbeg = val;
 	copied = 1;
 	*s = sav;
+	while (INULL(*s))
+	    s++;
 	v = (Value) NULL;
     } else if (aspar) {
 	if ((v = getvalue(&s, 1))) {
diff --git a/Src/zsh.export b/Src/zsh.export
index 65626e2f6..7595f1d2e 100644
--- a/Src/zsh.export
+++ b/Src/zsh.export
@@ -44,6 +44,7 @@ deletebuiltins
 deleteconddefs
 deletehashtable
 deleteparamdefs
+deleteparamtable
 deletewrapper
 domatch
 dosetopt
@@ -191,6 +192,7 @@ pwd
 quietgetevent
 quietgethist
 quotedzputs
+readoutput
 realparamtab
 refreshptr
 remlpaths
diff --git a/Src/zsh.h b/Src/zsh.h
index ae4513491..4d46beada 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1158,7 +1158,7 @@ enum {
     EXTENDEDHISTORY,
     FLOWCONTROL,
     FUNCTIONARGZERO,
-    GLOBALRCSFIRST,
+    GLOBALRCS,
     GLOBOPT,
     GLOBASSIGN,
     GLOBCOMPLETE,
diff --git a/configure.in b/configure.in
index 7ecdf620e..68413fad7 100644
--- a/configure.in
+++ b/configure.in
@@ -362,7 +362,7 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
 		 termios.h sys/param.h sys/filio.h string.h memory.h \
 		 limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
 		 locale.h errno.h stdlib.h unistd.h sys/capability.h \
-		 utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h)
+		 utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h)
 if test $dynamic = yes; then
   AC_CHECK_HEADERS(dlfcn.h)
   AC_CHECK_HEADERS(dl.h)
@@ -706,7 +706,7 @@ AC_CHECK_FUNCS(memcpy memmove \
               sigprocmask setuid seteuid setreuid setresuid setsid strerror \
               nis_list initgroups fchdir cap_get_proc readlink nice \
 	      getgrgid getgrnam getpwent getpwnam getpwuid setpgrp \
-	      fseeko ftello)
+	      fseeko ftello mmap munmap msync ftruncate)
 
 dnl ---------------
 dnl CHECK FUNCTIONS
@@ -1279,30 +1279,30 @@ AC_SUBST(IMPOPT)dnl
 AC_SUBST(L)dnl
 AC_SUBST(RTLD_GLOBAL_OK)dnl
 
+CLEAN_MK="${srcdir}/Config/clean.mk"
+CONFIG_MK="${srcdir}/Config/config.mk"
+dnl defs.mk is in the build tree, not the source tree
+DEFS_MK="Config/defs.mk"
+VERSION_MK="${srcdir}/Config/version.mk"
+
+AC_SUBST_FILE(CLEAN_MK)dnl
+AC_SUBST_FILE(CONFIG_MK)dnl
+AC_SUBST_FILE(DEFS_MK)dnl
+AC_SUBST_FILE(VERSION_MK)dnl
+
 real_no_create=$no_create
 no_create=yes
-AC_OUTPUT(Makefile Doc/Makefile Etc/Makefile Src/Makefile, \
+
+AC_OUTPUT(Config/defs.mk Makefile Doc/Makefile Etc/Makefile Src/Makefile, \
 [test -z "$CONFIG_HEADERS" || echo > stamp-h])
 
 dnl The standard config.status is missing some essential features.
 dnl So add them now.
-[(
-  echo '1,$s@^#( *ac_file_inputs=#).*$@#1`echo $ac_file_in | sed -e "s%^%:%" -e "s%:##([^!]##)% $ac_given_srcdir/##1%g" -e "s%:!% %"`@'
-  echo '/ac_sed_cmds=cat/+a'
-  echo ''
-  echo 'ac_sed_inc_cmds="'
-  quote_sed='s,\.,#.,g'
-  for name in `echo '' ${srcdir}/Config/*.mk | sed "s, ${srcdir}/Config/, ,g"`; do
-    echo '/^@@'`echo $name | sed -e "$quote_sed"`'@@#$/{r $ac_given_srcdir/Config/'$name
-    echo 'd;}'
-  done
-  echo '"'
-  echo '.'
-  echo '1,$s@^#( *#)#(sed -e "#$ac_comsub *#)$@#1sed -e "$ac_sed_inc_cmds" $ac_file_inputs | #2@'
-  echo '1,$s@^#( *"#)  *$ac_file_inputs |@#1 |@'
-  echo 'w'
-  echo 'q'
-) | tr '#' '\\' | ed $CONFIG_STATUS >/dev/null 2>/dev/null]
+[rm -f $CONFIG_STATUS.old
+cp $CONFIG_STATUS $CONFIG_STATUS.old
+sed '1,$s@^\( *ac_file_inputs=\).*$@\1`echo $ac_file_in | sed -e "s%^%:%" -e "s%:\\([^!]\\)% $ac_given_srcdir/\\1%g" -e "s%:!% %"`@' \
+ $CONFIG_STATUS.old >$CONFIG_STATUS
+ rm -f $CONFIG_STATUS.old]
 
 test "$real_no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
 
diff --git a/patchlist.txt b/patchlist.txt
index 40075513a..4af0e6ea0 100644
--- a/patchlist.txt
+++ b/patchlist.txt
@@ -1085,6 +1085,8 @@ pws: 6259: second version of compinstall
 
 pws: 6263: incrementalappendhistory -> incappendhistory
 
+Sven: 6268: parameter module for access to internal tables
+
 pws: 6284, should have been in 6269: changes to large file support
 
 pws: 6271: make sure -D_LARGEFILE_SOURCE is defined any time there are
@@ -1129,3 +1131,40 @@ pws: 6314: in something like `{ false; } || true', errexit shouldn't be
 used at all on the left of the ||
 
 pws: unposted: updated some .distfiles
+
+  pws-20
+
+Sven: 6318: memory fixes for parameter module (and compctl).
+
+Sven: 6322: reverse indexing of nested arrays
+
+Sven: 6326: compadd -r and -R work on automatically added suffixes, too
+
+pws: 6330: rewrite configuration system to use AC_SUBST_FILE instead
+of including files by ed trickery (ed is now no longer required).
+
+pws: 6331: protect against null hash tables in parameter module
+
+pws: 6332: mapfile module
+
+pws: 6335: now you can do ${(f)"$(...)"} to get arrays
+
+pws: 6340: INSTALL didn't work if it was install-sh after 6330
+
+Sven: 6343: test length of anchor in partial word matching
+
+pws: 6345: Config/defs.mk is now in build tree, not source tree
+
+pws: 6346: msync() missing from mapfile.c, somehow
+
+Sven: 6352, 6354: more quoting in completion
+
+Sven: 6355: ALL_EXPORT crashed the shell if set on command line
+
+Bart: 6368: don't use cp -f, use rm -f in configure.in
+
+Bart: 6369: fix use of relative paths in compinstall
+
+Sven: 6374: autoremove behaviour on -r and -R, documentation
+
+Sven: 6388: completion in braces removes later arguments