From 2d539f04beefc8859a19dc6fa37dbc2b8ab2cc46 Mon Sep 17 00:00:00 2001
From: Piotr Grzybowski <merlin@narsil.org.pl>
Date: Sun, 6 May 2018 15:38:21 +0200
Subject: [PATCH] Re: (enhancement request) Limiting depth of xtrace enabled

---
 execute_cmd.c | 16 ++++++++--------
 externs.h     |  1 +
 print_cmd.c   | 22 ++++++++++++++++++++++
 subst.c       |  2 +-
 variables.c   |  2 +-
 5 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/execute_cmd.c b/execute_cmd.c
index 7e25b74..04ea7ff 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -2833,7 +2833,7 @@ execute_for_command (for_command)
       command_string_index = 0;
       print_for_command_head (for_command);
 
-      if (echo_command_at_execute)
+      if (xtrace_print())
 	xtrace_print_for_command_head (for_command);
 
       /* Save this command unless it's a trap command and we're not running
@@ -2960,7 +2960,7 @@ eval_arith_for_expr (l, okp)
   new = expand_words_no_vars (l);
   if (new)
     {
-      if (echo_command_at_execute)
+      if (xtrace_print())
 	xtrace_print_arith_cmd (new);
       this_command_name = "((";		/* )) for expression error messages */
 
@@ -3303,7 +3303,7 @@ execute_select_command (select_command)
   command_string_index = 0;
   print_select_command_head (select_command);
 
-  if (echo_command_at_execute)
+  if (xtrace_print())
     xtrace_print_select_command_head (select_command);
 
 #if 0
@@ -3439,7 +3439,7 @@ execute_case_command (case_command)
   command_string_index = 0;
   print_case_command_head (case_command);
 
-  if (echo_command_at_execute)
+  if (xtrace_print())
     xtrace_print_case_command_head (case_command);
 
 #if 0
@@ -3710,7 +3710,7 @@ execute_arith_command (arith_command)
 
   /* If we're tracing, make a new word list with `((' at the front and `))'
      at the back and print it. */
-  if (echo_command_at_execute)
+  if (xtrace_print())
     xtrace_print_arith_cmd (new);
 
   if (new)
@@ -3783,7 +3783,7 @@ execute_cond_node (cond)
 	comsub_ignore_return--;
       if (arg1 == 0)
 	arg1 = nullstr;
-      if (echo_command_at_execute)
+      if (xtrace_print())
 	xtrace_print_cond_term (cond->type, invert, cond->op, arg1, (char *)NULL);
       result = unary_test (cond->op->word, arg1) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
       if (arg1 != nullstr)
@@ -3816,7 +3816,7 @@ execute_cond_node (cond)
       if (arg2 == 0)
 	arg2 = nullstr;
 
-      if (echo_command_at_execute)
+      if (xtrace_print())
 	xtrace_print_cond_term (cond->type, invert, cond->op, arg1, arg2);
 
 #if defined (COND_REGEXP)
@@ -4296,7 +4296,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
 
   begin_unwind_frame ("simple-command");
 
-  if (echo_command_at_execute)
+  if (xtrace_print())
     xtrace_print_word_list (words, 1);
 
   builtin = (sh_builtin_func_t *)NULL;
diff --git a/externs.h b/externs.h
index 9faf305..871878d 100644
--- a/externs.h
+++ b/externs.h
@@ -57,6 +57,7 @@ extern void print_cond_command __P((COND_COM *));
 
 /* set -x support */
 extern void xtrace_init __P((void));
+extern unsigned int xtrace_print __P((void));
 #ifdef NEED_XTRACE_SET_DECL
 extern void xtrace_set __P((int, FILE *));
 #endif
diff --git a/print_cmd.c b/print_cmd.c
index 405f3da..cbf1fca 100644
--- a/print_cmd.c
+++ b/print_cmd.c
@@ -137,6 +137,28 @@ static int group_command_nesting;
 static char *indirection_string = 0;
 static int indirection_stringsiz = 0;
 
+unsigned int xtrace_print() {
+ char *v=get_string_value ("XTRACE_DEPTH");
+ intmax_t limit=-1;
+
+ if (v) {
+  if (!legal_number(v,&limit)||limit<0) {
+   limit=-1;
+  }
+ }
+
+ if (echo_command_at_execute) {
+  if (limit==-1||indirection_level<=limit) {
+   return 1;
+  } else {
+   return 0;
+  }
+ } else {
+  return 0;
+ }
+}
+
+
 /* Print COMMAND (a command tree) on standard output. */
 void
 print_command (command)
diff --git a/subst.c b/subst.c
index 6d10009..1292b57 100644
--- a/subst.c
+++ b/subst.c
@@ -3187,7 +3187,7 @@ do_assignment_internal (word, expand)
       value[0] = '\0';
     }
 
-  if (echo_command_at_execute)
+  if (xtrace_print())
     {
       if (appendop)
 	name[offset - 1] = '+';
diff --git a/variables.c b/variables.c
index 9d46b9a..f4a32ea 100644
--- a/variables.c
+++ b/variables.c
@@ -3442,7 +3442,7 @@ assign_in_env (word, flags)
   if (flags)
     stupidly_hack_special_variables (newname);
 
-  if (echo_command_at_execute)
+  if (xtrace_print())
     /* The Korn shell prints the `+ ' in front of assignment statements,
 	so we do too. */
     xtrace_print_assignment (name, value, 0, 1);
-- 
2.10.0

