about summary refs log tree commit diff
path: root/Src/Modules
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-12-07 16:54:58 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-12-07 16:54:58 +0000
commit69b4b8bdde76b5aee6befa2b66957db22b3f6353 (patch)
tree505c080a68853aa351a887a3eac55c4737997885 /Src/Modules
parentddc186f3f69ee72f97d222eba424667164f73526 (diff)
downloadzsh-69b4b8bdde76b5aee6befa2b66957db22b3f6353.tar.gz
zsh-69b4b8bdde76b5aee6befa2b66957db22b3f6353.tar.xz
zsh-69b4b8bdde76b5aee6befa2b66957db22b3f6353.zip
20605: Use separate structure with get/set/unset methods fro parameters.
Separate justification width of parameters from base/precision.
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/datetime.c5
-rw-r--r--Src/Modules/langinfo.c30
-rw-r--r--Src/Modules/mapfile.c34
-rw-r--r--Src/Modules/parameter.c465
-rw-r--r--Src/Modules/system.c6
-rw-r--r--Src/Modules/termcap.c34
-rw-r--r--Src/Modules/terminfo.c42
-rw-r--r--Src/Modules/zftp.c4
8 files changed, 222 insertions, 398 deletions
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index 209675e5a..4a3478800 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -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),
 };
 
 /**/
diff --git a/Src/Modules/langinfo.c b/Src/Modules/langinfo.c
index 677440f52..10754e36c 100644
--- a/Src/Modules/langinfo.c
+++ b/Src/Modules/langinfo.c
@@ -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];
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index 66e311c63..0ba7e6fd9 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -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 */
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 1df6631fe..6b7db0387 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -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;
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index f292c1924..3f932c9fa 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -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);
diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c
index a74a0538e..4c94038b2 100644
--- a/Src/Modules/termcap.c
+++ b/Src/Modules/termcap.c
@@ -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 &&
diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c
index 6e9e32588..610df5a6d 100644
--- a/Src/Modules/terminfo.c
+++ b/Src/Modules/terminfo.c
@@ -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 &&
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index f41d902db..399070939 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -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);
 }
 
 /*