hush: add parse tree debug print
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 4 May 2007 13:07:27 +0000 (13:07 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 4 May 2007 13:07:27 +0000 (13:07 -0000)
shell/README
shell/hush.c

index 989587a4fc76f53f5d27e5cb852c9edcf0cfe406..c3e7132ce4d9b7e5df55e82c052df4ff620966ed 100644 (file)
@@ -1,5 +1,9 @@
 Various bits of what is known about busybox shells, in no particular order.
 
+2007-05-03
+hush: new bug spotted: Ctrl-C on "while true; do true; done" kills shell,
+not just the loop.
+
 2007-05-03
 hush: update on "sleep 1 | exit 3; echo $?" bug.
 parse_stream_outer() repeatedly calls parse_stream().
index 4d5e4124429cfabf68cc35676fd8f4ac154a393c..c51ed1a514267e32d7225ef01014ad6de1e80ef0 100644 (file)
 
 /* If you comment out one of these below, it will be #defined later
  * to perform debug printfs to stderr: */
-#define debug_printf(...)      do {} while (0)
-/* Finer-grained debug switch */
-#define debug_printf_jobs(...) do {} while (0)
-#define debug_printf_exec(...) do {} while (0)
+#define debug_printf(...)       do {} while (0)
+/* Finer-grained debug switches */
+#define debug_printf_jobs(...)  do {} while (0)
+#define debug_printf_exec(...)  do {} while (0)
 #define debug_printf_parse(...) do {} while (0)
+#define debug_print_tree(a, b)  do {} while (0)
 
 
 #ifndef debug_printf
@@ -1860,6 +1861,61 @@ static int run_pipe_real(struct pipe *pi)
        return -1;
 }
 
+#ifndef debug_print_tree       
+static void debug_print_tree(struct pipe *pi, int lvl)
+{
+       static const char *PIPE[] = {
+       [PIPE_SEQ] = "SEQ",
+       [PIPE_AND] = "AND",
+       [PIPE_OR ] = "OR",
+       [PIPE_BG ] = "BG",
+       };
+       static const char *RES[] = {
+       [RES_NONE ] = "NONE" ,
+       [RES_IF   ] = "IF"   ,
+       [RES_THEN ] = "THEN" ,
+       [RES_ELIF ] = "ELIF" ,
+       [RES_ELSE ] = "ELSE" ,
+       [RES_FI   ] = "FI"   ,
+       [RES_FOR  ] = "FOR"  ,
+       [RES_WHILE] = "WHILE",
+       [RES_UNTIL] = "UNTIL",
+       [RES_DO   ] = "DO"   ,
+       [RES_DONE ] = "DONE" ,
+       [RES_XXXX ] = "XXXX" ,
+       [RES_IN   ] = "IN"   ,
+       [RES_SNTX ] = "SNTX" ,
+       };
+
+       int pin, prn;
+       char **argv;
+       pin = 0;
+       while (pi) {
+               fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "",
+                               pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]);
+               prn = 0;
+               while (prn < pi->num_progs) {
+                       fprintf(stderr, "%*s prog %d", lvl*2, "", prn);
+                       if (pi->progs[prn].group) {
+                               fprintf(stderr, " group: (argv=%p)\n", pi->progs[prn].argv);
+                               debug_print_tree(pi->progs[prn].group, lvl+1);
+                               prn++;
+                               continue;
+                       }
+                       argv = pi->progs[prn].argv;
+                       if (argv) while (*argv) {
+                               fprintf(stderr, " '%s'", *argv);
+                               argv++;
+                       }                               
+                       fprintf(stderr, "\n");
+                       prn++;
+               }
+               pi = pi->next;
+               pin++;
+       }
+}
+#endif
+
 // NB: called by pseudo_exec, and therefore must not modify any
 // global data until exec/_exit (we can be a child after vfork!)
 static int run_list_real(struct pipe *pi)
@@ -2088,7 +2144,7 @@ static int run_list(struct pipe *pi)
        /* free_pipe_list has the side effect of clearing memory
         * In the long run that function can be merged with run_list_real,
         * but doing that now would hobble the debugging effort. */
-       free_pipe_list(pi,0);
+       free_pipe_list(pi, 0);
        return rcode;
 }
 
@@ -3177,6 +3233,7 @@ static int parse_stream_outer(struct in_str *inp, int flag)
                        done_word(&temp, &ctx);
                        done_pipe(&ctx, PIPE_SEQ);
                        debug_printf_exec("parse_stream_outer: run_list\n");
+                       debug_print_tree(ctx.list_head, 0);
                        run_list(ctx.list_head);
                } else {
                        if (ctx.old_flag != 0) {