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>
* 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
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.
)
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
point numbers are not permitted.
)
@ -585,7 +586,8 @@ the form of a call to hash.
)
alias(history)(fc -l)
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
integers are not permitted.
)
@ -704,7 +706,8 @@ sitem([var(mm)tt(:)]var(ss))(minutes and seconds)
endsitem()
)
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
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.
@ -1217,10 +1220,12 @@ Equivalent to tt(whence -v).
findex(typeset)
cindex(parameters, setting)
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)] ... ])
item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
var(SCALAR)[tt(=)var(value)] var(array) tt([) var(sep) tt(]))(
item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(Urux) ] \
[ tt(-LRZ) [ var(n) ]] \
var(SCALAR)[tt(=)var(value)] var(array) tt([) var(sep) tt(]))(
Set or display attributes and values for shell parameters.
A parameter is created for each var(name) that does not already refer
@ -1312,20 +1317,21 @@ ifnzman(noderef(Array Parameters))\
)
item(tt(-L))(
Left justify and remove leading blanks from var(value).
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
assignment.
If var(n) is nonzero, it defines the width of the field.
If var(n) is zero, the width is determined by the width of the value of
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
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.
)
item(tt(-R))(
Right justify and fill with leading blanks. If var(n) is nonzero
if defines the width of the field;
otherwise it is determined by the width of the value of the first
assignment.
When the parameter is expanded, the field is left filled with
blanks or truncated from the end.
Similar to tt(-L), except that right justification is used;
when the parameter is expanded, the field is left filled with
blanks or truncated from the end. May not be combined with the tt(-Z)
flag.
)
item(tt(-U))(
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.
)
item(tt(-Z))(
Right justify and fill with leading zeros if the first non-blank
character is a digit and the tt(-L) flag has not been set.
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 assignment.
Specially handled if set along with the tt(-L) flag.
Otherwise, similar to tt(-R), except that leading zeros are used for
padding instead of blanks if the first non-blank character is a digit.
Numeric parameters are specially handled: they are always eligible
for padding with zeroes, and the zeroes are inserted at an appropriate
place in the output.
)
item(tt(-a))(
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),
};
static const struct gsu_integer epochseconds_gsu =
{ getcurrentsecs, NULL, stdunsetfn };
static struct paramdef patab[] = {
PARAMDEF("EPOCHSECONDS", PM_INTEGER|PM_SPECIAL|PM_READONLY,
NULL, NULL, &getcurrentsecs, stdunsetfn),
NULL, &epochseconds_gsu),
};
/**/

View File

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

View File

@ -358,6 +358,8 @@ static struct builtin bintab[] = {
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 */
@ -390,9 +392,7 @@ boot_(Module m)
if (!(pm_nos = createparam("errnos", PM_ARRAY|PM_SPECIAL|PM_READONLY|
PM_HIDE|PM_HIDEVAL|PM_REMOVABLE)))
return 1;
pm_nos->gets.afn = errnosgetfn;
pm_nos->sets.afn = arrsetfn;
pm_nos->unsetfn = stdunsetfn;
pm_nos->gsu.a = &errnos_gsu;
if (!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) {
tidyparam(pm_nos);

View File

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

View File

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

View File

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

View File

@ -3377,7 +3377,7 @@ bin_compquote(char *nam, char **args, Options ops, UNUSED(int func))
break;
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) *
sizeof(char *));
char **p = new;

View File

