1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2009 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 /* Non-zero means the stuff being printed is inside of a function def. */
117 static int inside_function_def;
118 static int skip_this_indent;
119 static int was_heredoc;
120 static int printing_connection;
121 static REDIRECT *deferred_heredocs;
123 /* The depth of the group commands that we are currently printing. This
124 includes the group command that is a function body. */
125 static int group_command_nesting;
127 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
128 static char indirection_string[100];
130 /* Print COMMAND (a command tree) on standard output. */
132 print_command (command)
135 command_string_index = 0;
136 printf ("%s", make_command_string (command));
139 /* Make a string which is the printed representation of the command
140 tree in COMMAND. We return this string. However, the string is
141 not consed, so you have to do that yourself if you want it to
144 make_command_string (command)
147 command_string_index = was_heredoc = 0;
148 deferred_heredocs = 0;
149 make_command_string_internal (command);
150 return (the_printed_command);
153 /* The internal function. This is the real workhorse. */
155 make_command_string_internal (command)
164 if (skip_this_indent)
167 indent (indentation);
169 if (command->flags & CMD_TIME_PIPELINE)
172 if (command->flags & CMD_TIME_POSIX)
176 if (command->flags & CMD_INVERT_RETURN)
179 switch (command->type)
182 print_for_command (command->value.For);
185 #if defined (ARITH_FOR_COMMAND)
187 print_arith_for_command (command->value.ArithFor);
191 #if defined (SELECT_COMMAND)
193 print_select_command (command->value.Select);
198 print_case_command (command->value.Case);
202 print_while_command (command->value.While);
206 print_until_command (command->value.While);
210 print_if_command (command->value.If);
213 #if defined (DPAREN_ARITHMETIC)
215 print_arith_command (command->value.Arith->exp);
219 #if defined (COND_COMMAND)
221 print_cond_command (command->value.Cond);
226 print_simple_command (command->value.Simple);
232 printing_connection++;
233 make_command_string_internal (command->value.Connection->first);
235 switch (command->value.Connection->connector)
240 char c = command->value.Connection->connector;
246 print_deferred_heredocs (s);
248 if (c != '&' || command->value.Connection->second)
257 print_deferred_heredocs (" && ");
258 if (command->value.Connection->second)
263 print_deferred_heredocs (" || ");
264 if (command->value.Connection->second)
269 if (deferred_heredocs == 0)
271 if (was_heredoc == 0)
277 print_deferred_heredocs (inside_function_def ? "" : ";");
279 if (inside_function_def)
284 if (command->value.Connection->second)
290 cprintf (_("print_command: bad connector `%d'"),
291 command->value.Connection->connector);
295 make_command_string_internal (command->value.Connection->second);
296 if (deferred_heredocs)
297 print_deferred_heredocs ("");
298 printing_connection--;
301 case cm_function_def:
302 print_function_def (command->value.Function_def);
306 print_group_command (command->value.Group);
312 make_command_string_internal (command->value.Subshell->command);
317 cprintf ("coproc %s ", command->value.Coproc->name);
319 make_command_string_internal (command->value.Coproc->command);
323 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
328 if (command->redirects)
331 print_redirection_list (command->redirects);
337 _print_word_list (list, separator, pfunc)
344 for (w = list; w; w = w->next)
345 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
349 print_word_list (list, separator)
353 _print_word_list (list, separator, xprintf);
361 if (fd >= 0 && sh_validfd (fd) == 0)
363 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
368 internal_error (_("xtrace_set: NULL file pointer"));
371 if (fd >= 0 && fileno (fp) != fd)
372 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
381 xtrace_set (-1, stderr);
387 if (xtrace_fd >= 0 && xtrace_fp)
392 else if (xtrace_fd >= 0)
407 /* Return a string denoting what our indirection level is. */
410 indirection_level_string ()
414 char ps4_firstc[MB_LEN_MAX+1];
415 int ps4_firstc_len, ps4_len;
417 indirection_string[0] = '\0';
418 ps4 = get_string_value ("PS4");
420 if (ps4 == 0 || *ps4 == '\0')
421 return (indirection_string);
423 change_flag ('x', FLAG_OFF);
424 ps4 = decode_prompt_string (ps4);
425 change_flag ('x', FLAG_ON);
427 if (ps4 == 0 || *ps4 == '\0')
428 return (indirection_string);
430 #if defined (HANDLE_MULTIBYTE)
431 ps4_len = strnlen (ps4, MB_CUR_MAX);
432 ps4_firstc_len = MBLEN (ps4, ps4_len);
433 if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
435 ps4_firstc[0] = ps4[0];
436 ps4_firstc[ps4_firstc_len = 1] = '\0';
439 memcpy (ps4_firstc, ps4, ps4_firstc_len);
441 ps4_firstc[0] = ps4[0];
442 ps4_firstc[ps4_firstc_len = 1] = '\0';
445 for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
447 if (ps4_firstc_len == 1)
448 indirection_string[i] = ps4_firstc[0];
450 memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
453 for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
454 indirection_string[i] = ps4[j];
456 indirection_string[i] = '\0';
458 return (indirection_string);
462 xtrace_print_assignment (name, value, assign_list, xflags)
464 int assign_list, xflags;
471 fprintf (xtrace_fp, "%s", indirection_level_string ());
473 /* VALUE should not be NULL when this is called. */
474 if (*value == '\0' || assign_list)
476 else if (sh_contains_shell_metas (value))
477 nval = sh_single_quote (value);
478 else if (ansic_shouldquote (value))
479 nval = ansic_quote (value, 0, (int *)0);
484 fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
486 fprintf (xtrace_fp, "%s=%s\n", name, nval);
494 /* A function to print the words of a simple command when set -x is on. */
496 xtrace_print_word_list (list, xtflags)
506 fprintf (xtrace_fp, "%s", indirection_level_string ());
508 for (w = list; w; w = w->next)
511 if (t == 0 || *t == '\0')
512 fprintf (xtrace_fp, "''%s", w->next ? " " : "");
513 else if (sh_contains_shell_metas (t))
515 x = sh_single_quote (t);
516 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
519 else if (ansic_shouldquote (t))
521 x = ansic_quote (t, 0, (int *)0);
522 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
526 fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
528 fprintf (xtrace_fp, "\n");
533 command_print_word_list (list, separator)
537 _print_word_list (list, separator, cprintf);
541 print_for_command_head (for_command)
542 FOR_COM *for_command;
544 cprintf ("for %s in ", for_command->name->word);
545 command_print_word_list (for_command->map_list, " ");
549 xtrace_print_for_command_head (for_command)
550 FOR_COM *for_command;
553 fprintf (xtrace_fp, "%s", indirection_level_string ());
554 fprintf (xtrace_fp, "for %s in ", for_command->name->word);
555 xtrace_print_word_list (for_command->map_list, 0);
559 print_for_command (for_command)
560 FOR_COM *for_command;
562 print_for_command_head (for_command);
566 indentation += indentation_amount;
567 make_command_string_internal (for_command->action);
569 indentation -= indentation_amount;
573 #if defined (ARITH_FOR_COMMAND)
575 print_arith_for_command (arith_for_command)
576 ARITH_FOR_COM *arith_for_command;
579 command_print_word_list (arith_for_command->init, " ");
581 command_print_word_list (arith_for_command->test, " ");
583 command_print_word_list (arith_for_command->step, " ");
586 indentation += indentation_amount;
587 make_command_string_internal (arith_for_command->action);
589 indentation -= indentation_amount;
592 #endif /* ARITH_FOR_COMMAND */
594 #if defined (SELECT_COMMAND)
596 print_select_command_head (select_command)
597 SELECT_COM *select_command;
599 cprintf ("select %s in ", select_command->name->word);
600 command_print_word_list (select_command->map_list, " ");
604 xtrace_print_select_command_head (select_command)
605 SELECT_COM *select_command;
608 fprintf (xtrace_fp, "%s", indirection_level_string ());
609 fprintf (xtrace_fp, "select %s in ", select_command->name->word);
610 xtrace_print_word_list (select_command->map_list, 0);
614 print_select_command (select_command)
615 SELECT_COM *select_command;
617 print_select_command_head (select_command);
621 indentation += indentation_amount;
622 make_command_string_internal (select_command->action);
624 indentation -= indentation_amount;
627 #endif /* SELECT_COMMAND */
630 print_group_command (group_command)
631 GROUP_COM *group_command;
633 group_command_nesting++;
636 if (inside_function_def == 0)
640 /* This is a group command { ... } inside of a function
641 definition, and should be printed as a multiline group
642 command, using the current indentation. */
644 indentation += indentation_amount;
647 make_command_string_internal (group_command->command);
649 if (inside_function_def)
652 indentation -= indentation_amount;
653 indent (indentation);
663 group_command_nesting--;
667 print_case_command_head (case_command)
668 CASE_COM *case_command;
670 cprintf ("case %s in ", case_command->word->word);
674 xtrace_print_case_command_head (case_command)
675 CASE_COM *case_command;
678 fprintf (xtrace_fp, "%s", indirection_level_string ());
679 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
683 print_case_command (case_command)
684 CASE_COM *case_command;
686 print_case_command_head (case_command);
688 if (case_command->clauses)
689 print_case_clauses (case_command->clauses);
694 print_case_clauses (clauses)
695 PATTERN_LIST *clauses;
697 indentation += indentation_amount;
701 command_print_word_list (clauses->patterns, " | ");
703 indentation += indentation_amount;
704 make_command_string_internal (clauses->action);
705 indentation -= indentation_amount;
706 if (clauses->flags & CASEPAT_FALLTHROUGH)
708 else if (clauses->flags & CASEPAT_TESTNEXT)
712 clauses = clauses->next;
714 indentation -= indentation_amount;
718 print_while_command (while_command)
719 WHILE_COM *while_command;
721 print_until_or_while (while_command, "while");
725 print_until_command (while_command)
726 WHILE_COM *while_command;
728 print_until_or_while (while_command, "until");
732 print_until_or_while (while_command, which)
733 WHILE_COM *while_command;
736 cprintf ("%s ", which);
738 make_command_string_internal (while_command->test);
740 cprintf (" do\n"); /* was newline ("do\n"); */
741 indentation += indentation_amount;
742 make_command_string_internal (while_command->action);
743 indentation -= indentation_amount;
749 print_if_command (if_command)
754 make_command_string_internal (if_command->test);
757 indentation += indentation_amount;
758 make_command_string_internal (if_command->true_case);
759 indentation -= indentation_amount;
761 if (if_command->false_case)
765 indentation += indentation_amount;
766 make_command_string_internal (if_command->false_case);
767 indentation -= indentation_amount;
773 #if defined (DPAREN_ARITHMETIC)
775 print_arith_command (arith_cmd_list)
776 WORD_LIST *arith_cmd_list;
779 command_print_word_list (arith_cmd_list, " ");
784 #if defined (COND_COMMAND)
786 print_cond_node (cond)
789 if (cond->flags & CMD_INVERT_RETURN)
792 if (cond->type == COND_EXPR)
795 print_cond_node (cond->left);
798 else if (cond->type == COND_AND)
800 print_cond_node (cond->left);
802 print_cond_node (cond->right);
804 else if (cond->type == COND_OR)
806 print_cond_node (cond->left);
808 print_cond_node (cond->right);
810 else if (cond->type == COND_UNARY)
812 cprintf ("%s", cond->op->word);
814 print_cond_node (cond->left);
816 else if (cond->type == COND_BINARY)
818 print_cond_node (cond->left);
820 cprintf ("%s", cond->op->word);
822 print_cond_node (cond->right);
824 else if (cond->type == COND_TERM)
826 cprintf ("%s", cond->op->word); /* need to add quoting here */
831 print_cond_command (cond)
835 print_cond_node (cond);
841 debug_print_cond_command (cond)
844 fprintf (stderr, "DEBUG: ");
845 command_string_index = 0;
846 print_cond_command (cond);
847 fprintf (stderr, "%s\n", the_printed_command);
852 xtrace_print_cond_term (type, invert, op, arg1, arg2)
858 command_string_index = 0;
859 fprintf (xtrace_fp, "%s", indirection_level_string ());
860 fprintf (xtrace_fp, "[[ ");
862 fprintf (xtrace_fp, "! ");
864 if (type == COND_UNARY)
866 fprintf (xtrace_fp, "%s ", op->word);
867 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
869 else if (type == COND_BINARY)
871 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
872 fprintf (xtrace_fp, " %s ", op->word);
873 fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
876 fprintf (xtrace_fp, " ]]\n");
880 #endif /* COND_COMMAND */
882 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
883 /* A function to print the words of an arithmetic command when set -x is on. */
885 xtrace_print_arith_cmd (list)
891 fprintf (xtrace_fp, "%s", indirection_level_string ());
892 fprintf (xtrace_fp, "(( ");
893 for (w = list; w; w = w->next)
894 fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
895 fprintf (xtrace_fp, " ))\n");
902 print_simple_command (simple_command)
903 SIMPLE_COM *simple_command;
905 command_print_word_list (simple_command->words, " ");
907 if (simple_command->redirects)
910 print_redirection_list (simple_command->redirects);
915 print_heredocs (heredocs)
921 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
923 print_redirection (hdtail);
929 /* Print heredocs that are attached to the command before the connector
930 represented by CSTRING. The parsing semantics require us to print the
931 here-doc delimiters, then the connector (CSTRING), then the here-doc
932 bodies. We don't print the connector if it's a `;', but we use it to
933 note not to print an extra space after the last heredoc body and
936 print_deferred_heredocs (cstring)
941 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
944 print_heredoc_header (hdtail);
946 if (cstring[0] != ';' || cstring[1])
947 cprintf ("%s", cstring);
948 if (deferred_heredocs)
950 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
952 print_heredoc_body (hdtail);
955 if (deferred_heredocs)
957 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
958 cprintf (" "); /* make sure there's at least one space */
959 dispose_redirects (deferred_heredocs);
962 deferred_heredocs = (REDIRECT *)NULL;
966 print_redirection_list (redirects)
969 REDIRECT *heredocs, *hdtail, *newredir;
971 heredocs = (REDIRECT *)NULL;
977 /* Defer printing the here documents until we've printed the
978 rest of the redirections. */
979 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
981 newredir = copy_redirect (redirects);
982 newredir->next = (REDIRECT *)NULL;
985 hdtail->next = newredir;
989 hdtail = heredocs = newredir;
991 else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
993 /* Temporarily translate it as the execution code does. */
994 redirects->instruction = r_err_and_out;
995 print_redirection (redirects);
996 redirects->instruction = r_duplicating_output_word;
999 print_redirection (redirects);
1001 redirects = redirects->next;
1006 /* Now that we've printed all the other redirections (on one line),
1007 print the here documents. */
1008 if (heredocs && printing_connection)
1009 deferred_heredocs = heredocs;
1012 print_heredocs (heredocs);
1013 dispose_redirects (heredocs);
1018 print_heredoc_header (redirect)
1024 kill_leading = redirect->instruction == r_deblank_reading_until;
1026 /* Here doc header */
1027 if (redirect->rflags & REDIR_VARASSIGN)
1028 cprintf ("{%s}", redirect->redirector.filename->word);
1029 else if (redirect->redirector.dest != 0)
1030 cprintf ("%d", redirect->redirector.dest);
1032 /* If the here document delimiter is quoted, single-quote it. */
1033 if (redirect->redirectee.filename->flags & W_QUOTED)
1035 x = sh_single_quote (redirect->here_doc_eof);
1036 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1040 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1044 print_heredoc_body (redirect)
1048 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1052 print_redirection (redirect)
1055 int kill_leading, redirector, redir_fd;
1056 WORD_DESC *redirectee, *redir_word;
1059 redirectee = redirect->redirectee.filename;
1060 redir_fd = redirect->redirectee.dest;
1062 redir_word = redirect->redirector.filename;
1063 redirector = redirect->redirector.dest;
1065 switch (redirect->instruction)
1067 case r_input_direction:
1068 if (redirect->rflags & REDIR_VARASSIGN)
1069 cprintf ("{%s}", redir_word->word);
1070 else if (redirector != 0)
1071 cprintf ("%d", redirector);
1072 cprintf ("< %s", redirectee->word);
1075 case r_output_direction:
1076 if (redirect->rflags & REDIR_VARASSIGN)
1077 cprintf ("{%s}", redir_word->word);
1078 else if (redirector != 1)
1079 cprintf ("%d", redirector);
1080 cprintf ("> %s", redirectee->word);
1083 case r_inputa_direction: /* Redirection created by the shell. */
1087 case r_output_force:
1088 if (redirect->rflags & REDIR_VARASSIGN)
1089 cprintf ("{%s}", redir_word->word);
1090 else if (redirector != 1)
1091 cprintf ("%d", redirector);
1092 cprintf (">|%s", redirectee->word);
1095 case r_appending_to:
1096 if (redirect->rflags & REDIR_VARASSIGN)
1097 cprintf ("{%s}", redir_word->word);
1098 else if (redirector != 1)
1099 cprintf ("%d", redirector);
1100 cprintf (">> %s", redirectee->word);
1103 case r_input_output:
1104 if (redirect->rflags & REDIR_VARASSIGN)
1105 cprintf ("{%s}", redir_word->word);
1106 else if (redirector != 1)
1107 cprintf ("%d", redirector);
1108 cprintf ("<> %s", redirectee->word);
1111 case r_deblank_reading_until:
1112 case r_reading_until:
1113 print_heredoc_header (redirect);
1115 print_heredoc_body (redirect);
1118 case r_reading_string:
1119 if (redirect->rflags & REDIR_VARASSIGN)
1120 cprintf ("{%s}", redir_word->word);
1121 else if (redirector != 0)
1122 cprintf ("%d", redirector);
1124 /* Don't need to check whether or not to requote, since original quotes
1125 are still intact. The only thing that has happened is that $'...'
1126 has been replaced with 'expanded ...'. */
1127 if (ansic_shouldquote (redirect->redirectee.filename->word))
1130 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1131 cprintf ("<<< %s", x);
1136 cprintf ("<<< %s", redirect->redirectee.filename->word);
1139 case r_duplicating_input:
1140 if (redirect->rflags & REDIR_VARASSIGN)
1141 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1143 cprintf ("%d<&%d", redirector, redir_fd);
1146 case r_duplicating_output:
1147 if (redirect->rflags & REDIR_VARASSIGN)
1148 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1150 cprintf ("%d>&%d", redirector, redir_fd);
1153 case r_duplicating_input_word:
1154 if (redirect->rflags & REDIR_VARASSIGN)
1155 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1157 cprintf ("%d<&%s", redirector, redirectee->word);
1160 case r_duplicating_output_word:
1161 if (redirect->rflags & REDIR_VARASSIGN)
1162 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1164 cprintf ("%d>&%s", redirector, redirectee->word);
1168 if (redirect->rflags & REDIR_VARASSIGN)
1169 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1171 cprintf ("%d<&%d-", redirector, redir_fd);
1175 if (redirect->rflags & REDIR_VARASSIGN)
1176 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1178 cprintf ("%d>&%d-", redirector, redir_fd);
1181 case r_move_input_word:
1182 if (redirect->rflags & REDIR_VARASSIGN)
1183 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1185 cprintf ("%d<&%s-", redirector, redirectee->word);
1188 case r_move_output_word:
1189 if (redirect->rflags & REDIR_VARASSIGN)
1190 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1192 cprintf ("%d>&%s-", redirector, redirectee->word);
1196 if (redirect->rflags & REDIR_VARASSIGN)
1197 cprintf ("{%s}>&-", redir_word->word);
1199 cprintf ("%d>&-", redirector);
1203 cprintf ("&>%s", redirectee->word);
1206 case r_append_err_and_out:
1207 cprintf ("&>>%s", redirectee->word);
1215 inside_function_def = 0;
1217 printing_connection = 0;
1218 deferred_heredocs = 0;
1222 print_function_def (func)
1226 REDIRECT *func_redirects;
1228 func_redirects = NULL;
1229 cprintf ("function %s () \n", func->name->word);
1230 add_unwind_protect (reset_locals, 0);
1232 indent (indentation);
1235 inside_function_def++;
1236 indentation += indentation_amount;
1238 cmdcopy = copy_command (func->command);
1239 if (cmdcopy->type == cm_group)
1241 func_redirects = cmdcopy->redirects;
1242 cmdcopy->redirects = (REDIRECT *)NULL;
1244 make_command_string_internal (cmdcopy->type == cm_group
1245 ? cmdcopy->value.Group->command
1248 remove_unwind_protect ();
1249 indentation -= indentation_amount;
1250 inside_function_def--;
1255 print_redirection_list (func_redirects);
1256 cmdcopy->redirects = func_redirects;
1261 dispose_command (cmdcopy);
1264 /* Return the string representation of the named function.
1265 NAME is the name of the function.
1266 COMMAND is the function body. It should be a GROUP_COM.
1267 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1268 flags&FUNC_EXTERNAL means convert from internal to external form
1271 named_function_string (name, command, flags)
1277 int old_indent, old_amount;
1279 REDIRECT *func_redirects;
1281 old_indent = indentation;
1282 old_amount = indentation_amount;
1283 command_string_index = was_heredoc = 0;
1284 deferred_heredocs = 0;
1287 cprintf ("%s ", name);
1291 if ((flags & FUNC_MULTILINE) == 0)
1294 indentation_amount = 0;
1299 indentation += indentation_amount;
1302 inside_function_def++;
1304 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1306 cmdcopy = copy_command (command);
1307 /* Take any redirections specified in the function definition (which should
1308 apply to the function as a whole) and save them for printing later. */
1309 func_redirects = (REDIRECT *)NULL;
1310 if (cmdcopy->type == cm_group)
1312 func_redirects = cmdcopy->redirects;
1313 cmdcopy->redirects = (REDIRECT *)NULL;
1315 make_command_string_internal (cmdcopy->type == cm_group
1316 ? cmdcopy->value.Group->command
1319 indentation = old_indent;
1320 indentation_amount = old_amount;
1321 inside_function_def--;
1326 print_redirection_list (func_redirects);
1327 cmdcopy->redirects = func_redirects;
1332 result = the_printed_command;
1334 if ((flags & FUNC_MULTILINE) == 0)
1338 for (i = 0; result[i]; i++)
1339 if (result[i] == '\n')
1341 strcpy (result + i, result + i + 1);
1345 if (result[2] == '\n') /* XXX -- experimental */
1346 strcpy (result + 2, result + 3);
1350 dispose_command (cmdcopy);
1352 if (flags & FUNC_EXTERNAL)
1353 result = remove_quoted_escapes (result);
1363 indent (indentation);
1364 if (string && *string)
1365 cprintf ("%s", string);
1368 static char *indentation_string;
1369 static int indentation_size;
1377 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1379 for (i = 0; amount > 0; amount--)
1380 indentation_string[i++] = ' ';
1381 indentation_string[i] = '\0';
1382 cprintf (indentation_string);
1388 if (command_string_index > 0 &&
1389 (the_printed_command[command_string_index - 1] == '&' ||
1390 the_printed_command[command_string_index - 1] == '\n'))
1395 /* How to make the string. */
1397 #if defined (PREFER_STDARG)
1398 cprintf (const char *control, ...)
1400 cprintf (control, va_alist)
1401 const char *control;
1405 register const char *s;
1406 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1407 int digit_arg, arg_len, c;
1410 SH_VA_START (args, control);
1412 arg_len = strlen (control);
1413 the_printed_command_resize (arg_len + 1);
1420 argp = (char *)NULL;
1421 if (c != '%' || !*s)
1439 argp = va_arg (args, char *);
1440 arg_len = strlen (argp);
1444 /* Represent an out-of-range file descriptor with an out-of-range
1445 integer value. We can do this because the only use of `%d' in
1446 the calls to cprintf is to output a file descriptor number for
1448 digit_arg = va_arg (args, int);
1451 sprintf (intbuf, "%u", (unsigned)-1);
1455 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1456 arg_len = strlen (argp);
1460 char_arg[0] = va_arg (args, int);
1466 programming_error (_("cprintf: `%c': invalid format character"), c);
1471 if (argp && arg_len)
1473 the_printed_command_resize (arg_len + 1);
1474 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1475 command_string_index += arg_len;
1479 the_printed_command[command_string_index] = '\0';
1482 /* Ensure that there is enough space to stuff LENGTH characters into
1483 THE_PRINTED_COMMAND. */
1485 the_printed_command_resize (length)
1488 if (the_printed_command == 0)
1490 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1491 the_printed_command = (char *)xmalloc (the_printed_command_size);
1492 command_string_index = 0;
1494 else if ((command_string_index + length) >= the_printed_command_size)
1497 new = command_string_index + length + 1;
1499 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1500 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1501 the_printed_command_size = new;
1503 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1507 #if defined (HAVE_VPRINTF)
1508 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1509 also available.'' */
1512 #if defined (PREFER_STDARG)
1513 xprintf (const char *format, ...)
1515 xprintf (format, va_alist)
1522 SH_VA_START (args, format);
1524 vfprintf (stdout, format, args);
1531 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1534 printf (format, arg1, arg2, arg3, arg4, arg5);
1537 #endif /* !HAVE_VPRINTF */