summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Builtins/rlimits.c18
-rw-r--r--Src/Builtins/sched.c26
-rw-r--r--Src/Modules/cap.c37
-rw-r--r--Src/Modules/clone.c2
-rw-r--r--Src/Modules/datetime.c2
-rw-r--r--Src/Modules/example.c174
-rw-r--r--Src/Modules/files.c40
-rw-r--r--Src/Modules/pcre.c16
-rw-r--r--Src/Modules/socket.c12
-rw-r--r--Src/Modules/stat.c56
-rw-r--r--Src/Modules/tcp.c18
-rw-r--r--Src/Modules/termcap.c2
-rw-r--r--Src/Modules/terminfo.c2
-rw-r--r--Src/Modules/zftp.c2
-rw-r--r--Src/Modules/zprof.c4
-rw-r--r--Src/Modules/zpty.c39
-rw-r--r--Src/Modules/zselect.c2
-rw-r--r--Src/Modules/zutil.c10
-rw-r--r--Src/Zle/compctl.c34
-rw-r--r--Src/Zle/complete.c4
-rw-r--r--Src/Zle/computil.c21
-rw-r--r--Src/Zle/zle_keymap.c51
-rw-r--r--Src/Zle/zle_main.c14
-rw-r--r--Src/Zle/zle_thingy.c42
-rw-r--r--Src/builtin.c726
-rw-r--r--Src/hashtable.c2
-rw-r--r--Src/hashtable.h19
-rw-r--r--Src/init.c2
-rw-r--r--Src/jobs.c23
-rw-r--r--Src/mem.c16
-rw-r--r--Src/module.c113
-rw-r--r--Src/options.c2
-rw-r--r--Src/parse.c38
-rw-r--r--Src/watch.c4
-rw-r--r--Src/zsh.h74
35 files changed, 997 insertions, 650 deletions
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c
index 7d20ab07b..228bba344 100644
--- a/Src/Builtins/rlimits.c
+++ b/Src/Builtins/rlimits.c
@@ -283,15 +283,15 @@ printulimit(int lim, int hard, int head)
/**/
static int
-bin_limit(char *nam, char **argv, char *ops, int func)
+bin_limit(char *nam, char **argv, Options ops, int func)
{
char *s;
int hard, limnum, lim;
rlim_t val;
int ret = 0;
- hard = ops['h'];
- if (ops['s'] && !*argv)
+ hard = OPT_ISSET(ops,'h');
+ if (OPT_ISSET(ops,'s') && !*argv)
return setlimits(NULL);
/* without arguments, display limits */
if (!*argv) {
@@ -380,7 +380,7 @@ bin_limit(char *nam, char **argv, char *ops, int func)
return 1;
} else
limits[lim].rlim_cur = val;
- if (ops['s'] && zsetlimit(lim, "limit"))
+ if (OPT_ISSET(ops,'s') && zsetlimit(lim, "limit"))
ret++;
}
return ret;
@@ -391,13 +391,13 @@ bin_limit(char *nam, char **argv, char *ops, int func)
/**/
static int
-bin_unlimit(char *nam, char **argv, char *ops, int func)
+bin_unlimit(char *nam, char **argv, Options ops, int func)
{
int hard, limnum, lim;
int ret = 0;
uid_t euid = geteuid();
- hard = ops['h'];
+ hard = OPT_ISSET(ops,'h');
/* Without arguments, remove all limits. */
if (!*argv) {
for (limnum = 0; limnum != RLIM_NLIMITS; limnum++) {
@@ -409,7 +409,7 @@ bin_unlimit(char *nam, char **argv, char *ops, int func)
} else
limits[limnum].rlim_cur = limits[limnum].rlim_max;
}
- if (ops['s'])
+ if (OPT_ISSET(ops,'s'))
ret += setlimits(nam);
if (ret)
zwarnnam(nam, "can't remove hard limits", NULL, 0);
@@ -443,7 +443,7 @@ bin_unlimit(char *nam, char **argv, char *ops, int func)
limits[lim].rlim_max = RLIM_INFINITY;
} else
limits[lim].rlim_cur = limits[lim].rlim_max;
- if (ops['s'] && zsetlimit(lim, nam))
+ if (OPT_ISSET(ops,'s') && zsetlimit(lim, nam))
ret++;
}
}
@@ -454,7 +454,7 @@ bin_unlimit(char *nam, char **argv, char *ops, int func)
/**/
static int
-bin_ulimit(char *name, char **argv, char *ops, int func)
+bin_ulimit(char *name, char **argv, Options ops, int func)
{
int res, resmask = 0, hard = 0, soft = 0, nres = 0;
char *options;
diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c
index b4914899e..05e3cfb3f 100644
--- a/Src/Builtins/sched.c
+++ b/Src/Builtins/sched.c
@@ -46,7 +46,7 @@ static struct schedcmd *schedcmds;
/**/
static int
-bin_sched(char *nam, char **argv, char *ops, int func)
+bin_sched(char *nam, char **argv, Options ops, int func)
{
char *s = *argv++;
time_t t;
@@ -143,9 +143,7 @@ bin_sched(char *nam, char **argv, char *ops, int func)
of scheduled commands. */
sch = (struct schedcmd *) zcalloc(sizeof *sch);
sch->time = t;
- PERMALLOC {
- sch->cmd = zjoin(argv, ' ');
- } LASTALLOC;
+ sch->cmd = zjoin(argv, ' ', 0);
sch->next = NULL;
for (sch2 = (struct schedcmd *)&schedcmds; sch2->next; sch2 = sch2->next);
sch2->next = sch;
@@ -185,7 +183,14 @@ static struct builtin bintab[] = {
/**/
int
-boot_sched(Module m)
+setup_(Module m)
+{
+ return 0;
+}
+
+/**/
+int
+boot_(Module m)
{
if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
return 1;
@@ -193,11 +198,9 @@ boot_sched(Module m)
return 0;
}
-#ifdef MODULE
-
/**/
int
-cleanup_sched(Module m)
+cleanup_(Module m)
{
struct schedcmd *sch, *schn;
@@ -211,4 +214,9 @@ cleanup_sched(Module m)
return 0;
}
-#endif
+/**/
+int
+finish_(Module m)
+{
+ return 0;
+}
diff --git a/Src/Modules/cap.c b/Src/Modules/cap.c
index 008b6932d..ba377f876 100644
--- a/Src/Modules/cap.c
+++ b/Src/Modules/cap.c
@@ -33,7 +33,7 @@
#ifdef HAVE_CAP_GET_PROC
static int
-bin_cap(char *nam, char **argv, char *ops, int func)
+bin_cap(char *nam, char **argv, Options ops, int func)
{
int ret = 0;
cap_t caps;
@@ -48,7 +48,7 @@ bin_cap(char *nam, char **argv, char *ops, int func)
ret = 1;
}
} else {
- char *result;
+ char *result = NULL;
ssize_t length;
caps = cap_get_proc();
if(caps)
@@ -59,17 +59,17 @@ bin_cap(char *nam, char **argv, char *ops, int func)
} else
puts(result);
}
- cap_free(&caps);
+ cap_free(caps);
return ret;
}
static int
-bin_getcap(char *nam, char **argv, char *ops, int func)
+bin_getcap(char *nam, char **argv, Options ops, int func)
{
int ret = 0;
do {
- char *result;
+ char *result = NULL;
ssize_t length;
cap_t caps = cap_get_file(*argv);
if(caps)
@@ -79,13 +79,13 @@ bin_getcap(char *nam, char **argv, char *ops, int func)
ret = 1;
} else
printf("%s %s\n", *argv, result);
- cap_free(&caps);
+ cap_free(caps);
} while(*++argv);
return ret;
}
static int
-bin_setcap(char *nam, char **argv, char *ops, int func)
+bin_setcap(char *nam, char **argv, Options ops, int func)
{
cap_t caps;
int ret = 0;
@@ -102,7 +102,7 @@ bin_setcap(char *nam, char **argv, char *ops, int func)
ret = 1;
}
} while(*++argv);
- cap_free(&caps);
+ cap_free(caps);
return ret;
}
@@ -124,18 +124,29 @@ static struct builtin bintab[] = {
/**/
int
-boot_cap(Module m)
+setup_(Module m)
{
- return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ return 0;
}
-#ifdef MODULE
+/**/
+int
+boot_(Module m)
+{
+ return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+}
/**/
int
-cleanup_cap(Module m)
+cleanup_(Module m)
{
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
return 0;
}
-#endif
+
+/**/
+int
+finish_(Module m)
+{
+ return 0;
+}
diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c
index 1a41b7448..335f0fc80 100644
--- a/Src/Modules/clone.c
+++ b/Src/Modules/clone.c
@@ -41,7 +41,7 @@
/**/
static int
-bin_clone(char *nam, char **args, char *ops, int func)
+bin_clone(char *nam, char **args, Options ops, int func)
{
int ttyfd, pid;
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index 4c2bcf791..e43f12b24 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -32,7 +32,7 @@
#include <time.h>
static int
-bin_strftime(char *nam, char **argv, char *ops, int func)
+bin_strftime(char *nam, char **argv, Options ops, int func)
{
int bufsize, x;
char *endptr = NULL, *buffer = NULL;
diff --git a/Src/Modules/example.c b/Src/Modules/example.c
index 45ef3c28f..793d743fc 100644
--- a/Src/Modules/example.c
+++ b/Src/Modules/example.c
@@ -30,47 +30,203 @@
#include "example.mdh"
#include "example.pro"
+/* parameters */
+
+static zlong intparam;
+static char *strparam;
+static char **arrparam;
+
+
/**/
static int
-bin_example(char *nam, char **args, char *ops, int func)
+bin_example(char *nam, char **args, Options ops, int func)
{
unsigned char c;
+ char **oargs = args, **p = arrparam;
+ long i = 0;
printf("Options: ");
for (c = 32; ++c < 128;)
- if (ops[c])
+ if (OPT_ISSET(ops,c))
putchar(c);
printf("\nArguments:");
- for (; *args; args++) {
+ for (; *args; i++, args++) {
putchar(' ');
fputs(*args, stdout);
}
printf("\nName: %s\n", nam);
+#ifdef ZSH_64_BIT_TYPE
+ printf("\nInteger Parameter: %s\n", output64(intparam));
+#else
+ printf("\nInteger Parameter: %ld\n", intparam);
+#endif
+ printf("String Parameter: %s\n", strparam ? strparam : "");
+ printf("Array Parameter:");
+ if (p)
+ while (*p) printf(" %s", *p++);
+ printf("\n");
+
+ intparam = i;
+ zsfree(strparam);
+ strparam = ztrdup(*oargs ? *oargs : "");
+ freearray(arrparam);
+ arrparam = zarrdup(oargs);
return 0;
}
+/**/
+static int
+cond_p_len(char **a, int id)
+{
+ char *s1 = cond_str(a, 0, 0);
+
+ if (a[1]) {
+ zlong v = cond_val(a, 1);
+
+ return strlen(s1) == v;
+ } else {
+ return !s1[0];
+ }
+}
+
+/**/
+static int
+cond_i_ex(char **a, int id)
+{
+ char *s1 = cond_str(a, 0, 0), *s2 = cond_str(a, 1, 0);
+
+ return !strcmp("example", dyncat(s1, s2));
+}
+
+/**/
+static mnumber
+math_sum(char *name, int argc, mnumber *argv, int id)
+{
+ mnumber ret;
+ int f = 0;
+
+ ret.u.l = 0;
+ while (argc--) {
+ if (argv->type == MN_INTEGER) {
+ if (f)
+ ret.u.d += (double) argv->u.l;
+ else
+ ret.u.l += argv->u.l;
+ } else {
+ if (f)
+ ret.u.d += argv->u.d;
+ else {
+ ret.u.d = ((double) ret.u.l) + ((double) argv->u.d);
+ f = 1;
+ }
+ }
+ argv++;
+ }
+ ret.type = (f ? MN_FLOAT : MN_INTEGER);
+
+ return ret;
+}
+
+/**/
+static mnumber
+math_length(char *name, char *arg, int id)
+{
+ mnumber ret;
+
+ ret.type = MN_INTEGER;
+ ret.u.l = strlen(arg);
+
+ return ret;
+}
+
+/**/
+static int
+ex_wrapper(Eprog prog, FuncWrap w, char *name)
+{
+ if (strncmp(name, "example", 7))
+ return 1;
+ else {
+ int ogd = opts[GLOBDOTS];
+
+ opts[GLOBDOTS] = 1;
+ runshfunc(prog, w, name);
+ opts[GLOBDOTS] = ogd;
+
+ return 0;
+ }
+}
+
/*
- * boot_example is executed when the module is loaded.
+ * boot_ is executed when the module is loaded.
*/
static struct builtin bintab[] = {
BUILTIN("example", 0, bin_example, 0, -1, 0, "flags", NULL),
};
+static struct conddef cotab[] = {
+ CONDDEF("len", 0, cond_p_len, 1, 2, 0),
+ CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
+};
+
+static struct paramdef patab[] = {
+ INTPARAMDEF("exint", &intparam),
+ STRPARAMDEF("exstr", &strparam),
+ ARRPARAMDEF("exarr", &arrparam),
+};
+
+static struct mathfunc mftab[] = {
+ NUMMATHFUNC("sum", math_sum, 1, -1, 0),
+ STRMATHFUNC("length", math_length, 0),
+};
+
+static struct funcwrap wrapper[] = {
+ WRAPDEF(ex_wrapper),
+};
+
/**/
int
-boot_example(Module m)
+setup_(Module m)
{
- return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ printf("The example module has now been set up.\n");
+ fflush(stdout);
+ return 0;
}
-#ifdef MODULE
+/**/
+int
+boot_(Module m)
+{
+ intparam = 42;
+ strparam = ztrdup("example");
+ arrparam = (char **) zalloc(3 * sizeof(char *));
+ arrparam[0] = ztrdup("example");
+ arrparam[1] = ztrdup("array");
+ arrparam[2] = NULL;
+ return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
+ addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) |
+ addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)) |
+ addmathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab)) |
+ !addwrapper(m, wrapper));
+}
/**/
int
-cleanup_example(Module m)
+cleanup_(Module m)
{
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
+ deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab));
+ deletemathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
+ deletewrapper(m, wrapper);
+ return 0;
+}
+
+/**/
+int
+finish_(Module m)
+{
+ printf("Thank you for using the example module. Have a nice day.\n");
+ fflush(stdout);
return 0;
}
-#endif
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index 6d962efd1..51f362631 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -56,7 +56,7 @@ ask(void)
/**/
static int
-bin_sync(char *nam, char **args, char *ops, int func)
+bin_sync(char *nam, char **args, Options ops, int func)
{
sync();
return 0;
@@ -66,14 +66,14 @@ bin_sync(char *nam, char **args, char *ops, int func)
/**/
static int
-bin_mkdir(char *nam, char **args, char *ops, int func)
+bin_mkdir(char *nam, char **args, Options ops, int func)
{
mode_t oumask = umask(0);
mode_t mode = 0777 & ~oumask;
int err = 0;
umask(oumask);
- if(ops['m']) {
+ if(OPT_ISSET(ops,'m')) {
char *str = *args++, *ptr;
if(!*args) {
@@ -91,7 +91,7 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
while(ptr > *args + (**args == '/') && *--ptr == '/')
*ptr = 0;
- if(ops['p']) {
+ if(OPT_ISSET(ops,'p')) {
char *ptr = *args;
for(;;) {
@@ -147,7 +147,7 @@ domkdir(char *nam, char *path, mode_t mode, int p)
/**/
static int
-bin_rmdir(char *nam, char **args, char *ops, int func)
+bin_rmdir(char *nam, char **args, Options ops, int func)
{
int err = 0;
@@ -183,7 +183,7 @@ bin_rmdir(char *nam, char **args, char *ops, int func)
/**/
static int
-bin_ln(char *nam, char **args, char *ops, int func)
+bin_ln(char *nam, char **args, Options ops, int func)
{
MoveFunc move;
int flags, err = 0;
@@ -194,22 +194,22 @@ bin_ln(char *nam, char **args, char *ops, int func)
if(func == BIN_MV) {
move = (MoveFunc) rename;
- flags = ops['f'] ? 0 : MV_ASKNW;
+ flags = OPT_ISSET(ops,'f') ? 0 : MV_ASKNW;
flags |= MV_ATOMIC;
} else {
- flags = ops['f'] ? MV_FORCE : 0;
+ flags = OPT_ISSET(ops,'f') ? MV_FORCE : 0;
#ifdef HAVE_LSTAT
- if(ops['s'])
+ if(OPT_ISSET(ops,'s'))
move = (MoveFunc) symlink;
else
#endif
{
move = (MoveFunc) link;
- if(!ops['d'])
+ if(!OPT_ISSET(ops,'d'))
flags |= MV_NODIRS;
}
}
- if(ops['i'] && !ops['f'])
+ if(OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f'))
flags |= MV_INTER;
for(a = args; a[1]; a++) ;
if(a != args) {
@@ -567,18 +567,20 @@ rm_dirpost(char *arg, char *rp, struct stat const *sp, void *magic)
/**/
static int
-bin_rm(char *nam, char **args, char *ops, int func)
+bin_rm(char *nam, char **args, Options ops, int func)
{
struct rmmagic rmm;
int err;
rmm.nam = nam;
- rmm.opt_force = ops['f'];
- rmm.opt_interact = ops['i'] && !ops['f'];
- rmm.opt_unlinkdir = ops['d'];
- err = recursivecmd(nam, ops['f'], ops['r'] && !ops['d'], ops['s'],
+ rmm.opt_force = OPT_ISSET(ops,'f');
+ rmm.opt_interact = OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f');
+ rmm.opt_unlinkdir = OPT_ISSET(ops,'d');
+ err = recursivecmd(nam, OPT_ISSET(ops,'f'),
+ OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'d'),
+ OPT_ISSET(ops,'s'),
args, recurse_donothing, rm_dirpost, rm_leaf, &rmm);
- return ops['f'] ? 0 : err;
+ return OPT_ISSET(ops,'f') ? 0 : err;
}
/* chown builtin */
@@ -620,7 +622,7 @@ enum { BIN_CHOWN, BIN_CHGRP };
/**/
static int
-bin_chown(char *nam, char **args, char *ops, int func)
+bin_chown(char *nam, char **args, Options ops, int func)
{
struct chownmagic chm;
char *uspec = ztrdup(*args), *p = uspec;
@@ -685,7 +687,7 @@ bin_chown(char *nam, char **args, char *ops, int func)
chm.gid = -1;
}
free(uspec);
- return recursivecmd(nam, 0, ops['R'], ops['s'],
+ return recursivecmd(nam, 0, OPT_ISSET(ops,'R'), OPT_ISSET(ops,'s'),
args + 1, chown_dochown, recurse_donothing, chown_dochown, &chm);
}
diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c
index b6304ff01..36c437bc3 100644
--- a/Src/Modules/pcre.c
+++ b/Src/Modules/pcre.c
@@ -40,15 +40,15 @@ static pcre_extra *pcre_hints;
/**/
static int
-bin_pcre_compile(char *nam, char **args, char *ops, int func)
+bin_pcre_compile(char *nam, char **args, Options ops, int func)
{
int pcre_opts = 0, pcre_errptr;
const char *pcre_error;
- if(ops['a']) pcre_opts |= PCRE_ANCHORED;
- if(ops['i']) pcre_opts |= PCRE_CASELESS;
- if(ops['m']) pcre_opts |= PCRE_MULTILINE;
- if(ops['x']) pcre_opts |= PCRE_EXTENDED;
+ if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED;
+ if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS;
+ if(OPT_ISSET(ops,'m')) pcre_opts |= PCRE_MULTILINE;
+ if(OPT_ISSET(ops,'x')) pcre_opts |= PCRE_EXTENDED;
pcre_hints = NULL; /* Is this necessary? */
@@ -68,7 +68,7 @@ bin_pcre_compile(char *nam, char **args, char *ops, int func)
/**/
static int
-bin_pcre_study(char *nam, char **args, char *ops, int func)
+bin_pcre_study(char *nam, char **args, Options ops, int func)
{
const char *pcre_error;
@@ -92,12 +92,12 @@ bin_pcre_study(char *nam, char **args, char *ops, int func)
/**/
static int
-bin_pcre_match(char *nam, char **args, char *ops, int func)
+bin_pcre_match(char *nam, char **args, Options ops, int func)
{
int ret, capcount, *ovec, ovecsize;
char **captures, **matches, *receptacle = NULL;
- if(ops['a']) {
+ if(OPT_ISSET(ops,'a')) {
receptacle = *args++;
if(!*args) {
zwarnnam(nam, "not enough arguments", NULL, 0);
diff --git a/Src/Modules/socket.c b/Src/Modules/socket.c
index b676e2d36..2b70eba6d 100644
--- a/Src/Modules/socket.c
+++ b/Src/Modules/socket.c
@@ -58,7 +58,7 @@
#endif
static int
-bin_zsocket(char *nam, char **args, char *ops, int func)
+bin_zsocket(char *nam, char **args, Options ops, int func)
{
int err=1, verbose=0, test=0, targetfd=0;
SOCKLEN_T len;
@@ -66,13 +66,13 @@ bin_zsocket(char *nam, char **args, char *ops, int func)
struct sockaddr_un soun;
int sfd;
- if (ops['v'])
+ if (OPT_ISSET(ops,'v'))
verbose = 1;
- if (ops['t'])
+ if (OPT_ISSET(ops,'t'))
test = 1;
- if (ops['d']) {
+ if (OPT_ISSET(ops,'d')) {
targetfd = atoi(args[0]);
dargs = args + 1;
if (!targetfd) {
@@ -84,7 +84,7 @@ bin_zsocket(char *nam, char **args, char *ops, int func)
dargs = args;
- if (ops['l']) {
+ if (OPT_ISSET(ops,'l')) {
char *localfn;
if (!dargs[0]) {
@@ -135,7 +135,7 @@ bin_zsocket(char *nam, char **args, char *ops, int func)
return 0;
}
- else if (ops['a'])
+ else if (OPT_ISSET(ops,'a'))
{
int lfd, rfd;
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 335f7271e..5b5479711 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -341,7 +341,7 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
*/
/**/
static int
-bin_stat(char *name, char **args, char *ops, int func)
+bin_stat(char *name, char **args, Options ops, int func)
{
char **aptr, *arrnam = NULL, **array = NULL, **arrptr = NULL;
char *hashnam = NULL, **hash = NULL, **hashptr = NULL;
@@ -376,12 +376,12 @@ bin_stat(char *name, char **args, char *ops, int func)
}
/* if name of link requested, turn on lstat */
if (iwhich == ST_READLINK)
- ops['L'] = 1;
+ ops->ind['L'] = 1;
flags |= STF_PICK;
} else {
for (; *arg; arg++) {
if (strchr("glLnNorstT", *arg))
- ops[STOUC(*arg)] = 1;
+ ops->ind[STOUC(*arg)] = 1;
else if (*arg == 'A') {
if (arg[1]) {
arrnam = arg+1;
@@ -404,7 +404,7 @@ bin_stat(char *name, char **args, char *ops, int func)
break;
} else if (*arg == 'f') {
char *sfd;
- ops['f'] = 1;
+ ops->ind['f'] = 1;
if (arg[1]) {
sfd = arg+1;
} else if (!(sfd = *++args)) {
@@ -425,7 +425,7 @@ bin_stat(char *name, char **args, char *ops, int func)
return 1;
}
/* force string format in order to use time format */
- ops['s'] = 1;
+ ops->ind['s'] = 1;
break;
} else {
zwarnnam(name, "bad option: -%c", NULL, *arg);
@@ -444,7 +444,7 @@ bin_stat(char *name, char **args, char *ops, int func)
* be similar to stat -A foo -A bar filename */
}
- if (ops['l']) {
+ if (OPT_ISSET(ops,'l')) {
/* list types and return: can also list to array */
if (arrnam) {
arrptr = array = (char **)zalloc((ST_COUNT+1)*sizeof(char *));
@@ -468,34 +468,34 @@ bin_stat(char *name, char **args, char *ops, int func)
return 0;
}
- if (!*args && !ops['f']) {
+ if (!*args && !OPT_ISSET(ops,'f')) {
zwarnnam(name, "no files given", NULL, 0);
return 1;
- } else if (*args && ops['f']) {
+ } else if (*args && OPT_ISSET(ops,'f')) {
zwarnnam(name, "no files allowed with -f", NULL, 0);
return 1;
}
nargs = 0;
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
nargs = 1;
else
for (aptr = args; *aptr; aptr++)
nargs++;
- if (ops['g']) {
+ if (OPT_ISSET(ops,'g')) {
flags |= STF_GMT;
- ops['s'] = 1;
+ ops->ind['s'] = 1;
}
- if (ops['s'] || ops['r'])
+ if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'r'))
flags |= STF_STRING;
- if (ops['r'] || !ops['s'])
+ if (OPT_ISSET(ops,'r') || !OPT_ISSET(ops,'s'))
flags |= STF_RAW;
- if (ops['n'])
+ if (OPT_ISSET(ops,'n'))
flags |= STF_FILE;
- if (ops['o'])
+ if (OPT_ISSET(ops,'o'))
flags |= STF_OCTAL;
- if (ops['t'])
+ if (OPT_ISSET(ops,'t'))
flags |= STF_NAME;
if (!(arrnam || hashnam)) {
@@ -505,9 +505,9 @@ bin_stat(char *name, char **args, char *ops, int func)
flags |= STF_NAME;
}
- if (ops['N'] || ops['f'])
+ if (OPT_ISSET(ops,'N') || OPT_ISSET(ops,'f'))
flags &= ~STF_FILE;
- if (ops['T'] || ops['H'])
+ if (OPT_ISSET(ops,'T') || OPT_ISSET(ops,'H'))
flags &= ~STF_NAME;
if (hashnam) {
@@ -529,16 +529,18 @@ bin_stat(char *name, char **args, char *ops, int func)
arrptr = array = (char **)zcalloc((arrsize+1)*sizeof(char *));
}
- for (; ops['f'] || *args; args++) {
+ for (; OPT_ISSET(ops,'f') || *args; args++) {
char outbuf[PATH_MAX + 9]; /* "link " + link name + NULL */
- int rval = ops['f'] ? fstat(fd, &statbuf) :
- ops['L'] ? lstat(*args, &statbuf) : stat(*args, &statbuf);
+ int rval = OPT_ISSET(ops,'f') ? fstat(fd, &statbuf) :
+ OPT_ISSET(ops,'L') ? lstat(*args, &statbuf) :
+ stat(*args, &statbuf);
if (rval) {
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
sprintf(outbuf, "%d", fd);
- zwarnnam(name, "%s: %e", ops['f'] ? outbuf : *args, errno);
+ zwarnnam(name, "%s: %e", OPT_ISSET(ops,'f') ? outbuf : *args,
+ errno);
ret = 1;
- if (ops['f'] || arrnam)
+ if (OPT_ISSET(ops,'f') || arrnam)
break;
else
continue;
@@ -558,7 +560,7 @@ bin_stat(char *name, char **args, char *ops, int func)
if (arrnam)
*arrptr++ = ztrdup(outbuf);
else if (hashnam) {
- /* STF_NAME explicitly turned off for ops['H'] above */
+ /* STF_NAME explicitly turned off for ops.ind['H'] above */
*hashptr++ = ztrdup(statelts[iwhich]);
*hashptr++ = ztrdup(outbuf);
} else
@@ -570,14 +572,14 @@ bin_stat(char *name, char **args, char *ops, int func)
if (arrnam)
*arrptr++= ztrdup(outbuf);
else if (hashnam) {
- /* STF_NAME explicitly turned off for ops['H'] above */
+ /* STF_NAME explicitly turned off for ops.ind['H'] above */
*hashptr++ = ztrdup(statelts[i]);
*hashptr++ = ztrdup(outbuf);
} else
printf("%s\n", outbuf);
}
}
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
break;
if (!arrnam && !hashnam && args[1] && !(flags & STF_PICK))
diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c
index 5dc00d0bc..96dde66e3 100644
--- a/Src/Modules/tcp.c
+++ b/Src/Modules/tcp.c
@@ -336,7 +336,7 @@ tcp_connect(Tcp_session sess, char *addrp, struct hostent *zhost, int d_port)
}
static int
-bin_ztcp(char *nam, char **args, char *ops, int func)
+bin_ztcp(char *nam, char **args, Options ops, int func)
{
int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
SOCKLEN_T len;
@@ -345,16 +345,16 @@ bin_ztcp(char *nam, char **args, char *ops, int func)
struct servent *srv;
Tcp_session sess = NULL;
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
force = 1;
- if (ops['v'])
+ if (OPT_ISSET(ops,'v'))
verbose = 1;
- if (ops['t'])
+ if (OPT_ISSET(ops,'t'))
test = 1;
- if (ops['d']) {
+ if (OPT_ISSET(ops,'d')) {
targetfd = atoi(args[0]);
dargs = args + 1;
if (!targetfd) {
@@ -366,7 +366,7 @@ bin_ztcp(char *nam, char **args, char *ops, int func)
dargs = args;
- if (ops['c']) {
+ if (OPT_ISSET(ops,'c')) {
if (!dargs[0]) {
tcp_cleanup();
}
@@ -395,7 +395,7 @@ bin_ztcp(char *nam, char **args, char *ops, int func)
}
}
}
- else if (ops['l']) {
+ else if (OPT_ISSET(ops,'l')) {
int lport = 0;
if (!dargs[0]) {
@@ -462,7 +462,7 @@ bin_ztcp(char *nam, char **args, char *ops, int func)
return 0;
}
- else if (ops['a'])
+ else if (OPT_ISSET(ops,'a'))
{
int lfd, rfd;
@@ -571,7 +571,7 @@ bin_ztcp(char *nam, char **args, char *ops, int func)
remotename = ztpeer->h_name;
else
remotename = ztrdup(inet_ntoa(sess->peer.in.sin_addr));
- if (ops['L']) {
+ if (OPT_ISSET(ops,'L')) {
int schar;
if (sess->flags & ZTCP_ZFTP)
schar = 'Z';
diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c
index 8ec8919d9..177a0d5c7 100644
--- a/Src/Modules/termcap.c
+++ b/Src/Modules/termcap.c
@@ -103,7 +103,7 @@ ztgetflag(char *s)
/**/
static int
-bin_echotc(char *name, char **argv, char *ops, int func)
+bin_echotc(char *name, char **argv, Options ops, int func)
{
char *s, buf[2048], *t, *u;
int num, argct;
diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c
index 3f62f0367..732495891 100644
--- a/Src/Modules/terminfo.c
+++ b/Src/Modules/terminfo.c
@@ -57,7 +57,7 @@ static Param terminfo_pm;
/**/
static int
-bin_echoti(char *name, char **argv, char *ops, int func)
+bin_echoti(char *name, char **argv, Options ops, int func)
{
char *s, *t;
int num;
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index de762e883..918061e42 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -2951,7 +2951,7 @@ zftp_rmsession(char *name, char **args, int flags)
/**/
static int
-bin_zftp(char *name, char **args, char *ops, int func)
+bin_zftp(char *name, char **args, Options ops, int func)
{
char fullname[20] = "zftp ";
char *cnam = *args++, *prefs, *ptr;
diff --git a/Src/Modules/zprof.c b/Src/Modules/zprof.c
index 9c7acb334..3121efacf 100644
--- a/Src/Modules/zprof.c
+++ b/Src/Modules/zprof.c
@@ -136,9 +136,9 @@ cmpparcs(Parc *a, Parc *b)
}
static int
-bin_zprof(char *nam, char **args, char *ops, int func)
+bin_zprof(char *nam, char **args, Options ops, int func)
{
- if (ops['c']) {
+ if (OPT_ISSET(ops,'c')) {
freepfuncs(calls);
calls = NULL;
ncalls = 0;
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index ad5d2ab39..1be615610 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -603,20 +603,23 @@ ptywrite(Ptycmd cmd, char **args, int nonl)
/**/
static int
-bin_zpty(char *nam, char **args, char *ops, int func)
+bin_zpty(char *nam, char **args, Options ops, int func)
{
- if ((ops['r'] && ops['w']) ||
- ((ops['r'] || ops['w']) && (ops['d'] || ops['e'] ||
- ops['b'] || ops['L'])) ||
- (ops['w'] && ops['t']) ||
- (ops['n'] && (ops['b'] || ops['e'] || ops['r'] || ops['t'] ||
- ops['d'] || ops['L'])) ||
- (ops['d'] && (ops['b'] || ops['e'] || ops['L'] || ops['t'])) ||
- (ops['L'] && (ops['b'] || ops['e']))) {
+ if ((OPT_ISSET(ops,'r') && OPT_ISSET(ops,'w')) ||
+ ((OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) &&
+ (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'e') ||
+ OPT_ISSET(ops,'b') || OPT_ISSET(ops,'L'))) ||
+ (OPT_ISSET(ops,'w') && OPT_ISSET(ops,'t')) ||
+ (OPT_ISSET(ops,'n') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
+ OPT_ISSET(ops,'r') || OPT_ISSET(ops,'t') ||
+ OPT_ISSET(ops,'d') || OPT_ISSET(ops,'L'))) ||
+ (OPT_ISSET(ops,'d') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
+ OPT_ISSET(ops,'L') || OPT_ISSET(ops,'t'))) ||
+ (OPT_ISSET(ops,'L') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e')))) {
zwarnnam(nam, "illegal option combination", NULL, 0);
return 1;
}
- if (ops['r'] || ops['w']) {
+ if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) {
Ptycmd p;
if (!*args) {
@@ -628,13 +631,14 @@ bin_zpty(char *nam, char **args, char *ops, int func)
}
if (p->fin)
return 2;
- if (ops['t'] && p->read == -1 && !read_poll(p->fd, &p->read, 0))
+ if (OPT_ISSET(ops,'t') && p->read == -1 &&
+ !read_poll(p->fd, &p->read, 0))
return 1;
- return (ops['r'] ?
+ return (OPT_ISSET(ops,'r') ?
ptyread(nam, p, args + 1) :
- ptywrite(p, args + 1, ops['n']));
- } else if (ops['d']) {
+ ptywrite(p, args + 1, OPT_ISSET(ops,'n')));
+ } else if (OPT_ISSET(ops,'d')) {
Ptycmd p;
int ret = 0;
@@ -650,7 +654,7 @@ bin_zpty(char *nam, char **args, char *ops, int func)
deleteallptycmds();
return ret;
- } else if (ops['t']) {
+ } else if (OPT_ISSET(ops,'t')) {
Ptycmd p;
if (!*args) {
@@ -671,14 +675,15 @@ bin_zpty(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "pty command name already used: %s", *args, 0);
return 1;
}
- return newptycmd(nam, *args, args + 1, ops['e'], ops['b']);
+ return newptycmd(nam, *args, args + 1, OPT_ISSET(ops,'e'),
+ OPT_ISSET(ops,'b'));
} else {
Ptycmd p;
char **a;
for (p = ptycmds; p; p = p->next) {
checkptycmd(p);
- if (ops['L'])
+ if (OPT_ISSET(ops,'L'))
printf("%s %s%s%s ", nam, (p->echo ? "-e " : ""),
(p->nblock ? "-b " : ""), p->name);
else if (p->fin)
diff --git a/Src/Modules/zselect.c b/Src/Modules/zselect.c
index 2eee59d03..25954559b 100644
--- a/Src/Modules/zselect.c
+++ b/Src/Modules/zselect.c
@@ -62,7 +62,7 @@ handle_digits(char *nam, char *argptr, fd_set *fdset, int *fdmax)
/**/
static int
-bin_zselect(char *nam, char **args, char *ops, int func)
+bin_zselect(char *nam, char **args, Options ops, int func)
{
#ifdef HAVE_SELECT
int i, fd, fdsetind = 0, fdmax = 0, fdcount;
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index cb099bbcc..4ef237d90 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -254,7 +254,7 @@ lookupstyle(char *ctxt, char *style)
}
static int
-bin_zstyle(char *nam, char **args, char *ops, int func)
+bin_zstyle(char *nam, char **args, Options ops, int func)
{
int min, max, n, add = 0, list = 0, eval = 0;
@@ -550,7 +550,7 @@ bin_zstyle(char *nam, char **args, char *ops, int func)
/* Format stuff. */
static int
-bin_zformat(char *nam, char **args, char *ops, int func)
+bin_zformat(char *nam, char **args, Options ops, int func)
{
char opt;
@@ -1161,7 +1161,7 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp)
*/
static int
-bin_zregexparse(char *nam, char **args, char *ops, int func)
+bin_zregexparse(char *nam, char **args, Options ops, int func)
{
int oldextendedglob = opts[EXTENDEDGLOB];
char *var1 = args[0];
@@ -1187,7 +1187,7 @@ bin_zregexparse(char *nam, char **args, char *ops, int func)
ret = 0;
if (!ret)
- ret = rmatch(&result, subj, var1, var2, ops['c']);
+ ret = rmatch(&result, subj, var1, var2, OPT_ISSET(ops,'c'));
popheap();
opts[EXTENDEDGLOB] = oldextendedglob;
@@ -1315,7 +1315,7 @@ add_opt_val(Zoptdesc d, char *arg)
}
static int
-bin_zparseopts(char *nam, char **args, char *ops, int func)
+bin_zparseopts(char *nam, char **args, Options ops, int func)
{
char *o, *p, *n, **pp, **aval, **ap, *assoc = NULL, **cp, **np;
int del = 0, f, extract = 0, keep = 0;
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index a84f604cc..69f742731 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -187,7 +187,7 @@ freecompcond(void *a)
/**/
int
-compctlread(char *name, char **args, char *ops, char *reply)
+compctlread(char *name, char **args, Options ops, char *reply)
{
char *buf, *bptr;
@@ -198,15 +198,15 @@ compctlread(char *name, char **args, char *ops, char *reply)
return 1;
}
- if (ops['l']) {
+ if (OPT_ISSET(ops,'l')) {
/* -ln gives the index of the word the cursor is currently on, which is
available in cs (but remember that Zsh counts from one, not zero!) */
- if (ops['n']) {
+ if (OPT_ISSET(ops,'n')) {
char nbuf[14];
- if (ops['e'] || ops['E'])
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
printf("%d\n", cs + 1);
- if (!ops['e']) {
+ if (!OPT_ISSET(ops,'e')) {
sprintf(nbuf, "%d", cs + 1);
setsparam(reply, ztrdup(nbuf));
}
@@ -214,11 +214,11 @@ compctlread(char *name, char **args, char *ops, char *reply)
}
/* without -n, the current line is assigned to the given parameter as a
scalar */
- if (ops['e'] || ops['E']) {
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
zputs((char *) line, stdout);
putchar('\n');
}
- if (!ops['e'])
+ if (!OPT_ISSET(ops,'e'))
setsparam(reply, ztrdup((char *) line));
} else {
int i;
@@ -226,12 +226,12 @@ compctlread(char *name, char **args, char *ops, char *reply)
/* -cn gives the current cursor position within the current word, which
is available in clwpos (but remember that Zsh counts from one, not
zero!) */
- if (ops['n']) {
+ if (OPT_ISSET(ops,'n')) {
char nbuf[14];
- if (ops['e'] || ops['E'])
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
printf("%d\n", clwpos + 1);
- if (!ops['e']) {
+ if (!OPT_ISSET(ops,'e')) {
sprintf(nbuf, "%d", clwpos + 1);
setsparam(reply, ztrdup(nbuf));
}
@@ -239,7 +239,7 @@ compctlread(char *name, char **args, char *ops, char *reply)
}
/* without -n, the words of the current line are assigned to the given
parameters separately */
- if (ops['A'] && !ops['e']) {
+ if (OPT_ISSET(ops,'A') && !OPT_ISSET(ops,'e')) {
/* the -A option means that one array is specified, instead of
many parameters */
char **p, **b = (char **)zcalloc((clwnum + 1) * sizeof(char *));
@@ -250,13 +250,13 @@ compctlread(char *name, char **args, char *ops, char *reply)
setaparam(reply, b);
return 0;
}
- if (ops['e'] || ops['E']) {
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
for (i = 0; i < clwnum; i++) {
zputs(clwords[i], stdout);
putchar('\n');
}
- if (ops['e'])
+ if (OPT_ISSET(ops,'e'))
return 0;
}
@@ -1572,7 +1572,7 @@ printcompctlp(HashNode hn, int printflags)
/**/
static int
-bin_compctl(char *name, char **argv, char *ops, int func)
+bin_compctl(char *name, char **argv, Options ops, int func)
{
Compctl cc = NULL;
int ret = 0;
@@ -1678,14 +1678,14 @@ bin_compctl(char *name, char **argv, char *ops, int func)
#define CFN_DEFAULT 2
static int
-bin_compcall(char *name, char **argv, char *ops, int func)
+bin_compcall(char *name, char **argv, Options ops, int func)
{
if (incompfunc != 1) {
zwarnnam(name, "can only be called from completion function", NULL, 0);
return 1;
}
- return makecomplistctl((ops['T'] ? 0 : CFN_FIRST) |
- (ops['D'] ? 0 : CFN_DEFAULT));
+ return makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
+ (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
}
/*
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index ef029ddcb..713ce7f9e 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -421,7 +421,7 @@ parse_class(Cpattern p, unsigned char *s, unsigned char e)
/**/
static int
-bin_compadd(char *name, char **argv, char *ops, int func)
+bin_compadd(char *name, char **argv, Options ops, int func)
{
struct cadata dat;
char *p, **sp, *e, *m = NULL, *mstr = NULL;
@@ -866,7 +866,7 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
/**/
static int
-bin_compset(char *name, char **argv, char *ops, int func)
+bin_compset(char *name, char **argv, Options ops, int func)
{
int test = 0, na = 0, nb = 0;
char *sa = NULL, *sb = NULL;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 412347ec9..7fa4364df 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -717,7 +717,7 @@ cd_get(char **params)
/**/
static int
-bin_compdescribe(char *nam, char **args, char *ops, int func)
+bin_compdescribe(char *nam, char **args, Options ops, int func)
{
int n = arrlen(args);
@@ -2259,7 +2259,7 @@ ca_set_data(LinkList descr, LinkList act, LinkList subc,
}
static int
-bin_comparguments(char *nam, char **args, char *ops, int func)
+bin_comparguments(char *nam, char **args, Options ops, int func)
{
int min, max, n;
Castate lstate = &ca_laststate;
@@ -3136,7 +3136,7 @@ cv_parse_word(Cvdef d)
}
static int
-bin_compvalues(char *nam, char **args, char *ops, int func)
+bin_compvalues(char *nam, char **args, Options ops, int func)
{
int min, max, n;
@@ -3349,7 +3349,7 @@ comp_quote(char *str, int prefix)
}
static int
-bin_compquote(char *nam, char **args, char *ops, int func)
+bin_compquote(char *nam, char **args, Options ops, int func)
{
char *name;
struct value vbuf;
@@ -3372,7 +3372,8 @@ bin_compquote(char *nam, char **args, char *ops, int func)
if ((v = getvalue(&vbuf, &name, 0))) {
switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR:
- setstrvalue(v, ztrdup(comp_quote(getstrvalue(v), ops['p'])));
+ setstrvalue(v, ztrdup(comp_quote(getstrvalue(v),
+ OPT_ISSET(ops,'p'))));
break;
case PM_ARRAY:
{
@@ -3382,7 +3383,7 @@ bin_compquote(char *nam, char **args, char *ops, int func)
char **p = new;
for (; *val; val++, p++)
- *p = ztrdup(comp_quote(*val, ops['p']));
+ *p = ztrdup(comp_quote(*val, OPT_ISSET(ops,'p')));
*p = NULL;
setarrvalue(v, new);
@@ -3499,7 +3500,7 @@ arrcontains(char **a, char *s, int colon)
}
static int
-bin_comptags(char *nam, char **args, char *ops, int func)
+bin_comptags(char *nam, char **args, Options ops, int func)
{
int min, max, n, level;
@@ -3629,7 +3630,7 @@ bin_comptags(char *nam, char **args, char *ops, int func)
}
static int
-bin_comptry(char *nam, char **args, char *ops, int func)
+bin_comptry(char *nam, char **args, Options ops, int func)
{
if (incompfunc != 1) {
zwarnnam(nam, "can only be called from completion function", NULL, 0);
@@ -4321,7 +4322,7 @@ cf_remove_other(char **names, char *pre, int *amb)
}
static int
-bin_compfiles(char *nam, char **args, char *ops, int func)
+bin_compfiles(char *nam, char **args, Options ops, int func)
{
if (incompfunc != 1) {
zwarnnam(nam, "can only be called from completion function", NULL, 0);
@@ -4423,7 +4424,7 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
}
static int
-bin_compgroups(char *nam, char **args, char *ops, int func)
+bin_compgroups(char *nam, char **args, Options ops, int func)
{
Heap oldheap;
char *n;
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 9fd5a9197..c36657697 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -604,12 +604,12 @@ keyisprefix(Keymap km, char *seq)
/**/
int
-bin_bindkey(char *name, char **argv, char *ops, int func)
+bin_bindkey(char *name, char **argv, Options ops, int func)
{
static struct opn {
char o;
char selp;
- int (*func) _((char *, char *, Keymap, char **, char *, char));
+ int (*func) _((char *, char *, Keymap, char **, Options, char));
int min, max;
} const opns[] = {
{ 'l', 0, bin_bindkey_lsmaps, 0, 0 },
@@ -628,15 +628,16 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
int n;
/* select operation and ensure no clashing arguments */
- for(op = opns; op->o && !ops[STOUC(op->o)]; op++) ;
+ for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ;
if(op->o)
for(opp = op; (++opp)->o; )
- if(ops[STOUC(opp->o)]) {
+ if(OPT_ISSET(ops,STOUC(opp->o))) {
zwarnnam(name, "incompatible operation selection options",
NULL, 0);
return 1;
}
- n = ops['e'] + ops['v'] + ops['a'] + ops['M'];
+ n = OPT_ISSET(ops,'e') + OPT_ISSET(ops,'v') +
+ OPT_ISSET(ops,'a') + OPT_ISSET(ops,'M');
if(!op->selp && n) {
zwarnnam(name, "keymap cannot be selected with -%c", NULL, op->o);
return 1;
@@ -648,13 +649,13 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
/* keymap selection */
if(op->selp) {
- if(ops['e'])
+ if(OPT_ISSET(ops,'e'))
kmname = "emacs";
- else if(ops['v'])
+ else if(OPT_ISSET(ops,'v'))
kmname = "viins";
- else if(ops['a'])
+ else if(OPT_ISSET(ops,'a'))
kmname = "vicmd";
- else if(ops['M']) {
+ else if(OPT_ISSET(ops,'M')) {
kmname = *argv++;
if(!kmname) {
zwarnnam(name, "-M option requires a keymap argument", NULL, 0);
@@ -667,7 +668,7 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
zwarnnam(name, "no such keymap `%s'", kmname, 0);
return 1;
}
- if(ops['e'] || ops['v'])
+ if(OPT_ISSET(ops,'e') || OPT_ISSET(ops,'v'))
linkkeymap(km, "main", 0);
} else {
kmname = NULL;
@@ -676,7 +677,7 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
/* listing is a special case */
if(!op->o && (!argv[0] || !argv[1])) {
- if(ops['e'] || ops['v'])
+ if(OPT_ISSET(ops,'e') || OPT_ISSET(ops,'v'))
return 0;
return bin_bindkey_list(name, kmname, km, argv, ops, op->o);
}
@@ -699,9 +700,9 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
/**/
static int
-bin_bindkey_lsmaps(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_lsmaps(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
- scanhashtable(keymapnamtab, 1, 0, 0, scanlistmaps, ops['L']);
+ scanhashtable(keymapnamtab, 1, 0, 0, scanlistmaps, OPT_ISSET(ops,'L'));
return 0;
}
@@ -725,7 +726,7 @@ scanlistmaps(HashNode hn, int list)
/**/
static int
-bin_bindkey_delall(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_delall(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
keymapnamtab->emptytable(keymapnamtab);
default_bindings();
@@ -736,7 +737,7 @@ bin_bindkey_delall(char *name, char *kmname, Keymap km, char **argv, char *ops,
/**/
static int
-bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
int ret = 0;
@@ -755,7 +756,7 @@ bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
/**/
static int
-bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
km = openkeymap(argv[0]);
if(!km) {
@@ -772,7 +773,7 @@ bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
/**/
static int
-bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
KeymapName kmn = (KeymapName) keymapnamtab->getnode(keymapnamtab, argv[0]);
@@ -800,7 +801,7 @@ bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
/**/
static int
-bin_bindkey_meta(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_meta(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
char m[3], *str;
int i;
@@ -830,7 +831,7 @@ bin_bindkey_meta(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
/**/
static int
-bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
int ret = 0;
@@ -847,7 +848,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
zwarnnam(name, "keymap `%s' is protected", kmname, 0);
return 1;
}
- if (func == 'r' && ops['p']) {
+ if (func == 'r' && OPT_ISSET(ops,'p')) {
char *useq, *bseq;
int len;
struct remprefstate rps;
@@ -878,7 +879,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
}
bseq = getkeystring(useq, &len, 2, NULL);
seq = metafy(bseq, len, META_USEHEAP);
- if(ops['R']) {
+ if(OPT_ISSET(ops,'R')) {
int first, last;
char m[3];
@@ -924,13 +925,13 @@ scanremoveprefix(char *seq, Thingy bind, char *str, void *magic)
/**/
static int
-bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, char func)
+bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, Options ops, char func)
{
struct bindstate bs;
- bs.flags = ops['L'] ? BS_LIST : 0;
+ bs.flags = OPT_ISSET(ops,'L') ? BS_LIST : 0;
bs.kmname = kmname;
- if(argv[0] && !ops['p']) {
+ if(argv[0] && !OPT_ISSET(ops,'p')) {
int len;
char *seq;
@@ -944,7 +945,7 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
bindlistout(&bs);
} else {
/* empty prefix is equivalent to no prefix */
- if (ops['p'] && (!argv[0] || argv[0][0])) {
+ if (OPT_ISSET(ops,'p') && (!argv[0] || argv[0][0])) {
if (!argv[0]) {
zwarnnam(name, "option -p requires a prefix string", NULL, 0);
return 1;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index e1429a0d0..1c45d120c 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -951,7 +951,7 @@ mod_export char *varedarg;
/**/
static int
-bin_vared(char *name, char **args, char *ops, int func)
+bin_vared(char *name, char **args, Options ops, int func)
{
char *s, *t, *ova = varedarg;
struct value vbuf;
@@ -1012,11 +1012,11 @@ bin_vared(char *name, char **args, char *ops, int func)
break;
case 'h':
/* -h option -- enable history */
- ops['h'] = 1;
+ ops->ind['h'] = 1;
break;
case 'e':
/* -e option -- enable EOF */
- ops['e'] = 1;
+ ops->ind['e'] = 1;
break;
default:
/* unrecognised option character */
@@ -1113,14 +1113,14 @@ bin_vared(char *name, char **args, char *ops, int func)
varedarg = *args;
ifl = isfirstln;
- if (ops['h'])
+ if (OPT_ISSET(ops,'h'))
hbegin(2);
- isfirstln = ops['e'];
+ isfirstln = OPT_ISSET(ops,'e');
ieof = opts[IGNOREEOF];
opts[IGNOREEOF] = 0;
- t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0);
+ t = (char *) zleread(p1, p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0);
opts[IGNOREEOF] = ieof;
- if (ops['h'])
+ if (OPT_ISSET(ops,'h'))
hend(NULL);
isfirstln = ifl;
varedarg = ova;
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 7d6c5103e..503060d7b 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -324,11 +324,11 @@ deletezlefunction(Widget w)
/**/
int
-bin_zle(char *name, char **args, char *ops, int func)
+bin_zle(char *name, char **args, Options ops, int func)
{
static struct opn {
char o;
- int (*func) _((char *, char **, char *, char));
+ int (*func) _((char *, char **, Options, char));
int min, max;
} const opns[] = {
{ 'l', bin_zle_list, 0, -1 },
@@ -348,10 +348,10 @@ bin_zle(char *name, char **args, char *ops, int func)
int n;
/* select operation and ensure no clashing arguments */
- for(op = opns; op->o && !ops[STOUC(op->o)]; op++) ;
+ for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ;
if(op->o)
for(opp = op; (++opp)->o; )
- if(ops[STOUC(opp->o)]) {
+ if(OPT_ISSET(ops,STOUC(opp->o))) {
zwarnnam(name, "incompatible operation selection options",
NULL, 0);
return 1;
@@ -373,11 +373,11 @@ bin_zle(char *name, char **args, char *ops, int func)
/**/
static int
-bin_zle_list(char *name, char **args, char *ops, char func)
+bin_zle_list(char *name, char **args, Options ops, char func)
{
if (!*args) {
scanhashtable(thingytab, 1, 0, DISABLED, scanlistwidgets,
- (ops['a'] ? -1 : ops['L']));
+ (OPT_ISSET(ops,'a') ? -1 : OPT_ISSET(ops,'L')));
return 0;
} else {
int ret = 0;
@@ -385,7 +385,7 @@ bin_zle_list(char *name, char **args, char *ops, char func)
for (; *args && !ret; args++) {
if (!(t = (Thingy) thingytab->getnode2(thingytab, *args)) ||
- (!ops['a'] && (t->widget->flags & WIDGET_INT)))
+ (!OPT_ISSET(ops,'a') && (t->widget->flags & WIDGET_INT)))
ret = 1;
}
return ret;
@@ -394,7 +394,7 @@ bin_zle_list(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_refresh(char *name, char **args, char *ops, char func)
+bin_zle_refresh(char *name, char **args, Options ops, char func)
{
char *s = statusline;
int sl = statusll, ocl = clearlist;
@@ -421,11 +421,11 @@ bin_zle_refresh(char *name, char **args, char *ops, char func)
lastlistlen++;
showinglist = clearlist = 0;
zmult = zmultsav;
- } else if (ops['c']) {
+ } else if (OPT_ISSET(ops,'c')) {
clearlist = 1;
lastlistlen = 0;
}
- } else if (ops['c']) {
+ } else if (OPT_ISSET(ops,'c')) {
clearlist = listshown = 1;
lastlistlen = 0;
}
@@ -439,7 +439,7 @@ bin_zle_refresh(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_mesg(char *name, char **args, char *ops, char func)
+bin_zle_mesg(char *name, char **args, Options ops, char func)
{
if (!zleactive) {
zwarnnam(name, "can only be called from widget function", NULL, 0);
@@ -453,7 +453,7 @@ bin_zle_mesg(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_unget(char *name, char **args, char *ops, char func)
+bin_zle_unget(char *name, char **args, Options ops, char func)
{
char *b = *args, *p = b + strlen(b);
@@ -468,7 +468,7 @@ bin_zle_unget(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_keymap(char *name, char **args, char *ops, char func)
+bin_zle_keymap(char *name, char **args, Options ops, char func)
{
if (!zleactive) {
zwarnnam(name, "can only be called from widget function", NULL, 0);
@@ -522,7 +522,7 @@ scanlistwidgets(HashNode hn, int list)
/**/
static int
-bin_zle_del(char *name, char **args, char *ops, char func)
+bin_zle_del(char *name, char **args, Options ops, char func)
{
int ret = 0;
@@ -541,7 +541,7 @@ bin_zle_del(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_link(char *name, char **args, char *ops, char func)
+bin_zle_link(char *name, char **args, Options ops, char func)
{
Thingy t = (Thingy) thingytab->getnode(thingytab, args[0]);
@@ -558,7 +558,7 @@ bin_zle_link(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_new(char *name, char **args, char *ops, char func)
+bin_zle_new(char *name, char **args, Options ops, char func)
{
Widget w = zalloc(sizeof(*w));
@@ -574,7 +574,7 @@ bin_zle_new(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_complete(char *name, char **args, char *ops, char func)
+bin_zle_complete(char *name, char **args, Options ops, char func)
{
Thingy t;
Widget w, cw;
@@ -608,7 +608,7 @@ bin_zle_complete(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_call(char *name, char **args, char *ops, char func)
+bin_zle_call(char *name, char **args, Options ops, char func)
{
Thingy t;
struct modifier modsave;
@@ -672,7 +672,7 @@ bin_zle_call(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_invalidate(char *name, char **args, char *ops, char func)
+bin_zle_invalidate(char *name, char **args, Options ops, char func)
{
if (zleactive) {
if (!trashedzle)
@@ -684,7 +684,7 @@ bin_zle_invalidate(char *name, char **args, char *ops, char func)
/**/
static int
-bin_zle_fd(char *name, char **args, char *ops, char func)
+bin_zle_fd(char *name, char **args, Options ops, char func)
{
int fd = 0, i, found = 0;
char *endptr;
@@ -698,7 +698,7 @@ bin_zle_fd(char *name, char **args, char *ops, char func)
}
}
- if (ops['L'] || !*args) {
+ if (OPT_ISSET(ops,'L') || !*args) {
/* Listing handlers. */
if (*args && args[1]) {
zwarnnam(name, "too many arguments for -FL", NULL, 0);
diff --git a/Src/builtin.c b/Src/builtin.c
index a8174a2bc..1bf26aeb8 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -46,14 +46,14 @@ static struct builtin builtins[] =
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmr", NULL),
- BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "tUXwkz", "u"),
+ BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "tUXwkz", "u"),
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
BUILTIN("cd", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
BUILTIN("chdir", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
- BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilprtux", NULL),
+ BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lprtux", NULL),
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmr", NULL),
BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
@@ -62,12 +62,18 @@ static struct builtin builtins[] =
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmr", NULL),
BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
- BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "EFHLRTUZafhilprtu", "xg"),
+ BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "E:%F:%HL:%R:%TUZ:%afhi:%lprtu", "xg"),
BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
- BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
+ /*
+ * We used to behave as if the argument to -e was optional.
+ * But that's actually not useful, so it's more consistent to
+ * cause an error.
+ */
+ BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEim",
+ NULL),
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
- BUILTIN("float", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "EFHghlprtux", "E"),
- BUILTIN("functions", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "mtuU", NULL),
+ BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%Hghlprtux", "E"),
+ BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "mtuU", NULL),
BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "Ldfmrv", NULL),
@@ -77,11 +83,11 @@ static struct builtin builtins[] =
#endif
BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEim", "l"),
- BUILTIN("integer", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghilprtux", "i"),
+ BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghi:%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),
- BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZahilprtux", NULL),
+ BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lprtux", NULL),
BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
@@ -94,14 +100,14 @@ static struct builtin builtins[] =
#endif
BUILTIN("popd", 0, bin_cd, 0, 2, BIN_POPD, NULL, NULL),
- BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "RDPbnrsflzNu0123456789pioOcm-", NULL),
+ BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "RDPbnrsf:lzNu:pioOcm-", NULL),
BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL),
BUILTIN("pushd", 0, bin_cd, 0, 2, BIN_PUSHD, NULL, NULL),
BUILTIN("pushln", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
- BUILTIN("r", BINF_R, bin_fc, 0, -1, BIN_FC, "nrl", NULL),
- BUILTIN("read", 0, bin_read, 0, -1, 0, "ceklnpqrstzuAE0123456789", NULL),
- BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilptux", "r"),
+ BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
+ BUILTIN("read", 0, bin_read, 0, -1, 0, "cek:%lnpqrstzu:AE", NULL),
+ BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lptux", "r"),
BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
BUILTIN("set", BINF_PSPECIAL, bin_set, 0, -1, 0, NULL, NULL),
@@ -115,7 +121,7 @@ static struct builtin builtins[] =
BUILTIN("trap", BINF_PSPECIAL, bin_trap, 0, -1, 0, NULL, NULL),
BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
- BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilprtuxm", NULL),
+ BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lprtuxm", NULL),
BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "m", "a"),
BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
@@ -201,29 +207,49 @@ freebuiltinnode(HashNode hn)
}
}
-static char *auxdata;
-static int auxlen;
+/* Make sure we have space for a new option and increment. */
-/* execute a builtin handler function after parsing the arguments */
+#define OPT_ALLOC_CHUNK 16
-#define MAX_OPS 128
+/**/
+static int
+new_optarg(Options ops)
+{
+ /* Argument index must be a non-zero 6-bit number. */
+ if (ops->argscount == 63)
+ return 1;
+ if (ops->argsalloc == ops->argscount) {
+ char **newptr =
+ (char **)zhalloc((ops->argsalloc + OPT_ALLOC_CHUNK) *
+ sizeof(char *));
+ if (ops->argsalloc)
+ memcpy(newptr, ops->args, ops->argsalloc * sizeof(char *));
+ ops->args = newptr;
+ ops->argsalloc += OPT_ALLOC_CHUNK;
+ }
+ ops->argscount++;
+ return 0;
+}
+
+
+/* execute a builtin handler function after parsing the arguments */
/**/
int
execbuiltin(LinkList args, Builtin bn)
{
LinkNode n;
- char ops[MAX_OPS], *arg, *pp, *name, *optstr;
+ char *arg, *pp, *name, *optstr;
char *oxarg, *xarg = NULL;
- char typenumstr[] = TYPESET_OPTNUM;
int flags, sense, argc = 0, execop, xtr = isset(XTRACE), lxarg = 0;
+ struct options ops;
- /* initialise some static variables */
- auxdata = NULL;
- auxlen = 0;
+ /* initialise options structure */
+ memset(ops.ind, 0, MAX_OPS*sizeof(unsigned char));
+ ops.args = NULL;
+ ops.argscount = ops.argsalloc = 0;
/* initialize some local variables */
- memset(ops, 0, MAX_OPS);
name = (char *) ugetnode(args);
arg = (char *) ugetnode(args);
@@ -239,7 +265,7 @@ execbuiltin(LinkList args, Builtin bn)
/* Sort out the options. */
if ((flags & BINF_ECHOPTS) && isset(BSDECHO))
- ops['E'] = 1;
+ ops.ind['E'] = 1;
if (optstr)
/* while arguments look like options ... */
while (arg &&
@@ -269,26 +295,62 @@ execbuiltin(LinkList args, Builtin bn)
lxarg = strlen(xarg);
}
}
- /* handle -- or - (ops['-']), and + (ops['-'] and ops['+']) */
+ /* handle -- or - (ops.ind['-']), and +
+ * (ops.ind['-'] and ops.ind['+']) */
if (arg[1] == '-')
arg++;
if (!arg[1]) {
- ops['-'] = 1;
+ ops.ind['-'] = 1;
if (!sense)
- ops['+'] = 1;
+ ops.ind['+'] = 1;
}
/* save options in ops, as long as they are in bn->optstr */
execop = -1;
- while (*++arg)
- if (strchr(optstr, execop = (int)*arg))
- ops[(int)*arg] = (sense) ? 1 : 2;
- else
+ while (*++arg) {
+ char *optptr;
+ if ((optptr = strchr(optstr, execop = (int)*arg))) {
+ ops.ind[(int)*arg] = (sense) ? 1 : 2;
+ if (optptr[1] == ':') {
+ char *argptr = NULL;
+ if (optptr[2] == ':') {
+ if (arg[1])
+ argptr = arg+1;
+ /* Optional argument in same word*/
+ } else if (optptr[2] == '%') {
+ /* Optional numeric argument in same
+ * or next word. */
+ if (arg[1] && idigit(arg[1]))
+ argptr = arg+1;
+ else if (firstnode(args) &&
+ idigit(*(char *)peekfirst(args)))
+ argptr = arg = (char *)ugetnode(args);
+ } else {
+ /* Mandatory argument */
+ if (arg[1])
+ argptr = arg+1;
+ else if ((arg = (char *)ugetnode(args)))
+ argptr = arg;
+ else {
+ zwarnnam(name, "argument expected: -%c", NULL,
+ execop);
+ return 1;
+ }
+ }
+ if (argptr) {
+ if (new_optarg(&ops)) {
+ zwarnnam(name,
+ "too many option arguments", NULL, 0);
+ return 1;
+ }
+ ops.ind[execop] |= ops.argscount << 2;
+ ops.args[ops.argscount-1] = argptr;
+ while (arg[1])
+ arg++;
+ }
+ }
+ } else
break;
- /* "typeset" may take a numeric argument *
- * at the tail of the options */
- if (idigit(*arg) && (flags & BINF_TYPEOPT) &&
- strchr(typenumstr, arg[-1]))
- auxlen = (int)zstrtol(arg, &arg, 10);
+ }
/* The above loop may have exited on an invalid option. (We *
* assume that any option requiring metafication is invalid.) */
if (*arg) {
@@ -299,41 +361,24 @@ execbuiltin(LinkList args, Builtin bn)
}
arg = (char *) ugetnode(args);
/* for the "print" builtin, the options after -R are treated as
- options to "echo" and -f takes an extra argument */
- if (flags & BINF_PRINTOPTS) {
- if (ops['R'] && !ops['f']) {
- optstr = "ne";
- flags |= BINF_ECHOPTS;
- } else if (execop == 'f') {
- if (!arg) {
- zwarnnam(name, "-f: format argument expected", NULL, 0);
- return 1;
- }
- auxdata = arg;
- arg = (char *) ugetnode(args);
- }
+ options to "echo" */
+ if ((flags & BINF_PRINTOPTS) && ops.ind['R'] && !ops.ind['f']) {
+ optstr = "ne";
+ flags |= BINF_ECHOPTS;
}
/* the option -- indicates the end of the options */
- if (ops['-'])
+ if (ops.ind['-'])
break;
- /* for "fc", -e takes an extra argument */
- if ((flags & BINF_FCOPTS) && execop == 'e') {
- auxdata = arg;
- arg = (char *) ugetnode(args);
- }
- /* some "typeset" options take a numeric extra argument */
- if ((flags & BINF_TYPEOPT) && strchr(typenumstr, execop) &&
- arg && idigit(*arg)) {
- auxlen = atoi(arg);
- arg = (char *) ugetnode(args);
- }
}
- if (flags & BINF_R)
- auxdata = "-";
/* handle built-in options, for overloaded handler functions */
- if ((pp = bn->defopts))
- while (*pp)
- ops[(int)*pp++] = 1;
+ if ((pp = bn->defopts)) {
+ while (*pp) {
+ /* only if not already set */
+ if (!ops.ind[(int)*pp])
+ ops.ind[(int)*pp] = 1;
+ pp++;
+ }
+ }
/* Set up the argument list. */
if (arg) {
@@ -381,7 +426,7 @@ execbuiltin(LinkList args, Builtin bn)
fflush(xtrerr);
}
/* call the handler function, and return its return value */
- return (*(bn->handlerfunc)) (name, argv, ops, bn->funcid);
+ return (*(bn->handlerfunc)) (name, argv, &ops, bn->funcid);
}
}
@@ -391,7 +436,7 @@ execbuiltin(LinkList args, Builtin bn)
/**/
int
-bin_enable(char *name, char **argv, char *ops, int func)
+bin_enable(char *name, char **argv, Options ops, int func)
{
HashTable ht;
HashNode hn;
@@ -401,11 +446,11 @@ bin_enable(char *name, char **argv, char *ops, int func)
int match = 0, returnval = 0;
/* Find out which hash table we are working with. */
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
ht = shfunctab;
- else if (ops['r'])
+ else if (OPT_ISSET(ops,'r'))
ht = reswdtab;
- else if (ops['a'])
+ else if (OPT_ISSET(ops,'a'))
ht = aliastab;
else
ht = builtintab;
@@ -431,7 +476,7 @@ bin_enable(char *name, char **argv, char *ops, int func)
}
/* With -m option, treat arguments as glob patterns. */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
for (; *argv; argv++) {
/* parse pattern */
tokenize(*argv);
@@ -471,7 +516,7 @@ bin_enable(char *name, char **argv, char *ops, int func)
/**/
int
-bin_set(char *nam, char **args, char *ops, int func)
+bin_set(char *nam, char **args, Options ops, int func)
{
int action, optno, array = 0, hadopt = 0,
hadplus = 0, hadend = 0, sort = 0;
@@ -590,9 +635,10 @@ int doprintdir = 0; /* set in exec.c (for autocd) */
/**/
int
-bin_pwd(char *name, char **argv, char *ops, int func)
+bin_pwd(char *name, char **argv, Options ops, int func)
{
- if (ops['r'] || ops['P'] || (isset(CHASELINKS) && !ops['L']))
+ if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'P') ||
+ (isset(CHASELINKS) && !OPT_ISSET(ops,'L')))
printf("%s\n", zgetcwd());
else {
zputs(pwd, stdout);
@@ -610,33 +656,34 @@ mod_export LinkList dirstack;
/**/
int
-bin_dirs(char *name, char **argv, char *ops, int func)
+bin_dirs(char *name, char **argv, Options ops, int func)
{
LinkList l;
queue_signals();
/* with -v, -p or no arguments display the directory stack */
- if (!(*argv || ops['c']) || ops['v'] || ops ['p']) {
+ if (!(*argv || OPT_ISSET(ops,'c')) || OPT_ISSET(ops,'v') ||
+ OPT_ISSET(ops,'p')) {
LinkNode node;
char *fmt;
int pos = 1;
/* with the -v option, display a numbered list, starting at zero */
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("0\t");
fmt = "\n%d\t";
/* with the -p option, display entries one per line */
- } else if (ops['p'])
+ } else if (OPT_ISSET(ops,'p'))
fmt = "\n";
else
fmt = " ";
- if (ops['l'])
+ if (OPT_ISSET(ops,'l'))
fputs(pwd, stdout);
else
fprintdir(pwd, stdout);
for (node = firstnode(dirstack); node; incnode(node)) {
printf(fmt, pos++);
- if (ops['l'])
+ if (OPT_ISSET(ops,'l'))
fputs(getdata(node), stdout);
else
fprintdir(getdata(node), stdout);
@@ -704,7 +751,7 @@ static int chasinglinks;
/**/
int
-bin_cd(char *nam, char **argv, char *ops, int func)
+bin_cd(char *nam, char **argv, Options ops, int func)
{
LinkNode dir;
struct stat st1, st2;
@@ -728,10 +775,11 @@ bin_cd(char *nam, char **argv, char *ops, int func)
goto brk;
}
} while (*++s);
- for (s = *argv; *++s; ops[STOUC(*s)] = 1);
+ for (s = *argv; *++s; ops->ind[STOUC(*s)] = 1);
}
brk:
- chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
+ chasinglinks = OPT_ISSET(ops,'P') ||
+ (isset(CHASELINKS) && !OPT_ISSET(ops,'L'));
queue_signals();
zpushnode(dirstack, ztrdup(pwd));
if (!(dir = cd_get_dest(nam, argv, ops, func))) {
@@ -764,7 +812,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
/**/
static LinkNode
-cd_get_dest(char *nam, char **argv, char *ops, int func)
+cd_get_dest(char *nam, char **argv, Options ops, int func)
{
LinkNode dir = NULL;
LinkNode target;
@@ -834,7 +882,7 @@ cd_get_dest(char *nam, char **argv, char *ops, int func)
if (!dir) {
dir = firstnode(dirstack);
}
- if (!(dest = cd_do_chdir(nam, getdata(dir), ops['s']))) {
+ if (!(dest = cd_do_chdir(nam, getdata(dir), OPT_ISSET(ops,'s')))) {
if (!target)
zsfree(getlinknode(dirstack));
if (func == BIN_POPD)
@@ -1232,7 +1280,7 @@ printif(char *str, int c)
/**/
int
-bin_fc(char *nam, char **argv, char *ops, int func)
+bin_fc(char *nam, char **argv, Options ops, int func)
{
int first = -1, last = -1, retval;
char *s;
@@ -1246,7 +1294,7 @@ bin_fc(char *nam, char **argv, char *ops, int func)
}
/* with the -m option, the first argument is taken *
* as a pattern that history lines have to match */
- if (*argv && ops['m']) {
+ if (*argv && OPT_ISSET(ops,'m')) {
tokenize(*argv);
if (!(pprog = patcompile(*argv++, 0, NULL))) {
zwarnnam(nam, "invalid match pattern", NULL, 0);
@@ -1254,21 +1302,22 @@ bin_fc(char *nam, char **argv, char *ops, int func)
}
}
queue_signals();
- if (ops['R']) {
+ if (OPT_ISSET(ops,'R')) {
/* read history from a file */
- readhistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
+ readhistfile(*argv, 1, OPT_ISSET(ops,'I') ? HFILE_SKIPOLD : 0);
unqueue_signals();
return 0;
}
- if (ops['W']) {
+ if (OPT_ISSET(ops,'W')) {
/* write history to a file */
- savehistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
+ savehistfile(*argv, 1, OPT_ISSET(ops,'I') ? HFILE_SKIPOLD : 0);
unqueue_signals();
return 0;
}
- if (ops['A']) {
+ if (OPT_ISSET(ops,'A')) {
/* append history to a file */
- savehistfile(*argv, 1, HFILE_APPEND | (ops['I'] ? HFILE_SKIPOLD : 0));
+ savehistfile(*argv, 1, HFILE_APPEND |
+ (OPT_ISSET(ops,'I') ? HFILE_SKIPOLD : 0));
unqueue_signals();
return 0;
}
@@ -1318,7 +1367,7 @@ bin_fc(char *nam, char **argv, char *ops, int func)
}
/* default values of first and last, and range checking */
if (last == -1) {
- if (ops['l'] && first < curhist) {
+ if (OPT_ISSET(ops,'l') && first < curhist) {
last = addhistnum(curline.histnum,-1,0);
if (last < firsthist())
last = firsthist();
@@ -1327,18 +1376,16 @@ bin_fc(char *nam, char **argv, char *ops, int func)
last = first;
}
if (first == -1) {
- first = ops['l']? addhistnum(curline.histnum,-16,0)
+ first = OPT_ISSET(ops,'l')? addhistnum(curline.histnum,-16,0)
: addhistnum(curline.histnum,-1,0);
if (first < 1)
first = 1;
if (last < first)
last = first;
}
- if (ops['l']) {
+ if (OPT_ISSET(ops,'l')) {
/* list the required part of the history */
- retval = fclist(stdout, !ops['n'], ops['r'], ops['D'],
- ops['d'] + ops['f'] * 2 + ops['E'] * 4 + ops['i'] * 8,
- first, last, asgf, pprog);
+ retval = fclist(stdout, ops, first, last, asgf, pprog);
unqueue_signals();
}
else {
@@ -1355,10 +1402,16 @@ bin_fc(char *nam, char **argv, char *ops, int func)
unqueue_signals();
zwarnnam("fc", "can't open temp file: %e", NULL, errno);
} else {
- if (!fclist(out, 0, ops['r'], 0, 0, first, last, asgf, pprog)) {
+ ops->ind['n'] = 1; /* No line numbers here. */
+ if (!fclist(out, ops, first, last, asgf, pprog)) {
char *editor;
- editor = auxdata ? auxdata : getsparam("FCEDIT");
+ if (func == BIN_R)
+ editor = "-";
+ else if (OPT_HASARG(ops, 'e'))
+ editor = OPT_ARG(ops, 'e');
+ else
+ editor = getsparam("FCEDIT");
if (!editor)
editor = DEFAULT_FCEDIT;
@@ -1456,17 +1509,17 @@ fcsubs(char **sp, struct asgment *sub)
/**/
static int
-fclist(FILE *f, int n, int r, int D, int d, int first, int last, struct asgment *subs, Patprog pprog)
+fclist(FILE *f, Options ops, int first, int last, struct asgment *subs, Patprog pprog)
{
- int fclistdone = 0;
+ int fclistdone = 0, tmp;
char *s;
Histent ent;
/* reverse range if required */
- if (r) {
- r = last;
+ if (OPT_ISSET(ops,'r')) {
+ tmp = last;
last = first;
- first = r;
+ first = tmp;
}
/* suppress "no substitution" warning if no substitution is requested */
if (!subs)
@@ -1489,34 +1542,33 @@ fclist(FILE *f, int n, int r, int D, int d, int first, int last, struct asgment
fclistdone |= fcsubs(&s, subs);
/* do numbering */
- if (n) {
+ if (!OPT_ISSET(ops,'n')) {
fprintf(f, "%5d%c ", ent->histnum,
ent->flags & HIST_FOREIGN? '*' : ' ');
}
/* output actual time (and possibly date) of execution of the
command, if required */
- if (d) {
+ if (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'f') ||
+ OPT_ISSET(ops,'E') || OPT_ISSET(ops,'i')) {
struct tm *ltm;
ltm = localtime(&ent->stim);
- if (d >= 2) {
- if (d >= 8) {
- fprintf(f, "%d-%02d-%02d ",
- ltm->tm_year + 1900,
- ltm->tm_mon + 1, ltm->tm_mday);
- } else if (d >= 4) {
- fprintf(f, "%d.%d.%d ",
- ltm->tm_mday, ltm->tm_mon + 1,
- ltm->tm_year + 1900);
- } else {
- fprintf(f, "%d/%d/%d ",
- ltm->tm_mon + 1, ltm->tm_mday,
- ltm->tm_year + 1900);
- }
+ if (OPT_ISSET(ops,'i')) {
+ fprintf(f, "%d-%02d-%02d ",
+ ltm->tm_year + 1900,
+ ltm->tm_mon + 1, ltm->tm_mday);
+ } else if (OPT_ISSET(ops,'E')) {
+ fprintf(f, "%d.%d.%d ",
+ ltm->tm_mday, ltm->tm_mon + 1,
+ ltm->tm_year + 1900);
+ } else if (OPT_ISSET(ops,'f')) {
+ fprintf(f, "%d/%d/%d ",
+ ltm->tm_mon + 1, ltm->tm_mday,
+ ltm->tm_year + 1900);
}
fprintf(f, "%02d:%02d ", ltm->tm_hour, ltm->tm_min);
}
/* display the time taken by the command, if required */
- if (D) {
+ if (OPT_ISSET(ops,'D')) {
long diff;
diff = (ent->ftim) ? ent->ftim - ent->stim : 0;
fprintf(f, "%ld:%02ld ", diff / 60, diff % 60);
@@ -1609,10 +1661,10 @@ getasg(char *s)
/* function to set a single parameter */
/**/
-Param
+static Param
typeset_single(char *cname, char *pname, Param pm, int func,
int on, int off, int roff, char *value, Param altpm,
- char *ops)
+ Options ops, int auxlen)
{
int usepm, tc, keeplocal = 0, newspecial = 0;
char *subscript;
@@ -1693,9 +1745,9 @@ typeset_single(char *cname, char *pname, Param pm, int func,
if (usepm) {
on &= ~PM_LOCAL;
if (!on && !roff && !value) {
- if (ops['p'])
+ if (OPT_ISSET(ops,'p'))
paramtab->printnode((HashNode)pm, PRINT_TYPESET);
- else if (unset(TYPESETSILENT) || ops['m'])
+ else if (unset(TYPESETSILENT) || OPT_ISSET(ops,'m'))
paramtab->printnode((HashNode)pm, PRINT_INCLUDEVALUE);
return pm;
}
@@ -1741,7 +1793,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
return NULL;
}
pm->flags |= (on & PM_READONLY);
- if (ops['p'])
+ if (OPT_ISSET(ops,'p'))
paramtab->printnode((HashNode)pm, PRINT_TYPESET);
return pm;
}
@@ -1931,7 +1983,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
return NULL;
}
- if (ops['p'])
+ if (OPT_ISSET(ops,'p'))
paramtab->printnode((HashNode)pm, PRINT_TYPESET);
return pm;
@@ -1941,7 +1993,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
/**/
int
-bin_typeset(char *name, char **argv, char *ops, int func)
+bin_typeset(char *name, char **argv, Options ops, int func)
{
Param pm;
Asgment asg;
@@ -1949,20 +2001,38 @@ bin_typeset(char *name, char **argv, char *ops, int func)
char *optstr = TYPESET_OPTSTR;
int on = 0, off = 0, roff, bit = PM_ARRAY;
int i;
- int returnval = 0, printflags = 0;
+ int returnval = 0, printflags = 0, auxlen = 0;
/* hash -f is really the builtin `functions' */
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
return bin_functions(name, argv, ops, func);
/* Translate the options into PM_* flags. *
* Unfortunately, this depends on the order *
* these flags are defined in zsh.h */
for (; *optstr; optstr++, bit <<= 1)
- if (ops[STOUC(*optstr)] == 1)
+ {
+ int optval = STOUC(*optstr);
+ if (OPT_MINUS(ops,optval))
on |= bit;
- else if (ops[STOUC(*optstr)] == 2)
+ 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. */
@@ -1998,13 +2068,13 @@ bin_typeset(char *name, char **argv, char *ops, int func)
queue_signals();
/* Given no arguments, list whatever the options specify. */
- if (ops['p'])
+ if (OPT_ISSET(ops,'p'))
printflags |= PRINT_TYPESET;
if (!*argv) {
- if (!ops['p']) {
+ if (!OPT_ISSET(ops,'p')) {
if (!(on|roff))
printflags |= PRINT_TYPE;
- if (roff || ops['+'])
+ if (roff || OPT_ISSET(ops,'+'))
printflags |= PRINT_NAMEONLY;
}
scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags);
@@ -2012,8 +2082,9 @@ bin_typeset(char *name, char **argv, char *ops, int func)
return 0;
}
- if (!(ops['g'] || ops['x'] || ops['m']) || ops['g'] == 2 || *name == 'l' ||
- (!isset(GLOBALEXPORT) && !ops['g']))
+ if (!(OPT_ISSET(ops,'g') || OPT_ISSET(ops,'x') || OPT_ISSET(ops,'m')) ||
+ OPT_ISSET(ops,'g') == 2 || *name == 'l' ||
+ (!isset(GLOBALEXPORT) && !OPT_ISSET(ops,'g')))
on |= PM_LOCAL;
if (on & PM_TIED) {
@@ -2021,7 +2092,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
struct asgment asg0;
char *oldval = NULL;
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
zwarnnam(name, "incompatible options for -T", NULL, 0);
unqueue_signals();
return 1;
@@ -2072,7 +2143,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
(Param)paramtab->getnode(paramtab,
asg->name),
func, (on | PM_ARRAY) & ~PM_EXPORTED,
- off, roff, asg->value, NULL, ops))) {
+ off, roff, asg->value, NULL, ops, auxlen))) {
unqueue_signals();
return 1;
}
@@ -2084,7 +2155,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
(Param)paramtab->getnode(paramtab,
asg0.name),
func, on, off, roff, asg0.value, apm,
- ops))) {
+ ops, auxlen))) {
if (oldval)
zsfree(oldval);
unsetparam_pm(apm, 1, 1);
@@ -2106,8 +2177,8 @@ bin_typeset(char *name, char **argv, char *ops, int func)
}
/* With the -m option, treat arguments as glob patterns */
- if (ops['m']) {
- if (!ops['p']) {
+ if (OPT_ISSET(ops,'m')) {
+ if (!OPT_ISSET(ops,'p')) {
if (!(on|roff))
printflags |= PRINT_TYPE;
if (!on)
@@ -2125,7 +2196,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
returnval = 1;
continue;
}
- if (ops['m'] == 2 && !asg->value) {
+ if (OPT_PLUS(ops,'m') == 2 && !asg->value) {
scanmatchtable(paramtab, pprog, on|roff, 0,
paramtab->printnode, printflags);
continue;
@@ -2151,7 +2222,7 @@ bin_typeset(char *name, char **argv, char *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))
+ asg->value, NULL, ops, auxlen))
returnval = 1;
}
}
@@ -2166,7 +2237,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
gethashnode2(paramtab, asg->name) :
paramtab->getnode(paramtab, asg->name)),
func, on, off, roff, asg->value, NULL,
- ops))
+ ops, auxlen))
returnval = 1;
}
unqueue_signals();
@@ -2177,7 +2248,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
/**/
int
-eval_autoload(Shfunc shf, char *name, char *ops, int func)
+eval_autoload(Shfunc shf, char *name, Options ops, int func)
{
if (!(shf->flags & PM_UNDEFINED))
return 1;
@@ -2186,7 +2257,7 @@ eval_autoload(Shfunc shf, char *name, char *ops, int func)
freeeprog(shf->funcdef);
shf->funcdef = &dummy_eprog;
}
- if (ops['X'] == 1) {
+ if (OPT_MINUS(ops,'X')) {
char *fargv[3];
fargv[0] = name;
fargv[1] = "\"$@\"";
@@ -2195,7 +2266,8 @@ eval_autoload(Shfunc shf, char *name, char *ops, int func)
return bin_eval(name, fargv, ops, func);
}
- return !loadautofn(shf, (ops['k'] ? 2 : (ops['z'] ? 0 : 1)), 1);
+ return !loadautofn(shf, (OPT_ISSET(ops,'k') ? 2 :
+ (OPT_ISSET(ops,'z') ? 0 : 1)), 1);
}
/* Display or change the attributes of shell functions. *
@@ -2204,7 +2276,7 @@ eval_autoload(Shfunc shf, char *name, char *ops, int func)
/**/
int
-bin_functions(char *name, char **argv, char *ops, int func)
+bin_functions(char *name, char **argv, Options ops, int func)
{
Patprog pprog;
Shfunc shf;
@@ -2212,27 +2284,27 @@ bin_functions(char *name, char **argv, char *ops, int func)
int on = 0, off = 0, pflags = 0;
/* Do we have any flags defined? */
- if (ops['u'] == 2)
+ if (OPT_ISSET(ops,'u') == 2)
off |= PM_UNDEFINED;
- else if (ops['u'] == 1 || ops['X'])
+ else if (OPT_MINUS(ops,'u') || OPT_ISSET(ops,'X'))
on |= PM_UNDEFINED;
- if (ops['U'] == 1)
+ if (OPT_MINUS(ops,'U'))
on |= PM_UNALIASED|PM_UNDEFINED;
- else if (ops['U'] == 2)
+ else if (OPT_PLUS(ops,'U'))
off |= PM_UNALIASED;
- if (ops['t'] == 1)
+ if (OPT_MINUS(ops,'t'))
on |= PM_TAGGED;
- else if (ops['t'] == 2)
+ else if (OPT_PLUS(ops,'t'))
off |= PM_TAGGED;
- if ((off & PM_UNDEFINED) || (ops['k'] && ops['z']) ||
- (ops['X'] != 2 && (ops['k'] || ops['z'])) ||
- (ops['X'] == 1 && (ops['m'] || *argv || !scriptname))) {
+ if ((off & PM_UNDEFINED) || (OPT_ISSET(ops,'k') && OPT_ISSET(ops,'z')) ||
+ (!OPT_PLUS(ops,'X') && (OPT_ISSET(ops,'k') || OPT_ISSET(ops,'z'))) ||
+ (OPT_MINUS(ops,'X') && (OPT_ISSET(ops,'m') || *argv || !scriptname))) {
zwarnnam(name, "invalid option(s)", NULL, 0);
return 1;
}
- if (ops['f'] == 2 || ops['+'])
+ if (OPT_PLUS(ops,'f') || OPT_ISSET(ops,'+'))
pflags |= PRINT_NAMEONLY;
/* If no arguments given, we will print functions. If flags *
@@ -2242,7 +2314,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
int ret = 0;
queue_signals();
- if (ops['X'] == 1) {
+ if (OPT_MINUS(ops,'X')) {
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) {
DPUTS(!shf->funcdef,
"BUG: Calling autoload from empty function");
@@ -2253,7 +2325,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
shf->flags = on;
ret = eval_autoload(shf, scriptname, ops, func);
} else {
- if (ops['U'] && !ops['u'])
+ if (OPT_ISSET(ops,'U') && !OPT_ISSET(ops,'u'))
on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags);
@@ -2263,7 +2335,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
}
/* With the -m option, treat arguments as glob patterns */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
on &= ~PM_UNDEFINED;
for (; *argv; argv++) {
/* expand argument */
@@ -2283,7 +2355,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
!(shf->flags & DISABLED)) {
shf->flags = (shf->flags |
(on & ~PM_UNDEFINED)) & ~off;
- if (ops['X'] &&
+ if (OPT_ISSET(ops,'X') &&
eval_autoload(shf, shf->nam, ops, func)) {
returnval = 1;
}
@@ -2303,14 +2375,15 @@ bin_functions(char *name, char **argv, char *ops, int func)
/* Take the arguments literally -- do not glob */
queue_signals();
for (; *argv; argv++) {
- if (ops['w'])
+ if (OPT_ISSET(ops,'w'))
returnval = dump_autoload(name, *argv, on, ops, func);
else if ((shf = (Shfunc) shfunctab->getnode(shfunctab, *argv))) {
/* if any flag was given */
if (on|off) {
/* turn on/off the given flags */
shf->flags = (shf->flags | (on & ~PM_UNDEFINED)) & ~off;
- if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
+ if (OPT_ISSET(ops,'X') &&
+ eval_autoload(shf, shf->nam, ops, func))
returnval = 1;
} else
/* no flags, so just print */
@@ -2322,7 +2395,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
shf->flags = on;
shf->funcdef = mkautofn(shf);
shfunctab->addnode(shfunctab, ztrdup(*argv), shf);
- if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
+ if (OPT_ISSET(ops,'X') && eval_autoload(shf, shf->nam, ops, func))
returnval = 1;
} else
returnval = 1;
@@ -2361,7 +2434,7 @@ mkautofn(Shfunc shf)
/**/
int
-bin_unset(char *name, char **argv, char *ops, int func)
+bin_unset(char *name, char **argv, Options ops, int func)
{
Param pm, next;
Patprog pprog;
@@ -2370,11 +2443,11 @@ bin_unset(char *name, char **argv, char *ops, int func)
int i;
/* unset -f is the same as unfunction */
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
return bin_unhash(name, argv, ops, func);
/* with -m option, treat arguments as glob patterns */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
while ((s = *argv++)) {
/* expand */
tokenize(s);
@@ -2453,7 +2526,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
/**/
int
-bin_whence(char *nam, char **argv, char *ops, int func)
+bin_whence(char *nam, char **argv, Options ops, int func)
{
HashNode hn;
Patprog pprog;
@@ -2464,24 +2537,24 @@ bin_whence(char *nam, char **argv, char *ops, int func)
char *cnam;
/* Check some option information */
- csh = ops['c'];
- v = ops['v'];
- all = ops['a'];
- wd = ops['w'];
+ csh = OPT_ISSET(ops,'c');
+ v = OPT_ISSET(ops,'v');
+ all = OPT_ISSET(ops,'a');
+ wd = OPT_ISSET(ops,'w');
- if (ops['w'])
+ if (OPT_ISSET(ops,'w'))
printflags |= PRINT_WHENCE_WORD;
- else if (ops['c'])
+ else if (OPT_ISSET(ops,'c'))
printflags |= PRINT_WHENCE_CSH;
- else if (ops['v'])
+ else if (OPT_ISSET(ops,'v'))
printflags |= PRINT_WHENCE_VERBOSE;
else
printflags |= PRINT_WHENCE_SIMPLE;
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
printflags |= PRINT_WHENCE_FUNCDEF;
/* With -m option -- treat arguments as a glob patterns */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
for (; *argv; argv++) {
/* parse the pattern */
tokenize(*argv);
@@ -2492,7 +2565,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
continue;
}
queue_signals();
- if (!ops['p']) {
+ if (!OPT_ISSET(ops,'p')) {
/* -p option is for path search only. *
* We're not using it, so search for ... */
@@ -2528,7 +2601,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
for (; *argv; argv++) {
informed = 0;
- if (!ops['p']) {
+ if (!OPT_ISSET(ops,'p')) {
/* Look for alias */
if ((hn = aliastab->getnode(aliastab, *argv))) {
aliastab->printnode(hn, printflags);
@@ -2585,7 +2658,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
if (v && !csh)
zputs(*argv, stdout), fputs(" is ", stdout);
zputs(buf, stdout);
- if (ops['s'])
+ if (OPT_ISSET(ops,'s'))
print_if_link(buf);
fputc('\n', stdout);
}
@@ -2606,7 +2679,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
if (v && !csh)
zputs(*argv, stdout), fputs(" is ", stdout);
zputs(cnam, stdout);
- if (ops['s'])
+ if (OPT_ISSET(ops,'s'))
print_if_link(cnam);
fputc('\n', stdout);
}
@@ -2643,7 +2716,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
/**/
int
-bin_hash(char *name, char **argv, char *ops, int func)
+bin_hash(char *name, char **argv, Options ops, int func)
{
HashTable ht;
Patprog pprog;
@@ -2651,12 +2724,12 @@ bin_hash(char *name, char **argv, char *ops, int func)
int returnval = 0;
int printflags = 0;
- if (ops['d'])
+ if (OPT_ISSET(ops,'d'))
ht = nameddirtab;
else
ht = cmdnamtab;
- if (ops['r'] || ops['f']) {
+ if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'f')) {
/* -f and -r can't be used with any arguments */
if (*argv) {
zwarnnam("hash", "too many arguments", NULL, 0);
@@ -2664,17 +2737,17 @@ bin_hash(char *name, char **argv, char *ops, int func)
}
/* empty the hash table */
- if (ops['r'])
+ if (OPT_ISSET(ops,'r'))
ht->emptytable(ht);
/* fill the hash table in a standard way */
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
ht->filltable(ht);
return 0;
}
- if (ops['L']) printflags |= PRINT_LIST;
+ if (OPT_ISSET(ops,'L')) printflags |= PRINT_LIST;
/* Given no arguments, display current hash table. */
if (!*argv) {
@@ -2687,7 +2760,7 @@ bin_hash(char *name, char **argv, char *ops, int func)
queue_signals();
while (*argv) {
void *hn;
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
/* with the -m option, treat the argument as a glob pattern */
tokenize(*argv); /* expand */
if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
@@ -2705,7 +2778,7 @@ bin_hash(char *name, char **argv, char *ops, int func)
} else {
/* The argument is of the form foo=bar, *
* so define an entry for the table. */
- if(ops['d']) {
+ if(OPT_ISSET(ops,'d')) {
Nameddir nd = hn = zcalloc(sizeof *nd);
nd->flags = 0;
nd->dir = ztrdup(asg->value);
@@ -2715,13 +2788,13 @@ bin_hash(char *name, char **argv, char *ops, int func)
cn->u.cmd = ztrdup(asg->value);
}
ht->addnode(ht, ztrdup(asg->name), hn);
- if(ops['v'])
+ if(OPT_ISSET(ops,'v'))
ht->printnode(hn, 0);
}
} else if (!(hn = ht->getnode2(ht, asg->name))) {
/* With no `=value' part to the argument, *
* work out what it ought to be. */
- if(ops['d']) {
+ if(OPT_ISSET(ops,'d')) {
if(!getnameddir(asg->name)) {
zwarnnam(name, "no such directory name: %s", asg->name, 0);
returnval = 1;
@@ -2732,9 +2805,9 @@ bin_hash(char *name, char **argv, char *ops, int func)
returnval = 1;
}
}
- if(ops['v'] && (hn = ht->getnode2(ht, asg->name)))
+ if(OPT_ISSET(ops,'v') && (hn = ht->getnode2(ht, asg->name)))
ht->printnode(hn, 0);
- } else if(ops['v'])
+ } else if(OPT_ISSET(ops,'v'))
ht->printnode(hn, 0);
argv++;
}
@@ -2746,7 +2819,7 @@ bin_hash(char *name, char **argv, char *ops, int func)
/**/
int
-bin_unhash(char *name, char **argv, char *ops, int func)
+bin_unhash(char *name, char **argv, Options ops, int func)
{
HashTable ht;
HashNode hn, nhn;
@@ -2755,18 +2828,18 @@ bin_unhash(char *name, char **argv, char *ops, int func)
int i;
/* Check which hash table we are working with. */
- if (ops['d'])
+ if (OPT_ISSET(ops,'d'))
ht = nameddirtab; /* named directories */
- else if (ops['f'])
+ else if (OPT_ISSET(ops,'f'))
ht = shfunctab; /* shell functions */
- else if (ops['a'])
+ else if (OPT_ISSET(ops,'a'))
ht = aliastab; /* aliases */
else
ht = cmdnamtab; /* external commands */
/* With -m option, treat arguments as glob patterns. *
* "unhash -m '*'" is legal, but not recommended. */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
for (; *argv; argv++) {
/* expand argument */
tokenize(*argv);
@@ -2816,7 +2889,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
/**/
int
-bin_alias(char *name, char **argv, char *ops, int func)
+bin_alias(char *name, char **argv, Options ops, int func)
{
Alias a;
Patprog pprog;
@@ -2826,21 +2899,22 @@ bin_alias(char *name, char **argv, char *ops, int func)
int printflags = 0;
/* Did we specify the type of alias? */
- if (ops['r'] || ops['g']) {
- if (ops['r'] && ops['g']) {
+ if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'g')) {
+ if (OPT_ISSET(ops,'r') && OPT_ISSET(ops,'g')) {
zwarnnam(name, "illegal combination of options", NULL, 0);
return 1;
}
haveflags = 1;
- if (ops['g'])
+ if (OPT_ISSET(ops,'g'))
flags1 |= ALIAS_GLOBAL;
else
flags2 |= ALIAS_GLOBAL;
}
- if (ops['L'])
+ if (OPT_ISSET(ops,'L'))
printflags |= PRINT_LIST;
- else if (ops['r'] == 2 || ops['g'] == 2 || ops['m'] == 2 || ops['+'])
+ else if (OPT_PLUS(ops,'r') || OPT_PLUS(ops,'g')|| OPT_PLUS(ops,'m') ||
+ OPT_ISSET(ops,'+'))
printflags |= PRINT_NAMEONLY;
/* In the absence of arguments, list all aliases. If a command *
@@ -2854,7 +2928,7 @@ bin_alias(char *name, char **argv, char *ops, int func)
/* With the -m option, treat the arguments as *
* glob patterns of aliases to display. */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
for (; *argv; argv++) {
tokenize(*argv); /* expand argument */
if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
@@ -2875,7 +2949,7 @@ bin_alias(char *name, char **argv, char *ops, int func)
/* Take arguments literally. Don't glob */
queue_signals();
while ((asg = getasg(*argv++))) {
- if (asg->value && !ops['L']) {
+ if (asg->value && !OPT_ISSET(ops,'L')) {
/* The argument is of the form foo=bar and we are not *
* forcing a listing with -L, so define an alias */
aliastab->addnode(aliastab, ztrdup(asg->name),
@@ -2883,8 +2957,8 @@ bin_alias(char *name, char **argv, char *ops, int func)
} else if ((a = (Alias) aliastab->getnode(aliastab, asg->name))) {
/* display alias if appropriate */
if (!haveflags ||
- (ops['r'] && !(a->flags & ALIAS_GLOBAL)) ||
- (ops['g'] && (a->flags & ALIAS_GLOBAL)))
+ (OPT_ISSET(ops,'r') && !(a->flags & ALIAS_GLOBAL)) ||
+ (OPT_ISSET(ops,'g') && (a->flags & ALIAS_GLOBAL)))
aliastab->printnode((HashNode) a, printflags);
} else
returnval = 1;
@@ -2900,7 +2974,7 @@ bin_alias(char *name, char **argv, char *ops, int func)
/**/
int
-bin_true(char *name, char **argv, char *ops, int func)
+bin_true(char *name, char **argv, Options ops, int func)
{
return 0;
}
@@ -2909,7 +2983,7 @@ bin_true(char *name, char **argv, char *ops, int func)
/**/
int
-bin_false(char *name, char **argv, char *ops, int func)
+bin_false(char *name, char **argv, Options ops, int func)
{
return 1;
}
@@ -2929,7 +3003,7 @@ mod_export LinkList bufstack;
/**/
int
-bin_print(char *name, char **args, char *ops, int func)
+bin_print(char *name, char **args, Options ops, int func)
{
int flen, width, prec, type, argc, n, narg;
int nnl = 0, ret = 0, maxarg = 0;
@@ -2950,14 +3024,18 @@ bin_print(char *name, char **args, char *ops, int func)
zulong zulongval;
char *stringval;
- if (func == BIN_PRINTF) auxdata = *args++;
- if (auxdata)
- fmt = getkeystring(auxdata, &flen, ops['b'] ? 2 : 0, &nnl);
+ if (func == BIN_PRINTF)
+ fmt = *args++;
+ else if (OPT_HASARG(ops,'f'))
+ fmt = OPT_ARG(ops,'f');
+ if (fmt)
+ fmt = getkeystring(fmt, &flen, OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
+
first = args;
/* -m option -- treat the first argument as a pattern and remove
* arguments not matching */
- if (ops['m']) {
+ if (OPT_ISSET(ops,'m')) {
Patprog pprog;
char **t, **p;
@@ -2979,13 +3057,16 @@ bin_print(char *name, char **args, char *ops, int func)
len = (int *) hcalloc(argc * sizeof(int));
for(n = 0; n < argc; n++) {
/* first \ sequences */
- if (fmt || (!ops['e'] && (ops['R'] || ops['r'] || ops['E'])))
+ if (fmt ||
+ (!OPT_ISSET(ops,'e') &&
+ (OPT_ISSET(ops,'R') || OPT_ISSET(ops,'r') || OPT_ISSET(ops,'E'))))
unmetafy(args[n], &len[n]);
else
- args[n] = getkeystring(args[n], &len[n], ops['b'] ? 2 :
- (func != BIN_ECHO && !ops['e']), &nnl);
+ args[n] = getkeystring(args[n], &len[n], OPT_ISSET(ops,'b') ? 2 :
+ (func != BIN_ECHO && !OPT_ISSET(ops,'e')),
+ &nnl);
/* -P option -- interpret as a prompt sequence */
- if(ops['P']) {
+ if(OPT_ISSET(ops,'P')) {
/*
* promptexpand uses permanent storage: to avoid
* messy memory management, stick it on the heap
@@ -2997,7 +3078,7 @@ bin_print(char *name, char **args, char *ops, int func)
free(str);
}
/* -D option -- interpret as a directory, and use ~ */
- if(ops['D']) {
+ if(OPT_ISSET(ops,'D')) {
Nameddir d;
queue_signals();
@@ -3014,48 +3095,57 @@ bin_print(char *name, char **args, char *ops, int func)
}
/* -u and -p -- output to other than standard output */
- if (ops['u'] || ops['p']) {
+ if (OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) {
int fd;
- if (ops['u']) {
- for (fd = 0; fd < 10; fd++)
- if (ops[fd + '0'])
- break;
- if (fd == 10)
- fd = 0;
- } else
+ if (OPT_ISSET(ops, 'p'))
fd = coprocout;
+ else {
+ char *argptr = OPT_ARG(ops,'u'), *eptr;
+ /* Handle undocumented feature that -up worked */
+ if (!strcmp(argptr, "p")) {
+ fd = coprocout;
+ } else {
+ fd = (int)zstrtol(argptr, &eptr, 10);
+ if (*eptr) {
+ zwarnnam(name, "number expected after -u: %s", argptr, 0);
+ return 1;
+ }
+ }
+ }
+
if ((fd = dup(fd)) < 0) {
- zwarnnam(name, "bad file number", NULL, 0);
+ zwarnnam(name, "bad file number: %d", NULL, fd);
return 1;
}
if ((fout = fdopen(fd, "w")) == 0) {
- zwarnnam(name, "bad mode on fd", NULL, 0);
+ close(fd);
+ zwarnnam(name, "bad mode on fd %d", NULL, fd);
return 1;
}
}
/* -o and -O -- sort the arguments */
- if (ops['o']) {
+ if (OPT_ISSET(ops,'o')) {
if (fmt && !*args) return 0;
- if (ops['i'])
+ if (OPT_ISSET(ops,'i'))
qsort(args, arrlen(args), sizeof(char *), cstrpcmp);
else
qsort(args, arrlen(args), sizeof(char *), strpcmp);
- } else if (ops['O']) {
+ } else if (OPT_ISSET(ops,'O')) {
if (fmt && !*args) return 0;
- if (ops['i'])
+ if (OPT_ISSET(ops,'i'))
qsort(args, arrlen(args), sizeof(char *), invcstrpcmp);
else
qsort(args, arrlen(args), sizeof(char *), invstrpcmp);
}
/* after sorting arguments, recalculate lengths */
- if(ops['o'] || ops['O'])
+ if(OPT_ISSET(ops,'o') || OPT_ISSET(ops,'O'))
for(n = 0; n < argc; n++)
len[n] = strlen(args[n]);
/* -c -- output in columns */
- if (ops['c']) {
+ if (OPT_ISSET(ops,'c')) {
int l, nc, nr, sc, n, t, i;
char **ap;
@@ -3079,7 +3169,7 @@ bin_print(char *name, char **args, char *ops, int func)
for (; l < sc; l++)
fputc(' ', fout);
} while (*ap);
- fputc(ops['N'] ? '\0' : '\n', fout);
+ fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
}
/* Testing EBADF special-cases >&- redirections */
if ((fout != stdout) ? (fclose(fout) != 0) :
@@ -3093,14 +3183,14 @@ bin_print(char *name, char **args, char *ops, int func)
/* normal output */
if (!fmt) {
/* -z option -- push the arguments onto the editing buffer stack */
- if (ops['z']) {
+ if (OPT_ISSET(ops,'z')) {
queue_signals();
zpushnode(bufstack, sepjoin(args, NULL, 0));
unqueue_signals();
return 0;
}
/* -s option -- add the arguments to the history list */
- if (ops['s']) {
+ if (OPT_ISSET(ops,'s')) {
int nwords = 0, nlen, iwords;
char **pargs = args;
@@ -3130,10 +3220,11 @@ bin_print(char *name, char **args, char *ops, int func)
for (; *args; args++, len++) {
fwrite(*args, *len, 1, fout);
if (args[1])
- fputc(ops['l'] ? '\n' : ops['N'] ? '\0' : ' ', fout);
+ fputc(OPT_ISSET(ops,'l') ? '\n' :
+ OPT_ISSET(ops,'N') ? '\0' : ' ', fout);
}
- if (!(ops['n'] || nnl))
- fputc(ops['N'] ? '\0' : '\n', fout);
+ if (!(OPT_ISSET(ops,'n') || nnl))
+ fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
/* Testing EBADF special-cases >&- redirections */
if ((fout != stdout) ? (fclose(fout) != 0) :
(fflush(fout) != 0 && errno != EBADF)) {
@@ -3143,7 +3234,7 @@ bin_print(char *name, char **args, char *ops, int func)
return ret;
}
- if (ops['z'] || ops['s']) {
+ if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
#ifdef HAVE_OPEN_MEMSTREAM
if ((fout = open_memstream(&buf, &mcount)) == NULL)
zwarnnam(name, "open_memstream failed", NULL, 0);
@@ -3291,7 +3382,8 @@ bin_print(char *name, char **args, char *ops, int func)
case 'b':
if (curarg) {
int l;
- char *b = getkeystring(curarg, &l, ops['b'] ? 2 : 0, &nnl);
+ char *b = getkeystring(curarg, &l,
+ OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
/* handle width/precision here and use fwrite so that
* nul characters can be output */
if (prec >= 0 && prec < l) l = prec;
@@ -3402,9 +3494,9 @@ bin_print(char *name, char **args, char *ops, int func)
if (maxarg) args = first + maxarg;
/* if there are remaining args, reuse format string */
- } while (*args && args != first && !ops['r']);
+ } while (*args && args != first && !OPT_ISSET(ops,'r'));
- if (ops['z'] || ops['s']) {
+ if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
#ifdef HAVE_OPEN_MEMSTREAM
putc(0, fout);
fflush(fout);
@@ -3416,7 +3508,7 @@ bin_print(char *name, char **args, char *ops, int func)
buf[count] = '\0';
#endif
queue_signals();
- if (ops['z']) {
+ if (OPT_ISSET(ops,'z')) {
zpushnode(bufstack, buf);
} else {
ent = prepnexthistent();
@@ -3442,7 +3534,7 @@ bin_print(char *name, char **args, char *ops, int func)
/**/
int
-bin_shift(char *name, char **argv, char *ops, int func)
+bin_shift(char *name, char **argv, Options ops, int func)
{
int num = 1, l, ret = 0;
char **s;
@@ -3493,7 +3585,7 @@ int optcind;
/**/
int
-bin_getopts(char *name, char **argv, char *ops, int func)
+bin_getopts(char *name, char **argv, Options ops, int func)
{
int lenstr, lenoptstr, quiet, lenoptbuf;
char *optstr = unmetafy(*argv++, &lenoptstr), *var = *argv++;
@@ -3600,7 +3692,7 @@ exit_pending;
/**/
int
-bin_break(char *name, char **argv, char *ops, int func)
+bin_break(char *name, char **argv, Options ops, int func)
{
int num = lastval, nump = 0;
@@ -3746,7 +3838,7 @@ zexit(int val, int from_where)
/**/
int
-bin_dot(char *name, char **argv, char *ops, int func)
+bin_dot(char *name, char **argv, Options ops, int func)
{
char **old, *old0 = NULL;
int ret, diddot = 0, dotdot = 0;
@@ -3824,10 +3916,10 @@ bin_dot(char *name, char **argv, char *ops, int func)
/**/
int
-bin_emulate(char *nam, char **argv, char *ops, int func)
+bin_emulate(char *nam, char **argv, Options ops, int func)
{
- emulate(*argv, ops['R']);
- if (ops['L'])
+ emulate(*argv, OPT_ISSET(ops,'R'));
+ if (OPT_ISSET(ops,'L'))
opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
return 0;
}
@@ -3836,7 +3928,7 @@ bin_emulate(char *nam, char **argv, char *ops, int func)
/**/
int
-bin_eval(char *nam, char **argv, char *ops, int func)
+bin_eval(char *nam, char **argv, Options ops, int func)
{
Eprog prog;
char *oscriptname = scriptname;
@@ -3873,7 +3965,7 @@ file/buffer. */
/**/
int
-bin_read(char *name, char **args, char *ops, int func)
+bin_read(char *name, char **args, Options ops, int func)
{
char *reply, *readpmpt;
int bsiz, c = 0, gotnl = 0, al = 0, first, nchars = 1, bslash, keys = 0;
@@ -3887,26 +3979,30 @@ bin_read(char *name, char **args, char *ops, int func)
char d;
- if ((ops['k'] || ops['b']) && *args && idigit(**args)) {
- if (!(nchars = atoi(*args)))
- nchars = 1;
- args++;
+ if ((OPT_HASARG(ops,c='k') || OPT_HASARG(ops,c='b'))) {
+ char *eptr, *optarg = OPT_ARG(ops,c);
+ nchars = (int)zstrtol(optarg, &eptr, 10);
+ if (*eptr) {
+ zwarnnam(name, "number expected after -%c: %s", optarg, c);
+ return 1;
+ }
}
/* This `*args++ : *args' looks a bit weird, but it works around a bug
* in gcc-2.8.1 under DU 4.0. */
firstarg = (*args && **args == '?' ? *args++ : *args);
- reply = *args ? *args++ : ops['A'] ? "reply" : "REPLY";
+ reply = *args ? *args++ : OPT_ISSET(ops,'A') ? "reply" : "REPLY";
- if (ops['A'] && *args) {
+ if (OPT_ISSET(ops,'A') && *args) {
zwarnnam(name, "only one array argument allowed", NULL, 0);
return 1;
}
/* handle compctl case */
- if(ops['l'] || ops['c'])
+ if(OPT_ISSET(ops,'l') || OPT_ISSET(ops,'c'))
return compctlread(name, args, ops, reply);
- if ((ops['k'] && !ops['u'] && !ops['p']) || ops['q']) {
+ if ((OPT_ISSET(ops,'k') && !OPT_ISSET(ops,'u') &&
+ !OPT_ISSET(ops,'p')) || OPT_ISSET(ops,'q')) {
if (!zleactive) {
if (SHTTY == -1) {
/* need to open /dev/tty specially */
@@ -3930,24 +4026,38 @@ bin_read(char *name, char **args, char *ops, int func)
gettyinfo(&shttyinfo);
/* attach to the tty */
attachtty(mypgrp);
- if (!isem && ops['k'])
+ if (!isem && OPT_ISSET(ops,'k'))
setcbreak();
readfd = SHTTY;
}
keys = 1;
- } else if (ops['u'] && !ops['p']) {
- /* -u means take input from the specified file descriptor. *
- * -up means take input from the coprocess. */
- for (readfd = 9; readfd && !ops[readfd + '0']; --readfd);
+ } else if (OPT_HASARG(ops,'u') && !OPT_ISSET(ops,'p')) {
+ /* -u means take input from the specified file descriptor. */
+ char *eptr, *argptr = OPT_ARG(ops,'u');
+ /* The old code handled -up, but that was never documented. Still...*/
+ if (!strcmp(argptr, "p")) {
+ readfd = coprocin;
+ } else {
+ readfd = (int)zstrtol(argptr, &eptr, 10);
+ if (*eptr) {
+ zwarnnam(name, "number expected after -u: %s", argptr, 0);
+ return 1;
+ }
+ }
+#if 0
+ /* This code is left as a warning to future generations --- pws. */
+ for (readfd = 9; readfd && !OPT_ISSET(ops,readfd + '0'); --readfd);
+#endif
izle = 0;
- } else if (ops['p']) {
+ } else if (OPT_ISSET(ops,'p')) {
readfd = coprocin;
izle = 0;
} else
readfd = izle = 0;
- if (ops['t'] && !read_poll(readfd, &readchar, keys && !zleactive)) {
- if (ops['k'] && !zleactive && !isem)
+ if (OPT_ISSET(ops,'t') &&
+ !read_poll(readfd, &readchar, keys && !zleactive)) {
+ if (OPT_ISSET(ops,'k') && !zleactive && !isem)
settyinfo(&shttyinfo);
if (haso) {
fclose(shout);
@@ -3956,7 +4066,7 @@ bin_read(char *name, char **args, char *ops, int func)
}
return 1;
}
- if (ops['s'] && SHTTY != -1) {
+ if (OPT_ISSET(ops,'s') && SHTTY != -1) {
struct ttyinfo ti;
gettyinfo(&ti);
saveti = ti;
@@ -3983,7 +4093,7 @@ bin_read(char *name, char **args, char *ops, int func)
}
/* option -k means read only a given number of characters (default 1) */
- if (ops['k']) {
+ if (OPT_ISSET(ops,'k')) {
/* allocate buffer space for result */
bptr = buf = (char *)zalloc(nchars+1);
@@ -4010,7 +4120,7 @@ bin_read(char *name, char **args, char *ops, int func)
}
} while (nchars > 0);
- if (!izle && !ops['u'] && !ops['p']) {
+ if (!izle && !OPT_ISSET(ops,'u') && !OPT_ISSET(ops,'p')) {
/* dispose of result appropriately, etc. */
if (isem)
while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n');
@@ -4025,9 +4135,9 @@ bin_read(char *name, char **args, char *ops, int func)
}
}
- if (ops['e'] || ops['E'])
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
fwrite(buf, bptr - buf, 1, stdout);
- if (!ops['e'])
+ if (!OPT_ISSET(ops,'e'))
setsparam(reply, metafy(buf, bptr - buf, META_REALLOC));
else
zfree(buf, bptr - buf + 1);
@@ -4037,7 +4147,7 @@ bin_read(char *name, char **args, char *ops, int func)
}
/* option -q means get one character, and interpret it as a Y or N */
- if (ops['q']) {
+ if (OPT_ISSET(ops,'q')) {
char readbuf[2];
/* set up the buffer */
@@ -4058,9 +4168,9 @@ bin_read(char *name, char **args, char *ops, int func)
SHTTY = -1;
}
}
- if (ops['e'] || ops['E'])
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
printf("%s\n", readbuf);
- if (!ops['e'])
+ if (!OPT_ISSET(ops,'e'))
setsparam(reply, ztrdup(readbuf));
if (resettty && SHTTY != -1)
@@ -4073,11 +4183,11 @@ bin_read(char *name, char **args, char *ops, int func)
onto the last parameter. If an array is specified, all the words become
separate elements of the array. */
- zbuforig = zbuf = (!ops['z']) ? NULL :
+ zbuforig = zbuf = (!OPT_ISSET(ops,'z')) ? NULL :
(nonempty(bufstack)) ? (char *) getlinknode(bufstack) : ztrdup("");
first = 1;
bslash = 0;
- while (*args || (ops['A'] && !gotnl)) {
+ while (*args || (OPT_ISSET(ops,'A') && !gotnl)) {
sigset_t s = child_unblock();
buf = bptr = (char *)zalloc(bsiz = 64);
/* get input, a character at a time */
@@ -4108,7 +4218,7 @@ bin_read(char *name, char **args, char *ops, int func)
first |= !iwsep(c);
continue;
}
- bslash = c == '\\' && !bslash && !ops['r'];
+ bslash = c == '\\' && !bslash && !OPT_ISSET(ops,'r');
if (bslash)
continue;
first = 0;
@@ -4130,19 +4240,19 @@ bin_read(char *name, char **args, char *ops, int func)
gotnl = 1;
*bptr = '\0';
/* dispose of word appropriately */
- if (ops['e'] || ops['E']) {
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
zputs(buf, stdout);
putchar('\n');
}
- if (!ops['e'] && (*buf || first)) {
- if (ops['A']) {
+ if (!OPT_ISSET(ops,'e') && (*buf || first)) {
+ if (OPT_ISSET(ops,'A')) {
addlinknode(readll, buf);
al++;
} else
setsparam(reply, buf);
} else
free(buf);
- if (!ops['A'])
+ if (!OPT_ISSET(ops,'A'))
reply = *args++;
}
/* handle EOF */
@@ -4154,15 +4264,15 @@ bin_read(char *name, char **args, char *ops, int func)
}
}
/* final assignment (and display) of array parameter */
- if (ops['A']) {
+ if (OPT_ISSET(ops,'A')) {
char **pp, **p = NULL;
LinkNode n;
- p = (ops['e'] ? (char **)NULL
+ p = (OPT_ISSET(ops,'e') ? (char **)NULL
: (char **)zalloc((al + 1) * sizeof(char *)));
for (pp = p, n = firstnode(readll); n; incnode(n)) {
- if (ops['e'] || ops['E']) {
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
zputs((char *) getdata(n), stdout);
putchar('\n');
}
@@ -4202,7 +4312,7 @@ bin_read(char *name, char **args, char *ops, int func)
continue;
}
}
- bslash = c == '\\' && !bslash && !ops['r'];
+ bslash = c == '\\' && !bslash && !OPT_ISSET(ops,'r');
if (bslash)
continue;
if (imeta(c)) {
@@ -4226,11 +4336,11 @@ bin_read(char *name, char **args, char *ops, int func)
if (resettty && SHTTY != -1)
settyinfo(&saveti);
/* final assignment of reply, etc. */
- if (ops['e'] || ops['E']) {
+ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
zputs(buf, stdout);
putchar('\n');
}
- if (!ops['e'])
+ if (!OPT_ISSET(ops,'e'))
setsparam(reply, buf);
else
zsfree(buf);
@@ -4345,7 +4455,7 @@ testlex(void)
/**/
int
-bin_test(char *name, char **argv, char *ops, int func)
+bin_test(char *name, char **argv, Options ops, int func)
{
char **s;
Eprog prog;
@@ -4400,7 +4510,7 @@ bin_test(char *name, char **argv, char *ops, int func)
/**/
int
-bin_times(char *name, char **argv, char *ops, int func)
+bin_times(char *name, char **argv, Options ops, int func)
{
struct tms buf;
@@ -4422,7 +4532,7 @@ bin_times(char *name, char **argv, char *ops, int func)
/**/
int
-bin_trap(char *name, char **argv, char *ops, int func)
+bin_trap(char *name, char **argv, Options ops, int func)
{
Eprog prog;
char *arg, *s;
@@ -4498,11 +4608,11 @@ bin_trap(char *name, char **argv, char *ops, int func)
/**/
int
-bin_ttyctl(char *name, char **argv, char *ops, int func)
+bin_ttyctl(char *name, char **argv, Options ops, int func)
{
- if (ops['f'])
+ if (OPT_ISSET(ops,'f'))
ttyfrozen = 1;
- else if (ops['u'])
+ else if (OPT_ISSET(ops,'u'))
ttyfrozen = 0;
else
printf("tty is %sfrozen\n", ttyfrozen ? "" : "not ");
@@ -4513,7 +4623,7 @@ bin_ttyctl(char *name, char **argv, char *ops, int func)
/**/
int
-bin_let(char *name, char **argv, char *ops, int func)
+bin_let(char *name, char **argv, Options ops, int func)
{
zlong val = 0;
@@ -4531,7 +4641,7 @@ bin_let(char *name, char **argv, char *ops, int func)
/**/
int
-bin_umask(char *nam, char **args, char *ops, int func)
+bin_umask(char *nam, char **args, Options ops, int func)
{
mode_t um;
char *s = *args;
@@ -4541,7 +4651,7 @@ bin_umask(char *nam, char **args, char *ops, int func)
umask(um);
/* No arguments means to display the current setting. */
if (!s) {
- if (ops['S']) {
+ if (OPT_ISSET(ops,'S')) {
char *who = "ugo";
while (*who) {
@@ -4642,7 +4752,7 @@ bin_umask(char *nam, char **args, char *ops, int func)
/**/
mod_export int
-bin_notavail(char *nam, char **argv, char *ops, int func)
+bin_notavail(char *nam, char **argv, Options ops, int func)
{
zwarnnam(nam, "not available on this system", NULL, 0);
return 1;
diff --git a/Src/hashtable.c b/Src/hashtable.c
index 01abbf380..9fc7a3232 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -557,7 +557,7 @@ printhashtabinfo(HashTable ht)
/**/
int
-bin_hashinfo(char *nam, char **args, char *ops, int func)
+bin_hashinfo(char *nam, char **args, Options ops, int func)
{
HashTable ht;
diff --git a/Src/hashtable.h b/Src/hashtable.h
index aa12ad3cb..fdb9ab4fc 100644
--- a/Src/hashtable.h
+++ b/Src/hashtable.h
@@ -48,15 +48,16 @@
#define BIN_EVAL 14
#define BIN_SCHED 15
#define BIN_FC 16
-#define BIN_PUSHLINE 17
-#define BIN_LOGOUT 18
-#define BIN_TEST 19
-#define BIN_BRACKET 20
-#define BIN_EXPORT 21
-#define BIN_ECHO 22
-#define BIN_DISABLE 23
-#define BIN_ENABLE 24
-#define BIN_PRINTF 25
+#define BIN_R 17
+#define BIN_PUSHLINE 18
+#define BIN_LOGOUT 19
+#define BIN_TEST 20
+#define BIN_BRACKET 21
+#define BIN_EXPORT 22
+#define BIN_ECHO 23
+#define BIN_DISABLE 24
+#define BIN_ENABLE 25
+#define BIN_PRINTF 26
/* These currently depend on being 0 and 1. */
#define BIN_SETOPT 0
diff --git a/Src/init.c b/Src/init.c
index 1d2d8828f..c1c16873a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1175,7 +1175,7 @@ mod_export CompctlReadFn compctlreadptr = fallback_compctlread;
/**/
mod_export int
-fallback_compctlread(char *name, char **args, char *ops, char *reply)
+fallback_compctlread(char *name, char **args, Options ops, char *reply)
{
zwarnnam(name, "option valid only in functions called from completion",
NULL, 0);
diff --git a/Src/jobs.c b/Src/jobs.c
index a2dbea983..eb8d24450 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1252,11 +1252,11 @@ init_hackzero(char **argv, char **envp)
/**/
int
-bin_fg(char *name, char **argv, char *ops, int func)
+bin_fg(char *name, char **argv, Options ops, int func)
{
int job, lng, firstjob = -1, retval = 0, ofunc = func;
- if (ops['Z']) {
+ if (OPT_ISSET(ops,'Z')) {
int len;
if(isset(RESTRICTED)) {
@@ -1277,8 +1277,8 @@ bin_fg(char *name, char **argv, char *ops, int func)
return 0;
}
- lng = (ops['l']) ? 1 : (ops['p']) ? 2 : 0;
- if (ops['d'])
+ lng = (OPT_ISSET(ops,'l')) ? 1 : (OPT_ISSET(ops,'p')) ? 2 : 0;
+ if (OPT_ISSET(ops,'d'))
lng |= 4;
if ((func == BIN_FG || func == BIN_BG) && !jobbing) {
@@ -1327,10 +1327,11 @@ bin_fg(char *name, char **argv, char *ops, int func)
}
for (job = 0; job != maxjob; job++, jobptr++)
if (job != ignorejob && jobptr->stat) {
- if ((!ops['r'] && !ops['s']) ||
- (ops['r'] && ops['s']) ||
- (ops['r'] && !(jobptr->stat & STAT_STOPPED)) ||
- (ops['s'] && jobptr->stat & STAT_STOPPED))
+ if ((!OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'s')) ||
+ (OPT_ISSET(ops,'r') && OPT_ISSET(ops,'s')) ||
+ (OPT_ISSET(ops,'r') &&
+ !(jobptr->stat & STAT_STOPPED)) ||
+ (OPT_ISSET(ops,'s') && jobptr->stat & STAT_STOPPED))
printjob(jobptr, lng, 2);
}
unqueue_signals();
@@ -1498,7 +1499,7 @@ bin_fg(char *name, char **argv, char *ops, int func)
/**/
int
-bin_kill(char *nam, char **argv, char *ops, int func)
+bin_kill(char *nam, char **argv, Options ops, int func)
{
int sig = SIGTERM;
int returnval = 0;
@@ -1642,10 +1643,10 @@ bin_kill(char *nam, char **argv, char *ops, int func)
/**/
int
-bin_suspend(char *name, char **argv, char *ops, int func)
+bin_suspend(char *name, char **argv, Options ops, int func)
{
/* won't suspend a login shell, unless forced */
- if (islogin && !ops['f']) {
+ if (islogin && !OPT_ISSET(ops,'f')) {
zwarnnam(name, "can't suspend login shell", NULL, 0);
return 1;
}
diff --git a/Src/mem.c b/Src/mem.c
index 67b4624d9..1d60fc42a 100644
--- a/Src/mem.c
+++ b/Src/mem.c
@@ -1238,7 +1238,7 @@ calloc(MALLOC_ARG_T n, MALLOC_ARG_T size)
/**/
int
-bin_mem(char *name, char **argv, char *ops, int func)
+bin_mem(char *name, char **argv, Options ops, int func)
{
int i, ii, fi, ui, j;
struct m_hdr *m, *mf, *ms;
@@ -1246,21 +1246,21 @@ bin_mem(char *name, char **argv, char *ops, int func)
long u = 0, f = 0, to, cu;
queue_signals();
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("The lower and the upper addresses of the heap. Diff gives\n");
printf("the difference between them, i.e. the size of the heap.\n\n");
}
printf("low mem %ld\t high mem %ld\t diff %ld\n",
(long)m_l, (long)m_high, (long)(m_high - ((char *)m_l)));
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\nThe number of bytes that were allocated using sbrk() and\n");
printf("the number of bytes that were given back to the system\n");
printf("via brk().\n");
}
printf("\nsbrk %d\tbrk %d\n", m_s, m_b);
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\nInformation about the sizes that were allocated or freed.\n");
printf("For each size that were used the number of mallocs and\n");
printf("frees is shown. Diff gives the difference between these\n");
@@ -1282,7 +1282,7 @@ bin_mem(char *name, char **argv, char *ops, int func)
if (m_m[i] || m_f[i])
printf("big\t%d\t%d\t%d\n", m_m[i], m_f[i], m_m[i] - m_f[i]);
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\nThe list of memory blocks. For each block the following\n");
printf("information is shown:\n\n");
printf("num\tthe number of this block\n");
@@ -1334,7 +1334,7 @@ bin_mem(char *name, char **argv, char *ops, int func)
mf = mf->next;
}
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\nHere is some information about the small blocks used.\n");
printf("For each size the arrays with the number of free and the\n");
printf("number of used blocks are shown.\n");
@@ -1353,7 +1353,7 @@ bin_mem(char *name, char **argv, char *ops, int func)
}
putchar('\n');
}
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\n\nBelow is some information about the allocation\n");
printf("behaviour of the zsh heaps. First the number of times\n");
printf("pushheap(), popheap(), and freeheap() were called.\n");
@@ -1362,7 +1362,7 @@ bin_mem(char *name, char **argv, char *ops, int func)
printf("push %d\tpop %d\tfree %d\n\n", h_push, h_pop, h_free);
- if (ops['v']) {
+ if (OPT_ISSET(ops,'v')) {
printf("\nThe next list shows for several sizes the number of times\n");
printf("memory of this size were taken from heaps.\n\n");
}
diff --git a/Src/module.c b/Src/module.c
index 9cecac826..2c2e9e0f0 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -92,9 +92,9 @@ register_module(char *n, Module_func setup, Module_func boot,
/**/
static void
-printmodalias(Module m, char *ops)
+printmodalias(Module m, Options ops)
{
- if (ops['L']) {
+ if (OPT_ISSET(ops,'L')) {
printf("zmodload -A ");
if (m->nam[0] == '-')
fputs("-- ", stdout);
@@ -956,10 +956,11 @@ autoloadscan(HashNode hn, int printflags)
/**/
int
-bin_zmodload(char *nam, char **args, char *ops, int func)
+bin_zmodload(char *nam, char **args, Options ops, int func)
{
- int ops_bcpf = ops['b'] || ops['c'] || ops['p'] || ops['f'];
- int ops_au = ops['a'] || ops['u'];
+ int ops_bcpf = OPT_ISSET(ops,'b') || OPT_ISSET(ops,'c') ||
+ OPT_ISSET(ops,'p') || OPT_ISSET(ops,'f');
+ int ops_au = OPT_ISSET(ops,'a') || OPT_ISSET(ops,'u');
int ret = 1;
if (ops_bcpf && !ops_au) {
@@ -967,41 +968,45 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
NULL, 0);
return 1;
}
- if (ops['A'] || ops['R']) {
- if (ops_bcpf || ops_au || ops['d'] || (ops['R'] && ops['e'])) {
+ if (OPT_ISSET(ops,'A') || OPT_ISSET(ops,'R')) {
+ if (ops_bcpf || ops_au || OPT_ISSET(ops,'d') ||
+ (OPT_ISSET(ops,'R') && OPT_ISSET(ops,'e'))) {
zwarnnam(nam, "illegal flags combined with -A or -R", NULL, 0);
return 1;
}
- if (!ops['e'])
+ if (!OPT_ISSET(ops,'e'))
return bin_zmodload_alias(nam, args, ops);
}
- if (ops['d'] && ops['a']) {
+ if (OPT_ISSET(ops,'d') && OPT_ISSET(ops,'a')) {
zwarnnam(nam, "-d cannot be combined with -a", NULL, 0);
return 1;
}
- if (ops['u'] && !*args) {
+ if (OPT_ISSET(ops,'u') && !*args) {
zwarnnam(nam, "what do you want to unload?", NULL, 0);
return 1;
}
- if (ops['e'] && (ops['I'] || ops['L'] || ops['a'] || ops['d'] ||
- ops['i'] || ops['u'])) {
+ if (OPT_ISSET(ops,'e') && (OPT_ISSET(ops,'I') || OPT_ISSET(ops,'L') ||
+ OPT_ISSET(ops,'a') || OPT_ISSET(ops,'d') ||
+ OPT_ISSET(ops,'i') || OPT_ISSET(ops,'u'))) {
zwarnnam(nam, "-e cannot be combined with other options", NULL, 0);
return 1;
}
queue_signals();
- if (ops['e'])
+ if (OPT_ISSET(ops,'e'))
ret = bin_zmodload_exist(nam, args, ops);
- else if (ops['d'])
+ else if (OPT_ISSET(ops,'d'))
ret = bin_zmodload_dep(nam, args, ops);
- else if ((ops['a'] || ops['b']) && !(ops['c'] || ops['p'] || ops['f']))
+ else if ((OPT_ISSET(ops,'a') || OPT_ISSET(ops,'b')) &&
+ !(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'p') || OPT_ISSET(ops,'f')))
ret = bin_zmodload_auto(nam, args, ops);
- else if (ops['c'] && !(ops['b'] || ops['p']))
+ else if (OPT_ISSET(ops,'c') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'p')))
ret = bin_zmodload_cond(nam, args, ops);
- else if (ops['f'] && !(ops['b'] || ops['p']))
+ else if (OPT_ISSET(ops,'f') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'p')))
ret = bin_zmodload_math(nam, args, ops);
- else if (ops['p'] && !(ops['b'] || ops['c']))
+ else if (OPT_ISSET(ops,'p') && !(OPT_ISSET(ops,'b') || OPT_ISSET(ops,'c')))
ret = bin_zmodload_param(nam, args, ops);
- else if (!(ops['a'] || ops['b'] || ops['c'] || ops['p']))
+ else if (!(OPT_ISSET(ops,'a') || OPT_ISSET(ops,'b') ||
+ OPT_ISSET(ops,'c') || OPT_ISSET(ops,'p')))
ret = bin_zmodload_load(nam, args, ops);
else
zwarnnam(nam, "use only one of -b, -c, or -p", NULL, 0);
@@ -1012,7 +1017,7 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
/**/
static int
-bin_zmodload_alias(char *nam, char **args, char *ops)
+bin_zmodload_alias(char *nam, char **args, Options ops)
{
/*
* TODO: while it would be too nasty to have aliases, as opposed
@@ -1032,7 +1037,7 @@ bin_zmodload_alias(char *nam, char **args, char *ops)
int ret = 0;
if (!*args) {
- if (ops['R']) {
+ if (OPT_ISSET(ops,'R')) {
zwarnnam(nam, "no module alias to remove", NULL, 0);
return 1;
}
@@ -1053,7 +1058,7 @@ bin_zmodload_alias(char *nam, char **args, char *ops)
zwarnnam(nam, "invalid module name `%s'", *args, 0);
return 1;
}
- if (ops['R']) {
+ if (OPT_ISSET(ops,'R')) {
if (aliasname) {
zwarnnam(nam, "bad syntax for removing module alias: %s",
*args, 0);
@@ -1123,7 +1128,7 @@ bin_zmodload_alias(char *nam, char **args, char *ops)
/**/
static int
-bin_zmodload_exist(char *nam, char **args, char *ops)
+bin_zmodload_exist(char *nam, char **args, Options ops)
{
LinkNode node;
Module m;
@@ -1135,7 +1140,8 @@ bin_zmodload_exist(char *nam, char **args, char *ops)
modname = m->nam;
if (m->flags & MOD_ALIAS) {
LinkNode node2;
- if (ops['A'] && (node2 = find_module(m->u.alias, 1, NULL)))
+ if (OPT_ISSET(ops,'A') &&
+ (node2 = find_module(m->u.alias, 1, NULL)))
m = (Module) getdata(node2);
else
continue;
@@ -1161,11 +1167,11 @@ bin_zmodload_exist(char *nam, char **args, char *ops)
/**/
static int
-bin_zmodload_dep(char *nam, char **args, char *ops)
+bin_zmodload_dep(char *nam, char **args, Options ops)
{
LinkNode node;
Module m;
- if (ops['u']) {
+ if (OPT_ISSET(ops,'u')) {
/* remove dependencies, which can't pertain to aliases */
const char *tnam = *args++;
node = find_module(tnam, 1, &tnam);
@@ -1201,7 +1207,7 @@ bin_zmodload_dep(char *nam, char **args, char *ops)
m = (Module) getdata(node);
if (m->deps && (!args[0] || !strcmp(args[0], m->nam))) {
LinkNode n;
- if (ops['L']) {
+ if (OPT_ISSET(ops,'L')) {
printf("zmodload -d ");
if(m->nam[0] == '-')
fputs("-- ", stdout);
@@ -1212,7 +1218,7 @@ bin_zmodload_dep(char *nam, char **args, char *ops)
}
for (n = firstnode(m->deps); n; incnode(n)) {
putchar(' ');
- if(ops['L'])
+ if(OPT_ISSET(ops,'L'))
quotedzputs((char *) getdata(n), stdout);
else
nicezputs((char *) getdata(n), stdout);
@@ -1234,15 +1240,15 @@ bin_zmodload_dep(char *nam, char **args, char *ops)
/**/
static int
-bin_zmodload_auto(char *nam, char **args, char *ops)
+bin_zmodload_auto(char *nam, char **args, Options ops)
{
int ret = 0;
- if(ops['u']) {
+ if(OPT_ISSET(ops,'u')) {
/* remove autoloaded builtins */
for (; *args; args++) {
Builtin bn = (Builtin) builtintab->getnode2(builtintab, *args);
if (!bn) {
- if(!ops['i']) {
+ if(!OPT_ISSET(ops,'i')) {
zwarnnam(nam, "%s: no such builtin", *args, 0);
ret = 1;
}
@@ -1256,7 +1262,7 @@ bin_zmodload_auto(char *nam, char **args, char *ops)
} else if(!*args) {
/* list autoloaded builtins */
scanhashtable(builtintab, 0, 0, 0,
- autoloadscan, ops['L'] ? PRINT_LIST : 0);
+ autoloadscan, OPT_ISSET(ops,'L') ? PRINT_LIST : 0);
return 0;
} else {
/* add autoloaded builtins */
@@ -1267,7 +1273,7 @@ bin_zmodload_auto(char *nam, char **args, char *ops)
if (strchr(bnam, '/')) {
zwarnnam(nam, "%s: `/' is illegal in a builtin", bnam, 0);
ret = 1;
- } else if (add_autobin(bnam, modnam) && !ops['i']) {
+ } else if (add_autobin(bnam, modnam) && !OPT_ISSET(ops,'i')) {
zwarnnam(nam, "failed to add builtin %s", bnam, 0);
ret = 1;
}
@@ -1278,17 +1284,17 @@ bin_zmodload_auto(char *nam, char **args, char *ops)
/**/
static int
-bin_zmodload_cond(char *nam, char **args, char *ops)
+bin_zmodload_cond(char *nam, char **args, Options ops)
{
int ret = 0;
- if (ops['u']) {
+ if (OPT_ISSET(ops,'u')) {
/* remove autoloaded conditions */
for (; *args; args++) {
- Conddef cd = getconddef(ops['I'], *args, 0);
+ Conddef cd = getconddef(OPT_ISSET(ops,'I'), *args, 0);
if (!cd) {
- if (!ops['i']) {
+ if (!OPT_ISSET(ops,'i')) {
zwarnnam(nam, "%s: no such condition", *args, 0);
ret = 1;
}
@@ -1305,7 +1311,7 @@ bin_zmodload_cond(char *nam, char **args, char *ops)
for (p = condtab; p; p = p->next) {
if (p->module) {
- if (ops['L']) {
+ if (OPT_ISSET(ops,'L')) {
fputs("zmodload -ac", stdout);
if (p->flags & CONDF_INFIX)
putchar('I');
@@ -1330,7 +1336,8 @@ bin_zmodload_cond(char *nam, char **args, char *ops)
if (strchr(cnam, '/')) {
zwarnnam(nam, "%s: `/' is illegal in a condition", cnam, 0);
ret = 1;
- } else if (add_autocond(cnam, ops['I'], modnam) && !ops['i']) {
+ } else if (add_autocond(cnam, OPT_ISSET(ops,'I'), modnam) &&
+ !OPT_ISSET(ops,'i')) {
zwarnnam(nam, "failed to add condition `%s'", cnam, 0);
ret = 1;
}
@@ -1341,17 +1348,17 @@ bin_zmodload_cond(char *nam, char **args, char *ops)
/**/
static int
-bin_zmodload_math(char *nam, char **args, char *ops)
+bin_zmodload_math(char *nam, char **args, Options ops)
{
int ret = 0;
- if (ops['u']) {
+ if (OPT_ISSET(ops,'u')) {
/* remove autoloaded math functions */
for (; *args; args++) {
MathFunc f = getmathfunc(*args, 0);
if (!f) {
- if (!ops['i']) {
+ if (!OPT_ISSET(ops,'i')) {
zwarnnam(nam, "%s: no such math function", *args, 0);
ret = 1;
}
@@ -1368,7 +1375,7 @@ bin_zmodload_math(char *nam, char **args, char *ops)
for (p = mathfuncs; p; p = p->next) {
if (p->module) {
- if (ops['L']) {
+ if (OPT_ISSET(ops,'L')) {
fputs("zmodload -af", stdout);
printf(" %s %s\n", p->module, p->name);
} else
@@ -1387,7 +1394,7 @@ bin_zmodload_math(char *nam, char **args, char *ops)
zwarnnam(nam, "%s: `/' is illegal in a math function",
fnam, 0);
ret = 1;
- } else if (add_automathfunc(fnam, modnam) && !ops['i']) {
+ } else if (add_automathfunc(fnam, modnam) && !OPT_ISSET(ops,'i')) {
zwarnnam(nam, "failed to add math function `%s'", fnam, 0);
ret = 1;
}
@@ -1411,17 +1418,17 @@ printautoparams(HashNode hn, int lon)
/**/
static int
-bin_zmodload_param(char *nam, char **args, char *ops)
+bin_zmodload_param(char *nam, char **args, Options ops)
{
int ret = 0;
- if (ops['u']) {
+ if (OPT_ISSET(ops,'u')) {
/* remove autoloaded parameters */
for (; *args; args++) {
Param pm = (Param) gethashnode2(paramtab, *args);
if (!pm) {
- if (!ops['i']) {
+ if (!OPT_ISSET(ops,'i')) {
zwarnnam(nam, "%s: no such parameter", *args, 0);
ret = 1;
}
@@ -1433,7 +1440,7 @@ bin_zmodload_param(char *nam, char **args, char *ops)
}
return ret;
} else if (!*args) {
- scanhashtable(paramtab, 1, 0, 0, printautoparams, ops['L']);
+ scanhashtable(paramtab, 1, 0, 0, printautoparams, OPT_ISSET(ops,'L'));
return 0;
} else {
/* add autoloaded parameters */
@@ -1544,12 +1551,12 @@ unload_module(Module m, LinkNode node)
/**/
static int
-bin_zmodload_load(char *nam, char **args, char *ops)
+bin_zmodload_load(char *nam, char **args, Options ops)
{
LinkNode node;
Module m;
int ret = 0;
- if(ops['u']) {
+ if(OPT_ISSET(ops,'u')) {
/* unload modules */
const char *mname = *args;
for(; *args; args++) {
@@ -1579,7 +1586,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
ret = 1;
if (del)
m->wrapper--;
- } else if (!ops['i']) {
+ } else if (!OPT_ISSET(ops,'i')) {
zwarnnam(nam, "no such module %s", *args, 0);
ret = 1;
}
@@ -1591,7 +1598,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node);
if (m->u.handle && !(m->flags & (MOD_UNLOAD|MOD_ALIAS))) {
- if(ops['L']) {
+ if(OPT_ISSET(ops,'L')) {
printf("zmodload ");
if(m->nam[0] == '-')
fputs("-- ", stdout);
@@ -1605,7 +1612,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
} else {
/* load modules */
for (; *args; args++)
- if (!require_module(nam, *args, 1, (!ops['i'])))
+ if (!require_module(nam, *args, 1, (!OPT_ISSET(ops,'i'))))
ret = 1;
return ret;
diff --git a/Src/options.c b/Src/options.c
index 7555440f6..841a3cb82 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -481,7 +481,7 @@ setoption(HashNode hn, int value)
/**/
int
-bin_setopt(char *nam, char **args, char *ops, int isun)
+bin_setopt(char *nam, char **args, Options ops, int isun)
{
int action, optno, match = 0;
diff --git a/Src/parse.c b/Src/parse.c
index 4b105d868..b53b36a0e 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2396,24 +2396,26 @@ dump_find_func(Wordcode h, char *name)
/**/
int
-bin_zcompile(char *nam, char **args, char *ops, int func)
+bin_zcompile(char *nam, char **args, Options ops, int func)
{
int map, flags, ret;
char *dump;
- if ((ops['k'] && ops['z']) || (ops['R'] && ops['M']) ||
- (ops['c'] && (ops['U'] || ops['k'] || ops['z'])) ||
- (!(ops['c'] || ops['a']) && ops['m'])) {
+ if ((OPT_ISSET(ops,'k') && OPT_ISSET(ops,'z')) ||
+ (OPT_ISSET(ops,'R') && OPT_ISSET(ops,'M')) ||
+ (OPT_ISSET(ops,'c') &&
+ (OPT_ISSET(ops,'U') || OPT_ISSET(ops,'k') || OPT_ISSET(ops,'z'))) ||
+ (!(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) && OPT_ISSET(ops,'m'))) {
zwarnnam(nam, "illegal combination of options", NULL, 0);
return 1;
}
- if ((ops['c'] || ops['a']) && isset(KSHAUTOLOAD))
+ if ((OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) && isset(KSHAUTOLOAD))
zwarnnam(nam, "functions will use zsh style autoloading", NULL, 0);
- flags = (ops['k'] ? FDHF_KSHLOAD :
- (ops['z'] ? FDHF_ZSHLOAD : 0));
+ flags = (OPT_ISSET(ops,'k') ? FDHF_KSHLOAD :
+ (OPT_ISSET(ops,'z') ? FDHF_ZSHLOAD : 0));
- if (ops['t']) {
+ if (OPT_ISSET(ops,'t')) {
Wordcode f;
if (!*args) {
@@ -2443,21 +2445,23 @@ bin_zcompile(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too few arguments", NULL, 0);
return 1;
}
- map = (ops['M'] ? 2 : (ops['R'] ? 0 : 1));
+ map = (OPT_ISSET(ops,'M') ? 2 : (OPT_ISSET(ops,'R') ? 0 : 1));
- if (!args[1] && !(ops['c'] || ops['a'])) {
+ if (!args[1] && !(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a'))) {
queue_signals();
- ret = build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map, flags);
+ ret = build_dump(nam, dyncat(*args, FD_EXT), args, OPT_ISSET(ops,'U'),
+ map, flags);
unqueue_signals();
return ret;
}
dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT));
queue_signals();
- ret = ((ops['c'] || ops['a']) ?
- build_cur_dump(nam, dump, args + 1, ops['m'], map,
- (ops['c'] ? 1 : 0) | (ops['a'] ? 2 : 0)) :
- build_dump(nam, dump, args + 1, ops['U'], map, flags));
+ ret = ((OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) ?
+ build_cur_dump(nam, dump, args + 1, OPT_ISSET(ops,'m'), map,
+ (OPT_ISSET(ops,'c') ? 1 : 0) |
+ (OPT_ISSET(ops,'a') ? 2 : 0)) :
+ build_dump(nam, dump, args + 1, OPT_ISSET(ops,'U'), map, flags));
unqueue_signals();
return ret;
@@ -3217,7 +3221,7 @@ closedumps(void)
/**/
int
-dump_autoload(char *nam, char *file, int on, char *ops, int func)
+dump_autoload(char *nam, char *file, int on, Options ops, int func)
{
Wordcode h;
FDHead n, e;
@@ -3236,7 +3240,7 @@ dump_autoload(char *nam, char *file, int on, char *ops, int func)
shf->flags = on;
shf->funcdef = mkautofn(shf);
shfunctab->addnode(shfunctab, ztrdup(fdname(n) + fdhtail(n)), shf);
- if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
+ if (OPT_ISSET(ops,'X') && eval_autoload(shf, shf->nam, ops, func))
ret = 1;
}
return ret;
diff --git a/Src/watch.c b/Src/watch.c
index 4f63a5bd9..e2a65207c 100644
--- a/Src/watch.c
+++ b/Src/watch.c
@@ -559,7 +559,7 @@ dowatch(void)
/**/
int
-bin_log(char *nam, char **argv, char *ops, int func)
+bin_log(char *nam, char **argv, Options ops, int func)
{
if (!watch)
return 1;
@@ -581,7 +581,7 @@ void dowatch(void)
/**/
int
-bin_log(char *nam, char **argv, char *ops, int func)
+bin_log(char *nam, char **argv, Options ops, int func)
{
return bin_notavail(nam, argv, ops, func);
}
diff --git a/Src/zsh.h b/Src/zsh.h
index 881dd05b4..4cb87e085 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -298,6 +298,7 @@ typedef struct cmdnam *Cmdnam;
typedef struct shfunc *Shfunc;
typedef struct funcstack *Funcstack;
typedef struct funcwrap *FuncWrap;
+typedef struct options *Options;
typedef struct builtin *Builtin;
typedef struct nameddir *Nameddir;
typedef struct module *Module;
@@ -934,7 +935,49 @@ struct funcwrap {
/* node in builtin command hash table (builtintab) */
-typedef int (*HandlerFunc) _((char *, char **, char *, int));
+/*
+ * Handling of options.
+ *
+ * Option strings are standard in that a trailing `:' indicates
+ * a mandatory argument. In addtion, `::' indicates an optional
+ * argument which must immediately follow the option letter if it is present.
+ * `:%' indicates an optional numeric argument which may follow
+ * the option letter or be in the next word; the only test is
+ * that the next character is a digit, and no actual conversion is done.
+ */
+
+#define MAX_OPS 128
+
+/* Macros taking struct option * and char argument */
+/* Option was set as -X */
+#define OPT_MINUS(ops,c) ((ops)->ind[c] & 1)
+/* Option was set as +X */
+#define OPT_PLUS(ops,c) ((ops)->ind[c] & 2)
+/*
+ * Option was set any old how, maybe including an argument
+ * (cheap test when we don't care).
+ */
+#define OPT_ISSET(ops,c) ((ops)->ind[c])
+/* Option has an argument */
+#define OPT_HASARG(ops,c) ((ops)->ind[c] > 3)
+/* The argument for the option; not safe if it doesn't have one */
+#define OPT_ARG(ops,c) ((ops)->args[((ops)->ind[c] >> 2) - 1])
+/* Ditto, but safely returns NULL if there is no argument. */
+#define OPT_ARG_SAFE(ops,c) (OPT_HASARG(ops,c) ? OPT_ARG(ops,c) : NULL)
+
+struct options {
+ unsigned char ind[MAX_OPS];
+ char **args;
+ int argscount, argsalloc;
+};
+
+/*
+ * Handler arguments are: builtin name, null-terminated argument
+ * list excluding command name, option structure, the funcid element from the
+ * builtin structure.
+ */
+
+typedef int (*HandlerFunc) _((char *, char **, Options, int));
#define NULLBINCMD ((HandlerFunc) 0)
struct builtin {
@@ -957,22 +1000,17 @@ struct builtin {
/* builtin flags */
/* DISABLE IS DEFINED AS (1<<0) */
#define BINF_PLUSOPTS (1<<1) /* +xyz legal */
-#define BINF_R (1<<2) /* this is the builtin `r' (fc -e -) */
-#define BINF_PRINTOPTS (1<<3)
-#define BINF_ADDED (1<<4) /* is in the builtins hash table */
-#define BINF_FCOPTS (1<<5)
-#define BINF_TYPEOPT (1<<6)
-#define BINF_ECHOPTS (1<<7)
-#define BINF_MAGICEQUALS (1<<8) /* needs automatic MAGIC_EQUAL_SUBST substitution */
-#define BINF_PREFIX (1<<9)
-#define BINF_DASH (1<<10)
-#define BINF_BUILTIN (1<<11)
-#define BINF_COMMAND (1<<12)
-#define BINF_EXEC (1<<13)
-#define BINF_NOGLOB (1<<14)
-#define BINF_PSPECIAL (1<<15)
-
-#define BINF_TYPEOPTS (BINF_TYPEOPT|BINF_PLUSOPTS)
+#define BINF_PRINTOPTS (1<<2)
+#define BINF_ADDED (1<<3) /* is in the builtins hash table */
+#define BINF_ECHOPTS (1<<4)
+#define BINF_MAGICEQUALS (1<<5) /* needs automatic MAGIC_EQUAL_SUBST substitution */
+#define BINF_PREFIX (1<<6)
+#define BINF_DASH (1<<7)
+#define BINF_BUILTIN (1<<8)
+#define BINF_COMMAND (1<<9)
+#define BINF_EXEC (1<<10)
+#define BINF_NOGLOB (1<<11)
+#define BINF_PSPECIAL (1<<12)
struct module {
char *nam;
@@ -1711,7 +1749,7 @@ struct heap {
/* compctl entry point pointers */
-typedef int (*CompctlReadFn) _((char *, char **, char *, char *));
+typedef int (*CompctlReadFn) _((char *, char **, Options, char *));
/* ZLE entry point pointers */