From 77a39b57bf467812b9219ae6a84f2f71e6a50065 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 24 Nov 2017 22:09:41 +0000 Subject: 42031 + 42048: Make [[ -o invalidoption ]] a normal(ish) false value, rather than a syntax error. --- ChangeLog | 6 ++++++ Doc/Zsh/cond.yo | 4 ++++ Doc/Zsh/options.yo | 3 +++ README | 12 ++++++++++++ Src/cond.c | 20 +++++++++++++------- Test/C02cond.ztst | 20 ++++++++++++++++++++ 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84578a73e..3efa686c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-11-24 Daniel Shahaf + + * 42031 + 42048: Doc/Zsh/cond.yo, Doc/Zsh/options.yo, README, + Src/cond.c, Test/C02cond.ztst: Make [[ -o invalidoption ]] + a normal(ish) false value, rather than a syntax error. + 2017-11-20 Peter Stephenson * Dima Kogan: 42040: Src/glob.c: buffer for glob qualifiers diff --git a/Doc/Zsh/cond.yo b/Doc/Zsh/cond.yo index e08fc0d36..4ca132a26 100644 --- a/Doc/Zsh/cond.yo +++ b/Doc/Zsh/cond.yo @@ -45,6 +45,10 @@ item(tt(-o) var(option))( true if option named var(option) is on. var(option) may be a single character, in which case it is a single letter option name. (See noderef(Specifying Options).) + +When no option named var(option) exists, and the tt(POSIX_BUILTINS) option +hasn't been set, return 3 with a warning. If that option is set, return 1 +with no warning. ) item(tt(-p) var(file))( true if var(file) exists and is a FIFO special file (named pipe). diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 28155d796..d043cf398 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -2169,6 +2169,9 @@ command found in the path. Furthermore, the tt(getopts) builtin behaves in a POSIX-compatible fashion in that the associated variable tt(OPTIND) is not made local to functions. + +Moreover, the warning and special exit code from +tt([[ -o )var(non_existent_option)tt( ]]) are suppressed. ) pindex(POSIX_IDENTIFIERS) pindex(NO_POSIX_IDENTIFIERS) diff --git a/README b/README index 6fad1d516..00bcc1696 100644 --- a/README +++ b/README @@ -54,6 +54,18 @@ foo=([aeiou]\=vowel) This is only required for array values contained within parentheses; command line expansion for normal arguments has not changed. +3) The syntax + +[[ -o foo ]] + +where foo is not the name of a shell option (with optional underscores +and optional "no" prefix) used to be treated as a syntax error, i.e., +the enclosing command line or file were aborted. It now emits a warning +and returns a non-zero exit code. For further details, see the +documentation of the -o switch in the chapter "Conditional Expressions" +in the zshmisc(1) manual. + + Incompatibilities between 5.3.1 and 5.4.2 ----------------------------------------- diff --git a/Src/cond.c b/Src/cond.c index b9a47cea5..9f13e07d7 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -61,7 +61,8 @@ static void cond_subst(char **strp, int glob_ok) * of functionality. * * Return status is the final shell status, i.e. 0 for true, - * 1 for false and 2 for error. + * 1 for false, 2 for syntax error, 3 for "option in tested in + * -o does not exist". */ /**/ @@ -86,10 +87,10 @@ evalcond(Estate state, char *fromtest) if (tracingcond) fprintf(xtrerr, " %s", condstr[ctype]); ret = evalcond(state, fromtest); - if (ret == 2) - return ret; - else + if (ret == 0 || ret == 1) return !ret; + else + return ret; case COND_AND: if (!(ret = evalcond(state, fromtest))) { if (tracingcond) @@ -100,7 +101,8 @@ evalcond(Estate state, char *fromtest) return ret; } case COND_OR: - if ((ret = evalcond(state, fromtest)) == 1) { + ret = evalcond(state, fromtest); + if (ret == 1 || ret == 3) { if (tracingcond) fprintf(xtrerr, " %s", condstr[ctype]); goto rec; @@ -506,8 +508,12 @@ optison(char *name, char *s) else i = optlookup(s); if (!i) { - zwarnnam(name, "no such option: %s", s); - return 2; + if (isset(POSIXBUILTINS)) + return 1; + else { + zwarnnam(name, "no such option: %s", s); + return 3; + } } else if(i < 0) return !unset(-i); else diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 38525016c..4ffb07dd4 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -440,6 +440,26 @@ F:Failures in these cases do not indicate a problem in the shell. > [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]] >} + (setopt posixbuiltins; [[ -o invalidoption ]]; echo set: $?; echo "line 1: no warning" >&2) + (unsetopt posixbuiltins; [[ -o invalidoption ]]; echo unset: $?) + [[ -o invalidoption || -n nonempty ]]; echo "in disjunction, true: $?" + [[ -o invalidoption || -z nonempty ]]; echo "in disjunction, false: $?" + [[ ! -o invalidoption ]]; echo "negated: $?" + [[ -o invalidoption && -n nonempty ]] || echo "in conjunction: $?" +0:-o invalidoption +>set: 1 +?line 1: no warning +>unset: 3 +?(eval):2: no such option: invalidoption +>in disjunction, true: 0 +?(eval):3: no such option: invalidoption +>in disjunction, false: 1 +?(eval):4: no such option: invalidoption +>negated: 3 +?(eval):5: no such option: invalidoption +>in conjunction: 3 +?(eval):6: no such option: invalidoption + %clean # This works around a bug in rm -f in some versions of Cygwin chmod 644 unmodish -- cgit 1.4.1