summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-12-09 16:40:08 +0000
committerPeter Stephenson <pws@zsh.org>2015-12-09 16:40:08 +0000
commit67877f60552019226e93f56b108f7b61a60ea11b (patch)
tree49d506564c9eddecedbe4a8e056098676ad99a96
parent7f5b2f570961cd9b20f322d7f45318878a1a4b29 (diff)
downloadzsh-67877f60552019226e93f56b108f7b61a60ea11b.tar.gz
zsh-67877f60552019226e93f56b108f7b61a60ea11b.zip
37364: "test" and "[" handling of parentheses.
If three arguments, need to prefer binary operators if possible. Need to look for full string for parentheses.
-rw-r--r--ChangeLog6
-rw-r--r--Src/builtin.c8
-rw-r--r--Src/text.c32
-rw-r--r--Test/C02cond.ztst12
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