1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2010 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
[100];
136 /* Print COMMAND (a command tree) on standard output. */
138 print_command (command
)
141 command_string_index
= 0;
142 printf ("%s", make_command_string (command
));
145 /* Make a string which is the printed representation of the command
146 tree in COMMAND. We return this string. However, the string is
147 not consed, so you have to do that yourself if you want it to
150 make_command_string (command
)
153 command_string_index
= was_heredoc
= 0;
154 deferred_heredocs
= 0;
155 make_command_string_internal (command
);
156 return (the_printed_command
);
159 /* The internal function. This is the real workhorse. */
161 make_command_string_internal (command
)
170 if (skip_this_indent
)
173 indent (indentation
);
175 if (command
->flags
& CMD_TIME_PIPELINE
)
178 if (command
->flags
& CMD_TIME_POSIX
)
182 if (command
->flags
& CMD_INVERT_RETURN
)
185 switch (command
->type
)
188 print_for_command (command
->value
.For
);
191 #if defined (ARITH_FOR_COMMAND)
193 print_arith_for_command (command
->value
.ArithFor
);
197 #if defined (SELECT_COMMAND)
199 print_select_command (command
->value
.Select
);
204 print_case_command (command
->value
.Case
);
208 print_while_command (command
->value
.While
);
212 print_until_command (command
->value
.While
);
216 print_if_command (command
->value
.If
);
219 #if defined (DPAREN_ARITHMETIC)
221 print_arith_command (command
->value
.Arith
->exp
);
225 #if defined (COND_COMMAND)
227 print_cond_command (command
->value
.Cond
);
232 print_simple_command (command
->value
.Simple
);
238 printing_connection
++;
239 make_command_string_internal (command
->value
.Connection
->first
);
241 switch (command
->value
.Connection
->connector
)
246 char c
= command
->value
.Connection
->connector
;
252 print_deferred_heredocs (s
);
254 if (c
!= '&' || command
->value
.Connection
->second
)
263 print_deferred_heredocs (" && ");
264 if (command
->value
.Connection
->second
)
269 print_deferred_heredocs (" || ");
270 if (command
->value
.Connection
->second
)
275 if (deferred_heredocs
== 0)
277 if (was_heredoc
== 0)
283 print_deferred_heredocs (inside_function_def
? "" : ";");
285 if (inside_function_def
)
290 if (command
->value
.Connection
->second
)
296 cprintf (_("print_command: bad connector `%d'"),
297 command
->value
.Connection
->connector
);
301 make_command_string_internal (command
->value
.Connection
->second
);
302 PRINT_DEFERRED_HEREDOCS ("");
303 printing_connection
--;
306 case cm_function_def
:
307 print_function_def (command
->value
.Function_def
);
311 print_group_command (command
->value
.Group
);
317 make_command_string_internal (command
->value
.Subshell
->command
);
322 cprintf ("coproc %s ", command
->value
.Coproc
->name
);
324 make_command_string_internal (command
->value
.Coproc
->command
);
328 command_error ("print_command", CMDERR_BADTYPE
, command
->type
, 0);
333 if (command
->redirects
)
336 print_redirection_list (command
->redirects
);
342 _print_word_list (list
, separator
, pfunc
)
349 for (w
= list
; w
; w
= w
->next
)
350 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
354 print_word_list (list
, separator
)
358 _print_word_list (list
, separator
, xprintf
);
366 if (fd
>= 0 && sh_validfd (fd
) == 0)
368 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd
);
373 internal_error (_("xtrace_set: NULL file pointer"));
376 if (fd
>= 0 && fileno (fp
) != fd
)
377 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd
, fileno (fp
));
386 xtrace_set (-1, stderr
);
392 if (xtrace_fd
>= 0 && xtrace_fp
)
397 else if (xtrace_fd
>= 0)
412 /* Return a string denoting what our indirection level is. */
415 indirection_level_string ()
419 char ps4_firstc
[MB_LEN_MAX
+1];
420 int ps4_firstc_len
, ps4_len
;
422 indirection_string
[0] = '\0';
423 ps4
= get_string_value ("PS4");
425 if (ps4
== 0 || *ps4
== '\0')
426 return (indirection_string
);
428 change_flag ('x', FLAG_OFF
);
429 ps4
= decode_prompt_string (ps4
);
430 change_flag ('x', FLAG_ON
);
432 if (ps4
== 0 || *ps4
== '\0')
433 return (indirection_string
);
435 #if defined (HANDLE_MULTIBYTE)
436 ps4_len
= strnlen (ps4
, MB_CUR_MAX
);
437 ps4_firstc_len
= MBLEN (ps4
, ps4_len
);
438 if (ps4_firstc_len
== 1 || ps4_firstc_len
== 0 || MB_INVALIDCH (ps4_firstc_len
))
440 ps4_firstc
[0] = ps4
[0];
441 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
444 memcpy (ps4_firstc
, ps4
, ps4_firstc_len
);
446 ps4_firstc
[0] = ps4
[0];
447 ps4_firstc
[ps4_firstc_len
= 1] = '\0';
450 for (i
= j
= 0; ps4_firstc
[0] && j
< indirection_level
&& i
< 99; i
+= ps4_firstc_len
, j
++)
452 if (ps4_firstc_len
== 1)
453 indirection_string
[i
] = ps4_firstc
[0];
455 memcpy (indirection_string
+i
, ps4_firstc
, ps4_firstc_len
);
458 for (j
= ps4_firstc_len
; *ps4
&& ps4
[j
] && i
< 99; i
++, j
++)
459 indirection_string
[i
] = ps4
[j
];
461 indirection_string
[i
] = '\0';
463 return (indirection_string
);
467 xtrace_print_assignment (name
, value
, assign_list
, xflags
)
469 int assign_list
, xflags
;
476 fprintf (xtrace_fp
, "%s", indirection_level_string ());
478 /* VALUE should not be NULL when this is called. */
479 if (*value
== '\0' || assign_list
)
481 else if (sh_contains_shell_metas (value
))
482 nval
= sh_single_quote (value
);
483 else if (ansic_shouldquote (value
))
484 nval
= ansic_quote (value
, 0, (int *)0);
489 fprintf (xtrace_fp
, "%s=(%s)\n", name
, nval
);
491 fprintf (xtrace_fp
, "%s=%s\n", name
, nval
);
499 /* A function to print the words of a simple command when set -x is on. */
501 xtrace_print_word_list (list
, xtflags
)
511 fprintf (xtrace_fp
, "%s", indirection_level_string ());
513 for (w
= list
; w
; w
= w
->next
)
516 if (t
== 0 || *t
== '\0')
517 fprintf (xtrace_fp
, "''%s", w
->next
? " " : "");
518 else if (sh_contains_shell_metas (t
))
520 x
= sh_single_quote (t
);
521 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
524 else if (ansic_shouldquote (t
))
526 x
= ansic_quote (t
, 0, (int *)0);
527 fprintf (xtrace_fp
, "%s%s", x
, w
->next
? " " : "");
531 fprintf (xtrace_fp
, "%s%s", t
, w
->next
? " " : "");
533 fprintf (xtrace_fp
, "\n");
538 command_print_word_list (list
, separator
)
542 _print_word_list (list
, separator
, cprintf
);
546 print_for_command_head (for_command
)
547 FOR_COM
*for_command
;
549 cprintf ("for %s in ", for_command
->name
->word
);
550 command_print_word_list (for_command
->map_list
, " ");
554 xtrace_print_for_command_head (for_command
)
555 FOR_COM
*for_command
;
558 fprintf (xtrace_fp
, "%s", indirection_level_string ());
559 fprintf (xtrace_fp
, "for %s in ", for_command
->name
->word
);
560 xtrace_print_word_list (for_command
->map_list
, 0);
564 print_for_command (for_command
)
565 FOR_COM
*for_command
;
567 print_for_command_head (for_command
);
571 indentation
+= indentation_amount
;
572 make_command_string_internal (for_command
->action
);
573 PRINT_DEFERRED_HEREDOCS ("");
575 indentation
-= indentation_amount
;
580 #if defined (ARITH_FOR_COMMAND)
582 print_arith_for_command (arith_for_command
)
583 ARITH_FOR_COM
*arith_for_command
;
586 command_print_word_list (arith_for_command
->init
, " ");
588 command_print_word_list (arith_for_command
->test
, " ");
590 command_print_word_list (arith_for_command
->step
, " ");
593 indentation
+= indentation_amount
;
594 make_command_string_internal (arith_for_command
->action
);
596 indentation
-= indentation_amount
;
599 #endif /* ARITH_FOR_COMMAND */
601 #if defined (SELECT_COMMAND)
603 print_select_command_head (select_command
)
604 SELECT_COM
*select_command
;
606 cprintf ("select %s in ", select_command
->name
->word
);
607 command_print_word_list (select_command
->map_list
, " ");
611 xtrace_print_select_command_head (select_command
)
612 SELECT_COM
*select_command
;
615 fprintf (xtrace_fp
, "%s", indirection_level_string ());
616 fprintf (xtrace_fp
, "select %s in ", select_command
->name
->word
);
617 xtrace_print_word_list (select_command
->map_list
, 0);
621 print_select_command (select_command
)
622 SELECT_COM
*select_command
;
624 print_select_command_head (select_command
);
628 indentation
+= indentation_amount
;
629 make_command_string_internal (select_command
->action
);
630 PRINT_DEFERRED_HEREDOCS ("");
632 indentation
-= indentation_amount
;
635 #endif /* SELECT_COMMAND */
638 print_group_command (group_command
)
639 GROUP_COM
*group_command
;
641 group_command_nesting
++;
644 if (inside_function_def
== 0)
648 /* This is a group command { ... } inside of a function
649 definition, and should be printed as a multiline group
650 command, using the current indentation. */
652 indentation
+= indentation_amount
;
655 make_command_string_internal (group_command
->command
);
657 if (inside_function_def
)
660 indentation
-= indentation_amount
;
661 indent (indentation
);
671 group_command_nesting
--;
675 print_case_command_head (case_command
)
676 CASE_COM
*case_command
;
678 cprintf ("case %s in ", case_command
->word
->word
);
682 xtrace_print_case_command_head (case_command
)
683 CASE_COM
*case_command
;
686 fprintf (xtrace_fp
, "%s", indirection_level_string ());
687 fprintf (xtrace_fp
, "case %s in\n", case_command
->word
->word
);
691 print_case_command (case_command
)
692 CASE_COM
*case_command
;
694 print_case_command_head (case_command
);
696 if (case_command
->clauses
)
697 print_case_clauses (case_command
->clauses
);
702 print_case_clauses (clauses
)
703 PATTERN_LIST
*clauses
;
705 indentation
+= indentation_amount
;
709 command_print_word_list (clauses
->patterns
, " | ");
711 indentation
+= indentation_amount
;
712 make_command_string_internal (clauses
->action
);
713 indentation
-= indentation_amount
;
714 PRINT_DEFERRED_HEREDOCS ("");
715 if (clauses
->flags
& CASEPAT_FALLTHROUGH
)
717 else if (clauses
->flags
& CASEPAT_TESTNEXT
)
721 clauses
= clauses
->next
;
723 indentation
-= indentation_amount
;
727 print_while_command (while_command
)
728 WHILE_COM
*while_command
;
730 print_until_or_while (while_command
, "while");
734 print_until_command (while_command
)
735 WHILE_COM
*while_command
;
737 print_until_or_while (while_command
, "until");
741 print_until_or_while (while_command
, which
)
742 WHILE_COM
*while_command
;
745 cprintf ("%s ", which
);
747 make_command_string_internal (while_command
->test
);
748 PRINT_DEFERRED_HEREDOCS ("");
750 cprintf (" do\n"); /* was newline ("do\n"); */
751 indentation
+= indentation_amount
;
752 make_command_string_internal (while_command
->action
);
753 PRINT_DEFERRED_HEREDOCS ("");
754 indentation
-= indentation_amount
;
760 print_if_command (if_command
)
765 make_command_string_internal (if_command
->test
);
768 indentation
+= indentation_amount
;
769 make_command_string_internal (if_command
->true_case
);
770 PRINT_DEFERRED_HEREDOCS ("");
771 indentation
-= indentation_amount
;
773 if (if_command
->false_case
)
777 indentation
+= indentation_amount
;
778 make_command_string_internal (if_command
->false_case
);
779 PRINT_DEFERRED_HEREDOCS ("");
780 indentation
-= indentation_amount
;
786 #if defined (DPAREN_ARITHMETIC)
788 print_arith_command (arith_cmd_list
)
789 WORD_LIST
*arith_cmd_list
;
792 command_print_word_list (arith_cmd_list
, " ");
797 #if defined (COND_COMMAND)
799 print_cond_node (cond
)
802 if (cond
->flags
& CMD_INVERT_RETURN
)
805 if (cond
->type
== COND_EXPR
)
808 print_cond_node (cond
->left
);
811 else if (cond
->type
== COND_AND
)
813 print_cond_node (cond
->left
);
815 print_cond_node (cond
->right
);
817 else if (cond
->type
== COND_OR
)
819 print_cond_node (cond
->left
);
821 print_cond_node (cond
->right
);
823 else if (cond
->type
== COND_UNARY
)
825 cprintf ("%s", cond
->op
->word
);
827 print_cond_node (cond
->left
);
829 else if (cond
->type
== COND_BINARY
)
831 print_cond_node (cond
->left
);
833 cprintf ("%s", cond
->op
->word
);
835 print_cond_node (cond
->right
);
837 else if (cond
->type
== COND_TERM
)
839 cprintf ("%s", cond
->op
->word
); /* need to add quoting here */
844 print_cond_command (cond
)
848 print_cond_node (cond
);
854 debug_print_cond_command (cond
)
857 fprintf (stderr
, "DEBUG: ");
858 command_string_index
= 0;
859 print_cond_command (cond
);
860 fprintf (stderr
, "%s\n", the_printed_command
);
865 xtrace_print_cond_term (type
, invert
, op
, arg1
, arg2
)
871 command_string_index
= 0;
872 fprintf (xtrace_fp
, "%s", indirection_level_string ());
873 fprintf (xtrace_fp
, "[[ ");
875 fprintf (xtrace_fp
, "! ");
877 if (type
== COND_UNARY
)
879 fprintf (xtrace_fp
, "%s ", op
->word
);
880 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
882 else if (type
== COND_BINARY
)
884 fprintf (xtrace_fp
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
885 fprintf (xtrace_fp
, " %s ", op
->word
);
886 fprintf (xtrace_fp
, "%s", (arg2
&& *arg2
) ? arg2
: "''");
889 fprintf (xtrace_fp
, " ]]\n");
893 #endif /* COND_COMMAND */
895 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
896 /* A function to print the words of an arithmetic command when set -x is on. */
898 xtrace_print_arith_cmd (list
)
904 fprintf (xtrace_fp
, "%s", indirection_level_string ());
905 fprintf (xtrace_fp
, "(( ");
906 for (w
= list
; w
; w
= w
->next
)
907 fprintf (xtrace_fp
, "%s%s", w
->word
->word
, w
->next
? " " : "");
908 fprintf (xtrace_fp
, " ))\n");
915 print_simple_command (simple_command
)
916 SIMPLE_COM
*simple_command
;
918 command_print_word_list (simple_command
->words
, " ");
920 if (simple_command
->redirects
)
923 print_redirection_list (simple_command
->redirects
);
928 print_heredocs (heredocs
)
934 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
936 print_redirection (hdtail
);
942 /* Print heredocs that are attached to the command before the connector
943 represented by CSTRING. The parsing semantics require us to print the
944 here-doc delimiters, then the connector (CSTRING), then the here-doc
945 bodies. We don't print the connector if it's a `;', but we use it to
946 note not to print an extra space after the last heredoc body and
949 print_deferred_heredocs (cstring
)
954 for (hdtail
= deferred_heredocs
; hdtail
; hdtail
= hdtail
->next
)
957 print_heredoc_header (hdtail
);
959 if (cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
960 cprintf ("%s", cstring
);
961 if (deferred_heredocs
)
963 for (hdtail
= deferred_heredocs
; hdtail
; hdtail
= hdtail
->next
)
965 print_heredoc_body (hdtail
);
968 if (deferred_heredocs
)
970 if (cstring
&& cstring
[0] && (cstring
[0] != ';' || cstring
[1]))
971 cprintf (" "); /* make sure there's at least one space */
972 dispose_redirects (deferred_heredocs
);
975 deferred_heredocs
= (REDIRECT
*)NULL
;
979 print_redirection_list (redirects
)
982 REDIRECT
*heredocs
, *hdtail
, *newredir
;
984 heredocs
= (REDIRECT
*)NULL
;
990 /* Defer printing the here documents until we've printed the
991 rest of the redirections. */
992 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
994 newredir
= copy_redirect (redirects
);
995 newredir
->next
= (REDIRECT
*)NULL
;
998 hdtail
->next
= newredir
;
1002 hdtail
= heredocs
= newredir
;
1004 else if (redirects
->instruction
== r_duplicating_output_word
&& redirects
->redirector
.dest
== 1)
1006 /* Temporarily translate it as the execution code does. */
1007 redirects
->instruction
= r_err_and_out
;
1008 print_redirection (redirects
);
1009 redirects
->instruction
= r_duplicating_output_word
;
1012 print_redirection (redirects
);
1014 redirects
= redirects
->next
;
1019 /* Now that we've printed all the other redirections (on one line),
1020 print the here documents. */
1021 if (heredocs
&& printing_connection
)
1022 deferred_heredocs
= heredocs
;
1025 print_heredocs (heredocs
);
1026 dispose_redirects (heredocs
);
1031 print_heredoc_header (redirect
)
1037 kill_leading
= redirect
->instruction
== r_deblank_reading_until
;
1039 /* Here doc header */
1040 if (redirect
->rflags
& REDIR_VARASSIGN
)
1041 cprintf ("{%s}", redirect
->redirector
.filename
->word
);
1042 else if (redirect
->redirector
.dest
!= 0)
1043 cprintf ("%d", redirect
->redirector
.dest
);
1045 /* If the here document delimiter is quoted, single-quote it. */
1046 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
1048 x
= sh_single_quote (redirect
->here_doc_eof
);
1049 cprintf ("<<%s%s", kill_leading
? "-" : "", x
);
1053 cprintf ("<<%s%s", kill_leading
? "-" : "", redirect
->here_doc_eof
);
1057 print_heredoc_body (redirect
)
1061 cprintf ("%s%s", redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
1065 print_redirection (redirect
)
1068 int redirector
, redir_fd
;
1069 WORD_DESC
*redirectee
, *redir_word
;
1071 redirectee
= redirect
->redirectee
.filename
;
1072 redir_fd
= redirect
->redirectee
.dest
;
1074 redir_word
= redirect
->redirector
.filename
;
1075 redirector
= redirect
->redirector
.dest
;
1077 switch (redirect
->instruction
)
1079 case r_input_direction
:
1080 if (redirect
->rflags
& REDIR_VARASSIGN
)
1081 cprintf ("{%s}", redir_word
->word
);
1082 else if (redirector
!= 0)
1083 cprintf ("%d", redirector
);
1084 cprintf ("< %s", redirectee
->word
);
1087 case r_output_direction
:
1088 if (redirect
->rflags
& REDIR_VARASSIGN
)
1089 cprintf ("{%s}", redir_word
->word
);
1090 else if (redirector
!= 1)
1091 cprintf ("%d", redirector
);
1092 cprintf ("> %s", redirectee
->word
);
1095 case r_inputa_direction
: /* Redirection created by the shell. */
1099 case r_output_force
:
1100 if (redirect
->rflags
& REDIR_VARASSIGN
)
1101 cprintf ("{%s}", redir_word
->word
);
1102 else if (redirector
!= 1)
1103 cprintf ("%d", redirector
);
1104 cprintf (">|%s", redirectee
->word
);
1107 case r_appending_to
:
1108 if (redirect
->rflags
& REDIR_VARASSIGN
)
1109 cprintf ("{%s}", redir_word
->word
);
1110 else if (redirector
!= 1)
1111 cprintf ("%d", redirector
);
1112 cprintf (">> %s", redirectee
->word
);
1115 case r_input_output
:
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_deblank_reading_until
:
1124 case r_reading_until
:
1125 print_heredoc_header (redirect
);
1127 print_heredoc_body (redirect
);
1130 case r_reading_string
:
1131 if (redirect
->rflags
& REDIR_VARASSIGN
)
1132 cprintf ("{%s}", redir_word
->word
);
1133 else if (redirector
!= 0)
1134 cprintf ("%d", redirector
);
1136 /* Don't need to check whether or not to requote, since original quotes
1137 are still intact. The only thing that has happened is that $'...'
1138 has been replaced with 'expanded ...'. */
1139 if (ansic_shouldquote (redirect
->redirectee
.filename
->word
))
1142 x
= ansic_quote (redirect
->redirectee
.filename
->word
, 0, (int *)0);
1143 cprintf ("<<< %s", x
);
1148 cprintf ("<<< %s", redirect
->redirectee
.filename
->word
);
1151 case r_duplicating_input
:
1152 if (redirect
->rflags
& REDIR_VARASSIGN
)
1153 cprintf ("{%s}<&%d", redir_word
->word
, redir_fd
);
1155 cprintf ("%d<&%d", redirector
, redir_fd
);
1158 case r_duplicating_output
:
1159 if (redirect
->rflags
& REDIR_VARASSIGN
)
1160 cprintf ("{%s}>&%d", redir_word
->word
, redir_fd
);
1162 cprintf ("%d>&%d", redirector
, redir_fd
);
1165 case r_duplicating_input_word
:
1166 if (redirect
->rflags
& REDIR_VARASSIGN
)
1167 cprintf ("{%s}<&%s", redir_word
->word
, redirectee
->word
);
1169 cprintf ("%d<&%s", redirector
, redirectee
->word
);
1172 case r_duplicating_output_word
:
1173 if (redirect
->rflags
& REDIR_VARASSIGN
)
1174 cprintf ("{%s}>&%s", redir_word
->word
, redirectee
->word
);
1176 cprintf ("%d>&%s", redirector
, redirectee
->word
);
1180 if (redirect
->rflags
& REDIR_VARASSIGN
)
1181 cprintf ("{%s}<&%d-", redir_word
->word
, redir_fd
);
1183 cprintf ("%d<&%d-", redirector
, redir_fd
);
1187 if (redirect
->rflags
& REDIR_VARASSIGN
)
1188 cprintf ("{%s}>&%d-", redir_word
->word
, redir_fd
);
1190 cprintf ("%d>&%d-", redirector
, redir_fd
);
1193 case r_move_input_word
:
1194 if (redirect
->rflags
& REDIR_VARASSIGN
)
1195 cprintf ("{%s}<&%s-", redir_word
->word
, redirectee
->word
);
1197 cprintf ("%d<&%s-", redirector
, redirectee
->word
);
1200 case r_move_output_word
:
1201 if (redirect
->rflags
& REDIR_VARASSIGN
)
1202 cprintf ("{%s}>&%s-", redir_word
->word
, redirectee
->word
);
1204 cprintf ("%d>&%s-", redirector
, redirectee
->word
);
1208 if (redirect
->rflags
& REDIR_VARASSIGN
)
1209 cprintf ("{%s}>&-", redir_word
->word
);
1211 cprintf ("%d>&-", redirector
);
1215 cprintf ("&>%s", redirectee
->word
);
1218 case r_append_err_and_out
:
1219 cprintf ("&>>%s", redirectee
->word
);
1227 inside_function_def
= 0;
1229 printing_connection
= 0;
1230 deferred_heredocs
= 0;
1234 print_function_def (func
)
1238 REDIRECT
*func_redirects
;
1240 func_redirects
= NULL
;
1241 cprintf ("function %s () \n", func
->name
->word
);
1242 add_unwind_protect (reset_locals
, 0);
1244 indent (indentation
);
1247 inside_function_def
++;
1248 indentation
+= indentation_amount
;
1250 cmdcopy
= copy_command (func
->command
);
1251 if (cmdcopy
->type
== cm_group
)
1253 func_redirects
= cmdcopy
->redirects
;
1254 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1256 make_command_string_internal (cmdcopy
->type
== cm_group
1257 ? cmdcopy
->value
.Group
->command
1260 remove_unwind_protect ();
1261 indentation
-= indentation_amount
;
1262 inside_function_def
--;
1267 print_redirection_list (func_redirects
);
1268 cmdcopy
->redirects
= func_redirects
;
1273 dispose_command (cmdcopy
);
1276 /* Return the string representation of the named function.
1277 NAME is the name of the function.
1278 COMMAND is the function body. It should be a GROUP_COM.
1279 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1280 flags&FUNC_EXTERNAL means convert from internal to external form
1283 named_function_string (name
, command
, flags
)
1289 int old_indent
, old_amount
;
1291 REDIRECT
*func_redirects
;
1293 old_indent
= indentation
;
1294 old_amount
= indentation_amount
;
1295 command_string_index
= was_heredoc
= 0;
1296 deferred_heredocs
= 0;
1299 cprintf ("%s ", name
);
1303 if ((flags
& FUNC_MULTILINE
) == 0)
1306 indentation_amount
= 0;
1311 indentation
+= indentation_amount
;
1314 inside_function_def
++;
1316 cprintf ((flags
& FUNC_MULTILINE
) ? "{ \n" : "{ ");
1318 cmdcopy
= copy_command (command
);
1319 /* Take any redirections specified in the function definition (which should
1320 apply to the function as a whole) and save them for printing later. */
1321 func_redirects
= (REDIRECT
*)NULL
;
1322 if (cmdcopy
->type
== cm_group
)
1324 func_redirects
= cmdcopy
->redirects
;
1325 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1327 make_command_string_internal (cmdcopy
->type
== cm_group
1328 ? cmdcopy
->value
.Group
->command
1331 indentation
= old_indent
;
1332 indentation_amount
= old_amount
;
1333 inside_function_def
--;
1338 print_redirection_list (func_redirects
);
1339 cmdcopy
->redirects
= func_redirects
;
1344 result
= the_printed_command
;
1346 if ((flags
& FUNC_MULTILINE
) == 0)
1350 for (i
= 0; result
[i
]; i
++)
1351 if (result
[i
] == '\n')
1353 strcpy (result
+ i
, result
+ i
+ 1);
1357 if (result
[2] == '\n') /* XXX -- experimental */
1358 strcpy (result
+ 2, result
+ 3);
1362 dispose_command (cmdcopy
);
1364 if (flags
& FUNC_EXTERNAL
)
1365 result
= remove_quoted_escapes (result
);
1375 indent (indentation
);
1376 if (string
&& *string
)
1377 cprintf ("%s", string
);
1380 static char *indentation_string
;
1381 static int indentation_size
;
1389 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
1391 for (i
= 0; amount
> 0; amount
--)
1392 indentation_string
[i
++] = ' ';
1393 indentation_string
[i
] = '\0';
1394 cprintf (indentation_string
);
1400 if (command_string_index
> 0 &&
1401 (the_printed_command
[command_string_index
- 1] == '&' ||
1402 the_printed_command
[command_string_index
- 1] == '\n'))
1407 /* How to make the string. */
1409 #if defined (PREFER_STDARG)
1410 cprintf (const char *control
, ...)
1412 cprintf (control
, va_alist
)
1413 const char *control
;
1417 register const char *s
;
1418 char char_arg
[2], *argp
, intbuf
[INT_STRLEN_BOUND (int) + 1];
1419 int digit_arg
, arg_len
, c
;
1422 SH_VA_START (args
, control
);
1424 arg_len
= strlen (control
);
1425 the_printed_command_resize (arg_len
+ 1);
1432 argp
= (char *)NULL
;
1433 if (c
!= '%' || !*s
)
1451 argp
= va_arg (args
, char *);
1452 arg_len
= strlen (argp
);
1456 /* Represent an out-of-range file descriptor with an out-of-range
1457 integer value. We can do this because the only use of `%d' in
1458 the calls to cprintf is to output a file descriptor number for
1460 digit_arg
= va_arg (args
, int);
1463 sprintf (intbuf
, "%u", (unsigned)-1);
1467 argp
= inttostr (digit_arg
, intbuf
, sizeof (intbuf
));
1468 arg_len
= strlen (argp
);
1472 char_arg
[0] = va_arg (args
, int);
1478 programming_error (_("cprintf: `%c': invalid format character"), c
);
1483 if (argp
&& arg_len
)
1485 the_printed_command_resize (arg_len
+ 1);
1486 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1487 command_string_index
+= arg_len
;
1491 the_printed_command
[command_string_index
] = '\0';
1494 /* Ensure that there is enough space to stuff LENGTH characters into
1495 THE_PRINTED_COMMAND. */
1497 the_printed_command_resize (length
)
1500 if (the_printed_command
== 0)
1502 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
1503 the_printed_command
= (char *)xmalloc (the_printed_command_size
);
1504 command_string_index
= 0;
1506 else if ((command_string_index
+ length
) >= the_printed_command_size
)
1509 new = command_string_index
+ length
+ 1;
1511 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1512 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
1513 the_printed_command_size
= new;
1515 the_printed_command
= (char *)xrealloc (the_printed_command
, the_printed_command_size
);
1519 #if defined (HAVE_VPRINTF)
1520 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1521 also available.'' */
1524 #if defined (PREFER_STDARG)
1525 xprintf (const char *format
, ...)
1527 xprintf (format
, va_alist
)
1534 SH_VA_START (args
, format
);
1536 vfprintf (stdout
, format
, args
);
1543 xprintf (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1546 printf (format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1549 #endif /* !HAVE_VPRINTF */