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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #if defined (HAVE_UNISTD_H)
28 #if defined (PREFER_STDARG)
31 # if defined (PREFER_VARARGS)
39 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
41 #include "builtins/common.h"
43 #if !defined (PRINTF_DECLARED)
44 extern int printf
__P((const char *, ...)); /* Yuck. Double yuck. */
47 static int indentation
;
48 static int indentation_amount
= 4;
50 #if defined (PREFER_STDARG)
51 static void cprintf
__P((char *, ...));
53 static void cprintf ();
56 static void newline (), indent (), the_printed_command_resize ();
57 static void semicolon ();
58 static void xprintf ();
60 static void make_command_string_internal ();
61 static void command_print_word_list ();
62 static void print_case_clauses ();
63 static void print_redirection_list ();
64 static void print_redirection ();
66 static void print_for_command ();
67 #if defined (SELECT_COMMAND)
68 static void print_select_command ();
70 static void print_group_command ();
71 static void print_case_command ();
72 static void print_while_command ();
73 static void print_until_command ();
74 static void print_until_or_while ();
75 static void print_if_command ();
76 static void print_function_def ();
78 #define PRINTED_COMMAND_INITIAL_SIZE 64
79 #define PRINTED_COMMAND_GROW_SIZE 128
81 char *the_printed_command
= (char *)NULL
;
82 int the_printed_command_size
= 0;
83 int command_string_index
= 0;
85 /* Non-zero means the stuff being printed is inside of a function def. */
86 static int inside_function_def
;
87 static int skip_this_indent
;
88 static int was_heredoc
;
90 /* The depth of the group commands that we are currently printing. This
91 includes the group command that is a function body. */
92 static int group_command_nesting
;
94 /* Print COMMAND (a command tree) on standard output. */
96 print_command (command
)
99 command_string_index
= 0;
100 printf ("%s", make_command_string (command
));
103 /* Make a string which is the printed representation of the command
104 tree in COMMAND. We return this string. However, the string is
105 not consed, so you have to do that yourself if you want it to
108 make_command_string (command
)
111 command_string_index
= was_heredoc
= 0;
112 make_command_string_internal (command
);
113 return (the_printed_command
);
116 /* The internal function. This is the real workhorse. */
118 make_command_string_internal (command
)
125 if (skip_this_indent
)
128 indent (indentation
);
130 if (command
->flags
& CMD_WANT_SUBSHELL
)
133 if (command
->flags
& CMD_TIME_PIPELINE
)
136 if (command
->flags
& CMD_TIME_POSIX
)
140 if (command
->flags
& CMD_INVERT_RETURN
)
143 switch (command
->type
)
146 print_for_command (command
->value
.For
);
149 #if defined (SELECT_COMMAND)
151 print_select_command (command
->value
.Select
);
156 print_case_command (command
->value
.Case
);
160 print_while_command (command
->value
.While
);
164 print_until_command (command
->value
.While
);
168 print_if_command (command
->value
.If
);
172 print_simple_command (command
->value
.Simple
);
178 make_command_string_internal (command
->value
.Connection
->first
);
180 switch (command
->value
.Connection
->connector
)
185 char c
= command
->value
.Connection
->connector
;
187 if (c
!= '&' || command
->value
.Connection
->second
)
197 if (command
->value
.Connection
->second
)
203 if (command
->value
.Connection
->second
)
208 if (was_heredoc
== 0)
213 if (inside_function_def
)
218 if (command
->value
.Connection
->second
)
224 cprintf ("print_command: bad connector `%d'",
225 command
->value
.Connection
->connector
);
229 make_command_string_internal (command
->value
.Connection
->second
);
232 case cm_function_def
:
233 print_function_def (command
->value
.Function_def
);
237 print_group_command (command
->value
.Group
);
241 programming_error ("print_command: bad command type `%d'", command
->type
);
245 if (command
->flags
& CMD_WANT_SUBSHELL
)
248 if (command
->redirects
)
249 print_redirection_list (command
->redirects
);
254 _print_word_list (list
, separator
, pfunc
)
261 for (w
= list
; w
; w
= w
->next
)
262 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
266 print_word_list (list
, separator
)
270 _print_word_list (list
, separator
, xprintf
);
273 /* A function to print the words of a simple command when set -x is on. */
275 xtrace_print_word_list (list
)
281 fprintf (stderr
, "%s", indirection_level_string ());
282 for (w
= list
; w
; w
= w
->next
)
285 if (t
== 0 || *t
== '\0')
286 fprintf (stderr
, "''%s", w
->next
? " " : "");
287 else if (contains_shell_metas (t
))
288 fprintf (stderr
, "'%s'%s", t
, w
->next
? " " : "");
290 fprintf (stderr
, "%s%s", t
, w
->next
? " " : "");
292 fprintf (stderr
, "\n");
296 command_print_word_list (list
, separator
)
300 _print_word_list (list
, separator
, cprintf
);
304 print_for_command (for_command
)
305 FOR_COM
*for_command
;
307 cprintf ("for %s in ", for_command
->name
->word
);
308 command_print_word_list (for_command
->map_list
, " ");
311 indentation
+= indentation_amount
;
312 make_command_string_internal (for_command
->action
);
314 indentation
-= indentation_amount
;
318 #if defined (SELECT_COMMAND)
320 print_select_command (select_command
)
321 SELECT_COM
*select_command
;
323 cprintf ("select %s in ", select_command
->name
->word
);
324 command_print_word_list (select_command
->map_list
, " ");
327 indentation
+= indentation_amount
;
328 make_command_string_internal (select_command
->action
);
330 indentation
-= indentation_amount
;
333 #endif /* SELECT_COMMAND */
336 print_group_command (group_command
)
337 GROUP_COM
*group_command
;
339 group_command_nesting
++;
342 if (inside_function_def
== 0)
346 /* This is a group command { ... } inside of a function
347 definition, and should be printed as a multiline group
348 command, using the current indentation. */
350 indentation
+= indentation_amount
;
353 make_command_string_internal (group_command
->command
);
355 if (inside_function_def
)
358 indentation
-= indentation_amount
;
359 indent (indentation
);
369 group_command_nesting
--;
373 print_case_command (case_command
)
374 CASE_COM
*case_command
;
376 cprintf ("case %s in ", case_command
->word
->word
);
377 if (case_command
->clauses
)
378 print_case_clauses (case_command
->clauses
);
383 print_case_clauses (clauses
)
384 PATTERN_LIST
*clauses
;
386 indentation
+= indentation_amount
;
390 command_print_word_list (clauses
->patterns
, " | ");
392 indentation
+= indentation_amount
;
393 make_command_string_internal (clauses
->action
);
394 indentation
-= indentation_amount
;
396 clauses
= clauses
->next
;
398 indentation
-= indentation_amount
;
402 print_while_command (while_command
)
403 WHILE_COM
*while_command
;
405 print_until_or_while (while_command
, "while");
409 print_until_command (while_command
)
410 WHILE_COM
*while_command
;
412 print_until_or_while (while_command
, "until");
416 print_until_or_while (while_command
, which
)
417 WHILE_COM
*while_command
;
420 cprintf ("%s ", which
);
422 make_command_string_internal (while_command
->test
);
424 cprintf (" do\n"); /* was newline ("do\n"); */
425 indentation
+= indentation_amount
;
426 make_command_string_internal (while_command
->action
);
427 indentation
-= indentation_amount
;
433 print_if_command (if_command
)
438 make_command_string_internal (if_command
->test
);
441 indentation
+= indentation_amount
;
442 make_command_string_internal (if_command
->true_case
);
443 indentation
-= indentation_amount
;
445 if (if_command
->false_case
)
449 indentation
+= indentation_amount
;
450 make_command_string_internal (if_command
->false_case
);
451 indentation
-= indentation_amount
;
458 print_simple_command (simple_command
)
459 SIMPLE_COM
*simple_command
;
461 command_print_word_list (simple_command
->words
, " ");
463 if (simple_command
->redirects
)
466 print_redirection_list (simple_command
->redirects
);
471 print_redirection_list (redirects
)
474 REDIRECT
*heredocs
, *hdtail
, *newredir
;
476 heredocs
= (REDIRECT
*)NULL
;
482 /* Defer printing the here documents until we've printed the
483 rest of the redirections. */
484 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
486 newredir
= copy_redirect (redirects
);
487 newredir
->next
= (REDIRECT
*)NULL
;
490 hdtail
->next
= newredir
;
494 hdtail
= heredocs
= newredir
;
497 print_redirection (redirects
);
499 redirects
= redirects
->next
;
504 /* Now that we've printed all the other redirections (on one line),
505 print the here documents. */
509 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
511 print_redirection (hdtail
);
514 dispose_redirects (heredocs
);
520 print_redirection (redirect
)
523 int kill_leading
, redirector
, redir_fd
;
524 WORD_DESC
*redirectee
;
527 redirectee
= redirect
->redirectee
.filename
;
528 redirector
= redirect
->redirector
;
529 redir_fd
= redirect
->redirectee
.dest
;
531 switch (redirect
->instruction
)
533 case r_output_direction
:
535 cprintf ("%d", redirector
);
536 cprintf (">%s", redirectee
->word
);
539 case r_input_direction
:
541 cprintf ("%d", redirector
);
542 cprintf ("<%s", redirectee
->word
);
545 case r_inputa_direction
: /* Redirection created by the shell. */
551 cprintf ("%d", redirector
);
552 cprintf (">>%s", redirectee
->word
);
555 case r_deblank_reading_until
:
558 case r_reading_until
:
560 cprintf ("%d", redirector
);
561 /* If the here document delimiter is quoted, single-quote it. */
562 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
565 x
= single_quote (redirect
->here_doc_eof
);
566 cprintf ("<<%s%s\n", kill_leading
? "-" : "", x
);
570 cprintf ("<<%s%s\n", kill_leading
? "-" : "", redirect
->here_doc_eof
);
572 redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
575 case r_duplicating_input
:
576 cprintf ("%d<&%d", redirector
, redir_fd
);
579 case r_duplicating_output
:
580 cprintf ("%d>&%d", redirector
, redir_fd
);
583 case r_duplicating_input_word
:
584 cprintf ("%d<&%s", redirector
, redirectee
->word
);
587 case r_duplicating_output_word
:
588 cprintf ("%d>&%s", redirector
, redirectee
->word
);
592 cprintf ("%d>&-", redirector
);
596 cprintf (">&%s", redirectee
->word
);
601 cprintf ("%d", redirector
);
602 cprintf ("<>%s", redirectee
->word
);
607 cprintf ("%d", redirector
);
608 cprintf (">|%s", redirectee
->word
);
616 inside_function_def
= 0;
621 print_function_def (func
)
624 cprintf ("function %s () \n", func
->name
->word
);
625 add_unwind_protect (reset_locals
, 0);
627 indent (indentation
);
630 inside_function_def
++;
631 indentation
+= indentation_amount
;
633 make_command_string_internal (func
->command
->type
== cm_group
634 ? func
->command
->value
.Group
->command
637 remove_unwind_protect ();
638 indentation
-= indentation_amount
;
639 inside_function_def
--;
644 /* Return the string representation of the named function.
645 NAME is the name of the function.
646 COMMAND is the function body. It should be a GROUP_COM.
647 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
650 named_function_string (name
, command
, multi_line
)
656 int old_indent
, old_amount
;
658 old_indent
= indentation
;
659 old_amount
= indentation_amount
;
660 command_string_index
= was_heredoc
= 0;
663 cprintf ("%s ", name
);
670 indentation_amount
= 0;
675 indentation
+= indentation_amount
;
678 inside_function_def
++;
680 cprintf (multi_line
? "{ \n" : "{ ");
682 make_command_string_internal (command
->type
== cm_group
683 ? command
->value
.Group
->command
686 indentation
= old_indent
;
687 indentation_amount
= old_amount
;
688 inside_function_def
--;
692 result
= the_printed_command
;
698 for (i
= 0; result
[i
]; i
++)
699 if (result
[i
] == '\n')
701 strcpy (result
+ i
, result
+ i
+ 1);
705 if (result
[2] == '\n') /* XXX -- experimental */
706 strcpy (result
+ 2, result
+ 3);
718 indent (indentation
);
719 if (string
&& *string
)
720 cprintf ("%s", string
);
723 static char *indentation_string
;
724 static int indentation_size
;
732 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
734 for (i
= 0; amount
> 0; amount
--)
735 indentation_string
[i
++] = ' ';
736 indentation_string
[i
] = '\0';
737 cprintf (indentation_string
);
743 if (command_string_index
> 0 && the_printed_command
[command_string_index
- 1] == '&')
748 #if !defined (USE_VARARGS)
749 /* How to make the string. */
751 cprintf (format
, arg1
, arg2
)
752 char *format
, *arg1
, *arg2
;
755 char char_arg
[2], *argp
, *args
[2];
756 int arg_len
, c
, arg_index
;
758 args
[arg_index
= 0] = arg1
;
761 arg_len
= strlen (format
);
762 the_printed_command_resize (arg_len
+ 1);
787 argp
= (char *)args
[arg_index
++];
788 arg_len
= strlen (argp
);
792 argp
= itos (pointer_to_int (args
[arg_index
]));
794 arg_len
= strlen (argp
);
799 char_arg
[0] = pointer_to_int (args
[arg_index
]);
806 programming_error ("cprintf: bad `%%' argument (%c)", c
);
811 the_printed_command_resize (arg_len
+ 1);
812 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
813 command_string_index
+= arg_len
;
819 the_printed_command
[command_string_index
] = '\0';
822 #else /* We have support for varargs. */
824 /* How to make the string. */
826 #if defined (PREFER_STDARG)
827 cprintf (char *control
, ...)
829 cprintf (control
, va_alist
)
835 char char_arg
[2], *argp
;
836 int digit_arg
, arg_len
, c
;
839 #if defined (PREFER_STDARG)
840 va_start (args
, control
);
845 arg_len
= strlen (control
);
846 the_printed_command_resize (arg_len
+ 1);
873 argp
= va_arg (args
, char *);
874 arg_len
= strlen (argp
);
878 digit_arg
= va_arg (args
, int);
879 argp
= itos (digit_arg
);
880 arg_len
= strlen (argp
);
885 char_arg
[0] = va_arg (args
, int);
891 programming_error ("cprintf: bad `%%' argument (%c)", c
);
898 the_printed_command_resize (arg_len
+ 1);
899 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
900 command_string_index
+= arg_len
;
906 the_printed_command
[command_string_index
] = '\0';
908 #endif /* HAVE_VARARGS_H */
910 /* Ensure that there is enough space to stuff LENGTH characters into
911 THE_PRINTED_COMMAND. */
913 the_printed_command_resize (length
)
916 if (the_printed_command
== 0)
918 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
919 the_printed_command
= xmalloc (the_printed_command_size
);
920 command_string_index
= 0;
922 else if ((command_string_index
+ length
) >= the_printed_command_size
)
925 new = command_string_index
+ length
+ 1;
927 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
928 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
930 new = new + 2 * PRINTED_COMMAND_GROW_SIZE
- 1;
931 new -= new % PRINTED_COMMAND_GROW_SIZE
;
933 the_printed_command_size
= new;
934 the_printed_command
= xrealloc (the_printed_command
, the_printed_command_size
);
938 #if defined (HAVE_VFPRINTF)
941 #if defined (PREFER_STDARG)
942 xprintf (const char *format
, ...)
944 xprintf (format
, va_alist
)
951 #if defined (PREFER_STDARG)
952 va_start (args
, format
);
957 vfprintf (stdout
, format
, args
);
964 xprintf (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
967 printf (format
, arg1
, arg2
, arg3
, arg4
, arg5
);
970 #endif /* !HAVE_VFPRINTF */