1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2010 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
25 #if defined (HAVE_UNISTD_H)
27 # include <sys/types.h>
32 #if defined (PREFER_STDARG)
43 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
47 #include "builtins/common.h"
50 extern int printf __P((const char *, ...)); /* Yuck. Double yuck. */
53 extern int indirection_level;
55 static int indentation;
56 static int indentation_amount = 4;
58 #if defined (PREFER_STDARG)
59 typedef void PFUNC __P((const char *, ...));
61 static void cprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
62 static void xprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
64 #define PFUNC VFunction
65 static void cprintf ();
66 static void xprintf ();
69 static void reset_locals __P((void));
70 static void newline __P((char *));
71 static void indent __P((int));
72 static void semicolon __P((void));
73 static void the_printed_command_resize __P((int));
75 static void make_command_string_internal __P((COMMAND *));
76 static void _print_word_list __P((WORD_LIST *, char *, PFUNC *));
77 static void command_print_word_list __P((WORD_LIST *, char *));
78 static void print_case_clauses __P((PATTERN_LIST *));
79 static void print_redirection_list __P((REDIRECT *));
80 static void print_redirection __P((REDIRECT *));
81 static void print_heredoc_header __P((REDIRECT *));
82 static void print_heredoc_body __P((REDIRECT *));
83 static void print_heredocs __P((REDIRECT *));
84 static void print_deferred_heredocs __P((const char *));
86 static void print_for_command __P((FOR_COM *));
87 #if defined (ARITH_FOR_COMMAND)
88 static void print_arith_for_command __P((ARITH_FOR_COM *));
90 #if defined (SELECT_COMMAND)
91 static void print_select_command __P((SELECT_COM *));
93 static void print_group_command __P((GROUP_COM *));
94 static void print_case_command __P((CASE_COM *));
95 static void print_while_command __P((WHILE_COM *));
96 static void print_until_command __P((WHILE_COM *));
97 static void print_until_or_while __P((WHILE_COM *, char *));
98 static void print_if_command __P((IF_COM *));
99 #if defined (COND_COMMAND)
100 static void print_cond_node __P((COND_COM *));
102 static void print_function_def __P((FUNCTION_DEF *));
104 #define PRINTED_COMMAND_INITIAL_SIZE 64
105 #define PRINTED_COMMAND_GROW_SIZE 128
107 char *the_printed_command = (char *)NULL;
108 int the_printed_command_size = 0;
109 int command_string_index = 0;
114 #define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
116 #define PRINT_DEFERRED_HEREDOCS(x) \
118 if (deferred_heredocs) \
119 print_deferred_heredocs (x); \
122 /* Non-zero means the stuff being printed is inside of a function def. */
123 static int inside_function_def;
124 static int skip_this_indent;
125 static int was_heredoc;
126 static int printing_connection;
127 static REDIRECT *deferred_heredocs;
129 /* The depth of the group commands that we are currently printing. This
130 includes the group command that is a function body. */
131 static int group_command_nesting;
133 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
134 static char indirection_string[100];
136 /* Print COMMAND (a command tree) on standard output. */
138 print_command (command)
141 command_string_index = 0;
142 printf ("%s", make_command_string (command));
145 /* Make a string which is the printed representation of the command
146 tree in COMMAND. We return this string. However, the string is
147 not consed, so you have to do that yourself if you want it to
150 make_command_string (command)
153 command_string_index = was_heredoc = 0;
154 deferred_heredocs = 0;
155 make_command_string_internal (command);
156 return (the_printed_command);
159 /* The internal function. This is the real workhorse. */
161 make_command_string_internal (command)
170 if (skip_this_indent)
173 indent (indentation);
175 if (command->flags & CMD_TIME_PIPELINE)
178 if (command->flags & CMD_TIME_POSIX)
182 if (command->flags & CMD_INVERT_RETURN)
185 switch (command->type)
188 print_for_command (command->value.For);
191 #if defined (ARITH_FOR_COMMAND)
193 print_arith_for_command (command->value.ArithFor);
197 #if defined (SELECT_COMMAND)
199 print_select_command (command->value.Select);
204 print_case_command (command->value.Case);
208 print_while_command (command->value.While);
212 print_until_command (command->value.While);
216 print_if_command (command->value.If);
219 #if defined (DPAREN_ARITHMETIC)
221 print_arith_command (command->value.Arith->exp);
225 #if defined (COND_COMMAND)
227 print_cond_command (command->value.Cond);
232 print_simple_command (command->value.Simple);
238 printing_connection++;
239 make_command_string_internal (command->value.Connection->first);
241 switch (command->value.Connection->connector)
246 char c = command->value.Connection->connector;
252 print_deferred_heredocs (s);
254 if (c != '&' || command->value.Connection->second)
263 print_deferred_heredocs (" && ");
264 if (command->value.Connection->second)
269 print_deferred_heredocs (" || ");
270 if (command->value.Connection->second)
275 if (deferred_heredocs == 0)
277 if (was_heredoc == 0)
283 print_deferred_heredocs (inside_function_def ? "" : ";");
285 if (inside_function_def)
290 if (command->value.Connection->second)
296 cprintf (_("print_command: bad connector `%d'"),
297 command->value.Connection->connector);
301 make_command_string_internal (command->value.Connection->second);
302 PRINT_DEFERRED_HEREDOCS ("");
303 printing_connection--;
306 case cm_function_def:
307 print_function_def (command->value.Function_def);
311 print_group_command (command->value.Group);
317 make_command_string_internal (command->value.Subshell->command);
318 PRINT_DEFERRED_HEREDOCS ("");
323 cprintf ("coproc %s ", command->value.Coproc->name);
325 make_command_string_internal (command->value.Coproc->command);
329 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
334 if (command->redirects)
337 print_redirection_list (command->redirects);
343 _print_word_list (list, separator, pfunc)
350 for (w = list; w; w = w->next)
351 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
355 print_word_list (list, separator)
359 _print_word_list (list, separator, xprintf);
367 if (fd >= 0 && sh_validfd (fd) == 0)
369 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
374 internal_error (_("xtrace_set: NULL file pointer"));
377 if (fd >= 0 && fileno (fp) != fd)
378 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
387 xtrace_set (-1, stderr);
393 if (xtrace_fd >= 0 && xtrace_fp)
398 else if (xtrace_fd >= 0)
413 /* Return a string denoting what our indirection level is. */
416 indirection_level_string ()
420 char ps4_firstc[MB_LEN_MAX+1];
421 int ps4_firstc_len, ps4_len;
423 indirection_string[0] = '\0';
424 ps4 = get_string_value ("PS4");
426 if (ps4 == 0 || *ps4 == '\0')
427 return (indirection_string);
429 change_flag ('x', FLAG_OFF);
430 ps4 = decode_prompt_string (ps4);
431 change_flag ('x', FLAG_ON);
433 if (ps4 == 0 || *ps4 == '\0')
434 return (indirection_string);
436 #if defined (HANDLE_MULTIBYTE)
437 ps4_len = strnlen (ps4, MB_CUR_MAX);
438 ps4_firstc_len = MBLEN (ps4, ps4_len);
439 if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
441 ps4_firstc[0] = ps4[0];
442 ps4_firstc[ps4_firstc_len = 1] = '\0';
445 memcpy (ps4_firstc, ps4, ps4_firstc_len);
447 ps4_firstc[0] = ps4[0];
448 ps4_firstc[ps4_firstc_len = 1] = '\0';
451 for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
453 if (ps4_firstc_len == 1)
454 indirection_string[i] = ps4_firstc[0];
456 memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
459 for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
460 indirection_string[i] = ps4[j];
462 indirection_string[i] = '\0';
464 return (indirection_string);
468 xtrace_print_assignment (name, value, assign_list, xflags)
470 int assign_list, xflags;
477 fprintf (xtrace_fp, "%s", indirection_level_string ());
479 /* VALUE should not be NULL when this is called. */
480 if (*value == '\0' || assign_list)
482 else if (sh_contains_shell_metas (value))
483 nval = sh_single_quote (value);
484 else if (ansic_shouldquote (value))
485 nval = ansic_quote (value, 0, (int *)0);
490 fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
492 fprintf (xtrace_fp, "%s=%s\n", name, nval);
500 /* A function to print the words of a simple command when set -x is on. */
502 xtrace_print_word_list (list, xtflags)
512 fprintf (xtrace_fp, "%s", indirection_level_string ());
514 for (w = list; w; w = w->next)
517 if (t == 0 || *t == '\0')
518 fprintf (xtrace_fp, "''%s", w->next ? " " : "");
519 else if (sh_contains_shell_metas (t))
521 x = sh_single_quote (t);
522 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
525 else if (ansic_shouldquote (t))
527 x = ansic_quote (t, 0, (int *)0);
528 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
532 fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
534 fprintf (xtrace_fp, "\n");
539 command_print_word_list (list, separator)
543 _print_word_list (list, separator, cprintf);
547 print_for_command_head (for_command)
548 FOR_COM *for_command;
550 cprintf ("for %s in ", for_command->name->word);
551 command_print_word_list (for_command->map_list, " ");
555 xtrace_print_for_command_head (for_command)
556 FOR_COM *for_command;
559 fprintf (xtrace_fp, "%s", indirection_level_string ());
560 fprintf (xtrace_fp, "for %s in ", for_command->name->word);
561 xtrace_print_word_list (for_command->map_list, 0);
565 print_for_command (for_command)
566 FOR_COM *for_command;
568 print_for_command_head (for_command);
572 indentation += indentation_amount;
573 make_command_string_internal (for_command->action);
574 PRINT_DEFERRED_HEREDOCS ("");
576 indentation -= indentation_amount;
581 #if defined (ARITH_FOR_COMMAND)
583 print_arith_for_command (arith_for_command)
584 ARITH_FOR_COM *arith_for_command;
587 command_print_word_list (arith_for_command->init, " ");
589 command_print_word_list (arith_for_command->test, " ");
591 command_print_word_list (arith_for_command->step, " ");
594 indentation += indentation_amount;
595 make_command_string_internal (arith_for_command->action);
596 PRINT_DEFERRED_HEREDOCS ("");
598 indentation -= indentation_amount;
601 #endif /* ARITH_FOR_COMMAND */
603 #if defined (SELECT_COMMAND)
605 print_select_command_head (select_command)
606 SELECT_COM *select_command;
608 cprintf ("select %s in ", select_command->name->word);
609 command_print_word_list (select_command->map_list, " ");
613 xtrace_print_select_command_head (select_command)
614 SELECT_COM *select_command;
617 fprintf (xtrace_fp, "%s", indirection_level_string ());
618 fprintf (xtrace_fp, "select %s in ", select_command->name->word);
619 xtrace_print_word_list (select_command->map_list, 0);
623 print_select_command (select_command)
624 SELECT_COM *select_command;
626 print_select_command_head (select_command);
630 indentation += indentation_amount;
631 make_command_string_internal (select_command->action);
632 PRINT_DEFERRED_HEREDOCS ("");
634 indentation -= indentation_amount;
637 #endif /* SELECT_COMMAND */
640 print_group_command (group_command)
641 GROUP_COM *group_command;
643 group_command_nesting++;
646 if (inside_function_def == 0)
650 /* This is a group command { ... } inside of a function
651 definition, and should be printed as a multiline group
652 command, using the current indentation. */
654 indentation += indentation_amount;
657 make_command_string_internal (group_command->command);
658 PRINT_DEFERRED_HEREDOCS ("");
660 if (inside_function_def)
663 indentation -= indentation_amount;
664 indent (indentation);
674 group_command_nesting--;
678 print_case_command_head (case_command)
679 CASE_COM *case_command;
681 cprintf ("case %s in ", case_command->word->word);
685 xtrace_print_case_command_head (case_command)
686 CASE_COM *case_command;
689 fprintf (xtrace_fp, "%s", indirection_level_string ());
690 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
694 print_case_command (case_command)
695 CASE_COM *case_command;
697 print_case_command_head (case_command);
699 if (case_command->clauses)
700 print_case_clauses (case_command->clauses);
705 print_case_clauses (clauses)
706 PATTERN_LIST *clauses;
708 indentation += indentation_amount;
712 command_print_word_list (clauses->patterns, " | ");
714 indentation += indentation_amount;
715 make_command_string_internal (clauses->action);
716 indentation -= indentation_amount;
717 PRINT_DEFERRED_HEREDOCS ("");
718 if (clauses->flags & CASEPAT_FALLTHROUGH)
720 else if (clauses->flags & CASEPAT_TESTNEXT)
724 clauses = clauses->next;
726 indentation -= indentation_amount;
730 print_while_command (while_command)
731 WHILE_COM *while_command;
733 print_until_or_while (while_command, "while");
737 print_until_command (while_command)
738 WHILE_COM *while_command;
740 print_until_or_while (while_command, "until");
744 print_until_or_while (while_command, which)
745 WHILE_COM *while_command;
748 cprintf ("%s ", which);
750 make_command_string_internal (while_command->test);
751 PRINT_DEFERRED_HEREDOCS ("");
753 cprintf (" do\n"); /* was newline ("do\n"); */
754 indentation += indentation_amount;
755 make_command_string_internal (while_command->action);
756 PRINT_DEFERRED_HEREDOCS ("");
757 indentation -= indentation_amount;
763 print_if_command (if_command)
768 make_command_string_internal (if_command->test);
771 indentation += indentation_amount;
772 make_command_string_internal (if_command->true_case);
773 PRINT_DEFERRED_HEREDOCS ("");
774 indentation -= indentation_amount;
776 if (if_command->false_case)
780 indentation += indentation_amount;
781 make_command_string_internal (if_command->false_case);
782 PRINT_DEFERRED_HEREDOCS ("");
783 indentation -= indentation_amount;
789 #if defined (DPAREN_ARITHMETIC)
791 print_arith_command (arith_cmd_list)
792 WORD_LIST *arith_cmd_list;
795 command_print_word_list (arith_cmd_list, " ");
800 #if defined (COND_COMMAND)
802 print_cond_node (cond)
805 if (cond->flags & CMD_INVERT_RETURN)
808 if (cond->type == COND_EXPR)
811 print_cond_node (cond->left);
814 else if (cond->type == COND_AND)
816 print_cond_node (cond->left);
818 print_cond_node (cond->right);
820 else if (cond->type == COND_OR)
822 print_cond_node (cond->left);
824 print_cond_node (cond->right);
826 else if (cond->type == COND_UNARY)
828 cprintf ("%s", cond->op->word);
830 print_cond_node (cond->left);
832 else if (cond->type == COND_BINARY)
834 print_cond_node (cond->left);
836 cprintf ("%s", cond->op->word);
838 print_cond_node (cond->right);
840 else if (cond->type == COND_TERM)
842 cprintf ("%s", cond->op->word); /* need to add quoting here */
847 print_cond_command (cond)
851 print_cond_node (cond);
857 debug_print_cond_command (cond)
860 fprintf (stderr, "DEBUG: ");
861 command_string_index = 0;
862 print_cond_command (cond);
863 fprintf (stderr, "%s\n", the_printed_command);
868 xtrace_print_cond_term (type, invert, op, arg1, arg2)
874 command_string_index = 0;
875 fprintf (xtrace_fp, "%s", indirection_level_string ());
876 fprintf (xtrace_fp, "[[ ");
878 fprintf (xtrace_fp, "! ");
880 if (type == COND_UNARY)
882 fprintf (xtrace_fp, "%s ", op->word);
883 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
885 else if (type == COND_BINARY)
887 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
888 fprintf (xtrace_fp, " %s ", op->word);
889 fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
892 fprintf (xtrace_fp, " ]]\n");
896 #endif /* COND_COMMAND */
898 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
899 /* A function to print the words of an arithmetic command when set -x is on. */
901 xtrace_print_arith_cmd (list)
907 fprintf (xtrace_fp, "%s", indirection_level_string ());
908 fprintf (xtrace_fp, "(( ");
909 for (w = list; w; w = w->next)
910 fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
911 fprintf (xtrace_fp, " ))\n");
918 print_simple_command (simple_command)
919 SIMPLE_COM *simple_command;
921 command_print_word_list (simple_command->words, " ");
923 if (simple_command->redirects)
926 print_redirection_list (simple_command->redirects);
931 print_heredocs (heredocs)
937 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
939 print_redirection (hdtail);
945 /* Print heredocs that are attached to the command before the connector
946 represented by CSTRING. The parsing semantics require us to print the
947 here-doc delimiters, then the connector (CSTRING), then the here-doc
948 bodies. We don't print the connector if it's a `;', but we use it to
949 note not to print an extra space after the last heredoc body and
952 print_deferred_heredocs (cstring)
957 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
960 print_heredoc_header (hdtail);
962 if (cstring[0] && (cstring[0] != ';' || cstring[1]))
963 cprintf ("%s", cstring);
964 if (deferred_heredocs)
966 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
968 print_heredoc_body (hdtail);
971 if (deferred_heredocs)
973 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
974 cprintf (" "); /* make sure there's at least one space */
975 dispose_redirects (deferred_heredocs);
978 deferred_heredocs = (REDIRECT *)NULL;
982 print_redirection_list (redirects)
985 REDIRECT *heredocs, *hdtail, *newredir;
987 heredocs = (REDIRECT *)NULL;
993 /* Defer printing the here documents until we've printed the
994 rest of the redirections. */
995 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
997 newredir = copy_redirect (redirects);
998 newredir->next = (REDIRECT *)NULL;
1001 hdtail->next = newredir;
1005 hdtail = heredocs = newredir;
1007 else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
1009 /* Temporarily translate it as the execution code does. */
1010 redirects->instruction = r_err_and_out;
1011 print_redirection (redirects);
1012 redirects->instruction = r_duplicating_output_word;
1015 print_redirection (redirects);
1017 redirects = redirects->next;
1022 /* Now that we've printed all the other redirections (on one line),
1023 print the here documents. */
1024 if (heredocs && printing_connection)
1025 deferred_heredocs = heredocs;
1028 print_heredocs (heredocs);
1029 dispose_redirects (heredocs);
1034 print_heredoc_header (redirect)
1040 kill_leading = redirect->instruction == r_deblank_reading_until;
1042 /* Here doc header */
1043 if (redirect->rflags & REDIR_VARASSIGN)
1044 cprintf ("{%s}", redirect->redirector.filename->word);
1045 else if (redirect->redirector.dest != 0)
1046 cprintf ("%d", redirect->redirector.dest);
1048 /* If the here document delimiter is quoted, single-quote it. */
1049 if (redirect->redirectee.filename->flags & W_QUOTED)
1051 x = sh_single_quote (redirect->here_doc_eof);
1052 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1056 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1060 print_heredoc_body (redirect)
1064 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1068 print_redirection (redirect)
1071 int redirector, redir_fd;
1072 WORD_DESC *redirectee, *redir_word;
1074 redirectee = redirect->redirectee.filename;
1075 redir_fd = redirect->redirectee.dest;
1077 redir_word = redirect->redirector.filename;
1078 redirector = redirect->redirector.dest;
1080 switch (redirect->instruction)
1082 case r_input_direction:
1083 if (redirect->rflags & REDIR_VARASSIGN)
1084 cprintf ("{%s}", redir_word->word);
1085 else if (redirector != 0)
1086 cprintf ("%d", redirector);
1087 cprintf ("< %s", redirectee->word);
1090 case r_output_direction:
1091 if (redirect->rflags & REDIR_VARASSIGN)
1092 cprintf ("{%s}", redir_word->word);
1093 else if (redirector != 1)
1094 cprintf ("%d", redirector);
1095 cprintf ("> %s", redirectee->word);
1098 case r_inputa_direction: /* Redirection created by the shell. */
1102 case r_output_force:
1103 if (redirect->rflags & REDIR_VARASSIGN)
1104 cprintf ("{%s}", redir_word->word);
1105 else if (redirector != 1)
1106 cprintf ("%d", redirector);
1107 cprintf (">|%s", redirectee->word);
1110 case r_appending_to:
1111 if (redirect->rflags & REDIR_VARASSIGN)
1112 cprintf ("{%s}", redir_word->word);
1113 else if (redirector != 1)
1114 cprintf ("%d", redirector);
1115 cprintf (">> %s", redirectee->word);
1118 case r_input_output:
1119 if (redirect->rflags & REDIR_VARASSIGN)
1120 cprintf ("{%s}", redir_word->word);
1121 else if (redirector != 1)
1122 cprintf ("%d", redirector);
1123 cprintf ("<> %s", redirectee->word);
1126 case r_deblank_reading_until:
1127 case r_reading_until:
1128 print_heredoc_header (redirect);
1130 print_heredoc_body (redirect);
1133 case r_reading_string:
1134 if (redirect->rflags & REDIR_VARASSIGN)
1135 cprintf ("{%s}", redir_word->word);
1136 else if (redirector != 0)
1137 cprintf ("%d", redirector);
1139 /* Don't need to check whether or not to requote, since original quotes
1140 are still intact. The only thing that has happened is that $'...'
1141 has been replaced with 'expanded ...'. */
1142 if (ansic_shouldquote (redirect->redirectee.filename->word))
1145 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1146 cprintf ("<<< %s", x);
1151 cprintf ("<<< %s", redirect->redirectee.filename->word);
1154 case r_duplicating_input:
1155 if (redirect->rflags & REDIR_VARASSIGN)
1156 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1158 cprintf ("%d<&%d", redirector, redir_fd);
1161 case r_duplicating_output:
1162 if (redirect->rflags & REDIR_VARASSIGN)
1163 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1165 cprintf ("%d>&%d", redirector, redir_fd);
1168 case r_duplicating_input_word:
1169 if (redirect->rflags & REDIR_VARASSIGN)
1170 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1172 cprintf ("%d<&%s", redirector, redirectee->word);
1175 case r_duplicating_output_word:
1176 if (redirect->rflags & REDIR_VARASSIGN)
1177 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1179 cprintf ("%d>&%s", redirector, redirectee->word);
1183 if (redirect->rflags & REDIR_VARASSIGN)
1184 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1186 cprintf ("%d<&%d-", redirector, redir_fd);
1190 if (redirect->rflags & REDIR_VARASSIGN)
1191 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1193 cprintf ("%d>&%d-", redirector, redir_fd);
1196 case r_move_input_word:
1197 if (redirect->rflags & REDIR_VARASSIGN)
1198 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1200 cprintf ("%d<&%s-", redirector, redirectee->word);
1203 case r_move_output_word:
1204 if (redirect->rflags & REDIR_VARASSIGN)
1205 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1207 cprintf ("%d>&%s-", redirector, redirectee->word);
1211 if (redirect->rflags & REDIR_VARASSIGN)
1212 cprintf ("{%s}>&-", redir_word->word);
1214 cprintf ("%d>&-", redirector);
1218 cprintf ("&>%s", redirectee->word);
1221 case r_append_err_and_out:
1222 cprintf ("&>>%s", redirectee->word);
1230 inside_function_def = 0;
1232 printing_connection = 0;
1233 deferred_heredocs = 0;
1237 print_function_def (func)
1241 REDIRECT *func_redirects;
1243 func_redirects = NULL;
1244 cprintf ("function %s () \n", func->name->word);
1245 add_unwind_protect (reset_locals, 0);
1247 indent (indentation);
1250 inside_function_def++;
1251 indentation += indentation_amount;
1253 cmdcopy = copy_command (func->command);
1254 if (cmdcopy->type == cm_group)
1256 func_redirects = cmdcopy->redirects;
1257 cmdcopy->redirects = (REDIRECT *)NULL;
1259 make_command_string_internal (cmdcopy->type == cm_group
1260 ? cmdcopy->value.Group->command
1263 remove_unwind_protect ();
1264 indentation -= indentation_amount;
1265 inside_function_def--;
1270 print_redirection_list (func_redirects);
1271 cmdcopy->redirects = func_redirects;
1276 dispose_command (cmdcopy);
1279 /* Return the string representation of the named function.
1280 NAME is the name of the function.
1281 COMMAND is the function body. It should be a GROUP_COM.
1282 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1283 flags&FUNC_EXTERNAL means convert from internal to external form
1286 named_function_string (name, command, flags)
1292 int old_indent, old_amount;
1294 REDIRECT *func_redirects;
1296 old_indent = indentation;
1297 old_amount = indentation_amount;
1298 command_string_index = was_heredoc = 0;
1299 deferred_heredocs = 0;
1302 cprintf ("%s ", name);
1306 if ((flags & FUNC_MULTILINE) == 0)
1309 indentation_amount = 0;
1314 indentation += indentation_amount;
1317 inside_function_def++;
1319 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1321 cmdcopy = copy_command (command);
1322 /* Take any redirections specified in the function definition (which should
1323 apply to the function as a whole) and save them for printing later. */
1324 func_redirects = (REDIRECT *)NULL;
1325 if (cmdcopy->type == cm_group)
1327 func_redirects = cmdcopy->redirects;
1328 cmdcopy->redirects = (REDIRECT *)NULL;
1330 make_command_string_internal (cmdcopy->type == cm_group
1331 ? cmdcopy->value.Group->command
1334 indentation = old_indent;
1335 indentation_amount = old_amount;
1336 inside_function_def--;
1341 print_redirection_list (func_redirects);
1342 cmdcopy->redirects = func_redirects;
1347 result = the_printed_command;
1349 if ((flags & FUNC_MULTILINE) == 0)
1353 for (i = 0; result[i]; i++)
1354 if (result[i] == '\n')
1356 strcpy (result + i, result + i + 1);
1360 if (result[2] == '\n') /* XXX -- experimental */
1361 strcpy (result + 2, result + 3);
1365 dispose_command (cmdcopy);
1367 if (flags & FUNC_EXTERNAL)
1368 result = remove_quoted_escapes (result);
1378 indent (indentation);
1379 if (string && *string)
1380 cprintf ("%s", string);
1383 static char *indentation_string;
1384 static int indentation_size;
1392 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1394 for (i = 0; amount > 0; amount--)
1395 indentation_string[i++] = ' ';
1396 indentation_string[i] = '\0';
1397 cprintf (indentation_string);
1403 if (command_string_index > 0 &&
1404 (the_printed_command[command_string_index - 1] == '&' ||
1405 the_printed_command[command_string_index - 1] == '\n'))
1410 /* How to make the string. */
1412 #if defined (PREFER_STDARG)
1413 cprintf (const char *control, ...)
1415 cprintf (control, va_alist)
1416 const char *control;
1420 register const char *s;
1421 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1422 int digit_arg, arg_len, c;
1425 SH_VA_START (args, control);
1427 arg_len = strlen (control);
1428 the_printed_command_resize (arg_len + 1);
1435 argp = (char *)NULL;
1436 if (c != '%' || !*s)
1454 argp = va_arg (args, char *);
1455 arg_len = strlen (argp);
1459 /* Represent an out-of-range file descriptor with an out-of-range
1460 integer value. We can do this because the only use of `%d' in
1461 the calls to cprintf is to output a file descriptor number for
1463 digit_arg = va_arg (args, int);
1466 sprintf (intbuf, "%u", (unsigned)-1);
1470 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1471 arg_len = strlen (argp);
1475 char_arg[0] = va_arg (args, int);
1481 programming_error (_("cprintf: `%c': invalid format character"), c);
1486 if (argp && arg_len)
1488 the_printed_command_resize (arg_len + 1);
1489 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1490 command_string_index += arg_len;
1494 the_printed_command[command_string_index] = '\0';
1497 /* Ensure that there is enough space to stuff LENGTH characters into
1498 THE_PRINTED_COMMAND. */
1500 the_printed_command_resize (length)
1503 if (the_printed_command == 0)
1505 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1506 the_printed_command = (char *)xmalloc (the_printed_command_size);
1507 command_string_index = 0;
1509 else if ((command_string_index + length) >= the_printed_command_size)
1512 new = command_string_index + length + 1;
1514 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1515 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1516 the_printed_command_size = new;
1518 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1522 #if defined (HAVE_VPRINTF)
1523 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1524 also available.'' */
1527 #if defined (PREFER_STDARG)
1528 xprintf (const char *format, ...)
1530 xprintf (format, va_alist)
1537 SH_VA_START (args, format);
1539 vfprintf (stdout, format, args);
1546 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1549 printf (format, arg1, arg2, arg3, arg4, arg5);
1552 #endif /* !HAVE_VPRINTF */