Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] Fix value of $? when used in array assignment



Hi again. Daniel discovered the following behaviour:

  % false; arr=( $? ); typeset -p arr
  typeset -a arr=( 0 )

It seems that lastval is discarded before an assignment of this sort is actually
executed.

Not sure if it's the most elegant way, but the attached patch fixes it, and all
of the tests pass. I also added some regression tests.

dana


diff --git a/Src/exec.c b/Src/exec.c
index fc6d02dc3..7d94d2cd7 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2722,7 +2722,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
     char *text;
     int save[10];
     int fil, dfil, is_cursh, do_exec = 0, redir_err = 0, i;
-    int nullexec = 0, magic_assign = 0, forked = 0;
+    int nullexec = 0, magic_assign = 0, forked = 0, old_lastval;
     int is_shfunc = 0, is_builtin = 0, is_exec = 0, use_defpath = 0;
     /* Various flags to the command. */
     int cflags = 0, orig_cflags = 0, checked = 0, oautocont = -1;
@@ -2747,8 +2747,10 @@ execcmd_exec(Estate state, Execcmd_params eparams,
      * If assignment but no command get the status from variable
      * assignment.
      */
-    if (!args && varspc)
+    if (!args && varspc) {
+	old_lastval = lastval;
 	lastval = errflag ? errflag : cmdoutval;
+    }
     /*
      * If there are arguments, we should reset the status for the
      * command before execution---unless we are using the result of a
@@ -3146,8 +3148,11 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 			return;
 		    }
 		    cmdoutval = use_cmdoutval ? lastval : 0;
-		    if (varspc)
+		    if (varspc) {
+			/* Make sure $? is still correct for assignment */
+			lastval = old_lastval;
 			addvars(state, varspc, 0);
+		    }
 		    if (errflag)
 			lastval = 1;
 		    else
diff --git a/Test/A06assign.ztst b/Test/A06assign.ztst
index fd2b4177c..f89edb888 100644
--- a/Test/A06assign.ztst
+++ b/Test/A06assign.ztst
@@ -199,6 +199,41 @@
 >a 1 2 3
 >a 1 2 3
 
+# tests of array assignment using lastval ($?)
+
+  true
+  array=( $? )
+  print $array
+0:Assign $? to array (true)
+>0
+
+  false
+  array=( $? )
+  print $array
+0:Assign $? to array (false)
+>1
+
+  true
+  typeset array=( $? )
+  print $array
+0:Assign $? to array with typeset (true)
+>0
+
+  false
+  typeset array=( $? )
+  print $array
+0:Assign $? to array with typeset (false)
+>1
+
+  array=( )
+  true
+  array+=( $? )
+  false
+  array+=( $? )
+  print $array
+0:Append $? to array (true+false)
+>0 1
+
 # tests of var+=scalar
 
  s+=foo



Messages sorted by: Reverse Date, Date, Thread, Author