about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Config/version.mk4
-rw-r--r--Src/cond.c11
-rw-r--r--Src/parse.c9
-rw-r--r--Src/text.c3
-rw-r--r--Src/zsh.h39
-rw-r--r--Test/C02cond.ztst7
-rw-r--r--Test/D01prompt.ztst4
-rw-r--r--Test/E02xtrace.ztst6
9 files changed, 60 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 145e9fbc2..603466e2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2016-09-13  Peter Stephenson  <p.stephenson@samsung.com>
 
+	* 39292: Config/version.mk, Src/cond.c, Src/parse.c, Src/text.c,
+	Src/zsh.h, Test/C02cond.ztst, Test/D01prompt.ztst,
+	Test/E02xtrace.ztst: Distinguish "=" and "==" tests in output to
+	avoid confusion.  Update version number to 5.2-dev-2 (unposted:
+	update date, too).
+
 	* 39305: Src/exec.c: error handling on substitution for here
 	document was illogical.
 
diff --git a/Config/version.mk b/Config/version.mk
index 5577f4a0b..a62de3f59 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=5.2-dev-1
-VERSION_DATE='January 20, 2015'
+VERSION=5.2-dev-2
+VERSION_DATE='August 13, 2016'
diff --git a/Src/cond.c b/Src/cond.c
index 0381fe94b..f25ebd4a3 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -34,7 +34,7 @@
 int tracingcond;    /* updated by execcond() in exec.c */
 
 static char *condstr[COND_MOD] = {
-    "!", "&&", "||", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
+    "!", "&&", "||", "=", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
     "-ne", "-lt", "-gt", "-le", "-ge", "=~"
 };
 
@@ -196,7 +196,8 @@ evalcond(Estate state, char *fromtest)
 	cond_subst(&left, !fromtest);
 	untokenize(left);
     }
