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

PATCH: 3.1.5-pws-8: set -x output in [[ ... ]]



This patch finally (after however many years of neglect) allows zsh to
produce trace output inside conditions.  It's not quite the same output as
in ksh, but I don't think that's a major concern here.

One thing that's a little odd is with conditions defined in modules.  Here,
the arguments only undergo singsub() right at the last minute, so the
strings printed out from the trace are untokenized versions of the
unsubstituted strings.  Is there some reason why the words from such
conditions shouldn't all undergo singsub() (thought not untokenize() since
they may be patterns) before calling the handler in evalcond()?  If the
condition arguments are always retrieved via cond_str(), cond_val() and
cond_match(), this should have the same effect, since all three call
singsub(), but I don't know if that's a warranted assumption.  If the idea
is that sometimes a module condition may not want substitution performed,
or may allow multi-word substitution, then we're stuck with always printing
the unsubstituted form.

The tracingcond variable is needed (instead of using isset(XTRACE)
directly) because if the evalcond() was called from test, the arguments
already appeared as command line arguments to the builtin and shouldn't
appear again.

At first sight, it looks tempting to have the trace output more closely
connected with the printing routines in text.c.  However, they operate on
different structures with different degrees of substitution at different
times in the execution cycle, so this is distinctly non-trivial.

--- Src/cond.c.xtr	Sat Jan  9 17:08:22 1999
+++ Src/cond.c	Wed Feb 17 09:57:15 1999
@@ -30,6 +30,13 @@
 #include "zsh.mdh"
 #include "cond.pro"
 
+int tracingcond;
+
+static char *condstr[COND_MOD] = {
+    "!", "&&", "||", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
+    "-ne", "-lt", "-gt", "-le", "-ge"
+};
+
 /**/
 int
 evalcond(Cond c)
@@ -38,11 +45,23 @@
 
     switch (c->type) {
     case COND_NOT:
+	if (tracingcond)
+	    fprintf(stderr, " %s", condstr[c->type]);
 	return !evalcond(c->left);
     case COND_AND:
-	return evalcond(c->left) && evalcond(c->right);
+	if (evalcond(c->left)) {
+	    if (tracingcond)
+		fprintf(stderr, " %s", condstr[c->type]);
+	    return evalcond(c->right);
+	} else
+	    return 0;
     case COND_OR:
-	return evalcond(c->left) || evalcond(c->right);
+	if (!evalcond(c->left)) {
+	    if (tracingcond)
+		fprintf(stderr, " %s", condstr[c->type]);
+	    return evalcond(c->right);
+	} else
+	    return 1;
     case COND_MOD:
     case COND_MODI:
 	{
@@ -58,6 +77,9 @@
 			return 0;
 		    }
 		}
+		if (tracingcond)
+		    tracemodcond((char *)c->left, (char **)c->right,
+				 c->type == COND_MODI);
 		return cd->handler((char **) c->right, cd->condid);
 	    }
 	    else {
@@ -71,6 +93,8 @@
 			zerr("unrecognized condition: `%s'", (char *) c->left, 0);
 			return 0;
 		    }
+		    if (tracingcond)
+			tracemodcond((char *)c->left, a, c->type == COND_MODI);
 		    a[0] = (char *) c->left;
 		    return cd->handler(a, cd->condid);
 		} else
@@ -86,6 +110,20 @@
 	if (c->type != COND_STREQ && c->type != COND_STRNEQ)
 	    untokenize(c->right);
     }
+
+    if (tracingcond) {
+	if (c->type < COND_MOD) {
+	    char *rt = (char *)c->right;
+	    if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
+		rt = dupstring(rt);
+		untokenize(rt);
+	    }
+	    fprintf(stderr, " %s %s %s", (char *)c->left, condstr[c->type],
+		    rt);
+	} else
+	    fprintf(stderr, " -%c %s", c->type, (char *)c->left);
+    }
+
     switch (c->type) {
     case COND_STREQ:
 	return matchpat(c->left, c->right);
@@ -293,4 +331,22 @@
     singsub(&s);
 
     return matchpat(str, s);
+}
+
+/**/
+static void
+tracemodcond(char *name, char **args, int inf)
+{
+    char **aptr;
+    MUSTUSEHEAP("tracemodcond");
+    args = duparray(args, (VFunc) dupstring);
+    for (aptr = args; *aptr; aptr++)
+	untokenize(*aptr);
+    if (inf) {
+	fprintf(stderr, " %s %s %s", args[0], name, args[1]);
+    } else {
+	fprintf(stderr, " %s", name);
+	while (*args)
+	    fprintf(stderr, " %s", *args++);
+    }
 }
--- Src/exec.c.xtr	Mon Feb 15 18:10:51 1999
+++ Src/exec.c	Tue Feb 16 18:15:15 1999
@@ -2519,13 +2519,26 @@
     }
 }
 
+extern int tracingcond;
+
 /* evaluate a [[ ... ]] */
 
 /**/
 static int
 execcond(Cmd cmd)
 {
-    return !evalcond(cmd->u.cond);
+    int stat;
+    if (isset(XTRACE)) {
+	fprintf(stderr, "+ [[");
+	tracingcond++;
+    }
+    stat = !evalcond(cmd->u.cond);
+    if (isset(XTRACE)) {
+	fprintf(stderr, " ]]\n");
+	fflush(stderr);
+	tracingcond--;
+    }
+    return stat;
 }
 
 /* evaluate a ((...)) arithmetic command */
--- Src/utils.c.xtr	Sat Feb 13 15:26:32 1999
+++ Src/utils.c	Wed Feb 17 09:37:44 1999
@@ -2261,7 +2261,7 @@
 }
 
 /**/
-static char **
+char **
 duparray(char **arr, VFunc func)
 {
     char **ret, **rr;

-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxx>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy



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