From f42e3fa8e6152e145251e8f16f4c61c23dec1f59 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Mon, 31 May 1999 17:10:12 +0000 Subject: pws-20 --- Src/Makefile.in | 15 +- Src/Makemod.in.in | 13 +- Src/Modules/mapfile.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++ Src/Modules/mapfile.mdd | 3 + Src/Modules/parameter.c | 25 +++- Src/Zle/compctl.c | 1 + Src/Zle/zle_tricky.c | 31 ++-- Src/builtin.c | 3 +- Src/exec.c | 2 +- Src/init.c | 21 +-- Src/options.c | 4 +- Src/params.c | 36 +++-- Src/subst.c | 8 +- Src/zsh.export | 2 + Src/zsh.h | 2 +- 15 files changed, 474 insertions(+), 61 deletions(-) create mode 100644 Src/Modules/mapfile.c create mode 100644 Src/Modules/mapfile.mdd (limited to 'Src') 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 + +#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, -- cgit 1.4.1