1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2011 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 /* shell expansion characters: used in print_redirection_list */
117 #define EXPCHAR(c) ((c) == '{' || (c) == '~' || (c) == '$' || (c) == '`')
119 #define PRINT_DEFERRED_HEREDOCS(x) \
121 if (deferred_heredocs) \
122 print_deferred_heredocs (x); \
125 /* Non-zero means the stuff being printed is inside of a function def. */
126 static int inside_function_def;
127 static int skip_this_indent;
128 static int was_heredoc;
129 static int printing_connection;
130 static REDIRECT *deferred_heredocs;
132 /* The depth of the group commands that we are currently printing. This
133 includes the group command that is a function body. */
134 static int group_command_nesting;
136 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
137 static char *indirection_string = 0;
138 static int indirection_stringsiz = 0;
140 /* Print COMMAND (a command tree) on standard output. */
142 print_command (command)
145 command_string_index = 0;
146 printf ("%s", make_command_string (command));
149 /* Make a string which is the printed representation of the command
150 tree in COMMAND. We return this string. However, the string is
151 not consed, so you have to do that yourself if you want it to
154 make_command_string (command)
157 command_string_index = was_heredoc = 0;
158 deferred_heredocs = 0;
159 make_command_string_internal (command);
160 return (the_printed_command);
163 /* The internal function. This is the real workhorse. */
165 make_command_string_internal (command)
174 if (skip_this_indent)
177 indent (indentation);
179 if (command->flags & CMD_TIME_PIPELINE)
182 if (command->flags & CMD_TIME_POSIX)
186 if (command->flags & CMD_INVERT_RETURN)
189 switch (command->type)
192 print_for_command (command->value.For);
195 #if defined (ARITH_FOR_COMMAND)
197 print_arith_for_command (command->value.ArithFor);
201 #if defined (SELECT_COMMAND)
203 print_select_command (command->value.Select);
208 print_case_command (command->value.Case);
212 print_while_command (command->value.While);
216 print_until_command (command->value.While);
220 print_if_command (command->value.If);
223 #if defined (DPAREN_ARITHMETIC)
225 print_arith_command (command->value.Arith->exp);
229 #if defined (COND_COMMAND)
231 print_cond_command (command->value.Cond);
236 print_simple_command (command->value.Simple);
242 printing_connection++;
243 make_command_string_internal (command->value.Connection->first);
245 switch (command->value.Connection->connector)
250 char c = command->value.Connection->connector;
256 print_deferred_heredocs (s);
258 if (c != '&' || command->value.Connection->second)
267 print_deferred_heredocs (" && ");
268 if (command->value.Connection->second)
273 print_deferred_heredocs (" || ");
274 if (command->value.Connection->second)
279 if (deferred_heredocs == 0)
281 if (was_heredoc == 0)
287 print_deferred_heredocs (inside_function_def ? "" : ";");
289 if (inside_function_def)
294 if (command->value.Connection->second)
300 cprintf (_("print_command: bad connector `%d'"),
301 command->value.Connection->connector);
305 make_command_string_internal (command->value.Connection->second);
306 PRINT_DEFERRED_HEREDOCS ("");
307 printing_connection--;
310 case cm_function_def:
311 print_function_def (command->value.Function_def);
315 print_group_command (command->value.Group);
321 make_command_string_internal (command->value.Subshell->command);
322 PRINT_DEFERRED_HEREDOCS ("");
327 cprintf ("coproc %s ", command->value.Coproc->name);
329 make_command_string_internal (command->value.Coproc->command);
333 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
338 if (command->redirects)
341 print_redirection_list (command->redirects);
347 _print_word_list (list, separator, pfunc)
354 for (w = list; w; w = w->next)
355 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
359 print_word_list (list, separator)
363 _print_word_list (list, separator, xprintf);
371 if (fd >= 0 && sh_validfd (fd) == 0)
373 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
378 internal_error (_("xtrace_set: NULL file pointer"));
381 if (fd >= 0 && fileno (fp) != fd)
382 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
391 xtrace_set (-1, stderr);
397 if (xtrace_fd >= 0 && xtrace_fp)
402 else if (xtrace_fd >= 0)
417 /* Return a string denoting what our indirection level is. */
420 indirection_level_string ()
424 char ps4_firstc[MB_LEN_MAX+1];
425 int ps4_firstc_len, ps4_len, ineed, old;
427 ps4 = get_string_value ("PS4");
428 if (indirection_string == 0)
429 indirection_string = xmalloc (indirection_stringsiz = 100);
430 indirection_string[0] = '\0';
432 if (ps4 == 0 || *ps4 == '\0')
433 return (indirection_string);
435 old = change_flag ('x', FLAG_OFF);
436 ps4 = decode_prompt_string (ps4);
438 change_flag ('x', FLAG_ON);
440 if (ps4 == 0 || *ps4 == '\0')
441 return (indirection_string);
443 #if defined (HANDLE_MULTIBYTE)
444 ps4_len = strnlen (ps4, MB_CUR_MAX);
445 ps4_firstc_len = MBLEN (ps4, ps4_len);
446 if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || ps4_firstc_len < 0)
448 ps4_firstc[0] = ps4[0];
449 ps4_firstc[ps4_firstc_len = 1] = '\0';
452 memcpy (ps4_firstc, ps4, ps4_firstc_len);
454 ps4_firstc[0] = ps4[0];
455 ps4_firstc[ps4_firstc_len = 1] = '\0';
458 /* Dynamically resize indirection_string so we have room for everything
459 and we don't have to truncate ps4 */
460 ineed = (ps4_firstc_len * indirection_level) + strlen (ps4);
461 if (ineed > indirection_stringsiz - 1)
463 indirection_stringsiz = ineed + 1;
464 indirection_string = xrealloc (indirection_string, indirection_stringsiz);
467 for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < indirection_stringsiz - 1; i += ps4_firstc_len, j++)
469 if (ps4_firstc_len == 1)
470 indirection_string[i] = ps4_firstc[0];
472 memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
475 for (j = ps4_firstc_len; *ps4 && ps4[j] && i < indirection_stringsiz - 1; i++, j++)
476 indirection_string[i] = ps4[j];
478 indirection_string[i] = '\0';
480 return (indirection_string);
484 xtrace_print_assignment (name, value, assign_list, xflags)
486 int assign_list, xflags;
493 fprintf (xtrace_fp, "%s", indirection_level_string ());
495 /* VALUE should not be NULL when this is called. */
496 if (*value == '\0' || assign_list)
498 else if (sh_contains_shell_metas (value))
499 nval = sh_single_quote (value);
500 else if (ansic_shouldquote (value))
501 nval = ansic_quote (value, 0, (int *)0);
506 fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
508 fprintf (xtrace_fp, "%s=%s\n", name, nval);
516 /* A function to print the words of a simple command when set -x is on. */
518 xtrace_print_word_list (list, xtflags)
528 fprintf (xtrace_fp, "%s", indirection_level_string ());
530 for (w = list; w; w = w->next)
533 if (t == 0 || *t == '\0')
534 fprintf (xtrace_fp, "''%s", w->next ? " " : "");
535 else if (sh_contains_shell_metas (t))
537 x = sh_single_quote (t);
538 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
541 else if (ansic_shouldquote (t))
543 x = ansic_quote (t, 0, (int *)0);
544 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
548 fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
550 fprintf (xtrace_fp, "\n");
555 command_print_word_list (list, separator)
559 _print_word_list (list, separator, cprintf);
563 print_for_command_head (for_command)
564 FOR_COM *for_command;
566 cprintf ("for %s in ", for_command->name->word);
567 command_print_word_list (for_command->map_list, " ");
571 xtrace_print_for_command_head (for_command)
572 FOR_COM *for_command;
575 fprintf (xtrace_fp, "%s", indirection_level_string ());
576 fprintf (xtrace_fp, "for %s in ", for_command->name->word);
577 xtrace_print_word_list (for_command->map_list, 0);
581 print_for_command (for_command)
582 FOR_COM *for_command;
584 print_for_command_head (for_command);
588 indentation += indentation_amount;
589 make_command_string_internal (for_command->action);
590 PRINT_DEFERRED_HEREDOCS ("");
592 indentation -= indentation_amount;
597 #if defined (ARITH_FOR_COMMAND)
599 print_arith_for_command (arith_for_command)
600 ARITH_FOR_COM *arith_for_command;
603 command_print_word_list (arith_for_command->init, " ");
605 command_print_word_list (arith_for_command->test, " ");
607 command_print_word_list (arith_for_command->step, " ");
610 indentation += indentation_amount;
611 make_command_string_internal (arith_for_command->action);
612 PRINT_DEFERRED_HEREDOCS ("");
614 indentation -= indentation_amount;
617 #endif /* ARITH_FOR_COMMAND */
619 #if defined (SELECT_COMMAND)
621 print_select_command_head (select_command)
622 SELECT_COM *select_command;
624 cprintf ("select %s in ", select_command->name->word);
625 command_print_word_list (select_command->map_list, " ");
629 xtrace_print_select_command_head (select_command)
630 SELECT_COM *select_command;
633 fprintf (xtrace_fp, "%s", indirection_level_string ());
634 fprintf (xtrace_fp, "select %s in ", select_command->name->word);
635 xtrace_print_word_list (select_command->map_list, 0);
639 print_select_command (select_command)
640 SELECT_COM *select_command;
642 print_select_command_head (select_command);
646 indentation += indentation_amount;
647 make_command_string_internal (select_command->action);
648 PRINT_DEFERRED_HEREDOCS ("");
650 indentation -= indentation_amount;
653 #endif /* SELECT_COMMAND */
656 print_group_command (group_command)
657 GROUP_COM *group_command;
659 group_command_nesting++;
662 if (inside_function_def == 0)
666 /* This is a group command { ... } inside of a function
667 definition, and should be printed as a multiline group
668 command, using the current indentation. */
670 indentation += indentation_amount;
673 make_command_string_internal (group_command->command);
674 PRINT_DEFERRED_HEREDOCS ("");
676 if (inside_function_def)
679 indentation -= indentation_amount;
680 indent (indentation);
690 group_command_nesting--;
694 print_case_command_head (case_command)
695 CASE_COM *case_command;
697 cprintf ("case %s in ", case_command->word->word);
701 xtrace_print_case_command_head (case_command)
702 CASE_COM *case_command;
705 fprintf (xtrace_fp, "%s", indirection_level_string ());
706 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
710 print_case_command (case_command)
711 CASE_COM *case_command;
713 print_case_command_head (case_command);
715 if (case_command->clauses)
716 print_case_clauses (case_command->clauses);
721 print_case_clauses (clauses)
722 PATTERN_LIST *clauses;
724 indentation += indentation_amount;
728 command_print_word_list (clauses->patterns, " | ");
730 indentation += indentation_amount;
731 make_command_string_internal (clauses->action);
732 indentation -= indentation_amount;
733 PRINT_DEFERRED_HEREDOCS ("");
734 if (clauses->flags & CASEPAT_FALLTHROUGH)
736 else if (clauses->flags & CASEPAT_TESTNEXT)
740 clauses = clauses->next;
742 indentation -= indentation_amount;
746 print_while_command (while_command)
747 WHILE_COM *while_command;
749 print_until_or_while (while_command, "while");
753 print_until_command (while_command)
754 WHILE_COM *while_command;
756 print_until_or_while (while_command, "until");
760 print_until_or_while (while_command, which)
761 WHILE_COM *while_command;
764 cprintf ("%s ", which);
766 make_command_string_internal (while_command->test);
767 PRINT_DEFERRED_HEREDOCS ("");
769 cprintf (" do\n"); /* was newline ("do\n"); */
770 indentation += indentation_amount;
771 make_command_string_internal (while_command->action);
772 PRINT_DEFERRED_HEREDOCS ("");
773 indentation -= indentation_amount;
779 print_if_command (if_command)
784 make_command_string_internal (if_command->test);
787 indentation += indentation_amount;
788 make_command_string_internal (if_command->true_case);
789 PRINT_DEFERRED_HEREDOCS ("");
790 indentation -= indentation_amount;
792 if (if_command->false_case)
796 indentation += indentation_amount;
797 make_command_string_internal (if_command->false_case);
798 PRINT_DEFERRED_HEREDOCS ("");
799 indentation -= indentation_amount;
805 #if defined (DPAREN_ARITHMETIC)
807 print_arith_command (arith_cmd_list)
808 WORD_LIST *arith_cmd_list;
811 command_print_word_list (arith_cmd_list, " ");
816 #if defined (COND_COMMAND)
818 print_cond_node (cond)
821 if (cond->flags & CMD_INVERT_RETURN)
824 if (cond->type == COND_EXPR)
827 print_cond_node (cond->left);
830 else if (cond->type == COND_AND)
832 print_cond_node (cond->left);
834 print_cond_node (cond->right);
836 else if (cond->type == COND_OR)
838 print_cond_node (cond->left);
840 print_cond_node (cond->right);
842 else if (cond->type == COND_UNARY)
844 cprintf ("%s", cond->op->word);
846 print_cond_node (cond->left);
848 else if (cond->type == COND_BINARY)
850 print_cond_node (cond->left);
852 cprintf ("%s", cond->op->word);
854 print_cond_node (cond->right);
856 else if (cond->type == COND_TERM)
858 cprintf ("%s", cond->op->word); /* need to add quoting here */
863 print_cond_command (cond)
867 print_cond_node (cond);
873 debug_print_word_list (s, list, sep)
881 fprintf (stderr, "%s: ", s);
882 for (w = list; w; w = w->next)
883 fprintf (stderr, "%s%s", w->word->word, w->next ? sep : "");
884 fprintf (stderr, "\n");
888 debug_print_cond_command (cond)
891 fprintf (stderr, "DEBUG: ");
892 command_string_index = 0;
893 print_cond_command (cond);
894 fprintf (stderr, "%s\n", the_printed_command);
899 xtrace_print_cond_term (type, invert, op, arg1, arg2)
905 command_string_index = 0;
906 fprintf (xtrace_fp, "%s", indirection_level_string ());
907 fprintf (xtrace_fp, "[[ ");
909 fprintf (xtrace_fp, "! ");
911 if (type == COND_UNARY)
913 fprintf (xtrace_fp, "%s ", op->word);
914 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
916 else if (type == COND_BINARY)
918 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
919 fprintf (xtrace_fp, " %s ", op->word);
920 fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
923 fprintf (xtrace_fp, " ]]\n");
927 #endif /* COND_COMMAND */
929 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
930 /* A function to print the words of an arithmetic command when set -x is on. */
932 xtrace_print_arith_cmd (list)
938 fprintf (xtrace_fp, "%s", indirection_level_string ());
939 fprintf (xtrace_fp, "(( ");
940 for (w = list; w; w = w->next)
941 fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
942 fprintf (xtrace_fp, " ))\n");
949 print_simple_command (simple_command)
950 SIMPLE_COM *simple_command;
952 command_print_word_list (simple_command->words, " ");
954 if (simple_command->redirects)
957 print_redirection_list (simple_command->redirects);
962 print_heredocs (heredocs)
968 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
970 print_redirection (hdtail);
976 /* Print heredocs that are attached to the command before the connector
977 represented by CSTRING. The parsing semantics require us to print the
978 here-doc delimiters, then the connector (CSTRING), then the here-doc
979 bodies. We don't print the connector if it's a `;', but we use it to
980 note not to print an extra space after the last heredoc body and
983 print_deferred_heredocs (cstring)
988 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
991 print_heredoc_header (hdtail);
993 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
994 cprintf ("%s", cstring);
995 if (deferred_heredocs)
997 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
999 print_heredoc_body (hdtail);
1002 if (deferred_heredocs)
1004 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
1005 cprintf (" "); /* make sure there's at least one space */
1006 dispose_redirects (deferred_heredocs);
1009 deferred_heredocs = (REDIRECT *)NULL;
1013 print_redirection_list (redirects)
1014 REDIRECT *redirects;
1016 REDIRECT *heredocs, *hdtail, *newredir;
1019 heredocs = (REDIRECT *)NULL;
1025 /* Defer printing the here documents until we've printed the
1026 rest of the redirections. */
1027 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
1029 newredir = copy_redirect (redirects);
1030 newredir->next = (REDIRECT *)NULL;
1033 hdtail->next = newredir;
1037 hdtail = heredocs = newredir;
1039 else if (redirects->instruction == r_duplicating_output_word && (redirects->flags & REDIR_VARASSIGN) == 0 && redirects->redirector.dest == 1)
1041 /* Temporarily translate it as the execution code does. */
1042 rw = redirects->redirectee.filename->word;
1043 if (rw && *rw != '-' && DIGIT (*rw) == 0 && EXPCHAR (*rw) == 0)
1044 redirects->instruction = r_err_and_out;
1045 print_redirection (redirects);
1046 redirects->instruction = r_duplicating_output_word;
1049 print_redirection (redirects);
1051 redirects = redirects->next;
1056 /* Now that we've printed all the other redirections (on one line),
1057 print the here documents. */
1058 if (heredocs && printing_connection)
1059 deferred_heredocs = heredocs;
1062 print_heredocs (heredocs);
1063 dispose_redirects (heredocs);
1068 print_heredoc_header (redirect)
1074 kill_leading = redirect->instruction == r_deblank_reading_until;
1076 /* Here doc header */
1077 if (redirect->rflags & REDIR_VARASSIGN)
1078 cprintf ("{%s}", redirect->redirector.filename->word);
1079 else if (redirect->redirector.dest != 0)
1080 cprintf ("%d", redirect->redirector.dest);
1082 /* If the here document delimiter is quoted, single-quote it. */
1083 if (redirect->redirectee.filename->flags & W_QUOTED)
1085 x = sh_single_quote (redirect->here_doc_eof);
1086 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1090 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1094 print_heredoc_body (redirect)
1098 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1102 print_redirection (redirect)
1105 int redirector, redir_fd;
1106 WORD_DESC *redirectee, *redir_word;
1108 redirectee = redirect->redirectee.filename;
1109 redir_fd = redirect->redirectee.dest;
1111 redir_word = redirect->redirector.filename;
1112 redirector = redirect->redirector.dest;
1114 switch (redirect->instruction)
1116 case r_input_direction:
1117 if (redirect->rflags & REDIR_VARASSIGN)
1118 cprintf ("{%s}", redir_word->word);
1119 else if (redirector != 0)
1120 cprintf ("%d", redirector);
1121 cprintf ("< %s", redirectee->word);
1124 case r_output_direction:
1125 if (redirect->rflags & REDIR_VARASSIGN)
1126 cprintf ("{%s}", redir_word->word);
1127 else if (redirector != 1)
1128 cprintf ("%d", redirector);
1129 cprintf ("> %s", redirectee->word);
1132 case r_inputa_direction: /* Redirection created by the shell. */
1136 case r_output_force:
1137 if (redirect->rflags & REDIR_VARASSIGN)
1138 cprintf ("{%s}", redir_word->word);
1139 else if (redirector != 1)
1140 cprintf ("%d", redirector);
1141 cprintf (">| %s", redirectee->word);
1144 case r_appending_to:
1145 if (redirect->rflags & REDIR_VARASSIGN)
1146 cprintf ("{%s}", redir_word->word);
1147 else if (redirector != 1)
1148 cprintf ("%d", redirector);
1149 cprintf (">> %s", redirectee->word);
1152 case r_input_output:
1153 if (redirect->rflags & REDIR_VARASSIGN)
1154 cprintf ("{%s}", redir_word->word);
1155 else if (redirector != 1)
1156 cprintf ("%d", redirector);
1157 cprintf ("<> %s", redirectee->word);
1160 case r_deblank_reading_until:
1161 case r_reading_until:
1162 print_heredoc_header (redirect);
1164 print_heredoc_body (redirect);
1167 case r_reading_string:
1168 if (redirect->rflags & REDIR_VARASSIGN)
1169 cprintf ("{%s}", redir_word->word);
1170 else if (redirector != 0)
1171 cprintf ("%d", redirector);
1173 /* Don't need to check whether or not to requote, since original quotes
1174 are still intact. The only thing that has happened is that $'...'
1175 has been replaced with 'expanded ...'. */
1176 if (ansic_shouldquote (redirect->redirectee.filename->word))
1179 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1180 cprintf ("<<< %s", x);
1185 cprintf ("<<< %s", redirect->redirectee.filename->word);
1188 case r_duplicating_input:
1189 if (redirect->rflags & REDIR_VARASSIGN)
1190 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1192 cprintf ("%d<&%d", redirector, redir_fd);
1195 case r_duplicating_output:
1196 if (redirect->rflags & REDIR_VARASSIGN)
1197 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1199 cprintf ("%d>&%d", redirector, redir_fd);
1202 case r_duplicating_input_word:
1203 if (redirect->rflags & REDIR_VARASSIGN)
1204 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1206 cprintf ("%d<&%s", redirector, redirectee->word);
1209 case r_duplicating_output_word:
1210 if (redirect->rflags & REDIR_VARASSIGN)
1211 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1213 cprintf ("%d>&%s", redirector, redirectee->word);
1217 if (redirect->rflags & REDIR_VARASSIGN)
1218 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1220 cprintf ("%d<&%d-", redirector, redir_fd);
1224 if (redirect->rflags & REDIR_VARASSIGN)
1225 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1227 cprintf ("%d>&%d-", redirector, redir_fd);
1230 case r_move_input_word:
1231 if (redirect->rflags & REDIR_VARASSIGN)
1232 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1234 cprintf ("%d<&%s-", redirector, redirectee->word);
1237 case r_move_output_word:
1238 if (redirect->rflags & REDIR_VARASSIGN)
1239 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1241 cprintf ("%d>&%s-", redirector, redirectee->word);
1245 if (redirect->rflags & REDIR_VARASSIGN)
1246 cprintf ("{%s}>&-", redir_word->word);
1248 cprintf ("%d>&-", redirector);
1252 cprintf ("&> %s", redirectee->word);
1255 case r_append_err_and_out:
1256 cprintf ("&>> %s", redirectee->word);
1264 inside_function_def = 0;
1266 printing_connection = 0;
1267 deferred_heredocs = 0;
1271 print_function_def (func)
1275 REDIRECT *func_redirects;
1277 func_redirects = NULL;
1278 cprintf ("function %s () \n", func->name->word);
1279 add_unwind_protect (reset_locals, 0);
1281 indent (indentation);
1284 inside_function_def++;
1285 indentation += indentation_amount;
1287 cmdcopy = copy_command (func->command);
1288 if (cmdcopy->type == cm_group)
1290 func_redirects = cmdcopy->redirects;
1291 cmdcopy->redirects = (REDIRECT *)NULL;
1293 make_command_string_internal (cmdcopy->type == cm_group
1294 ? cmdcopy->value.Group->command
1296 /* XXX - PRINT_DEFERRED_HEREDOCS (""); ? */
1298 remove_unwind_protect ();
1299 indentation -= indentation_amount;
1300 inside_function_def--;
1305 print_redirection_list (func_redirects);
1306 cmdcopy->redirects = func_redirects;
1311 dispose_command (cmdcopy);
1314 /* Return the string representation of the named function.
1315 NAME is the name of the function.
1316 COMMAND is the function body. It should be a GROUP_COM.
1317 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1318 flags&FUNC_EXTERNAL means convert from internal to external form
1321 named_function_string (name, command, flags)
1327 int old_indent, old_amount;
1329 REDIRECT *func_redirects;
1331 old_indent = indentation;
1332 old_amount = indentation_amount;
1333 command_string_index = was_heredoc = 0;
1334 deferred_heredocs = 0;
1337 cprintf ("%s ", name);
1341 if ((flags & FUNC_MULTILINE) == 0)
1344 indentation_amount = 0;
1349 indentation += indentation_amount;
1352 inside_function_def++;
1354 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1356 cmdcopy = copy_command (command);
1357 /* Take any redirections specified in the function definition (which should
1358 apply to the function as a whole) and save them for printing later. */
1359 func_redirects = (REDIRECT *)NULL;
1360 if (cmdcopy->type == cm_group)
1362 func_redirects = cmdcopy->redirects;
1363 cmdcopy->redirects = (REDIRECT *)NULL;
1365 make_command_string_internal (cmdcopy->type == cm_group
1366 ? cmdcopy->value.Group->command
1368 /* XXX - PRINT_DEFERRED_HEREDOCS (""); ? */
1370 indentation = old_indent;
1371 indentation_amount = old_amount;
1372 inside_function_def--;
1377 print_redirection_list (func_redirects);
1378 cmdcopy->redirects = func_redirects;
1383 result = the_printed_command;
1385 if ((flags & FUNC_MULTILINE) == 0)
1389 for (i = 0; result[i]; i++)
1390 if (result[i] == '\n')
1392 strcpy (result + i, result + i + 1);
1396 if (result[2] == '\n') /* XXX -- experimental */
1397 memmove (result + 2, result + 3, strlen (result) - 2);
1402 dispose_command (cmdcopy);
1404 if (flags & FUNC_EXTERNAL)
1405 result = remove_quoted_escapes (result);
1415 indent (indentation);
1416 if (string && *string)
1417 cprintf ("%s", string);
1420 static char *indentation_string;
1421 static int indentation_size;
1429 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1431 for (i = 0; amount > 0; amount--)
1432 indentation_string[i++] = ' ';
1433 indentation_string[i] = '\0';
1434 cprintf ("%s", indentation_string);
1440 if (command_string_index > 0 &&
1441 (the_printed_command[command_string_index - 1] == '&' ||
1442 the_printed_command[command_string_index - 1] == '\n'))
1447 /* How to make the string. */
1449 #if defined (PREFER_STDARG)
1450 cprintf (const char *control, ...)
1452 cprintf (control, va_alist)
1453 const char *control;
1457 register const char *s;
1458 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1459 int digit_arg, arg_len, c;
1462 SH_VA_START (args, control);
1464 arg_len = strlen (control);
1465 the_printed_command_resize (arg_len + 1);
1472 argp = (char *)NULL;
1473 if (c != '%' || !*s)
1491 argp = va_arg (args, char *);
1492 arg_len = strlen (argp);
1496 /* Represent an out-of-range file descriptor with an out-of-range
1497 integer value. We can do this because the only use of `%d' in
1498 the calls to cprintf is to output a file descriptor number for
1500 digit_arg = va_arg (args, int);
1503 sprintf (intbuf, "%u", (unsigned)-1);
1507 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1508 arg_len = strlen (argp);
1512 char_arg[0] = va_arg (args, int);
1518 programming_error (_("cprintf: `%c': invalid format character"), c);
1523 if (argp && arg_len)
1525 the_printed_command_resize (arg_len + 1);
1526 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1527 command_string_index += arg_len;
1533 the_printed_command[command_string_index] = '\0';
1536 /* Ensure that there is enough space to stuff LENGTH characters into
1537 THE_PRINTED_COMMAND. */
1539 the_printed_command_resize (length)
1542 if (the_printed_command == 0)
1544 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1545 the_printed_command = (char *)xmalloc (the_printed_command_size);
1546 command_string_index = 0;
1548 else if ((command_string_index + length) >= the_printed_command_size)
1551 new = command_string_index + length + 1;
1553 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1554 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1555 the_printed_command_size = new;
1557 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1561 #if defined (HAVE_VPRINTF)
1562 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1563 also available.'' */
1566 #if defined (PREFER_STDARG)
1567 xprintf (const char *format, ...)
1569 xprintf (format, va_alist)
1576 SH_VA_START (args, format);
1578 vfprintf (stdout, format, args);
1585 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1588 printf (format, arg1, arg2, arg3, arg4, arg5);
1591 #endif /* !HAVE_VPRINTF */