diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Builtins/rlimits.c | 6 | ||||
-rw-r--r-- | Src/Modules/.distfiles | 1 | ||||
-rw-r--r-- | Src/Modules/example.c | 8 | ||||
-rw-r--r-- | Src/Modules/parameter.c | 662 | ||||
-rw-r--r-- | Src/Modules/parameter.mdd | 3 | ||||
-rw-r--r-- | Src/Modules/stat.c | 12 | ||||
-rw-r--r-- | Src/Modules/zftp.c | 135 | ||||
-rw-r--r-- | Src/Zle/comp1.c | 10 | ||||
-rw-r--r-- | Src/Zle/compctl.c | 6 | ||||
-rw-r--r-- | Src/Zle/zle_params.c | 14 | ||||
-rw-r--r-- | Src/Zle/zle_refresh.c | 54 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 5 | ||||
-rw-r--r-- | Src/builtin.c | 13 | ||||
-rw-r--r-- | Src/compat.c | 18 | ||||
-rw-r--r-- | Src/cond.c | 2 | ||||
-rw-r--r-- | Src/exec.c | 98 | ||||
-rw-r--r-- | Src/glob.c | 130 | ||||
-rw-r--r-- | Src/hashtable.c | 5 | ||||
-rw-r--r-- | Src/hist.c | 6 | ||||
-rw-r--r-- | Src/init.c | 6 | ||||
-rw-r--r-- | Src/input.c | 2 | ||||
-rw-r--r-- | Src/jobs.c | 57 | ||||
-rw-r--r-- | Src/math.c | 54 | ||||
-rw-r--r-- | Src/mem.c | 33 | ||||
-rw-r--r-- | Src/module.c | 4 | ||||
-rw-r--r-- | Src/options.c | 26 | ||||
-rw-r--r-- | Src/params.c | 90 | ||||
-rw-r--r-- | Src/prototypes.h | 2 | ||||
-rw-r--r-- | Src/subst.c | 19 | ||||
-rw-r--r-- | Src/system.h | 18 | ||||
-rw-r--r-- | Src/utils.c | 12 | ||||
-rw-r--r-- | Src/zsh.export | 16 | ||||
-rw-r--r-- | Src/zsh.h | 41 |
33 files changed, 1260 insertions, 308 deletions
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index 34344f5c1..f8167a106 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -112,9 +112,15 @@ showlimits(int hard, int lim) else printf("%lldkB\n", val / 1024L); # else +# ifdef RLIM_T_IS_UNSIGNED + printf("%luMB\n", val / (1024L * 1024L)); + else + printf("%lukB\n", val / 1024L); +# else printf("%ldMB\n", val / (1024L * 1024L)); else printf("%ldkB\n", val / 1024L); +# endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ } diff --git a/Src/Modules/.distfiles b/Src/Modules/.distfiles index 23c7eae3f..dbc152fa8 100644 --- a/Src/Modules/.distfiles +++ b/Src/Modules/.distfiles @@ -4,6 +4,7 @@ DISTFILES_SRC=' clone.mdd clone.c example.mdd example.c files.mdd files.c + parameter.mdd parameter.c stat.mdd stat.c zftp.mdd zftp.c ' diff --git a/Src/Modules/example.c b/Src/Modules/example.c index 50b8c1626..1b24f336c 100644 --- a/Src/Modules/example.c +++ b/Src/Modules/example.c @@ -32,7 +32,7 @@ /* parameters */ -static long intparam; +static zlong intparam; static char *strparam; static char **arrparam; @@ -55,7 +55,11 @@ bin_example(char *nam, char **args, char *ops, int func) fputs(*args, stdout); } printf("\nName: %s\n", nam); +#ifdef ZSH_64_BIT_TYPE + printf("\nInteger Parameter: %s\n", output64(intparam)); +#else printf("\nInteger Parameter: %ld\n", intparam); +#endif printf("String Parameter: %s\n", strparam ? strparam : ""); printf("Array Parameter:"); if (p) @@ -79,7 +83,7 @@ cond_p_len(char **a, int id) char *s1 = cond_str(a, 0); if (a[1]) { - long v = cond_val(a, 1); + zlong v = cond_val(a, 1); return strlen(s1) == v; } else { diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c new file mode 100644 index 000000000..2257933f5 --- /dev/null +++ b/Src/Modules/parameter.c @@ -0,0 +1,662 @@ +/* + * parameter.c - parameter interface to zsh internals + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1999 Sven Wischnowsky + * 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 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 Sven Wischnowsky and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * 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 software + * provided hereunder is on an "as is" basis, and Sven Wischnowsky and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "parameter.mdh" +#include "parameter.pro" + +/* Empty dummy function for special hash parameters. */ + +/**/ +static void +shempty(void) +{ +} + +/* Create a simple special hash parameter. */ + +/**/ +static Param +createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan) +{ + Param pm; + HashTable ht; + + if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED))) + return NULL; + + pm->level = pm->old ? locallevel : 0; + pm->gets.hfn = hashgetfn; + pm->sets.hfn = hashsetfn; + pm->unsetfn = stdunsetfn; + pm->u.hash = ht = newhashtable(7, name, NULL); + + ht->hash = hasher; + ht->emptytable = (TableFunc) shempty; + ht->filltable = NULL; + ht->addnode = (AddNodeFunc) shempty; + ht->getnode = ht->getnode2 = get; + ht->removenode = (RemoveNodeFunc) shempty; + ht->disablenode = NULL; + ht->enablenode = NULL; + ht->freenode = (FreeNodeFunc) shempty; + ht->printnode = printparamnode; + ht->scantab = scan; + + return pm; +} + +/* Functions for the parameters special parameter. */ + +/* Return a string describing the type of a parameter. */ + +/**/ +static char * +paramtypestr(Param pm) +{ + char *val = NULL; + int f = pm->flags; + + if (!(f & PM_UNSET)) { + switch (PM_TYPE(f)) { + case PM_SCALAR: val = "scalar"; break; + case PM_ARRAY: val = "array"; break; + case PM_INTEGER: val = "integer"; break; + case PM_HASHED: val = "association"; break; + } + DPUTS(!val, "BUG: type not handled in parameter"); + val = dupstring(val); + if (f & PM_LEFT) + val = dyncat(val, "-left"); + if (f & PM_RIGHT_B) + val = dyncat(val, "-right_blanks"); + if (f & PM_RIGHT_Z) + val = dyncat(val, "-right_zeros"); + if (f & PM_LOWER) + val = dyncat(val, "-lower"); + if (f & PM_UPPER) + val = dyncat(val, "-upper"); + if (f & PM_READONLY) + val = dyncat(val, "-readonly"); + if (f & PM_TAGGED) + val = dyncat(val, "-tag"); + if (f & PM_EXPORTED) + val = dyncat(val, "-export"); + if (f & PM_UNIQUE) + val = dyncat(val, "-unique"); + } else + val = dupstring(""); + + return val; +} + +/**/ +static HashNode +getpmparameter(HashTable ht, char *name) +{ + Param rpm, pm = NULL; + + HEAPALLOC { + pm = (Param) zhalloc(sizeof(struct param)); + pm->nam = dupstring(name); + pm->flags = PM_SCALAR | PM_READONLY; + pm->sets.cfn = NULL; + pm->gets.cfn = strgetfn; + pm->unsetfn = NULL; + pm->ct = 0; + pm->env = NULL; + pm->ename = NULL; + pm->old = NULL; + pm->level = 0; + if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) && + !(rpm->flags & PM_UNSET)) + pm->u.str = paramtypestr(rpm); + else { + pm->u.str = ""; + pm->flags |= PM_UNSET; + } + } LASTALLOC; + + return (HashNode) pm; +} + +/**/ +static void +scanpmparameters(HashTable ht, ScanFunc func, int flags) +{ + struct param pm; + int i; + HashNode hn; + + pm.flags = PM_SCALAR | PM_READONLY; + pm.sets.cfn = NULL; + pm.gets.cfn = strgetfn; + pm.unsetfn = NULL; + pm.ct = 0; + pm.env = NULL; + pm.ename = NULL; + pm.old = NULL; + pm.level = 0; + + for (i = 0; i < realparamtab->hsize; i++) + for (hn = realparamtab->nodes[i]; hn; hn = hn->next) { + pm.nam = hn->nam; + if (func != scancountparams) + pm.u.str = paramtypestr((Param) hn); + func((HashNode) &pm, flags); + } +} + +/* Functions for the commands special parameter. */ + +/**/ +static void +setpmcommand(Param pm, char *value) +{ + if (isset(RESTRICTED)) + zwarnnam(NULL, "restricted: %s", value, 0); + else { + Cmdnam cn = zcalloc(sizeof(*cn)); + + cn->flags = HASHED; + cn->u.cmd = ztrdup(value); + + cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn); + } +} + +/**/ +static void +unsetpmcommand(Param pm, int exp) +{ + HashNode hn = cmdnamtab->removenode(cmdnamtab, pm->nam); + + if (hn) + cmdnamtab->freenode(hn); +} + +/**/ +static void +setpmcommands(Param pm, HashTable ht) +{ + int i; + HashNode hn; + + for (i = 0; i < ht->hsize; i++) + for (hn = ht->nodes[i]; hn; hn = hn->next) { + Cmdnam cn = zcalloc(sizeof(*cn)); + struct value v; + + v.isarr = v.inv = v.a = 0; + v.b = -1; + v.arr = NULL; + v.pm = (Param) hn; + + cn->flags = HASHED; + cn->u.cmd = ztrdup(getstrvalue(&v)); + + cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn); + } +} + +/**/ +static HashNode +getpmcommand(HashTable ht, char *name) +{ + Cmdnam cmd; + Param pm = NULL; + + if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name)) && + isset(HASHLISTALL)) { + cmdnamtab->filltable(cmdnamtab); + cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name); + } + HEAPALLOC { + pm = (Param) zhalloc(sizeof(struct param)); + pm->nam = dupstring(name); + pm->flags = PM_SCALAR; + pm->sets.cfn = setpmcommand; + pm->gets.cfn = strgetfn; + pm->unsetfn = unsetpmcommand; + pm->ct = 0; + pm->env = NULL; + pm->ename = NULL; + pm->old = NULL; + pm->level = 0; + if (cmd) { + if (cmd->flags & HASHED) + pm->u.str = cmd->u.cmd; + else { + pm->u.str = zhalloc(strlen(*(cmd->u.name)) + + strlen(name) + 2); + strcpy(pm->u.str, *(cmd->u.name)); + strcat(pm->u.str, "/"); + strcat(pm->u.str, name); + } + } else { + pm->u.str = ""; + pm->flags |= PM_UNSET; + } + } LASTALLOC; + + return (HashNode) pm; +} + +/**/ +static void +scanpmcommands(HashTable ht, ScanFunc func, int flags) +{ + struct param pm; + int i; + HashNode hn; + Cmdnam cmd; + + if (isset(HASHLISTALL)) + cmdnamtab->filltable(cmdnamtab); + + pm.flags = PM_SCALAR; + pm.sets.cfn = setpmcommand; + pm.gets.cfn = strgetfn; + pm.unsetfn = unsetpmcommand; + pm.ct = 0; + pm.env = NULL; + pm.ename = NULL; + pm.old = NULL; + pm.level = 0; + + for (i = 0; i < cmdnamtab->hsize; i++) + for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) { + pm.nam = hn->nam; + cmd = (Cmdnam) hn; + if (func != scancountparams) { + if (cmd->flags & HASHED) + pm.u.str = cmd->u.cmd; + else { + pm.u.str = zhalloc(strlen(*(cmd->u.name)) + + strlen(cmd->nam) + 2); + strcpy(pm.u.str, *(cmd->u.name)); + strcat(pm.u.str, "/"); + strcat(pm.u.str, cmd->nam); + } + } + func((HashNode) &pm, flags); + } +} + +/* Functions for the functions special parameter. */ + +/**/ +static void +setfunction(char *name, char *value) +{ + char *val; + Shfunc shf; + List list; + int sn; + + val = ztrdup(value); + val = metafy(val, strlen(val), META_REALLOC); + + HEAPALLOC { + list = parse_string(val); + } LASTALLOC; + + if (!list || list == &dummy_list) { + zwarnnam(NULL, "invalid function definition", val, 0); + zsfree(val); + return; + } + PERMALLOC { + shf = (Shfunc) zalloc(sizeof(*shf)); + shf->funcdef = (List) dupstruct(list); + shf->flags = 0; + + if (!strncmp(name, "TRAP", 4) && + (sn = getsignum(name + 4)) != -1) { + if (settrap(sn, shf->funcdef)) { + freestruct(shf->funcdef); + zfree(shf, sizeof(*shf)); + zsfree(val); + LASTALLOC_RETURN; + } + sigtrapped[sn] |= ZSIG_FUNC; + } + shfunctab->addnode(shfunctab, ztrdup(name), shf); + } LASTALLOC; + + zsfree(val); +} + +/**/ +static void +setpmfunction(Param pm, char *value) +{ + setfunction(pm->nam, value); +} + +/**/ +static void +unsetpmfunction(Param pm, int exp) +{ + HashNode hn = shfunctab->removenode(shfunctab, pm->nam); + + if (hn) + shfunctab->freenode(hn); +} + +/**/ +static void +setpmfunctions(Param pm, HashTable ht) +{ + int i; + HashNode hn; + + 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; + + setfunction(hn->nam, getstrvalue(&v)); + } +} + +/**/ +static HashNode +getpmfunction(HashTable ht, char *name) +{ + Shfunc shf; + Param pm = NULL; + + HEAPALLOC { + pm = (Param) zhalloc(sizeof(struct param)); + pm->nam = dupstring(name); + pm->flags = PM_SCALAR; + pm->sets.cfn = setpmfunction; + pm->gets.cfn = strgetfn; + pm->unsetfn = unsetpmfunction; + pm->ct = 0; + pm->env = NULL; + pm->ename = NULL; + pm->old = NULL; + pm->level = 0; + + if ((shf = (Shfunc) shfunctab->getnode(shfunctab, name))) { + if (shf->flags & PM_UNDEFINED) + pm->u.str = "undefined"; + else { + char *t = getpermtext((void *) dupstruct((void *) + shf->funcdef)), *h; + + h = dupstring(t); + zsfree(t); + unmetafy(h, NULL); + + pm->u.str = h; + } + } else { + pm->u.str = ""; + pm->flags |= PM_UNSET; + } + } LASTALLOC; + + return (HashNode) pm; +} + +/**/ +static void +scanpmfunctions(HashTable ht, ScanFunc func, int flags) +{ + struct param pm; + int i; + HashNode hn; + + pm.flags = PM_SCALAR; + pm.sets.cfn = setpmcommand; + pm.gets.cfn = strgetfn; + pm.unsetfn = unsetpmcommand; + pm.ct = 0; + pm.env = NULL; + pm.ename = NULL; + pm.old = NULL; + pm.level = 0; + + for (i = 0; i < shfunctab->hsize; i++) + for (hn = shfunctab->nodes[i]; hn; hn = hn->next) { + if (!(hn->flags & DISABLED)) { + pm.nam = hn->nam; + if (func != scancountparams) { + if (((Shfunc) hn)->flags & PM_UNDEFINED) + pm.u.str = "undefined"; + else { + char *t = getpermtext((void *) + dupstruct((void *) ((Shfunc) hn)->funcdef)); + + unmetafy((pm.u.str = dupstring(t)), NULL); + zsfree(t); + } + } + func((HashNode) &pm, flags); + } + } +} + +/* Functions for the options special parameter. */ + +/**/ +static void +setpmoption(Param pm, char *value) +{ + int n; + + if (!value || (strcmp(value, "on") && strcmp(value, "off"))) + zwarnnam(NULL, "invalid value: %s", value, 0); + else if (!(n = optlookup(pm->nam))) + 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); +} + +/**/ +static void +unsetpmoption(Param pm, int exp) +{ + int n; + + if (!(n = optlookup(pm->nam))) + zwarnnam(NULL, "no such option: %s", pm->nam, 0); + else if (dosetopt(n, 0, 0)) + zwarnnam(NULL, "can't change option: %s", pm->nam, 0); +} + +/**/ +static void +setpmoptions(Param pm, HashTable ht) +{ + int i; + HashNode hn; + + for (i = 0; i < ht->hsize; i++) + for (hn = ht->nodes[i]; hn; hn = hn->next) { + struct value v; + char *val; + + v.isarr = v.inv = v.a = 0; + v.b = -1; + v.arr = NULL; + v.pm = (Param) hn; + + val = getstrvalue(&v); + if (!val || (strcmp(val, "on") && strcmp(val, "off"))) + zwarnnam(NULL, "invalid value: %s", val, 0); + else if (dosetopt(optlookup(hn->nam), + (val && strcmp(val, "off")), 0)) + zwarnnam(NULL, "can't change option: %s", hn->nam, 0); + } +} + +/**/ +static HashNode +getpmoption(HashTable ht, char *name) +{ + Param pm = NULL; + int n; + + HEAPALLOC { + pm = (Param) zhalloc(sizeof(struct param)); + pm->nam = dupstring(name); + pm->flags = PM_SCALAR; + pm->sets.cfn = setpmoption; + pm->gets.cfn = strgetfn; + pm->unsetfn = unsetpmoption; + pm->ct = 0; + pm->env = NULL; + pm->ename = NULL; + pm->old = NULL; + pm->level = 0; + + if ((n = optlookup(name))) + pm->u.str = dupstring(opts[n] ? "on" : "off"); + else { + pm->u.str = ""; + pm->flags |= PM_UNSET; + } + } LASTALLOC; + + return (HashNode) pm; +} + +/**/ +static void +scanpmoptions(HashTable ht, ScanFunc func, int flags) +{ + struct param pm; + int i; + HashNode hn; + + pm.flags = PM_SCALAR; + pm.sets.cfn = setpmoption; + pm.gets.cfn = strgetfn; + pm.unsetfn = unsetpmoption; + pm.ct = 0; + pm.env = NULL; + pm.ename = NULL; + pm.old = NULL; + pm.level = 0; + + for (i = 0; i < optiontab->hsize; i++) + for (hn = optiontab->nodes[i]; hn; hn = hn->next) { + pm.nam = hn->nam; + pm.u.str = opts[((Optname) hn)->optno] ? "on" : "off"; + func((HashNode) &pm, flags); + } +} + +/* Names and Params for the special parameters. */ + +#define PAR_NAM "parameters" +#define CMD_NAM "commands" +#define FUN_NAM "functions" +#define OPT_NAM "options" + +static Param parpm, cmdpm, funpm, optpm; + +/**/ +int +setup_parameter(Module m) +{ + return 0; +} + +/**/ +int +boot_parameter(Module m) +{ + /* Create the special associative arrays. + * As an example for autoloaded parameters, this is probably a bad + * example, because we the zsh core doesn't support creation of + * special hashes, yet. */ + + unsetparam(PAR_NAM); + if (!(parpm = createspecialhash(PAR_NAM, getpmparameter, + scanpmparameters))) + return 1; + parpm->flags |= PM_READONLY; + unsetparam(CMD_NAM); + if (!(cmdpm = createspecialhash(CMD_NAM, getpmcommand, + scanpmcommands))) + return 1; + cmdpm->sets.hfn = setpmcommands; + unsetparam(FUN_NAM); + if (!(funpm = createspecialhash(FUN_NAM, getpmfunction, + scanpmfunctions))) + return 1; + funpm->sets.hfn = setpmfunctions; + unsetparam(OPT_NAM); + if (!(optpm = createspecialhash(OPT_NAM, getpmoption, + scanpmoptions))) + return 1; + optpm->sets.hfn = setpmoptions; + + return 0; +} + +#ifdef MODULE + +/**/ +int +cleanup_parameter(Module m) +{ + Param pm; + + /* Remove the special parameters if they are still the same. */ + + if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm) { + pm->flags &= ~PM_READONLY; + unsetparam_pm(pm, 0, 1); + } + if ((pm = (Param) paramtab->getnode(paramtab, CMD_NAM)) && pm == cmdpm) + unsetparam_pm(pm, 0, 1); + if ((pm = (Param) paramtab->getnode(paramtab, FUN_NAM)) && pm == funpm) + unsetparam_pm(pm, 0, 1); + if ((pm = (Param) paramtab->getnode(paramtab, OPT_NAM)) && pm == optpm) + unsetparam_pm(pm, 0, 1); + return 0; +} + +/**/ +int +finish_parameter(Module m) +{ + return 0; +} + +#endif diff --git a/Src/Modules/parameter.mdd b/Src/Modules/parameter.mdd new file mode 100644 index 000000000..e2820aa9c --- /dev/null +++ b/Src/Modules/parameter.mdd @@ -0,0 +1,3 @@ +autoparams="parameters commands functions options" + +objects="parameter.o" diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index 6f80e2a96..d8179143e 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -213,7 +213,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags) break; case ST_INO: +#ifdef INO_T_IS_64_BIT + convbase(optr, sbuf->st_ino, 0); +#else + DPUTS(sizeof(sbuf->st_ino) > 4, + "Shell compiled with wrong ino_t size"); statulprint((unsigned long)sbuf->st_ino, optr); +#endif break; case ST_MODE: @@ -237,7 +243,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags) break; case ST_SIZE: +#ifdef OFF_T_IS_64_BIT + convbase(optr, sbuf->st_size, 0); +#else + DPUTS(sizeof(sbuf->st_size) > 4, + "Shell compiled with wrong off_t size"); statulprint((unsigned long)sbuf->st_size, optr); +#endif break; case ST_ATIM: diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 651a5c952..873617e95 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -117,7 +117,7 @@ enum { ZFHD_EORB = 128 /* block is end of file */ }; -typedef int (*readwrite_t)(int, char *, size_t, int); +typedef int (*readwrite_t)(int, char *, off_t, int); struct zftpcmd { const char *nam; @@ -195,7 +195,7 @@ static char *zfparams[] = { enum { ZFPM_READONLY = 0x01, /* make parameter readonly */ ZFPM_IFUNSET = 0x02, /* only set if not already set */ - ZFPM_INTEGER = 0x04 /* passed pointer to long */ + ZFPM_INTEGER = 0x04 /* passed pointer to off_t */ }; /* @@ -250,25 +250,26 @@ static int zfhas_size, zfhas_mdtm; * --- we don't try to track it because it's too complicated. */ enum { - ZFST_ASCI = 0x00, /* type for next transfer is ASCII */ - ZFST_IMAG = 0x01, /* type for next transfer is image */ + ZFST_ASCI = 0x0000, /* type for next transfer is ASCII */ + ZFST_IMAG = 0x0001, /* type for next transfer is image */ - ZFST_TMSK = 0x01, /* mask for type flags */ - ZFST_TBIT = 0x01, /* number of bits in type flags */ + ZFST_TMSK = 0x0001, /* mask for type flags */ + ZFST_TBIT = 0x0001, /* number of bits in type flags */ - ZFST_CASC = 0x00, /* current type is ASCII - default */ - ZFST_CIMA = 0x02, /* current type is image */ + ZFST_CASC = 0x0000, /* current type is ASCII - default */ + ZFST_CIMA = 0x0002, /* current type is image */ - ZFST_STRE = 0x00, /* stream mode - default */ - ZFST_BLOC = 0x04, /* block mode */ + ZFST_STRE = 0x0000, /* stream mode - default */ + ZFST_BLOC = 0x0004, /* block mode */ - ZFST_MMSK = 0x04, /* mask for mode flags */ + ZFST_MMSK = 0x0004, /* mask for mode flags */ - ZFST_LOGI = 0x08, /* user logged in */ - ZFST_NOPS = 0x10, /* server doesn't understand PASV */ - ZFST_NOSZ = 0x20, /* server doesn't send `(XXXX bytes)' reply */ - ZFST_TRSZ = 0x40, /* tried getting 'size' from reply */ - ZFST_CLOS = 0x80 /* connection closed */ + ZFST_LOGI = 0x0008, /* user logged in */ + ZFST_SYST = 0x0010, /* done system type check */ + ZFST_NOPS = 0x0020, /* server doesn't understand PASV */ + ZFST_NOSZ = 0x0040, /* server doesn't send `(XXXX bytes)' reply */ + ZFST_TRSZ = 0x0080, /* tried getting 'size' from reply */ + ZFST_CLOS = 0x0100 /* connection closed */ }; #define ZFST_TYPE(x) (x & ZFST_TMSK) /* @@ -461,7 +462,7 @@ zfmovefd(int fd) * set a non-special parameter. * if ZFPM_IFUNSET, don't set if it already exists. * if ZFPM_READONLY, make it readonly, but only when creating it. - * if ZFPM_INTEGER, val pointer is to long (NB not int), don't free. + * if ZFPM_INTEGER, val pointer is to off_t (NB not int), don't free. */ /**/ static void @@ -488,7 +489,7 @@ zfsetparam(char *name, void *val, int flags) return; } if (type == PM_INTEGER) - pm->sets.ifn(pm, *(long *)val); + pm->sets.ifn(pm, *(off_t *)val); else pm->sets.cfn(pm, (char *)val); } @@ -1009,7 +1010,7 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize) if (isdigit(STOUC(*ptr))) { zfstatus &= ~ZFST_NOSZ; if (getsize) { - long sz = zstrtol(ptr, NULL, 10); + off_t sz = zstrtol(ptr, NULL, 10); zfsetparam("ZFTP_SIZE", &sz, ZFPM_READONLY|ZFPM_INTEGER); } } @@ -1090,9 +1091,9 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize) /**/ static int -zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd) +zfstats(char *fnam, int remote, off_t *retsize, char **retmdtm, int fd) { - long sz = -1; + off_t sz = -1; char *mt = NULL; int ret; @@ -1151,7 +1152,7 @@ zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd) if ((fd == -1 ? stat(fnam, &statbuf) : fstat(fd, &statbuf)) < 0) return 1; - /* make sure it's long, since this has to be a pointer */ + /* make sure it's off_t, since this has to be a pointer */ sz = statbuf.st_size; if (retmdtm) { @@ -1179,9 +1180,9 @@ zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd) /**/ static void -zfstarttrans(char *nam, int recv, long sz) +zfstarttrans(char *nam, int recv, off_t sz) { - long cnt = 0; + off_t cnt = 0; /* * sz = -1 signifies error getting size. don't set ZFTP_SIZE if sz is * zero, either: it probably came from an fstat() on a pipe, so it @@ -1210,7 +1211,7 @@ zfendtrans() /**/ static int -zfread(int fd, char *bf, size_t sz, int tmout) +zfread(int fd, char *bf, off_t sz, int tmout) { int ret; @@ -1235,7 +1236,7 @@ zfread(int fd, char *bf, size_t sz, int tmout) /**/ static int -zfwrite(int fd, char *bf, size_t sz, int tmout) +zfwrite(int fd, char *bf, off_t sz, int tmout) { int ret; @@ -1262,11 +1263,11 @@ static int zfread_eof; /**/ static int -zfread_block(int fd, char *bf, size_t sz, int tmout) +zfread_block(int fd, char *bf, off_t sz, int tmout) { int n; struct zfheader hdr; - size_t blksz, cnt; + off_t blksz, cnt; char *bfptr; do { /* we need the header */ @@ -1314,11 +1315,11 @@ zfread_block(int fd, char *bf, size_t sz, int tmout) /**/ static int -zfwrite_block(int fd, char *bf, size_t sz, int tmout) +zfwrite_block(int fd, char *bf, off_t sz, int tmout) { int n; struct zfheader hdr; - size_t cnt; + off_t cnt; char *bfptr; /* we need the header */ do { @@ -1359,7 +1360,7 @@ zfwrite_block(int fd, char *bf, size_t sz, int tmout) /**/ static int -zfsenddata(char *name, int recv, int progress, long startat) +zfsenddata(char *name, int recv, int progress, off_t startat) { #define ZF_BUFSIZE 32768 #define ZF_ASCSIZE (ZF_BUFSIZE/2) @@ -1367,7 +1368,7 @@ zfsenddata(char *name, int recv, int progress, long startat) int n, ret = 0, gotack = 0, fdin, fdout, fromasc = 0, toasc = 0; int rtmout = 0, wtmout = 0; char lsbuf[ZF_BUFSIZE], *ascbuf = NULL, *optr; - long sofar = 0, last_sofar = 0; + off_t sofar = 0, last_sofar = 0; readwrite_t read_ptr = zfread, write_ptr = zfwrite; List l; @@ -1598,7 +1599,7 @@ zftp_open(char *name, char **args, int flags) struct protoent *zprotop; struct servent *zservp; struct hostent *zhostp = NULL; - char **addrp, tbuf[2] = "X", *fname; + char **addrp, *fname; int err, len, tmout; if (!*args) { @@ -1802,32 +1803,11 @@ zftp_open(char *name, char **args, int flags) #endif unlink(fname); - /* now find out what system we're connected to */ - if (!(zfprefs & ZFPF_DUMB) && zfsendcmd("SYST\r\n") == 2) { - char *ptr = lastmsg, *eptr, *systype; - for (eptr = ptr; *eptr; eptr++) - ; - systype = ztrduppfx(ptr, eptr-ptr); - if (!strncmp(systype, "UNIX Type: L8", 13)) { - /* - * Use binary for transfers. This simple test saves much - * hassle for all concerned, particularly me. - */ - zfstatus |= ZFST_IMAG; - zfis_unix = 1; - } - /* - * we could set zfis_unix based just on the UNIX part, - * but I don't really know the consequences of that. - */ - zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY); - } else if (zcfd == -1) { + if (zcfd == -1) { /* final paranoid check */ return 1; } - tbuf[0] = (ZFST_TYPE(zfstatus) == ZFST_ASCI) ? 'A' : 'I'; - zfsetparam("ZFTP_TYPE", ztrdup(tbuf), ZFPM_READONLY); zfsetparam("ZFTP_MODE", ztrdup("S"), ZFPM_READONLY); /* if remaining arguments, use them to log in. */ if (zcfd > -1 && *++args) @@ -1964,7 +1944,7 @@ static int zftp_login(char *name, char **args, int flags) { char *ucmd, *passwd = NULL, *acct = NULL; - char *user; + char *user, tbuf[2] = "X"; int stopit; if ((zfstatus & ZFST_LOGI) && zfsendcmd("REIN\r\n") >= 4) @@ -2045,6 +2025,36 @@ zftp_login(char *name, char **args, int flags) zfsetparam("ZFTP_ACCOUNT", ztrdup(acct), ZFPM_READONLY); /* + * Now find out what system we're connected to. Some systems + * won't let us do this until we're logged in; it's fairly safe + * to delay it here for all systems. + */ + if (!(zfprefs & ZFPF_DUMB) && !(zfstatus & ZFST_SYST)) { + if (zfsendcmd("SYST\r\n") == 2) { + char *ptr = lastmsg, *eptr, *systype; + for (eptr = ptr; *eptr; eptr++) + ; + systype = ztrduppfx(ptr, eptr-ptr); + if (!strncmp(systype, "UNIX Type: L8", 13)) { + /* + * Use binary for transfers. This simple test saves much + * hassle for all concerned, particularly me. + */ + zfstatus |= ZFST_IMAG; + zfis_unix = 1; + } + /* + * we could set zfis_unix based just on the UNIX part, + * but I don't really know the consequences of that. + */ + zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY); + } + zfstatus |= ZFST_SYST; + } + tbuf[0] = (ZFST_TYPE(zfstatus) == ZFST_ASCI) ? 'A' : 'I'; + zfsetparam("ZFTP_TYPE", ztrdup(tbuf), ZFPM_READONLY); + + /* * Get the directory. This is possibly an unnecessary overhead, of * course, but when you're being driven by shell functions there's * just no way of telling. @@ -2307,7 +2317,7 @@ zftp_local(char *name, char **args, int flags) { int more = !!args[1], ret = 0, dofd = !*args; while (*args || dofd) { - long sz; + off_t sz; char *mt; int newret = zfstats(*args, !(flags & ZFTP_HERE), &sz, &mt, dofd ? 0 : -1); @@ -2324,7 +2334,12 @@ zftp_local(char *name, char **args, int flags) fputs(*args, stdout); fputc(' ', stdout); } +#ifdef OFF_T_IS_64_BIT + printf("%s %s\n", output64(sz), mt); +#else + DPUTS(sizeof(sz) > 4, "Shell compiled with wrong off_t size"); printf("%ld %s\n", sz, mt); +#endif zsfree(mt); if (dofd) break; @@ -2371,9 +2386,9 @@ zftp_getput(char *name, char **args, int flags) fflush(stdout); /* since we may be using fd 1 */ for (; *args; args++) { char *ln, *rest = NULL; - long startat = 0; + off_t startat = 0; if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) { - long sz; + off_t sz; /* * This calls the SIZE command to get the size for remote * files. Some servers send the size with the reply to @@ -2701,7 +2716,7 @@ boot_zftp(Module m) if ((ret = addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) == 1) { /* if successful, set some default parameters */ - long tmout_def = 60; + off_t tmout_def = 60; zfsetparam("ZFTP_VERBOSE", ztrdup("450"), ZFPM_IFUNSET); zfsetparam("ZFTP_TMOUT", &tmout_def, ZFPM_IFUNSET|ZFPM_INTEGER); zfsetparam("ZFTP_PREFS", ztrdup("PS"), ZFPM_IFUNSET); diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index f32e5f5c0..071a8e64a 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -100,11 +100,11 @@ int incompfunc; /* global variables for shell parameters in new style completion */ /**/ -long compcurrent, - compnmatches, - compmatcher, - compmatchertot, - complistmax; +zlong compcurrent, + compnmatches, + compmatcher, + compmatchertot, + complistmax; /**/ char **compwords, diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index a06d558e3..217678c00 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -2270,7 +2270,7 @@ set_compstate(Param pm, HashTable ht) v.arr = NULL; v.pm = (Param) hn; if (cp->type == PM_INTEGER) - *((long *) cp->var) = getintvalue(&v); + *((zlong *) cp->var) = getintvalue(&v); else if ((str = getstrvalue(&v))) { zsfree(*((char **) cp->var)); *((char **) cp->var) = ztrdup(str); @@ -2289,7 +2289,7 @@ get_unambig(Param pm) } /**/ -static long +static zlong get_unambig_curs(Param pm) { int c; @@ -2342,7 +2342,7 @@ comp_wrapper(List list, FuncWrap w, char *name) return 1; else { char *orest, *opre, *osuf, *oipre, *oisuf, **owords; - long ocur; + zlong ocur; unsigned int unset = 0, m, sm; Param *pp; diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index d9fefe659..5c4feef50 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -101,8 +101,8 @@ makezleparams(int ro) pm->gets.afn = (char **(*) _((Param))) zp->getfn; break; case PM_INTEGER: - pm->sets.ifn = (void (*) _((Param, long))) zp->setfn; - pm->gets.ifn = (long (*) _((Param))) zp->getfn; + pm->sets.ifn = (void (*) _((Param, zlong))) zp->setfn; + pm->gets.ifn = (zlong (*) _((Param))) zp->getfn; pm->ct = 10; break; } @@ -146,7 +146,7 @@ get_buffer(Param pm) /**/ static void -set_cursor(Param pm, long x) +set_cursor(Param pm, zlong x) { if(x < 0) cs = 0; @@ -157,7 +157,7 @@ set_cursor(Param pm, long x) } /**/ -static long +static zlong get_cursor(Param pm) { return cs; @@ -264,20 +264,20 @@ get_keys(Param pm) /**/ static void -set_numeric(Param pm, long x) +set_numeric(Param pm, zlong x) { zmult = x; } /**/ -static long +static zlong get_numeric(Param pm) { return zmult; } /**/ -static long +static zlong get_histno(Param pm) { return histline; diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 2377b70fa..9742ba501 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -881,20 +881,8 @@ moveto(int ln, int cl) } } - if (cl == vcs) - return; - -/* choose cheapest movements for ttys without multiple movement capabilities - - do this now because it's easier (to code) */ - if (cl <= vcs / 2) { - zputc('\r', shout); - vcs = 0; - } - if (vcs < cl) - tc_rightcurs(cl); - else if (vcs > cl) - tc_leftcurs(vcs - cl); - vcs = cl; + if (cl != vcs) + singmoveto(cl); } /**/ @@ -912,16 +900,17 @@ tcmultout(int cap, int multcap, int ct) return 0; } +/* ct: number of characters to move across */ /**/ static void -tc_rightcurs(int cl) +tc_rightcurs(int ct) { - int ct, /* number of characters to move across */ + int cl, /* ``desired'' absolute horizontal position */ i = vcs, /* cursor position after initial movements */ j; char *t; - ct = cl - vcs; + cl = ct + vcs; /* do a multright if we can - it's the most reliable */ if (tccan(TCMULTRIGHT)) { @@ -929,6 +918,13 @@ tc_rightcurs(int cl) return; } +/* do an absolute horizontal position if we can */ + if (tccan(TCHORIZPOS)) { + tcoutarg(TCHORIZPOS, cl); + return; + } + +/* XXX: should really check "it" in termcap and use / and % */ /* try tabs if tabs are non destructive and multright is not possible */ if (!oxtabs && tccan(TCNEXTTAB) && ((vcs | 7) < cl)) { i = (vcs | 7) + 1; @@ -1137,21 +1133,19 @@ singmoveto(int pos) { if (pos == vcs) return; - if (pos <= vcs / 2) { + +/* choose cheapest movements for ttys without multiple movement capabilities - + do this now because it's easier (to code) */ + + if ((!tccan(TCMULTLEFT) || pos == 0) && (pos <= vcs / 2)) { zputc('\r', shout); vcs = 0; } - if (pos < vcs) { + + if (pos < vcs) tc_leftcurs(vcs - pos); - vcs = pos; - } - if (pos > vcs) { - if (tcmultout(TCRIGHT, TCMULTRIGHT, pos - vcs)) - vcs = pos; - else - while (pos > vcs) { - zputc(nbuf[0][vcs], shout); - vcs++; - } - } + else if (pos > vcs) + tc_rightcurs(pos - vcs); + + vcs = pos; } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index bc6cff8b6..aadbaec6c 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -3723,7 +3723,8 @@ addmatches(Cadata dat, char **argv) } } if (!(dat->aflags & CAF_MATCH)) { - ms = dupstring(s); + ms = ((dat->aflags & CAF_QUOTE) ? dupstring(s) : + quotename(s, NULL)); lc = bld_parts(ms, sl, -1, NULL); isexact = 0; } else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc, @@ -3734,7 +3735,7 @@ addmatches(Cadata dat, char **argv) continue; } if (doadd) { - cm = add_match_data(isalt, ms, lc, dat->ipre, dat->ipre, + cm = add_match_data(isalt, ms, lc, dat->ipre, NULL, dat->isuf, dat->pre, dat->prpre, dat->ppre, dat->psuf, dat->suf, bpl, bsl, dat->flags, isexact); diff --git a/Src/builtin.c b/Src/builtin.c index 8436cde33..a90d59cae 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1521,9 +1521,14 @@ typeset_single(char *cname, char *pname, Param pm, int func, zerrnam(cname, "%s: restricted", pname, 0); return pm; } - if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) && - !(pm->flags & PM_READONLY & ~off)) - uniqarray((*pm->gets.afn) (pm)); + if ((on & PM_UNIQUE) && !(pm->flags & PM_READONLY & ~off)) { + Param apm; + if (PM_TYPE(pm->flags) == PM_ARRAY) + uniqarray((*pm->gets.afn) (pm)); + else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename && + (apm = (Param) paramtab->getnode(paramtab, pm->ename))) + uniqarray((*apm->gets.afn) (apm)); + } pm->flags = (pm->flags | on) & ~off; /* This auxlen/pm->ct stuff is a nasty hack. */ if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) && @@ -3647,7 +3652,7 @@ bin_ttyctl(char *name, char **argv, char *ops, int func) int bin_let(char *name, char **argv, char *ops, int func) { - long val = 0; + zlong val = 0; while (*argv) val = matheval(*argv++); diff --git a/Src/compat.c b/Src/compat.c index 53ab6b7a3..7af984799 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -304,3 +304,21 @@ zchdir(char *dir) return currdir == -2 ? -1 : -2; #endif } + +/* + * How to print out a 64 bit integer. This isn't needed (1) if longs + * are 64 bit, since ordinary %ld will work (2) if we couldn't find a + * 64 bit type anyway. + */ +/**/ +#ifdef ZSH_64_BIT_TYPE +/**/ +char * +output64(zlong val) +{ + static char llbuf[DIGBUFSIZE]; + convbase(llbuf, val, 0); + return llbuf; +} +/**/ +#endif /* ZSH_64_BIT_TYPE */ diff --git a/Src/cond.c b/Src/cond.c index 00beb8e65..a8387a454 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -311,7 +311,7 @@ cond_str(char **args, int num) } /**/ -long +zlong cond_val(char **args, int num) { char *s = args[num]; diff --git a/Src/exec.c b/Src/exec.c index da2bf9fe2..7d15facfd 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -213,6 +213,78 @@ zfork(void) return pid; } +/* + * Allen Edeln gebiet ich Andacht, + * Hohen und Niedern von Heimdalls Geschlecht; + * Ich will list_pipe's Wirken kuenden + * Die aeltesten Sagen, der ich mich entsinne... + * + * In most shells, if you do something like: + * + * cat foo | while read a; do grep $a bar; done + * + * the shell forks and executes the loop in the sub-shell thus created. + * In zsh this traditionally executes the loop in the current shell, which + * is nice to have if the loop does something to change the shell, like + * setting parameters or calling builtins. + * Putting the loop in a sub-shell makes live easy, because the shell only + * has to put it into the job-structure and then treats it as a normal + * process. Suspending and interrupting is no problem then. + * Some years ago, zsh either couldn't suspend such things at all, or + * it got really messed up when users tried to do it. As a solution, we + * implemented the list_pipe-stuff, which has since then become a reason + * for many nightmares. + * Pipelines like the one above are executed by the functions in this file + * which call each other (and sometimes recursively). The one above, for + * example would lead to a function call stack roughly like: + * + * execlist->execpline->execcmd->execwhile->execlist->execpline + * + * (when waiting for the grep, ignoring execpline2 for now). At this time, + * zsh has build two job-table entries for it: one for the cat and one for + * the grep. If the user hits ^Z at this point (and jobbing is used), the + * shell is notified that the grep was suspended. The list_pipe flag is + * used to tell the execpline where it was waiting that it was in a pipeline + * with a shell construct at the end (which may also be a shell function or + * several other things). When zsh sees the suspended grep, it forks to let + * the sub-shell execute the rest of the while loop. The parent shell walks + * up in the function call stack to the first execpline. There it has to find + * out that it has just forked and then has to add information about the sub- + * shell (its pid and the text for it) in the job entry of the cat. The pid + * is passed down in the list_pipe_pid variable. + * But there is a problem: the suspended grep is a child of the parent shell + * and can't be adopted by the sub-shell. So the parent shell also has to + * keep the information about this process (more precisely: this pipeline) + * by keeping the job table entry it created for it. The fact that there + * are two jobs which have to be treated together is remembered by setting + * the STAT_SUPERJOB flag in the entry for the cat-job (which now also + * contains a process-entry for the whole loop -- the sub-shell) and by + * setting STAT_SUBJOB in the job of the grep-job. With that we can keep + * sub-jobs from being displayed and we can handle an fg/bg on the super- + * job correctly. When the super-job is continued, the shell also wakes up + * the sub-job. But then, the grep will exit sometime. Now the parent shell + * has to remember not to try to wake it up again (in case of another ^Z). + * It also has to wake up the sub-shell (which suspended itself immediately + * after creation), so that the rest of the loop is executed by it. + * But there is more: when the sub-shell is created, the cat may already + * have exited, so we can't put the sub-shell in the process group of it. + * In this case, we put the sub-shell in the process group of the parent + * shell and in any case, the sub-shell has to put all commands executed + * by it into its own process group, because only this way the parent + * shell can control them since it only knows the process group of the sub- + * shell. Of course, this information is also important when putting a job + * in the foreground, where we have to attach its process group to the + * controlling tty. + * All this is made more difficult because we have to handle return values + * correctly. If the grep is signaled, its exit status has to be propagated + * back to the parent shell which needs it to set the exit status of the + * super-job. And of course, when the grep is signaled (including ^C), the + * loop has to be stopped, etc. + * The code for all this is distributed over three files (exec.c, jobs.c, + * and signals.c) and none of them is a simple one. So, all in all, there + * may still be bugs, but considering the complexity (with race conditions, + * signal handling, and all that), this should probably be expected. + */ /**/ int list_pipe = 0, simple_pline = 0; @@ -625,6 +697,13 @@ execlist(List list, int dont_change_job, int exiting) static int donetrap; int ret, cj; int old_pline_level, old_list_pipe; + /* + * ERREXIT only forces the shell to exit if the last command in a && + * or || fails. This is the case even if an earlier command is a + * shell function or other current shell structure, so we have to set + * noerrexit here if the sublist is not of type END. + */ + int oldnoerrexit = noerrexit; cj = thisjob; old_pline_level = pline_level; @@ -644,6 +723,8 @@ execlist(List list, int dont_change_job, int exiting) /* Loop through code followed by &&, ||, or end of sublist. */ while (slist) { + if (!oldnoerrexit) + noerrexit = (slist->type != END); switch (slist->type) { case END: /* End of sublist; just execute, ignoring status. */ @@ -687,6 +768,8 @@ execlist(List list, int dont_change_job, int exiting) } sublist_done: + noerrexit = oldnoerrexit; + if (sigtrapped[SIGDEBUG]) dotrap(SIGDEBUG); @@ -761,13 +844,17 @@ execpline(Sublist l, int how, int last1) coprocout = opipe[1]; fdtable[coprocin] = fdtable[coprocout] = 0; } + /* This used to set list_pipe_pid=0 unconditionally, but in things + * like `ls|if true; then sleep 20; cat; fi' where the sleep was + * stopped, the top-level execpline() didn't get the pid for the + * sub-shell because it was overwritten. */ if (!pline_level++) { list_pipe_job = newjob; + list_pipe_pid = 0; nowait = 0; - } - list_pipe_pid = lastwj = 0; - if (pline_level == 1) simple_pline = (l->left->type == END); + } + lastwj = 0; execpline2(l->left, how, opipe[0], ipipe[1], last1); pline_level--; if (how & Z_ASYNC) { @@ -800,6 +887,7 @@ execpline(Sublist l, int how, int last1) struct process *pn, *qn; curjob = newjob; + DPUTS(!list_pipe_pid, "invalid list_pipe_pid"); addproc(list_pipe_pid, list_pipe_text); for (pn = jobtab[jn->other].procs; pn; pn = pn->next) @@ -1588,7 +1676,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1) closem(2); #endif if (how & Z_ASYNC) { - lastpid = (long) pid; + lastpid = (zlong) pid; } else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) { /* search for STTY=... */ while (nonempty(cmd->vars)) @@ -2548,7 +2636,7 @@ static int execarith(Cmd cmd) { char *e; - long val = 0; + zlong val = 0; if (isset(XTRACE)) fprintf(stderr, "%s((", prompt4 ? prompt4 : ""); diff --git a/Src/glob.c b/Src/glob.c index 79a86bbef..596a05ebf 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -30,18 +30,24 @@ #include "zsh.mdh" #include "glob.pro" +#if defined(OFF_T_IS_64_BIT) && defined(__GNUC__) +# define ALIGN64 __attribute__((aligned(8))) +#else +# define ALIGN64 +#endif + /* flag for CSHNULLGLOB */ typedef struct gmatch *Gmatch; struct gmatch { char *name; - long size; + off_t size ALIGN64; long atime; long mtime; long ctime; long links; - long _size; + off_t _size ALIGN64; long _atime; long _mtime; long _ctime; @@ -97,13 +103,13 @@ typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figu #define TT_KILOBYTES 2 #define TT_MEGABYTES 3 -typedef int (*TestMatchFunc) _((struct stat *, long)); +typedef int (*TestMatchFunc) _((struct stat *, off_t)); struct qual { struct qual *next; /* Next qualifier, must match */ struct qual *or; /* Alternative set of qualifiers to match */ TestMatchFunc func; /* Function to call to test match */ - long data; /* Argument passed to function */ + off_t data ALIGN64; /* Argument passed to function */ int sense; /* Whether asserting or negating */ int amc; /* Flag for which time to test (a, m, c) */ int range; /* Whether to test <, > or = (as per signum) */ @@ -244,7 +250,7 @@ insert(char *s, int checked) if (gf_follow) { if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0)) memcpy(&buf2, &buf, sizeof(buf)); - statted = 2; + statted |= 2; mode = buf2.st_mode; } if (gf_listtypes || S_ISDIR(mode)) { @@ -268,11 +274,11 @@ insert(char *s, int checked) range = qn->range; amc = qn->amc; units = qn->units; - if ((qn->sense & 2) && statted != 2) { + if ((qn->sense & 2) && !(statted & 2)) { /* If (sense & 2), we're following links */ if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0)) memcpy(&buf2, &buf, sizeof(buf)); - statted = 2; + statted |= 2; } bp = (qn->sense & 2) ? &buf2 : &buf; /* Reject the file if the function returned zero * @@ -302,24 +308,29 @@ insert(char *s, int checked) statfullpath(s, &buf, 1); statted = 1; } - if (statted != 2 && (gf_sorts & GS_LINKED)) { + if (!(statted & 2) && (gf_sorts & GS_LINKED)) { if (statted) { if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0)) memcpy(&buf2, &buf, sizeof(buf)); } else if (statfullpath(s, &buf2, 0)) statfullpath(s, &buf2, 1); + statted |= 2; } matchptr->name = news; - matchptr->size = buf.st_size; - matchptr->atime = buf.st_atime; - matchptr->mtime = buf.st_mtime; - matchptr->ctime = buf.st_ctime; - matchptr->links = buf.st_nlink; - matchptr->_size = buf2.st_size; - matchptr->_atime = buf2.st_atime; - matchptr->_mtime = buf2.st_mtime; - matchptr->_ctime = buf2.st_ctime; - matchptr->_links = buf2.st_nlink; + if (statted & 1) { + matchptr->size = buf.st_size; + matchptr->atime = buf.st_atime; + matchptr->mtime = buf.st_mtime; + matchptr->ctime = buf.st_ctime; + matchptr->links = buf.st_nlink; + } + if (statted & 2) { + matchptr->_size = buf2.st_size; + matchptr->_atime = buf2.st_atime; + matchptr->_mtime = buf2.st_mtime; + matchptr->_ctime = buf2.st_ctime; + matchptr->_links = buf2.st_nlink; + } matchptr++; if (++matchct == matchsz) { @@ -1102,10 +1113,10 @@ parsepat(char *str) /* get number after qualifier */ /**/ -static long +static off_t qgetnum(char **s) { - long v = 0; + off_t v = 0; if (!idigit(**s)) { zerr("number expected", NULL, 0); @@ -1119,10 +1130,10 @@ qgetnum(char **s) /* get mode spec after qualifier */ /**/ -static long +static zlong qgetmodespec(char **s) { - long yes = 0, no = 0, val, mask, t; + zlong yes = 0, no = 0, val, mask, t; char *p = *s, c, how, end; if ((c = *p) == '=' || c == Equals || c == '+' || c == '-' || @@ -1163,7 +1174,7 @@ qgetmodespec(char **s) case 't': val |= 01000; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - t = ((long) c - '0'); + t = ((zlong) c - '0'); val |= t | (t << 3) | (t << 6); break; default: @@ -1186,7 +1197,7 @@ qgetmodespec(char **s) val <<= 3; } else { t <<= 3; - val = (val << 3) | ((long) c - '0'); + val = (val << 3) | ((zlong) c - '0'); } p++; } @@ -1212,7 +1223,7 @@ static int gmatchcmp(Gmatch a, Gmatch b) { int i, *s; - long r = 0L; + off_t r = 0L; for (i = gf_nsorts, s = gf_sortlist; i; i--, s++) { switch (*s & ~GS_DESC) { @@ -1306,13 +1317,13 @@ glob(LinkList list, LinkNode np) /* Real qualifiers found. */ int sense = 0; /* bit 0 for match (0)/don't match (1) */ /* bit 1 for follow links (2), don't (0) */ - long data = 0; /* Any numerical argument required */ - int (*func) _((Statptr, long)); + off_t data = 0; /* Any numerical argument required */ + int (*func) _((Statptr, off_t)); str[sl-1] = 0; *s++ = 0; while (*s && !colonmod) { - func = (int (*) _((Statptr, long)))0; + func = (int (*) _((Statptr, off_t)))0; if (idigit(*s)) { /* Store numeric argument for qualifier */ func = qualflags; @@ -3142,7 +3153,14 @@ matchonce(Comp c) } if (*pat == Inang) { /* Numeric globbing. */ +#ifdef ZSH_64_BIT_TYPE +/* zstrtol returns zlong anyway */ +# define RANGE_CAST() + zlong t1, t2, t3; +#else +# define RANGE_CAST() (unsigned long) unsigned long t1, t2, t3; +#endif char *ptr, *saves = pptr, *savep = pat; if (!idigit(*pptr)) @@ -3161,18 +3179,18 @@ matchonce(Comp c) * t1 = number supplied: must be positive, so use * unsigned arithmetic. */ - t1 = (unsigned long)zstrtol(pptr, &ptr, 10); + t1 = RANGE_CAST() zstrtol(pptr, &ptr, 10); pptr = ptr; /* t2 = lower limit */ if (idigit(*pat)) - t2 = (unsigned long)zstrtol(pat, &ptr, 10); + t2 = RANGE_CAST() zstrtol(pat, &ptr, 10); else t2 = 0, ptr = pat; if (*ptr != '-' || (not3 = (ptr[1] == Outang))) /* exact match or no upper limit */ t3 = t2, pat = ptr + not3; else /* t3 = upper limit */ - t3 = (unsigned long)zstrtol(ptr + 1, &pat, 10); + t3 = RANGE_CAST() zstrtol(ptr + 1, &pat, 10); DPUTS(*pat != Outang, "BUG: wrong internal range pattern"); pat++; /* @@ -3191,6 +3209,7 @@ matchonce(Comp c) } } continue; +#undef RANGE_CAST } /* itok(Meta) is zero */ DPUTS(itok(*pat), "BUG: matching tokenized character"); @@ -3430,7 +3449,7 @@ remnulargs(char *s) /**/ static int -qualdev(struct stat *buf, long dv) +qualdev(struct stat *buf, off_t dv) { return buf->st_dev == dv; } @@ -3439,7 +3458,7 @@ qualdev(struct stat *buf, long dv) /**/ static int -qualnlink(struct stat *buf, long ct) +qualnlink(struct stat *buf, off_t ct) { return (range < 0 ? buf->st_nlink < ct : range > 0 ? buf->st_nlink > ct : @@ -3450,7 +3469,7 @@ qualnlink(struct stat *buf, long ct) /**/ static int -qualuid(struct stat *buf, long uid) +qualuid(struct stat *buf, off_t uid) { return buf->st_uid == uid; } @@ -3459,7 +3478,7 @@ qualuid(struct stat *buf, long uid) /**/ static int -qualgid(struct stat *buf, long gid) +qualgid(struct stat *buf, off_t gid) { return buf->st_gid == gid; } @@ -3468,7 +3487,7 @@ qualgid(struct stat *buf, long gid) /**/ static int -qualisdev(struct stat *buf, long junk) +qualisdev(struct stat *buf, off_t junk) { return S_ISBLK(buf->st_mode) || S_ISCHR(buf->st_mode); } @@ -3477,7 +3496,7 @@ qualisdev(struct stat *buf, long junk) /**/ static int -qualisblk(struct stat *buf, long junk) +qualisblk(struct stat *buf, off_t junk) { return S_ISBLK(buf->st_mode); } @@ -3486,7 +3505,7 @@ qualisblk(struct stat *buf, long junk) /**/ static int -qualischr(struct stat *buf, long junk) +qualischr(struct stat *buf, off_t junk) { return S_ISCHR(buf->st_mode); } @@ -3495,7 +3514,7 @@ qualischr(struct stat *buf, long junk) /**/ static int -qualisdir(struct stat *buf, long junk) +qualisdir(struct stat *buf, off_t junk) { return S_ISDIR(buf->st_mode); } @@ -3504,7 +3523,7 @@ qualisdir(struct stat *buf, long junk) /**/ static int -qualisfifo(struct stat *buf, long junk) +qualisfifo(struct stat *buf, off_t junk) { return S_ISFIFO(buf->st_mode); } @@ -3513,7 +3532,7 @@ qualisfifo(struct stat *buf, long junk) /**/ static int -qualislnk(struct stat *buf, long junk) +qualislnk(struct stat *buf, off_t junk) { return S_ISLNK(buf->st_mode); } @@ -3522,7 +3541,7 @@ qualislnk(struct stat *buf, long junk) /**/ static int -qualisreg(struct stat *buf, long junk) +qualisreg(struct stat *buf, off_t junk) { return S_ISREG(buf->st_mode); } @@ -3531,7 +3550,7 @@ qualisreg(struct stat *buf, long junk) /**/ static int -qualissock(struct stat *buf, long junk) +qualissock(struct stat *buf, off_t junk) { return S_ISSOCK(buf->st_mode); } @@ -3540,7 +3559,7 @@ qualissock(struct stat *buf, long junk) /**/ static int -qualflags(struct stat *buf, long mod) +qualflags(struct stat *buf, off_t mod) { return mode_to_octal(buf->st_mode) & mod; } @@ -3549,7 +3568,7 @@ qualflags(struct stat *buf, long mod) /**/ static int -qualmodeflags(struct stat *buf, long mod) +qualmodeflags(struct stat *buf, off_t mod) { long v = mode_to_octal(buf->st_mode), y = mod & 07777, n = mod >> 12; @@ -3560,7 +3579,7 @@ qualmodeflags(struct stat *buf, long mod) /**/ static int -qualiscom(struct stat *buf, long mod) +qualiscom(struct stat *buf, off_t mod) { return S_ISREG(buf->st_mode) && (buf->st_mode & S_IXUGO); } @@ -3569,9 +3588,15 @@ qualiscom(struct stat *buf, long mod) /**/ static int -qualsize(struct stat *buf, long size) +qualsize(struct stat *buf, off_t size) { - unsigned long scaled = buf->st_size; +#if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT) +# define QS_CAST_SIZE() + off_t scaled = buf->st_size; +#else +# define QS_CAST_SIZE() (unsigned long) + unsigned long scaled = (unsigned long)buf->st_size; +#endif switch (units) { case TT_POSIX_BLOCKS: @@ -3588,16 +3613,17 @@ qualsize(struct stat *buf, long size) break; } - return (range < 0 ? scaled < (unsigned long) size : - range > 0 ? scaled > (unsigned long) size : - scaled == (unsigned long) size); + return (range < 0 ? scaled < QS_CAST_SIZE() size : + range > 0 ? scaled > QS_CAST_SIZE() size : + scaled == QS_CAST_SIZE() size); +#undef QS_CAST_SIZE } /* time in required range? */ /**/ static int -qualtime(struct stat *buf, long days) +qualtime(struct stat *buf, off_t days) { time_t now, diff; diff --git a/Src/hashtable.c b/Src/hashtable.c index 0a640349b..b534d8ac1 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -112,6 +112,7 @@ newhashtable(int size, char const *name, PrintTableStats printinfo) ht->hsize = size; ht->ct = 0; ht->scan = NULL; + ht->scantab = NULL; return ht; } @@ -361,6 +362,10 @@ scanhashtable(HashTable ht, int sorted, int flags1, int flags2, ScanFunc scanfun { struct scanstatus st; + if (ht->scantab) { + ht->scantab(ht, scanfunc, scanflags); + return; + } if (sorted) { int i, ct = ht->ct; VARARR(HashNode, hnsorttab, ct); diff --git a/Src/hist.c b/Src/hist.c index 55209a1c0..6b2c2a653 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -972,7 +972,7 @@ hend(void) zfree(chwords, chwordlen*sizeof(short)); chline = NULL; histactive = 0; - if (isset(SHAREHISTORY) || isset(INCREMENTALAPPENDHISTORY)) + if (isset(SHAREHISTORY) || isset(INCAPPENDHISTORY)) savehistfile(hf, 1, HFILE_USE_OPTIONS | HFILE_FAST); unlockhistfile(hf); /* It's OK to call this even if we aren't locked */ return !(flag & HISTFLAG_NOEXEC || errflag); @@ -1778,7 +1778,7 @@ savehistfile(char *fn, int err, int writeflags) he = hist_ring->down; } if (writeflags & HFILE_USE_OPTIONS) { - if (isset(APPENDHISTORY) || isset(INCREMENTALAPPENDHISTORY) + if (isset(APPENDHISTORY) || isset(INCAPPENDHISTORY) || isset(SHAREHISTORY)) writeflags |= HFILE_APPEND | HFILE_SKIPOLD; else @@ -1883,7 +1883,7 @@ lockhistfile(char *fn, int keep_trying) char *tmpfile, *lockfile; tmpfile = zalloc(len + 10 + 1); - sprintf(tmpfile, "%s.%ld", fn, mypid); + sprintf(tmpfile, "%s.%ld", fn, (long)mypid); if ((fd = open(tmpfile, O_RDWR|O_CREAT|O_EXCL, 0644)) >= 0) { write(fd, "0\n", 2); close(fd); diff --git a/Src/init.c b/Src/init.c index e92a5000f..86d5aa505 100644 --- a/Src/init.c +++ b/Src/init.c @@ -414,7 +414,7 @@ init_shout(void) static char *tccapnams[TC_COUNT] = { "cl", "le", "LE", "nd", "RI", "up", "UP", "do", "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta", - "md", "so", "us", "me", "se", "ue" + "md", "so", "us", "me", "se", "ue", "ch" }; /* Initialise termcap */ @@ -583,8 +583,8 @@ setupvals(void) zoptarg = ztrdup(""); zoptind = 1; - ppid = (long) getppid(); - mypid = (long) getpid(); + ppid = (zlong) getppid(); + mypid = (zlong) getpid(); term = ztrdup(""); /* The following variable assignments cause zsh to behave more * diff --git a/Src/input.c b/Src/input.c index 6e62ce2c7..b4a6fe22d 100644 --- a/Src/input.c +++ b/Src/input.c @@ -406,7 +406,7 @@ stuff(char *fn) { FILE *in; char *buf; - int len; + off_t len; if (!(in = fopen(unmeta(fn), "r"))) { zerr("can't open %s", fn, 0); diff --git a/Src/jobs.c b/Src/jobs.c index 6ddef0f70..7b0eca6b6 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -175,8 +175,23 @@ update_job(Job jn) jn->ty = (struct ttyinfo *) zalloc(sizeof(struct ttyinfo)); gettyinfo(jn->ty); } - if (jn->stat & STAT_STOPPED) + if (jn->stat & STAT_STOPPED) { + if (jn->stat & STAT_SUBJOB) { + /* If we have `cat foo|while read a; grep $a bar;done' + * and have hit ^Z, the sub-job is stopped, but the + * super-job may still be running, waiting to be stopped + * or to exit. So we have to send it a SIGSTOP. */ + int i; + + for (i = 1; i < MAXJOB; i++) + if ((jobtab[i].stat & STAT_SUPERJOB) && + jobtab[i].other == job) { + killpg(jobtab[i].gleader, SIGSTOP); + break; + } + } return; + } } else { /* job is done, so remember return value */ lastval2 = val; /* If last process was run in the current shell, keep old status @@ -202,14 +217,27 @@ update_job(Job jn) if (mypgrp != pgrp && inforeground && (jn->gleader == pgrp || (pgrp > 1 && kill(-pgrp, 0) == -1))) { if (list_pipe) { - /* - * Oh, dear, we're right in the middle of some confusion - * of shell jobs on the righthand side of a pipeline, so - * it's death to call attachtty() just yet. Mark the - * fact in the job, so that the attachtty() will be called - * when the job is finally deleted. - */ - jn->stat |= STAT_ATTACH; + if (pgrp > 1 && kill(-pgrp, 0) == -1) { + attachtty(mypgrp); + /* check window size and adjust if necessary */ + adjustwinsize(0); + } else { + /* + * Oh, dear, we're right in the middle of some confusion + * of shell jobs on the righthand side of a pipeline, so + * it's death to call attachtty() just yet. Mark the + * fact in the job, so that the attachtty() will be called + * when the job is finally deleted. + */ + jn->stat |= STAT_ATTACH; + } + /* If we have `foo|while true; (( x++ )); done', and hit + * ^C, we have to stop the loop, too. */ + if ((val & 0200) && inforeground == 1) { + breaks = loops; + errflag = 1; + inerrflush(); + } } else { attachtty(mypgrp); /* check window size and adjust if necessary */ @@ -765,8 +793,17 @@ waitjob(int job, int sig) } if (!p) { jn->stat &= ~STAT_SUPERJOB; + if (WIFEXITED(jn->procs->status)) + jn->gleader = mypgrp; + /* This deleted the job too early if the parent + shell waited for a command in a list that will + be executed by the sub-shell (e.g.: if we have + `ls|if true;then sleep 20;cat;fi' and ^Z the + sleep, the rest will be executed by a sub-shell, + but the parent shell gets notified for the + sleep. + deletejob(sj); */ kill(sj->other, SIGCONT); - deletejob(sj); } curjob = jn - jobtab; } diff --git a/Src/math.c b/Src/math.c index 7a0a1f9bd..efbf22e44 100644 --- a/Src/math.c +++ b/Src/math.c @@ -42,7 +42,7 @@ int lastbase; static char *ptr; -static long yyval; +static zlong yyval; static LV yylval; static int mlevel = 0; @@ -409,14 +409,14 @@ static int sp = -1; /* stack pointer */ struct mathvalue { LV lval; - long val; + zlong val; }; static struct mathvalue *stack; /**/ static void -push(long val, LV lval) +push(zlong val, LV lval) { if (sp == STACKSZ - 1) zerr("stack overflow", NULL, 0); @@ -428,7 +428,7 @@ push(long val, LV lval) /**/ -static long +static zlong getcvar(LV s) { char *t; @@ -440,8 +440,8 @@ getcvar(LV s) /**/ -static long -setvar(LV s, long v) +static zlong +setvar(LV s, zlong v) { if (s == -1 || s >= lvc) { zerr("lvalue required", NULL, 0); @@ -456,7 +456,7 @@ setvar(LV s, long v) /**/ static int -notzero(long a) +notzero(zlong a) { if (a == 0) { zerr("division by zero", NULL, 0); @@ -496,7 +496,7 @@ notzero(long a) void op(int what) { - long a, b, c; + zlong a, b, c; LV lv; if (sp < 0) { @@ -569,39 +569,39 @@ op(int what) break; case LES: pop2(); - pushv((long)(a < b)); + pushv((zlong)(a < b)); break; case LEQ: pop2(); - pushv((long)(a <= b)); + pushv((zlong)(a <= b)); break; case GRE: pop2(); - pushv((long)(a > b)); + pushv((zlong)(a > b)); break; case GEQ: pop2(); - pushv((long)(a >= b)); + pushv((zlong)(a >= b)); break; case DEQ: pop2(); - pushv((long)(a == b)); + pushv((zlong)(a == b)); break; case NEQ: pop2(); - pushv((long)(a != b)); + pushv((zlong)(a != b)); break; case DAND: pop2(); - pushv((long)(a && b)); + pushv((zlong)(a && b)); break; case DOR: pop2(); - pushv((long)(a || b)); + pushv((zlong)(a || b)); break; case DXOR: pop2(); - pushv((long)((a && !b) || (!a && b))); + pushv((zlong)((a && !b) || (!a && b))); break; case QUEST: pop3(); @@ -658,15 +658,15 @@ op(int what) break; case DANDEQ: pop2lv(); - set((long)(a && b)); + set((zlong)(a && b)); break; case DOREQ: pop2lv(); - set((long)(a || b)); + set((zlong)(a || b)); break; case DXOREQ: pop2lv(); - set((long)((a && !b) || (!a && b))); + set((zlong)((a && !b) || (!a && b))); break; case COMMA: pop2(); @@ -725,18 +725,18 @@ bop(int tk) /**/ -static long +static zlong mathevall(char *s, int prek, char **ep) { int t0; int xlastbase, xnoeval, xunary, xlvc; char *xptr; - long xyyval; + zlong xyyval; LV xyylval; char **xlvals = 0; int xsp; struct mathvalue *xstack = 0; - long ret; + zlong ret; xlastbase = xnoeval = xunary = xlvc = xyyval = xyylval = xsp = 0; xptr = NULL; @@ -789,11 +789,11 @@ mathevall(char *s, int prek, char **ep) /**/ -long +zlong matheval(char *s) { char *junk; - long x; + zlong x; int xmtok = mtok; if (!*s) @@ -807,10 +807,10 @@ matheval(char *s) /**/ -long +zlong mathevalarg(char *s, char **ss) { - long x; + zlong x; int xmtok = mtok; x = mathevall(s, ARGPREC, ss); diff --git a/Src/mem.c b/Src/mem.c index ee0f5635f..97ff7fdc2 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -96,7 +96,7 @@ static int h_m[1025], h_push, h_pop, h_free; #endif -#define H_ISIZE sizeof(long) +#define H_ISIZE sizeof(zlong) #define HEAPSIZE (8192 - H_ISIZE) #define HEAP_ARENA_SIZE (HEAPSIZE - sizeof(struct heap)) #define HEAPFREE (16384 - H_ISIZE) @@ -500,8 +500,9 @@ ztrdup(const char *s) /* Below is a simple segment oriented memory allocator for systems on which it is better than the system's one. Memory is given in blocks - aligned to an integer multiple of sizeof(long) (4 bytes on most machines, - but 8 bytes on e.g. a dec alpha). Each block is preceded by a header + aligned to an integer multiple of sizeof(zlong) (4 bytes on most machines, + but 8 bytes on e.g. a dec alpha; it will be 8 bytes if we are using + long long's or equivalent). Each block is preceded by a header which contains the length of the data part (in bytes). In allocated blocks only this field of the structure m_hdr is senseful. In free blocks the second field (next) is a pointer to the next free segment @@ -561,22 +562,26 @@ ztrdup(const char *s) struct m_shdr { struct m_shdr *next; /* next one on free list */ +#ifdef ZSH_64_BIT_TYPE + /* dummy to make this 64-bit aligned */ + struct m_shdr *dummy; +#endif }; struct m_hdr { - long len; /* length of memory block */ + zlong len; /* length of memory block */ struct m_hdr *next; /* if free: next on free list if block of small blocks: next one with small blocks of same size*/ struct m_shdr *free; /* if block of small blocks: free list */ - long used; /* if block of small blocks: number of used + zlong used; /* if block of small blocks: number of used blocks */ }; /* alignment for memory blocks */ -#define M_ALIGN (sizeof(long)) +#define M_ALIGN (sizeof(zlong)) /* length of memory header, length of first field of memory header and minimal size of a block left free (if we allocate memory and take a @@ -585,7 +590,7 @@ struct m_hdr { the free list) */ #define M_HSIZE (sizeof(struct m_hdr)) -#define M_ISIZE (sizeof(long)) +#define M_ISIZE (sizeof(zlong)) #define M_MIN (2 * M_ISIZE) /* a pointer to the last free block, a pointer to the free list (the blocks @@ -621,9 +626,9 @@ static char *m_high, *m_low; #define M_SNUM 50 #define M_SLEN(M) ((M)->len / M_SNUM) #define M_SBLEN(S) ((S) * M_SNUM + sizeof(struct m_shdr *) + \ - sizeof(long) + sizeof(struct m_hdr *)) + sizeof(zlong) + sizeof(struct m_hdr *)) #define M_BSLEN(S) (((S) - sizeof(struct m_shdr *) - \ - sizeof(long) - sizeof(struct m_hdr *)) / M_SNUM) + sizeof(zlong) - sizeof(struct m_hdr *)) / M_SNUM) #define M_NSMALL 8 static struct m_hdr *m_small[M_NSMALL]; @@ -1198,8 +1203,9 @@ bin_mem(char *name, char **argv, char *ops, int func) if (m == mf) buf[0] = '\0'; else if (m == ms) - sprintf(buf, "%ld %ld %ld", M_SNUM - ms->used, ms->used, - (m->len - sizeof(struct m_hdr)) / M_SNUM + 1); + sprintf(buf, "%ld %ld %ld", (long)(M_SNUM - ms->used), + (long)ms->used, + (long)(m->len - sizeof(struct m_hdr)) / M_SNUM + 1); else { for (i = 0, b = buf, c = (char *)&m->next; i < 20 && i < m->len; @@ -1210,7 +1216,7 @@ bin_mem(char *name, char **argv, char *ops, int func) printf("%d\t%d\t%ld\t%ld\t%s\t%ld\t%s\n", ii, (m == mf) ? fi++ : ui++, - (long)m, m->len, + (long)m, (long)m->len, (m == mf) ? "free" : ((m == ms) ? "small" : "used"), (m == mf) ? (f += m->len) : (u += m->len), buf); @@ -1231,7 +1237,8 @@ bin_mem(char *name, char **argv, char *ops, int func) printf("%ld\t", (long)i * M_ISIZE); for (ii = 0, m = m_small[i]; m; m = m->next) { - printf("(%ld/%ld) ", M_SNUM - m->used, m->used); + printf("(%ld/%ld) ", (long)(M_SNUM - m->used), + (long)m->used); if (!((++ii) & 7)) printf("\n\t"); } diff --git a/Src/module.c b/Src/module.c index c966d4497..fa7dd2774 100644 --- a/Src/module.c +++ b/Src/module.c @@ -1224,8 +1224,8 @@ addparamdef(Paramdef d) pm->level = 0; pm->u.data = d->var; - pm->sets.ifn = (void (*)(Param, long)) d->set; - pm->gets.ifn = (long (*)(Param)) d->get; + pm->sets.ifn = (void (*)(Param, zlong)) d->set; + pm->gets.ifn = (zlong (*)(Param)) d->get; pm->unsetfn = (void (*)(Param, int)) d->unset; return 0; diff --git a/Src/options.c b/Src/options.c index c0042a662..36030f516 100644 --- a/Src/options.c +++ b/Src/options.c @@ -45,15 +45,6 @@ char opts[OPT_SIZE]; /**/ HashTable optiontab; -typedef struct optname *Optname; - -struct optname { - HashNode next; /* next in hash chain */ - char *nam; /* hash data */ - int flags; - int optno; /* option number */ -}; - /* The canonical option name table */ #define OPT_CSH EMULATE_CSH @@ -73,6 +64,10 @@ struct optname { #define defset(X) (!!((X)->flags & emulation)) +/* + * Note that option names should usually be fewer than 20 characters long + * to avoid formatting problems. + */ static struct optname optns[] = { {NULL, "allexport", 0, ALLEXPORT}, {NULL, "alwayslastprompt", OPT_ALL, ALWAYSLASTPROMPT}, @@ -137,7 +132,7 @@ static struct optname optns[] = { {NULL, "hup", OPT_EMULATE|OPT_ZSH, HUP}, {NULL, "ignorebraces", OPT_EMULATE|OPT_SH, IGNOREBRACES}, {NULL, "ignoreeof", 0, IGNOREEOF}, -{NULL, "incrementalappendhistory",0, INCREMENTALAPPENDHISTORY}, +{NULL, "incappendhistory", 0, INCAPPENDHISTORY}, {NULL, "interactive", OPT_SPECIAL, INTERACTIVE}, {NULL, "interactivecomments", OPT_EMULATE|OPT_BOURNE, INTERACTIVECOMMENTS}, {NULL, "ksharrays", OPT_EMULATE|OPT_BOURNE, KSHARRAYS}, @@ -443,6 +438,17 @@ emulate(const char *zsh_name, int fully) { char ch = *zsh_name; + if (!strcmp("su", zsh_name)) { + /* We haven't set up the paramtable yet, so just use zgetenv */ + char *ptr = zgetenv("SHELL"); + if (ptr && *ptr) { + zsh_name = ptr; + if ((ptr = strrchr(zsh_name, '/'))) + zsh_name = ptr+1; + ch = *zsh_name; + } else + ch = 'z'; + } if (ch == 'r') ch = zsh_name[1]; diff --git a/Src/params.c b/Src/params.c index a8b027988..e10fbda93 100644 --- a/Src/params.c +++ b/Src/params.c @@ -74,7 +74,7 @@ char *argzero, /* $0 */ *zsh_name; /* $ZSH_NAME */ /**/ -long lastval, /* $? */ +zlong lastval, /* $? */ mypid, /* $$ */ lastpid, /* $! */ columns, /* $COLUMNS */ @@ -334,7 +334,7 @@ copyparamtable(HashTable ht, char *name) static unsigned numparamvals; /**/ -static void +void scancountparams(HashNode hn, int flags) { ++numparamvals; @@ -346,7 +346,7 @@ static Comp scancomp; static char **paramvals; /**/ -static void +void scanparamvals(HashNode hn, int flags) { struct value v; @@ -572,6 +572,8 @@ createparam(char *name, int flags) gethashnode2(paramtab, name) : paramtab->getnode(paramtab, name)); + DPUTS(oldpm && oldpm->level > locallevel, + "BUG: old local parameter not deleteed"); if (oldpm && oldpm->level == locallevel) { if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) { oldpm->flags &= ~PM_UNSET; @@ -704,13 +706,13 @@ isident(char *s) static char **garr; /**/ -static long -getarg(char **str, int *inv, Value v, int a2, long *w) +static zlong +getarg(char **str, int *inv, Value v, int a2, zlong *w) { int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash; int beg = 0, hasbeg = 0; char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt; - long r = 0; + zlong r = 0; Comp c; ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED); @@ -872,7 +874,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w) return 0; if (!a2 && *tt != ',') - *w = (long)(s - t) - 1; + *w = (zlong)(s - t) - 1; return (a2 ? s : d + 1) - t; } else if (!v->isarr && !word) { @@ -973,7 +975,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w) r++; for (i = 0; (t = findword(&d, sep)) && *t; i++) if (!--r) { - r = (long)(t - s + (a2 ? -1 : 1)); + r = (zlong)(t - s + (a2 ? -1 : 1)); if (!a2 && *tt != ',') *w = r + strlen(ta[i]) - 2; return r; @@ -1051,7 +1053,7 @@ getindex(char **pptr, Value v) v->b = -1; s += 2; } else { - long we = 0, dummy; + zlong we = 0, dummy; a = getarg(&s, &inv, v, 0, &we); @@ -1216,7 +1218,7 @@ char * getstrvalue(Value v) { char *s, **ss; - static char buf[(sizeof(long) * 8) + 4]; + static char buf[(sizeof(zlong) * 8) + 4]; if (!v) return hcalloc(1); @@ -1314,7 +1316,7 @@ getarrvalue(Value v) } /**/ -long +zlong getintvalue(Value v) { if (!v || v->isarr) @@ -1330,7 +1332,7 @@ getintvalue(Value v) static void setstrvalue(Value v, char *val) { - char buf[(sizeof(long) * 8) + 4]; + char buf[(sizeof(zlong) * 8) + 4]; if (v->pm->flags & PM_READONLY) { zerr("read-only variable: %s", v->pm->nam, 0); @@ -1414,7 +1416,7 @@ setstrvalue(Value v, char *val) /**/ static void -setintvalue(Value v, long val) +setintvalue(Value v, zlong val) { char buf[DIGBUFSIZE]; @@ -1429,7 +1431,7 @@ setintvalue(Value v, long val) switch (PM_TYPE(v->pm->flags)) { case PM_SCALAR: case PM_ARRAY: - sprintf(buf, "%ld", val); + convbase(buf, val, 0); setstrvalue(v, ztrdup(buf)); break; case PM_INTEGER: @@ -1508,7 +1510,7 @@ setarrvalue(Value v, char **val) /* Retrieve an integer parameter */ /**/ -long +zlong getiparam(char *s) { Value v; @@ -1681,7 +1683,7 @@ sethparam(char *s, char **val) /**/ Param -setiparam(char *s, long val) +setiparam(char *s, zlong val) { Value v; char *t = s; @@ -1794,7 +1796,7 @@ stdunsetfn(Param pm, int exp) /* Function to get value of an integer parameter */ /**/ -static long +static zlong intgetfn(Param pm) { return pm->u.val; @@ -1804,7 +1806,7 @@ intgetfn(Param pm) /**/ static void -intsetfn(Param pm, long x) +intsetfn(Param pm, zlong x) { pm->u.val = x; } @@ -1859,7 +1861,7 @@ arrsetfn(Param pm, char **x) /* Function to get value of an association parameter */ /**/ -static HashTable +HashTable hashgetfn(Param pm) { return pm->u.hash; @@ -1872,7 +1874,7 @@ static int delunset; /* Function to set value of an association parameter */ /**/ -static void +void hashsetfn(Param pm, HashTable x) { if (pm->u.hash && pm->u.hash != x) { @@ -1941,10 +1943,10 @@ nullsetfn(Param pm, char *x) * containing the integer value. */ /**/ -long +zlong intvargetfn(Param pm) { - return *((long *)pm->u.data); + return *((zlong *)pm->u.data); } /* Function to set value of generic special integer * @@ -1953,9 +1955,9 @@ intvargetfn(Param pm) /**/ void -intvarsetfn(Param pm, long x) +intvarsetfn(Param pm, zlong x) { - *((long *)pm->u.data) = x; + *((zlong *)pm->u.data) = x; } /* Function to set value of any ZLE-related integer * @@ -1964,9 +1966,9 @@ intvarsetfn(Param pm, long x) /**/ void -zlevarsetfn(Param pm, long x) +zlevarsetfn(Param pm, zlong x) { - long *p = (long *)pm->u.data; + zlong *p = (zlong *)pm->u.data; *p = x; if (p == &lines || p == &columns) @@ -2086,7 +2088,7 @@ uniqarray(char **x) /* Function to get value of special parameter `#' and `ARGC' */ /**/ -long +zlong poundgetfn(Param pm) { return arrlen(pparams); @@ -2095,7 +2097,7 @@ poundgetfn(Param pm) /* Function to get value for special parameter `RANDOM' */ /**/ -long +zlong randomgetfn(Param pm) { return rand() & 0x7fff; @@ -2105,7 +2107,7 @@ randomgetfn(Param pm) /**/ void -randomsetfn(Param pm, long v) +randomsetfn(Param pm, zlong v) { srand((unsigned int)v); } @@ -2113,7 +2115,7 @@ randomsetfn(Param pm, long v) /* Function to get value for special parameter `SECONDS' */ /**/ -long +zlong secondsgetfn(Param pm) { return time(NULL) - shtimer.tv_sec; @@ -2123,7 +2125,7 @@ secondsgetfn(Param pm) /**/ void -secondssetfn(Param pm, long x) +secondssetfn(Param pm, zlong x) { shtimer.tv_sec = time(NULL) - x; shtimer.tv_usec = 0; @@ -2163,7 +2165,7 @@ usernamesetfn(Param pm, char *x) /* Function to get value for special parameter `UID' */ /**/ -long +zlong uidgetfn(Param pm) { return getuid(); @@ -2183,7 +2185,7 @@ uidsetfn(Param pm, uid_t x) /* Function to get value for special parameter `EUID' */ /**/ -long +zlong euidgetfn(Param pm) { return geteuid(); @@ -2203,7 +2205,7 @@ euidsetfn(Param pm, uid_t x) /* Function to get value for special parameter `GID' */ /**/ -long +zlong gidgetfn(Param pm) { return getgid(); @@ -2223,7 +2225,7 @@ gidsetfn(Param pm, gid_t x) /* Function to get value for special parameter `EGID' */ /**/ -long +zlong egidgetfn(Param pm) { return getegid(); @@ -2241,7 +2243,7 @@ egidsetfn(Param pm, gid_t x) } /**/ -long +zlong ttyidlegetfn(Param pm) { struct stat ttystat; @@ -2345,7 +2347,7 @@ lcsetfn(Param pm, char *x) /* Function to get value for special parameter `HISTSIZE' */ /**/ -long +zlong histsizegetfn(Param pm) { return histsiz; @@ -2355,7 +2357,7 @@ histsizegetfn(Param pm) /**/ void -histsizesetfn(Param pm, long v) +histsizesetfn(Param pm, zlong v) { if ((histsiz = v) <= 2) histsiz = 2; @@ -2365,7 +2367,7 @@ histsizesetfn(Param pm, long v) /* Function to get value for special parameter `ERRNO' */ /**/ -long +zlong errnogetfn(Param pm) { return errno; @@ -2626,11 +2628,11 @@ delenv(char *x) } /**/ -static void -convbase(char *s, long v, int base) +void +convbase(char *s, zlong v, int base) { int digs = 0; - unsigned long x; + zulong x; if (v < 0) *s++ = '-', v = -v; @@ -2774,7 +2776,11 @@ printparamnode(HashNode hn, int printflags) break; case PM_INTEGER: /* integer */ +#ifdef ZSH_64_BIT_TYPE + fputs(output64(p->gets.ifn(p)), stdout); +#else printf("%ld", p->gets.ifn(p)); +#endif break; case PM_ARRAY: /* array */ diff --git a/Src/prototypes.h b/Src/prototypes.h index f7f560111..1754c9b96 100644 --- a/Src/prototypes.h +++ b/Src/prototypes.h @@ -51,7 +51,7 @@ extern int tputs _((char *cp, int affcnt, int (*outc) (int))); # define WRITE_ARG_2_T char * #endif -#if defined(__hpux) && defined(_HPUX_SOURCE) +#if defined(__hpux) && defined(_HPUX_SOURCE) && !defined(_XPG4_EXTENDED) # define SELECT_ARG_2_T int * #else # define SELECT_ARG_2_T fd_set * diff --git a/Src/subst.c b/Src/subst.c index 4b60de120..3030218d6 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -99,6 +99,8 @@ stringsubst(LinkList list, LinkNode node, int ssub) while (!errflag && *str) { if ((qt = *str == Qstring) || *str == String) { if (str[1] == Inpar) { + if (!qt) + mult_isarr = 1; str++; goto comsub; } else if (str[1] == Inbrack) { @@ -249,6 +251,7 @@ singsub(char **s) * The mult_isarr variable is used by paramsubst() to tell if it yields * * an array. */ +/**/ static int mult_isarr; /**/ @@ -282,6 +285,8 @@ multsub(char **s, char ***a, int *isarr, char *sep) } *s = sepjoin(r, NULL); mult_isarr = omi; + if (isarr) + *isarr = 0; return 0; } if (l) @@ -666,7 +671,7 @@ get_intarg(char **s) { char *t = get_strarg(*s + 1); char *p, sav; - long ret; + zlong ret; if (!*t) return -1; @@ -719,7 +724,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) char *sep = NULL, *spsep = NULL; char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL; char *replstr = NULL; /* replacement string for /orig/repl */ - long prenum = 0, postnum = 0; + zlong prenum = 0, postnum = 0; int copied = 0; int arrasg = 0; int eval = 0; @@ -751,7 +756,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) } else if (*s == '(' || *s == Inpar) { char *t, sav; int tt = 0; - long num; + zlong num; int escapes = 0; int klen; #define UNTOK(C) (itok(C) ? ztokens[(C) - Pound] : (C)) @@ -1678,13 +1683,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) static char * arithsubst(char *a, char **bptr, char *rest) { - char *s = *bptr, *t, buf[DIGBUFSIZE]; - char *b = buf; - long v; + char *s = *bptr, *t; + char buf[DIGBUFSIZE], *b = buf; + zlong v; singsub(&a); v = matheval(a); - sprintf(buf, "%ld", v); + convbase(buf, v, 0); t = *bptr = (char *)ncalloc(strlen(*bptr) + strlen(buf) + strlen(rest) + 1); t--; while ((*++t = *s++)); diff --git a/Src/system.h b/Src/system.h index 2babafa7a..e95e2c4cc 100644 --- a/Src/system.h +++ b/Src/system.h @@ -27,12 +27,6 @@ * */ -#ifdef __hpux -# define _INCLUDE_POSIX_SOURCE 1 -# define _INCLUDE_XOPEN_SOURCE 1 -# define _INCLUDE_HPUX_SOURCE 1 -#endif - #ifdef sinix # define _XPG_IV 1 #endif @@ -401,9 +395,10 @@ struct timezone { #endif /* DIGBUFSIZ is the length of a buffer which can hold the -LONG_MAX-1 * + * (or with ZSH_64_BIT_TYPE maybe -LONG_LONG_MAX-1) * * converted to printable decimal form including the sign and the * * terminating null character. Below 0.30103 > lg 2. */ -#define DIGBUFSIZE ((int)(((sizeof(long) * 8) - 1) * 0.30103) + 3) +#define DIGBUFSIZE ((int)(((sizeof(zlong) * 8) - 1) * 0.30103) + 3) /* If your stat macros are broken, we will * * just undefine them. */ @@ -609,3 +604,12 @@ extern short ospeed; #ifndef O_NOCTTY # define O_NOCTTY 0 #endif + +#ifdef _LARGEFILE_SOURCE +#ifdef HAVE_FSEEKO +#define fseek fseeko +#endif +#ifdef HAVE_FTELLO +#define ftell ftello +#endif +#endif diff --git a/Src/utils.c b/Src/utils.c index faeeb0c58..32588b4c3 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -134,7 +134,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num) fmt++; } if (unset(SHINSTDIN) && lineno) - fprintf(stderr, " [%ld]\n", lineno); + fprintf(stderr, " [%ld]\n", (long)lineno); else putc('\n', stderr); fflush(stderr); @@ -1096,15 +1096,15 @@ skipparens(char inpar, char outpar, char **s) return level; } -/* Convert string to long. This function (without the z) * - * is contained in the ANSI standard C library, but a lot * - * of them seem to be broken. */ +/* Convert string to zlong (see zsh.h). This function (without the z) * + * is contained in the ANSI standard C library, but a lot of them seem * + * to be broken. */ /**/ -long +zlong zstrtol(const char *s, char **t, int base) { - long ret = 0; + zlong ret = 0; int neg; while (inblank(*s)) diff --git a/Src/zsh.export b/Src/zsh.export index b62621e0f..65626e2f6 100644 --- a/Src/zsh.export +++ b/Src/zsh.export @@ -31,6 +31,7 @@ compctlreadptr cond_match cond_str cond_val +convbase coprocin coprocout countlinknodes @@ -45,6 +46,7 @@ deletehashtable deleteparamdefs deletewrapper domatch +dosetopt doshfunc down_histent dputs @@ -52,6 +54,7 @@ dquotedztrdup dummy_list dupstring dupstrpfx +dupstruct dyncat emptyhashtable endparamscope @@ -71,6 +74,7 @@ findcmd firsthist freearray freeheap +freestruct getaparam gethashnode gethashnode2 @@ -79,7 +83,9 @@ getintvalue getiparam getkeystring getlinknode +getpermtext getshfunc +getsignum getsparam getstrvalue gettempname @@ -92,6 +98,8 @@ gotwordptr hasam hashcmd hasher +hashgetfn +hashsetfn hasspecial haswilds hcalloc @@ -156,10 +164,13 @@ noop_function noop_function_int old_heaps optiontab +optlookup opts +output64 paramtab parbegin parend +parse_string parsereg parsestr path @@ -171,6 +182,7 @@ ppid prefork prepromptfns printif +printparamnode printqt promptexpand pushheap @@ -179,6 +191,7 @@ pwd quietgetevent quietgethist quotedzputs +realparamtab refreshptr remlpaths remnulargs @@ -189,11 +202,13 @@ restoredir reswdtab retflag runshfunc +scancountparams scanhashtable setaparam sethparam setlimits setsparam +settrap settyinfo sfcontext shfunctab @@ -211,6 +226,7 @@ startparamscope stdunsetfn stophist stopmsg +strgetfn strinbeg strinend strpfx diff --git a/Src/zsh.h b/Src/zsh.h index 1d635afdc..ae4513491 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -38,6 +38,21 @@ /* A few typical macros */ #define minimum(a,b) ((a) < (b) ? (a) : (b)) +/* + * Our longest integer type: will be a 64 bit either if long already is, + * or if we found some alternative such as long long. + * Currently we only define this to be longer than a long if --enable-lfs + * was given. That enables internal use of 64-bit types even if + * no actual large file support is present. + */ +#ifdef ZSH_64_BIT_TYPE +typedef ZSH_64_BIT_TYPE zlong; +typedef unsigned ZSH_64_BIT_TYPE zulong; +#else +typedef long zlong; +typedef unsigned long zulong; +#endif + /* math.c */ typedef int LV; @@ -228,6 +243,7 @@ typedef struct linklist *LinkList; typedef struct hashnode *HashNode; typedef struct hashtable *HashTable; +typedef struct optname *Optname; typedef struct reswd *Reswd; typedef struct alias *Alias; typedef struct param *Param; @@ -685,6 +701,7 @@ typedef int (*CompareFunc) _((const char *, const char *)); /* type of function that is passed to * * scanhashtable or scanmatchtable */ typedef void (*ScanFunc) _((HashNode, int)); +typedef void (*ScanTabFunc) _((HashTable, ScanFunc, int)); typedef void (*PrintTableStats) _((HashTable)); @@ -710,6 +727,7 @@ struct hashtable { ScanFunc enablenode; /* pointer to function to enable a node */ FreeNodeFunc freenode; /* pointer to function to free a node */ ScanFunc printnode; /* pointer to function to print a node */ + ScanTabFunc scantab; /* pointer to function to scan table */ #ifdef HASHTABLE_INTERNAL_MEMBERS HASHTABLE_INTERNAL_MEMBERS /* internal use in hashtable.c */ @@ -729,6 +747,15 @@ struct hashnode { * reserved words. */ #define DISABLED (1<<0) +/* node in shell option table */ + +struct optname { + HashNode next; /* next in hash chain */ + char *nam; /* hash data */ + int flags; + int optno; /* option number */ +}; + /* node in shell reserved word hash table (reswdtab) */ struct reswd { @@ -868,14 +895,14 @@ struct param { void *data; /* used by special parameter functions */ char **arr; /* value if declared array (PM_ARRAY) */ char *str; /* value if declared string (PM_SCALAR) */ - long val; /* value if declared integer (PM_INTEGER) */ + zlong val; /* value if declared integer (PM_INTEGER) */ HashTable hash; /* value if declared assoc (PM_HASHED) */ } u; /* pointer to function to set value of this parameter */ union { void (*cfn) _((Param, char *)); - void (*ifn) _((Param, long)); + void (*ifn) _((Param, zlong)); void (*afn) _((Param, char **)); void (*hfn) _((Param, HashTable)); } sets; @@ -883,7 +910,7 @@ struct param { /* pointer to function to get value of this parameter */ union { char *(*cfn) _((Param)); - long (*ifn) _((Param)); + zlong (*ifn) _((Param)); char **(*afn) _((Param)); HashTable (*hfn) _((Param)); } gets; @@ -1155,7 +1182,7 @@ enum { HUP, IGNOREBRACES, IGNOREEOF, - INCREMENTALAPPENDHISTORY, + INCAPPENDHISTORY, INTERACTIVE, INTERACTIVECOMMENTS, KSHARRAYS, @@ -1298,7 +1325,8 @@ struct ttyinfo { #define TCALLATTRSOFF 21 #define TCSTANDOUTEND 22 #define TCUNDERLINEEND 23 -#define TC_COUNT 24 +#define TCHORIZPOS 24 +#define TC_COUNT 25 #define tccan(X) (tclen[X]) @@ -1381,6 +1409,9 @@ struct heap { struct heap *next; /* next one */ size_t used; /* bytes used from the heap */ struct heapstack *sp; /* used by pushheap() to save the value used */ +#ifdef ZSH_64_BIT_TYPE + size_t dummy; /* Make sure sizeof(heap) is a multiple of 8 */ +#endif #define arena(X) ((char *) (X) + sizeof(struct heap)) }; |