-    if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRNEQ) {
+    if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRDEQ &&
+	ctype != COND_STRNEQ) {
 	right = ecgetstr(state, EC_DUPTOK, &htok);
 	if (htok) {
 	    cond_subst(&right, !fromtest);
@@ -208,7 +209,8 @@ evalcond(Estate state, char *fromtest)
 	    fputc(' ',xtrerr);
 	    quotedzputs(left, xtrerr);
 	    fprintf(xtrerr, " %s ", condstr[ctype]);
-	    if (ctype == COND_STREQ || ctype == COND_STRNEQ) {
+	    if (ctype == COND_STREQ || ctype == COND_STRDEQ ||
+		ctype == COND_STRNEQ) {
 		char *rt = dupstring(ecrawstr(state->prog, state->pc, NULL));
 		cond_subst(&rt, !fromtest);
 		quote_tokenized_output(rt, xtrerr);
@@ -287,6 +289,7 @@ evalcond(Estate state, char *fromtest)
 
     switch (ctype) {
     case COND_STREQ:
+    case COND_STRDEQ:
     case COND_STRNEQ:
 	{
 	    int test, npat = state->pc[1];
@@ -313,7 +316,7 @@ evalcond(Estate state, char *fromtest)
 	    state->pc += 2;
 	    test = (pprog && pattry(pprog, left));
 
-	    return !(ctype == COND_STREQ ? test : !test);
+	    return !(ctype == COND_STRNEQ ? !test : test);
 	}
     case COND_STRLT:
 	return !(strcmp(left, right) < 0);
diff --git a/Src/parse.c b/Src/parse.c
index 94ac04922..6e7d40e29 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2498,12 +2498,17 @@ par_cond_triple(char *a, char *b, char *c)
 {
     int t0;
 
-    if ((b[0] == Equals || b[0] == '=') &&
-	(!b[1] || ((b[1] == Equals || b[1] == '=') && !b[2]))) {
+    if ((b[0] == Equals || b[0] == '=') && !b[1]) {
 	ecadd(WCB_COND(COND_STREQ, 0));
 	ecstr(a);
 	ecstr(c);
 	ecadd(ecnpats++);
+    } else if ((b[0] == Equals || b[0] == '=') &&
+	       (b[1] == Equals || b[1] == '=') && !b[2]) {
+	ecadd(WCB_COND(COND_STRDEQ, 0));
+	ecstr(a);
+	ecstr(c);
+	ecadd(ecnpats++);
     } else if (b[0] == '!' && (b[1] == Equals || b[1] == '=') && !b[2]) {
 	ecadd(WCB_COND(COND_STRNEQ, 0));
 	ecstr(a);
diff --git a/Src/text.c b/Src/text.c
index d387d361a..3658b1bc6 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -46,7 +46,7 @@ int text_expand_tabs;
  * et seq. in zsh.h.
  */
 static const char *cond_binary_ops[] = {
-    "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
+    "=", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
     "-ne", "-lt", "-gt", "-le", "-ge", "=~", NULL
 };
 
@@ -934,6 +934,7 @@ gettext2(Estate state)
 			    taddstr(" ");
 			    taddstr(ecgetstr(state, EC_NODUP, NULL));
 			    if (ctype == COND_STREQ ||
+				ctype == COND_STRDEQ ||
 				ctype == COND_STRNEQ)
 				state->pc++;
 			} else {
diff --git a/Src/zsh.h b/Src/zsh.h
index 87e6a9868..996bc3369 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -622,27 +622,34 @@ struct timedfn {
 /* (1<<4) is used for Z_END, see the wordcode definitions */
 /* (1<<5) is used for Z_SIMPLE, see the wordcode definitions */
 
-/* Condition types. */
+/*
+ * Condition types.
+ *
+ * Careful when changing these: both cond_binary_ops in text.c and
+ * condstr in cond.c depend on these.  (The zsh motto is "two instances
+ * are better than one".  Or something.)
+ */
 
 #define COND_NOT    0
 #define COND_AND    1
 #define COND_OR     2
 #define COND_STREQ  3
-#define COND_STRNEQ 4
-#define COND_STRLT  5
-#define COND_STRGTR 6
-#define COND_NT     7
-#define COND_OT     8
-#define COND_EF     9
-#define COND_EQ    10
-#define COND_NE    11
-#define COND_LT    12
-#define COND_GT    13
-#define COND_LE    14
-#define COND_GE    15
-#define COND_REGEX 16
-#define COND_MOD   17
-#define COND_MODI  18
+#define COND_STRDEQ 4
+#define COND_STRNEQ 5
+#define COND_STRLT  6
+#define COND_STRGTR 7
+#define COND_NT     8
+#define COND_OT     9
+#define COND_EF    10
+#define COND_EQ    11
+#define COND_NE    12
+#define COND_LT    13
+#define COND_GT    14
+#define COND_LE    15
+#define COND_GE    16
+#define COND_REGEX 17
+#define COND_MOD   18
+#define COND_MODI  19
 
 typedef int (*CondHandler) _((char **, int));
 
diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst
index e315f6c10..78e644a72 100644
--- a/Test/C02cond.ztst
+++ b/Test/C02cond.ztst
@@ -414,6 +414,13 @@ F:Failures in these cases do not indicate a problem in the shell.
 >OK 4
 >OK 5
 
+  fn() { [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]] }
+  which -x2 fn
+0: = and == appear as input
+>fn () {
+>  [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]]
+>}
+
 %clean
   # This works around a bug in rm -f in some versions of Cygwin
   chmod 644 unmodish
diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst
index 2638e2438..607ffb698 100644
--- a/Test/D01prompt.ztst
+++ b/Test/D01prompt.ztst
@@ -196,8 +196,8 @@
 ?+zsh_directory_name:1> emulate -L zsh
 ?+zsh_directory_name:2> setopt extendedglob
 ?+zsh_directory_name:3> local -a match mbegin mend
-?+zsh_directory_name:4> [[ d == n ]]
-?+zsh_directory_name:12> [[ <parent>/very_long_directory_name == (#b)(*)/very_long_directory_name ]]
+?+zsh_directory_name:4> [[ d = n ]]
+?+zsh_directory_name:12> [[ <parent>/very_long_directory_name = (#b)(*)/very_long_directory_name ]]
 ?+zsh_directory_name:14> return 0
 ?+fn:7> local d='~[<parent>:l]'
 ?+fn:8> print '~[<parent>:l]'
diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst
index 6e425e703..da6191cd0 100644
--- a/Test/E02xtrace.ztst
+++ b/Test/E02xtrace.ztst
@@ -120,13 +120,15 @@
 ?+./fnfile:3> print This is fn.
 
  set -x
+ [[ 'f o' == 'f x'* || 'b r' != 'z o' && 'squashy sound' < 'squishy sound' ]]
  [[ 'f o' = 'f x'* || 'b r' != 'z o' && 'squashy sound' < 'squishy sound' ]]
  [[ -e nonexistentfile || ( -z '' && -t 3 ) ]]
  set +x
 0:Trace for conditions
 ?+(eval):2> [[ 'f o' == f\ x* || 'b r' != z\ o && 'squashy sound' < 'squishy sound' ]]
-?+(eval):3> [[ -e nonexistentfile || -z '' && -t 3 ]]
-?+(eval):4> set +x
+?+(eval):3> [[ 'f o' = f\ x* || 'b r' != z\ o && 'squashy sound' < 'squishy sound' ]]
+?+(eval):4> [[ -e nonexistentfile || -z '' && -t 3 ]]
+?+(eval):5> set +x
 
   # Part 1: Recurses into nested anonymous functions
   fn() {