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 #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 = 0;
135 static int indirection_stringsiz = 0;
137 /* Print COMMAND (a command tree) on standard output. */
139 print_command (command)
142 command_string_index = 0;
143 printf ("%s", make_command_string (command));
146 /* Make a string which is the printed representation of the command
147 tree in COMMAND. We return this string. However, the string is
148 not consed, so you have to do that yourself if you want it to
151 make_command_string (command)
154 command_string_index = was_heredoc = 0;
155 deferred_heredocs = 0;
156 make_command_string_internal (command);
157 return (the_printed_command);
160 /* The internal function. This is the real workhorse. */
162 make_command_string_internal (command)
171 if (skip_this_indent)
174 indent (indentation);
176 if (command->flags & CMD_TIME_PIPELINE)
179 if (command->flags & CMD_TIME_POSIX)
183 if (command->flags & CMD_INVERT_RETURN)
186 switch (command->type)
189 print_for_command (command->value.For);
192 #if defined (ARITH_FOR_COMMAND)
194 print_arith_for_command (command->value.ArithFor);
198 #if defined (SELECT_COMMAND)
200 print_select_command (command->value.Select);
205 print_case_command (command->value.Case);
209 print_while_command (command->value.While);
213 print_until_command (command->value.While);
217 print_if_command (command->value.If);
220 #if defined (DPAREN_ARITHMETIC)
222 print_arith_command (command->value.Arith->exp);
226 #if defined (COND_COMMAND)
228 print_cond_command (command->value.Cond);
233 print_simple_command (command->value.Simple);
239 printing_connection++;
240 make_command_string_internal (command->value.Connection->first);
242 switch (command->value.Connection->connector)
247 char c = command->value.Connection->connector;
253 print_deferred_heredocs (s);
255 if (c != '&' || command->value.Connection->second)
264 print_deferred_heredocs (" && ");
265 if (command->value.Connection->second)
270 print_deferred_heredocs (" || ");
271 if (command->value.Connection->second)
276 if (deferred_heredocs == 0)
278 if (was_heredoc == 0)
284 print_deferred_heredocs (inside_function_def ? "" : ";");
286 if (inside_function_def)
291 if (command->value.Connection->second)
297 cprintf (_("print_command: bad connector `%d'"),
298 command->value.Connection->connector);
302 make_command_string_internal (command->value.Connection->second);
303 PRINT_DEFERRED_HEREDOCS ("");
304 printing_connection--;
307 case cm_function_def:
308 print_function_def (command->value.Function_def);
312 print_group_command (command->value.Group);
318 make_command_string_internal (command->value.Subshell->command);
319 PRINT_DEFERRED_HEREDOCS ("");
324 cprintf ("coproc %s ", command->value.Coproc->name);
326 make_command_string_internal (command->value.Coproc->command);
330 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
335 if (command->redirects)
338 print_redirection_list (command->redirects);
344 _print_word_list (list, separator, pfunc)
351 for (w = list; w; w = w->next)
352 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
356 print_word_list (list, separator)
360 _print_word_list (list, separator, xprintf);
368 if (fd >= 0 && sh_validfd (fd) == 0)
370 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
375 internal_error (_("xtrace_set: NULL file pointer"));
378 if (fd >= 0 && fileno (fp) != fd)
379 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
388 xtrace_set (-1, stderr);
394 if (xtrace_fd >= 0 && xtrace_fp)
399 else if (xtrace_fd >= 0)
414 /* Return a string denoting what our indirection level is. */
417 indirection_level_string ()
421 char ps4_firstc[MB_LEN_MAX+1];
422 int ps4_firstc_len, ps4_len, ineed, old;
424 ps4 = get_string_value ("PS4");
425 if (indirection_string == 0)
426 indirection_string = xmalloc (indirection_stringsiz = 100);
427 indirection_string[0] = '\0';
429 if (ps4 == 0 || *ps4 == '\0')
430 return (indirection_string);
432 old = change_flag ('x', FLAG_OFF);
433 ps4 = decode_prompt_string (ps4);
435 change_flag ('x', FLAG_ON);
437 if (ps4 == 0 || *ps4 == '\0')
438 return (indirection_string);
440 #if defined (HANDLE_MULTIBYTE)
441 ps4_len = strnlen (ps4, MB_CUR_MAX);
442 ps4_firstc_len = MBLEN (ps4, ps4_len);
443 if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || ps4_firstc_len < 0)
445 ps4_firstc[0] = ps4[0];
446 ps4_firstc[ps4_firstc_len = 1] = '\0';
449 memcpy (ps4_firstc, ps4, ps4_firstc_len);
451 ps4_firstc[0] = ps4[0];
452 ps4_firstc[ps4_firstc_len = 1] = '\0';
455 /* Dynamically resize indirection_string so we have room for everything
456 and we don't have to truncate ps4 */
457 ineed = (ps4_firstc_len * indirection_level) + strlen (ps4);
458 if (ineed > indirection_stringsiz - 1)
460 indirection_stringsiz = ineed + 1;
461 indirection_string = xrealloc (indirection_string, indirection_stringsiz);
464 for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < indirection_stringsiz - 1; i += ps4_firstc_len, j++)
466 if (ps4_firstc_len == 1)
467 indirection_string[i] = ps4_firstc[0];
469 memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
472 for (j = ps4_firstc_len; *ps4 && ps4[j] && i < indirection_stringsiz - 1; i++, j++)
473 indirection_string[i] = ps4[j];
475 indirection_string[i] = '\0';
477 return (indirection_string);
481 xtrace_print_assignment (name, value, assign_list, xflags)
483 int assign_list, xflags;
490 fprintf (xtrace_fp, "%s", indirection_level_string ());
492 /* VALUE should not be NULL when this is called. */
493 if (*value == '\0' || assign_list)
495 else if (sh_contains_shell_metas (value))
496 nval = sh_single_quote (value);
497 else if (ansic_shouldquote (value))
498 nval = ansic_quote (value, 0, (int *)0);
503 fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
505 fprintf (xtrace_fp, "%s=%s\n", name, nval);
513 /* A function to print the words of a simple command when set -x is on. */
515 xtrace_print_word_list (list, xtflags)
525 fprintf (xtrace_fp, "%s", indirection_level_string ());
527 for (w = list; w; w = w->next)
530 if (t == 0 || *t == '\0')
531 fprintf (xtrace_fp, "''%s", w->next ? " " : "");
532 else if (sh_contains_shell_metas (t))
534 x = sh_single_quote (t);
535 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
538 else if (ansic_shouldquote (t))
540 x = ansic_quote (t, 0, (int *)0);
541 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
545 fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
547 fprintf (xtrace_fp, "\n");
552 command_print_word_list (list, separator)
556 _print_word_list (list, separator, cprintf);
560 print_for_command_head (for_command)
561 FOR_COM *for_command;
563 cprintf ("for %s in ", for_command->name->word);
564 command_print_word_list (for_command->map_list, " ");
568 xtrace_print_for_command_head (for_command)
569 FOR_COM *for_command;
572 fprintf (xtrace_fp, "%s", indirection_level_string ());
573 fprintf (xtrace_fp, "for %s in ", for_command->name->word);
574 xtrace_print_word_list (for_command->map_list, 0);
578 print_for_command (for_command)
579 FOR_COM *for_command;
581 print_for_command_head (for_command);
585 indentation += indentation_amount;
586 make_command_string_internal (for_command->action);
587 PRINT_DEFERRED_HEREDOCS ("");
589 indentation -= indentation_amount;
594 #if defined (ARITH_FOR_COMMAND)
596 print_arith_for_command (arith_for_command)
597 ARITH_FOR_COM *arith_for_command;
600 command_print_word_list (arith_for_command->init, " ");
602 command_print_word_list (arith_for_command->test, " ");
604 command_print_word_list (arith_for_command->step, " ");
607 indentation += indentation_amount;
608 make_command_string_internal (arith_for_command->action);
609 PRINT_DEFERRED_HEREDOCS ("");
611 indentation -= indentation_amount;
614 #endif /* ARITH_FOR_COMMAND */
616 #if defined (SELECT_COMMAND)
618 print_select_command_head (select_command)
619 SELECT_COM *select_command;
621 cprintf ("select %s in ", select_command->name->word);
622 command_print_word_list (select_command->map_list, " ");
626 xtrace_print_select_command_head (select_command)
627 SELECT_COM *select_command;
630 fprintf (xtrace_fp, "%s", indirection_level_string ());
631 fprintf (xtrace_fp, "select %s in ", select_command->name->word);
632 xtrace_print_word_list (select_command->map_list, 0);
636 print_select_command (select_command)
637 SELECT_COM *select_command;
639 print_select_command_head (select_command);
643 indentation += indentation_amount;
644 make_command_string_internal (select_command->action);
645 PRINT_DEFERRED_HEREDOCS ("");
647 indentation -= indentation_amount;
650 #endif /* SELECT_COMMAND */
653 print_group_command (group_command)
654 GROUP_COM *group_command;
656 group_command_nesting++;
659 if (inside_function_def == 0)
663 /* This is a group command { ... } inside of a function
664 definition, and should be printed as a multiline group
665 command, using the current indentation. */
667 indentation += indentation_amount;
670 make_command_string_internal (group_command->command);
671 PRINT_DEFERRED_HEREDOCS ("");
673 if (inside_function_def)
676 indentation -= indentation_amount;
677 indent (indentation);
687 group_command_nesting--;
691 print_case_command_head (case_command)
692 CASE_COM *case_command;
694 cprintf ("case %s in ", case_command->word->word);
698 xtrace_print_case_command_head (case_command)
699 CASE_COM *case_command;
702 fprintf (xtrace_fp, "%s", indirection_level_string ());
703 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
707 print_case_command (case_command)
708 CASE_COM *case_command;
710 print_case_command_head (case_command);
712 if (case_command->clauses)
713 print_case_clauses (case_command->clauses);
718 print_case_clauses (clauses)
719 PATTERN_LIST *clauses;
721 indentation += indentation_amount;
725 command_print_word_list (clauses->patterns, " | ");
727 indentation += indentation_amount;
728 make_command_string_internal (clauses->action);
729 indentation -= indentation_amount;
730 PRINT_DEFERRED_HEREDOCS ("");
731 if (clauses->flags & CASEPAT_FALLTHROUGH)
733 else if (clauses->flags & CASEPAT_TESTNEXT)
737 clauses = clauses->next;
739 indentation -= indentation_amount;
743 print_while_command (while_command)
744 WHILE_COM *while_command;
746 print_until_or_while (while_command, "while");
750 print_until_command (while_command)
751 WHILE_COM *while_command;
753 print_until_or_while (while_command, "until");
757 print_until_or_while (while_command, which)
758 WHILE_COM *while_command;
761 cprintf ("%s ", which);
763 make_command_string_internal (while_command->test);
764 PRINT_DEFERRED_HEREDOCS ("");
766 cprintf (" do\n"); /* was newline ("do\n"); */
767 indentation += indentation_amount;
768 make_command_string_internal (while_command->action);
769 PRINT_DEFERRED_HEREDOCS ("");
770 indentation -= indentation_amount;
776 print_if_command (if_command)
781 make_command_string_internal (if_command->test);
784 indentation += indentation_amount;
785 make_command_string_internal (if_command->true_case);
786 PRINT_DEFERRED_HEREDOCS ("");
787 indentation -= indentation_amount;
789 if (if_command->false_case)
793 indentation += indentation_amount;
794 make_command_string_internal (if_command->false_case);
795 PRINT_DEFERRED_HEREDOCS ("");
796 indentation -= indentation_amount;
802 #if defined (DPAREN_ARITHMETIC)
804 print_arith_command (arith_cmd_list)
805 WORD_LIST *arith_cmd_list;
808 command_print_word_list (arith_cmd_list, " ");
813 #if defined (COND_COMMAND)
815 print_cond_node (cond)
818 if (cond->flags & CMD_INVERT_RETURN)
821 if (cond->type == COND_EXPR)
824 print_cond_node (cond->left);
827 else if (cond->type == COND_AND)
829 print_cond_node (cond->left);
831 print_cond_node (cond->right);
833 else if (cond->type == COND_OR)
835 print_cond_node (cond->left);
837 print_cond_node (cond->right);
839 else if (cond->type == COND_UNARY)
841 cprintf ("%s", cond->op->word);
843 print_cond_node (cond->left);
845 else if (cond->type == COND_BINARY)
847 print_cond_node (cond->left);
849 cprintf ("%s", cond->op->word);
851 print_cond_node (cond->right);
853 else if (cond->type == COND_TERM)
855 cprintf ("%s", cond->op->word); /* need to add quoting here */
860 print_cond_command (cond)
864 print_cond_node (cond);
870 debug_print_cond_command (cond)
873 fprintf (stderr, "DEBUG: ");
874 command_string_index = 0;
875 print_cond_command (cond);
876 fprintf (stderr, "%s\n", the_printed_command);
881 xtrace_print_cond_term (type, invert, op, arg1, arg2)
887 command_string_index = 0;
888 fprintf (xtrace_fp, "%s", indirection_level_string ());
889 fprintf (xtrace_fp, "[[ ");
891 fprintf (xtrace_fp, "! ");
893 if (type == COND_UNARY)
895 fprintf (xtrace_fp, "%s ", op->word);
896 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
898 else if (type == COND_BINARY)
900 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
901 fprintf (xtrace_fp, " %s ", op->word);
902 fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
905 fprintf (xtrace_fp, " ]]\n");
909 #endif /* COND_COMMAND */
911 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
912 /* A function to print the words of an arithmetic command when set -x is on. */
914 xtrace_print_arith_cmd (list)
920 fprintf (xtrace_fp, "%s", indirection_level_string ());
921 fprintf (xtrace_fp, "(( ");
922 for (w = list; w; w = w->next)
923 fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
924 fprintf (xtrace_fp, " ))\n");
931 print_simple_command (simple_command)
932 SIMPLE_COM *simple_command;
934 command_print_word_list (simple_command->words, " ");
936 if (simple_command->redirects)
939 print_redirection_list (simple_command->redirects);
944 print_heredocs (heredocs)
950 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
952 print_redirection (hdtail);
958 /* Print heredocs that are attached to the command before the connector
959 represented by CSTRING. The parsing semantics require us to print the
960 here-doc delimiters, then the connector (CSTRING), then the here-doc
961 bodies. We don't print the connector if it's a `;', but we use it to
962 note not to print an extra space after the last heredoc body and
965 print_deferred_heredocs (cstring)
970 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
973 print_heredoc_header (hdtail);
975 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
976 cprintf ("%s", cstring);
977 if (deferred_heredocs)
979 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
981 print_heredoc_body (hdtail);
984 if (deferred_heredocs)
986 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
987 cprintf (" "); /* make sure there's at least one space */
988 dispose_redirects (deferred_heredocs);
991 deferred_heredocs = (REDIRECT *)NULL;
995 print_redirection_list (redirects)
998 REDIRECT *heredocs, *hdtail, *newredir;
1000 heredocs = (REDIRECT *)NULL;
1006 /* Defer printing the here documents until we've printed the
1007 rest of the redirections. */
1008 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
1010 newredir = copy_redirect (redirects);
1011 newredir->next = (REDIRECT *)NULL;
1014 hdtail->next = newredir;
1018 hdtail = heredocs = newredir;
1020 else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
1022 /* Temporarily translate it as the execution code does. */
1023 redirects->instruction = r_err_and_out;
1024 print_redirection (redirects);
1025 redirects->instruction = r_duplicating_output_word;
1028 print_redirection (redirects);
1030 redirects = redirects->next;
1035 /* Now that we've printed all the other redirections (on one line),
1036 print the here documents. */
1037 if (heredocs && printing_connection)
1038 deferred_heredocs = heredocs;
1041 print_heredocs (heredocs);
1042 dispose_redirects (heredocs);
1047 print_heredoc_header (redirect)
1053 kill_leading = redirect->instruction == r_deblank_reading_until;
1055 /* Here doc header */
1056 if (redirect->rflags & REDIR_VARASSIGN)
1057 cprintf ("{%s}", redirect->redirector.filename->word);
1058 else if (redirect->redirector.dest != 0)
1059 cprintf ("%d", redirect->redirector.dest);
1061 /* If the here document delimiter is quoted, single-quote it. */
1062 if (redirect->redirectee.filename->flags & W_QUOTED)
1064 x = sh_single_quote (redirect->here_doc_eof);
1065 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1069 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1073 print_heredoc_body (redirect)
1077 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1081 print_redirection (redirect)
1084 int redirector, redir_fd;
1085 WORD_DESC *redirectee, *redir_word;
1087 redirectee = redirect->redirectee.filename;
1088 redir_fd = redirect->redirectee.dest;
1090 redir_word = redirect->redirector.filename;
1091 redirector = redirect->redirector.dest;
1093 switch (redirect->instruction)
1095 case r_input_direction:
1096 if (redirect->rflags & REDIR_VARASSIGN)
1097 cprintf ("{%s}", redir_word->word);
1098 else if (redirector != 0)
1099 cprintf ("%d", redirector);
1100 cprintf ("< %s", redirectee->word);
1103 case r_output_direction:
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_inputa_direction: /* Redirection created by the shell. */
1115 case r_output_force:
1116 if (redirect->rflags & REDIR_VARASSIGN)
1117 cprintf ("{%s}", redir_word->word);
1118 else if (redirector != 1)
1119 cprintf ("%d", redirector);
1120 cprintf (">|%s", redirectee->word);
1123 case r_appending_to:
1124 if (redirect->rflags & REDIR_VARASSIGN)
1125 cprintf ("{%s}", redir_word->word);
1126 else if (redirector != 1)
1127 cprintf ("%d", redirector);
1128 cprintf (">> %s", redirectee->word);
1131 case r_input_output:
1132 if (redirect->rflags & REDIR_VARASSIGN)
1133 cprintf ("{%s}", redir_word->word);
1134 else if (redirector != 1)
1135 cprintf ("%d", redirector);
1136 cprintf ("<> %s", redirectee->word);
1139 case r_deblank_reading_until:
1140 case r_reading_until:
1141 print_heredoc_header (redirect);
1143 print_heredoc_body (redirect);
1146 case r_reading_string:
1147 if (redirect->rflags & REDIR_VARASSIGN)
1148 cprintf ("{%s}", redir_word->word);
1149 else if (redirector != 0)
1150 cprintf ("%d", redirector);
1152 /* Don't need to check whether or not to requote, since original quotes
1153 are still intact. The only thing that has happened is that $'...'
1154 has been replaced with 'expanded ...'. */
1155 if (ansic_shouldquote (redirect->redirectee.filename->word))
1158 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1159 cprintf ("<<< %s", x);
1164 cprintf ("<<< %s", redirect->redirectee.filename->word);
1167 case r_duplicating_input:
1168 if (redirect->rflags & REDIR_VARASSIGN)
1169 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1171 cprintf ("%d<&%d", redirector, redir_fd);
1174 case r_duplicating_output:
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_duplicating_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_duplicating_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}<&%d-", redir_word->word, redir_fd);
1199 cprintf ("%d<&%d-", redirector, redir_fd);
1203 if (redirect->rflags & REDIR_VARASSIGN)
1204 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1206 cprintf ("%d>&%d-", redirector, redir_fd);
1209 case r_move_input_word:
1210 if (redirect->rflags & REDIR_VARASSIGN)
1211 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1213 cprintf ("%d<&%s-", redirector, redirectee->word);
1216 case r_move_output_word:
1217 if (redirect->rflags & REDIR_VARASSIGN)
1218 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1220 cprintf ("%d>&%s-", redirector, redirectee->word);
1224 if (redirect->rflags & REDIR_VARASSIGN)
1225 cprintf ("{%s}>&-", redir_word->word);
1227 cprintf ("%d>&-", redirector);
1231 cprintf ("&>%s", redirectee->word);
1234 case r_append_err_and_out:
1235 cprintf ("&>>%s", redirectee->word);
1243 inside_function_def = 0;
1245 printing_connection = 0;
1246 deferred_heredocs = 0;
1250 print_function_def (func)
1254 REDIRECT *func_redirects;
1256 func_redirects = NULL;
1257 cprintf ("function %s () \n", func->name->word);
1258 add_unwind_protect (reset_locals, 0);
1260 indent (indentation);
1263 inside_function_def++;
1264 indentation += indentation_amount;
1266 cmdcopy = copy_command (func->command);
1267 if (cmdcopy->type == cm_group)
1269 func_redirects = cmdcopy->redirects;
1270 cmdcopy->redirects = (REDIRECT *)NULL;
1272 make_command_string_internal (cmdcopy->type == cm_group
1273 ? cmdcopy->value.Group->command
1275 /* XXX - PRINT_DEFERRED_HEREDOCS (""); ? */
1277 remove_unwind_protect ();
1278 indentation -= indentation_amount;
1279 inside_function_def--;
1284 print_redirection_list (func_redirects);
1285 cmdcopy->redirects = func_redirects;
1290 dispose_command (cmdcopy);
1293 /* Return the string representation of the named function.
1294 NAME is the name of the function.
1295 COMMAND is the function body. It should be a GROUP_COM.
1296 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1297 flags&FUNC_EXTERNAL means convert from internal to external form
1300 named_function_string (name, command, flags)
1306 int old_indent, old_amount;
1308 REDIRECT *func_redirects;
1310 old_indent = indentation;
1311 old_amount = indentation_amount;
1312 command_string_index = was_heredoc = 0;
1313 deferred_heredocs = 0;
1316 cprintf ("%s ", name);
1320 if ((flags & FUNC_MULTILINE) == 0)
1323 indentation_amount = 0;
1328 indentation += indentation_amount;
1331 inside_function_def++;
1333 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1335 cmdcopy = copy_command (command);
1336 /* Take any redirections specified in the function definition (which should
1337 apply to the function as a whole) and save them for printing later. */
1338 func_redirects = (REDIRECT *)NULL;
1339 if (cmdcopy->type == cm_group)
1341 func_redirects = cmdcopy->redirects;
1342 cmdcopy->redirects = (REDIRECT *)NULL;
1344 make_command_string_internal (cmdcopy->type == cm_group
1345 ? cmdcopy->value.Group->command
1347 /* XXX - PRINT_DEFERRED_HEREDOCS (""); ? */
1349 indentation = old_indent;
1350 indentation_amount = old_amount;
1351 inside_function_def--;
1356 print_redirection_list (func_redirects);
1357 cmdcopy->redirects = func_redirects;
1362 result = the_printed_command;
1364 if ((flags & FUNC_MULTILINE) == 0)
1368 for (i = 0; result[i]; i++)
1369 if (result[i] == '\n')
1371 strcpy (result + i, result + i + 1);
1375 if (result[2] == '\n') /* XXX -- experimental */
1376 memmove (result + 2, result + 3, strlen (result) - 2);
1381 dispose_command (cmdcopy);
1383 if (flags & FUNC_EXTERNAL)
1384 result = remove_quoted_escapes (result);
1394 indent (indentation);
1395 if (string && *string)
1396 cprintf ("%s", string);
1399 static char *indentation_string;
1400 static int indentation_size;
1408 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1410 for (i = 0; amount > 0; amount--)
1411 indentation_string[i++] = ' ';
1412 indentation_string[i] = '\0';
1413 cprintf (indentation_string);
1419 if (command_string_index > 0 &&
1420 (the_printed_command[command_string_index - 1] == '&' ||
1421 the_printed_command[command_string_index - 1] == '\n'))
1426 /* How to make the string. */
1428 #if defined (PREFER_STDARG)
1429 cprintf (const char *control, ...)
1431 cprintf (control, va_alist)
1432 const char *control;
1436 register const char *s;
1437 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1438 int digit_arg, arg_len, c;
1441 SH_VA_START (args, control);
1443 arg_len = strlen (control);
1444 the_printed_command_resize (arg_len + 1);
1451 argp = (char *)NULL;
1452 if (c != '%' || !*s)
1470 argp = va_arg (args, char *);
1471 arg_len = strlen (argp);
1475 /* Represent an out-of-range file descriptor with an out-of-range
1476 integer value. We can do this because the only use of `%d' in
1477 the calls to cprintf is to output a file descriptor number for
1479 digit_arg = va_arg (args, int);
1482 sprintf (intbuf, "%u", (unsigned)-1);
1486 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1487 arg_len = strlen (argp);
1491 char_arg[0] = va_arg (args, int);
1497 programming_error (_("cprintf: `%c': invalid format character"), c);
1502 if (argp && arg_len)
1504 the_printed_command_resize (arg_len + 1);
1505 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1506 command_string_index += arg_len;
1510 the_printed_command[command_string_index] = '\0';
1513 /* Ensure that there is enough space to stuff LENGTH characters into
1514 THE_PRINTED_COMMAND. */
1516 the_printed_command_resize (length)
1519 if (the_printed_command == 0)
1521 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1522 the_printed_command = (char *)xmalloc (the_printed_command_size);
1523 command_string_index = 0;
1525 else if ((command_string_index + length) >= the_printed_command_size)
1528 new = command_string_index + length + 1;
1530 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1531 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1532 the_printed_command_size = new;
1534 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1538 #if defined (HAVE_VPRINTF)
1539 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1540 also available.'' */
1543 #if defined (PREFER_STDARG)
1544 xprintf (const char *format, ...)
1546 xprintf (format, va_alist)
1553 SH_VA_START (args, format);
1555 vfprintf (stdout, format, args);
1562 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1565 printf (format, arg1, arg2, arg3, arg4, arg5);
1568 #endif /* !HAVE_VPRINTF */