@ -44,60 +44,86 @@
* 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 {
char *name;
int type;
void (*setfn) _((void));
void (*getfn) _((void));
void (*unsetfn) _((Param, int));
GsuScalar gsu;
void *data;
} zleparams[] = {
{ "BUFFER", PM_SCALAR, FN(set_buffer), FN(get_buffer),
zleunsetfn, NULL },
{ "BUFFERLINES", PM_INTEGER | PM_READONLY, NULL, FN(get_bufferlines),
zleunsetfn, NULL },
{ "CONTEXT", PM_SCALAR | PM_READONLY, NULL, FN(get_context),
zleunsetfn, NULL },
{ "CURSOR", PM_INTEGER, FN(set_cursor), FN(get_cursor),
zleunsetfn, NULL },
{ "CUTBUFFER", PM_SCALAR, FN(set_cutbuffer), FN(get_cutbuffer),
unset_cutbuffer, NULL },
{ "HISTNO", PM_INTEGER, FN(set_histno), FN(get_histno),
zleunsetfn, NULL },
{ "KEYMAP", PM_SCALAR | PM_READONLY, NULL, FN(get_keymap),
zleunsetfn, NULL },
{ "KEYS", PM_SCALAR | PM_READONLY, NULL, FN(get_keys),
zleunsetfn, NULL },
{ "killring", PM_ARRAY, FN(set_killring), FN(get_killring),
unset_killring, NULL },
{ "LASTSEARCH", PM_SCALAR | PM_READONLY, NULL, FN(get_lsearch),
zleunsetfn, NULL },
{ "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget),
zleunsetfn, NULL },
{ "LBUFFER", PM_SCALAR, FN(set_lbuffer), FN(get_lbuffer),
zleunsetfn, NULL },
{ "MARK", PM_INTEGER, FN(set_mark), FN(get_mark),
zleunsetfn, 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 }
{ "BUFFER", PM_SCALAR, GSU(buffer_gsu), NULL },
{ "BUFFERLINES", PM_INTEGER | PM_READONLY, GSU(bufferlines_gsu),
NULL },
{ "CONTEXT", PM_SCALAR | PM_READONLY, GSU(context_gsu),
NULL },
{ "CURSOR", PM_INTEGER, GSU(cursor_gsu),
NULL },
{ "CUTBUFFER", PM_SCALAR, GSU(cutbuffer_gsu), NULL },
{ "HISTNO", PM_INTEGER, GSU(histno_gsu), NULL },
{ "KEYMAP", PM_SCALAR | PM_READONLY, GSU(keymap_gsu), NULL },
{ "KEYS", PM_SCALAR | PM_READONLY, GSU(keys_gsu), NULL },
{ "killring", PM_ARRAY, GSU(killring_gsu), NULL },
{ "LASTSEARCH", PM_SCALAR | PM_READONLY, GSU(lastsearch_gsu), NULL },
{ "LASTWIDGET", PM_SCALAR | PM_READONLY, GSU(lastwidget_gsu), NULL },
{ "LBUFFER", PM_SCALAR, GSU(lbuffer_gsu), NULL },
{ "MARK", PM_INTEGER, GSU(mark_gsu), NULL },
{ "NUMERIC", PM_INTEGER | PM_UNSET, GSU(numeric_gsu), NULL },
{ "PENDING", PM_INTEGER | PM_READONLY, GSU(pending_gsu), NULL },
{ "POSTDISPLAY", PM_SCALAR, GSU(postdisplay_gsu), NULL },
{ "PREBUFFER", PM_SCALAR | PM_READONLY, GSU(prebuffer_gsu), NULL },
{ "PREDISPLAY", PM_SCALAR, GSU(predisplay_gsu), NULL },
{ "RBUFFER", PM_SCALAR, GSU(rbuffer_gsu), NULL },
{ "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
{ "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
{ "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },
{ NULL, 0, NULL, NULL }
};
/**/
@ -117,20 +143,16 @@ makezleparams(int ro)
pm->u.data = zp->data;
switch(PM_TYPE(zp->type)) {
case PM_SCALAR:
pm->sets.cfn = (void (*) _((Param, char *))) zp->setfn;
pm->gets.cfn = (char *(*) _((Param))) zp->getfn;
pm->gsu.s = zp->gsu;
break;
case PM_ARRAY:
pm->sets.afn = (void (*) _((Param, char **))) zp->setfn;
pm->gets.afn = (char **(*) _((Param))) zp->getfn;
pm->gsu.a = (GsuArray)zp->gsu;
break;
case PM_INTEGER:
pm->sets.ifn = (void (*) _((Param, zlong))) zp->setfn;
pm->gets.ifn = (zlong (*) _((Param))) zp->getfn;
pm->ct = 10;
pm->gsu.i = (GsuInteger)zp->gsu;
pm->base = 10;
break;
}
pm->unsetfn = zp->unsetfn;
if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT))
pm->flags &= ~PM_UNSET;
}

View File

