1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush 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 Bush 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 Bush. If not, see <http://www.gnu.org/licenses/>.
25 #if defined (HAVE_UNISTD_H)
27 # include <sys/types.h>
32 #if defined (PREFER_STDARG)
41 #define NEED_XTRACE_SET_DECL
45 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
50 #include "builtins/common.h"
53 extern int printf
PARAMS((const char *, ...)); /* Yuck. Double yuck. */
56 static int indentation
;
57 static int indentation_amount
= 4;
59 #if defined (PREFER_STDARG)
60 typedef void PFUNC
PARAMS((const char *, ...));
62 static void cprintf
PARAMS((const char *, ...)) __attribute__((__format__ (printf
, 1, 2)));
63 static void xprintf
PARAMS((const char *, ...)) __attribute__((__format__ (printf
, 1, 2)));
65 #define PFUNC VFunction
66 static void cprintf ();
67 static void xprintf ();
70 static void reset_locals
PARAMS((void));
71 static void newline
PARAMS((char *));
72 static void indent
PARAMS((int));
73 static void semicolon
PARAMS((void));
74 static void the_printed_command_resize
PARAMS((int));
76 static void make_command_string_internal
PARAMS((COMMAND
*));
77 static void _print_word_list
PARAMS((WORD_LIST
*, char *, PFUNC
*));
78 static void command_print_word_list
PARAMS((WORD_LIST
*, char *));
79 static void print_case_clauses
PARAMS((PATTERN_LIST
*));
80 static void print_redirection_list
PARAMS((REDIRECT
*));
81 static void print_redirection
PARAMS((REDIRECT
*));
82 static void print_heredoc_header
PARAMS((REDIRECT
*));
83 static void print_heredoc_body
PARAMS((REDIRECT
*));
84 static void print_heredocs
PARAMS((REDIRECT
*));
85 static void print_heredoc_bodies
PARAMS((REDIRECT
*));
86 static void print_deferred_heredocs
PARAMS((const char *));
88 static void print_for_command
PARAMS((FOR_COM
*));
89 #if defined (ARITH_FOR_COMMAND)
90 static void print_arith_for_command
PARAMS((ARITH_FOR_COM
*));
92 #if defined (SELECT_COMMAND)
93 static void print_select_command
PARAMS((SELECT_COM
*));
95 static void print_group_command
PARAMS((GROUP_COM
*));
96 static void print_case_command
PARAMS((CASE_COM
*));
97 static void print_while_command
PARAMS((WHILE_COM
*));
98 static void print_until_command
PARAMS((WHILE_COM
*));
99 static void print_until_or_while
PARAMS((WHILE_COM
*, char *));
100 static void print_if_command
PARAMS((IF_COM
*));
101 #if defined (COND_COMMAND)
102 static void print_cond_node
PARAMS((COND_COM
*));
104 static void print_function_def
PARAMS((FUNCTION_DEF
*));
106 #define PRINTED_COMMAND_INITIAL_SIZE 64
107 #define PRINTED_COMMAND_GROW_SIZE 128
109 char *the_printed_command
= (char *)NULL
;
110 int the_printed_command_size
= 0;
111 int command_string_index
= 0;
116 #define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
118 /* shell expansion characters: used in print_redirection_list */
119 #define EXPCHAR(c) ((c) == '{' || (c) == '~' || (c) == '$' || (c) == '`')
121 #define PRINT_DEFERRED_HEREDOCS(x) \
123 if (deferred_heredocs) \
124 print_deferred_heredocs (x); \
127 /* Non-zero means the stuff being printed is inside of a function def. */
128 static int inside_function_def
;
129 static int skip_this_indent
;
130 static int was_heredoc
;
131 static int printing_connection
;
132 static REDIRECT
*deferred_heredocs
;
134 /* The depth of the group commands that we are currently printing. This
135 includes the group command that is a function body. */
136 static int group_command_nesting
;
138 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
139 static char *indirection_string
= 0;
140 static int indirection_stringsiz
= 0;
142 /* Print COMMAND (a command tree) on standard output. */
144 print_command (command
)
147 command_string_index
= 0;
148 printf ("%s", make_command_string (command
));
151 /* Make a string which is the printed representation of the command
152 tree in COMMAND. We return this string. However, the string is
153 not consed, so you have to do that yourself if you want it to
156 make_command_string (command
)
159 command_string_index
= was_heredoc
= 0;
160 deferred_heredocs
= 0;
161 make_command_string_internal (command
);
162 return (the_printed_command
);
165 /* The internal function. This is the real workhorse. */
167 make_command_string_internal (command
)
176 if (skip_this_indent
)
179 indent (indentation
);
181 if (command
->flags
& CMD_TIME_PIPELINE
)
184 if (command
->flags
& CMD_TIME_POSIX
)
188 if (command
->flags
& CMD_INVERT_RETURN
)
191 switch (command
->type
)
194 print_for_command (command
->value
.For
);
197 #if defined (ARITH_FOR_COMMAND)
199 print_arith_for_command (command
->value
.ArithFor
);
203 #if defined (SELECT_COMMAND)
205 print_select_command (command
->value
.Select
);
210 print_case_command (command
->value
.Case
);
214 print_while_command (command
->value
.While
);
218 print_until_command (command
->value
.While
);
222 print_if_command (command
->value
.If
);
225 #if defined (DPAREN_ARITHMETIC)
227 print_arith_command (command
->value
.Arith
->exp
);
231 #if defined (COND_COMMAND)
233 print_cond_command (command
->value
.Cond
);
238 print_simple_command (command
->value
.Simple
);
244 printing_connection
++;
245 make_command_string_internal (command
->value
.Connection
->first
);
247 switch (command
->value
.Connection
->connector
)
252 char c
= command
->value
.Connection
->connector
;
258 print_deferred_heredocs (s
);
260 if (c
!= '&' || command
->value
.Connection
->second
)
269 print_deferred_heredocs (" && ");
270 if (command
->value
.Connection
->second
)
275 print_deferred_heredocs (" || ");
276 if (command
->value
.Connection
->second
)
281 if (deferred_heredocs
== 0)
283 if (was_heredoc
== 0)
289 print_deferred_heredocs (inside_function_def
? "" : ";");
291 if (inside_function_def
)
296 if (command
->value
.Connection
->second
)
302 cprintf (_("print_command: bad connector `%d'"),
303 command
->value
.Connection
->connector
);
307 make_command_string_internal (command
->value
.Connection
->second
);
308 PRINT_DEFERRED_HEREDOCS ("");
309 printing_connection
--;
312 case cm_function_def
:
313 print_function_def (command
->value
.Function_def
);
317 print_group_command (command
->value
.Group
);
323 make_command_string_internal (command
->value
.Subshell
->command
);
324 PRINT_DEFERRED_HEREDOCS ("");
329 cprintf ("coproc %s ", command
->value
.Coproc
->name
);
331 make_command_string_internal (command
->value
.Coproc
->command
);
335 command_error ("print_command", CMDERR_BADTYPE
, command
->type
, 0);
340 if (command
->redirects
)
343 print_redirection_list (command
->redirects
);
349 _print_word_list (list
, separator
, pfunc
)
356 for (w
= list
; w
; w
= w
->next
)
357 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
361 print_word_list (list
, separator
)
365 _print_word_list (list
, separator
, xprintf
);
373 if (fd
>= 0 && sh_validfd (fd
) == 0)
375 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd
);
380 internal_error (_("xtrace_set: NULL file pointer"));
383 if (fd
>= 0 && fileno (fp
) != fd
)
384 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd
, fileno (fp
));
393 xtrace_set (-1, stderr
);
399 if (xtrace_fd
>= 0 && xtrace_fp
)
404 else if (xtrace_fd
>= 0)
419 /* Return a string denoting what our indirection level is. */
422 indirection_level_string ()
426 char ps4_firstc
[MB_LEN_MAX
+1];
427 int ps4_firstc_len
, ps4_len
, ineed
, old
;
429 ps4
= get_string_value ("PS4");
430 if (indirection_string
== 0)
431 indirection_string
= xmalloc (indirection_stringsiz
= 100);
432 indirection_string
[0] = '\0';
434 if (ps4
== 0 || *ps4
== '\0')
435 return (indirection_string
);
437 old
= change_flag ('x', FLAG_OFF
);
438 ps4
= decode_prompt_string (ps4
);
440 change_flag ('x', FLAG_ON
);
442 if (ps4
== 0 || *ps4
== '\0')
443 return (indirection_string
);
445 #if defined (HANDLE_MULTIBYTE)
446 ps4_len
= strnlen (ps4
, MB_CUR_MAX
);
447 ps4_firstc_len
= MBLEN (ps4
, ps4_len
);
448 if (ps4_firstc_len
== 1 || ps4_firstc_len
== 0 || ps4_firstc_len
< 0)
450 ps4_firstc
[0] = ps4
[0];
451 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
454 memcpy (ps4_firstc
, ps4
, ps4_firstc_len
);
456 ps4_firstc
[0] = ps4
[0];
457 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
460 /* Dynamically resize indirection_string so we have room for everything
461 and we don't have to truncate ps4 */
462 ineed
= (ps4_firstc_len
* indirection_level
) + strlen (ps4
);
463 if (ineed
> indirection_stringsiz
- 1)
465 indirection_stringsiz
= ineed
+ 1;
466 indirection_string
= xrealloc (indirection_string
, indirection_stringsiz
);
469 for (i
= j
= 0; ps4_firstc
[0] && j
< indirection_level
&& i
< indirection_stringsiz
- 1; i
+= ps4_firstc_len
, j
++)
471 if (ps4_firstc_len
== 1)
472 indirection_string
[i
] = ps4_firstc
[0];
474 memcpy (indirection_string
+i
, ps4_firstc
, ps4_firstc_len
);
477 for (j
= ps4_firstc_len
; *ps4
&& ps4
[j
] && i
< indirection_stringsiz
- 1; i
++, j
++)
478 indirection_string
[i
] = ps4
[j
];
480 indirection_string
[i
] = '\0';
482 return (indirection_string
);
486 xtrace_print_assignment (name
, value
, assign_list
, xflags
)
488 int assign_list
, xflags
;
495 fprintf (xtrace_fp
, "%s", indirection_level_string ());
497 /* VALUE should not be NULL when this is called. */
498 if (*value
== '\0' || assign_list
)
500 else if (sh_contains_shell_metas (value
))
501 nval
= sh_single_quote (value
);
502 else if (ansic_shouldquote (value
))
503 nval
= ansic_quote (value
, 0, (int *)0);
508 fprintf (xtrace_fp
, "%s=(%s)\n", name
, nval
);
510 fprintf (xtrace_fp
, "%s=%s\n", name
, nval
);
518 /* A function to print the words of a simple command when set -x is on. Also used to
519 print the word list in a for or select command header; in that case, we suppress
520 quoting the words because they haven't been expanded yet. XTFLAGS&1 means to
521 print $PS4; XTFLAGS&2 means to suppress quoting the words in LIST. */
523 xtrace_print_word_list (list
, xtflags
)
533 fprintf (xtrace_fp
, "%s", indirection_level_string ());
535 for (w
= list
; w
; w
= w
->next
)
538 if (t
== 0 || *t
== '\0')
539 fprintf (xtrace_fp
, "''%s", w
->next
? " " : "");
540 else if (xtflags
& 2)
541 fprintf (xtrace_fp
, "%s%s", t
, w
->next
? " " : "");
542 else if (sh_contains_shell_metas (t
))
544 x
= sh_single_quote (t
);
545 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
548 else if (ansic_shouldquote (t
))
550 x
= ansic_quote (t
, 0, (int *)0);
551 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
555 fprintf (xtrace_fp
, "%s%s", t
, w
->next
? " " : "");
557 fprintf (xtrace_fp
, "\n");
562 command_print_word_list (list
, separator
)
566 _print_word_list (list
, separator
, cprintf
);
570 print_for_command_head (for_command
)
571 FOR_COM
*for_command
;
573 cprintf ("for %s in ", for_command
->name
->word
);
574 command_print_word_list (for_command
->map_list
, " ");
578 xtrace_print_for_command_head (for_command
)
579 FOR_COM
*for_command
;
582 fprintf (xtrace_fp
, "%s", indirection_level_string ());
583 fprintf (xtrace_fp
, "for %s in ", for_command
->name
->word
);
584 xtrace_print_word_list (for_command
->map_list
, 2);
588 print_for_command (for_command
)
589 FOR_COM
*for_command
;
591 print_for_command_head (for_command
);
595 indentation
+= indentation_amount
;
596 make_command_string_internal (for_command
->action
);
597 PRINT_DEFERRED_HEREDOCS ("");
599 indentation
-= indentation_amount
;
604 #if defined (ARITH_FOR_COMMAND)
606 print_arith_for_command (arith_for_command
)
607 ARITH_FOR_COM
*arith_for_command
;
610 command_print_word_list (arith_for_command
->init
, " ");
612 command_print_word_list (arith_for_command
->test
, " ");
614 command_print_word_list (arith_for_command
->step
, " ");
617 indentation
+= indentation_amount
;
618 make_command_string_internal (arith_for_command
->action
);
619 PRINT_DEFERRED_HEREDOCS ("");
621 indentation
-= indentation_amount
;
624 #endif /* ARITH_FOR_COMMAND */
626 #if defined (SELECT_COMMAND)
628 print_select_command_head (select_command
)
629 SELECT_COM
*select_command
;
631 cprintf ("select %s in ", select_command
->name
->word
);
632 command_print_word_list (select_command
->map_list
, " ");
636 xtrace_print_select_command_head (select_command
)
637 SELECT_COM
*select_command
;
640 fprintf (xtrace_fp
, "%s", indirection_level_string ());
641 fprintf (xtrace_fp
, "select %s in ", select_command
->name
->word
);
642 xtrace_print_word_list (select_command
->map_list
, 2);
646 print_select_command (select_command
)
647 SELECT_COM
*select_command
;
649 print_select_command_head (select_command
);
653 indentation
+= indentation_amount
;
654 make_command_string_internal (select_command
->action
);
655 PRINT_DEFERRED_HEREDOCS ("");
657 indentation
-= indentation_amount
;
660 #endif /* SELECT_COMMAND */
663 print_group_command (group_command
)
664 GROUP_COM
*group_command
;
666 group_command_nesting
++;
669 if (inside_function_def
== 0)
673 /* This is a group command { ... } inside of a function
674 definition, and should be printed as a multiline group
675 command, using the current indentation. */
677 indentation
+= indentation_amount
;
680 make_command_string_internal (group_command
->command
);
681 PRINT_DEFERRED_HEREDOCS ("");
683 if (inside_function_def
)
686 indentation
-= indentation_amount
;
687 indent (indentation
);
697 group_command_nesting
--;
701 print_case_command_head (case_command
)
702 CASE_COM
*case_command
;
704 cprintf ("case %s in ", case_command
->word
->word
);
708 xtrace_print_case_command_head (case_command
)
709 CASE_COM
*case_command
;
712 fprintf (xtrace_fp
, "%s", indirection_level_string ());
713 fprintf (xtrace_fp
, "case %s in\n", case_command
->word
->word
);
717 print_case_command (case_command
)
718 CASE_COM
*case_command
;
720 print_case_command_head (case_command
);
722 if (case_command
->clauses
)
723 print_case_clauses (case_command
->clauses
);
728 print_case_clauses (clauses
)
729 PATTERN_LIST
*clauses
;
731 indentation
+= indentation_amount
;
735 command_print_word_list (clauses
->patterns
, " | ");
737 indentation
+= indentation_amount
;
738 make_command_string_internal (clauses
->action
);
739 indentation
-= indentation_amount
;
740 PRINT_DEFERRED_HEREDOCS ("");
741 if (clauses
->flags
& CASEPAT_FALLTHROUGH
)
743 else if (clauses
->flags
& CASEPAT_TESTNEXT
)
747 clauses
= clauses
->next
;
749 indentation
-= indentation_amount
;
753 print_while_command (while_command
)
754 WHILE_COM
*while_command
;
756 print_until_or_while (while_command
, "while");
760 print_until_command (while_command
)
761 WHILE_COM
*while_command
;
763 print_until_or_while (while_command
, "until");
767 print_until_or_while (while_command
, which
)
768 WHILE_COM
*while_command
;
771 cprintf ("%s ", which
);
773 make_command_string_internal (while_command
->test
);
774 PRINT_DEFERRED_HEREDOCS ("");
776 cprintf (" do\n"); /* was newline ("do\n"); */
777 indentation
+= indentation_amount
;
778 make_command_string_internal (while_command
->action
);
779 PRINT_DEFERRED_HEREDOCS ("");
780 indentation
-= indentation_amount
;
786 print_if_command (if_command
)
791 make_command_string_internal (if_command
->test
);
794 indentation
+= indentation_amount
;
795 make_command_string_internal (if_command
->true_case
);
796 PRINT_DEFERRED_HEREDOCS ("");
797 indentation
-= indentation_amount
;
799 if (if_command
->false_case
)
803 indentation
+= indentation_amount
;
804 make_command_string_internal (if_command
->false_case
);
805 PRINT_DEFERRED_HEREDOCS ("");
806 indentation
-= indentation_amount
;
812 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
814 print_arith_command (arith_cmd_list
)
815 WORD_LIST
*arith_cmd_list
;
818 command_print_word_list (arith_cmd_list
, " ");
823 #if defined (COND_COMMAND)
825 print_cond_node (cond
)
828 if (cond
->flags
& CMD_INVERT_RETURN
)
831 if (cond
->type
== COND_EXPR
)
834 print_cond_node (cond
->left
);
837 else if (cond
->type
== COND_AND
)
839 print_cond_node (cond
->left
);
841 print_cond_node (cond
->right
);
843 else if (cond
->type
== COND_OR
)
845 print_cond_node (cond
->left
);
847 print_cond_node (cond
->right
);
849 else if (cond
->type
== COND_UNARY
)
851 cprintf ("%s", cond
->op
->word
);
853 print_cond_node (cond
->left
);
855 else if (cond
->type
== COND_BINARY
)
857 print_cond_node (cond
->left
);
859 cprintf ("%s", cond
->op
->word
);
861 print_cond_node (cond
->right
);
863 else if (cond
->type
== COND_TERM
)
865 cprintf ("%s", cond
->op
->word
); /* need to add quoting here */
870 print_cond_command (cond
)
874 print_cond_node (cond
);
880 debug_print_word_list (s
, list
, sep
)
888 fprintf (stderr
, "%s: ", s
);
889 for (w
= list
; w
; w
= w
->next
)
890 fprintf (stderr
, "%s%s", w
->word
->word
, w
->next
? sep
: "");
891 fprintf (stderr
, "\n");
895 debug_print_cond_command (cond
)
898 fprintf (stderr
, "DEBUG: ");
899 command_string_index
= 0;
900 print_cond_command (cond
);
901 fprintf (stderr
, "%s\n", the_printed_command
);
906 xtrace_print_cond_term (type
, invert
, op
, arg1
, arg2
)
912 command_string_index
= 0;
913 fprintf (xtrace_fp
, "%s", indirection_level_string ());
914 fprintf (xtrace_fp
, "[[ ");
916 fprintf (xtrace_fp
, "! ");
918 if (type
== COND_UNARY
)
920 fprintf (xtrace_fp
, "%s ", op
->word
);
921 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
923 else if (type
== COND_BINARY
)
925 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
926 fprintf (xtrace_fp
, " %s ", op
->word
);
927 fprintf (xtrace_fp
, "%s", (arg2
&& *arg2
) ? arg2
: "''");
930 fprintf (xtrace_fp
, " ]]\n");
934 #endif /* COND_COMMAND */
936 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
937 /* A function to print the words of an arithmetic command when set -x is on. */
939 xtrace_print_arith_cmd (list
)
945 fprintf (xtrace_fp
, "%s", indirection_level_string ());
946 fprintf (xtrace_fp
, "(( ");
947 for (w
= list
; w
; w
= w
->next
)
948 fprintf (xtrace_fp
, "%s%s", w
->word
->word
, w
->next
? " " : "");
949 fprintf (xtrace_fp
, " ))\n");
956 print_simple_command (simple_command
)
957 SIMPLE_COM
*simple_command
;
959 command_print_word_list (simple_command
->words
, " ");
961 if (simple_command
->redirects
)
964 print_redirection_list (simple_command
->redirects
);
969 print_heredocs (heredocs
)
975 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
977 print_redirection (hdtail
);
984 print_heredoc_bodies (heredocs
)
990 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
992 print_heredoc_body (hdtail
);
998 /* Print heredocs that are attached to the command before the connector
999 represented by CSTRING. The parsing semantics require us to print the
1000 here-doc delimiters, then the connector (CSTRING), then the here-doc
1001 bodies. We print the here-doc delimiters in print_redirection_list
1002 and print the connector and the bodies here. We don't print the connector
1003 if it's a `;', but we use it to note not to print an extra space after the
1004 last heredoc body and newline. */
1006 print_deferred_heredocs (cstring
)
1007 const char *cstring
;
1009 /* We now print the heredoc headers in print_redirection_list */
1010 if (cstring
&& cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
1011 cprintf ("%s", cstring
);
1012 if (deferred_heredocs
)
1014 print_heredoc_bodies (deferred_heredocs
);
1015 if (cstring
&& cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
1016 cprintf (" "); /* make sure there's at least one space */
1017 dispose_redirects (deferred_heredocs
);
1020 deferred_heredocs
= (REDIRECT
*)NULL
;
1024 print_redirection_list (redirects
)
1025 REDIRECT
*redirects
;
1027 REDIRECT
*heredocs
, *hdtail
, *newredir
;
1030 heredocs
= (REDIRECT
*)NULL
;
1036 /* Defer printing the here document bodiess until we've printed the rest of the
1037 redirections, but print the headers in the order they're given. */
1038 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
1040 newredir
= copy_redirect (redirects
);
1041 newredir
->next
= (REDIRECT
*)NULL
;
1043 print_heredoc_header (newredir
);
1047 hdtail
->next
= newredir
;
1051 hdtail
= heredocs
= newredir
;
1053 else if (redirects
->instruction
== r_duplicating_output_word
&& (redirects
->flags
& REDIR_VARASSIGN
) == 0 && redirects
->redirector
.dest
== 1)
1055 /* Temporarily translate it as the execution code does. */
1056 rw
= redirects
->redirectee
.filename
->word
;
1057 if (rw
&& *rw
!= '-' && DIGIT (*rw
) == 0 && EXPCHAR (*rw
) == 0)
1058 redirects
->instruction
= r_err_and_out
;
1059 print_redirection (redirects
);
1060 redirects
->instruction
= r_duplicating_output_word
;
1063 print_redirection (redirects
);
1065 redirects
= redirects
->next
;
1070 /* Now that we've printed all the other redirections (on one line),
1071 print the here documents. If we're printing a connection, we wait until
1072 we print the connector symbol, then we print the here document bodies */
1073 if (heredocs
&& printing_connection
)
1074 deferred_heredocs
= heredocs
;
1077 print_heredoc_bodies (heredocs
);
1078 dispose_redirects (heredocs
);
1083 print_heredoc_header (redirect
)
1089 kill_leading
= redirect
->instruction
== r_deblank_reading_until
;
1091 /* Here doc header */
1092 if (redirect
->rflags
& REDIR_VARASSIGN
)
1093 cprintf ("{%s}", redirect
->redirector
.filename
->word
);
1094 else if (redirect
->redirector
.dest
!= 0)
1095 cprintf ("%d", redirect
->redirector
.dest
);
1097 /* If the here document delimiter is quoted, single-quote it. */
1098 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
1100 x
= sh_single_quote (redirect
->here_doc_eof
);
1101 cprintf ("<<%s%s", kill_leading
? "-" : "", x
);
1105 cprintf ("<<%s%s", kill_leading
? "-" : "", redirect
->here_doc_eof
);
1109 print_heredoc_body (redirect
)
1113 cprintf ("%s%s", redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
1117 print_redirection (redirect
)
1120 int redirector
, redir_fd
;
1121 WORD_DESC
*redirectee
, *redir_word
;
1123 redirectee
= redirect
->redirectee
.filename
;
1124 redir_fd
= redirect
->redirectee
.dest
;
1126 redir_word
= redirect
->redirector
.filename
;
1127 redirector
= redirect
->redirector
.dest
;
1129 switch (redirect
->instruction
)
1131 case r_input_direction
:
1132 if (redirect
->rflags
& REDIR_VARASSIGN
)
1133 cprintf ("{%s}", redir_word
->word
);
1134 else if (redirector
!= 0)
1135 cprintf ("%d", redirector
);
1136 cprintf ("< %s", redirectee
->word
);
1139 case r_output_direction
:
1140 if (redirect
->rflags
& REDIR_VARASSIGN
)
1141 cprintf ("{%s}", redir_word
->word
);
1142 else if (redirector
!= 1)
1143 cprintf ("%d", redirector
);
1144 cprintf ("> %s", redirectee
->word
);
1147 case r_inputa_direction
: /* Redirection created by the shell. */
1151 case r_output_force
:
1152 if (redirect
->rflags
& REDIR_VARASSIGN
)
1153 cprintf ("{%s}", redir_word
->word
);
1154 else if (redirector
!= 1)
1155 cprintf ("%d", redirector
);
1156 cprintf (">| %s", redirectee
->word
);
1159 case r_appending_to
:
1160 if (redirect
->rflags
& REDIR_VARASSIGN
)
1161 cprintf ("{%s}", redir_word
->word
);
1162 else if (redirector
!= 1)
1163 cprintf ("%d", redirector
);
1164 cprintf (">> %s", redirectee
->word
);
1167 case r_input_output
:
1168 if (redirect
->rflags
& REDIR_VARASSIGN
)
1169 cprintf ("{%s}", redir_word
->word
);
1170 else if (redirector
!= 1)
1171 cprintf ("%d", redirector
);
1172 cprintf ("<> %s", redirectee
->word
);
1175 case r_deblank_reading_until
:
1176 case r_reading_until
:
1177 print_heredoc_header (redirect
);
1179 print_heredoc_body (redirect
);
1182 case r_reading_string
:
1183 if (redirect
->rflags
& REDIR_VARASSIGN
)
1184 cprintf ("{%s}", redir_word
->word
);
1185 else if (redirector
!= 0)
1186 cprintf ("%d", redirector
);
1188 /* Don't need to check whether or not to requote, since original quotes
1189 are still intact. The only thing that has happened is that $'...'
1190 has been replaced with 'expanded ...'. */
1191 if (ansic_shouldquote (redirect
->redirectee
.filename
->word
))
1194 x
= ansic_quote (redirect
->redirectee
.filename
->word
, 0, (int *)0);
1195 cprintf ("<<< %s", x
);
1200 cprintf ("<<< %s", redirect
->redirectee
.filename
->word
);
1203 case r_duplicating_input
:
1204 if (redirect
->rflags
& REDIR_VARASSIGN
)
1205 cprintf ("{%s}<&%d", redir_word
->word
, redir_fd
);
1207 cprintf ("%d<&%d", redirector
, redir_fd
);
1210 case r_duplicating_output
:
1211 if (redirect
->rflags
& REDIR_VARASSIGN
)
1212 cprintf ("{%s}>&%d", redir_word
->word
, redir_fd
);
1214 cprintf ("%d>&%d", redirector
, redir_fd
);
1217 case r_duplicating_input_word
:
1218 if (redirect
->rflags
& REDIR_VARASSIGN
)
1219 cprintf ("{%s}<&%s", redir_word
->word
, redirectee
->word
);
1221 cprintf ("%d<&%s", redirector
, redirectee
->word
);
1224 case r_duplicating_output_word
:
1225 if (redirect
->rflags
& REDIR_VARASSIGN
)
1226 cprintf ("{%s}>&%s", redir_word
->word
, redirectee
->word
);
1228 cprintf ("%d>&%s", redirector
, redirectee
->word
);
1232 if (redirect
->rflags
& REDIR_VARASSIGN
)
1233 cprintf ("{%s}<&%d-", redir_word
->word
, redir_fd
);
1235 cprintf ("%d<&%d-", redirector
, redir_fd
);
1239 if (redirect
->rflags
& REDIR_VARASSIGN
)
1240 cprintf ("{%s}>&%d-", redir_word
->word
, redir_fd
);
1242 cprintf ("%d>&%d-", redirector
, redir_fd
);
1245 case r_move_input_word
:
1246 if (redirect
->rflags
& REDIR_VARASSIGN
)
1247 cprintf ("{%s}<&%s-", redir_word
->word
, redirectee
->word
);
1249 cprintf ("%d<&%s-", redirector
, redirectee
->word
);
1252 case r_move_output_word
:
1253 if (redirect
->rflags
& REDIR_VARASSIGN
)
1254 cprintf ("{%s}>&%s-", redir_word
->word
, redirectee
->word
);
1256 cprintf ("%d>&%s-", redirector
, redirectee
->word
);
1260 if (redirect
->rflags
& REDIR_VARASSIGN
)
1261 cprintf ("{%s}>&-", redir_word
->word
);
1263 cprintf ("%d>&-", redirector
);
1267 cprintf ("&> %s", redirectee
->word
);
1270 case r_append_err_and_out
:
1271 cprintf ("&>> %s", redirectee
->word
);
1279 inside_function_def
= 0;
1281 printing_connection
= 0;
1282 deferred_heredocs
= 0;
1286 print_function_def (func
)
1290 REDIRECT
*func_redirects
;
1292 func_redirects
= NULL
;
1293 /* When in posix mode, print functions as posix specifies them. */
1294 if (posixly_correct
== 0)
1295 cprintf ("function %s () \n", func
->name
->word
);
1297 cprintf ("%s () \n", func
->name
->word
);
1298 add_unwind_protect (reset_locals
, 0);
1300 indent (indentation
);
1303 inside_function_def
++;
1304 indentation
+= indentation_amount
;
1306 cmdcopy
= copy_command (func
->command
);
1307 if (cmdcopy
->type
== cm_group
)
1309 func_redirects
= cmdcopy
->redirects
;
1310 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1312 make_command_string_internal (cmdcopy
->type
== cm_group
1313 ? cmdcopy
->value
.Group
->command
1315 PRINT_DEFERRED_HEREDOCS ("");
1317 remove_unwind_protect ();
1318 indentation
-= indentation_amount
;
1319 inside_function_def
--;
1324 print_redirection_list (func_redirects
);
1325 cmdcopy
->redirects
= func_redirects
;
1330 dispose_command (cmdcopy
);
1333 /* Return the string representation of the named function.
1334 NAME is the name of the function.
1335 COMMAND is the function body. It should be a GROUP_COM.
1336 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1337 flags&FUNC_EXTERNAL means convert from internal to external form
1340 named_function_string (name
, command
, flags
)
1346 int old_indent
, old_amount
;
1348 REDIRECT
*func_redirects
;
1350 old_indent
= indentation
;
1351 old_amount
= indentation_amount
;
1352 command_string_index
= was_heredoc
= 0;
1353 deferred_heredocs
= 0;
1357 if (find_reserved_word (name
) >= 0)
1358 cprintf ("function ");
1359 cprintf ("%s ", name
);
1364 if ((flags
& FUNC_MULTILINE
) == 0)
1367 indentation_amount
= 0;
1372 indentation
+= indentation_amount
;
1375 inside_function_def
++;
1377 cprintf ((flags
& FUNC_MULTILINE
) ? "{ \n" : "{ ");
1379 cmdcopy
= copy_command (command
);
1380 /* Take any redirections specified in the function definition (which should
1381 apply to the function as a whole) and save them for printing later. */
1382 func_redirects
= (REDIRECT
*)NULL
;
1383 if (cmdcopy
->type
== cm_group
)
1385 func_redirects
= cmdcopy
->redirects
;
1386 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1388 make_command_string_internal (cmdcopy
->type
== cm_group
1389 ? cmdcopy
->value
.Group
->command
1391 PRINT_DEFERRED_HEREDOCS ("");
1393 indentation
= old_indent
;
1394 indentation_amount
= old_amount
;
1395 inside_function_def
--;
1400 print_redirection_list (func_redirects
);
1401 cmdcopy
->redirects
= func_redirects
;
1406 result
= the_printed_command
;
1408 if ((flags
& FUNC_MULTILINE
) == 0)
1412 for (i
= 0; result
[i
]; i
++)
1413 if (result
[i
] == '\n')
1415 strcpy (result
+ i
, result
+ i
+ 1);
1419 if (result
[2] == '\n') /* XXX -- experimental */
1420 memmove (result
+ 2, result
+ 3, strlen (result
) - 2);
1424 dispose_command (cmdcopy
);
1426 if (flags
& FUNC_EXTERNAL
)
1427 result
= remove_quoted_escapes (result
);
1437 indent (indentation
);
1438 if (string
&& *string
)
1439 cprintf ("%s", string
);
1442 static char *indentation_string
;
1443 static int indentation_size
;
1451 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
1453 for (i
= 0; amount
> 0; amount
--)
1454 indentation_string
[i
++] = ' ';
1455 indentation_string
[i
] = '\0';
1456 cprintf ("%s", indentation_string
);
1462 if (command_string_index
> 0 &&
1463 (the_printed_command
[command_string_index
- 1] == '&' ||
1464 the_printed_command
[command_string_index
- 1] == '\n'))
1469 /* How to make the string. */
1471 #if defined (PREFER_STDARG)
1472 cprintf (const char *control
, ...)
1474 cprintf (control
, va_alist
)
1475 const char *control
;
1479 register const char *s
;
1480 char char_arg
[2], *argp
, intbuf
[INT_STRLEN_BOUND (unsigned int) + 1];
1481 int digit_arg
, arg_len
, c
;
1484 SH_VA_START (args
, control
);
1486 arg_len
= strlen (control
);
1487 the_printed_command_resize (arg_len
+ 1);
1494 argp
= (char *)NULL
;
1495 if (c
!= '%' || !*s
)
1513 argp
= va_arg (args
, char *);
1514 arg_len
= strlen (argp
);
1518 /* Represent an out-of-range file descriptor with an out-of-range
1519 integer value. We can do this because the only use of `%d' in
1520 the calls to cprintf is to output a file descriptor number for
1522 digit_arg
= va_arg (args
, int);
1525 sprintf (intbuf
, "%u", (unsigned int)-1);
1529 argp
= inttostr (digit_arg
, intbuf
, sizeof (intbuf
));
1530 arg_len
= strlen (argp
);
1534 char_arg
[0] = va_arg (args
, int);
1540 programming_error (_("cprintf: `%c': invalid format character"), c
);
1545 if (argp
&& arg_len
)
1547 the_printed_command_resize (arg_len
+ 1);
1548 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1549 command_string_index
+= arg_len
;
1555 the_printed_command
[command_string_index
] = '\0';
1558 /* Ensure that there is enough space to stuff LENGTH characters into
1559 THE_PRINTED_COMMAND. */
1561 the_printed_command_resize (length
)
1564 if (the_printed_command
== 0)
1566 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
1567 the_printed_command
= (char *)xmalloc (the_printed_command_size
);
1568 command_string_index
= 0;
1570 else if ((command_string_index
+ length
) >= the_printed_command_size
)
1573 new = command_string_index
+ length
+ 1;
1575 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1576 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
1577 the_printed_command_size
= new;
1579 the_printed_command
= (char *)xrealloc (the_printed_command
, the_printed_command_size
);
1583 #if defined (HAVE_VPRINTF)
1584 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1585 also available.'' */
1588 #if defined (PREFER_STDARG)
1589 xprintf (const char *format
, ...)
1591 xprintf (format
, va_alist
)
1598 SH_VA_START (args
, format
);
1600 vfprintf (stdout
, format
, args
);
1607 xprintf (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1610 printf (format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1613 #endif /* !HAVE_VPRINTF */