1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-30 05:40:58 +01:00

20605: Use separate structure with get/set/unset methods fro parameters.

Separate justification width of parameters from base/precision.
This commit is contained in:
Peter Stephenson 2004-12-07 16:54:58 +00:00
parent ddc186f3f6
commit 69b4b8bdde
22 changed files with 1042 additions and 819 deletions

View file

@ -1,5 +1,17 @@
2004-12-07 Peter Stephenson <pws@csr.com> 2004-12-07 Peter Stephenson <pws@csr.com>
* 20605: Doc/Zsh/builtins.yo, Src/builtin.c, Src/exec.c,
Src/module.c, Src/params.c, Src/subst.c, Src/zsh.h,
Src/Modules/datetime.c, Src/Modules/langinfo.c,
Src/Modules/mapfile.c, Src/Modules/parameter.c,
Src/Modules/system.c, Src/Modules/termcap.c,
Src/Modules/terminfo.c, Src/Modules/zftp.c, Src/Zle/compctl.c,
Src/Zle/complete.c, Src/Zle/computil.c, Src/Zle/zle_params.c,
Src/Zle/zleparameter.c, Test/B02typeset.ztst: Use separate
structures for get, set and unset methods of parameters.
Separate width and base/precision for parameters, so that
justification works for integers.
* 20606: Test/V03mathfunc.ztst: simple verification of * 20606: Test/V03mathfunc.ztst: simple verification of
pseudorandom numbers. pseudorandom numbers.

View file

@ -483,7 +483,8 @@ Bring each specified var(job) in turn to the foreground.
If no var(job) is specified, resume the current job. If no var(job) is specified, resume the current job.
) )
findex(float) findex(float)
item(tt(float) [ {tt(PLUS())|tt(-)}tt(EFHghlprtux) ] [ var(name)[tt(=)var(value)] ... ])( item(tt(float) [ {tt(PLUS())|tt(-)}tt(EFHghlprtux) ] [ tt(-LRZ) [ var(n) ]] \
[ var(name)[tt(=)var(value)] ... ])(
Equivalent to tt(typeset -E), except that options irrelevant to floating Equivalent to tt(typeset -E), except that options irrelevant to floating
point numbers are not permitted. point numbers are not permitted.
) )
@ -585,7 +586,8 @@ the form of a call to hash.
) )
alias(history)(fc -l) alias(history)(fc -l)
findex(integer) findex(integer)
item(tt(integer) [ {tt(PLUS())|tt(-)}tt(Hghilprtux) ] [ var(name)[tt(=)var(value)] ... ])( item(tt(integer) [ {tt(PLUS())|tt(-)}tt(Hghilprtux) ] \
[ tt(-LRZ) [ var(n) ]] [ var(name)[tt(=)var(value)] ... ])(
Equivalent to tt(typeset -i), except that options irrelevant to Equivalent to tt(typeset -i), except that options irrelevant to
integers are not permitted. integers are not permitted.
) )
@ -704,7 +706,8 @@ sitem([var(mm)tt(:)]var(ss))(minutes and seconds)
endsitem() endsitem()
) )
findex(local) findex(local)
item(tt(local) [ {tt(PLUS())|tt(-)}tt(AEFHLRUZahilprtux) [var(n)]] [ var(name)[tt(=)var(value)] ] ...)( item(tt(local) [ {tt(PLUS())|tt(-)}tt(AEFHUahlprtux) ] \
[ tt(-LRZi) [ var(n) ]] [ var(name)[tt(=)var(value)] ] ...)(
Same as tt(typeset), except that the options tt(-g), and Same as tt(typeset), except that the options tt(-g), and
tt(-f) are not permitted. In this case the tt(-x) option does not force tt(-f) are not permitted. In this case the tt(-x) option does not force
the use of tt(-g), i.e. exported variables will be local to functions. the use of tt(-g), i.e. exported variables will be local to functions.
@ -1217,10 +1220,12 @@ Equivalent to tt(whence -v).
findex(typeset) findex(typeset)
cindex(parameters, setting) cindex(parameters, setting)
cindex(parameters, declaring) cindex(parameters, declaring)
xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFHLRUZafghiklprtuxmz) [var(n)]] [ \ xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFHUafghklprtuxmz) ] [ tt(-LRZi) \
[ var(n) ]] [ \
var(name)[tt(=)var(value)] ... ]) var(name)[tt(=)var(value)] ... ])
item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \ item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(Urux) ] \
var(SCALAR)[tt(=)var(value)] var(array) tt([) var(sep) tt(]))( [ tt(-LRZ) [ var(n) ]] \
var(SCALAR)[tt(=)var(value)] var(array) tt([) var(sep) tt(]))(
Set or display attributes and values for shell parameters. Set or display attributes and values for shell parameters.
A parameter is created for each var(name) that does not already refer A parameter is created for each var(name) that does not already refer
@ -1312,20 +1317,21 @@ ifnzman(noderef(Array Parameters))\
) )
item(tt(-L))( item(tt(-L))(
Left justify and remove leading blanks from var(value). Left justify and remove leading blanks from var(value).
If var(n) is nonzero, it defines the width of the field; If var(n) is nonzero, it defines the width of the field.
otherwise it is determined by the width of the value of the first If var(n) is zero, the width is determined by the width of the value of
assignment. the first assignment. In the case of numeric parameters, the length of the
complete value assigned to the parameter is used to determine the width,
not the value that would be output.
When the parameter is expanded, it is filled on the right with When the parameter is expanded, it is filled on the right with
blanks or truncated if necessary to fit the field. blanks or truncated if necessary to fit the field.
Note truncation can lead to unexpected results with numeric parameters.
Leading zeros are removed if the tt(-Z) flag is also set. Leading zeros are removed if the tt(-Z) flag is also set.
) )
item(tt(-R))( item(tt(-R))(
Right justify and fill with leading blanks. If var(n) is nonzero Similar to tt(-L), except that right justification is used;
if defines the width of the field; when the parameter is expanded, the field is left filled with
otherwise it is determined by the width of the value of the first blanks or truncated from the end. May not be combined with the tt(-Z)
assignment. flag.
When the parameter is expanded, the field is left filled with
blanks or truncated from the end.
) )
item(tt(-U))( item(tt(-U))(
For arrays (but not for associative arrays), keep only the first For arrays (but not for associative arrays), keep only the first
@ -1334,11 +1340,12 @@ colon-separated special parameters like tt(PATH) or tt(FIGNORE), etc.
This flag has a different meaning when used with tt(-f); see below. This flag has a different meaning when used with tt(-f); see below.
) )
item(tt(-Z))( item(tt(-Z))(
Right justify and fill with leading zeros if the first non-blank Specially handled if set along with the tt(-L) flag.
character is a digit and the tt(-L) flag has not been set. Otherwise, similar to tt(-R), except that leading zeros are used for
If var(n) is nonzero it defines the width of the field; padding instead of blanks if the first non-blank character is a digit.
otherwise it is determined by the width of the value of the Numeric parameters are specially handled: they are always eligible
first assignment. for padding with zeroes, and the zeroes are inserted at an appropriate
place in the output.
) )
item(tt(-a))( item(tt(-a))(
The names refer to array parameters. An array parameter may be The names refer to array parameters. An array parameter may be

View file

@ -86,9 +86,12 @@ static struct builtin bintab[] = {
BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "s:", NULL), BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "s:", NULL),
}; };
static const struct gsu_integer epochseconds_gsu =
{ getcurrentsecs, NULL, stdunsetfn };
static struct paramdef patab[] = { static struct paramdef patab[] = {
PARAMDEF("EPOCHSECONDS", PM_INTEGER|PM_SPECIAL|PM_READONLY, PARAMDEF("EPOCHSECONDS", PM_INTEGER|PM_SPECIAL|PM_READONLY,
NULL, NULL, &getcurrentsecs, stdunsetfn), NULL, &epochseconds_gsu),
}; };
/**/ /**/

View file

@ -417,9 +417,7 @@ createlihash()
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &stdhash_gsu;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(7, langinfo_nam, NULL); pm->u.hash = ht = newhashtable(7, langinfo_nam, NULL);
ht->hash = hasher; ht->hash = hasher;
@ -447,19 +445,10 @@ getlanginfo(UNUSED(HashTable ht), char *name)
unmetafy(name, &len); unmetafy(name, &len);
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->sets.ifn = NULL;
pm->gets.ifn = intgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if(name) if(name)
elem = liitem(name); elem = liitem(name);
@ -486,17 +475,8 @@ scanlanginfo(UNUSED(HashTable ht), ScanFunc func, int flags)
char **element, *langstr; char **element, *langstr;
nl_item *nlcode; nl_item *nlcode;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->sets.ifn = NULL;
pm->gets.ifn = intgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
nlcode = &nl_vals[0]; nlcode = &nl_vals[0];

View file

@ -74,6 +74,9 @@ shempty(void)
{ {
} }
static const struct gsu_hash mapfiles_gsu =
{ hashgetfn, setpmmapfiles, stdunsetfn };
/* Create the special hash parameter. */ /* Create the special hash parameter. */
/**/ /**/
@ -91,9 +94,7 @@ createmapfilehash()
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &mapfiles_gsu;
pm->sets.hfn = setpmmapfiles;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(7, mapfile_nam, NULL); pm->u.hash = ht = newhashtable(7, mapfile_nam, NULL);
ht->hash = hasher; ht->hash = hasher;
@ -257,6 +258,9 @@ get_contents(char *fname)
return val; return val;
} }
static const struct gsu_scalar mapfile_gsu =
{ strgetfn, setpmmapfile, unsetpmmapfile };
/**/ /**/
static HashNode static HashNode
getpmmapfile(UNUSED(HashTable ht), char *name) getpmmapfile(UNUSED(HashTable ht), char *name)
@ -264,18 +268,10 @@ getpmmapfile(UNUSED(HashTable ht), char *name)
char *contents; char *contents;
Param pm = NULL; Param pm = NULL;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR; pm->flags = PM_SCALAR;
pm->sets.cfn = setpmmapfile; pm->gsu.s = &mapfile_gsu;
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); pm->flags |= (mapfile_pm->flags & PM_READONLY);
/* Set u.str to contents of file given by name */ /* Set u.str to contents of file given by name */
@ -288,6 +284,7 @@ getpmmapfile(UNUSED(HashTable ht), char *name)
return (HashNode) pm; return (HashNode) pm;
} }
/**/ /**/
static void static void
scanpmmapfile(UNUSED(HashTable ht), ScanFunc func, int flags) scanpmmapfile(UNUSED(HashTable ht), ScanFunc func, int flags)
@ -298,16 +295,9 @@ scanpmmapfile(UNUSED(HashTable ht), ScanFunc func, int flags)
if (!(dir = opendir("."))) if (!(dir = opendir(".")))
return; return;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR; pm.flags = PM_SCALAR;
pm.sets.cfn = setpmmapfile; pm.gsu.s = &mapfile_gsu;
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); pm.flags |= (mapfile_pm->flags & PM_READONLY);
/* Here we scan the current directory, calling func() for each file */ /* Here we scan the current directory, calling func() for each file */

View file