@ -51,11 +51,8 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
return NULL;
pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->gsu.h = &stdhash_gsu;
pm->u.hash = ht = newhashtable(0, name, NULL);
pm->ct = 0;
ht->hash = hasher;
ht->emptytable = (TableFunc) shempty;
@ -101,17 +98,11 @@ getpmwidgets(UNUSED(HashTable ht), char *name)
Param pm = NULL;
Thingy th;
pm = (Param) zhalloc(sizeof(struct param));
pm = (Param) hcalloc(sizeof(struct param));
pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
pm->gsu.s = &nullsetscalar_gsu;
if ((th = (Thingy) thingytab->getnode(thingytab, name)) &&
!(th->flags & DISABLED))
pm->u.str = widgetstr(th->widget);
@ -130,15 +121,9 @@ scanpmwidgets(UNUSED(HashTable ht), ScanFunc func, int flags)
int i;
HashNode hn;
memset((void *)&pm, 0, sizeof(struct param));
pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
pm.gsu.s = &nullsetscalar_gsu;
for (i = 0; i < thingytab->hsize; i++)
for (hn = thingytab->nodes[i]; hn; hn = hn->next) {
@ -177,21 +162,22 @@ struct pardef {
int flags;
GetNodeFunc getnfn;
ScanTabFunc scantfn;
void (*hsetfn) _((Param, HashTable));
void (*setfn) _((Param, char **));
char **(*getfn) _((Param));
void (*unsetfn) _((Param, int));
GsuHash hash_gsu;
GsuArray array_gsu;
Param pm;
};
static const struct gsu_array keymaps_gsu =
{ keymapsgetfn, arrsetfn, stdunsetfn };
static struct pardef partab[] = {
{ "widgets", PM_READONLY,
getpmwidgets, scanpmwidgets, hashsetfn,
NULL, NULL, stdunsetfn, NULL },
getpmwidgets, scanpmwidgets, &stdhash_gsu,
NULL, NULL },
{ "keymaps", PM_ARRAY|PM_SPECIAL|PM_READONLY,
NULL, NULL, NULL,
arrsetfn, keymapsgetfn, stdunsetfn, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
&keymaps_gsu, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL, NULL }
};
/**/
@ -215,14 +201,12 @@ boot_(UNUSED(Module m))
def->scantfn)))
return 1;
def->pm->flags |= def->flags;
if (def->hsetfn)
def->pm->sets.hfn = def->hsetfn;
if (def->hash_gsu)
def->pm->gsu.h = def->hash_gsu;
} else {
if (!(def->pm = createparam(def->name, def->flags | PM_HIDE)))
return 1;
def->pm->sets.afn = def->setfn;
def->pm->gets.afn = def->getfn;
def->pm->unsetfn = def->unsetfn;
def->pm->gsu.a = def->array_gsu;
}
}
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("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("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
@ -82,7 +82,7 @@ static struct builtin builtins[] =
#endif
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("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
@ -1719,13 +1719,73 @@ enum {
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 */
/**/
static Param
typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
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;
char *subscript;
@ -1862,25 +1922,28 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
Param apm;
char **x;
if (PM_TYPE(pm->flags) == PM_ARRAY) {
x = (*pm->gets.afn)(pm);
x = (*pm->gsu.a->getfn)(pm);
uniqarray(x);
if (pm->ename && x)
arrfixenv(pm->ename, x);
} else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename &&
(apm =
(Param) paramtab->getnode(paramtab, pm->ename))) {
x = (*apm->gets.afn)(apm);
x = (*apm->gsu.a->getfn)(apm);
uniqarray(x);
if (x)
arrfixenv(pm->nam, x);
}
}
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 | PM_INTEGER |
PM_EFLOAT | PM_FFLOAT)) &&
auxlen)
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;
}
if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
if (pm->flags & PM_EXPORTED) {
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->level = pm->level;
tpm->ct = pm->ct;
tpm->base = pm->base;
tpm->width = pm->width;
if (pm->env)
delenv(pm);
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
* numbers, we should use the appropriate integer.
*/
if (on & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z|PM_INTEGER|
PM_EFLOAT|PM_FFLOAT))
pm->ct = auxlen;
else
pm->ct = 0;
if (on & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) {
if (typeset_setwidth(cname, pm, ops, on, 1))
return NULL;
}
if (on & (PM_INTEGER|PM_EFLOAT|PM_FFLOAT)) {
if (typeset_setbase(cname, pm, ops, on, 1))
return NULL;
}
} else if ((subscript = strchr(pname, '['))) {
if (on & PM_READONLY) {
zerrnam(cname,
@ -2027,7 +2094,14 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
*/
pm = createparam(pname, on & ~PM_READONLY);
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 {
if (isident(pname))
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->arrptr = &altpm->u.arr;
pm->sets.cfn = tiedarrsetfn;
pm->gets.cfn = tiedarrgetfn;
pm->unsetfn = tiedarrunsetfn;
pm->gsu.s = &tiedarr_gsu;
pm->u.data = tdp;
}
@ -2075,20 +2147,20 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
*/
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
pm->sets.cfn(pm, ztrdup(""));
pm->gsu.s->setfn(pm, ztrdup(""));
break;
case PM_INTEGER:
pm->sets.ifn(pm, 0);
pm->gsu.i->setfn(pm, 0);
break;
case PM_EFLOAT:
case PM_FFLOAT:
pm->sets.ffn(pm, 0.0);
pm->gsu.f->setfn(pm, 0.0);
break;
case PM_ARRAY:
pm->sets.afn(pm, mkarray(NULL));
pm->gsu.a->setfn(pm, mkarray(NULL));
break;
case PM_HASHED:
pm->sets.hfn(pm, newparamtable(17, pm->nam));
pm->gsu.h->setfn(pm, newparamtable(17, pm->nam));
break;
}
}
@ -2118,7 +2190,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
char *optstr = TYPESET_OPTSTR;
int on = 0, off = 0, roff, bit = PM_ARRAY;
int i;
int returnval = 0, printflags = 0, auxlen = 0;
int returnval = 0, printflags = 0;
/* hash -f is really the builtin `functions' */
if (OPT_ISSET(ops,'f'))
@ -2134,43 +2206,27 @@ bin_typeset(char *name, char **argv, Options ops, int func)
on |= bit;
else if (OPT_PLUS(ops,optval))
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;
/* Sanity checks on the options. Remove conflicting options. */
if (on & PM_FFLOAT) {
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY |
PM_HASHED | PM_INTEGER | PM_EFLOAT;
off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_INTEGER | PM_EFLOAT;
/* Allow `float -F' to work even though float sets -E by default */
on &= ~PM_EFLOAT;
}
if (on & PM_EFLOAT)
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY |
PM_HASHED | PM_INTEGER | PM_FFLOAT;
off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_INTEGER | PM_FFLOAT;
if (on & PM_INTEGER)
off |= PM_RIGHT_B | PM_LEFT | PM_RIGHT_Z | PM_UPPER | PM_ARRAY |
PM_HASHED | PM_EFLOAT | PM_FFLOAT;
if (on & PM_LEFT)
off |= PM_RIGHT_B | PM_INTEGER | PM_EFLOAT | PM_FFLOAT;
off |= PM_UPPER | PM_ARRAY | PM_HASHED | PM_EFLOAT | PM_FFLOAT;
/*
* Allowing -Z with -L is a feature: left justify, suppressing
* leading zeroes.
*/
if (on & (PM_LEFT|PM_RIGHT_Z))
off |= PM_RIGHT_B;
if (on & PM_RIGHT_B)
off |= PM_LEFT | PM_INTEGER | PM_EFLOAT | PM_FFLOAT;
if (on & PM_RIGHT_Z)
off |= PM_INTEGER | PM_EFLOAT | PM_FFLOAT;
off |= PM_LEFT | PM_RIGHT_Z;
if (on & PM_UPPER)
off |= PM_LOWER;
if (on & PM_LOWER)
@ -2279,8 +2335,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
(Param)paramtab->getnode(paramtab,
asg->name),
func, (on | PM_ARRAY) & ~PM_EXPORTED,
off, roff, asg->value, NULL, ops, auxlen,
0))) {
off, roff, asg->value, NULL, ops, 0))) {
unqueue_signals();
return 1;
}
@ -2292,7 +2347,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
(Param)paramtab->getnode(paramtab,
asg0.name),
func, on, off, roff, asg0.value, apm,
ops, auxlen, joinchar))) {
ops, joinchar))) {
if (oldval)
zsfree(oldval);
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)) {
pm = (Param) getdata(pmnode);
if (!typeset_single(name, pm->nam, pm, func, on, off, roff,
asg->value, NULL, ops, auxlen, 0))
asg->value, NULL, ops, 0))
returnval = 1;
}
}
@ -2382,7 +2437,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
gethashnode2(paramtab, asg->name) :
paramtab->getnode(paramtab, asg->name)),
func, on, off, roff, asg->value, NULL,
ops, auxlen, 0))
ops, 0))
returnval = 1;
}
unqueue_signals();
@ -2681,7 +2736,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
} else if (ss) {
if (PM_TYPE(pm->flags) == PM_HASHED) {
HashTable tht = paramtab;
if ((paramtab = pm->gets.hfn(pm))) {
if ((paramtab = pm->gsu.h->getfn(pm))) {
*--sse = 0;
unsetparam(ss+1);
*sse = ']';

View File

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

View File

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

View File

@ -106,10 +106,114 @@ struct timeval shtimer;
/* 0 if this $TERM setup is usable, otherwise it contains TERM_* flags */
/**/
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 */
#ifdef HAVE_UNION_INIT
@ -122,10 +226,9 @@ typedef struct iparam {
char *nam; /* hash data */
int flags; /* PM_* flags (defined in zsh.h) */
void *value;
void (*func1) _((void)); /* set func */
char *(*func2) _((void)); /* get func */
void (*unsetfn) _((Param, int)); /* unset func */
int ct; /* output base or field width */
void *gsu; /* get/set/unset methods */
int base; /* output base */
int width; /* output field width */
char *env; /* location in environment, if exported */
char *ename; /* name of corresponding environment var */
Param old; /* old struct for use with local */
@ -134,35 +237,35 @@ typedef struct iparam {
#endif
static initparam special_params[] ={
#define SFN(X) BR(((void (*)_((Param, char *)))(X)))
#define GFN(X) BR(((char *(*)_((Param)))(X)))
#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}
IPDEF1("#", poundgetfn, nullintsetfn, PM_READONLY),
IPDEF1("ERRNO", errnogetfn, errnosetfn, 0),
IPDEF1("GID", gidgetfn, gidsetfn, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EGID", egidgetfn, egidsetfn, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("HISTSIZE", histsizegetfn, histsizesetfn, PM_RESTRICTED),
IPDEF1("RANDOM", randomgetfn, randomsetfn, 0),
IPDEF1("SAVEHIST", savehistsizegetfn, savehistsizesetfn, PM_RESTRICTED),
IPDEF1("SECONDS", intsecondsgetfn, intsecondssetfn, 0),
IPDEF1("UID", uidgetfn, uidsetfn, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EUID", euidgetfn, euidsetfn, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("TTYIDLE", ttyidlegetfn, nullintsetfn, PM_READONLY),
#define GSU(X) BR((GsuScalar)(void *)(&(X)))
#define NULL_GSU BR((GsuScalar)(void *)NULL)
#define IPDEF1(A,B,C) {NULL,A,PM_INTEGER|PM_SPECIAL|C,BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0}
IPDEF1("#", pound_gsu, PM_READONLY),
IPDEF1("ERRNO", errno_gsu, 0),
IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EGID", egid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("HISTSIZE", histsize_gsu, PM_RESTRICTED),
IPDEF1("RANDOM", random_gsu, 0),
IPDEF1("SAVEHIST", savehist_gsu, PM_RESTRICTED),
IPDEF1("SECONDS", intseconds_gsu, 0),
IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
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}
IPDEF2("USERNAME", usernamegetfn, usernamesetfn, PM_DONTIMPORT|PM_RESTRICTED),
IPDEF2("-", dashgetfn, nullstrsetfn, PM_READONLY),
IPDEF2("histchars", histcharsgetfn, histcharssetfn, PM_DONTIMPORT),
IPDEF2("HOME", homegetfn, homesetfn, 0),
IPDEF2("TERM", termgetfn, termsetfn, 0),
IPDEF2("WORDCHARS", wordcharsgetfn, wordcharssetfn, 0),
IPDEF2("IFS", ifsgetfn, ifssetfn, PM_DONTIMPORT),
IPDEF2("_", underscoregetfn, nullstrsetfn, PM_READONLY),
#define IPDEF2(A,B,C) {NULL,A,PM_SCALAR|PM_SPECIAL|C,BR(NULL),GSU(B),0,0,NULL,NULL,NULL,0}
IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED),
IPDEF2("-", dash_gsu, PM_READONLY),
IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
IPDEF2("HOME", home_gsu, 0),
IPDEF2("TERM", term_gsu, 0),
IPDEF2("WORDCHARS", wordchars_gsu, 0),
IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT),
IPDEF2("_", underscore_gsu, PM_READONLY),
#ifdef USE_LOCALE
# define LCIPDEF(name) IPDEF2(name, strgetfn, lcsetfn, PM_UNSET)
IPDEF2("LANG", strgetfn, langsetfn, PM_UNSET),
IPDEF2("LC_ALL", strgetfn, lc_allsetfn, PM_UNSET),
# define LCIPDEF(name) IPDEF2(name, lc_blah_gsu, PM_UNSET)
IPDEF2("LANG", lang_gsu, PM_UNSET),
IPDEF2("LC_ALL", lc_all_gsu, PM_UNSET),
# ifdef LC_COLLATE
LCIPDEF("LC_COLLATE"),
# endif
@ -180,7 +283,7 @@ LCIPDEF("LC_TIME"),
# endif
#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("$", &mypid),
IPDEF4("?", &lastval),
@ -188,14 +291,14 @@ IPDEF4("HISTCMD", &curhist),
IPDEF4("LINENO", &lineno),
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}
IPDEF5("COLUMNS", &columns, zlevarsetfn),
IPDEF5("LINES", &lines, zlevarsetfn),
IPDEF5("OPTIND", &zoptind, intvarsetfn),
IPDEF5("SHLVL", &shlvl, intvarsetfn),
IPDEF5("TRY_BLOCK_ERROR", &try_errflag, intvarsetfn),
#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, zlevar_gsu),
IPDEF5("LINES", &lines, zlevar_gsu),
IPDEF5("OPTIND", &zoptind, varinteger_gsu),
IPDEF5("SHLVL", &shlvl, varinteger_gsu),
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("NULLCMD", &nullcmd),
IPDEF7("POSTEDIT", &postedit),
@ -211,7 +314,7 @@ IPDEF7("PS4", &prompt4),
IPDEF7("SPROMPT", &sprompt),
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("FIGNORE", &fignore, "fignore", 0),
IPDEF8("FPATH", &fpath, "fpath", 0),
@ -223,18 +326,18 @@ IPDEF8("PSVAR", &psvar, "psvar", 0),
/* MODULE_PATH is not imported for security reasons */
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)
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 *
* mode. All of these have sh compatible equivalents. */
IPDEF1("ARGC", poundgetfn, nullintsetfn, PM_READONLY),
IPDEF2("HISTCHARS", histcharsgetfn, histcharssetfn, PM_DONTIMPORT),
IPDEF1("ARGC", argc_gsu, PM_READONLY),
IPDEF2("HISTCHARS", histchars_gsu, PM_DONTIMPORT),
IPDEF4("status", &lastval),
IPDEF7("prompt", &prompt),
IPDEF7("PROMPT", &prompt),
@ -254,9 +357,9 @@ IPDEF9("watch", &watch, "WATCH"),
IPDEF9F("module_path", &module_path, "MODULE_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)
return v->arr;
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) {
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 */
v->start = 0;
v->end = numparamvals + 1;
@ -631,31 +734,25 @@ assigngetset(Param pm)
{
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
pm->sets.cfn = strsetfn;
pm->gets.cfn = strgetfn;
pm->gsu.s = &stdscalar_gsu;
break;
case PM_INTEGER:
pm->sets.ifn = intsetfn;
pm->gets.ifn = intgetfn;
pm->gsu.i = &stdinteger_gsu;
break;
case PM_EFLOAT:
case PM_FFLOAT:
pm->sets.ffn = floatsetfn;
pm->gets.ffn = floatgetfn;
pm->gsu.f = &stdfloat_gsu;
break;
case PM_ARRAY:
pm->sets.afn = arrsetfn;
pm->gets.afn = arrgetfn;
pm->gsu.a = &stdarray_gsu;
break;
case PM_HASHED:
pm->sets.hfn = hashsetfn;
pm->gets.hfn = hashgetfn;
pm->gsu.h = &stdhash_gsu;
break;
default:
DPUTS(1, "BUG: tried to create param node without valid flag");
break;
}
pm->unsetfn = stdunsetfn;
}
/* 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->ct = 0;
pm->base = pm->width = 0;
oldpm = pm->old;
} else {
pm = (Param) zshcalloc(sizeof *pm);
@ -741,25 +838,26 @@ copyparam(Param tpm, Param pm, int toplevel)
* with sets.?fn() usage).
*/
tpm->flags = pm->flags;
tpm->ct = pm->ct;
tpm->base = pm->base;
tpm->width = pm->width;
if (!toplevel)
tpm->flags &= ~PM_SPECIAL;
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
tpm->u.str = ztrdup(pm->gets.cfn(pm));
tpm->u.str = ztrdup(pm->gsu.s->getfn(pm));
break;
case PM_INTEGER:
tpm->u.val = pm->gets.ifn(pm);
tpm->u.val = pm->gsu.i->getfn(pm);
break;
case PM_EFLOAT:
case PM_FFLOAT:
tpm->u.dval = pm->gets.ffn(pm);
tpm->u.dval = pm->gsu.f->getfn(pm);
break;
case PM_ARRAY:
tpm->u.arr = zarrdup(pm->gets.afn(pm));
tpm->u.arr = zarrdup(pm->gsu.a->getfn(pm));
break;
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;
}
/*
@ -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 ... */
if (!rev) {
if (ishash) {
HashTable ht = v->pm->gets.hfn(v->pm);
HashTable ht = v->pm->gsu.h->getfn(v->pm);
if (!ht) {
ht = newparamtable(17, v->pm->nam);
v->pm->sets.hfn(v->pm, ht);
v->pm->gsu.h->setfn(v->pm, ht);
}
untokenize(s);
if (!(v->pm = (Param) ht->getnode(ht, s))) {
@ -1447,15 +1545,16 @@ getstrvalue(Value v)
}
return s;
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);
break;
case PM_EFLOAT:
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;
case PM_SCALAR:
s = v->pm->gets.cfn(v->pm);
s = v->pm->gsu.s->getfn(v->pm);
break;
default:
s = NULL;
@ -1526,9 +1625,9 @@ getintvalue(Value v)
if (v->inv)
return v->start;
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))
return (zlong)v->pm->gets.ffn(v->pm);
return (zlong)v->pm->gsu.f->getfn(v->pm);
return mathevali(getstrvalue(v));
}
@ -1544,10 +1643,10 @@ getnumvalue(Value v)
} else if (v->inv) {
mn.u.l = v->start;
} 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)) {
mn.type = MN_FLOAT;
mn.u.d = v->pm->gets.ffn(v->pm);
mn.u.d = v->pm->gsu.f->getfn(v->pm);
} else
return matheval(getstrvalue(v));
return mn;
@ -1572,12 +1671,12 @@ export_param(Param pm)
#endif
return;
} 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))
val = convfloat(pm->gets.ffn(pm), pm->ct,
val = convfloat(pm->gsu.f->getfn(pm), pm->base,
pm->flags, NULL);
else
val = pm->gets.cfn(pm);
val = pm->gsu.s->getfn(pm);
addenv(pm, val);
}
@ -1605,14 +1704,15 @@ setstrvalue(Value v, char *val)
switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR:
if (v->start == 0 && v->end == -1) {
(v->pm->sets.cfn) (v->pm, val);
if (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z) && !v->pm->ct)
v->pm->ct = strlen(val);
v->pm->gsu.s->setfn(v->pm, val);
if ((v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
!v->pm->width)
v->pm->width = strlen(val);
} else {
char *z, *x;
int zlen;
z = dupstring((v->pm->gets.cfn) (v->pm));
z = dupstring(v->pm->gsu.s->getfn(v->pm));
zlen = strlen(z);
if (v->inv && unset(KSHARRAYS))
v->start--, v->end--;
@ -1631,25 +1731,31 @@ setstrvalue(Value v, char *val)
strncpy(x, z, v->start);
strcpy(x + v->start, val);
strcat(x + v->start, z + v->end);
(v->pm->sets.cfn) (v->pm, x);
v->pm->gsu.s->setfn(v->pm, x);
zsfree(val);
}
break;
case PM_INTEGER:
if (val) {
(v->pm->sets.ifn) (v->pm, mathevali(val));
v->pm->gsu.i->setfn(v->pm, mathevali(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)
v->pm->ct = lastbase;
if (!v->pm->base && lastbase != -1)
v->pm->base = lastbase;
break;
case PM_EFLOAT:
case PM_FFLOAT:
if (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);
zsfree(val);
if ((v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
!v->pm->width)
v->pm->width = strlen(val);
}
break;
case PM_ARRAY:
@ -1663,7 +1769,7 @@ setstrvalue(Value v, char *val)
break;
case PM_HASHED:
{
(foundparam->sets.cfn) (foundparam, val);
foundparam->gsu.s->setfn(foundparam, val);
}
break;
}
@ -1700,14 +1806,14 @@ setnumvalue(Value v, mnumber val)
setstrvalue(v, ztrdup(p));
break;
case PM_INTEGER:
(v->pm->sets.ifn) (v->pm, (val.type & MN_INTEGER) ? val.u.l :
(zlong) val.u.d);
v->pm->gsu.i->setfn(v->pm, (val.type & MN_INTEGER) ? val.u.l :
(zlong) val.u.d);
setstrvalue(v, NULL);
break;
case PM_EFLOAT:
case PM_FFLOAT:
(v->pm->sets.ffn) (v->pm, (val.type & MN_INTEGER) ?
(double)val.u.l : val.u.d);
v->pm->gsu.f->setfn(v->pm, (val.type & MN_INTEGER) ?
(double)val.u.l : val.u.d);
setstrvalue(v, NULL);
break;
}
@ -1737,7 +1843,7 @@ setarrvalue(Value v, char **val)
if (PM_TYPE(v->pm->flags) == PM_HASHED)
arrhashsetfn(v->pm, val, 0);
else
(v->pm->sets.afn) (v->pm, val);
v->pm->gsu.a->setfn(v->pm, val);
} else if (v->start == -1 && v->end == 0 &&
PM_TYPE(v->pm->flags) == PM_HASHED) {
arrhashsetfn(v->pm, val, 1);
@ -1758,7 +1864,7 @@ setarrvalue(Value v, char **val)
}
if (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);
if (v->start < 0) {
v->start += n;
@ -1786,7 +1892,7 @@ setarrvalue(Value v, char **val)
*p++ = ztrdup(*q++);
*p = NULL;
(v->pm->sets.afn) (v->pm, new);
v->pm->gsu.a->setfn(v->pm, new);
freearray(val);
}
}
@ -1848,7 +1954,7 @@ getaparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
PM_TYPE(v->pm->flags) == PM_ARRAY)
return v->pm->gets.afn(v->pm);
return v->pm->gsu.a->getfn(v->pm);
return NULL;
}
@ -1863,7 +1969,7 @@ gethparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
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;
}
@ -1878,7 +1984,7 @@ gethkparam(char *s)
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
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;
}
@ -1952,7 +2058,7 @@ assignsparam(char *s, char *val, int augment)
return v->pm; /* avoid later setstrvalue() call */
case PM_ARRAY:
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;
} else {
/* ksh appends scalar to first element */
@ -1967,7 +2073,7 @@ assignsparam(char *s, char *val, int augment)
if (v->end > 0)
v->start = v->end;
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;
break;
case PM_INTEGER:
@ -2064,7 +2170,7 @@ assignaparam(char *s, char **val, int augment)
if (augment) {
if (v->start == 0 && v->end == -1) {
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;
} else if (PM_TYPE(v->pm->flags) & PM_HASHED)
v->start = -1, v->end = 0;
@ -2072,7 +2178,7 @@ assignaparam(char *s, char **val, int augment)
if (v->end > 0)
v->start = v->end--;
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;
}
}
@ -2147,7 +2253,7 @@ setiparam(char *s, zlong val)
if (ss) {
*ss = '[';
} else {
pm->ct = outputradix;
pm->base = outputradix;
}
v = getvalue(&vbuf, &t, 1);
DPUTS(!v, "BUG: value not found for new parameter");
@ -2190,7 +2296,7 @@ setnparam(char *s, mnumber val)
if (ss) {
*ss = '[';
} else if (val.type & MN_INTEGER) {
pm->ct = outputradix;
pm->base = outputradix;
}
v = getvalue(&vbuf, &t, 1);
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);
return 1;
}
pm->unsetfn(pm, exp);
pm->gsu.s->unsetfn(pm, exp);
if (pm->env)
delenv(pm);
@ -2281,7 +2387,7 @@ unsetparam_pm(Param pm, int altflag, int exp)
if ((PM_TYPE(oldpm->flags) == PM_SCALAR) &&
!(pm->flags & PM_HASHELEM) &&
(oldpm->flags & PM_NAMEDDIR) &&
oldpm->sets.cfn == strsetfn)
oldpm->gsu.s == &stdscalar_gsu)
adduserdir(oldpm->nam, oldpm->u.str, 0, 0);
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 *
* 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
stdunsetfn(Param pm, UNUSED(int exp))
{
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR: pm->sets.cfn(pm, NULL); break;
case PM_ARRAY: pm->sets.afn(pm, NULL); break;
case PM_HASHED: pm->sets.hfn(pm, NULL); break;
case PM_SCALAR: pm->gsu.s->setfn(pm, NULL); break;
case PM_ARRAY: pm->gsu.a->setfn(pm, NULL); break;
case PM_HASHED: pm->gsu.h->setfn(pm, NULL); break;
default:
if (!(pm->flags & PM_SPECIAL))
pm->u.str = NULL;
@ -2425,6 +2535,15 @@ hashsetfn(Param pm, HashTable 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 */
/**/
@ -2433,7 +2552,7 @@ arrhashsetfn(Param pm, char **val, int augment)
{
/* Best not to shortcut this by using the existing hash table, *
* 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);
HashTable opmtab = paramtab, ht = 0;
char **aptr = val;
@ -2447,7 +2566,7 @@ arrhashsetfn(Param pm, char **val, int augment)
return;
}
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);
while (*aptr) {
/* The parameter name is ztrdup'd... */
@ -2463,7 +2582,7 @@ arrhashsetfn(Param pm, char **val, int augment)
setstrvalue(v, *aptr++);
}
paramtab = opmtab;
pm->sets.hfn(pm, ht);
pm->gsu.h->setfn(pm, ht);
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
* need to delete.
*/
pm->sets.cfn(pm, NULL);
pm->gsu.s->setfn(pm, NULL);
zfree(pm->u.data, sizeof(struct tieddata));
/* paranoia -- shouldn't need these, but in case we reuse the struct... */
pm->u.data = NULL;
@ -2822,13 +2941,11 @@ setsecondstype(Param pm, int on, int off)
/* Only one of the numeric types is allowed. */
if (tp == PM_EFLOAT || tp == PM_FFLOAT)
{
pm->gets.ffn = floatsecondsgetfn;
pm->sets.ffn = floatsecondssetfn;
pm->gsu.f = &floatseconds_gsu;
}
else if (tp == PM_INTEGER)
{
pm->gets.ifn = intsecondsgetfn;
pm->sets.ifn = intsecondssetfn;
pm->gsu.i = &intseconds_gsu;
}
else
return 1;
@ -2881,10 +2998,10 @@ uidgetfn(UNUSED(Param pm))
/**/
void
uidsetfn(UNUSED(Param pm), uid_t x)
uidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETUID
setuid(x);
setuid((uid_t)x);
#endif
}
@ -2901,10 +3018,10 @@ euidgetfn(UNUSED(Param pm))
/**/
void
euidsetfn(UNUSED(Param pm), uid_t x)
euidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETEUID
seteuid(x);
seteuid((uid_t)x);
#endif
}
@ -2921,10 +3038,10 @@ gidgetfn(UNUSED(Param pm))
/**/
void
gidsetfn(UNUSED(Param pm), gid_t x)
gidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETUID
setgid(x);
setgid((gid_t)x);
#endif
}
@ -2941,10 +3058,10 @@ egidgetfn(UNUSED(Param pm))
/**/
void
egidsetfn(UNUSED(Param pm), gid_t x)
egidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETEUID
setegid(x);
setegid((gid_t)x);
#endif
}
@ -3650,27 +3767,28 @@ scanendscope(HashNode hn, UNUSED(int flags))
pm->old = tpm->old;
pm->flags = (tpm->flags & ~PM_NORESTORE);
pm->level = tpm->level;
pm->ct = tpm->ct;
pm->base = tpm->base;
pm->width = tpm->width;
if (pm->env)
delenv(pm);
if (!(tpm->flags & PM_NORESTORE))
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
pm->sets.cfn(pm, tpm->u.str);
pm->gsu.s->setfn(pm, tpm->u.str);
break;
case PM_INTEGER:
pm->sets.ifn(pm, tpm->u.val);
pm->gsu.i->setfn(pm, tpm->u.val);
break;
case PM_EFLOAT:
case PM_FFLOAT:
pm->sets.ffn(pm, tpm->u.dval);
pm->gsu.f->setfn(pm, tpm->u.dval);
break;
case PM_ARRAY:
pm->sets.afn(pm, tpm->u.arr);
pm->gsu.a->setfn(pm, tpm->u.arr);
break;
case PM_HASHED:
pm->sets.hfn(pm, tpm->u.hash);
pm->gsu.h->setfn(pm, tpm->u.hash);
break;
}
zfree(tpm, sizeof(*tpm));
@ -3696,7 +3814,7 @@ freeparamnode(HashNode hn)
/* Since the second flag to unsetfn isn't used, I don't *
* know what its value should be. */
if (delunset)
pm->unsetfn(pm, 1);
pm->gsu.s->unsetfn(pm, 1);
zsfree(pm->nam);
/* If this variable was tied by the user, ename was ztrdup'd */
if (pm->flags & PM_TIED)
@ -3707,8 +3825,9 @@ freeparamnode(HashNode hn)
/* Print a parameter */
enum paramtypes_flags {
PMTF_USE_CT = (1<<0),
PMTF_TEST_LEVEL = (1<<1)
PMTF_USE_BASE = (1<<0),
PMTF_USE_WIDTH = (1<<1),
PMTF_TEST_LEVEL = (1<<2)
};
struct paramtypes {
@ -3720,15 +3839,15 @@ struct paramtypes {
static const struct paramtypes pmtypes[] = {
{ 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_FFLOAT, "float", 'F', 0},
{ PM_ARRAY, "array", 'a', 0},
{ PM_HASHED, "association", 'A', 0},
{ 0, "local", 0, PMTF_TEST_LEVEL},
{ PM_LEFT, "left justified", 'L', PMTF_USE_CT},
{ PM_RIGHT_B, "right justified", 'R', PMTF_USE_CT},
{ PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_CT},
{ PM_LEFT, "left justified", 'L', PMTF_USE_WIDTH},
{ PM_RIGHT_B, "right justified", 'R', PMTF_USE_WIDTH},
{ PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_WIDTH},
{ PM_LOWER, "lowercase", 'l', 0},
{ PM_UPPER, "uppercase", 'u', 0},
{ PM_READONLY, "readonly", 'r', 0},
@ -3776,8 +3895,12 @@ printparamnode(HashNode hn, int printflags)
} else {
printf("%s ", pmptr->string);
}
if ((pmptr->flags & PMTF_USE_CT) && p->ct) {
printf("%d ", p->ct);
if ((pmptr->flags & PMTF_USE_BASE) && p->base) {
printf("%d ", p->base);
doneminus = 0;
}
if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) {
printf("%d ", p->width);
doneminus = 0;
}
}
@ -3812,27 +3935,27 @@ printparamnode(HashNode hn, int printflags)
switch (PM_TYPE(p->flags)) {
case PM_SCALAR:
/* 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);
break;
case PM_INTEGER:
/* integer */
#ifdef ZSH_64_BIT_TYPE
fputs(output64(p->gets.ifn(p)), stdout);
fputs(output64(p->gsu.i->getfn(p)), stdout);
#else
printf("%ld", p->gets.ifn(p));
printf("%ld", p->gsu.i->getfn(p));
#endif
break;
case PM_EFLOAT:
case PM_FFLOAT:
/* float */
convfloat(p->gets.ffn(p), p->ct, p->flags, stdout);
convfloat(p->gsu.f->getfn(p), p->base, p->flags, stdout);
break;
case PM_ARRAY:
/* array */
if (!(printflags & PRINT_KV_PAIR))
putchar('(');
u = p->gets.afn(p);
u = p->gsu.a->getfn(p);
if(*u) {
quotedzputs(*u++, stdout);
while (*u) {
@ -3848,7 +3971,7 @@ printparamnode(HashNode hn, int printflags)
if (!(printflags & PRINT_KV_PAIR))
putchar('(');
{
HashTable ht = p->gets.hfn(p);
HashTable ht = p->gsu.h->getfn(p);
if (ht)
scanhashtable(ht, 0, 0, PM_UNSET,
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
* 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)
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.
*/
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)) {
char *t;
unsigned int t0;
@ -1695,17 +1695,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
int zero = 1;
if (strlen(val) < fwidth) {
char *valprefend = val;
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;
}
t = (char *) hcalloc(fwidth + 1);
memset(t, (((v->pm->flags & PM_RIGHT_B) || !zero) ?
' ' : '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)
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;
} else {
t = (char *) hcalloc(fwidth + 1);
@ -2019,7 +2069,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
if (arrasg > 1) {
Param pm = sethparam(idbeg, a);
if (pm)
aval = paramvalarr(pm->gets.hfn(pm), hkeys|hvals);
aval = paramvalarr(pm->gsu.h->getfn(pm), hkeys|hvals);
} else
setaparam(idbeg, a);
} else {

View File

@ -1123,6 +1123,49 @@ struct patprog {
#define dummy_patprog1 ((Patprog) 1)
#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) */
struct param {
@ -1142,28 +1185,24 @@ struct param {
HashTable hash; /* value if declared assoc (PM_HASHED) */
} 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 {
void (*cfn) _((Param, char *));
void (*ifn) _((Param, zlong));
void (*ffn) _((Param, double));
void (*afn) _((Param, char **));
void (*hfn) _((Param, HashTable));
} sets;
GsuScalar s;
GsuInteger i;
GsuFloat f;
GsuArray a;
GsuHash h;
} gsu;
/* pointer to function to get value of this parameter */
union {
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 */
int base; /* output base or floating point prec */
int width; /* field width */
char *env; /* location in environment, if exported */
char *ename; /* name of corresponding environment var */
Param old; /* old struct for use with local */
@ -1272,22 +1311,17 @@ struct paramdef {
char *name;
int flags;
void *var;
void *set;
void *get;
void *unset;
void *gsu; /* get/set/unset structure */
};
#define PARAMDEF(name, flags, var, set, get, unset) \
{ name, flags, (void *) var, (void *) set, (void *) get, (void *) unset }
#define PARAMDEF(name, flags, var, gsu) \
{ name, flags, (void *) var, (void *) gsu, }
#define INTPARAMDEF(name, var) \
{ name, PM_INTEGER, (void *) var, (void *) intvarsetfn, \
(void *) intvargetfn, (void *) stdunsetfn }
{ name, PM_INTEGER, (void *) var, (void *) &stdinteger_gsu }
#define STRPARAMDEF(name, var) \
{ name, PM_SCALAR, (void *) var, (void *) strvarsetfn, \
(void *) strvargetfn, (void *) stdunsetfn }
{ name, PM_SCALAR, (void *) var, (void *) &varscalar_gsu }
#define ARRPARAMDEF(name, var) \
{ name, PM_ARRAY, (void *) var, (void *) arrvarsetfn, \
(void *) arrvargetfn, (void *) stdunsetfn }
{ name, PM_ARRAY, (void *) var, (void *) &vararray_gsu }
#define setsparam(S,V) assignsparam(S,V,0)
#define setaparam(S,V) assignaparam(S,V,0)

View File

@ -18,7 +18,6 @@
# Function tracing (typeset -ft) E02xtrace
# Not yet tested:
# Justification (-L, -R, -Z)
# Case conversion (-l, -u)
# Assorted illegal flag combinations
@ -244,6 +243,99 @@
0:Local scalar subscript assignment
>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
print $scalar $array
0q:Stress test: all parameters are local and unset, using -m