about summary refs log tree commit diff
path: root/Src/Zle
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/Zle
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/Zle')
-rw-r--r--Src/Zle/compctl.c4
-rw-r--r--Src/Zle/complete.c130
-rw-r--r--Src/Zle/computil.c2
-rw-r--r--Src/Zle/zle_params.c136
-rw-r--r--Src/Zle/zleparameter.c52
5 files changed, 176 insertions, 148 deletions
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 2f2996013..a71921a04 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -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);
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index d015ab356..717be8896 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -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;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 9450aa3ad..aa62cc78b 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -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;
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index d5fa6dd26..4a12dc2e7 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -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;
     }
diff --git a/Src/Zle/zleparameter.c b/Src/Zle/zleparameter.c
index 38b2a3608..ed415c960 100644
--- a/Src/Zle/zleparameter.c
+++ b/Src/Zle/zleparameter.c
@@ -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;