hush: add parse tree debug print
This commit is contained in:
parent
6e6d331d97
commit
400c5b6fc6
@ -1,5 +1,9 @@
|
|||||||
Various bits of what is known about busybox shells, in no particular order.
|
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
|
2007-05-03
|
||||||
hush: update on "sleep 1 | exit 3; echo $?" bug.
|
hush: update on "sleep 1 | exit 3; echo $?" bug.
|
||||||
parse_stream_outer() repeatedly calls parse_stream().
|
parse_stream_outer() repeatedly calls parse_stream().
|
||||||
|
67
shell/hush.c
67
shell/hush.c
@ -85,11 +85,12 @@
|
|||||||
|
|
||||||
/* If you comment out one of these below, it will be #defined later
|
/* If you comment out one of these below, it will be #defined later
|
||||||
* to perform debug printfs to stderr: */
|
* to perform debug printfs to stderr: */
|
||||||
#define debug_printf(...) do {} while (0)
|
#define debug_printf(...) do {} while (0)
|
||||||
/* Finer-grained debug switch */
|
/* Finer-grained debug switches */
|
||||||
#define debug_printf_jobs(...) do {} while (0)
|
#define debug_printf_jobs(...) do {} while (0)
|
||||||
#define debug_printf_exec(...) do {} while (0)
|
#define debug_printf_exec(...) do {} while (0)
|
||||||
#define debug_printf_parse(...) do {} while (0)
|
#define debug_printf_parse(...) do {} while (0)
|
||||||
|
#define debug_print_tree(a, b) do {} while (0)
|
||||||
|
|
||||||
|
|
||||||
#ifndef debug_printf
|
#ifndef debug_printf
|
||||||
@ -1860,6 +1861,61 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
return -1;
|
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
|
// NB: called by pseudo_exec, and therefore must not modify any
|
||||||
// global data until exec/_exit (we can be a child after vfork!)
|
// global data until exec/_exit (we can be a child after vfork!)
|
||||||
static int run_list_real(struct pipe *pi)
|
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
|
/* free_pipe_list has the side effect of clearing memory
|
||||||
* In the long run that function can be merged with run_list_real,
|
* In the long run that function can be merged with run_list_real,
|
||||||
* but doing that now would hobble the debugging effort. */
|
* but doing that now would hobble the debugging effort. */
|
||||||
free_pipe_list(pi,0);
|
free_pipe_list(pi, 0);
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3177,6 +3233,7 @@ static int parse_stream_outer(struct in_str *inp, int flag)
|
|||||||
done_word(&temp, &ctx);
|
done_word(&temp, &ctx);
|
||||||
done_pipe(&ctx, PIPE_SEQ);
|
done_pipe(&ctx, PIPE_SEQ);
|
||||||
debug_printf_exec("parse_stream_outer: run_list\n");
|
debug_printf_exec("parse_stream_outer: run_list\n");
|
||||||
|
debug_print_tree(ctx.list_head, 0);
|
||||||
run_list(ctx.list_head);
|
run_list(ctx.list_head);
|
||||||
} else {
|
} else {
|
||||||
if (ctx.old_flag != 0) {
|
if (ctx.old_flag != 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user