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)
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 ();
88 #define PRINTED_COMMAND_INITIAL_SIZE 64
89 #define PRINTED_COMMAND_GROW_SIZE 128
91 char *the_printed_command = (char *)NULL;
92 int the_printed_command_size = 0;
93 int command_string_index = 0;
95 /* Non-zero means the stuff being printed is inside of a function def. */
96 static int inside_function_def;
97 static int skip_this_indent;
98 static int was_heredoc;
100 /* The depth of the group commands that we are currently printing. This
101 includes the group command that is a function body. */
102 static int group_command_nesting;
104 /* Print COMMAND (a command tree) on standard output. */
106 print_command (command)
109 command_string_index = 0;
110 printf ("%s", make_command_string (command));
113 /* Make a string which is the printed representation of the command
114 tree in COMMAND. We return this string. However, the string is
115 not consed, so you have to do that yourself if you want it to
118 make_command_string (command)
121 command_string_index = was_heredoc = 0;
122 make_command_string_internal (command);
123 return (the_printed_command);
126 /* The internal function. This is the real workhorse. */
128 make_command_string_internal (command)
135 if (skip_this_indent)
138 indent (indentation);
140 if (command->flags & CMD_WANT_SUBSHELL)
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 (SELECT_COMMAND)
161 print_select_command (command->value.Select);
166 print_case_command (command->value.Case);
170 print_while_command (command->value.While);
174 print_until_command (command->value.While);
178 print_if_command (command->value.If);
181 #if defined (DPAREN_ARITHMETIC)
183 print_arith_command (command->value.Arith);
187 #if defined (COND_COMMAND)
189 print_cond_command (command->value.Cond);
194 print_simple_command (command->value.Simple);
200 make_command_string_internal (command->value.Connection->first);
202 switch (command->value.Connection->connector)
207 char c = command->value.Connection->connector;
209 if (c != '&' || command->value.Connection->second)
219 if (command->value.Connection->second)
225 if (command->value.Connection->second)
230 if (was_heredoc == 0)
235 if (inside_function_def)
240 if (command->value.Connection->second)
246 cprintf ("print_command: bad connector `%d'",
247 command->value.Connection->connector);
251 make_command_string_internal (command->value.Connection->second);
254 case cm_function_def:
255 print_function_def (command->value.Function_def);
259 print_group_command (command->value.Group);
263 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
267 if (command->flags & CMD_WANT_SUBSHELL)
270 if (command->redirects)
273 print_redirection_list (command->redirects);
279 _print_word_list (list, separator, pfunc)
286 for (w = list; w; w = w->next)
287 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
291 print_word_list (list, separator)
295 _print_word_list (list, separator, xprintf);
298 /* A function to print the words of a simple command when set -x is on. */
300 xtrace_print_word_list (list)
306 fprintf (stderr, "%s", indirection_level_string ());
307 for (w = list; w; w = w->next)
310 if (t == 0 || *t == '\0')
311 fprintf (stderr, "''%s", w->next ? " " : "");
312 else if (contains_shell_metas (t))
314 x = single_quote (t);
315 fprintf (stderr, "%s%s", x, w->next ? " " : "");
319 fprintf (stderr, "%s%s", t, w->next ? " " : "");
321 fprintf (stderr, "\n");
325 command_print_word_list (list, separator)
329 _print_word_list (list, separator, cprintf);
333 print_for_command (for_command)
334 FOR_COM *for_command;
336 cprintf ("for %s in ", for_command->name->word);
337 command_print_word_list (for_command->map_list, " ");
340 indentation += indentation_amount;
341 make_command_string_internal (for_command->action);
343 indentation -= indentation_amount;
347 #if defined (SELECT_COMMAND)
349 print_select_command (select_command)
350 SELECT_COM *select_command;
352 cprintf ("select %s in ", select_command->name->word);
353 command_print_word_list (select_command->map_list, " ");
356 indentation += indentation_amount;
357 make_command_string_internal (select_command->action);
359 indentation -= indentation_amount;
362 #endif /* SELECT_COMMAND */
365 print_group_command (group_command)
366 GROUP_COM *group_command;
368 group_command_nesting++;
371 if (inside_function_def == 0)
375 /* This is a group command { ... } inside of a function
376 definition, and should be printed as a multiline group
377 command, using the current indentation. */
379 indentation += indentation_amount;
382 make_command_string_internal (group_command->command);
384 if (inside_function_def)
387 indentation -= indentation_amount;
388 indent (indentation);
398 group_command_nesting--;
402 print_case_command (case_command)
403 CASE_COM *case_command;
405 cprintf ("case %s in ", case_command->word->word);
406 if (case_command->clauses)
407 print_case_clauses (case_command->clauses);
412 print_case_clauses (clauses)
413 PATTERN_LIST *clauses;
415 indentation += indentation_amount;
419 command_print_word_list (clauses->patterns, " | ");
421 indentation += indentation_amount;
422 make_command_string_internal (clauses->action);
423 indentation -= indentation_amount;
425 clauses = clauses->next;
427 indentation -= indentation_amount;
431 print_while_command (while_command)
432 WHILE_COM *while_command;
434 print_until_or_while (while_command, "while");
438 print_until_command (while_command)
439 WHILE_COM *while_command;
441 print_until_or_while (while_command, "until");
445 print_until_or_while (while_command, which)
446 WHILE_COM *while_command;
449 cprintf ("%s ", which);
451 make_command_string_internal (while_command->test);
453 cprintf (" do\n"); /* was newline ("do\n"); */
454 indentation += indentation_amount;
455 make_command_string_internal (while_command->action);
456 indentation -= indentation_amount;
462 print_if_command (if_command)
467 make_command_string_internal (if_command->test);
470 indentation += indentation_amount;
471 make_command_string_internal (if_command->true_case);
472 indentation -= indentation_amount;
474 if (if_command->false_case)
478 indentation += indentation_amount;
479 make_command_string_internal (if_command->false_case);
480 indentation -= indentation_amount;
486 #if defined (DPAREN_ARITHMETIC)
488 print_arith_command (arith_command)
489 ARITH_COM *arith_command;
492 command_print_word_list (arith_command->exp, " ");
496 #if defined (COND_COMMAND)
498 print_cond_node (cond)
501 if (cond->flags & CMD_INVERT_RETURN)
504 if (cond->type == COND_EXPR)
507 print_cond_node (cond->left);
510 else if (cond->type == COND_AND)
512 print_cond_node (cond->left);
514 print_cond_node (cond->right);
516 else if (cond->type == COND_OR)
518 print_cond_node (cond->left);
520 print_cond_node (cond->right);
522 else if (cond->type == COND_UNARY)
524 cprintf ("%s", cond->op->word);
526 print_cond_node (cond->left);
528 else if (cond->type == COND_BINARY)
530 print_cond_node (cond->left);
532 cprintf ("%s", cond->op->word);
534 print_cond_node (cond->right);
536 else if (cond->type == COND_TERM)
538 cprintf ("%s", cond->op->word); /* need to add quoting here */
543 print_cond_command (cond)
547 print_cond_node (cond);
552 debug_print_cond_command (cond)
555 fprintf (stderr, "DEBUG: ");
556 command_string_index = 0;
557 print_cond_command (cond);
558 fprintf (stderr, "%s\n", the_printed_command);
562 xtrace_print_cond_term (type, invert, op, arg1, arg2)
567 command_string_index = 0;
568 fprintf (stderr, "%s", indirection_level_string ());
569 fprintf (stderr, "[[ ");
571 fprintf (stderr, "! ");
573 if (type == COND_UNARY)
575 fprintf (stderr, "%s ", op->word);
576 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
578 else if (type == COND_BINARY)
580 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
581 fprintf (stderr, " %s ", op->word);
582 fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
585 fprintf (stderr, " ]]\n");
587 #endif /* COND_COMMAND */
589 /* A function to print the words of an arithmetic command when set -x is on. */
591 xtrace_print_arith_cmd (list)
596 fprintf (stderr, "%s", indirection_level_string ());
597 fprintf (stderr, "(( ");
598 for (w = list; w; w = w->next)
599 fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
600 fprintf (stderr, " ))\n");
605 print_simple_command (simple_command)
606 SIMPLE_COM *simple_command;
608 command_print_word_list (simple_command->words, " ");
610 if (simple_command->redirects)
613 print_redirection_list (simple_command->redirects);
618 print_redirection_list (redirects)
621 REDIRECT *heredocs, *hdtail, *newredir;
623 heredocs = (REDIRECT *)NULL;
629 /* Defer printing the here documents until we've printed the
630 rest of the redirections. */
631 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
633 newredir = copy_redirect (redirects);
634 newredir->next = (REDIRECT *)NULL;
637 hdtail->next = newredir;
641 hdtail = heredocs = newredir;
644 print_redirection (redirects);
646 redirects = redirects->next;
651 /* Now that we've printed all the other redirections (on one line),
652 print the here documents. */
656 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
658 print_redirection (hdtail);
661 dispose_redirects (heredocs);
667 print_redirection (redirect)
670 int kill_leading, redirector, redir_fd;
671 WORD_DESC *redirectee;
674 redirectee = redirect->redirectee.filename;
675 redirector = redirect->redirector;
676 redir_fd = redirect->redirectee.dest;
678 switch (redirect->instruction)
680 case r_output_direction:
682 cprintf ("%d", redirector);
683 cprintf (">%s", redirectee->word);
686 case r_input_direction:
688 cprintf ("%d", redirector);
689 cprintf ("<%s", redirectee->word);
692 case r_inputa_direction: /* Redirection created by the shell. */
698 cprintf ("%d", redirector);
699 cprintf (">>%s", redirectee->word);
702 case r_deblank_reading_until:
705 case r_reading_until:
707 cprintf ("%d", redirector);
708 /* If the here document delimiter is quoted, single-quote it. */
709 if (redirect->redirectee.filename->flags & W_QUOTED)
712 x = single_quote (redirect->here_doc_eof);
713 cprintf ("<<%s%s\n", kill_leading? "-" : "", x);
717 cprintf ("<<%s%s\n", kill_leading? "-" : "", redirect->here_doc_eof);
719 redirect->redirectee.filename->word, redirect->here_doc_eof);
722 case r_duplicating_input:
723 cprintf ("%d<&%d", redirector, redir_fd);
726 case r_duplicating_output:
727 cprintf ("%d>&%d", redirector, redir_fd);
730 case r_duplicating_input_word:
731 cprintf ("%d<&%s", redirector, redirectee->word);
734 case r_duplicating_output_word:
735 cprintf ("%d>&%s", redirector, redirectee->word);
739 cprintf ("%d>&-", redirector);
743 cprintf (">&%s", redirectee->word);
748 cprintf ("%d", redirector);
749 cprintf ("<>%s", redirectee->word);
754 cprintf ("%d", redirector);
755 cprintf (">|%s", redirectee->word);
763 inside_function_def = 0;
768 print_function_def (func)
771 cprintf ("function %s () \n", func->name->word);
772 add_unwind_protect (reset_locals, 0);
774 indent (indentation);
777 inside_function_def++;
778 indentation += indentation_amount;
780 make_command_string_internal (func->command->type == cm_group
781 ? func->command->value.Group->command
784 remove_unwind_protect ();
785 indentation -= indentation_amount;
786 inside_function_def--;
791 /* Return the string representation of the named function.
792 NAME is the name of the function.
793 COMMAND is the function body. It should be a GROUP_COM.
794 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
797 named_function_string (name, command, multi_line)
803 int old_indent, old_amount;
805 old_indent = indentation;
806 old_amount = indentation_amount;
807 command_string_index = was_heredoc = 0;
810 cprintf ("%s ", name);
817 indentation_amount = 0;
822 indentation += indentation_amount;
825 inside_function_def++;
827 cprintf (multi_line ? "{ \n" : "{ ");
829 make_command_string_internal (command->type == cm_group
830 ? command->value.Group->command
833 indentation = old_indent;
834 indentation_amount = old_amount;
835 inside_function_def--;
839 result = the_printed_command;
845 for (i = 0; result[i]; i++)
846 if (result[i] == '\n')
848 strcpy (result + i, result + i + 1);
852 if (result[2] == '\n') /* XXX -- experimental */
853 strcpy (result + 2, result + 3);
865 indent (indentation);
866 if (string && *string)
867 cprintf ("%s", string);
870 static char *indentation_string;
871 static int indentation_size;
879 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
881 for (i = 0; amount > 0; amount--)
882 indentation_string[i++] = ' ';
883 indentation_string[i] = '\0';
884 cprintf (indentation_string);
890 if (command_string_index > 0 && the_printed_command[command_string_index - 1] == '&')
895 #if !defined (USE_VARARGS)
896 /* How to make the string. */
898 cprintf (format, arg1, arg2)
899 char *format, *arg1, *arg2;
902 char char_arg[2], *argp, *args[2], intbuf[32];
903 int arg_len, c, arg_index;
905 args[arg_index = 0] = arg1;
908 arg_len = strlen (format);
909 the_printed_command_resize (arg_len + 1);
934 argp = (char *)args[arg_index++];
935 arg_len = strlen (argp);
939 argp = inttostr (pointer_to_int (args[arg_index]), intbuf, sizeof (intbuf));
941 arg_len = strlen (argp);
945 char_arg[0] = pointer_to_int (args[arg_index]);
952 programming_error ("cprintf: bad `%%' argument (%c)", c);
957 the_printed_command_resize (arg_len + 1);
958 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
959 command_string_index += arg_len;
965 the_printed_command[command_string_index] = '\0';
968 #else /* We have support for varargs. */
970 /* How to make the string. */
972 #if defined (PREFER_STDARG)
973 cprintf (char *control, ...)
975 cprintf (control, va_alist)
981 char char_arg[2], *argp, intbuf[32];
982 int digit_arg, arg_len, c;
985 #if defined (PREFER_STDARG)
986 va_start (args, control);
991 arg_len = strlen (control);
992 the_printed_command_resize (arg_len + 1);
1001 argp = (char *)NULL;
1002 if (c != '%' || !*s)
1019 argp = va_arg (args, char *);
1020 arg_len = strlen (argp);
1024 digit_arg = va_arg (args, int);
1025 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1026 arg_len = strlen (argp);
1030 char_arg[0] = va_arg (args, int);
1036 programming_error ("cprintf: bad `%%' argument (%c)", c);
1041 if (argp && arg_len)
1043 the_printed_command_resize (arg_len + 1);
1044 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1045 command_string_index += arg_len;
1051 the_printed_command[command_string_index] = '\0';
1053 #endif /* HAVE_VARARGS_H */
1055 /* Ensure that there is enough space to stuff LENGTH characters into
1056 THE_PRINTED_COMMAND. */
1058 the_printed_command_resize (length)
1061 if (the_printed_command == 0)
1063 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1064 the_printed_command = xmalloc (the_printed_command_size);
1065 command_string_index = 0;
1067 else if ((command_string_index + length) >= the_printed_command_size)
1070 new = command_string_index + length + 1;
1072 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1073 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1075 new = new + 2 * PRINTED_COMMAND_GROW_SIZE - 1;
1076 new -= new % PRINTED_COMMAND_GROW_SIZE;
1078 the_printed_command_size = new;
1079 the_printed_command = xrealloc (the_printed_command, the_printed_command_size);
1083 #if defined (HAVE_VFPRINTF)
1086 #if defined (PREFER_STDARG)
1087 xprintf (const char *format, ...)
1089 xprintf (format, va_alist)
1096 #if defined (PREFER_STDARG)
1097 va_start (args, format);
1102 vfprintf (stdout, format, args);
1109 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1112 printf (format, arg1, arg2, arg3, arg4, arg5);
1115 #endif /* !HAVE_VFPRINTF */