1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2023 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>
37 #define NEED_XTRACE_SET_DECL
41 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
46 #include "builtins/common.h"
49 extern int printf (const char *, ...); /* Yuck. Double yuck. */
52 static int indentation
;
53 static int indentation_amount
= 4;
55 typedef void PFUNC (const char *, ...);
57 static void cprintf (const char *, ...) __attribute__((__format__ (printf
, 1, 2)));
58 static void xprintf (const char *, ...) __attribute__((__format__ (printf
, 1, 2)));
60 static void uw_reset_locals (void *);
62 static void newline (char *);
63 static void indent (int);
64 static void semicolon (void);
65 static void the_printed_command_resize (size_t);
67 static void make_command_string_internal (COMMAND
*);
68 static void _print_word_list (WORD_LIST
*, char *, PFUNC
*);
69 static void command_print_word_list (WORD_LIST
*, char *);
70 static void print_case_clauses (PATTERN_LIST
*);
71 static void print_redirection_list (REDIRECT
*);
72 static void print_redirection (REDIRECT
*);
73 static void print_heredoc_header (REDIRECT
*);
74 static void print_heredoc_body (REDIRECT
*);
75 static void print_heredocs (REDIRECT
*);
76 static void print_heredoc_bodies (REDIRECT
*);
77 static void print_deferred_heredocs (const char *);
79 static void print_for_command (FOR_COM
*);
80 #if defined (ARITH_FOR_COMMAND)
81 static void print_arith_for_command (ARITH_FOR_COM
*);
83 #if defined (SELECT_COMMAND)
84 static void print_select_command (SELECT_COM
*);
86 static void print_group_command (GROUP_COM
*);
87 static void print_case_command (CASE_COM
*);
88 static void print_while_command (WHILE_COM
*);
89 static void print_until_command (WHILE_COM
*);
90 static void print_until_or_while (WHILE_COM
*, char *);
91 static void print_if_command (IF_COM
*);
92 #if defined (COND_COMMAND)
93 static void print_cond_node (COND_COM
*);
95 static void print_function_def (FUNCTION_DEF
*);
98 void debug_print_word_list (char *, WORD_LIST
*, char *);
99 void debug_print_cond_command (COND_COM
*);
102 #define PRINTED_COMMAND_INITIAL_SIZE 64
103 #define PRINTED_COMMAND_GROW_SIZE 128
105 char *the_printed_command
= (char *)NULL
;
106 size_t the_printed_command_size
= 0;
107 int command_string_index
= 0;
112 #define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
114 /* shell expansion characters: used in print_redirection_list */
115 #define EXPCHAR(c) ((c) == '{' || (c) == '~' || (c) == '$' || (c) == '`')
117 #define PRINT_DEFERRED_HEREDOCS(x) \
119 if (deferred_heredocs) \
120 print_deferred_heredocs (x); \
123 /* Non-zero means the stuff being printed is inside of a function def. */
124 static int inside_function_def
;
125 static int skip_this_indent
;
126 static int was_heredoc
;
127 static int printing_connection
;
128 static int printing_comsub
;
129 static REDIRECT
*deferred_heredocs
;
131 /* The depth of the group commands that we are currently printing. This
132 includes the group command that is a function body. */
133 static int group_command_nesting
;
135 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
136 static char *indirection_string
= 0;
137 static size_t indirection_stringsiz
= 0;
139 /* Print COMMAND (a command tree) on standard output. */
141 print_command (COMMAND
*command
)
143 command_string_index
= 0;
144 printf ("%s", make_command_string (command
));
147 /* Make a string which is the printed representation of the command
148 tree in COMMAND. We return this string. However, the string is
149 not consed, so you have to do that yourself if you want it to
152 make_command_string (COMMAND
*command
)
154 command_string_index
= was_heredoc
= 0;
155 deferred_heredocs
= 0;
156 make_command_string_internal (command
);
157 return (the_printed_command
);
160 /* Print a command substitution after parsing it in parse_comsub to turn it
161 back into an external representation without turning newlines into `;'.
162 Placeholder for other changes, if any are necessary. */
164 print_comsub (COMMAND
*command
)
169 ret
= make_command_string (command
);
174 /* The internal function. This is the real workhorse. */
176 make_command_string_internal (COMMAND
*command
)
184 if (skip_this_indent
)
187 indent (indentation
);
189 if (command
->flags
& CMD_TIME_PIPELINE
)
192 if (command
->flags
& CMD_TIME_POSIX
)
196 if (command
->flags
& CMD_INVERT_RETURN
)
199 switch (command
->type
)
202 print_for_command (command
->value
.For
);
205 #if defined (ARITH_FOR_COMMAND)
207 print_arith_for_command (command
->value
.ArithFor
);
211 #if defined (SELECT_COMMAND)
213 print_select_command (command
->value
.Select
);
218 print_case_command (command
->value
.Case
);
222 print_while_command (command
->value
.While
);
226 print_until_command (command
->value
.While
);
230 print_if_command (command
->value
.If
);
233 #if defined (DPAREN_ARITHMETIC)
235 print_arith_command (command
->value
.Arith
->exp
);
239 #if defined (COND_COMMAND)
241 print_cond_command (command
->value
.Cond
);
246 print_simple_command (command
->value
.Simple
);
252 printing_connection
++;
253 make_command_string_internal (command
->value
.Connection
->first
);
255 switch (command
->value
.Connection
->connector
)
260 char c
= command
->value
.Connection
->connector
;
266 print_deferred_heredocs (s
);
268 if (c
!= '&' || command
->value
.Connection
->second
)
277 print_deferred_heredocs (" && ");
278 if (command
->value
.Connection
->second
)
283 print_deferred_heredocs (" || ");
284 if (command
->value
.Connection
->second
)
289 case '\n': /* special case this */
291 char c
= command
->value
.Connection
->connector
;
294 s
[0] = printing_comsub
? c
: ';';
297 was_newline
= deferred_heredocs
== 0 && was_heredoc
== 0 && c
== '\n';
298 if (deferred_heredocs
== 0)
300 if (was_heredoc
== 0)
301 cprintf ("%s", s
); /* inside_function_def? */
306 /* print_deferred_heredocs special-cases `;' */
307 print_deferred_heredocs (inside_function_def
? "" : ";");
309 if (inside_function_def
)
311 else if (printing_comsub
&& c
== '\n' && was_newline
== 0)
312 cprintf ("\n"); /* preserve newlines in comsubs but don't double them */
317 if (command
->value
.Connection
->second
)
324 cprintf (_("print_command: bad connector `%d'"),
325 command
->value
.Connection
->connector
);
329 make_command_string_internal (command
->value
.Connection
->second
);
330 /* If this is a recursive call to make_command_string_internal to
331 print a connection with more than two components, defer printing
332 the here-document bodies until our caller can print the
333 connector. Remember that the parser builds lists to be left-side
335 if (printing_connection
== 1)
336 PRINT_DEFERRED_HEREDOCS ("");
337 printing_connection
--;
340 case cm_function_def
:
341 print_function_def (command
->value
.Function_def
);
345 print_group_command (command
->value
.Group
);
351 make_command_string_internal (command
->value
.Subshell
->command
);
352 PRINT_DEFERRED_HEREDOCS ("");
354 was_heredoc
= 0; /* last wasn't heredoc/newline */
358 cprintf ("coproc %s ", command
->value
.Coproc
->name
);
360 make_command_string_internal (command
->value
.Coproc
->command
);
364 command_error ("print_command", CMDERR_BADTYPE
, command
->type
, 0);
369 if (command
->redirects
)
372 print_redirection_list (command
->redirects
);
378 _print_word_list (WORD_LIST
*list
, char *separator
, PFUNC
*pfunc
)
382 for (w
= list
; w
; w
= w
->next
)
383 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
387 print_word_list (WORD_LIST
*list
, char *separator
)
389 _print_word_list (list
, separator
, xprintf
);
393 xtrace_set (int fd
, FILE *fp
)
395 if (fd
>= 0 && sh_validfd (fd
) == 0)
397 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd
);
402 internal_error (_("xtrace_set: NULL file pointer"));
405 if (fd
>= 0 && fileno (fp
) != fd
)
406 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd
, fileno (fp
));
415 xtrace_set (-1, stderr
);
421 if (xtrace_fd
>= 0 && xtrace_fp
)
426 else if (xtrace_fd
>= 0)
434 xtrace_fdchk (int fd
)
440 /* Return a string denoting what our indirection level is. */
443 indirection_level_string (void)
447 char ps4_firstc
[MB_LEN_MAX
+1];
448 size_t ps4_firstc_len
, ps4_len
, ineed
;
452 ps4
= get_string_value ("PS4");
453 if (indirection_string
== 0)
454 indirection_string
= xmalloc (indirection_stringsiz
= 100);
455 indirection_string
[0] = '\0';
457 if (ps4
== 0 || *ps4
== '\0')
458 return (indirection_string
);
460 old
= change_flag ('x', FLAG_OFF
);
461 ps4
= decode_prompt_string (ps4
);
463 change_flag ('x', FLAG_ON
);
465 if (ps4
== 0 || *ps4
== '\0')
468 return (indirection_string
);
471 #if defined (HANDLE_MULTIBYTE)
472 ps4_len
= strnlen (ps4
, MB_CUR_MAX
);
473 ps4_firstc_len
= MBRLEN (ps4
, ps4_len
, &state
);
474 if (ps4_firstc_len
== 1 || ps4_firstc_len
== 0 || ps4_firstc_len
< 0)
476 ps4_firstc
[0] = ps4
[0];
477 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
480 memcpy (ps4_firstc
, ps4
, ps4_firstc_len
);
482 ps4_firstc
[0] = ps4
[0];
483 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
486 /* Dynamically resize indirection_string so we have room for everything
487 and we don't have to truncate ps4 */
488 ineed
= (ps4_firstc_len
* indirection_level
) + strlen (ps4
);
489 if (ineed
+ 1 > indirection_stringsiz
)
491 indirection_stringsiz
= ineed
+ 1;
492 indirection_string
= xrealloc (indirection_string
, indirection_stringsiz
);
495 for (i
= j
= 0; ps4_firstc
[0] && j
< indirection_level
&& i
< indirection_stringsiz
- 1; i
+= ps4_firstc_len
, j
++)
497 if (ps4_firstc_len
== 1)
498 indirection_string
[i
] = ps4_firstc
[0];
500 memcpy (indirection_string
+i
, ps4_firstc
, ps4_firstc_len
);
503 for (j
= ps4_firstc_len
; *ps4
&& ps4
[j
] && i
< indirection_stringsiz
- 1; i
++, j
++)
504 indirection_string
[i
] = ps4
[j
];
506 indirection_string
[i
] = '\0';
508 return (indirection_string
);
512 xtrace_print_assignment (char *name
, char *value
, int assign_list
, int xflags
)
519 fprintf (xtrace_fp
, "%s", indirection_level_string ());
521 /* VALUE should not be NULL when this is called. */
522 if (*value
== '\0' || assign_list
)
524 else if (ansic_shouldquote (value
))
525 nval
= ansic_quote (value
, 0, (int *)0);
526 else if (sh_contains_shell_metas (value
))
527 nval
= sh_single_quote (value
);
532 fprintf (xtrace_fp
, "%s=(%s)\n", name
, nval
);
534 fprintf (xtrace_fp
, "%s=%s\n", name
, nval
);
542 /* A function to print the words of a simple command when set -x is on. Also used to
543 print the word list in a for or select command header; in that case, we suppress
544 quoting the words because they haven't been expanded yet. XTFLAGS&1 means to
545 print $PS4; XTFLAGS&2 means to suppress quoting the words in LIST. */
547 xtrace_print_word_list (WORD_LIST
*list
, int xtflags
)
555 fprintf (xtrace_fp
, "%s", indirection_level_string ());
557 for (w
= list
; w
; w
= w
->next
)
560 if (t
== 0 || *t
== '\0')
561 fprintf (xtrace_fp
, "''%s", w
->next
? " " : "");
562 else if (xtflags
& 2)
563 fprintf (xtrace_fp
, "%s%s", t
, w
->next
? " " : "");
564 else if (ansic_shouldquote (t
))
566 x
= ansic_quote (t
, 0, (int *)0);
567 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
570 else if (sh_contains_shell_metas (t
))
572 x
= sh_single_quote (t
);
573 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
577 fprintf (xtrace_fp
, "%s%s", t
, w
->next
? " " : "");
579 fprintf (xtrace_fp
, "\n");
584 command_print_word_list (WORD_LIST
*list
, char *separator
)
586 _print_word_list (list
, separator
, cprintf
);
590 print_for_command_head (FOR_COM
*for_command
)
592 cprintf ("for %s in ", for_command
->name
->word
);
593 command_print_word_list (for_command
->map_list
, " ");
597 xtrace_print_for_command_head (FOR_COM
*for_command
)
600 fprintf (xtrace_fp
, "%s", indirection_level_string ());
601 fprintf (xtrace_fp
, "for %s in ", for_command
->name
->word
);
602 xtrace_print_word_list (for_command
->map_list
, 2);
606 print_for_command (FOR_COM
*for_command
)
608 print_for_command_head (for_command
);
612 indentation
+= indentation_amount
;
613 make_command_string_internal (for_command
->action
);
614 PRINT_DEFERRED_HEREDOCS ("");
616 indentation
-= indentation_amount
;
621 #if defined (ARITH_FOR_COMMAND)
623 print_arith_for_command (ARITH_FOR_COM
*arith_for_command
)
626 command_print_word_list (arith_for_command
->init
, " ");
628 command_print_word_list (arith_for_command
->test
, " ");
630 command_print_word_list (arith_for_command
->step
, " ");
633 indentation
+= indentation_amount
;
634 make_command_string_internal (arith_for_command
->action
);
635 PRINT_DEFERRED_HEREDOCS ("");
637 indentation
-= indentation_amount
;
640 #endif /* ARITH_FOR_COMMAND */
642 #if defined (SELECT_COMMAND)
644 print_select_command_head (SELECT_COM
*select_command
)
646 cprintf ("select %s in ", select_command
->name
->word
);
647 command_print_word_list (select_command
->map_list
, " ");
651 xtrace_print_select_command_head (SELECT_COM
*select_command
)
654 fprintf (xtrace_fp
, "%s", indirection_level_string ());
655 fprintf (xtrace_fp
, "select %s in ", select_command
->name
->word
);
656 xtrace_print_word_list (select_command
->map_list
, 2);
660 print_select_command (SELECT_COM
*select_command
)
662 print_select_command_head (select_command
);
666 indentation
+= indentation_amount
;
667 make_command_string_internal (select_command
->action
);
668 PRINT_DEFERRED_HEREDOCS ("");
670 indentation
-= indentation_amount
;
673 #endif /* SELECT_COMMAND */
676 print_group_command (GROUP_COM
*group_command
)
678 group_command_nesting
++;
681 if (inside_function_def
== 0 /* && pretty_print_mode == 0 */)
685 /* This is a group command { ... } inside of a function
686 definition, and should be printed as a multiline group
687 command, using the current indentation. */
689 indentation
+= indentation_amount
;
692 make_command_string_internal (group_command
->command
);
693 PRINT_DEFERRED_HEREDOCS ("");
695 if (inside_function_def
/* || pretty_print_mode */)
698 indentation
-= indentation_amount
;
699 indent (indentation
);
708 was_heredoc
= 0; /* last wasn't heredoc/newline */
710 group_command_nesting
--;
714 print_case_command_head (CASE_COM
*case_command
)
716 cprintf ("case %s in ", case_command
->word
->word
);
720 xtrace_print_case_command_head (CASE_COM
*case_command
)
723 fprintf (xtrace_fp
, "%s", indirection_level_string ());
724 fprintf (xtrace_fp
, "case %s in\n", case_command
->word
->word
);
728 print_case_command (CASE_COM
*case_command
)
730 print_case_command_head (case_command
);
732 if (case_command
->clauses
)
733 print_case_clauses (case_command
->clauses
);
738 print_case_clauses (PATTERN_LIST
*clauses
)
740 indentation
+= indentation_amount
;
744 command_print_word_list (clauses
->patterns
, " | ");
746 indentation
+= indentation_amount
;
747 make_command_string_internal (clauses
->action
);
748 indentation
-= indentation_amount
;
749 PRINT_DEFERRED_HEREDOCS ("");
750 if (clauses
->flags
& CASEPAT_FALLTHROUGH
)
752 else if (clauses
->flags
& CASEPAT_TESTNEXT
)
756 clauses
= clauses
->next
;
758 indentation
-= indentation_amount
;
762 print_while_command (WHILE_COM
*while_command
)
764 print_until_or_while (while_command
, "while");
768 print_until_command (WHILE_COM
*while_command
)
770 print_until_or_while (while_command
, "until");
774 print_until_or_while (WHILE_COM
*while_command
, char *which
)
776 cprintf ("%s ", which
);
778 make_command_string_internal (while_command
->test
);
779 PRINT_DEFERRED_HEREDOCS ("");
783 indent (indentation
);
788 cprintf (" do\n"); /* was newline ("do\n"); */
789 indentation
+= indentation_amount
;
790 make_command_string_internal (while_command
->action
);
791 PRINT_DEFERRED_HEREDOCS ("");
792 indentation
-= indentation_amount
;
798 print_if_command (IF_COM
*if_command
)
802 make_command_string_internal (if_command
->test
);
803 PRINT_DEFERRED_HEREDOCS ("");
807 indent (indentation_amount
);
813 indentation
+= indentation_amount
;
814 make_command_string_internal (if_command
->true_case
);
815 PRINT_DEFERRED_HEREDOCS ("");
816 indentation
-= indentation_amount
;
818 if (if_command
->false_case
)
822 indentation
+= indentation_amount
;
823 make_command_string_internal (if_command
->false_case
);
824 PRINT_DEFERRED_HEREDOCS ("");
825 indentation
-= indentation_amount
;
831 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
833 print_arith_command (WORD_LIST
*arith_cmd_list
)
836 command_print_word_list (arith_cmd_list
, " ");
841 #if defined (COND_COMMAND)
843 print_cond_node (COND_COM
*cond
)
845 if (cond
->flags
& CMD_INVERT_RETURN
)
848 if (cond
->type
== COND_EXPR
)
851 print_cond_node (cond
->left
);
854 else if (cond
->type
== COND_AND
)
856 print_cond_node (cond
->left
);
858 print_cond_node (cond
->right
);
860 else if (cond
->type
== COND_OR
)
862 print_cond_node (cond
->left
);
864 print_cond_node (cond
->right
);
866 else if (cond
->type
== COND_UNARY
)
868 cprintf ("%s", cond
->op
->word
);
870 print_cond_node (cond
->left
);
872 else if (cond
->type
== COND_BINARY
)
874 print_cond_node (cond
->left
);
876 cprintf ("%s", cond
->op
->word
);
878 print_cond_node (cond
->right
);
880 else if (cond
->type
== COND_TERM
)
882 cprintf ("%s", cond
->op
->word
); /* need to add quoting here */
887 print_cond_command (COND_COM
*cond
)
890 print_cond_node (cond
);
896 debug_print_word_list (char *s
, WORD_LIST
*list
, char *sep
)
901 fprintf (stderr
, "%s: ", s
);
902 for (w
= list
; w
; w
= w
->next
)
903 fprintf (stderr
, "%s%s", w
->word
->word
, w
->next
? sep
: "");
904 fprintf (stderr
, "\n");
908 debug_print_cond_command (COND_COM
*cond
)
910 fprintf (stderr
, "DEBUG: ");
911 command_string_index
= 0;
912 print_cond_command (cond
);
913 fprintf (stderr
, "%s\n", the_printed_command
);
918 xtrace_print_cond_term (int type
, int invert
, WORD_DESC
*op
, char *arg1
, char *arg2
)
921 command_string_index
= 0;
922 fprintf (xtrace_fp
, "%s", indirection_level_string ());
923 fprintf (xtrace_fp
, "[[ ");
925 fprintf (xtrace_fp
, "! ");
927 if (type
== COND_UNARY
)
929 fprintf (xtrace_fp
, "%s ", op
->word
);
930 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
932 else if (type
== COND_BINARY
)
934 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
935 fprintf (xtrace_fp
, " %s ", op
->word
);
936 fprintf (xtrace_fp
, "%s", (arg2
&& *arg2
) ? arg2
: "''");
939 fprintf (xtrace_fp
, " ]]\n");
943 #endif /* COND_COMMAND */
945 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
946 /* A function to print the words of an arithmetic command when set -x is on. */
948 xtrace_print_arith_cmd (WORD_LIST
*list
)
953 fprintf (xtrace_fp
, "%s", indirection_level_string ());
954 fprintf (xtrace_fp
, "(( ");
955 for (w
= list
; w
; w
= w
->next
)
956 fprintf (xtrace_fp
, "%s%s", w
->word
->word
, w
->next
? " " : "");
957 fprintf (xtrace_fp
, " ))\n");
964 print_simple_command (SIMPLE_COM
*simple_command
)
966 if (simple_command
->words
)
967 command_print_word_list (simple_command
->words
, " ");
971 if (simple_command
->redirects
)
973 if (simple_command
->words
)
975 print_redirection_list (simple_command
->redirects
);
980 print_heredocs (REDIRECT
*heredocs
)
985 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
987 print_redirection (hdtail
);
994 print_heredoc_bodies (REDIRECT
*heredocs
)
999 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
1001 print_heredoc_body (hdtail
);
1007 /* Print heredocs that are attached to the command before the connector
1008 represented by CSTRING. The parsing semantics require us to print the
1009 here-doc delimiters, then the connector (CSTRING), then the here-doc
1010 bodies. We print the here-doc delimiters in print_redirection_list
1011 and print the connector and the bodies here. We don't print the connector
1012 if it's a `;', but we use it to note not to print an extra space after the
1013 last heredoc body and newline. */
1015 print_deferred_heredocs (const char *cstring
)
1017 /* We now print the heredoc headers in print_redirection_list */
1018 if (cstring
&& cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
1019 cprintf ("%s", cstring
);
1020 if (deferred_heredocs
)
1022 print_heredoc_bodies (deferred_heredocs
);
1023 if (cstring
&& cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
1024 cprintf (" "); /* make sure there's at least one space */
1025 dispose_redirects (deferred_heredocs
);
1028 deferred_heredocs
= (REDIRECT
*)NULL
;
1032 print_redirection_list (REDIRECT
*redirects
)
1034 REDIRECT
*heredocs
, *hdtail
, *newredir
;
1036 heredocs
= (REDIRECT
*)NULL
;
1042 /* Defer printing the here document bodies until we've printed the rest of the
1043 redirections, but print the headers in the order they're given. */
1044 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
1046 newredir
= copy_redirect (redirects
);
1047 newredir
->next
= (REDIRECT
*)NULL
;
1049 print_heredoc_header (newredir
);
1053 hdtail
->next
= newredir
;
1057 hdtail
= heredocs
= newredir
;
1060 print_redirection (redirects
);
1062 redirects
= redirects
->next
;
1067 /* Now that we've printed all the other redirections (on one line),
1068 print the here documents. If we're printing a connection, we wait until
1069 we print the connector symbol, then we print the here document bodies */
1070 if (heredocs
&& printing_connection
)
1071 deferred_heredocs
= heredocs
;
1074 print_heredoc_bodies (heredocs
);
1075 dispose_redirects (heredocs
);
1080 print_heredoc_header (REDIRECT
*redirect
)
1085 kill_leading
= redirect
->instruction
== r_deblank_reading_until
;
1087 /* Here doc header */
1088 if (redirect
->rflags
& REDIR_VARASSIGN
)
1089 cprintf ("{%s}", redirect
->redirector
.filename
->word
);
1090 else if (redirect
->redirector
.dest
!= 0)
1091 cprintf ("%d", redirect
->redirector
.dest
);
1093 /* If the here document delimiter is quoted, single-quote it. */
1094 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
1096 x
= sh_single_quote (redirect
->here_doc_eof
);
1097 cprintf ("<<%s%s", kill_leading
? "-" : "", x
);
1101 cprintf ("<<%s%s", kill_leading
? "-" : "", redirect
->here_doc_eof
);
1105 print_heredoc_body (REDIRECT
*redirect
)
1108 cprintf ("%s%s", redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
1112 print_redirection (REDIRECT
*redirect
)
1114 int redirector
, redir_fd
;
1115 WORD_DESC
*redirectee
, *redir_word
;
1117 redirectee
= redirect
->redirectee
.filename
;
1118 redir_fd
= redirect
->redirectee
.dest
;
1120 redir_word
= redirect
->redirector
.filename
;
1121 redirector
= redirect
->redirector
.dest
;
1123 switch (redirect
->instruction
)
1125 case r_input_direction
:
1126 if (redirect
->rflags
& REDIR_VARASSIGN
)
1127 cprintf ("{%s}", redir_word
->word
);
1128 else if (redirector
!= 0)
1129 cprintf ("%d", redirector
);
1130 cprintf ("< %s", redirectee
->word
);
1133 case r_output_direction
:
1134 if (redirect
->rflags
& REDIR_VARASSIGN
)
1135 cprintf ("{%s}", redir_word
->word
);
1136 else if (redirector
!= 1)
1137 cprintf ("%d", redirector
);
1138 cprintf ("> %s", redirectee
->word
);
1141 case r_inputa_direction
: /* Redirection created by the shell. */
1145 case r_output_force
:
1146 if (redirect
->rflags
& REDIR_VARASSIGN
)
1147 cprintf ("{%s}", redir_word
->word
);
1148 else if (redirector
!= 1)
1149 cprintf ("%d", redirector
);
1150 cprintf (">| %s", redirectee
->word
);
1153 case r_appending_to
:
1154 if (redirect
->rflags
& REDIR_VARASSIGN
)
1155 cprintf ("{%s}", redir_word
->word
);
1156 else if (redirector
!= 1)
1157 cprintf ("%d", redirector
);
1158 cprintf (">> %s", redirectee
->word
);
1161 case r_input_output
:
1162 if (redirect
->rflags
& REDIR_VARASSIGN
)
1163 cprintf ("{%s}", redir_word
->word
);
1164 else if (redirector
!= 1)
1165 cprintf ("%d", redirector
);
1166 cprintf ("<> %s", redirectee
->word
);
1169 case r_deblank_reading_until
:
1170 case r_reading_until
:
1171 print_heredoc_header (redirect
);
1173 print_heredoc_body (redirect
);
1176 case r_reading_string
:
1177 if (redirect
->rflags
& REDIR_VARASSIGN
)
1178 cprintf ("{%s}", redir_word
->word
);
1179 else if (redirector
!= 0)
1180 cprintf ("%d", redirector
);
1182 /* Don't need to check whether or not to requote, since original quotes
1183 are still intact. The only thing that has happened is that $'...'
1184 has been replaced with 'expanded ...'. */
1185 if (ansic_shouldquote (redirect
->redirectee
.filename
->word
))
1188 x
= ansic_quote (redirect
->redirectee
.filename
->word
, 0, (int *)0);
1189 cprintf ("<<< %s", x
);
1194 cprintf ("<<< %s", redirect
->redirectee
.filename
->word
);
1197 case r_duplicating_input
:
1198 if (redirect
->rflags
& REDIR_VARASSIGN
)
1199 cprintf ("{%s}<&%d", redir_word
->word
, redir_fd
);
1201 cprintf ("%d<&%d", redirector
, redir_fd
);
1204 case r_duplicating_output
:
1205 if (redirect
->rflags
& REDIR_VARASSIGN
)
1206 cprintf ("{%s}>&%d", redir_word
->word
, redir_fd
);
1208 cprintf ("%d>&%d", redirector
, redir_fd
);
1211 case r_duplicating_input_word
:
1212 if (redirect
->rflags
& REDIR_VARASSIGN
)
1213 cprintf ("{%s}<&%s", redir_word
->word
, redirectee
->word
);
1214 else if (redirector
== 0)
1215 cprintf ("<&%s", redirectee
->word
);
1217 cprintf ("%d<&%s", redirector
, redirectee
->word
);
1220 case r_duplicating_output_word
:
1221 if (redirect
->rflags
& REDIR_VARASSIGN
)
1222 cprintf ("{%s}>&%s", redir_word
->word
, redirectee
->word
);
1223 else if (redirector
== 1)
1224 cprintf (">&%s", redirectee
->word
);
1226 cprintf ("%d>&%s", redirector
, redirectee
->word
);
1230 if (redirect
->rflags
& REDIR_VARASSIGN
)
1231 cprintf ("{%s}<&%d-", redir_word
->word
, redir_fd
);
1233 cprintf ("%d<&%d-", redirector
, redir_fd
);
1237 if (redirect
->rflags
& REDIR_VARASSIGN
)
1238 cprintf ("{%s}>&%d-", redir_word
->word
, redir_fd
);
1240 cprintf ("%d>&%d-", redirector
, redir_fd
);
1243 case r_move_input_word
:
1244 if (redirect
->rflags
& REDIR_VARASSIGN
)
1245 cprintf ("{%s}<&%s-", redir_word
->word
, redirectee
->word
);
1247 cprintf ("%d<&%s-", redirector
, redirectee
->word
);
1250 case r_move_output_word
:
1251 if (redirect
->rflags
& REDIR_VARASSIGN
)
1252 cprintf ("{%s}>&%s-", redir_word
->word
, redirectee
->word
);
1254 cprintf ("%d>&%s-", redirector
, redirectee
->word
);
1258 if (redirect
->rflags
& REDIR_VARASSIGN
)
1259 cprintf ("{%s}>&-", redir_word
->word
);
1261 cprintf ("%d>&-", redirector
);
1265 cprintf ("&> %s", redirectee
->word
);
1268 case r_append_err_and_out
:
1269 cprintf ("&>> %s", redirectee
->word
);
1275 uw_reset_locals (void *ignore
)
1277 inside_function_def
= 0;
1279 printing_connection
= 0;
1280 deferred_heredocs
= 0;
1281 printing_comsub
= 0;
1285 print_function_def (FUNCTION_DEF
*func
)
1288 REDIRECT
*func_redirects
;
1290 func_redirects
= NULL
;
1291 /* When in posix mode, print functions as posix specifies them, but prefix
1292 `function' to words that are not valid POSIX identifiers. */
1293 if (posixly_correct
== 0)
1294 cprintf ("function %s () \n", func
->name
->word
);
1295 else if (valid_function_name (func
->name
->word
, posixly_correct
) == 0)
1296 cprintf ("function %s () \n", func
->name
->word
);
1298 cprintf ("%s () \n", func
->name
->word
);
1300 begin_unwind_frame ("function-def");
1301 add_unwind_protect (uw_reset_locals
, 0);
1303 indent (indentation
);
1304 cprintf ("{ \n"); /* } */
1306 inside_function_def
++;
1307 indentation
+= indentation_amount
;
1309 cmdcopy
= func
->command
;
1310 unwind_protect_pointer (cmdcopy
);
1311 if (cmdcopy
->type
== cm_group
)
1313 func_redirects
= cmdcopy
->redirects
;
1314 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1316 make_command_string_internal (cmdcopy
->type
== cm_group
1317 ? cmdcopy
->value
.Group
->command
1319 PRINT_DEFERRED_HEREDOCS ("");
1321 indentation
-= indentation_amount
;
1322 inside_function_def
--;
1327 print_redirection_list (func_redirects
);
1328 cmdcopy
->redirects
= func_redirects
;
1334 was_heredoc
= 0; /* not printing any here-documents now */
1337 discard_unwind_frame ("function-def");
1340 /* Return the string representation of the named function.
1341 NAME is the name of the function.
1342 COMMAND is the function body. It should be a GROUP_COM.
1343 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1344 flags&FUNC_EXTERNAL means convert from internal to external form
1347 named_function_string (char *name
, COMMAND
*command
, int flags
)
1350 int old_indent
, old_amount
;
1352 REDIRECT
*func_redirects
;
1354 old_indent
= indentation
;
1355 old_amount
= indentation_amount
;
1356 command_string_index
= was_heredoc
= 0;
1357 deferred_heredocs
= 0;
1358 printing_comsub
= 0;
1362 if (valid_function_name (name
, posixly_correct
) == 0)
1363 cprintf ("function ");
1364 cprintf ("%s ", name
);
1369 if ((flags
& FUNC_MULTILINE
) == 0)
1372 indentation_amount
= 0;
1377 indentation
+= indentation_amount
;
1380 inside_function_def
++;
1382 cprintf ((flags
& FUNC_MULTILINE
) ? "{ \n" : "{ "); /* }} */
1385 unwind_protect_pointer (cmdcopy
);
1387 /* Take any redirections specified in the function definition (which should
1388 apply to the function as a whole) and save them for printing later. */
1389 func_redirects
= (REDIRECT
*)NULL
;
1390 if (cmdcopy
->type
== cm_group
)
1392 func_redirects
= cmdcopy
->redirects
;
1393 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1395 make_command_string_internal (cmdcopy
->type
== cm_group
1396 ? cmdcopy
->value
.Group
->command
1398 PRINT_DEFERRED_HEREDOCS ("");
1400 indentation
= old_indent
;
1401 indentation_amount
= old_amount
;
1402 inside_function_def
--;
1407 print_redirection_list (func_redirects
);
1408 cmdcopy
->redirects
= func_redirects
;
1416 remove_unwind_protect (); /* unwind_protect_pointer */
1417 result
= the_printed_command
;
1419 if ((flags
& FUNC_MULTILINE
) == 0)
1421 if (result
[2] == '\n')
1422 memmove (result
+ 2, result
+ 3, strlen (result
) - 2);
1425 if (flags
& FUNC_EXTERNAL
)
1426 result
= remove_quoted_escapes (result
);
1432 newline (char *string
)
1435 indent (indentation
);
1436 if (string
&& *string
)
1437 cprintf ("%s", string
);
1440 static char *indentation_string
;
1441 static size_t indentation_size
;
1448 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
1450 for (i
= 0; amount
> 0; amount
--)
1451 indentation_string
[i
++] = ' ';
1452 indentation_string
[i
] = '\0';
1453 cprintf ("%s", indentation_string
);
1459 if ((command_string_index
> 0 &&
1460 the_printed_command
[command_string_index
- 1] == '\n') ||
1461 (command_string_index
> 1 &&
1462 the_printed_command
[command_string_index
- 1] == '&' &&
1463 the_printed_command
[command_string_index
- 2] == ' '))
1468 /* How to make the string. */
1470 cprintf (const char *control
, ...)
1473 char char_arg
[2], *argp
, intbuf
[INT_STRLEN_BOUND (unsigned int) + 1];
1478 va_start (args
, control
);
1480 arg_len
= strlen (control
);
1481 the_printed_command_resize (arg_len
+ 1);
1488 argp
= (char *)NULL
;
1489 if (c
!= '%' || !*s
)
1507 argp
= va_arg (args
, char *);
1508 arg_len
= strlen (argp
);
1512 /* Represent an out-of-range file descriptor with an out-of-range
1513 integer value. We can do this because the only use of `%d' in
1514 the calls to cprintf is to output a file descriptor number for
1516 digit_arg
= va_arg (args
, int);
1519 sprintf (intbuf
, "%u", (unsigned int)-1);
1523 argp
= inttostr (digit_arg
, intbuf
, sizeof (intbuf
));
1524 arg_len
= strlen (argp
);
1528 char_arg
[0] = va_arg (args
, int);
1534 programming_error (_("cprintf: `%c': invalid format character"), c
);
1539 if (argp
&& arg_len
)
1541 the_printed_command_resize (arg_len
+ 1);
1542 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1543 command_string_index
+= arg_len
;
1549 the_printed_command
[command_string_index
] = '\0';
1552 /* Ensure that there is enough space to stuff LENGTH characters into
1553 THE_PRINTED_COMMAND. */
1555 the_printed_command_resize (size_t length
)
1557 if (the_printed_command
== 0)
1559 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
1560 the_printed_command
= (char *)xmalloc (the_printed_command_size
);
1561 command_string_index
= 0;
1563 else if ((command_string_index
+ length
) >= the_printed_command_size
)
1566 new = command_string_index
+ length
+ 1;
1568 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1569 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
1570 the_printed_command_size
= new;
1572 the_printed_command
= (char *)xrealloc (the_printed_command
, the_printed_command_size
);
1577 xprintf (const char *format
, ...)
1581 va_start (args
, format
);
1583 vfprintf (stdout
, format
, args
);