diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/builtin.c | 8 | ||||
-rw-r--r-- | Src/text.c | 32 | ||||
-rw-r--r-- | Test/C02cond.ztst | 12 |
4 files changed, 50 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 75f4eeb2f..aab214f2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-12-09 Peter Stephenson <p.stephenson@samsung.com> + + * 37364: Src/builtin.c, Src/text.c, Test/C02cond.ztst: "test" + and "[" need to prefer binary operators to parentheses in + three-argument expressions. + 2015-12-08 Peter Stephenson <p.stephenson@samsung.com> * 37348: Src/utils.c, Test/D04parameter.ztst, diff --git a/Src/builtin.c b/Src/builtin.c index cac4f42f9..b06bc6de7 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6463,7 +6463,13 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) nargs = arrlen(argv); if (nargs == 3 || nargs == 4) { - if (*argv[0] == '(' && *argv[nargs-1] == ')') { + /* + * As parentheses are an extension, we need to be careful --- + * if this is a three-argument expression that could + * be a binary operator, prefer that. + */ + if (!strcmp(argv[0], "(") && !strcmp(argv[nargs-1],")") && + (nargs != 3 || !is_cond_binary_op(argv[1]))) { argv[nargs-1] = NULL; argv++; } diff --git a/Src/text.c b/Src/text.c index 9421d70ce..04acd2aac 100644 --- a/Src/text.c +++ b/Src/text.c @@ -40,9 +40,32 @@ /**/ int text_expand_tabs; +/* + * Binary operators in conditions. + * There order is tied to the order of the definitions COND_STREQ + * et seq. in zsh.h. + */ +static const char *cond_binary_ops[] = { + "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq", + "-ne", "-lt", "-gt", "-le", "-ge", "=~" +}; + static char *tptr, *tbuf, *tlim, *tpending; static int tsiz, tindent, tnewlins, tjob; +/**/ +int +is_cond_binary_op(const char *str) +{ + const char **op; + for (op = cond_binary_ops; *op; op++) + { + if (!strcmp(str, *op)) + return 1; + } + return 0; +} + static void dec_tindent(void) { @@ -120,7 +143,7 @@ taddchr(int c) /**/ static void -taddstr(char *s) +taddstr(const char *s) { int sl = strlen(s); char c; @@ -822,11 +845,6 @@ gettext2(Estate state) break; case WC_COND: { - static char *c1[] = { - "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq", - "-ne", "-lt", "-gt", "-le", "-ge", "=~" - }; - int ctype; if (!s) { @@ -912,7 +930,7 @@ gettext2(Estate state) /* Binary test: `a = b' etc. */ taddstr(ecgetstr(state, EC_NODUP, NULL)); taddstr(" "); - taddstr(c1[ctype - COND_STREQ]); + taddstr(cond_binary_ops[ctype - COND_STREQ]); taddstr(" "); taddstr(ecgetstr(state, EC_NODUP, NULL)); if (ctype == COND_STREQ || diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 40bbf424a..9e1369689 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -389,6 +389,18 @@ F:Failures in these cases do not indicate a problem in the shell. >Not zero 5 >Not zero 6 + [ '(' = ')' ] || print OK 1 + [ '((' = '))' ] || print OK 2 + [ '(' = '(' ] && print OK 3 + [ '(' non-empty-string ')' ] && echo OK 4 + [ '(' '' ')' ] || echo OK 5 +0:yet more old-fashioned test fix ups: prefer comparison to parentheses +>OK 1 +>OK 2 +>OK 3 +>OK 4 +>OK 5 + %clean # This works around a bug in rm -f in some versions of Cygwin chmod 644 unmodish |