summaryrefslogtreecommitdiff
path: root/Src/builtin.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2002-08-27 21:10:30 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2002-08-27 21:10:30 +0000
commit9634760d5eae4e8618e4b9ed9752d7305b3695a9 (patch)
treefc717bec9a623d6e80f2c4544cec14b8b8eb07da /Src/builtin.c
parent043c302261dfee52e54e9a6c42b4ebcc2f7ccd33 (diff)
downloadzsh-9634760d5eae4e8618e4b9ed9752d7305b3695a9.tar.gz
zsh-9634760d5eae4e8618e4b9ed9752d7305b3695a9.zip
17582: Improved option argument handling.
unposted: Updated version to 4.1.0-dev-6 because of interface change.
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c726
1 files changed, 418 insertions, 308 deletions
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;