diff options
Diffstat (limited to 'Src/builtin.c')
-rw-r--r-- | Src/builtin.c | 297 |
1 files changed, 200 insertions, 97 deletions
diff --git a/Src/builtin.c b/Src/builtin.c index 4a10c7dd1..ffde5c916 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -119,7 +119,7 @@ static struct builtin builtins[] = BUILTIN("times", BINF_PSPECIAL, bin_times, 0, 0, 0, NULL, NULL), BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, 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("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"), @@ -128,9 +128,9 @@ static struct builtin builtins[] = BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, 0, "fmv", NULL), BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL), BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL), - BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsw", NULL), - BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"), - BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"), + BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsSw", NULL), + BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsSw", "ca"), + BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsSw", "c"), BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "AFRILP:abcfdilmpue", NULL), BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUMRcmzka", NULL), }; @@ -422,7 +422,7 @@ execbuiltin(LinkList args, Builtin bn) argc -= argv - argarr; if (errflag) { - errflag = 0; + errflag &= ~ERRFLAG_ERROR; return 1; } @@ -719,7 +719,7 @@ bin_dirs(UNUSED(char *name), char **argv, Options ops, UNUSED(int func)) for (node = firstnode(dirstack); node; incnode(node)) { printf(fmt, pos++); if (OPT_ISSET(ops,'l')) - fputs(getdata(node), stdout); + zputs(getdata(node), stdout); else fprintdir(getdata(node), stdout); @@ -1093,9 +1093,11 @@ cd_try_chdir(char *pfix, char *dest, int hard) } else { int pfl = strlen(pfix); dlen = strlen(pwd); - + if (dlen == 1 && *pwd == '/') + dlen = 0; buf = zalloc(dlen + pfl + strlen(dest) + 3); - strcpy(buf, pwd); + if (dlen) + strcpy(buf, pwd); buf[dlen] = '/'; strcpy(buf + dlen + 1, pfix); buf[dlen + 1 + pfl] = '/'; @@ -1156,9 +1158,11 @@ cd_new_pwd(int func, LinkNode dir, int quiet) zsfree(getlinknode(dirstack)); if (chasinglinks) { - s = new_pwd; - new_pwd = findpwd(s); - zsfree(s); + s = findpwd(new_pwd); + if (s) { + zsfree(new_pwd); + new_pwd = s; + } } if (isset(PUSHDIGNOREDUPS)) { LinkNode n; @@ -1363,10 +1367,19 @@ bin_fc(char *nam, char **argv, Options ops, int func) if (*argv) { hf = *argv++; if (*argv) { - hs = zstrtol(*argv++, NULL, 10); - if (*argv) - shs = zstrtol(*argv++, NULL, 10); - else + char *check; + hs = zstrtol(*argv++, &check, 10); + if (*check) { + zwarnnam("fc", "HISTSIZE must be an integer"); + return 1; + } + if (*argv) { + shs = zstrtol(*argv++, &check, 10); + if (*check) { + zwarnnam("fc", "SAVEHIST must be an integer"); + return 1; + } + } else shs = hs; if (*argv) { zwarnnam("fc", "too many arguments"); @@ -1855,7 +1868,7 @@ typeset_setbase(const char *name, Param pm, Options ops, int on, int always) if (arg) { char *eptr; - pm->base = (int)zstrtol(arg, &eptr, 10); + int base = (int)zstrtol(arg, &eptr, 10); if (*eptr) { if (on & PM_INTEGER) zwarnnam(name, "bad base value: %s", arg); @@ -1863,11 +1876,12 @@ typeset_setbase(const char *name, Param pm, Options ops, int on, int always) zwarnnam(name, "bad precision value: %s", arg); return 1; } - if (pm->base < 2 || pm->base > 36) { + if ((on & PM_INTEGER) && (base < 2 || base > 36)) { zwarnnam(name, "invalid base (must be 2 to 36 inclusive): %d", - pm->base); + base); return 1; } + pm->base = base; } else if (always) pm->base = 0; @@ -1918,15 +1932,19 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), * locallevel as an unset one we use the pm struct anyway: that's * handled in createparam(). Here we just avoid using it for the * present tests if it's unset. + * + * POSIXBUILTINS horror: we need to retain the 'readonly' flag + * of an unset parameter. */ - usepm = pm && !(pm->node.flags & PM_UNSET); + usepm = pm && (!(pm->node.flags & PM_UNSET) || + (isset(POSIXBUILTINS) && (pm->node.flags & PM_READONLY))); /* * We need to compare types with an existing pm if special, * even if that's unset */ - if (pm && (pm->node.flags & PM_SPECIAL)) - usepm = 1; + if (!usepm && pm && (pm->node.flags & PM_SPECIAL)) + usepm = 2; /* indicate that we preserve the PM_UNSET flag */ /* * Don't use an existing param if @@ -2019,6 +2037,20 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), else if (newspecial != NS_NONE && strcmp(pname, "SECONDS") == 0) newspecial = NS_SECONDS; + if (isset(POSIXBUILTINS)) { + /* + * Stricter rules about retaining readonly attribute in this case. + */ + if ((on & PM_READONLY) && (!usepm || (pm->node.flags & PM_UNSET)) && + !value) + on |= PM_UNSET; + else if (usepm && (pm->node.flags & PM_READONLY) && + !(on & PM_READONLY)) { + zerr("read-only variable: %s", pm->node.nam); + return NULL; + } + } + /* * A parameter will be local if * 1. we are re-using an existing local parameter @@ -2063,7 +2095,17 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), arrfixenv(pm->node.nam, x); } } - pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET); + if (usepm == 2) /* do not change the PM_UNSET flag */ + pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off; + else { + /* + * Keep unset if using readonly in POSIX mode. + */ + if (!(on & PM_READONLY) || !isset(POSIXBUILTINS)) + off |= PM_UNSET; + pm->node.flags = (pm->node.flags | + (on & ~PM_READONLY)) & ~off; + } if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { if (typeset_setwidth(cname, pm, ops, on, 0)) return NULL; @@ -2239,7 +2281,12 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), * readonly flag */ pm = createparam(pname, on & ~PM_READONLY); - DPUTS(!pm, "BUG: parameter not created"); + if (!pm) { + if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | + PM_INTEGER | PM_EFLOAT | PM_FFLOAT)) + zerrnam(cname, "can't change variable attribute: %s", pname); + return NULL; + } if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { if (typeset_setwidth(cname, pm, ops, on, 0)) return NULL; @@ -2501,6 +2548,8 @@ bin_typeset(char *name, char **argv, Options ops, int func) asg->name), func, (on | PM_ARRAY) & ~PM_EXPORTED, off, roff, asg->value, NULL, ops, 0))) { + if (oldval) + zsfree(oldval); unqueue_signals(); return 1; } @@ -3127,7 +3176,7 @@ bin_unset(char *name, char **argv, Options ops, int func) } } returnval = errflag; - errflag = 0; + errflag &= ~ERRFLAG_ERROR; } else { zerrnam(name, "%s: invalid element for unset", s); returnval = 1; @@ -3145,6 +3194,15 @@ bin_unset(char *name, char **argv, Options ops, int func) /* type, whence, which, command */ +static LinkList matchednodes; + +static void +fetchcmdnamnode(HashNode hn, UNUSED(int printflags)) +{ + Cmdnam cn = (Cmdnam) hn; + addlinknode(matchednodes, cn->node.nam); +} + /**/ int bin_whence(char *nam, char **argv, Options ops, int func) @@ -3155,8 +3213,8 @@ bin_whence(char *nam, char **argv, Options ops, int func) int printflags = 0; int aliasflags; int csh, all, v, wd; - int informed; - char *cnam; + int informed = 0; + char *cnam, **allmatched = 0; /* Check some option information */ csh = OPT_ISSET(ops,'c'); @@ -3189,6 +3247,11 @@ bin_whence(char *nam, char **argv, Options ops, int func) /* With -m option -- treat arguments as a glob patterns */ if (OPT_ISSET(ops,'m')) { + cmdnamtab->filltable(cmdnamtab); + if (all) { + pushheap(); + matchednodes = newlinklist(); + } for (; *argv; argv++) { /* parse the pattern */ tokenize(*argv); @@ -3204,97 +3267,105 @@ bin_whence(char *nam, char **argv, Options ops, int func) * We're not using it, so search for ... */ /* aliases ... */ + informed += scanmatchtable(aliastab, pprog, 1, 0, DISABLED, aliastab->printnode, printflags); /* and reserved words ... */ + informed += scanmatchtable(reswdtab, pprog, 1, 0, DISABLED, reswdtab->printnode, printflags); /* and shell functions... */ + informed += scanmatchtable(shfunctab, pprog, 1, 0, DISABLED, shfunctab->printnode, printflags); /* and builtins. */ + informed += scanmatchtable(builtintab, pprog, 1, 0, DISABLED, builtintab->printnode, printflags); } /* Done search for `internal' commands, if the -p option * * was not used. Now search the path. */ - cmdnamtab->filltable(cmdnamtab); + informed += scanmatchtable(cmdnamtab, pprog, 1, 0, 0, - cmdnamtab->printnode, printflags); + (all ? fetchcmdnamnode : cmdnamtab->printnode), + printflags); unqueue_signals(); } - return returnval; + if (all) { + allmatched = argv = zlinklist2array(matchednodes); + matchednodes = NULL; + popheap(); + } else + return returnval || !informed; } /* Take arguments literally -- do not glob */ queue_signals(); for (; *argv; argv++) { - informed = 0; - - if (!OPT_ISSET(ops,'p')) { + if (!OPT_ISSET(ops,'p') && !allmatched) { char *suf; /* Look for alias */ if ((hn = aliastab->getnode(aliastab, *argv))) { aliastab->printnode(hn, aliasflags); + informed = 1; if (!all) continue; - informed = 1; } /* Look for suffix alias */ if ((suf = strrchr(*argv, '.')) && suf[1] && suf > *argv && suf[-1] != Meta && (hn = sufaliastab->getnode(sufaliastab, suf+1))) { sufaliastab->printnode(hn, printflags); + informed = 1; if (!all) continue; - informed = 1; } /* Look for reserved word */ if ((hn = reswdtab->getnode(reswdtab, *argv))) { reswdtab->printnode(hn, printflags); + informed = 1; if (!all) continue; - informed = 1; } /* Look for shell function */ if ((hn = shfunctab->getnode(shfunctab, *argv))) { shfunctab->printnode(hn, printflags); + informed = 1; if (!all) continue; - informed = 1; } /* Look for builtin command */ if ((hn = builtintab->getnode(builtintab, *argv))) { builtintab->printnode(hn, printflags); + informed = 1; if (!all) continue; - informed = 1; } /* Look for commands that have been added to the * * cmdnamtab with the builtin `hash foo=bar'. */ if ((hn = cmdnamtab->getnode(cmdnamtab, *argv)) && (hn->flags & HASHED)) { cmdnamtab->printnode(hn, printflags); + informed = 1; if (!all) continue; - informed = 1; } } /* Option -a is to search the entire path, * * rather than just looking for one match. */ - if (all) { + if (all && **argv != '/') { char **pp, *buf; pushheap(); for (pp = path; *pp; pp++) { if (**pp) { buf = zhtricat(*pp, "/", *argv); - } else buf = ztrdup(*argv); + } else buf = dupstring(*argv); if (iscom(buf)) { if (wd) { @@ -3303,8 +3374,8 @@ bin_whence(char *nam, char **argv, Options ops, int func) if (v && !csh) zputs(*argv, stdout), fputs(" is ", stdout); zputs(buf, stdout); - if (OPT_ISSET(ops,'s')) - print_if_link(buf); + if (OPT_ISSET(ops,'s') || OPT_ISSET(ops, 'S')) + print_if_link(buf, OPT_ISSET(ops, 'S')); fputc('\n', stdout); } informed = 1; @@ -3324,10 +3395,11 @@ bin_whence(char *nam, char **argv, Options ops, int func) if (v && !csh) zputs(*argv, stdout), fputs(" is ", stdout); zputs(cnam, stdout); - if (OPT_ISSET(ops,'s')) - print_if_link(cnam); + if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S')) + print_if_link(cnam, OPT_ISSET(ops,'S')); fputc('\n', stdout); } + informed = 1; } else { /* Not found at all. */ if (v || csh || wd) @@ -3335,8 +3407,11 @@ bin_whence(char *nam, char **argv, Options ops, int func) returnval = 1; } } + if (allmatched) + freearray(allmatched); + unqueue_signals(); - return returnval; + return returnval || !informed; } /**** command & named directory hash table builtins ****/ @@ -3689,9 +3764,9 @@ int bin_print(char *name, char **args, Options ops, int func) { int flen, width, prec, type, argc, n, narg, curlen = 0; - int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0; + int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0, nc = 0; int flags[5], *len; - char *start, *endptr, *c, *d, *flag, *buf, spec[13], *fmt = NULL; + char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[13], *fmt = NULL; char **first, **argp, *curarg, *flagch = "0+- #", save = '\0', nullstr = '\0'; size_t rcount, count = 0; #ifdef HAVE_OPEN_MEMSTREAM @@ -3749,7 +3824,7 @@ bin_print(char *name, char **args, Options ops, int func) /* compute lengths, and interpret according to -P, -D, -e, etc. */ argc = arrlen(args); len = (int *) hcalloc(argc * sizeof(int)); - for(n = 0; n < argc; n++) { + for (n = 0; n < argc; n++) { /* first \ sequences */ if (fmt || (!OPT_ISSET(ops,'e') && @@ -3802,8 +3877,38 @@ bin_print(char *name, char **args, Options ops, int func) } } + /* -o and -O -- sort the arguments */ + if (OPT_ISSET(ops,'o') || OPT_ISSET(ops,'O')) { + int flags; + + if (fmt && !*args) + return 0; + flags = OPT_ISSET(ops,'i') ? SORTIT_IGNORING_CASE : 0; + if (OPT_ISSET(ops,'O')) + flags |= SORTIT_BACKWARDS; + strmetasort(args, flags, len); + } + + /* -C -- number of columns */ + if (!fmt && OPT_ISSET(ops,'C')) { + char *eptr, *argptr = OPT_ARG(ops,'C'); + nc = (int)zstrtol(argptr, &eptr, 10); + if (*eptr) { + zwarnnam(name, "number expected after -%c: %s", 'C', argptr); + return 1; + } + if (nc <= 0) { + zwarnnam(name, "invalid number of columns: %s", argptr); + return 1; + } + } + /* -u and -p -- output to other than standard output */ - if (OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) { + if ((OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) && + /* rule out conflicting options -- historical precedence */ + ((!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) || + !(OPT_ISSET(ops, 'z') || + OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')))) { int fdarg, fd; if (OPT_ISSET(ops, 'p')) { @@ -3816,7 +3921,7 @@ bin_print(char *name, char **args, Options ops, int func) char *argptr = OPT_ARG(ops,'u'), *eptr; /* Handle undocumented feature that -up worked */ if (!strcmp(argptr, "p")) { - fdarg= coprocout; + fdarg = coprocout; if (fdarg < 0) { zwarnnam(name, "-p: no coprocess"); return 1; @@ -3842,24 +3947,9 @@ bin_print(char *name, char **args, Options ops, int func) } } - /* -o and -O -- sort the arguments */ - if (OPT_ISSET(ops,'o') || OPT_ISSET(ops,'O')) { - int flags; - - if (fmt && !*args) { - if (fout != stdout) - fclose(fout); - return 0; - } - flags = OPT_ISSET(ops,'i') ? SORTIT_IGNORING_CASE : 0; - if (OPT_ISSET(ops,'O')) - flags |= SORTIT_BACKWARDS; - strmetasort(args, flags, len); - } - /* -c -- output in columns */ if (!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) { - int l, nc, nr, sc, n, t, i; + int l, nr, sc, n, t, i; #ifdef MULTIBYTE_SUPPORT int *widths; @@ -3930,19 +4020,9 @@ bin_print(char *name, char **args, Options ops, int func) #endif if (OPT_ISSET(ops,'C')) { - char *eptr, *argptr = OPT_ARG(ops,'C'); - nc = (int)zstrtol(argptr, &eptr, 10); - if (*eptr) { - zwarnnam(name, "number expcted after -%c: %s", 'C', argptr); - return 1; - } - if (nc <= 0) { - zwarnnam(name, "invalid number of columns: %s", argptr); - return 1; - } /* * n: number of elements - * nc: number of columns + * nc: number of columns (above) * nr: number of rows */ n = arrlen(args); @@ -4168,6 +4248,10 @@ bin_print(char *name, char **args, Options ops, int func) narg); if (fout != stdout) fclose(fout); +#ifdef HAVE_OPEN_MEMSTREAM + if (buf) + free(buf); +#endif return 1; } else { if (narg > maxarg) maxarg = narg; @@ -4201,6 +4285,10 @@ bin_print(char *name, char **args, Options ops, int func) narg); if (fout != stdout) fclose(fout); +#ifdef HAVE_OPEN_MEMSTREAM + if (buf) + free(buf); +#endif return 1; } else { if (narg > maxarg) maxarg = narg; @@ -4211,7 +4299,7 @@ bin_print(char *name, char **args, Options ops, int func) if (*argp) { width = (int)mathevali(*argp++); if (errflag) { - errflag = 0; + errflag &= ~ERRFLAG_ERROR; ret = 1; } } @@ -4230,6 +4318,10 @@ bin_print(char *name, char **args, Options ops, int func) narg); if (fout != stdout) fclose(fout); +#ifdef HAVE_OPEN_MEMSTREAM + if (buf) + free(buf); +#endif return 1; } else { if (narg > maxarg) maxarg = narg; @@ -4241,7 +4333,7 @@ bin_print(char *name, char **args, Options ops, int func) if (*argp) { prec = (int)mathevali(*argp++); if (errflag) { - errflag = 0; + errflag &= ~ERRFLAG_ERROR; ret = 1; } } @@ -4385,6 +4477,10 @@ bin_print(char *name, char **args, Options ops, int func) (fflush(fout) != 0 && errno != EBADF)) { zwarnnam(name, "write error: %e", errno); } +#ifdef HAVE_OPEN_MEMSTREAM + if (buf) + free(buf); +#endif return 1; } @@ -4421,7 +4517,7 @@ bin_print(char *name, char **args, Options ops, int func) zlongval = (curarg) ? mathevali(curarg) : 0; if (errflag) { zlongval = 0; - errflag = 0; + errflag &= ~ERRFLAG_ERROR; ret = 1; } print_val(zlongval) @@ -4450,7 +4546,7 @@ bin_print(char *name, char **args, Options ops, int func) } else doubleval = 0; if (errflag) { doubleval = 0; - errflag = 0; + errflag &= ~ERRFLAG_ERROR; ret = 1; } print_val(doubleval) @@ -4463,7 +4559,7 @@ bin_print(char *name, char **args, Options ops, int func) zulongval = (curarg) ? mathevali(curarg) : 0; if (errflag) { zulongval = 0; - errflag = 0; + errflag &= ~ERRFLAG_ERROR; ret = 1; } print_val(zulongval) @@ -4481,7 +4577,8 @@ bin_print(char *name, char **args, Options ops, int func) if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) { #ifdef HAVE_OPEN_MEMSTREAM putc(0, fout); - fflush(fout); + fclose(fout); + fout = NULL; #else rewind(fout); buf = (char *)zalloc(count + 1); @@ -4502,11 +4599,16 @@ bin_print(char *name, char **args, Options ops, int func) unqueue_signals(); } - /* Testing EBADF special-cases >&- redirections */ - if ((fout != stdout) ? (fclose(fout) != 0) : - (fflush(fout) != 0 && errno != EBADF)) { - zwarnnam(name, "write error: %e", errno); - ret = 1; +#ifdef HAVE_OPEN_MEMSTREAM + if (fout) +#endif + { + /* Testing EBADF special-cases >&- redirections */ + if ((fout != stdout) ? (fclose(fout) != 0) : + (fflush(fout) != 0 && errno != EBADF)) { + zwarnnam(name, "write error: %e", errno); + ret = 1; + } } return ret; } @@ -4840,7 +4942,7 @@ zexit(int val, int from_where) in_exit = -1; /* * We want to do all remaining processing regardless of preceding - * errors. + * errors, even user interrupts. */ errflag = 0; @@ -5043,7 +5145,7 @@ eval(char **argv) if (fpushed) funcstack = funcstack->prev; - errflag = 0; + errflag &= ~ERRFLAG_ERROR; scriptname = oscriptname; ineval = oineval; @@ -5140,7 +5242,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func)) if (cmd) { if (opt_L) { zwarnnam("emulate", "option -L incompatible with -c"); - goto restore; + goto restore2; } *--argv = cmd; /* on stack, never free()d, see execbuiltin() */ } else @@ -5178,6 +5280,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func)) } ret = eval(argv); sticky = save_sticky; +restore2: emulation = saveemulation; memcpy(opts, saveopts, sizeof(opts)); restorepatterndisables(savepatterns); @@ -6061,7 +6164,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) } } - lexsave(); + zcontext_save(); testargs = argv; tok = NULLTOK; condlex = testlex; @@ -6070,17 +6173,17 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) condlex = zshlex; if (errflag) { - errflag = 0; - lexrestore(); + errflag &= ~ERRFLAG_ERROR; + zcontext_restore(); return 1; } if (!prog || tok == LEXERR) { zwarnnam(name, tokstr ? "parse error" : "argument expected"); - lexrestore(); + zcontext_restore(); return 1; } - lexrestore(); + zcontext_restore(); if (*curtestarg) { zwarnnam(name, "too many arguments"); @@ -6247,7 +6350,7 @@ bin_let(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int func)) while (*argv) val = matheval(*argv++); /* Errors in math evaluation in let are non-fatal. */ - errflag = 0; + errflag &= ~ERRFLAG_ERROR; /* should test for fabs(val.u.d) < epsilon? */ return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0; } |