@ -56,11 +56,8 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &stdhash_gsu;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(0, name, NULL); pm->u.hash = ht = newhashtable(0, name, NULL);
pm->ct = 0;
ht->hash = hasher; ht->hash = hasher;
ht->emptytable = (TableFunc) shempty; ht->emptytable = (TableFunc) shempty;
@ -140,17 +137,10 @@ getpmparameter(UNUSED(HashTable ht), char *name)
{ {
Param rpm, pm = NULL; Param rpm, pm = NULL;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
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)) && if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
!(rpm->flags & PM_UNSET)) !(rpm->flags & PM_UNSET))
pm->u.str = paramtypestr(rpm); pm->u.str = paramtypestr(rpm);
@ -169,15 +159,9 @@ scanpmparameters(UNUSED(HashTable ht), ScanFunc func, int flags)
int i; int i;
HashNode hn; HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
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 (i = 0; i < realparamtab->hsize; i++)
for (hn = realparamtab->nodes[i]; hn; hn = hn->next) { for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
@ -249,6 +233,10 @@ setpmcommands(UNUSED(Param pm), HashTable ht)
deleteparamtable(ht); deleteparamtable(ht);
} }
static const struct gsu_scalar pmcommand_gsu =
{ strgetfn, setpmcommand, unsetpmcommand };
/**/ /**/
static HashNode static HashNode
getpmcommand(UNUSED(HashTable ht), char *name) getpmcommand(UNUSED(HashTable ht), char *name)
@ -261,17 +249,10 @@ getpmcommand(UNUSED(HashTable ht), char *name)
cmdnamtab->filltable(cmdnamtab); cmdnamtab->filltable(cmdnamtab);
cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name); cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
} }
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR; pm->flags = PM_SCALAR;
pm->sets.cfn = setpmcommand; pm->gsu.s = &pmcommand_gsu;
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) {
if (cmd->flags & HASHED) if (cmd->flags & HASHED)
pm->u.str = cmd->u.cmd; pm->u.str = cmd->u.cmd;
@ -300,15 +281,9 @@ scanpmcommands(UNUSED(HashTable ht), ScanFunc func, int flags)
if (isset(HASHLISTALL)) if (isset(HASHLISTALL))
cmdnamtab->filltable(cmdnamtab); cmdnamtab->filltable(cmdnamtab);
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR; pm.flags = PM_SCALAR;
pm.sets.cfn = setpmcommand; pm.gsu.s = &pmcommand_gsu;
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 (i = 0; i < cmdnamtab->hsize; i++)
for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) { for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) {
@ -431,6 +406,11 @@ setpmdisfunctions(Param pm, HashTable ht)
setfunctions(pm, ht, DISABLED); setfunctions(pm, ht, DISABLED);
} }
static const struct gsu_scalar pmfunction_gsu =
{ strgetfn, setpmfunction, unsetpmfunction };
static const struct gsu_scalar pmdisfunction_gsu =
{ strgetfn, setpmdisfunction, unsetpmfunction };
/**/ /**/
static HashNode static HashNode
getfunction(UNUSED(HashTable ht), char *name, int dis) getfunction(UNUSED(HashTable ht), char *name, int dis)
@ -438,17 +418,10 @@ getfunction(UNUSED(HashTable ht), char *name, int dis)
Shfunc shf; Shfunc shf;
Param pm = NULL; Param pm = NULL;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR; pm->flags = PM_SCALAR;
pm->sets.cfn = (dis ? setpmdisfunction : setpmfunction); pm->gsu.s = dis ? &pmdisfunction_gsu : &pmfunction_gsu;
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->getnode2(shfunctab, name)) && if ((shf = (Shfunc) shfunctab->getnode2(shfunctab, name)) &&
(dis ? (shf->flags & DISABLED) : !(shf->flags & DISABLED))) { (dis ? (shf->flags & DISABLED) : !(shf->flags & DISABLED))) {
@ -504,15 +477,9 @@ scanfunctions(UNUSED(HashTable ht), ScanFunc func, int flags, int dis)
int i; int i;
HashNode hn; HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR; pm.flags = PM_SCALAR;
pm.sets.cfn = (dis ? setpmdisfunction : setpmfunction); pm.gsu.s = dis ? &pmdisfunction_gsu : &pmfunction_gsu;
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 (i = 0; i < shfunctab->hsize; i++)
for (hn = shfunctab->nodes[i]; hn; hn = hn->next) { for (hn = shfunctab->nodes[i]; hn; hn = hn->next) {
@ -594,17 +561,10 @@ getbuiltin(UNUSED(HashTable ht), char *name, int dis)
Param pm = NULL; Param pm = NULL;
Builtin bn; Builtin bn;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((bn = (Builtin) builtintab->getnode2(builtintab, name)) && if ((bn = (Builtin) builtintab->getnode2(builtintab, name)) &&
(dis ? (bn->flags & DISABLED) : !(bn->flags & DISABLED))) { (dis ? (bn->flags & DISABLED) : !(bn->flags & DISABLED))) {
char *t = ((bn->handlerfunc || (bn->flags & BINF_PREFIX)) ? char *t = ((bn->handlerfunc || (bn->flags & BINF_PREFIX)) ?
@ -640,15 +600,9 @@ scanbuiltins(UNUSED(HashTable ht), ScanFunc func, int flags, int dis)
int i; int i;
HashNode hn; HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
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 < builtintab->hsize; i++) for (i = 0; i < builtintab->hsize; i++)
for (hn = builtintab->nodes[i]; hn; hn = hn->next) { for (hn = builtintab->nodes[i]; hn; hn = hn->next) {
@ -776,6 +730,9 @@ setpmoptions(UNUSED(Param pm), HashTable ht)
deleteparamtable(ht); deleteparamtable(ht);
} }
static const struct gsu_scalar pmoption_gsu =
{ strgetfn, setpmoption, unsetpmoption };
/**/ /**/
static HashNode static HashNode
getpmoption(UNUSED(HashTable ht), char *name) getpmoption(UNUSED(HashTable ht), char *name)
@ -783,17 +740,10 @@ getpmoption(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
int n; int n;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR; pm->flags = PM_SCALAR;
pm->sets.cfn = setpmoption; pm->gsu.s = &pmoption_gsu;
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))) if ((n = optlookup(name)))
{ {
@ -819,15 +769,9 @@ scanpmoptions(UNUSED(HashTable ht), ScanFunc func, int flags)
int i; int i;
HashNode hn; HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR; pm.flags = PM_SCALAR;
pm.sets.cfn = setpmoption; pm.gsu.s = &pmoption_gsu;
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 (i = 0; i < optiontab->hsize; i++)
for (hn = optiontab->nodes[i]; hn; hn = hn->next) { for (hn = optiontab->nodes[i]; hn; hn = hn->next) {
@ -883,17 +827,10 @@ getpmmodule(UNUSED(HashTable ht), char *name)
char *type = NULL; char *type = NULL;
LinkNode node; LinkNode node;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if (!type) { if (!type) {
Module m; Module m;
@ -948,15 +885,9 @@ scanpmmodules(UNUSED(HashTable ht), ScanFunc func, int flags)
Conddef p; Conddef p;
char *loaded = dupstring("loaded"); char *loaded = dupstring("loaded");
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (node = firstnode(modules); node; incnode(node)) { for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node); m = (Module) getdata(node);
@ -1039,17 +970,10 @@ getpmhistory(UNUSED(HashTable ht), char *name)
char *p; char *p;
int ok = 1; int ok = 1;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if (*name != '0' || name[1]) { if (*name != '0' || name[1]) {
if (*name == '0') if (*name == '0')
@ -1078,15 +1002,9 @@ scanpmhistory(UNUSED(HashTable ht), ScanFunc func, int flags)
Histent he = gethistent(i, GETHIST_UPWARD); Histent he = gethistent(i, GETHIST_UPWARD);
char buf[40]; char buf[40];
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
while (he) { while (he) {
if (func != scancountparams) { if (func != scancountparams) {
@ -1169,17 +1087,10 @@ getpmjobtext(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
int job; int job;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((job = atoi(name)) >= 1 && job <= maxjob && if ((job = atoi(name)) >= 1 && job <= maxjob &&
jobtab[job].stat && jobtab[job].procs && jobtab[job].stat && jobtab[job].procs &&
@ -1200,15 +1111,9 @@ scanpmjobtexts(UNUSED(HashTable ht), ScanFunc func, int flags)
int job; int job;
char buf[40]; char buf[40];
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (job = 1; job <= maxjob; job++) { for (job = 1; job <= maxjob; job++) {
if (jobtab[job].stat && jobtab[job].procs && if (jobtab[job].stat && jobtab[job].procs &&
@ -1279,17 +1184,10 @@ getpmjobstate(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
int job; int job;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((job = atoi(name)) >= 1 && job <= maxjob && if ((job = atoi(name)) >= 1 && job <= maxjob &&
jobtab[job].stat && jobtab[job].procs && jobtab[job].stat && jobtab[job].procs &&
@ -1310,15 +1208,9 @@ scanpmjobstates(UNUSED(HashTable ht), ScanFunc func, int flags)
int job; int job;
char buf[40]; char buf[40];
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (job = 1; job <= maxjob; job++) { for (job = 1; job <= maxjob; job++) {
if (jobtab[job].stat && jobtab[job].procs && if (jobtab[job].stat && jobtab[job].procs &&
@ -1354,17 +1246,10 @@ getpmjobdir(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
int job; int job;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((job = atoi(name)) >= 1 && job <= maxjob && if ((job = atoi(name)) >= 1 && job <= maxjob &&
jobtab[job].stat && jobtab[job].procs && jobtab[job].stat && jobtab[job].procs &&
@ -1385,15 +1270,9 @@ scanpmjobdirs(UNUSED(HashTable ht), ScanFunc func, int flags)
int job; int job;
char buf[40]; char buf[40];
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (job = 1; job <= maxjob; job++) { for (job = 1; job <= maxjob; job++) {
if (jobtab[job].stat && jobtab[job].procs && if (jobtab[job].stat && jobtab[job].procs &&
@ -1485,6 +1364,9 @@ setpmnameddirs(UNUSED(Param pm), HashTable ht)
opts[INTERACTIVE] = i; opts[INTERACTIVE] = i;
} }
static const struct gsu_scalar pmnamedir_gsu =
{ strgetfn, setpmnameddir, unsetpmnameddir };
/**/ /**/
static HashNode static HashNode
getpmnameddir(UNUSED(HashTable ht), char *name) getpmnameddir(UNUSED(HashTable ht), char *name)
@ -1492,17 +1374,10 @@ getpmnameddir(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
Nameddir nd; Nameddir nd;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR; pm->flags = PM_SCALAR;
pm->sets.cfn = setpmnameddir; pm->gsu.s = &pmnamedir_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = unsetpmnameddir;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) && if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) &&
!(nd->flags & ND_USERNAME)) !(nd->flags & ND_USERNAME))
pm->u.str = dupstring(nd->dir); pm->u.str = dupstring(nd->dir);
@ -1522,15 +1397,9 @@ scanpmnameddirs(UNUSED(HashTable ht), ScanFunc func, int flags)
HashNode hn; HashNode hn;
Nameddir nd; Nameddir nd;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR; pm.flags = PM_SCALAR;
pm.sets.cfn = setpmnameddir; pm.gsu.s = &pmnamedir_gsu;
pm.gets.cfn = strgetfn;
pm.unsetfn = unsetpmnameddir;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (i = 0; i < nameddirtab->hsize; i++) for (i = 0; i < nameddirtab->hsize; i++)
for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) { for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) {
@ -1556,17 +1425,10 @@ getpmuserdir(UNUSED(HashTable ht), char *name)
nameddirtab->filltable(nameddirtab); nameddirtab->filltable(nameddirtab);
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) && if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) &&
(nd->flags & ND_USERNAME)) (nd->flags & ND_USERNAME))
pm->u.str = dupstring(nd->dir); pm->u.str = dupstring(nd->dir);
@ -1588,15 +1450,9 @@ scanpmuserdirs(UNUSED(HashTable ht), ScanFunc func, int flags)
nameddirtab->filltable(nameddirtab); nameddirtab->filltable(nameddirtab);
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
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 < nameddirtab->hsize; i++) for (i = 0; i < nameddirtab->hsize; i++)
for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) { for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) {
@ -1766,6 +1622,19 @@ setpmdissaliases(Param pm, HashTable ht)
setaliases(sufaliastab, pm, ht, ALIAS_SUFFIX|DISABLED); setaliases(sufaliastab, pm, ht, ALIAS_SUFFIX|DISABLED);
} }
static const struct gsu_scalar pmralias_gsu =
{ strgetfn, setpmralias, unsetpmalias };
static const struct gsu_scalar pmgalias_gsu =
{ strgetfn, setpmgalias, unsetpmalias };
static const struct gsu_scalar pmsalias_gsu =
{ strgetfn, setpmsalias, unsetpmsalias };
static const struct gsu_scalar pmdisralias_gsu =
{ strgetfn, setpmdisralias, unsetpmalias };
static const struct gsu_scalar pmdisgalias_gsu =
{ strgetfn, setpmdisgalias, unsetpmalias };
static const struct gsu_scalar pmdissalias_gsu =
{ strgetfn, setpmdissalias, unsetpmsalias };
/**/ /**/
static void static void
assignaliasdefs(Param pm, int flags) assignaliasdefs(Param pm, int flags)
@ -1775,40 +1644,29 @@ assignaliasdefs(Param pm, int flags)
/* we really need to squirrel the flags away somewhere... */ /* we really need to squirrel the flags away somewhere... */
switch (flags) { switch (flags) {
case 0: case 0:
pm->sets.cfn = setpmralias; pm->gsu.s = &pmralias_gsu;
break; break;
case ALIAS_GLOBAL: case ALIAS_GLOBAL:
pm->sets.cfn = setpmgalias; pm->gsu.s = &pmgalias_gsu;
break; break;
case ALIAS_SUFFIX: case ALIAS_SUFFIX:
pm->sets.cfn = setpmsalias; pm->gsu.s = &pmsalias_gsu;
break; break;
case DISABLED: case DISABLED:
pm->sets.cfn = setpmdisralias; pm->gsu.s = &pmdisralias_gsu;
break; break;
case ALIAS_GLOBAL|DISABLED: case ALIAS_GLOBAL|DISABLED:
pm->sets.cfn = setpmdisgalias; pm->gsu.s = &pmdisgalias_gsu;
break; break;
case ALIAS_SUFFIX|DISABLED: case ALIAS_SUFFIX|DISABLED:
pm->sets.cfn = setpmdissalias; pm->gsu.s = &pmdissalias_gsu;
break; break;
} }
pm->gets.cfn = strgetfn;
if (flags & ALIAS_SUFFIX)
pm->unsetfn = unsetpmsalias;
else
pm->unsetfn = unsetpmalias;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
} }
/**/ /**/
@ -1818,7 +1676,7 @@ getalias(HashTable alht, UNUSED(HashTable ht), char *name, int flags)
Param pm = NULL; Param pm = NULL;
Alias al; Alias al;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
assignaliasdefs(pm, flags); assignaliasdefs(pm, flags);
@ -1884,6 +1742,7 @@ scanaliases(HashTable alht, UNUSED(HashTable ht), ScanFunc func,
int i; int i;
Alias al; Alias al;
memset((void *)&pm, 0, sizeof(struct param));
assignaliasdefs(&pm, alflags); assignaliasdefs(&pm, alflags);
for (i = 0; i < alht->hsize; i++) for (i = 0; i < alht->hsize; i++)
@ -1948,90 +1807,122 @@ struct pardef {
int flags; int flags;
GetNodeFunc getnfn; GetNodeFunc getnfn;
ScanTabFunc scantfn; ScanTabFunc scantfn;
void (*hsetfn) _((Param, HashTable)); GsuHash hash_gsu;
void (*setfn) _((Param, char **)); GsuArray array_gsu;
char **(*getfn) _((Param));
void (*unsetfn) _((Param, int));
Param pm; Param pm;
}; };
static const struct gsu_hash pmcommands_gsu =
{ hashgetfn, setpmcommands, stdunsetfn };
static const struct gsu_hash pmfunctions_gsu =
{ hashgetfn, setpmfunctions, stdunsetfn };
static const struct gsu_hash pmdisfunctions_gsu =
{ hashgetfn, setpmdisfunctions, stdunsetfn };
static const struct gsu_hash pmoptions_gsu =
{ hashgetfn, setpmoptions, stdunsetfn };
static const struct gsu_hash pmnameddirs_gsu =
{ hashgetfn, setpmnameddirs, stdunsetfn };
static const struct gsu_hash pmraliases_gsu =
{ hashgetfn, setpmraliases, stdunsetfn };
static const struct gsu_hash pmgaliases_gsu =
{ hashgetfn, setpmgaliases, stdunsetfn };
static const struct gsu_hash pmsaliases_gsu =
{ hashgetfn, setpmsaliases, stdunsetfn };
static const struct gsu_hash pmdisraliases_gsu =
{ hashgetfn, setpmdisraliases, stdunsetfn };
static const struct gsu_hash pmdisgaliases_gsu =
{ hashgetfn, setpmdisgaliases, stdunsetfn };
static const struct gsu_hash pmdissaliases_gsu =
{ hashgetfn, setpmdissaliases, stdunsetfn };
static const struct gsu_array funcstack_gsu =
{ funcstackgetfn, arrsetfn, stdunsetfn };
static const struct gsu_array reswords_gsu =
{ reswordsgetfn, arrsetfn, stdunsetfn };
static const struct gsu_array disreswords_gsu =
{ disreswordsgetfn, arrsetfn, stdunsetfn };
static const struct gsu_array dirs_gsu =
{ dirsgetfn, dirssetfn, stdunsetfn };
static const struct gsu_array historywords_gsu =
{ histwgetfn, arrsetfn, stdunsetfn };
static struct pardef partab[] = { static struct pardef partab[] = {
{ "parameters", PM_READONLY, { "parameters", PM_READONLY,
getpmparameter, scanpmparameters, hashsetfn, getpmparameter, scanpmparameters, &nullsethash_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "commands", 0, { "commands", 0,
getpmcommand, scanpmcommands, setpmcommands, getpmcommand, scanpmcommands, &pmcommands_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "functions", 0, { "functions", 0,
getpmfunction, scanpmfunctions, setpmfunctions, getpmfunction, scanpmfunctions, &pmfunctions_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dis_functions", 0, { "dis_functions", 0,
getpmdisfunction, scanpmdisfunctions, setpmdisfunctions, getpmdisfunction, scanpmdisfunctions, &pmdisfunctions_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "funcstack", PM_ARRAY|PM_SPECIAL|PM_READONLY, { "funcstack", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL, NULL, NULL, NULL,
arrsetfn, funcstackgetfn, stdunsetfn, NULL }, &funcstack_gsu, NULL },
{ "builtins", PM_READONLY, { "builtins", PM_READONLY,
getpmbuiltin, scanpmbuiltins, hashsetfn, getpmbuiltin, scanpmbuiltins, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dis_builtins", PM_READONLY, { "dis_builtins", PM_READONLY,
getpmdisbuiltin, scanpmdisbuiltins, hashsetfn, getpmdisbuiltin, scanpmdisbuiltins,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL, },
{ "reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY, { "reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL, NULL, NULL, NULL,
arrsetfn, reswordsgetfn, stdunsetfn, NULL }, &reswords_gsu, NULL },
{ "dis_reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY, { "dis_reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL, NULL, NULL, NULL,
arrsetfn, disreswordsgetfn, stdunsetfn, NULL }, &disreswords_gsu, NULL },
{ "options", 0, { "options", 0,
getpmoption, scanpmoptions, setpmoptions, getpmoption, scanpmoptions, &pmoptions_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "modules", PM_READONLY, { "modules", PM_READONLY,
getpmmodule, scanpmmodules, hashsetfn, getpmmodule, scanpmmodules, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dirstack", PM_ARRAY|PM_SPECIAL|PM_REMOVABLE, { "dirstack", PM_ARRAY|PM_SPECIAL|PM_REMOVABLE,
NULL, NULL, NULL, NULL, NULL, NULL,
dirssetfn, dirsgetfn, stdunsetfn, NULL }, &dirs_gsu, NULL },
{ "history", PM_READONLY, { "history", PM_READONLY,
getpmhistory, scanpmhistory, hashsetfn, getpmhistory, scanpmhistory, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL, },
{ "historywords", PM_ARRAY|PM_SPECIAL|PM_READONLY, { "historywords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL, NULL, NULL, NULL,
arrsetfn, histwgetfn, stdunsetfn, NULL }, &historywords_gsu, NULL },
{ "jobtexts", PM_READONLY, { "jobtexts", PM_READONLY,
getpmjobtext, scanpmjobtexts, hashsetfn, getpmjobtext, scanpmjobtexts, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "jobstates", PM_READONLY, { "jobstates", PM_READONLY,
getpmjobstate, scanpmjobstates, hashsetfn, getpmjobstate, scanpmjobstates, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "jobdirs", PM_READONLY, { "jobdirs", PM_READONLY,
getpmjobdir, scanpmjobdirs, hashsetfn, getpmjobdir, scanpmjobdirs, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "nameddirs", 0, { "nameddirs", 0,
getpmnameddir, scanpmnameddirs, setpmnameddirs, getpmnameddir, scanpmnameddirs, &pmnameddirs_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "userdirs", PM_READONLY, { "userdirs", PM_READONLY,
getpmuserdir, scanpmuserdirs, hashsetfn, getpmuserdir, scanpmuserdirs, NULL,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "aliases", 0, { "aliases", 0,
getpmralias, scanpmraliases, setpmraliases, getpmralias, scanpmraliases, &pmraliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "galiases", 0, { "galiases", 0,
getpmgalias, scanpmgaliases, setpmgaliases, getpmgalias, scanpmgaliases, &pmgaliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "saliases", 0, { "saliases", 0,
getpmsalias, scanpmsaliases, setpmsaliases, getpmsalias, scanpmsaliases, &pmsaliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dis_aliases", 0, { "dis_aliases", 0,
getpmdisralias, scanpmdisraliases, setpmdisraliases, getpmdisralias, scanpmdisraliases, &pmdisraliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dis_galiases", 0, { "dis_galiases", 0,
getpmdisgalias, scanpmdisgaliases, setpmdisgaliases, getpmdisgalias, scanpmdisgaliases, &pmdisgaliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "dis_saliases", 0, { "dis_saliases", 0,
getpmdissalias, scanpmdissaliases, setpmdissaliases, getpmdissalias, scanpmdissaliases, &pmdissaliases_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL } { NULL, 0, NULL, NULL, NULL, NULL, NULL }
}; };
/**/ /**/
@ -2062,15 +1953,13 @@ boot_(UNUSED(Module m))
def->scantfn))) def->scantfn)))
return 1; return 1;
def->pm->flags |= def->flags; def->pm->flags |= def->flags;
if (def->hsetfn) if (def->hash_gsu)
def->pm->sets.hfn = def->hsetfn; def->pm->gsu.h = def->hash_gsu;
} else { } else {
if (!(def->pm = createparam(def->name, def->flags | PM_HIDE| if (!(def->pm = createparam(def->name, def->flags | PM_HIDE|
PM_HIDEVAL | PM_REMOVABLE))) PM_HIDEVAL | PM_REMOVABLE)))
return 1; return 1;
def->pm->sets.afn = def->setfn; def->pm->gsu.a = def->array_gsu;
def->pm->gets.afn = def->getfn;
def->pm->unsetfn = def->unsetfn;
} }
} }
return 0; return 0;

View file

@ -358,6 +358,8 @@ static struct builtin bintab[] = {
BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL), BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL),
}; };
static const struct gsu_array errnos_gsu =
{ errnosgetfn, arrsetfn, stdunsetfn };
/* The load/unload routines required by the zsh library interface */ /* The load/unload routines required by the zsh library interface */
@ -390,9 +392,7 @@ boot_(Module m)
if (!(pm_nos = createparam("errnos", PM_ARRAY|PM_SPECIAL|PM_READONLY| if (!(pm_nos = createparam("errnos", PM_ARRAY|PM_SPECIAL|PM_READONLY|
PM_HIDE|PM_HIDEVAL|PM_REMOVABLE))) PM_HIDE|PM_HIDEVAL|PM_REMOVABLE)))
return 1; return 1;
pm_nos->gets.afn = errnosgetfn; pm_nos->gsu.a = &errnos_gsu;
pm_nos->sets.afn = arrsetfn;
pm_nos->unsetfn = stdunsetfn;
if (!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) { if (!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) {
tidyparam(pm_nos); tidyparam(pm_nos);

View file

@ -197,9 +197,7 @@ createtchash()
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &stdhash_gsu;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(7, termcap_nam, NULL); pm->u.hash = ht = newhashtable(7, termcap_nam, NULL);
ht->hash = hasher; ht->hash = hasher;
@ -233,29 +231,21 @@ gettermcap(UNUSED(HashTable ht), char *name)
unmetafy(name, &len); unmetafy(name, &len);
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_READONLY; pm->flags = PM_READONLY;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
u = buf; u = buf;
/* logic in the following cascade copied from echotc, above */ /* logic in the following cascade copied from echotc, above */
if ((num = tgetnum(name)) != -1) { if ((num = tgetnum(name)) != -1) {
pm->sets.ifn = NULL; pm->gsu.i = &nullsetinteger_gsu;
pm->gets.ifn = intgetfn;
pm->u.val = num; pm->u.val = num;
pm->flags |= PM_INTEGER; pm->flags |= PM_INTEGER;
return (HashNode) pm; return (HashNode) pm;
} }
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
switch (ztgetflag(name)) { switch (ztgetflag(name)) {
case -1: case -1:
break; break;
@ -338,17 +328,11 @@ scantermcap(UNUSED(HashTable ht), ScanFunc func, int flags)
"MT", "Xh", "Xl", "Xo", "Xr", "Xt", "Xv", "sA", "sL", NULL}; "MT", "Xh", "Xl", "Xo", "Xr", "Xt", "Xv", "sA", "sL", NULL};
#endif #endif
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
u = buf; u = buf;
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
for (capcode = (char **)boolcodes; *capcode; capcode++) { for (capcode = (char **)boolcodes; *capcode; capcode++) {
if ((num = ztgetflag(*capcode)) != -1) { if ((num = ztgetflag(*capcode)) != -1) {
@ -359,8 +343,7 @@ scantermcap(UNUSED(HashTable ht), ScanFunc func, int flags)
} }
pm->flags = PM_READONLY | PM_INTEGER; pm->flags = PM_READONLY | PM_INTEGER;
pm->sets.ifn = NULL; pm->gsu.i = &nullsetinteger_gsu;
pm->gets.ifn = intgetfn;
for (capcode = (char **)numcodes; *capcode; capcode++) { for (capcode = (char **)numcodes; *capcode; capcode++) {
if ((num = tgetnum(*capcode)) != -1) { if ((num = tgetnum(*capcode)) != -1) {
@ -371,8 +354,7 @@ scantermcap(UNUSED(HashTable ht), ScanFunc func, int flags)
} }
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
for (capcode = (char **)strcodes; *capcode; capcode++) { for (capcode = (char **)strcodes; *capcode; capcode++) {
if ((tcstr = (char *)tgetstr(*capcode,&u)) != NULL && if ((tcstr = (char *)tgetstr(*capcode,&u)) != NULL &&

View file

@ -165,9 +165,7 @@ createtihash()
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &stdhash_gsu;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(7, terminfo_nam, NULL); pm->u.hash = ht = newhashtable(7, terminfo_nam, NULL);
ht->hash = hasher; ht->hash = hasher;
@ -201,42 +199,32 @@ getterminfo(UNUSED(HashTable ht), char *name)
unmetafy(name, &len); unmetafy(name, &len);
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_READONLY; pm->flags = PM_READONLY;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if (((num = tigetnum(name)) != -1) && (num != -2)) { if (((num = tigetnum(name)) != -1) && (num != -2)) {
pm->u.val = num; pm->u.val = num;
pm->flags |= PM_INTEGER; pm->flags |= PM_INTEGER;
pm->sets.ifn = NULL; pm->gsu.i = &nullsetinteger_gsu;
pm->gets.ifn = intgetfn;
} }
else if ((num = tigetflag(name)) != -1) { else if ((num = tigetflag(name)) != -1) {
pm->u.str = num ? dupstring("yes") : dupstring("no"); pm->u.str = num ? dupstring("yes") : dupstring("no");
pm->flags |= PM_SCALAR; pm->flags |= PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
} }
else if ((tistr = (char *)tigetstr(name)) != NULL && tistr != (char *)-1) else if ((tistr = (char *)tigetstr(name)) != NULL && tistr != (char *)-1)
{ {
pm->u.str = dupstring(tistr); pm->u.str = dupstring(tistr);
pm->flags |= PM_SCALAR; pm->flags |= PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
} }
else else
{ {
/* zwarn("no such capability: %s", name, 0); */ /* zwarn("no such capability: %s", name, 0); */
pm->u.str = dupstring(""); pm->u.str = dupstring("");
pm->flags |= PM_UNSET; pm->flags |= PM_UNSET;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
} }
return (HashNode) pm; return (HashNode) pm;
} }
@ -319,16 +307,10 @@ scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags)
"slength", NULL}; "slength", NULL};
#endif #endif
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
for (capname = (char **)boolnames; *capname; capname++) { for (capname = (char **)boolnames; *capname; capname++) {
if ((num = tigetflag(*capname)) != -1) { if ((num = tigetflag(*capname)) != -1) {
@ -339,8 +321,7 @@ scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags)
} }
pm->flags = PM_READONLY | PM_INTEGER; pm->flags = PM_READONLY | PM_INTEGER;
pm->sets.ifn = NULL; pm->gsu.i = &nullsetinteger_gsu;
pm->gets.ifn = intgetfn;
for (capname = (char **)numnames; *capname; capname++) { for (capname = (char **)numnames; *capname; capname++) {
if (((num = tigetnum(*capname)) != -1) && (num != -2)) { if (((num = tigetnum(*capname)) != -1) && (num != -2)) {
@ -351,8 +332,7 @@ scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags)
} }
pm->flags = PM_READONLY | PM_SCALAR; pm->flags = PM_READONLY | PM_SCALAR;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
for (capname = (char **)strnames; *capname; capname++) { for (capname = (char **)strnames; *capname; capname++) {
if ((tistr = (char *)tigetstr(*capname)) != NULL && if ((tistr = (char *)tigetstr(*capname)) != NULL &&

View file

@ -513,9 +513,9 @@ zfsetparam(char *name, void *val, int flags)
return; return;
} }
if (type == PM_INTEGER) if (type == PM_INTEGER)
pm->sets.ifn(pm, *(off_t *)val); pm->gsu.i->setfn(pm, *(off_t *)val);
else else
pm->sets.cfn(pm, (char *)val); pm->gsu.s->setfn(pm, (char *)val);
} }
/* /*

View file

@ -1975,7 +1975,7 @@ addmatch(char *s, char *t)
} else if (addwhat == CC_QUOTEFLAG || addwhat == -2 || } else if (addwhat == CC_QUOTEFLAG || addwhat == -2 ||
(addwhat == -3 && !(hn->flags & DISABLED)) || (addwhat == -3 && !(hn->flags & DISABLED)) ||
(addwhat == -4 && (PM_TYPE(pm->flags) == PM_SCALAR) && (addwhat == -4 && (PM_TYPE(pm->flags) == PM_SCALAR) &&
!pm->level && (tt = pm->gets.cfn(pm)) && *tt == '/') || !pm->level && (tt = pm->gsu.s->getfn(pm)) && *tt == '/') ||
(addwhat == -9 && !(hn->flags & PM_UNSET) && !pm->level) || (addwhat == -9 && !(hn->flags & PM_UNSET) && !pm->level) ||
(addwhat > 0 && (addwhat > 0 &&
((!(hn->flags & PM_UNSET) && ((!(hn->flags & PM_UNSET) &&
@ -3750,7 +3750,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
dumphashtable(aliastab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS))); dumphashtable(aliastab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
if (keypm && cc == &cc_dummy) { if (keypm && cc == &cc_dummy) {
/* Add the keys of the parameter in keypm. */ /* Add the keys of the parameter in keypm. */
HashTable t = keypm->gets.hfn(keypm); HashTable t = keypm->gsu.h->getfn(keypm);
if (t) if (t)
scanhashtable(t, 0, 0, PM_UNSET, addhnmatch, 0); scanhashtable(t, 0, 0, PM_UNSET, addhnmatch, 0);

View file

@ -943,56 +943,82 @@ bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
* order of the CP_* bits in comp.h */ * order of the CP_* bits in comp.h */
#define VAL(X) ((void *) (&(X))) #define VAL(X) ((void *) (&(X)))
#define GSU(X) ((GsuScalar)(void *) (&(X)))
struct compparam { struct compparam {
char *name; char *name;
int type; int type;
void *var, *set, *get; void *var;
GsuScalar gsu;
}; };
static const struct gsu_scalar compvarscalar_gsu =
{ strvargetfn, strvarsetfn, compunsetfn };
static const struct gsu_scalar complist_gsu =
{ get_complist, set_complist, compunsetfn };
static const struct gsu_scalar unambig_gsu =
{ get_unambig, nullstrsetfn, compunsetfn };
static const struct gsu_scalar unambig_pos_gsu =
{ get_unambig_pos, nullstrsetfn, compunsetfn };
static const struct gsu_scalar insert_pos_gsu =
{ get_insert_pos, nullstrsetfn, compunsetfn };
static const struct gsu_integer compvarinteger_gsu =
{ intvargetfn, intvarsetfn, compunsetfn };
static const struct gsu_integer nmatches_gsu =
{ get_nmatches, NULL, compunsetfn };
static const struct gsu_integer unambig_curs_gsu =
{ get_unambig_curs, NULL, compunsetfn };
static const struct gsu_integer listlines_gsu =
{ get_listlines, NULL, compunsetfn };
static const struct gsu_array compvararray_gsu =
{ arrvargetfn, arrvarsetfn, compunsetfn };
static struct compparam comprparams[] = { static struct compparam comprparams[] = {
{ "words", PM_ARRAY, VAL(compwords), NULL, NULL }, { "words", PM_ARRAY, VAL(compwords), NULL },
{ "redirections", PM_ARRAY, VAL(compredirs), NULL, NULL }, { "redirections", PM_ARRAY, VAL(compredirs), NULL },
{ "CURRENT", PM_INTEGER, VAL(compcurrent), NULL, NULL }, { "CURRENT", PM_INTEGER, VAL(compcurrent), NULL },
{ "PREFIX", PM_SCALAR, VAL(compprefix), NULL, NULL }, { "PREFIX", PM_SCALAR, VAL(compprefix), NULL },
{ "SUFFIX", PM_SCALAR, VAL(compsuffix), NULL, NULL }, { "SUFFIX", PM_SCALAR, VAL(compsuffix), NULL },
{ "IPREFIX", PM_SCALAR, VAL(compiprefix), NULL, NULL }, { "IPREFIX", PM_SCALAR, VAL(compiprefix), NULL },
{ "ISUFFIX", PM_SCALAR, VAL(compisuffix), NULL, NULL }, { "ISUFFIX", PM_SCALAR, VAL(compisuffix), NULL },
{ "QIPREFIX", PM_SCALAR | PM_READONLY, VAL(compqiprefix), NULL, NULL }, { "QIPREFIX", PM_SCALAR | PM_READONLY, VAL(compqiprefix), NULL },
{ "QISUFFIX", PM_SCALAR | PM_READONLY, VAL(compqisuffix), NULL, NULL }, { "QISUFFIX", PM_SCALAR | PM_READONLY, VAL(compqisuffix), NULL },
{ NULL, 0, NULL, NULL, NULL } { NULL, 0, NULL, NULL }
}; };
static struct compparam compkparams[] = { static struct compparam compkparams[] = {
{ "nmatches", PM_INTEGER | PM_READONLY, NULL, NULL, VAL(get_nmatches) }, { "nmatches", PM_INTEGER | PM_READONLY, NULL, GSU(nmatches_gsu) },
{ "context", PM_SCALAR, VAL(compcontext), NULL, NULL }, { "context", PM_SCALAR, VAL(compcontext), NULL },
{ "parameter", PM_SCALAR, VAL(compparameter), NULL, NULL }, { "parameter", PM_SCALAR, VAL(compparameter), NULL },
{ "redirect", PM_SCALAR, VAL(compredirect), NULL, NULL }, { "redirect", PM_SCALAR, VAL(compredirect), NULL },
{ "quote", PM_SCALAR | PM_READONLY, VAL(compquote), NULL, NULL }, { "quote", PM_SCALAR | PM_READONLY, VAL(compquote), NULL },
{ "quoting", PM_SCALAR | PM_READONLY, VAL(compquoting), NULL, NULL }, { "quoting", PM_SCALAR | PM_READONLY, VAL(compquoting), NULL },
{ "restore", PM_SCALAR, VAL(comprestore), NULL, NULL }, { "restore", PM_SCALAR, VAL(comprestore), NULL },
{ "list", PM_SCALAR, NULL, VAL(set_complist), VAL(get_complist) }, { "list", PM_SCALAR, NULL, GSU(complist_gsu) },
{ "insert", PM_SCALAR, VAL(compinsert), NULL, NULL }, { "insert", PM_SCALAR, VAL(compinsert), NULL },
{ "exact", PM_SCALAR, VAL(compexact), NULL, NULL }, { "exact", PM_SCALAR, VAL(compexact), NULL },
{ "exact_string", PM_SCALAR, VAL(compexactstr), NULL, NULL }, { "exact_string", PM_SCALAR, VAL(compexactstr), NULL },
{ "pattern_match", PM_SCALAR, VAL(comppatmatch), NULL, NULL }, { "pattern_match", PM_SCALAR, VAL(comppatmatch), NULL },
{ "pattern_insert", PM_SCALAR, VAL(comppatinsert), NULL, NULL }, { "pattern_insert", PM_SCALAR, VAL(comppatinsert), NULL },
{ "unambiguous", PM_SCALAR | PM_READONLY, NULL, NULL, VAL(get_unambig) }, { "unambiguous", PM_SCALAR | PM_READONLY, NULL, GSU(unambig_gsu) },
{ "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL, NULL, { "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL,
VAL(get_unambig_curs) }, GSU(unambig_curs_gsu) },
{ "unambiguous_positions", PM_SCALAR | PM_READONLY, NULL, NULL, { "unambiguous_positions", PM_SCALAR | PM_READONLY, NULL,
VAL(get_unambig_pos) }, GSU(unambig_pos_gsu) },
{ "insert_positions", PM_SCALAR | PM_READONLY, NULL, NULL, { "insert_positions", PM_SCALAR | PM_READONLY, NULL,
VAL(get_insert_pos) }, GSU(insert_pos_gsu) },
{ "list_max", PM_INTEGER, VAL(complistmax), NULL, NULL }, { "list_max", PM_INTEGER, VAL(complistmax), NULL },
{ "last_prompt", PM_SCALAR, VAL(complastprompt), NULL, NULL }, { "last_prompt", PM_SCALAR, VAL(complastprompt), NULL },
{ "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL }, { "to_end", PM_SCALAR, VAL(comptoend), NULL },
{ "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL }, { "old_list", PM_SCALAR, VAL(compoldlist), NULL },
{ "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL }, { "old_insert", PM_SCALAR, VAL(compoldins), NULL },
{ "vared", PM_SCALAR, VAL(compvared), NULL, NULL }, { "vared", PM_SCALAR, VAL(compvared), NULL },
{ "list_lines", PM_INTEGER | PM_READONLY, NULL, NULL, VAL(get_listlines) }, { "list_lines", PM_INTEGER | PM_READONLY, NULL, GSU(listlines_gsu) },
{ "all_quotes", PM_SCALAR | PM_READONLY, VAL(compqstack), NULL, NULL }, { "all_quotes", PM_SCALAR | PM_READONLY, VAL(compqstack), NULL },
{ "ignored", PM_INTEGER | PM_READONLY, VAL(compignored), NULL, NULL }, { "ignored", PM_INTEGER | PM_READONLY, VAL(compignored), NULL },
{ NULL, 0, NULL, NULL, NULL } { NULL, 0, NULL, NULL }
}; };
#define COMPSTATENAME "compstate" #define COMPSTATENAME "compstate"
@ -1012,27 +1038,25 @@ addcompparams(struct compparam *cp, Param *pp)
if ((pm->u.data = cp->var)) { if ((pm->u.data = cp->var)) {
switch(PM_TYPE(cp->type)) { switch(PM_TYPE(cp->type)) {
case PM_SCALAR: case PM_SCALAR:
pm->sets.cfn = strvarsetfn; pm->gsu.s = &compvarscalar_gsu;
pm->gets.cfn = strvargetfn;
break; break;
case PM_INTEGER: case PM_INTEGER:
pm->sets.ifn = intvarsetfn; pm->gsu.i = &compvarinteger_gsu;
pm->gets.ifn = intvargetfn; pm->base = 10;
pm->ct = 10;
break; break;
case PM_ARRAY: case PM_ARRAY:
pm->sets.afn = arrvarsetfn; pm->gsu.a = &compvararray_gsu;
pm->gets.afn = arrvargetfn;
break; break;
} }
} else { } else {
pm->sets.cfn = (void (*) _((Param, char *))) cp->set; pm->gsu.s = cp->gsu;
pm->gets.cfn = (char *(*) _((Param))) cp->get;
} }
pm->unsetfn = compunsetfn;
} }
} }
static const struct gsu_hash compstate_gsu =
{ get_compstate, set_compstate, compunsetfn };
/**/ /**/
void void
makecompparams(void) makecompparams(void)
@ -1050,9 +1074,7 @@ makecompparams(void)
comprpms[CPN_COMPSTATE] = cpm; comprpms[CPN_COMPSTATE] = cpm;
tht = paramtab; tht = paramtab;
cpm->level = locallevel + 1; cpm->level = locallevel + 1;
cpm->gets.hfn = get_compstate; cpm->gsu.h = &compstate_gsu;
cpm->sets.hfn = set_compstate;
cpm->unsetfn = compunsetfn;
cpm->u.hash = paramtab = newparamtable(31, COMPSTATENAME); cpm->u.hash = paramtab = newparamtable(31, COMPSTATENAME);
addcompparams(compkparams, compkpms); addcompparams(compkparams, compkpms);
paramtab = tht; paramtab = tht;

View file

@ -3377,7 +3377,7 @@ bin_compquote(char *nam, char **args, Options ops, UNUSED(int func))
break; break;
case PM_ARRAY: case PM_ARRAY:
{ {
char **val = v->pm->gets.afn(v->pm); char **val = v->pm->gsu.a->getfn(v->pm);
char **new = (char **) zalloc((arrlen(val) + 1) * char **new = (char **) zalloc((arrlen(val) + 1) *
sizeof(char *)); sizeof(char *));
char **p = new; char **p = new;

View file

@ -44,60 +44,86 @@
* RBUFFER (scalar) portion of buffer to the right of the cursor * RBUFFER (scalar) portion of buffer to the right of the cursor
*/ */
#define FN(X) ( (void (*) _((void))) (X) ) static const struct gsu_scalar buffer_gsu =
{ get_buffer, set_buffer, zleunsetfn };
static const struct gsu_scalar context_gsu =
{ get_context, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar cutbuffer_gsu =
{ get_cutbuffer, set_cutbuffer, unset_cutbuffer };
static const struct gsu_scalar keymap_gsu =
{ get_keymap, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar keys_gsu =
{ get_keys, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar lastsearch_gsu =
{ get_lsearch, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar lastwidget_gsu =
{ get_lwidget, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar lbuffer_gsu =
{ get_lbuffer, set_lbuffer, zleunsetfn };
static const struct gsu_scalar postdisplay_gsu =
{ get_postdisplay, set_postdisplay, zleunsetfn };
static const struct gsu_scalar prebuffer_gsu =
{ get_prebuffer, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar predisplay_gsu =
{ get_predisplay, set_predisplay, zleunsetfn };
static const struct gsu_scalar rbuffer_gsu =
{ get_rbuffer, set_rbuffer, zleunsetfn };
static const struct gsu_scalar widget_gsu =
{ get_widget, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar widgetfunc_gsu =
{ get_widgetfunc, nullstrsetfn, zleunsetfn };
static const struct gsu_scalar widgetstyle_gsu =
{ get_widgetstyle, nullstrsetfn, zleunsetfn };
static const struct gsu_integer bufferlines_gsu =
{ get_bufferlines, NULL, zleunsetfn };
static const struct gsu_integer cursor_gsu =
{ get_cursor, set_cursor, zleunsetfn };
static const struct gsu_integer histno_gsu =
{ get_histno, set_histno, zleunsetfn };
static const struct gsu_integer mark_gsu =
{ get_mark, set_mark, zleunsetfn };
static const struct gsu_integer numeric_gsu =
{ get_numeric, set_numeric, unset_numeric };
static const struct gsu_integer pending_gsu =
{ get_pending, NULL, zleunsetfn };
static const struct gsu_array killring_gsu =
{ get_killring, set_killring, unset_killring };
#define GSU(X) ( (GsuScalar)(void*)(&(X)) )
static struct zleparam { static struct zleparam {
char *name; char *name;
int type; int type;
void (*setfn) _((void)); GsuScalar gsu;
void (*getfn) _((void));
void (*unsetfn) _((Param, int));
void *data; void *data;
} zleparams[] = { } zleparams[] = {
{ "BUFFER", PM_SCALAR, FN(set_buffer), FN(get_buffer), { "BUFFER", PM_SCALAR, GSU(buffer_gsu), NULL },
zleunsetfn, NULL }, { "BUFFERLINES", PM_INTEGER | PM_READONLY, GSU(bufferlines_gsu),
{ "BUFFERLINES", PM_INTEGER | PM_READONLY, NULL, FN(get_bufferlines), NULL },
zleunsetfn, NULL }, { "CONTEXT", PM_SCALAR | PM_READONLY, GSU(context_gsu),
{ "CONTEXT", PM_SCALAR | PM_READONLY, NULL, FN(get_context), NULL },
zleunsetfn, NULL }, { "CURSOR", PM_INTEGER, GSU(cursor_gsu),
{ "CURSOR", PM_INTEGER, FN(set_cursor), FN(get_cursor), NULL },
zleunsetfn, NULL }, { "CUTBUFFER", PM_SCALAR, GSU(cutbuffer_gsu), NULL },
{ "CUTBUFFER", PM_SCALAR, FN(set_cutbuffer), FN(get_cutbuffer), { "HISTNO", PM_INTEGER, GSU(histno_gsu), NULL },
unset_cutbuffer, NULL }, { "KEYMAP", PM_SCALAR | PM_READONLY, GSU(keymap_gsu), NULL },
{ "HISTNO", PM_INTEGER, FN(set_histno), FN(get_histno), { "KEYS", PM_SCALAR | PM_READONLY, GSU(keys_gsu), NULL },
zleunsetfn, NULL }, { "killring", PM_ARRAY, GSU(killring_gsu), NULL },
{ "KEYMAP", PM_SCALAR | PM_READONLY, NULL, FN(get_keymap), { "LASTSEARCH", PM_SCALAR | PM_READONLY, GSU(lastsearch_gsu), NULL },
zleunsetfn, NULL }, { "LASTWIDGET", PM_SCALAR | PM_READONLY, GSU(lastwidget_gsu), NULL },
{ "KEYS", PM_SCALAR | PM_READONLY, NULL, FN(get_keys), { "LBUFFER", PM_SCALAR, GSU(lbuffer_gsu), NULL },
zleunsetfn, NULL }, { "MARK", PM_INTEGER, GSU(mark_gsu), NULL },
{ "killring", PM_ARRAY, FN(set_killring), FN(get_killring), { "NUMERIC", PM_INTEGER | PM_UNSET, GSU(numeric_gsu), NULL },
unset_killring, NULL }, { "PENDING", PM_INTEGER | PM_READONLY, GSU(pending_gsu), NULL },
{ "LASTSEARCH", PM_SCALAR | PM_READONLY, NULL, FN(get_lsearch), { "POSTDISPLAY", PM_SCALAR, GSU(postdisplay_gsu), NULL },
zleunsetfn, NULL }, { "PREBUFFER", PM_SCALAR | PM_READONLY, GSU(prebuffer_gsu), NULL },
{ "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget), { "PREDISPLAY", PM_SCALAR, GSU(predisplay_gsu), NULL },
zleunsetfn, NULL }, { "RBUFFER", PM_SCALAR, GSU(rbuffer_gsu), NULL },
{ "LBUFFER", PM_SCALAR, FN(set_lbuffer), FN(get_lbuffer), { "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
zleunsetfn, NULL }, { "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
{ "MARK", PM_INTEGER, FN(set_mark), FN(get_mark), { "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },
zleunsetfn, NULL }, { NULL, 0, NULL, NULL }
{ "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric),
unset_numeric, NULL },
{ "PENDING", PM_INTEGER | PM_READONLY, NULL, FN(get_pending),
zleunsetfn, NULL },
{ "POSTDISPLAY", PM_SCALAR, FN(set_postdisplay), FN(get_postdisplay),
zleunsetfn, NULL },
{ "PREBUFFER", PM_SCALAR | PM_READONLY, NULL, FN(get_prebuffer),
zleunsetfn, NULL },
{ "PREDISPLAY", PM_SCALAR, FN(set_predisplay), FN(get_predisplay),
zleunsetfn, NULL },
{ "RBUFFER", PM_SCALAR, FN(set_rbuffer), FN(get_rbuffer),
zleunsetfn, NULL },
{ "WIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_widget),
zleunsetfn, NULL },
{ "WIDGETFUNC", PM_SCALAR | PM_READONLY, NULL, FN(get_widgetfunc),
zleunsetfn, NULL },
{ "WIDGETSTYLE", PM_SCALAR | PM_READONLY, NULL, FN(get_widgetstyle),
zleunsetfn, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL }
}; };
/**/ /**/
@ -117,20 +143,16 @@ makezleparams(int ro)
pm->u.data = zp->data; pm->u.data = zp->data;
switch(PM_TYPE(zp->type)) { switch(PM_TYPE(zp->type)) {
case PM_SCALAR: case PM_SCALAR:
pm->sets.cfn = (void (*) _((Param, char *))) zp->setfn; pm->gsu.s = zp->gsu;
pm->gets.cfn = (char *(*) _((Param))) zp->getfn;
break; break;
case PM_ARRAY: case PM_ARRAY:
pm->sets.afn = (void (*) _((Param, char **))) zp->setfn; pm->gsu.a = (GsuArray)zp->gsu;
pm->gets.afn = (char **(*) _((Param))) zp->getfn;
break; break;
case PM_INTEGER: case PM_INTEGER:
pm->sets.ifn = (void (*) _((Param, zlong))) zp->setfn; pm->gsu.i = (GsuInteger)zp->gsu;
pm->gets.ifn = (zlong (*) _((Param))) zp->getfn; pm->base = 10;
pm->ct = 10;
break; break;
} }
pm->unsetfn = zp->unsetfn;
if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT)) if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT))
pm->flags &= ~PM_UNSET; pm->flags &= ~PM_UNSET;
} }

View file

@ -51,11 +51,8 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
return NULL; return NULL;
pm->level = pm->old ? locallevel : 0; pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn; pm->gsu.h = &stdhash_gsu;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(0, name, NULL); pm->u.hash = ht = newhashtable(0, name, NULL);
pm->ct = 0;
ht->hash = hasher; ht->hash = hasher;
ht->emptytable = (TableFunc) shempty; ht->emptytable = (TableFunc) shempty;
@ -101,17 +98,11 @@ getpmwidgets(UNUSED(HashTable ht), char *name)
Param pm = NULL; Param pm = NULL;
Thingy th; Thingy th;
pm = (Param) zhalloc(sizeof(struct param)); pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name); pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY; pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL; pm->gsu.s = &nullsetscalar_gsu;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((th = (Thingy) thingytab->getnode(thingytab, name)) && if ((th = (Thingy) thingytab->getnode(thingytab, name)) &&
!(th->flags & DISABLED)) !(th->flags & DISABLED))
pm->u.str = widgetstr(th->widget); pm->u.str = widgetstr(th->widget);
@ -130,15 +121,9 @@ scanpmwidgets(UNUSED(HashTable ht), ScanFunc func, int flags)
int i; int i;
HashNode hn; HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY; pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL; pm.gsu.s = &nullsetscalar_gsu;
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 < thingytab->hsize; i++) for (i = 0; i < thingytab->hsize; i++)
for (hn = thingytab->nodes[i]; hn; hn = hn->next) { for (hn = thingytab->nodes[i]; hn; hn = hn->next) {
@ -177,21 +162,22 @@ struct pardef {
int flags; int flags;
GetNodeFunc getnfn; GetNodeFunc getnfn;
ScanTabFunc scantfn; ScanTabFunc scantfn;
void (*hsetfn) _((Param, HashTable)); GsuHash hash_gsu;
void (*setfn) _((Param, char **)); GsuArray array_gsu;
char **(*getfn) _((Param));
void (*unsetfn) _((Param, int));
Param pm; Param pm;
}; };
static const struct gsu_array keymaps_gsu =
{ keymapsgetfn, arrsetfn, stdunsetfn };
static struct pardef partab[] = { static struct pardef partab[] = {
{ "widgets", PM_READONLY, { "widgets", PM_READONLY,
getpmwidgets, scanpmwidgets, hashsetfn, getpmwidgets, scanpmwidgets, &stdhash_gsu,
NULL, NULL, stdunsetfn, NULL }, NULL, NULL },
{ "keymaps", PM_ARRAY|PM_SPECIAL|PM_READONLY, { "keymaps", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL, NULL, NULL, NULL,
arrsetfn, keymapsgetfn, stdunsetfn, NULL }, &keymaps_gsu, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL } { NULL, 0, NULL, NULL, NULL, NULL, NULL }
}; };
/**/ /**/
@ -215,14 +201,12 @@ boot_(UNUSED(Module m))
def->scantfn))) def->scantfn)))
return 1; return 1;
def->pm->flags |= def->flags; def->pm->flags |= def->flags;
if (def->hsetfn) if (def->hash_gsu)
def->pm->sets.hfn = def->hsetfn; def->pm->gsu.h = def->hash_gsu;
} else { } else {
if (!(def->pm = createparam(def->name, def->flags | PM_HIDE))) if (!(def->pm = createparam(def->name, def->flags | PM_HIDE)))
return 1; return 1;
def->pm->sets.afn = def->setfn; def->pm->gsu.a = def->array_gsu;
def->pm->gets.afn = def->getfn;
def->pm->unsetfn = def->unsetfn;
} }
} }
return 0; return 0;

View file

@ -71,7 +71,7 @@ static struct builtin builtins[] =
*/ */
BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpPa", NULL), BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpPa", NULL),
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL), BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%Hghlprtux", "E"), BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmtuUz", NULL), BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmtuUz", NULL),
BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"), BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL), BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
@ -82,7 +82,7 @@ static struct builtin builtins[] =
#endif #endif
BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEimpPa", "l"), BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEimpPa", "l"),
BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghi:%lprtux", "i"), BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lprtux", "i"),
BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL), BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL), BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
@ -1719,13 +1719,73 @@ enum {
NS_SECONDS NS_SECONDS
}; };
static const struct gsu_scalar tiedarr_gsu =
{ tiedarrgetfn, tiedarrsetfn, tiedarrunsetfn };
/* Install a base if we are turning on a numeric option with an argument */
static int
typeset_setbase(const char *name, Param pm, Options ops, int on, int always)
{
char *arg = NULL;
if ((on & PM_INTEGER) && OPT_HASARG(ops,'i'))
arg = OPT_ARG(ops,'i');
else if ((on & PM_EFLOAT) && OPT_HASARG(ops,'E'))
arg = OPT_ARG(ops,'E');
else if ((on & PM_FFLOAT) && OPT_HASARG(ops,'F'))
arg = OPT_ARG(ops,'F');
if (arg) {
char *eptr;
pm->base = (int)zstrtol(arg, &eptr, 10);
if (*eptr) {
if (on & PM_INTEGER)
zwarnnam(name, "bad base value: %s", arg, 0);
else
zwarnnam(name, "bad precision value: %s", arg, 0);
return 1;
}
} else if (always)
pm->base = 0;
return 0;
}
/* Install a width if we are turning on a padding option with an argument */
static int
typeset_setwidth(const char * name, Param pm, Options ops, int on, int always)
{
char *arg = NULL;
if ((on & PM_LEFT) && OPT_HASARG(ops,'L'))
arg = OPT_ARG(ops,'L');
else if ((on & PM_RIGHT_B) && OPT_HASARG(ops,'R'))
arg = OPT_ARG(ops,'R');
else if ((on & PM_RIGHT_Z) && OPT_HASARG(ops,'Z'))
arg = OPT_ARG(ops,'Z');
if (arg) {
char *eptr;
pm->width = (int)zstrtol(arg, &eptr, 10);
if (*eptr) {
zwarnnam(name, "bad width value: %s", arg, 0);
return 1;
}
} else if (always)
pm->width = 0;
return 0;
}
/* function to set a single parameter */ /* function to set a single parameter */
/**/ /**/
static Param static Param
typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
int on, int off, int roff, char *value, Param altpm, int on, int off, int roff, char *value, Param altpm,
Options ops, int auxlen, int joinchar) Options ops, int joinchar)
{ {
int usepm, tc, keeplocal = 0, newspecial = NS_NONE, readonly; int usepm, tc, keeplocal = 0, newspecial = NS_NONE, readonly;
char *subscript; char *subscript;
@ -1862,25 +1922,28 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
Param apm; Param apm;
char **x; char **x;
if (PM_TYPE(pm->flags) == PM_ARRAY) { if (PM_TYPE(pm->flags) == PM_ARRAY) {
x = (*pm->gets.afn)(pm); x = (*pm->gsu.a->getfn)(pm);
uniqarray(x); uniqarray(x);
if (pm->ename && x) if (pm->ename && x)
arrfixenv(pm->ename, x); arrfixenv(pm->ename, x);
} else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename && } else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename &&
(apm = (apm =
(Param) paramtab->getnode(paramtab, pm->ename))) { (Param) paramtab->getnode(paramtab, pm->ename))) {
x = (*apm->gets.afn)(apm); x = (*apm->gsu.a->getfn)(apm);
uniqarray(x); uniqarray(x);
if (x) if (x)
arrfixenv(pm->nam, x); arrfixenv(pm->nam, x);
} }
} }
pm->flags = (pm->flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET); pm->flags = (pm->flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET);
/* This auxlen/pm->ct stuff is a nasty hack. */ if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER | if (typeset_setwidth(cname, pm, ops, on, 0))
PM_EFLOAT | PM_FFLOAT)) && return NULL;
auxlen) }
pm->ct = auxlen; if (on & (PM_INTEGER | PM_EFLOAT | PM_FFLOAT)) {
if (typeset_setbase(cname, pm, ops, on, 0))
return NULL;
}
if (!(pm->flags & (PM_ARRAY|PM_HASHED))) { if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
if (pm->flags & PM_EXPORTED) { if (pm->flags & PM_EXPORTED) {
if (!(pm->flags & PM_UNSET) && !pm->env && !value) if (!(pm->flags & PM_UNSET) && !pm->env && !value)
@ -1960,7 +2023,8 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
} }
tpm->old = pm->old; tpm->old = pm->old;
tpm->level = pm->level; tpm->level = pm->level;
tpm->ct = pm->ct; tpm->base = pm->base;
tpm->width = pm->width;
if (pm->env) if (pm->env)
delenv(pm); delenv(pm);
tpm->env = NULL; tpm->env = NULL;
@ -1981,11 +2045,14 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
* Final tweak: if we've turned on one of the flags with * Final tweak: if we've turned on one of the flags with
* numbers, we should use the appropriate integer. * numbers, we should use the appropriate integer.
*/ */
if (on & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z|PM_INTEGER| if (on & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) {
PM_EFLOAT|PM_FFLOAT)) if (typeset_setwidth(cname, pm, ops, on, 1))
pm->ct = auxlen; return NULL;
else }
pm->ct = 0; if (on & (PM_INTEGER|PM_EFLOAT|PM_FFLOAT)) {
if (typeset_setbase(cname, pm, ops, on, 1))
return NULL;
}
} else if ((subscript = strchr(pname, '['))) { } else if ((subscript = strchr(pname, '['))) {
if (on & PM_READONLY) { if (on & PM_READONLY) {
zerrnam(cname, zerrnam(cname,
@ -2027,7 +2094,14 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
*/ */
pm = createparam(pname, on & ~PM_READONLY); pm = createparam(pname, on & ~PM_READONLY);
DPUTS(!pm, "BUG: parameter not created"); DPUTS(!pm, "BUG: parameter not created");
pm->ct = auxlen; if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
if (typeset_setwidth(cname, pm, ops, on, 0))
return NULL;
}
if (on & (PM_INTEGER | PM_EFLOAT | PM_FFLOAT)) {
if (typeset_setbase(cname, pm, ops, on, 0))
return NULL;
}
} else { } else {
if (isident(pname)) if (isident(pname))
zerrnam(cname, "not valid in this context: %s", pname, 0); zerrnam(cname, "not valid in this context: %s", pname, 0);
@ -2049,9 +2123,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
tdp->joinchar = joinchar; tdp->joinchar = joinchar;
tdp->arrptr = &altpm->u.arr; tdp->arrptr = &altpm->u.arr;
pm->sets.cfn = tiedarrsetfn; pm->gsu.s = &tiedarr_gsu;
pm->gets.cfn = tiedarrgetfn;
pm->unsetfn = tiedarrunsetfn;
pm->u.data = tdp; pm->u.data = tdp;
} }
@ -2075,20 +2147,20 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
*/ */
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
pm->sets.cfn(pm, ztrdup("")); pm->gsu.s->setfn(pm, ztrdup(""));
break; break;
case PM_INTEGER: case PM_INTEGER:
pm->sets.ifn(pm, 0); pm->gsu.i->setfn(pm, 0);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
pm->sets.ffn(pm, 0.0); pm->gsu.f->setfn(pm, 0.0);
break; break;
case PM_ARRAY: case PM_ARRAY:
pm->sets.afn(pm, mkarray(NULL)); pm->gsu.a->setfn(pm, mkarray(NULL));
break; break;
case PM_HASHED: case PM_HASHED:
pm->sets.hfn(pm, newparamtable(17, pm->nam)); pm->gsu.h->setfn(pm, newparamtable(17, pm->nam));
break; break;
} }
} }
@ -2118,7 +2190,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
char *optstr = TYPESET_OPTSTR; char *optstr = TYPESET_OPTSTR;
int on = 0, off = 0, roff, bit = PM_ARRAY; int on = 0, off = 0, roff, bit = PM_ARRAY;
int i; int i;
int returnval = 0, printflags = 0, auxlen = 0; int returnval = 0, printflags = 0;
/* hash -f is really the builtin `functions' */ /* hash -f is really the builtin `functions' */
if (OPT_ISSET(ops,'f')) if (OPT_ISSET(ops,'f'))
@ -2134,43 +2206,27 @@ bin_typeset(char *name, char **argv, Options ops, int func)
on |= bit; on |= bit;
else if (OPT_PLUS(ops,optval)) else if (OPT_PLUS(ops,optval))
off |= bit; off |= bit;
/*
* There is only a single field in struct param for widths,
* precisions and bases. Until this gets fixed, we can therefore
* bundle all optional arguments up into a single word. You
* may think this is very nasty, but then you should have seen the
* code before option arguments were handled properly.
*/
if (OPT_HASARG(ops,optval)) {
char *eptr, *arg = OPT_ARG(ops,optval);
auxlen = (int)zstrtol(arg, &eptr, 10);
if (*eptr) {
zwarnnam(name, "bad integer value: %s", arg, 0);
return 1;
}
}
} }
roff = off; roff = off;
/* Sanity checks on the options. Remove conflicting options. */ /* Sanity checks on the options. Remove conflicting options. */
if (on & PM_FFLOAT) { if (on & PM_FFLOAT) {
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY | off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_INTEGER | PM_EFLOAT;
PM_HASHED | PM_INTEGER | PM_EFLOAT;
/* Allow `float -F' to work even though float sets -E by default */ /* Allow `float -F' to work even though float sets -E by default */
on &= ~PM_EFLOAT; on &= ~PM_EFLOAT;
} }
if (on & PM_EFLOAT) if (on & PM_EFLOAT)
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY | off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_INTEGER | PM_FFLOAT;
PM_HASHED | PM_INTEGER | PM_FFLOAT;
if (on & PM_INTEGER) if (on & PM_INTEGER)
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY | off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_EFLOAT | PM_FFLOAT;
PM_HASHED | PM_EFLOAT | PM_FFLOAT; /*
if (on & PM_LEFT) * Allowing -Z with -L is a feature: left justify, suppressing
off |= PM_RIGHT_B | PM_INTEGER | PM_EFLOAT | PM_FFLOAT; * leading zeroes.
*/
if (on & (PM_LEFT|PM_RIGHT_Z))
off |= PM_RIGHT_B;
if (on & PM_RIGHT_B) if (on & PM_RIGHT_B)
off |= PM_LEFT | PM_INTEGER | PM_EFLOAT | PM_FFLOAT; off |= PM_LEFT | PM_RIGHT_Z;
if (on & PM_RIGHT_Z)
off |= PM_INTEGER | PM_EFLOAT | PM_FFLOAT;
if (on & PM_UPPER) if (on & PM_UPPER)
off |= PM_LOWER; off |= PM_LOWER;
if (on & PM_LOWER) if (on & PM_LOWER)
@ -2279,8 +2335,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
(Param)paramtab->getnode(paramtab, (Param)paramtab->getnode(paramtab,
asg->name), asg->name),
func, (on | PM_ARRAY) & ~PM_EXPORTED, func, (on | PM_ARRAY) & ~PM_EXPORTED,
off, roff, asg->value, NULL, ops, auxlen, off, roff, asg->value, NULL, ops, 0))) {
0))) {
unqueue_signals(); unqueue_signals();
return 1; return 1;
} }
@ -2292,7 +2347,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
(Param)paramtab->getnode(paramtab, (Param)paramtab->getnode(paramtab,
asg0.name), asg0.name),
func, on, off, roff, asg0.value, apm, func, on, off, roff, asg0.value, apm,
ops, auxlen, joinchar))) { ops, joinchar))) {
if (oldval) if (oldval)
zsfree(oldval); zsfree(oldval);
unsetparam_pm(apm, 1, 1); unsetparam_pm(apm, 1, 1);
@ -2367,7 +2422,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) { for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
pm = (Param) getdata(pmnode); pm = (Param) getdata(pmnode);
if (!typeset_single(name, pm->nam, pm, func, on, off, roff, if (!typeset_single(name, pm->nam, pm, func, on, off, roff,
asg->value, NULL, ops, auxlen, 0)) asg->value, NULL, ops, 0))
returnval = 1; returnval = 1;
} }
} }
@ -2382,7 +2437,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
gethashnode2(paramtab, asg->name) : gethashnode2(paramtab, asg->name) :
paramtab->getnode(paramtab, asg->name)), paramtab->getnode(paramtab, asg->name)),
func, on, off, roff, asg->value, NULL, func, on, off, roff, asg->value, NULL,
ops, auxlen, 0)) ops, 0))
returnval = 1; returnval = 1;
} }
unqueue_signals(); unqueue_signals();
@ -2681,7 +2736,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
} else if (ss) { } else if (ss) {
if (PM_TYPE(pm->flags) == PM_HASHED) { if (PM_TYPE(pm->flags) == PM_HASHED) {
HashTable tht = paramtab; HashTable tht = paramtab;
if ((paramtab = pm->gets.hfn(pm))) { if ((paramtab = pm->gsu.h->getfn(pm))) {
*--sse = 0; *--sse = 0;
unsetparam(ss+1); unsetparam(ss+1);
*sse = ']'; *sse = ']';

View file

@ -2592,20 +2592,20 @@ restore_params(LinkList restorelist, LinkList removelist)
tpm->flags = pm->flags; tpm->flags = pm->flags;
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
tpm->sets.cfn(tpm, pm->u.str); tpm->gsu.s->setfn(tpm, pm->u.str);
break; break;
case PM_INTEGER: case PM_INTEGER:
tpm->sets.ifn(tpm, pm->u.val); tpm->gsu.i->setfn(tpm, pm->u.val);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
tpm->sets.ffn(tpm, pm->u.dval); tpm->gsu.f->setfn(tpm, pm->u.dval);
break; break;
case PM_ARRAY: case PM_ARRAY:
tpm->sets.afn(tpm, pm->u.arr); tpm->gsu.a->setfn(tpm, pm->u.arr);
break; break;
case PM_HASHED: case PM_HASHED:
tpm->sets.hfn(tpm, pm->u.hash); tpm->gsu.h->setfn(tpm, pm->u.hash);
break; break;
} }
pm = tpm; pm = tpm;

View file

@ -1894,9 +1894,7 @@ addparamdef(Paramdef d)
pm->level = 0; pm->level = 0;
pm->u.data = d->var; pm->u.data = d->var;
pm->sets.ifn = (void (*)(Param, zlong)) d->set; pm->gsu.i = (GsuInteger) d->gsu;
pm->gets.ifn = (zlong (*)(Param)) d->get;
pm->unsetfn = (void (*)(Param, int)) d->unset;
return 0; return 0;
} }

View file

@ -106,10 +106,114 @@ struct timeval shtimer;
/* 0 if this $TERM setup is usable, otherwise it contains TERM_* flags */ /* 0 if this $TERM setup is usable, otherwise it contains TERM_* flags */
/**/ /**/
mod_export int termflags; mod_export int termflags;
/* Standard methods for get/set/unset pointers in parameters */
/**/
mod_export const struct gsu_scalar stdscalar_gsu =
{ strgetfn, strsetfn, stdunsetfn };
/**/
mod_export const struct gsu_scalar varscalar_gsu =
{ strvargetfn, strvarsetfn, stdunsetfn };
/**/
mod_export const struct gsu_scalar nullsetscalar_gsu =
{ strgetfn, nullstrsetfn, NULL };
/**/
mod_export const struct gsu_integer stdinteger_gsu =
{ intgetfn, intsetfn, stdunsetfn };
/**/
mod_export const struct gsu_integer varinteger_gsu =
{ intvargetfn, intvarsetfn, stdunsetfn };
/**/
mod_export const struct gsu_integer nullsetinteger_gsu =
{ intgetfn, NULL, NULL };
/**/
mod_export const struct gsu_float stdfloat_gsu =
{ floatgetfn, floatsetfn, stdunsetfn };
/**/
mod_export const struct gsu_array stdarray_gsu =
{ arrgetfn, arrsetfn, stdunsetfn };
/**/
mod_export const struct gsu_array vararray_gsu =
{ arrvargetfn, arrvarsetfn, stdunsetfn };
/**/
mod_export const struct gsu_hash stdhash_gsu =
{ hashgetfn, hashsetfn, stdunsetfn };
/**/
mod_export const struct gsu_hash nullsethash_gsu =
{ hashgetfn, nullsethashfn, NULL };
/* Non standard methods (not exported) */
static const struct gsu_integer pound_gsu =
{ poundgetfn, nullintsetfn, stdunsetfn };
static const struct gsu_integer errno_gsu =
{ errnogetfn, errnosetfn, stdunsetfn };
static const struct gsu_integer gid_gsu =
{ gidgetfn, gidsetfn, stdunsetfn };
static const struct gsu_integer egid_gsu =
{ egidgetfn, egidsetfn, stdunsetfn };
static const struct gsu_integer histsize_gsu =
{ histsizegetfn, histsizesetfn, stdunsetfn };
static const struct gsu_integer random_gsu =
{ randomgetfn, randomsetfn, stdunsetfn };
static const struct gsu_integer savehist_gsu =
{ savehistsizegetfn, savehistsizesetfn, stdunsetfn };
static const struct gsu_integer intseconds_gsu =
{ intsecondsgetfn, intsecondssetfn, stdunsetfn };
static const struct gsu_float floatseconds_gsu =
{ floatsecondsgetfn, floatsecondssetfn, stdunsetfn };
static const struct gsu_integer uid_gsu =
{ uidgetfn, uidsetfn, stdunsetfn };
static const struct gsu_integer euid_gsu =
{ euidgetfn, euidsetfn, stdunsetfn };
static const struct gsu_integer ttyidle_gsu =
{ ttyidlegetfn, nullintsetfn, stdunsetfn };
static const struct gsu_scalar username_gsu =
{ usernamegetfn, usernamesetfn, stdunsetfn };
static const struct gsu_scalar dash_gsu =
{ dashgetfn, nullstrsetfn, stdunsetfn };
static const struct gsu_scalar histchars_gsu =
{ histcharsgetfn, histcharssetfn, stdunsetfn };
static const struct gsu_scalar home_gsu =
{ homegetfn, homesetfn, stdunsetfn };
static const struct gsu_scalar term_gsu =
{ termgetfn, termsetfn, stdunsetfn };
static const struct gsu_scalar wordchars_gsu =
{ wordcharsgetfn, wordcharssetfn, stdunsetfn };
static const struct gsu_scalar ifs_gsu =
{ ifsgetfn, ifssetfn, stdunsetfn };
static const struct gsu_scalar underscore_gsu =
{ underscoregetfn, nullstrsetfn, stdunsetfn };
#ifdef USE_LOCALE
static const struct gsu_scalar lc_blah_gsu =
{ strgetfn, lcsetfn, stdunsetfn };
static const struct gsu_scalar lang_gsu =
{ strgetfn, langsetfn, stdunsetfn };
static const struct gsu_scalar lc_all_gsu =
{ strgetfn, lc_allsetfn, stdunsetfn };
#endif
static const struct gsu_integer varint_readonly_gsu =
{ intvargetfn, nullintsetfn, stdunsetfn };
static const struct gsu_integer zlevar_gsu =
{ intvargetfn, zlevarsetfn, stdunsetfn };
static const struct gsu_scalar colonarr_gsu =
{ colonarrgetfn, colonarrsetfn, stdunsetfn };
static const struct gsu_integer argc_gsu =
{ poundgetfn, nullintsetfn, stdunsetfn };
static const struct gsu_array pipestatus_gsu =
{ pipestatgetfn, pipestatsetfn, stdunsetfn };
/* Nodes for special parameters for parameter hash table */ /* Nodes for special parameters for parameter hash table */
#ifdef HAVE_UNION_INIT #ifdef HAVE_UNION_INIT
@ -122,10 +226,9 @@ typedef struct iparam {
char *nam; /* hash data */ char *nam; /* hash data */
int flags; /* PM_* flags (defined in zsh.h) */ int flags; /* PM_* flags (defined in zsh.h) */
void *value; void *value;
void (*func1) _((void)); /* set func */ void *gsu; /* get/set/unset methods */
char *(*func2) _((void)); /* get func */ int base; /* output base */
void (*unsetfn) _((Param, int)); /* unset func */ int width; /* output field width */
int ct; /* output base or field width */
char *env; /* location in environment, if exported */ char *env; /* location in environment, if exported */
char *ename; /* name of corresponding environment var */ char *ename; /* name of corresponding environment var */
Param old; /* old struct for use with local */ Param old; /* old struct for use with local */
@ -134,35 +237,35 @@ typedef struct iparam {
#endif #endif
static initparam special_params[] ={ static initparam special_params[] ={
#define SFN(X) BR(((void (*)_((Param, char *)))(X))) #define GSU(X) BR((GsuScalar)(void *)(&(X)))
#define GFN(X) BR(((char *(*)_((Param)))(X))) #define NULL_GSU BR((GsuScalar)(void *)NULL)
#define IPDEF1(A,B,C,D) {NULL,A,PM_INTEGER|PM_SPECIAL|D,BR(NULL),SFN(C),GFN(B),stdunsetfn,10,NULL,NULL,NULL,0} #define IPDEF1(A,B,C) {NULL,A,PM_INTEGER|PM_SPECIAL|C,BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0}
IPDEF1("#", poundgetfn, nullintsetfn, PM_READONLY), IPDEF1("#", pound_gsu, PM_READONLY),
IPDEF1("ERRNO", errnogetfn, errnosetfn, 0), IPDEF1("ERRNO", errno_gsu, 0),
IPDEF1("GID", gidgetfn, gidsetfn, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EGID", egidgetfn, egidsetfn, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("EGID", egid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("HISTSIZE", histsizegetfn, histsizesetfn, PM_RESTRICTED), IPDEF1("HISTSIZE", histsize_gsu, PM_RESTRICTED),
IPDEF1("RANDOM", randomgetfn, randomsetfn, 0), IPDEF1("RANDOM", random_gsu, 0),
IPDEF1("SAVEHIST", savehistsizegetfn, savehistsizesetfn, PM_RESTRICTED), IPDEF1("SAVEHIST", savehist_gsu, PM_RESTRICTED),
IPDEF1("SECONDS", intsecondsgetfn, intsecondssetfn, 0), IPDEF1("SECONDS", intseconds_gsu, 0),
IPDEF1("UID", uidgetfn, uidsetfn, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EUID", euidgetfn, euidsetfn, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("TTYIDLE", ttyidlegetfn, nullintsetfn, PM_READONLY), IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY),
#define IPDEF2(A,B,C,D) {NULL,A,PM_SCALAR|PM_SPECIAL|D,BR(NULL),SFN(C),GFN(B),stdunsetfn,0,NULL,NULL,NULL,0} #define IPDEF2(A,B,C) {NULL,A,PM_SCALAR|PM_SPECIAL|C,BR(NULL),GSU(B),0,0,NULL,NULL,NULL,0}
IPDEF2("USERNAME", usernamegetfn, usernamesetfn, PM_DONTIMPORT|PM_RESTRICTED), IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED),
IPDEF2("-", dashgetfn, nullstrsetfn, PM_READONLY), IPDEF2("-", dash_gsu, PM_READONLY),
IPDEF2("histchars", histcharsgetfn, histcharssetfn, PM_DONTIMPORT), IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
IPDEF2("HOME", homegetfn, homesetfn, 0), IPDEF2("HOME", home_gsu, 0),
IPDEF2("TERM", termgetfn, termsetfn, 0), IPDEF2("TERM", term_gsu, 0),
IPDEF2("WORDCHARS", wordcharsgetfn, wordcharssetfn, 0), IPDEF2("WORDCHARS", wordchars_gsu, 0),
IPDEF2("IFS", ifsgetfn, ifssetfn, PM_DONTIMPORT), IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT),
IPDEF2("_", underscoregetfn, nullstrsetfn, PM_READONLY), IPDEF2("_", underscore_gsu, PM_READONLY),
#ifdef USE_LOCALE #ifdef USE_LOCALE
# define LCIPDEF(name) IPDEF2(name, strgetfn, lcsetfn, PM_UNSET) # define LCIPDEF(name) IPDEF2(name, lc_blah_gsu, PM_UNSET)
IPDEF2("LANG", strgetfn, langsetfn, PM_UNSET), IPDEF2("LANG", lang_gsu, PM_UNSET),
IPDEF2("LC_ALL", strgetfn, lc_allsetfn, PM_UNSET), IPDEF2("LC_ALL", lc_all_gsu, PM_UNSET),
# ifdef LC_COLLATE # ifdef LC_COLLATE
LCIPDEF("LC_COLLATE"), LCIPDEF("LC_COLLATE"),
# endif # endif
@ -180,7 +283,7 @@ LCIPDEF("LC_TIME"),
# endif # endif
#endif /* USE_LOCALE */ #endif /* USE_LOCALE */
#define IPDEF4(A,B) {NULL,A,PM_INTEGER|PM_READONLY|PM_SPECIAL,BR((void *)B),SFN(nullintsetfn),GFN(intvargetfn),stdunsetfn,10,NULL,NULL,NULL,0} #define IPDEF4(A,B) {NULL,A,PM_INTEGER|PM_READONLY|PM_SPECIAL,BR((void *)B),GSU(varint_readonly_gsu),10,0,NULL,NULL,NULL,0}
IPDEF4("!", &lastpid), IPDEF4("!", &lastpid),
IPDEF4("$", &mypid), IPDEF4("$", &mypid),
IPDEF4("?", &lastval), IPDEF4("?", &lastval),
@ -188,14 +291,14 @@ IPDEF4("HISTCMD", &curhist),
IPDEF4("LINENO", &lineno), IPDEF4("LINENO", &lineno),
IPDEF4("PPID", &ppid), IPDEF4("PPID", &ppid),
#define IPDEF5(A,B,F) {NULL,A,PM_INTEGER|PM_SPECIAL,BR((void *)B),SFN(F),GFN(intvargetfn),stdunsetfn,10,NULL,NULL,NULL,0} #define IPDEF5(A,B,F) {NULL,A,PM_INTEGER|PM_SPECIAL,BR((void *)B),GSU(varinteger_gsu),10,0,NULL,NULL,NULL,0}
IPDEF5("COLUMNS", &columns, zlevarsetfn), IPDEF5("COLUMNS", &columns, zlevar_gsu),
IPDEF5("LINES", &lines, zlevarsetfn), IPDEF5("LINES", &lines, zlevar_gsu),
IPDEF5("OPTIND", &zoptind, intvarsetfn), IPDEF5("OPTIND", &zoptind, varinteger_gsu),
IPDEF5("SHLVL", &shlvl, intvarsetfn), IPDEF5("SHLVL", &shlvl, varinteger_gsu),
IPDEF5("TRY_BLOCK_ERROR", &try_errflag, intvarsetfn), IPDEF5("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
#define IPDEF7(A,B) {NULL,A,PM_SCALAR|PM_SPECIAL,BR((void *)B),SFN(strvarsetfn),GFN(strvargetfn),stdunsetfn,0,NULL,NULL,NULL,0} #define IPDEF7(A,B) {NULL,A,PM_SCALAR|PM_SPECIAL,BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
IPDEF7("OPTARG", &zoptarg), IPDEF7("OPTARG", &zoptarg),
IPDEF7("NULLCMD", &nullcmd), IPDEF7("NULLCMD", &nullcmd),
IPDEF7("POSTEDIT", &postedit), IPDEF7("POSTEDIT", &postedit),
@ -211,7 +314,7 @@ IPDEF7("PS4", &prompt4),
IPDEF7("SPROMPT", &sprompt), IPDEF7("SPROMPT", &sprompt),
IPDEF7("0", &argzero), IPDEF7("0", &argzero),
#define IPDEF8(A,B,C,D) {NULL,A,D|PM_SCALAR|PM_SPECIAL,BR((void *)B),SFN(colonarrsetfn),GFN(colonarrgetfn),stdunsetfn,0,NULL,C,NULL,0} #define IPDEF8(A,B,C,D) {NULL,A,D|PM_SCALAR|PM_SPECIAL,BR((void *)B),GSU(colonarr_gsu),0,0,NULL,C,NULL,0}
IPDEF8("CDPATH", &cdpath, "cdpath", 0), IPDEF8("CDPATH", &cdpath, "cdpath", 0),
IPDEF8("FIGNORE", &fignore, "fignore", 0), IPDEF8("FIGNORE", &fignore, "fignore", 0),
IPDEF8("FPATH", &fpath, "fpath", 0), IPDEF8("FPATH", &fpath, "fpath", 0),
@ -223,18 +326,18 @@ IPDEF8("PSVAR", &psvar, "psvar", 0),
/* MODULE_PATH is not imported for security reasons */ /* MODULE_PATH is not imported for security reasons */
IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED), IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED),
#define IPDEF9F(A,B,C,D) {NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT,BR((void *)B),SFN(arrvarsetfn),GFN(arrvargetfn),stdunsetfn,0,NULL,C,NULL,0} #define IPDEF9F(A,B,C,D) {NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT,BR((void *)B),GSU(vararray_gsu),0,0,NULL,C,NULL,0}
#define IPDEF9(A,B,C) IPDEF9F(A,B,C,0) #define IPDEF9(A,B,C) IPDEF9F(A,B,C,0)
IPDEF9F("*", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY), IPDEF9F("*", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY),
IPDEF9F("@", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY), IPDEF9F("@", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY),
{NULL,NULL,0,BR(NULL),SFN(NULL),GFN(NULL),NULL,0,NULL,NULL,NULL,0}, {NULL,NULL,0,BR(NULL),NULL_GSU,0,0,NULL,NULL,NULL,0},
#define IPDEF10(A,B,C) {NULL,A,PM_ARRAY|PM_SPECIAL,BR(NULL),SFN(C),GFN(B),stdunsetfn,10,NULL,NULL,NULL,0} #define IPDEF10(A,B) {NULL,A,PM_ARRAY|PM_SPECIAL,BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0}
/* The following parameters are not available in sh/ksh compatibility * /* The following parameters are not available in sh/ksh compatibility *
* mode. All of these have sh compatible equivalents. */ * mode. All of these have sh compatible equivalents. */
IPDEF1("ARGC", poundgetfn, nullintsetfn, PM_READONLY), IPDEF1("ARGC", argc_gsu, PM_READONLY),
IPDEF2("HISTCHARS", histcharsgetfn, histcharssetfn, PM_DONTIMPORT), IPDEF2("HISTCHARS", histchars_gsu, PM_DONTIMPORT),
IPDEF4("status", &lastval), IPDEF4("status", &lastval),
IPDEF7("prompt", &prompt), IPDEF7("prompt", &prompt),
IPDEF7("PROMPT", &prompt), IPDEF7("PROMPT", &prompt),
@ -254,9 +357,9 @@ IPDEF9("watch", &watch, "WATCH"),
IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED), IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED),
IPDEF9F("path", &path, "PATH", PM_RESTRICTED), IPDEF9F("path", &path, "PATH", PM_RESTRICTED),
IPDEF10("pipestatus", pipestatgetfn, pipestatsetfn), IPDEF10("pipestatus", pipestatus_gsu),
{NULL,NULL,0,BR(NULL),SFN(NULL),GFN(NULL),NULL,0,NULL,NULL,NULL,0}, {NULL,NULL,0,BR(NULL),NULL_GSU,0,0,NULL,NULL,NULL,0},
}; };
/* /*
@ -456,9 +559,9 @@ getvaluearr(Value v)
if (v->arr) if (v->arr)
return v->arr; return v->arr;
else if (PM_TYPE(v->pm->flags) == PM_ARRAY) else if (PM_TYPE(v->pm->flags) == PM_ARRAY)
return v->arr = v->pm->gets.afn(v->pm); return v->arr = v->pm->gsu.a->getfn(v->pm);
else if (PM_TYPE(v->pm->flags) == PM_HASHED) { else if (PM_TYPE(v->pm->flags) == PM_HASHED) {
v->arr = paramvalarr(v->pm->gets.hfn(v->pm), v->isarr); v->arr = paramvalarr(v->pm->gsu.h->getfn(v->pm), v->isarr);
/* Can't take numeric slices of associative arrays */ /* Can't take numeric slices of associative arrays */
v->start = 0; v->start = 0;
v->end = numparamvals + 1; v->end = numparamvals + 1;
@ -631,31 +734,25 @@ assigngetset(Param pm)
{ {
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
pm->sets.cfn = strsetfn; pm->gsu.s = &stdscalar_gsu;
pm->gets.cfn = strgetfn;
break; break;
case PM_INTEGER: case PM_INTEGER:
pm->sets.ifn = intsetfn; pm->gsu.i = &stdinteger_gsu;
pm->gets.ifn = intgetfn;
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
pm->sets.ffn = floatsetfn; pm->gsu.f = &stdfloat_gsu;
pm->gets.ffn = floatgetfn;
break; break;
case PM_ARRAY: case PM_ARRAY:
pm->sets.afn = arrsetfn; pm->gsu.a = &stdarray_gsu;
pm->gets.afn = arrgetfn;
break; break;
case PM_HASHED: case PM_HASHED:
pm->sets.hfn = hashsetfn; pm->gsu.h = &stdhash_gsu;
pm->gets.hfn = hashgetfn;
break; break;
default: default:
DPUTS(1, "BUG: tried to create param node without valid flag"); DPUTS(1, "BUG: tried to create param node without valid flag");
break; break;
} }
pm->unsetfn = stdunsetfn;
} }
/* Create a parameter, so that it can be assigned to. Returns NULL if the * /* Create a parameter, so that it can be assigned to. Returns NULL if the *
@ -699,7 +796,7 @@ createparam(char *name, int flags)
} }
pm = oldpm; pm = oldpm;
pm->ct = 0; pm->base = pm->width = 0;
oldpm = pm->old; oldpm = pm->old;
} else { } else {
pm = (Param) zshcalloc(sizeof *pm); pm = (Param) zshcalloc(sizeof *pm);
@ -741,25 +838,26 @@ copyparam(Param tpm, Param pm, int toplevel)
* with sets.?fn() usage). * with sets.?fn() usage).
*/ */
tpm->flags = pm->flags; tpm->flags = pm->flags;
tpm->ct = pm->ct; tpm->base = pm->base;
tpm->width = pm->width;
if (!toplevel) if (!toplevel)
tpm->flags &= ~PM_SPECIAL; tpm->flags &= ~PM_SPECIAL;
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
tpm->u.str = ztrdup(pm->gets.cfn(pm)); tpm->u.str = ztrdup(pm->gsu.s->getfn(pm));
break; break;
case PM_INTEGER: case PM_INTEGER:
tpm->u.val = pm->gets.ifn(pm); tpm->u.val = pm->gsu.i->getfn(pm);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
tpm->u.dval = pm->gets.ffn(pm); tpm->u.dval = pm->gsu.f->getfn(pm);
break; break;
case PM_ARRAY: case PM_ARRAY:
tpm->u.arr = zarrdup(pm->gets.afn(pm)); tpm->u.arr = zarrdup(pm->gsu.a->getfn(pm));
break; break;
case PM_HASHED: case PM_HASHED:
tpm->u.hash = copyparamtable(pm->gets.hfn(pm), pm->nam); tpm->u.hash = copyparamtable(pm->gsu.h->getfn(pm), pm->nam);
break; break;
} }
/* /*
@ -985,10 +1083,10 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
remnulargs(s); /* This is probably always a no-op, but ... */ remnulargs(s); /* This is probably always a no-op, but ... */
if (!rev) { if (!rev) {
if (ishash) { if (ishash) {
HashTable ht = v->pm->gets.hfn(v->pm); HashTable ht = v->pm->gsu.h->getfn(v->pm);
if (!ht) { if (!ht) {
ht = newparamtable(17, v->pm->nam); ht = newparamtable(17, v->pm->nam);
v->pm->sets.hfn(v->pm, ht); v->pm->gsu.h->setfn(v->pm, ht);
} }
untokenize(s); untokenize(s);
if (!(v->pm = (Param) ht->getnode(ht, s))) { if (!(v->pm = (Param) ht->getnode(ht, s))) {
@ -1447,15 +1545,16 @@ getstrvalue(Value v)
} }
return s; return s;
case PM_INTEGER: case PM_INTEGER:
convbase(buf, v->pm->gets.ifn(v->pm), v->pm->ct); convbase(buf, v->pm->gsu.i->getfn(v->pm), v->pm->base);
s = dupstring(buf); s = dupstring(buf);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
s = convfloat(v->pm->gets.ffn(v->pm), v->pm->ct, v->pm->flags, NULL); s = convfloat(v->pm->gsu.f->getfn(v->pm),
v->pm->base, v->pm->flags, NULL);
break; break;
case PM_SCALAR: case PM_SCALAR:
s = v->pm->gets.cfn(v->pm); s = v->pm->gsu.s->getfn(v->pm);
break; break;
default: default:
s = NULL; s = NULL;
@ -1526,9 +1625,9 @@ getintvalue(Value v)
if (v->inv) if (v->inv)
return v->start; return v->start;
if (PM_TYPE(v->pm->flags) == PM_INTEGER) if (PM_TYPE(v->pm->flags) == PM_INTEGER)
return v->pm->gets.ifn(v->pm); return v->pm->gsu.i->getfn(v->pm);
if (v->pm->flags & (PM_EFLOAT|PM_FFLOAT)) if (v->pm->flags & (PM_EFLOAT|PM_FFLOAT))
return (zlong)v->pm->gets.ffn(v->pm); return (zlong)v->pm->gsu.f->getfn(v->pm);
return mathevali(getstrvalue(v)); return mathevali(getstrvalue(v));
} }
@ -1544,10 +1643,10 @@ getnumvalue(Value v)
} else if (v->inv) { } else if (v->inv) {
mn.u.l = v->start; mn.u.l = v->start;
} else if (PM_TYPE(v->pm->flags) == PM_INTEGER) { } else if (PM_TYPE(v->pm->flags) == PM_INTEGER) {
mn.u.l = v->pm->gets.ifn(v->pm); mn.u.l = v->pm->gsu.i->getfn(v->pm);
} else if (v->pm->flags & (PM_EFLOAT|PM_FFLOAT)) { } else if (v->pm->flags & (PM_EFLOAT|PM_FFLOAT)) {
mn.type = MN_FLOAT; mn.type = MN_FLOAT;
mn.u.d = v->pm->gets.ffn(v->pm); mn.u.d = v->pm->gsu.f->getfn(v->pm);
} else } else
return matheval(getstrvalue(v)); return matheval(getstrvalue(v));
return mn; return mn;
@ -1572,12 +1671,12 @@ export_param(Param pm)
#endif #endif
return; return;
} else if (PM_TYPE(pm->flags) == PM_INTEGER) } else if (PM_TYPE(pm->flags) == PM_INTEGER)
convbase(val = buf, pm->gets.ifn(pm), pm->ct); convbase(val = buf, pm->gsu.i->getfn(pm), pm->base);
else if (pm->flags & (PM_EFLOAT|PM_FFLOAT)) else if (pm->flags & (PM_EFLOAT|PM_FFLOAT))
val = convfloat(pm->gets.ffn(pm), pm->ct, val = convfloat(pm->gsu.f->getfn(pm), pm->base,
pm->flags, NULL); pm->flags, NULL);
else else
val = pm->gets.cfn(pm); val = pm->gsu.s->getfn(pm);
addenv(pm, val); addenv(pm, val);
} }
@ -1605,14 +1704,15 @@ setstrvalue(Value v, char *val)
switch (PM_TYPE(v->pm->flags)) { switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
if (v->start == 0 && v->end == -1) { if (v->start == 0 && v->end == -1) {
(v->pm->sets.cfn) (v->pm, val); v->pm->gsu.s->setfn(v->pm, val);
if (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z) && !v->pm->ct) if ((v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
v->pm->ct = strlen(val); !v->pm->width)
v->pm->width = strlen(val);
} else { } else {
char *z, *x; char *z, *x;
int zlen; int zlen;
z = dupstring((v->pm->gets.cfn) (v->pm)); z = dupstring(v->pm->gsu.s->getfn(v->pm));
zlen = strlen(z); zlen = strlen(z);
if (v->inv && unset(KSHARRAYS)) if (v->inv && unset(KSHARRAYS))
v->start--, v->end--; v->start--, v->end--;
@ -1631,25 +1731,31 @@ setstrvalue(Value v, char *val)
strncpy(x, z, v->start); strncpy(x, z, v->start);
strcpy(x + v->start, val); strcpy(x + v->start, val);
strcat(x + v->start, z + v->end); strcat(x + v->start, z + v->end);
(v->pm->sets.cfn) (v->pm, x); v->pm->gsu.s->setfn(v->pm, x);
zsfree(val); zsfree(val);
} }
break; break;
case PM_INTEGER: case PM_INTEGER:
if (val) { if (val) {
(v->pm->sets.ifn) (v->pm, mathevali(val)); v->pm->gsu.i->setfn(v->pm, mathevali(val));
zsfree(val); zsfree(val);
if ((v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
!v->pm->width)
v->pm->width = strlen(val);
} }
if (!v->pm->ct && lastbase != -1) if (!v->pm->base && lastbase != -1)
v->pm->ct = lastbase; v->pm->base = lastbase;
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
if (val) { if (val) {
mnumber mn = matheval(val); mnumber mn = matheval(val);
(v->pm->sets.ffn) (v->pm, (mn.type & MN_FLOAT) ? mn.u.d : v->pm->gsu.f->setfn(v->pm, (mn.type & MN_FLOAT) ? mn.u.d :
(double)mn.u.l); (double)mn.u.l);
zsfree(val); zsfree(val);
if ((v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
!v->pm->width)
v->pm->width = strlen(val);
} }
break; break;
case PM_ARRAY: case PM_ARRAY:
@ -1663,7 +1769,7 @@ setstrvalue(Value v, char *val)
break; break;
case PM_HASHED: case PM_HASHED:
{ {
(foundparam->sets.cfn) (foundparam, val); foundparam->gsu.s->setfn(foundparam, val);
} }
break; break;
} }
@ -1700,14 +1806,14 @@ setnumvalue(Value v, mnumber val)
setstrvalue(v, ztrdup(p)); setstrvalue(v, ztrdup(p));
break; break;
case PM_INTEGER: case PM_INTEGER:
(v->pm->sets.ifn) (v->pm, (val.type & MN_INTEGER) ? val.u.l : v->pm->gsu.i->setfn(v->pm, (val.type & MN_INTEGER) ? val.u.l :
(zlong) val.u.d); (zlong) val.u.d);
setstrvalue(v, NULL); setstrvalue(v, NULL);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
(v->pm->sets.ffn) (v->pm, (val.type & MN_INTEGER) ? v->pm->gsu.f->setfn(v->pm, (val.type & MN_INTEGER) ?
(double)val.u.l : val.u.d); (double)val.u.l : val.u.d);
setstrvalue(v, NULL); setstrvalue(v, NULL);
break; break;
} }
@ -1737,7 +1843,7 @@ setarrvalue(Value v, char **val)
if (PM_TYPE(v->pm->flags) == PM_HASHED) if (PM_TYPE(v->pm->flags) == PM_HASHED)
arrhashsetfn(v->pm, val, 0); arrhashsetfn(v->pm, val, 0);
else else
(v->pm->sets.afn) (v->pm, val); v->pm->gsu.a->setfn(v->pm, val);
} else if (v->start == -1 && v->end == 0 && } else if (v->start == -1 && v->end == 0 &&
PM_TYPE(v->pm->flags) == PM_HASHED) { PM_TYPE(v->pm->flags) == PM_HASHED) {
arrhashsetfn(v->pm, val, 1); arrhashsetfn(v->pm, val, 1);
@ -1758,7 +1864,7 @@ setarrvalue(Value v, char **val)
} }
if (v->end < v->start) if (v->end < v->start)
v->end = v->start; v->end = v->start;
q = old = v->pm->gets.afn(v->pm); q = old = v->pm->gsu.a->getfn(v->pm);
n = arrlen(old); n = arrlen(old);
if (v->start < 0) { if (v->start < 0) {
v->start += n; v->start += n;
@ -1786,7 +1892,7 @@ setarrvalue(Value v, char **val)
*p++ = ztrdup(*q++); *p++ = ztrdup(*q++);
*p = NULL; *p = NULL;
(v->pm->sets.afn) (v->pm, new); v->pm->gsu.a->setfn(v->pm, new);
freearray(val); freearray(val);
} }
} }
@ -1848,7 +1954,7 @@ getaparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
PM_TYPE(v->pm->flags) == PM_ARRAY) PM_TYPE(v->pm->flags) == PM_ARRAY)
return v->pm->gets.afn(v->pm); return v->pm->gsu.a->getfn(v->pm);
return NULL; return NULL;
} }
@ -1863,7 +1969,7 @@ gethparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
PM_TYPE(v->pm->flags) == PM_HASHED) PM_TYPE(v->pm->flags) == PM_HASHED)
return paramvalarr(v->pm->gets.hfn(v->pm), SCANPM_WANTVALS); return paramvalarr(v->pm->gsu.h->getfn(v->pm), SCANPM_WANTVALS);
return NULL; return NULL;
} }
@ -1878,7 +1984,7 @@ gethkparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
PM_TYPE(v->pm->flags) == PM_HASHED) PM_TYPE(v->pm->flags) == PM_HASHED)
return paramvalarr(v->pm->gets.hfn(v->pm), SCANPM_WANTKEYS); return paramvalarr(v->pm->gsu.h->getfn(v->pm), SCANPM_WANTKEYS);
return NULL; return NULL;
} }
@ -1952,7 +2058,7 @@ assignsparam(char *s, char *val, int augment)
return v->pm; /* avoid later setstrvalue() call */ return v->pm; /* avoid later setstrvalue() call */
case PM_ARRAY: case PM_ARRAY:
if (unset(KSHARRAYS)) { if (unset(KSHARRAYS)) {
v->start = arrlen(v->pm->gets.afn(v->pm)); v->start = arrlen(v->pm->gsu.a->getfn(v->pm));
v->end = v->start + 1; v->end = v->start + 1;
} else { } else {
/* ksh appends scalar to first element */ /* ksh appends scalar to first element */
@ -1967,7 +2073,7 @@ assignsparam(char *s, char *val, int augment)
if (v->end > 0) if (v->end > 0)
v->start = v->end; v->start = v->end;
else else
v->start = v->end = strlen(v->pm->gets.cfn(v->pm)) + v->start = v->end = strlen(v->pm->gsu.s->getfn(v->pm)) +
v->end + 1; v->end + 1;
break; break;
case PM_INTEGER: case PM_INTEGER:
@ -2064,7 +2170,7 @@ assignaparam(char *s, char **val, int augment)
if (augment) { if (augment) {
if (v->start == 0 && v->end == -1) { if (v->start == 0 && v->end == -1) {
if (PM_TYPE(v->pm->flags) & PM_ARRAY) { if (PM_TYPE(v->pm->flags) & PM_ARRAY) {
v->start = arrlen(v->pm->gets.afn(v->pm)); v->start = arrlen(v->pm->gsu.a->getfn(v->pm));
v->end = v->start + 1; v->end = v->start + 1;
} else if (PM_TYPE(v->pm->flags) & PM_HASHED) } else if (PM_TYPE(v->pm->flags) & PM_HASHED)
v->start = -1, v->end = 0; v->start = -1, v->end = 0;
@ -2072,7 +2178,7 @@ assignaparam(char *s, char **val, int augment)
if (v->end > 0) if (v->end > 0)
v->start = v->end--; v->start = v->end--;
else if (PM_TYPE(v->pm->flags) & PM_ARRAY) { else if (PM_TYPE(v->pm->flags) & PM_ARRAY) {
v->end = arrlen(v->pm->gets.afn(v->pm)) + v->end; v->end = arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end;
v->start = v->end + 1; v->start = v->end + 1;
} }
} }
@ -2147,7 +2253,7 @@ setiparam(char *s, zlong val)
if (ss) { if (ss) {
*ss = '['; *ss = '[';
} else { } else {
pm->ct = outputradix; pm->base = outputradix;
} }
v = getvalue(&vbuf, &t, 1); v = getvalue(&vbuf, &t, 1);
DPUTS(!v, "BUG: value not found for new parameter"); DPUTS(!v, "BUG: value not found for new parameter");
@ -2190,7 +2296,7 @@ setnparam(char *s, mnumber val)
if (ss) { if (ss) {
*ss = '['; *ss = '[';
} else if (val.type & MN_INTEGER) { } else if (val.type & MN_INTEGER) {
pm->ct = outputradix; pm->base = outputradix;
} }
v = getvalue(&vbuf, &t, 1); v = getvalue(&vbuf, &t, 1);
DPUTS(!v, "BUG: value not found for new parameter"); DPUTS(!v, "BUG: value not found for new parameter");
@ -2232,7 +2338,7 @@ unsetparam_pm(Param pm, int altflag, int exp)
zerr("%s: restricted", pm->nam, 0); zerr("%s: restricted", pm->nam, 0);
return 1; return 1;
} }
pm->unsetfn(pm, exp); pm->gsu.s->unsetfn(pm, exp);
if (pm->env) if (pm->env)
delenv(pm); delenv(pm);
@ -2281,7 +2387,7 @@ unsetparam_pm(Param pm, int altflag, int exp)
if ((PM_TYPE(oldpm->flags) == PM_SCALAR) && if ((PM_TYPE(oldpm->flags) == PM_SCALAR) &&
!(pm->flags & PM_HASHELEM) && !(pm->flags & PM_HASHELEM) &&
(oldpm->flags & PM_NAMEDDIR) && (oldpm->flags & PM_NAMEDDIR) &&
oldpm->sets.cfn == strsetfn) oldpm->gsu.s == &stdscalar_gsu)
adduserdir(oldpm->nam, oldpm->u.str, 0, 0); adduserdir(oldpm->nam, oldpm->u.str, 0, 0);
if (oldpm->flags & PM_EXPORTED) { if (oldpm->flags & PM_EXPORTED) {
/* /*
@ -2300,16 +2406,20 @@ unsetparam_pm(Param pm, int altflag, int exp)
} }
/* Standard function to unset a parameter. This is mostly delegated to * /* Standard function to unset a parameter. This is mostly delegated to *
* the specific set function. */ * the specific set function.
*
* This could usefully be made type-specific, but then we need
* to be more careful when calling the unset method directly.
*/
/**/ /**/
mod_export void mod_export void
stdunsetfn(Param pm, UNUSED(int exp)) stdunsetfn(Param pm, UNUSED(int exp))
{ {
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: pm->sets.cfn(pm, NULL); break; case PM_SCALAR: pm->gsu.s->setfn(pm, NULL); break;
case PM_ARRAY: pm->sets.afn(pm, NULL); break; case PM_ARRAY: pm->gsu.a->setfn(pm, NULL); break;
case PM_HASHED: pm->sets.hfn(pm, NULL); break; case PM_HASHED: pm->gsu.h->setfn(pm, NULL); break;
default: default:
if (!(pm->flags & PM_SPECIAL)) if (!(pm->flags & PM_SPECIAL))
pm->u.str = NULL; pm->u.str = NULL;
@ -2425,6 +2535,15 @@ hashsetfn(Param pm, HashTable x)
pm->u.hash = x; pm->u.hash = x;
} }
/* Function to dispose of setting of an unsettable hash */
/**/
mod_export void
nullsethashfn(Param pm, HashTable x)
{
deleteparamtable(x);
}
/* Function to set value of an association parameter using key/value pairs */ /* Function to set value of an association parameter using key/value pairs */
/**/ /**/
@ -2433,7 +2552,7 @@ arrhashsetfn(Param pm, char **val, int augment)
{ {
/* Best not to shortcut this by using the existing hash table, * /* Best not to shortcut this by using the existing hash table, *
* since that could cause trouble for special hashes. This way, * * since that could cause trouble for special hashes. This way, *
* it's up to pm->sets.hfn() what to do. */ * it's up to pm->gsu.h->setfn() what to do. */
int alen = arrlen(val); int alen = arrlen(val);
HashTable opmtab = paramtab, ht = 0; HashTable opmtab = paramtab, ht = 0;
char **aptr = val; char **aptr = val;
@ -2447,7 +2566,7 @@ arrhashsetfn(Param pm, char **val, int augment)
return; return;
} }
if (alen) if (alen)
if (!(augment && (ht = paramtab = pm->gets.hfn(pm)))) if (!(augment && (ht = paramtab = pm->gsu.h->getfn(pm))))
ht = paramtab = newparamtable(17, pm->nam); ht = paramtab = newparamtable(17, pm->nam);
while (*aptr) { while (*aptr) {
/* The parameter name is ztrdup'd... */ /* The parameter name is ztrdup'd... */
@ -2463,7 +2582,7 @@ arrhashsetfn(Param pm, char **val, int augment)
setstrvalue(v, *aptr++); setstrvalue(v, *aptr++);
} }
paramtab = opmtab; paramtab = opmtab;
pm->sets.hfn(pm, ht); pm->gsu.h->setfn(pm, ht);
free(val); /* not freearray() */ free(val); /* not freearray() */
} }
@ -2671,7 +2790,7 @@ tiedarrunsetfn(Param pm, UNUSED(int exp))
* in typeset_single to hold the special data which we now * in typeset_single to hold the special data which we now
* need to delete. * need to delete.
*/ */
pm->sets.cfn(pm, NULL); pm->gsu.s->setfn(pm, NULL);
zfree(pm->u.data, sizeof(struct tieddata)); zfree(pm->u.data, sizeof(struct tieddata));
/* paranoia -- shouldn't need these, but in case we reuse the struct... */ /* paranoia -- shouldn't need these, but in case we reuse the struct... */
pm->u.data = NULL; pm->u.data = NULL;
@ -2822,13 +2941,11 @@ setsecondstype(Param pm, int on, int off)
/* Only one of the numeric types is allowed. */ /* Only one of the numeric types is allowed. */
if (tp == PM_EFLOAT || tp == PM_FFLOAT) if (tp == PM_EFLOAT || tp == PM_FFLOAT)
{ {
pm->gets.ffn = floatsecondsgetfn; pm->gsu.f = &floatseconds_gsu;
pm->sets.ffn = floatsecondssetfn;
} }
else if (tp == PM_INTEGER) else if (tp == PM_INTEGER)
{ {
pm->gets.ifn = intsecondsgetfn; pm->gsu.i = &intseconds_gsu;
pm->sets.ifn = intsecondssetfn;
} }
else else
return 1; return 1;
@ -2881,10 +2998,10 @@ uidgetfn(UNUSED(Param pm))
/**/ /**/
void void
uidsetfn(UNUSED(Param pm), uid_t x) uidsetfn(UNUSED(Param pm), zlong x)
{ {
#ifdef HAVE_SETUID #ifdef HAVE_SETUID
setuid(x); setuid((uid_t)x);
#endif #endif
} }
@ -2901,10 +3018,10 @@ euidgetfn(UNUSED(Param pm))
/**/ /**/
void void
euidsetfn(UNUSED(Param pm), uid_t x) euidsetfn(UNUSED(Param pm), zlong x)
{ {
#ifdef HAVE_SETEUID #ifdef HAVE_SETEUID
seteuid(x); seteuid((uid_t)x);
#endif #endif
} }
@ -2921,10 +3038,10 @@ gidgetfn(UNUSED(Param pm))
/**/ /**/
void void
gidsetfn(UNUSED(Param pm), gid_t x) gidsetfn(UNUSED(Param pm), zlong x)
{ {
#ifdef HAVE_SETUID #ifdef HAVE_SETUID
setgid(x); setgid((gid_t)x);
#endif #endif
} }
@ -2941,10 +3058,10 @@ egidgetfn(UNUSED(Param pm))
/**/ /**/
void void
egidsetfn(UNUSED(Param pm), gid_t x) egidsetfn(UNUSED(Param pm), zlong x)
{ {
#ifdef HAVE_SETEUID #ifdef HAVE_SETEUID
setegid(x); setegid((gid_t)x);
#endif #endif
} }
@ -3650,27 +3767,28 @@ scanendscope(HashNode hn, UNUSED(int flags))
pm->old = tpm->old; pm->old = tpm->old;
pm->flags = (tpm->flags & ~PM_NORESTORE); pm->flags = (tpm->flags & ~PM_NORESTORE);
pm->level = tpm->level; pm->level = tpm->level;
pm->ct = tpm->ct; pm->base = tpm->base;
pm->width = tpm->width;
if (pm->env) if (pm->env)
delenv(pm); delenv(pm);
if (!(tpm->flags & PM_NORESTORE)) if (!(tpm->flags & PM_NORESTORE))
switch (PM_TYPE(pm->flags)) { switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
pm->sets.cfn(pm, tpm->u.str); pm->gsu.s->setfn(pm, tpm->u.str);
break; break;
case PM_INTEGER: case PM_INTEGER:
pm->sets.ifn(pm, tpm->u.val); pm->gsu.i->setfn(pm, tpm->u.val);
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
pm->sets.ffn(pm, tpm->u.dval); pm->gsu.f->setfn(pm, tpm->u.dval);
break; break;
case PM_ARRAY: case PM_ARRAY:
pm->sets.afn(pm, tpm->u.arr); pm->gsu.a->setfn(pm, tpm->u.arr);
break; break;
case PM_HASHED: case PM_HASHED:
pm->sets.hfn(pm, tpm->u.hash); pm->gsu.h->setfn(pm, tpm->u.hash);
break; break;
} }
zfree(tpm, sizeof(*tpm)); zfree(tpm, sizeof(*tpm));
@ -3696,7 +3814,7 @@ freeparamnode(HashNode hn)
/* Since the second flag to unsetfn isn't used, I don't * /* Since the second flag to unsetfn isn't used, I don't *
* know what its value should be. */ * know what its value should be. */
if (delunset) if (delunset)
pm->unsetfn(pm, 1); pm->gsu.s->unsetfn(pm, 1);
zsfree(pm->nam); zsfree(pm->nam);
/* If this variable was tied by the user, ename was ztrdup'd */ /* If this variable was tied by the user, ename was ztrdup'd */
if (pm->flags & PM_TIED) if (pm->flags & PM_TIED)
@ -3707,8 +3825,9 @@ freeparamnode(HashNode hn)
/* Print a parameter */ /* Print a parameter */
enum paramtypes_flags { enum paramtypes_flags {
PMTF_USE_CT = (1<<0), PMTF_USE_BASE = (1<<0),
PMTF_TEST_LEVEL = (1<<1) PMTF_USE_WIDTH = (1<<1),
PMTF_TEST_LEVEL = (1<<2)
}; };
struct paramtypes { struct paramtypes {
@ -3720,15 +3839,15 @@ struct paramtypes {
static const struct paramtypes pmtypes[] = { static const struct paramtypes pmtypes[] = {
{ PM_AUTOLOAD, "undefined", 0, 0}, { PM_AUTOLOAD, "undefined", 0, 0},
{ PM_INTEGER, "integer", 'i', PMTF_USE_CT}, { PM_INTEGER, "integer", 'i', PMTF_USE_BASE},
{ PM_EFLOAT, "float", 'E', 0}, { PM_EFLOAT, "float", 'E', 0},
{ PM_FFLOAT, "float", 'F', 0}, { PM_FFLOAT, "float", 'F', 0},
{ PM_ARRAY, "array", 'a', 0}, { PM_ARRAY, "array", 'a', 0},
{ PM_HASHED, "association", 'A', 0}, { PM_HASHED, "association", 'A', 0},
{ 0, "local", 0, PMTF_TEST_LEVEL}, { 0, "local", 0, PMTF_TEST_LEVEL},
{ PM_LEFT, "left justified", 'L', PMTF_USE_CT}, { PM_LEFT, "left justified", 'L', PMTF_USE_WIDTH},
{ PM_RIGHT_B, "right justified", 'R', PMTF_USE_CT}, { PM_RIGHT_B, "right justified", 'R', PMTF_USE_WIDTH},
{ PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_CT}, { PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_WIDTH},
{ PM_LOWER, "lowercase", 'l', 0}, { PM_LOWER, "lowercase", 'l', 0},
{ PM_UPPER, "uppercase", 'u', 0}, { PM_UPPER, "uppercase", 'u', 0},
{ PM_READONLY, "readonly", 'r', 0}, { PM_READONLY, "readonly", 'r', 0},
@ -3776,8 +3895,12 @@ printparamnode(HashNode hn, int printflags)
} else { } else {
printf("%s ", pmptr->string); printf("%s ", pmptr->string);
} }
if ((pmptr->flags & PMTF_USE_CT) && p->ct) { if ((pmptr->flags & PMTF_USE_BASE) && p->base) {
printf("%d ", p->ct); printf("%d ", p->base);
doneminus = 0;
}
if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) {
printf("%d ", p->width);
doneminus = 0; doneminus = 0;
} }
} }
@ -3812,27 +3935,27 @@ printparamnode(HashNode hn, int printflags)
switch (PM_TYPE(p->flags)) { switch (PM_TYPE(p->flags)) {
case PM_SCALAR: case PM_SCALAR:
/* string: simple output */ /* string: simple output */
if (p->gets.cfn && (t = p->gets.cfn(p))) if (p->gsu.s->getfn && (t = p->gsu.s->getfn(p)))
quotedzputs(t, stdout); quotedzputs(t, stdout);
break; break;
case PM_INTEGER: case PM_INTEGER:
/* integer */ /* integer */
#ifdef ZSH_64_BIT_TYPE #ifdef ZSH_64_BIT_TYPE
fputs(output64(p->gets.ifn(p)), stdout); fputs(output64(p->gsu.i->getfn(p)), stdout);
#else #else
printf("%ld", p->gets.ifn(p)); printf("%ld", p->gsu.i->getfn(p));
#endif #endif
break; break;
case PM_EFLOAT: case PM_EFLOAT:
case PM_FFLOAT: case PM_FFLOAT:
/* float */ /* float */
convfloat(p->gets.ffn(p), p->ct, p->flags, stdout); convfloat(p->gsu.f->getfn(p), p->base, p->flags, stdout);
break; break;
case PM_ARRAY: case PM_ARRAY:
/* array */ /* array */
if (!(printflags & PRINT_KV_PAIR)) if (!(printflags & PRINT_KV_PAIR))
putchar('('); putchar('(');
u = p->gets.afn(p); u = p->gsu.a->getfn(p);
if(*u) { if(*u) {
quotedzputs(*u++, stdout); quotedzputs(*u++, stdout);
while (*u) { while (*u) {
@ -3848,7 +3971,7 @@ printparamnode(HashNode hn, int printflags)
if (!(printflags & PRINT_KV_PAIR)) if (!(printflags & PRINT_KV_PAIR))
putchar('('); putchar('(');
{ {
HashTable ht = p->gets.hfn(p); HashTable ht = p->gsu.h->getfn(p);
if (ht) if (ht)
scanhashtable(ht, 0, 0, PM_UNSET, scanhashtable(ht, 0, 0, PM_UNSET,
ht->printnode, PRINT_KV_PAIR); ht->printnode, PRINT_KV_PAIR);

View file

@ -1649,7 +1649,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
* necessary joining of arrays until this point * necessary joining of arrays until this point
* to avoid the multsub() horror. * to avoid the multsub() horror.
*/ */
int tmplen = arrlen(v->pm->gets.afn(v->pm)); int tmplen = arrlen(v->pm->gsu.a->getfn(v->pm));
if (v->start < 0) if (v->start < 0)
v->start += tmplen + v->inv; v->start += tmplen + v->inv;
@ -1667,7 +1667,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
* Bet that's easier said than done. * Bet that's easier said than done.
*/ */
val = getstrvalue(v); val = getstrvalue(v);
fwidth = v->pm->ct ? v->pm->ct : (int)strlen(val); fwidth = v->pm->width ? v->pm->width : (int)strlen(val);
switch (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { switch (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
char *t; char *t;
unsigned int t0; unsigned int t0;
@ -1695,17 +1695,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
int zero = 1; int zero = 1;
if (strlen(val) < fwidth) { if (strlen(val) < fwidth) {
char *valprefend = val;
if (v->pm->flags & PM_RIGHT_Z) { if (v->pm->flags & PM_RIGHT_Z) {
for (t = val; iblank(*t); t++); /*
if (!*t || !idigit(*t)) * This is a documented feature: when deciding
* whether to pad with zeroes, ignore
* leading blanks already in the value;
* only look for numbers after that.
* Not sure how useful this really is.
* It's certainly confusing to code around.
*/
for (t = val; iblank(*t); t++)
;
/*
* Allow padding after initial minus
* for numeric variables.
*/
if ((v->pm->flags &
(PM_INTEGER|PM_EFLOAT|PM_FFLOAT)) &&
*t == '-')
t++;
/*
* Allow padding after initial 0x or
* base# for integer variables.
*/
if (v->pm->flags & PM_INTEGER) {
if (isset(CBASES) &&
t[0] == '0' && t[1] == 'x')
t += 2;
else if ((valprefend = strchr(t, '#')))
t = valprefend + 1;
}
valprefend = t;
if (!*t)
zero = 0;
else if (v->pm->flags &
(PM_INTEGER|PM_EFLOAT|PM_FFLOAT)) {
/* zero always OK */
} else if (!idigit(*t))
zero = 0; zero = 0;
} }
t = (char *) hcalloc(fwidth + 1); t = (char *) hcalloc(fwidth + 1);
memset(t, (((v->pm->flags & PM_RIGHT_B) || !zero) ? memset(t, (((v->pm->flags & PM_RIGHT_B) || !zero) ?
' ' : '0'), fwidth); ' ' : '0'), fwidth);
/*
* How can the following trigger? We
* haven't altered val or fwidth since
* the last time we tested this.
*/
if ((t0 = strlen(val)) > fwidth) if ((t0 = strlen(val)) > fwidth)
t0 = fwidth; t0 = fwidth;
strcpy(t + (fwidth - t0), val); /*
* Copy - or 0x or base# before any padding
* zeroes.
*/
if (zero && val != valprefend) {
int preflen = valprefend - val;
memcpy(t, val, preflen);
strcpy(t + (fwidth - t0) + preflen,
valprefend);
} else
strcpy(t + (fwidth - t0), val);
val = t; val = t;
} else { } else {
t = (char *) hcalloc(fwidth + 1); t = (char *) hcalloc(fwidth + 1);
@ -2019,7 +2069,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
if (arrasg > 1) { if (arrasg > 1) {
Param pm = sethparam(idbeg, a); Param pm = sethparam(idbeg, a);
if (pm) if (pm)
aval = paramvalarr(pm->gets.hfn(pm), hkeys|hvals); aval = paramvalarr(pm->gsu.h->getfn(pm), hkeys|hvals);
} else } else
setaparam(idbeg, a); setaparam(idbeg, a);
} else { } else {

View file

@ -1123,6 +1123,49 @@ struct patprog {
#define dummy_patprog1 ((Patprog) 1) #define dummy_patprog1 ((Patprog) 1)
#define dummy_patprog2 ((Patprog) 2) #define dummy_patprog2 ((Patprog) 2)
/* standard node types for get/set/unset union in parameter */
/*
* note non-standard const in pointer declaration: structures are
* assumed to be read-only.
*/
typedef const struct gsu_scalar *GsuScalar;
typedef const struct gsu_integer *GsuInteger;
typedef const struct gsu_float *GsuFloat;
typedef const struct gsu_array *GsuArray;
typedef const struct gsu_hash *GsuHash;
struct gsu_scalar {
char *(*getfn) _((Param));
void (*setfn) _((Param, char *));
void (*unsetfn) _((Param, int));
};
struct gsu_integer {
zlong (*getfn) _((Param));
void (*setfn) _((Param, zlong));
void (*unsetfn) _((Param, int));
};
struct gsu_float {
double (*getfn) _((Param));
void (*setfn) _((Param, double));
void (*unsetfn) _((Param, int));
};
struct gsu_array {
char **(*getfn) _((Param));
void (*setfn) _((Param, char **));
void (*unsetfn) _((Param, int));
};
struct gsu_hash {
HashTable (*getfn) _((Param));
void (*setfn) _((Param, HashTable));
void (*unsetfn) _((Param, int));
};
/* node used in parameter hash table (paramtab) */ /* node used in parameter hash table (paramtab) */
struct param { struct param {
@ -1142,28 +1185,24 @@ struct param {
HashTable hash; /* value if declared assoc (PM_HASHED) */ HashTable hash; /* value if declared assoc (PM_HASHED) */
} u; } u;
/* pointer to function to set value of this parameter */ /*
* get/set/unset methods.
*
* Unlike the data union, this points to a single instance
* for every type (although there are special types, e.g.
* tied arrays have a different gsu_scalar struct from the
* normal one). It's really a poor man's vtable.
*/
union { union {
void (*cfn) _((Param, char *)); GsuScalar s;
void (*ifn) _((Param, zlong)); GsuInteger i;
void (*ffn) _((Param, double)); GsuFloat f;
void (*afn) _((Param, char **)); GsuArray a;
void (*hfn) _((Param, HashTable)); GsuHash h;
} sets; } gsu;
/* pointer to function to get value of this parameter */ int base; /* output base or floating point prec */
union { int width; /* field width */
char *(*cfn) _((Param));
zlong (*ifn) _((Param));
double (*ffn) _((Param));
char **(*afn) _((Param));
HashTable (*hfn) _((Param));
} gets;
/* pointer to function to unset this parameter */
void (*unsetfn) _((Param, int));
int ct; /* output base or field width */
char *env; /* location in environment, if exported */ char *env; /* location in environment, if exported */
char *ename; /* name of corresponding environment var */ char *ename; /* name of corresponding environment var */
Param old; /* old struct for use with local */ Param old; /* old struct for use with local */
@ -1272,22 +1311,17 @@ struct paramdef {
char *name; char *name;
int flags; int flags;
void *var; void *var;
void *set; void *gsu; /* get/set/unset structure */
void *get;
void *unset;
}; };
#define PARAMDEF(name, flags, var, set, get, unset) \ #define PARAMDEF(name, flags, var, gsu) \
{ name, flags, (void *) var, (void *) set, (void *) get, (void *) unset } { name, flags, (void *) var, (void *) gsu, }
#define INTPARAMDEF(name, var) \ #define INTPARAMDEF(name, var) \
{ name, PM_INTEGER, (void *) var, (void *) intvarsetfn, \ { name, PM_INTEGER, (void *) var, (void *) &stdinteger_gsu }
(void *) intvargetfn, (void *) stdunsetfn }
#define STRPARAMDEF(name, var) \ #define STRPARAMDEF(name, var) \
{ name, PM_SCALAR, (void *) var, (void *) strvarsetfn, \ { name, PM_SCALAR, (void *) var, (void *) &varscalar_gsu }
(void *) strvargetfn, (void *) stdunsetfn }
#define ARRPARAMDEF(name, var) \ #define ARRPARAMDEF(name, var) \
{ name, PM_ARRAY, (void *) var, (void *) arrvarsetfn, \ { name, PM_ARRAY, (void *) var, (void *) &vararray_gsu }
(void *) arrvargetfn, (void *) stdunsetfn }
#define setsparam(S,V) assignsparam(S,V,0) #define setsparam(S,V) assignsparam(S,V,0)
#define setaparam(S,V) assignaparam(S,V,0) #define setaparam(S,V) assignaparam(S,V,0)

View file

@ -18,7 +18,6 @@
# Function tracing (typeset -ft) E02xtrace # Function tracing (typeset -ft) E02xtrace
# Not yet tested: # Not yet tested:
# Justification (-L, -R, -Z)
# Case conversion (-l, -u) # Case conversion (-l, -u)
# Assorted illegal flag combinations # Assorted illegal flag combinations
@ -244,6 +243,99 @@
0:Local scalar subscript assignment 0:Local scalar subscript assignment
>abc >abc
typeset -L 10 fools
for fools in " once" "twice" " thrice" " oops too long here"; do
print "'$fools'"
done
0:Left justification of scalars
>'once '
>'twice '
>'thrice '
>'oops too l'
typeset -L 10 -F 3 foolf
for foolf in 1.3 4.6 -2.987 -4.91031; do
print "'$foolf'"
done
0:Left justification of floating point
>'1.300 '
>'4.600 '
>'-2.987 '
>'-4.910 '
typeset -L 10 -Z foolzs
for foolzs in 001.3 04.6 -2.987 -04.91231; do
print "'$foolzs'"
done
0:Left justification of scalars with zero suppression
>'1.3 '
>'4.6 '
>'-2.987 '
>'-04.91231 '
typeset -R 10 foors
for foors in short longer even-longer; do
print "'$foors'"
done
0:Right justification of scalars
>' short'
>' longer'
>'ven-longer'
typeset -Z 10 foozs
for foozs in 42 -42 " 43" " -43"; do
print "'$foozs'"
done
0:Right justification of scalars with zeroes
>'0000000042'
>' -42'
>' 000000043'
>' -43'
integer -Z 10 foozi
for foozi in 42 -42 " 43" " -43"; do
print "'$foozi'"
done
0:Right justification of integers with zero, no initial base
>'0000000042'
>'-000000042'
>'0000000043'
>'-000000043'
# In case you hadn't twigged, the spaces are absorbed in the initial
# math evaluation, so don't get through.
unsetopt cbases
integer -Z 10 -i 16 foozi16
for foozi16 in 42 -42 " 43" " -43"; do
print "'$foozi16'"
done
0:Right justification of integers with zero, base 16, C_BASES off
>'16#000002A'
>'-16#00002A'
>'16#000002B'
>'-16#00002B'
setopt cbases
integer -Z 10 -i 16 foozi16c
for foozi16c in 42 -42 " 43" " -43"; do
print "'$foozi16c'"
done
0:Right justification of integers with zero, base 16, C_BASES on
>'0x0000002A'
>'-0x000002A'
>'0x0000002B'
>'-0x000002B'
typeset -F 3 -Z 10 foozf
for foozf in 3.14159 -3.14159 4 -4; do
print "'$foozf'"
done
0:Right justification of fixed point numbers with zero
>'000003.142'
>'-00003.142'
>'000004.000'
>'-00004.000'
stress00 stress00
print $scalar $array print $scalar $array
0q:Stress test: all parameters are local and unset, using -m 0q:Stress test: all parameters are local and unset, using -m