1 /* print_command -- A way to make readable commands from a command tree. */
2 /* Copyright (C) 1989 Free Software Foundation, Inc.
4 This file is part of GNU Bash, the Bourne Again SHell.
6 Bash is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License along
17 with Bash; see the file COPYING. If not, write to the Free Software
18 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 #if defined (HAVE_UNISTD_H)
26 # include <sys/types.h>
31 #if defined (PREFER_STDARG)
34 # if defined (PREFER_VARARGS)
42 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
44 #include "builtins/common.h"
46 #if !defined (PRINTF_DECLARED)
47 extern int printf
__P((const char *, ...)); /* Yuck. Double yuck. */
50 static int indentation
;
51 static int indentation_amount
= 4;
53 #if defined (PREFER_STDARG)
54 static void cprintf
__P((char *, ...));
56 static void cprintf ();
59 static void newline (), indent (), the_printed_command_resize ();
60 static void semicolon ();
61 static void xprintf ();
63 static void make_command_string_internal ();
64 static void command_print_word_list ();
65 static void print_case_clauses ();
66 static void print_redirection_list ();
67 static void print_redirection ();
69 static void print_for_command ();
70 #if defined (SELECT_COMMAND)
71 static void print_select_command ();
73 static void print_group_command ();
74 static void print_case_command ();
75 static void print_while_command ();
76 static void print_until_command ();
77 static void print_until_or_while ();
78 static void print_if_command ();
79 static void print_function_def ();
80 #if defined (DPAREN_ARITHMETIC)
81 static void print_arith_command ();
83 #if defined (COND_COMMAND)
84 static void print_cond_node ();
85 static void print_cond_command ();
87 #if defined (ARITH_FOR_COMMAND)
88 static void print_arith_for_command ();
91 #define PRINTED_COMMAND_INITIAL_SIZE 64
92 #define PRINTED_COMMAND_GROW_SIZE 128
94 char *the_printed_command
= (char *)NULL
;
95 int the_printed_command_size
= 0;
96 int command_string_index
= 0;
98 /* Non-zero means the stuff being printed is inside of a function def. */
99 static int inside_function_def
;
100 static int skip_this_indent
;
101 static int was_heredoc
;
103 /* The depth of the group commands that we are currently printing. This
104 includes the group command that is a function body. */
105 static int group_command_nesting
;
107 /* Print COMMAND (a command tree) on standard output. */
109 print_command (command
)
112 command_string_index
= 0;
113 printf ("%s", make_command_string (command
));
116 /* Make a string which is the printed representation of the command
117 tree in COMMAND. We return this string. However, the string is
118 not consed, so you have to do that yourself if you want it to
121 make_command_string (command
)
124 command_string_index
= was_heredoc
= 0;
125 make_command_string_internal (command
);
126 return (the_printed_command
);
129 /* The internal function. This is the real workhorse. */
131 make_command_string_internal (command
)
138 if (skip_this_indent
)
141 indent (indentation
);
143 if (command
->flags
& CMD_TIME_PIPELINE
)
146 if (command
->flags
& CMD_TIME_POSIX
)
150 if (command
->flags
& CMD_INVERT_RETURN
)
153 switch (command
->type
)
156 print_for_command (command
->value
.For
);
159 #if defined (ARITH_FOR_COMMAND)
161 print_arith_for_command (command
->value
.ArithFor
);
165 #if defined (SELECT_COMMAND)
167 print_select_command (command
->value
.Select
);
172 print_case_command (command
->value
.Case
);
176 print_while_command (command
->value
.While
);
180 print_until_command (command
->value
.While
);
184 print_if_command (command
->value
.If
);
187 #if defined (DPAREN_ARITHMETIC)
189 print_arith_command (command
->value
.Arith
);
193 #if defined (COND_COMMAND)
195 print_cond_command (command
->value
.Cond
);
200 print_simple_command (command
->value
.Simple
);
206 make_command_string_internal (command
->value
.Connection
->first
);
208 switch (command
->value
.Connection
->connector
)
213 char c
= command
->value
.Connection
->connector
;
215 if (c
!= '&' || command
->value
.Connection
->second
)
225 if (command
->value
.Connection
->second
)
231 if (command
->value
.Connection
->second
)
236 if (was_heredoc
== 0)
241 if (inside_function_def
)
246 if (command
->value
.Connection
->second
)
252 cprintf ("print_command: bad connector `%d'",
253 command
->value
.Connection
->connector
);
257 make_command_string_internal (command
->value
.Connection
->second
);
260 case cm_function_def
:
261 print_function_def (command
->value
.Function_def
);
265 print_group_command (command
->value
.Group
);
271 make_command_string_internal (command
->value
.Subshell
->command
);
276 command_error ("print_command", CMDERR_BADTYPE
, command
->type
, 0);
281 if (command
->redirects
)
284 print_redirection_list (command
->redirects
);
290 _print_word_list (list
, separator
, pfunc
)
297 for (w
= list
; w
; w
= w
->next
)
298 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
302 print_word_list (list
, separator
)
306 _print_word_list (list
, separator
, xprintf
);
309 /* A function to print the words of a simple command when set -x is on. */
311 xtrace_print_word_list (list
)
317 fprintf (stderr
, "%s", indirection_level_string ());
318 for (w
= list
; w
; w
= w
->next
)
321 if (t
== 0 || *t
== '\0')
322 fprintf (stderr
, "''%s", w
->next
? " " : "");
323 else if (sh_contains_shell_metas (t
))
325 x
= sh_single_quote (t
);
326 fprintf (stderr
, "%s%s", x
, w
->next
? " " : "");
330 fprintf (stderr
, "%s%s", t
, w
->next
? " " : "");
332 fprintf (stderr
, "\n");
336 command_print_word_list (list
, separator
)
340 _print_word_list (list
, separator
, cprintf
);
344 print_for_command (for_command
)
345 FOR_COM
*for_command
;
347 cprintf ("for %s in ", for_command
->name
->word
);
348 command_print_word_list (for_command
->map_list
, " ");
351 indentation
+= indentation_amount
;
352 make_command_string_internal (for_command
->action
);
354 indentation
-= indentation_amount
;
358 #if defined (ARITH_FOR_COMMAND)
360 print_arith_for_command (arith_for_command
)
361 ARITH_FOR_COM
*arith_for_command
;
364 command_print_word_list (arith_for_command
->init
, " ");
366 command_print_word_list (arith_for_command
->test
, " ");
368 command_print_word_list (arith_for_command
->step
, " ");
371 indentation
+= indentation_amount
;
372 make_command_string_internal (arith_for_command
->action
);
374 indentation
-= indentation_amount
;
377 #endif /* ARITH_FOR_COMMAND */
379 #if defined (SELECT_COMMAND)
381 print_select_command (select_command
)
382 SELECT_COM
*select_command
;
384 cprintf ("select %s in ", select_command
->name
->word
);
385 command_print_word_list (select_command
->map_list
, " ");
388 indentation
+= indentation_amount
;
389 make_command_string_internal (select_command
->action
);
391 indentation
-= indentation_amount
;
394 #endif /* SELECT_COMMAND */
397 print_group_command (group_command
)
398 GROUP_COM
*group_command
;
400 group_command_nesting
++;
403 if (inside_function_def
== 0)
407 /* This is a group command { ... } inside of a function
408 definition, and should be printed as a multiline group
409 command, using the current indentation. */
411 indentation
+= indentation_amount
;
414 make_command_string_internal (group_command
->command
);
416 if (inside_function_def
)
419 indentation
-= indentation_amount
;
420 indent (indentation
);
430 group_command_nesting
--;
434 print_case_command (case_command
)
435 CASE_COM
*case_command
;
437 cprintf ("case %s in ", case_command
->word
->word
);
438 if (case_command
->clauses
)
439 print_case_clauses (case_command
->clauses
);
444 print_case_clauses (clauses
)
445 PATTERN_LIST
*clauses
;
447 indentation
+= indentation_amount
;
451 command_print_word_list (clauses
->patterns
, " | ");
453 indentation
+= indentation_amount
;
454 make_command_string_internal (clauses
->action
);
455 indentation
-= indentation_amount
;
457 clauses
= clauses
->next
;
459 indentation
-= indentation_amount
;
463 print_while_command (while_command
)
464 WHILE_COM
*while_command
;
466 print_until_or_while (while_command
, "while");
470 print_until_command (while_command
)
471 WHILE_COM
*while_command
;
473 print_until_or_while (while_command
, "until");
477 print_until_or_while (while_command
, which
)
478 WHILE_COM
*while_command
;
481 cprintf ("%s ", which
);
483 make_command_string_internal (while_command
->test
);
485 cprintf (" do\n"); /* was newline ("do\n"); */
486 indentation
+= indentation_amount
;
487 make_command_string_internal (while_command
->action
);
488 indentation
-= indentation_amount
;
494 print_if_command (if_command
)
499 make_command_string_internal (if_command
->test
);
502 indentation
+= indentation_amount
;
503 make_command_string_internal (if_command
->true_case
);
504 indentation
-= indentation_amount
;
506 if (if_command
->false_case
)
510 indentation
+= indentation_amount
;
511 make_command_string_internal (if_command
->false_case
);
512 indentation
-= indentation_amount
;
518 #if defined (DPAREN_ARITHMETIC)
520 print_arith_command (arith_command
)
521 ARITH_COM
*arith_command
;
524 command_print_word_list (arith_command
->exp
, " ");
529 #if defined (COND_COMMAND)
531 print_cond_node (cond
)
534 if (cond
->flags
& CMD_INVERT_RETURN
)
537 if (cond
->type
== COND_EXPR
)
540 print_cond_node (cond
->left
);
543 else if (cond
->type
== COND_AND
)
545 print_cond_node (cond
->left
);
547 print_cond_node (cond
->right
);
549 else if (cond
->type
== COND_OR
)
551 print_cond_node (cond
->left
);
553 print_cond_node (cond
->right
);
555 else if (cond
->type
== COND_UNARY
)
557 cprintf ("%s", cond
->op
->word
);
559 print_cond_node (cond
->left
);
561 else if (cond
->type
== COND_BINARY
)
563 print_cond_node (cond
->left
);
565 cprintf ("%s", cond
->op
->word
);
567 print_cond_node (cond
->right
);
569 else if (cond
->type
== COND_TERM
)
571 cprintf ("%s", cond
->op
->word
); /* need to add quoting here */
576 print_cond_command (cond
)
580 print_cond_node (cond
);
586 debug_print_cond_command (cond
)
589 fprintf (stderr
, "DEBUG: ");
590 command_string_index
= 0;
591 print_cond_command (cond
);
592 fprintf (stderr
, "%s\n", the_printed_command
);
597 xtrace_print_cond_term (type
, invert
, op
, arg1
, arg2
)
602 command_string_index
= 0;
603 fprintf (stderr
, "%s", indirection_level_string ());
604 fprintf (stderr
, "[[ ");
606 fprintf (stderr
, "! ");
608 if (type
== COND_UNARY
)
610 fprintf (stderr
, "%s ", op
->word
);
611 fprintf (stderr
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
613 else if (type
== COND_BINARY
)
615 fprintf (stderr
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
616 fprintf (stderr
, " %s ", op
->word
);
617 fprintf (stderr
, "%s", (arg2
&& *arg2
) ? arg2
: "''");
620 fprintf (stderr
, " ]]\n");
622 #endif /* COND_COMMAND */
624 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
625 /* A function to print the words of an arithmetic command when set -x is on. */
627 xtrace_print_arith_cmd (list
)
632 fprintf (stderr
, "%s", indirection_level_string ());
633 fprintf (stderr
, "(( ");
634 for (w
= list
; w
; w
= w
->next
)
635 fprintf (stderr
, "%s%s", w
->word
->word
, w
->next
? " " : "");
636 fprintf (stderr
, " ))\n");
641 print_simple_command (simple_command
)
642 SIMPLE_COM
*simple_command
;
644 command_print_word_list (simple_command
->words
, " ");
646 if (simple_command
->redirects
)
649 print_redirection_list (simple_command
->redirects
);
654 print_redirection_list (redirects
)
657 REDIRECT
*heredocs
, *hdtail
, *newredir
;
659 heredocs
= (REDIRECT
*)NULL
;
665 /* Defer printing the here documents until we've printed the
666 rest of the redirections. */
667 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
669 newredir
= copy_redirect (redirects
);
670 newredir
->next
= (REDIRECT
*)NULL
;
673 hdtail
->next
= newredir
;
677 hdtail
= heredocs
= newredir
;
680 print_redirection (redirects
);
682 redirects
= redirects
->next
;
687 /* Now that we've printed all the other redirections (on one line),
688 print the here documents. */
692 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
694 print_redirection (hdtail
);
697 dispose_redirects (heredocs
);
703 print_redirection (redirect
)
706 int kill_leading
, redirector
, redir_fd
;
707 WORD_DESC
*redirectee
;
710 redirectee
= redirect
->redirectee
.filename
;
711 redirector
= redirect
->redirector
;
712 redir_fd
= redirect
->redirectee
.dest
;
714 switch (redirect
->instruction
)
716 case r_output_direction
:
718 cprintf ("%d", redirector
);
719 cprintf (">%s", redirectee
->word
);
722 case r_input_direction
:
724 cprintf ("%d", redirector
);
725 cprintf ("<%s", redirectee
->word
);
728 case r_inputa_direction
: /* Redirection created by the shell. */
734 cprintf ("%d", redirector
);
735 cprintf (">>%s", redirectee
->word
);
738 case r_deblank_reading_until
:
741 case r_reading_until
:
743 cprintf ("%d", redirector
);
744 /* If the here document delimiter is quoted, single-quote it. */
745 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
748 x
= sh_single_quote (redirect
->here_doc_eof
);
749 cprintf ("<<%s%s\n", kill_leading
? "-" : "", x
);
753 cprintf ("<<%s%s\n", kill_leading
? "-" : "", redirect
->here_doc_eof
);
755 redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
758 case r_duplicating_input
:
759 cprintf ("%d<&%d", redirector
, redir_fd
);
762 case r_duplicating_output
:
763 cprintf ("%d>&%d", redirector
, redir_fd
);
766 case r_duplicating_input_word
:
767 cprintf ("%d<&%s", redirector
, redirectee
->word
);
770 case r_duplicating_output_word
:
771 cprintf ("%d>&%s", redirector
, redirectee
->word
);
775 cprintf ("%d>&-", redirector
);
779 cprintf (">&%s", redirectee
->word
);
784 cprintf ("%d", redirector
);
785 cprintf ("<>%s", redirectee
->word
);
790 cprintf ("%d", redirector
);
791 cprintf (">|%s", redirectee
->word
);
799 inside_function_def
= 0;
804 print_function_def (func
)
808 REDIRECT
*func_redirects
;
810 cprintf ("function %s () \n", func
->name
->word
);
811 add_unwind_protect (reset_locals
, 0);
813 indent (indentation
);
816 inside_function_def
++;
817 indentation
+= indentation_amount
;
819 cmdcopy
= copy_command (func
->command
);
820 if (cmdcopy
->type
== cm_group
)
822 func_redirects
= cmdcopy
->redirects
;
823 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
825 make_command_string_internal (cmdcopy
->type
== cm_group
826 ? cmdcopy
->value
.Group
->command
829 remove_unwind_protect ();
830 indentation
-= indentation_amount
;
831 inside_function_def
--;
836 print_redirection_list (func_redirects
);
837 cmdcopy
->redirects
= func_redirects
;
842 dispose_command (cmdcopy
);
845 /* Return the string representation of the named function.
846 NAME is the name of the function.
847 COMMAND is the function body. It should be a GROUP_COM.
848 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
851 named_function_string (name
, command
, multi_line
)
857 int old_indent
, old_amount
;
859 REDIRECT
*func_redirects
;
861 old_indent
= indentation
;
862 old_amount
= indentation_amount
;
863 command_string_index
= was_heredoc
= 0;
866 cprintf ("%s ", name
);
873 indentation_amount
= 0;
878 indentation
+= indentation_amount
;
881 inside_function_def
++;
883 cprintf (multi_line
? "{ \n" : "{ ");
885 cmdcopy
= copy_command (command
);
886 /* Take any redirections specified in the function definition (which should
887 apply to the function as a whole) and save them for printing later. */
888 func_redirects
= (REDIRECT
*)NULL
;
889 if (cmdcopy
->type
== cm_group
)
891 func_redirects
= cmdcopy
->redirects
;
892 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
894 make_command_string_internal (cmdcopy
->type
== cm_group
895 ? cmdcopy
->value
.Group
->command
898 indentation
= old_indent
;
899 indentation_amount
= old_amount
;
900 inside_function_def
--;
905 print_redirection_list (func_redirects
);
906 cmdcopy
->redirects
= func_redirects
;
911 result
= the_printed_command
;
917 for (i
= 0; result
[i
]; i
++)
918 if (result
[i
] == '\n')
920 strcpy (result
+ i
, result
+ i
+ 1);
924 if (result
[2] == '\n') /* XXX -- experimental */
925 strcpy (result
+ 2, result
+ 3);
929 dispose_command (cmdcopy
);
939 indent (indentation
);
940 if (string
&& *string
)
941 cprintf ("%s", string
);
944 static char *indentation_string
;
945 static int indentation_size
;
953 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
955 for (i
= 0; amount
> 0; amount
--)
956 indentation_string
[i
++] = ' ';
957 indentation_string
[i
] = '\0';
958 cprintf (indentation_string
);
964 if (command_string_index
> 0 && the_printed_command
[command_string_index
- 1] == '&')
969 #if !defined (USE_VARARGS)
970 /* How to make the string. */
972 cprintf (format
, arg1
, arg2
)
973 char *format
, *arg1
, *arg2
;
976 char char_arg
[2], *argp
, *args
[2], intbuf
[32];
977 int arg_len
, c
, arg_index
;
979 args
[arg_index
= 0] = arg1
;
982 arg_len
= strlen (format
);
983 the_printed_command_resize (arg_len
+ 1);
1008 argp
= (char *)args
[arg_index
++];
1009 arg_len
= strlen (argp
);
1013 argp
= inttostr (pointer_to_int (args
[arg_index
]), intbuf
, sizeof (intbuf
));
1015 arg_len
= strlen (argp
);
1019 char_arg
[0] = pointer_to_int (args
[arg_index
]);
1026 programming_error ("cprintf: bad `%%' argument (%c)", c
);
1031 the_printed_command_resize (arg_len
+ 1);
1032 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1033 command_string_index
+= arg_len
;
1039 the_printed_command
[command_string_index
] = '\0';
1042 #else /* We have support for varargs. */
1044 /* How to make the string. */
1046 #if defined (PREFER_STDARG)
1047 cprintf (char *control
, ...)
1049 cprintf (control
, va_alist
)
1055 char char_arg
[2], *argp
, intbuf
[32];
1056 int digit_arg
, arg_len
, c
;
1059 #if defined (PREFER_STDARG)
1060 va_start (args
, control
);
1065 arg_len
= strlen (control
);
1066 the_printed_command_resize (arg_len
+ 1);
1075 argp
= (char *)NULL
;
1076 if (c
!= '%' || !*s
)
1093 argp
= va_arg (args
, char *);
1094 arg_len
= strlen (argp
);
1098 digit_arg
= va_arg (args
, int);
1099 argp
= inttostr (digit_arg
, intbuf
, sizeof (intbuf
));
1100 arg_len
= strlen (argp
);
1104 char_arg
[0] = va_arg (args
, int);
1110 programming_error ("cprintf: bad `%%' argument (%c)", c
);
1115 if (argp
&& arg_len
)
1117 the_printed_command_resize (arg_len
+ 1);
1118 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1119 command_string_index
+= arg_len
;
1125 the_printed_command
[command_string_index
] = '\0';
1127 #endif /* HAVE_VARARGS_H */
1129 /* Ensure that there is enough space to stuff LENGTH characters into
1130 THE_PRINTED_COMMAND. */
1132 the_printed_command_resize (length
)
1135 if (the_printed_command
== 0)
1137 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
1138 the_printed_command
= xmalloc (the_printed_command_size
);
1139 command_string_index
= 0;
1141 else if ((command_string_index
+ length
) >= the_printed_command_size
)
1144 new = command_string_index
+ length
+ 1;
1146 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1147 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
1148 the_printed_command_size
= new;
1150 the_printed_command
= xrealloc (the_printed_command
, the_printed_command_size
);
1154 #if defined (HAVE_VFPRINTF)
1157 #if defined (PREFER_STDARG)
1158 xprintf (const char *format
, ...)
1160 xprintf (format
, va_alist
)
1167 #if defined (PREFER_STDARG)
1168 va_start (args
, format
);
1173 vfprintf (stdout
, format
, args
);
1180 xprintf (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1183 printf (format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1186 #endif /* !HAVE_VFPRINTF */