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

PATCH: More useful variable tracing



On Wed, 13 Mar 2013 10:22:06 +0000
Peter Stephenson <p.stephenson@xxxxxxxxxxx> wrote:
> On Tue, 12 Mar 2013 20:17:38 -0400
> Phil Pennock <zsh-workers+phil.pennock@xxxxxxxxxxxx> wrote:
>   <useful but necessarily slightly tortuous instructions for finding
>    out how path is set>
>
> Off the wall aside, vaguely related to Bart's point about tracing array
> subscripts: I've had the growing suspicion we ought to be able to do a
> lot better than this with only moderate effort.  Tracing setting of
> variables is a particularly common thing to do.  It would be good to
> come up with something that can be set on the command line that can
> cause tracing of a given set of variables (so whatever we did would need
> to take effect before initialisation files but not otherwise affect the
> start sequence).  It might take a while to find all the places
> internally that need to check, but the code shouldn't actually be that
> hard.

Here's an ultra-simple starting point.  It's very limited:

- I only put code into addvars().  There are all sorts of other ways
  a variable could get set or altered that are likely to make this a
  nightmare to be fully general.
- I hijacked the XTRACE code directly, so no extra special goodness
  (not that much is necessarily wanted).
- It doesn't know that setting path sets PATH, and so on.
- No documentation yet, though all you really need to know is that
  zsh_trace_vars and ZSH_TRACE_VARS are path-style variables that
  take variable names.

However, it's already of some use, particularly since the value of
ZSH_TRACE_VARS can be imported from the environment, so takes effect
early:

% ZSH_TRACE_VARS=path:PATH zsh
+/export/home/pws/.zshenv:47> path=( /export/home/pws/bin /usr/local/bin /usr/kerberos/bin /bin /usr/bin /sbin /usr/sbin . ) 
%

so I present it for comments.


diff --git a/Src/exec.c b/Src/exec.c
index fa14875..ce65a08 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2163,7 +2163,7 @@ static void
 addvars(Estate state, Wordcode pc, int addflags)
 {
     LinkList vl;
-    int xtr, isstr, htok = 0;
+    int xtr, xtr_any = 0, isstr, htok = 0;
     char **arr, **ptr, *name;
     int flags;
 
@@ -2188,12 +2188,27 @@ addvars(Estate state, Wordcode pc, int addflags)
     state->pc = pc;
     while (wc_code(ac = *state->pc++) == WC_ASSIGN) {
 	int myflags = flags;
+	int xtr_here = xtr;
 	name = ecgetstr(state, EC_DUPTOK, &htok);
 	if (htok)
 	    untokenize(name);
 	if (WC_ASSIGN_TYPE2(ac) == WC_ASSIGN_INC)
 	    myflags |= ASSPM_AUGMENT;
-	if (xtr)
+	if (!xtr)
+	{
+	    char **trace_vars;
+	    for (trace_vars = zsh_trace_vars; *trace_vars; trace_vars++)
+	    {
+		if (!strcmp(*trace_vars, name)) {
+		    xtr_here = 1;
+		    if (!xtr_any) {
+			printprompt4();
+			doneps4 = xtr_any = 1;
+		    }
+		}
+	    }
+	}
+	if (xtr_here)
 	    fprintf(xtrerr,
 		WC_ASSIGN_TYPE2(ac) == WC_ASSIGN_INC ? "%s+=" : "%s=", name);
 	if ((isstr = (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR))) {
@@ -2227,7 +2242,7 @@ addvars(Estate state, Wordcode pc, int addflags)
 		untokenize(peekfirst(vl));
 		val = ztrdup(ugetnode(vl));
 	    }
-	    if (xtr) {
+	    if (xtr_here) {
 		quotedzputs(val, xtrerr);
 		fputc(' ', xtrerr);
 	    }
@@ -2266,7 +2281,7 @@ addvars(Estate state, Wordcode pc, int addflags)
 	    ptr = arr = (char **) zalloc(sizeof(char **));
 
 	*ptr = NULL;
-	if (xtr) {
+	if (xtr_here) {
 	    fprintf(xtrerr, "( ");
 	    for (ptr = arr; *ptr; ptr++) {
 		quotedzputs(*ptr, xtrerr);
@@ -2280,6 +2295,11 @@ addvars(Estate state, Wordcode pc, int addflags)
 	    return;
 	}
     }
+    if (xtr_any) {
+	/* XTRACE not set but we output some variable tracing */
+	fputc('\n', xtrerr);
+	fflush(xtrerr);
+    }
     state->pc = opc;
 }
 
diff --git a/Src/init.c b/Src/init.c
index 8467a73..0388740 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -897,6 +897,7 @@ setupvals(void)
     mailpath = mkarray(NULL);
     watch    = mkarray(NULL);
     psvar    = mkarray(NULL);
+    zsh_trace_vars = mkarray(NULL);
     module_path = mkarray(ztrdup(MODULE_DIR));
     modulestab = newmoduletable(17, "modules");
     linkedmodules = znewlinklist();
diff --git a/Src/params.c b/Src/params.c
index 8649178..2697aaa 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -58,7 +58,8 @@ char **pparams,		/* $argv        */
      **manpath,		/* $manpath     */
      **psvar,		/* $psvar       */
      **watch,		/* $watch       */
-     **zsh_eval_context; /* $zsh_eval_context */
+     **zsh_eval_context, /* $zsh_eval_context */
+     **zsh_trace_vars;  /* $zsh_trace_vars */
 /**/
 mod_export
 char **path,		/* $path        */
@@ -347,6 +348,7 @@ IPDEF8("WATCH", &watch, "watch", 0),
 IPDEF8("PATH", &path, "path", PM_RESTRICTED),
 IPDEF8("PSVAR", &psvar, "psvar", 0),
 IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, "zsh_eval_context", PM_READONLY),
+IPDEF8("ZSH_TRACE_VARS", &zsh_trace_vars, "zsh_trace_vars", 0),
 
 /* MODULE_PATH is not imported for security reasons */
 IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED),
@@ -387,6 +389,7 @@ IPDEF9("mailpath", &mailpath, "MAILPATH"),
 IPDEF9("manpath", &manpath, "MANPATH"),
 IPDEF9("psvar", &psvar, "PSVAR"),
 IPDEF9("watch", &watch, "WATCH"),
+IPDEF9("zsh_trace_vars", &zsh_trace_vars, "ZSH_TRACE_VARS"),
 
 IPDEF9F("zsh_eval_context", &zsh_eval_context, "ZSH_EVAL_CONTEXT", PM_READONLY),
 

-- 
Peter Stephenson <p.stephenson@xxxxxxxxxxx>       Consultant, Software
Tel: +44 (0)1223 434724              Samsung Cambridge Solution Centre
St John's House, St John's Innovation Park,
Cowley Road, Cambridge, CB4 0DS, UK



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