summaryrefslogtreecommitdiff
path: root/Src/builtin.c
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/builtin.c
parentddc186f3f69ee72f97d222eba424667164f73526 (diff)
downloadzsh-69b4b8bdde76b5aee6befa2b66957db22b3f6353.tar.gz
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/builtin.c')
-rw-r--r--Src/builtin.c171
1 files changed, 113 insertions, 58 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index 3a471760a..a3e7149d9 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -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 = ']';