diff options
38 files changed, 1018 insertions, 657 deletions
diff --git a/ChangeLog b/ChangeLog index 58614413a..652639d30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2002-08-27 Peter Stephenson <pws@pwstephenson.fsnet.co.uk> + + * unposted: Config/version.mk: Update version to 4.1.0-dev-6. + + * 17582: Doc/Zsh/builtins.yo, Src/builtin.c, Src/hashtable.c, + Src/hashtable.h, Src/init.c, Src/jobs.c, Src/mem.c, Src/module.c, + Src/options.c, Src/parse.c, Src/watch.c, Src/zsh.h, + Src/Builtins/rlimits.c, Src/Builtins/sched.c, Src/Modules/cap.c, + Src/Modules/clone.c, Src/Modules/datetime.c, + Src/Modules/example.c, Src/Modules/files.c, Src/Modules/pcre.c, + Src/Modules/socket.c, Src/Modules/stat.c, Src/Modules/tcp.c, + Src/Modules/termcap.c, Src/Modules/terminfo.c, Src/Modules/zftp.c, + Src/Modules/zprof.c, Src/Modules/zpty.c, Src/Modules/zselect.c, + Src/Modules/zutil.c, Src/Zle/compctl.c, Src/Zle/complete.c, + Src/Zle/computil.c, Src/Zle/zle_keymap.c, Src/Zle/zle_main.c, + Src/Zle/zle_thingy.c: Improve handling of arguments to options + of builtins by replacing character array with `struct options'. + 2002-08-24 Oliver Kiddle <opk@zsh.org> * 17577: Completion/Unix/Command/_ant, Completion/Unix/Command/_zip, diff --git a/Config/version.mk b/Config/version.mk index af4b0ea23..53e9df858 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=4.1.0-dev-5 -VERSION_DATE='June 17, 2002' +VERSION=4.1.0-dev-6 +VERSION_DATE='August 26, 2002' diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 5c084302d..42e85ea1f 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -846,9 +846,6 @@ Read only one (or var(num)) characters. All are assigned to the first var(name), without word splitting. This flag is ignored when tt(-q) is present. Input is read from the terminal unless one of tt(-u) or tt(-p) is present. This option may also be used within zle widgets. - -Note that var(num) must be in the argument word that follows tt(-k), not -in the same word. See tt(-u). ) item(tt(-z))( Read one entry from the editor buffer stack and assign it to the first @@ -884,8 +881,7 @@ and that when the cursor is at the end of the line, its character index is the length of the line plus one. ) item(tt(-u)var(n))( -Input is read from file descriptor var(n), where var(n) is a single -digit and must em(not) be separated from tt(-u) by any whitespace. +Input is read from file descriptor var(n). ) item(tt(-p))( Input is read from the coprocess. 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 */ |