Patch-ID: bash40-032
[bash.git] / print_cmd.c
blob285d8fffc8c39d5626ec950529c49a90d6032029
1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2009 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/>.
21 #include "config.h"
23 #include <stdio.h>
25 #if defined (HAVE_UNISTD_H)
26 # ifdef _MINIX
27 # include <sys/types.h>
28 # endif
29 # include <unistd.h>
30 #endif
32 #if defined (PREFER_STDARG)
33 # include <stdarg.h>
34 #else
35 # include <varargs.h>
36 #endif
38 #include "bashansi.h"
39 #include "bashintl.h"
41 #include "shell.h"
42 #include "flags.h"
43 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
45 #include "shmbutil.h"
47 #include "builtins/common.h"
49 #if !HAVE_DECL_PRINTF
50 extern int printf __P((const char *, ...)); /* Yuck. Double yuck. */
51 #endif
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)));
63 #else
64 #define PFUNC VFunction
65 static void cprintf ();
66 static void xprintf ();
67 #endif
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 *));
89 #endif
90 #if defined (SELECT_COMMAND)
91 static void print_select_command __P((SELECT_COM *));
92 #endif
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 *));
101 #endif
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;
111 /* Non-zero means the stuff being printed is inside of a function def. */
112 static int inside_function_def;
113 static int skip_this_indent;
114 static int was_heredoc;
115 static int printing_connection;
116 static REDIRECT *deferred_heredocs;
118 /* The depth of the group commands that we are currently printing. This
119 includes the group command that is a function body. */
120 static int group_command_nesting;
122 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
123 static char indirection_string[100];
125 /* Print COMMAND (a command tree) on standard output. */
126 void
127 print_command (command)
128 COMMAND *command;
130 command_string_index = 0;
131 printf ("%s", make_command_string (command));
134 /* Make a string which is the printed representation of the command
135 tree in COMMAND. We return this string. However, the string is
136 not consed, so you have to do that yourself if you want it to
137 remain around. */
138 char *
139 make_command_string (command)
140 COMMAND *command;
142 command_string_index = was_heredoc = 0;
143 deferred_heredocs = 0;
144 make_command_string_internal (command);
145 return (the_printed_command);
148 /* The internal function. This is the real workhorse. */
149 static void
150 make_command_string_internal (command)
151 COMMAND *command;
153 char s[3], *op;
155 if (command == 0)
156 cprintf ("");
157 else
159 if (skip_this_indent)
160 skip_this_indent--;
161 else
162 indent (indentation);
164 if (command->flags & CMD_TIME_PIPELINE)
166 cprintf ("time ");
167 if (command->flags & CMD_TIME_POSIX)
168 cprintf ("-p ");
171 if (command->flags & CMD_INVERT_RETURN)
172 cprintf ("! ");
174 switch (command->type)
176 case cm_for:
177 print_for_command (command->value.For);
178 break;
180 #if defined (ARITH_FOR_COMMAND)
181 case cm_arith_for:
182 print_arith_for_command (command->value.ArithFor);
183 break;
184 #endif
186 #if defined (SELECT_COMMAND)
187 case cm_select:
188 print_select_command (command->value.Select);
189 break;
190 #endif
192 case cm_case:
193 print_case_command (command->value.Case);
194 break;
196 case cm_while:
197 print_while_command (command->value.While);
198 break;
200 case cm_until:
201 print_until_command (command->value.While);
202 break;
204 case cm_if:
205 print_if_command (command->value.If);
206 break;
208 #if defined (DPAREN_ARITHMETIC)
209 case cm_arith:
210 print_arith_command (command->value.Arith->exp);
211 break;
212 #endif
214 #if defined (COND_COMMAND)
215 case cm_cond:
216 print_cond_command (command->value.Cond);
217 break;
218 #endif
220 case cm_simple:
221 print_simple_command (command->value.Simple);
222 break;
224 case cm_connection:
226 skip_this_indent++;
227 printing_connection++;
228 make_command_string_internal (command->value.Connection->first);
230 switch (command->value.Connection->connector)
232 case '&':
233 case '|':
235 char c = command->value.Connection->connector;
237 s[0] = ' ';
238 s[1] = c;
239 s[2] = '\0';
241 print_deferred_heredocs (s);
243 if (c != '&' || command->value.Connection->second)
245 cprintf (" ");
246 skip_this_indent++;
249 break;
251 case AND_AND:
252 print_deferred_heredocs (" && ");
253 if (command->value.Connection->second)
254 skip_this_indent++;
255 break;
257 case OR_OR:
258 print_deferred_heredocs (" || ");
259 if (command->value.Connection->second)
260 skip_this_indent++;
261 break;
263 case ';':
264 if (deferred_heredocs == 0)
266 if (was_heredoc == 0)
267 cprintf (";");
268 else
269 was_heredoc = 0;
271 else
272 print_deferred_heredocs (inside_function_def ? "" : ";");
274 if (inside_function_def)
275 cprintf ("\n");
276 else
278 cprintf (" ");
279 if (command->value.Connection->second)
280 skip_this_indent++;
282 break;
284 default:
285 cprintf (_("print_command: bad connector `%d'"),
286 command->value.Connection->connector);
287 break;
290 make_command_string_internal (command->value.Connection->second);
291 if (deferred_heredocs)
292 print_deferred_heredocs ("");
293 printing_connection--;
294 break;
296 case cm_function_def:
297 print_function_def (command->value.Function_def);
298 break;
300 case cm_group:
301 print_group_command (command->value.Group);
302 break;
304 case cm_subshell:
305 cprintf ("( ");
306 skip_this_indent++;
307 make_command_string_internal (command->value.Subshell->command);
308 cprintf (" )");
309 break;
311 case cm_coproc:
312 cprintf ("coproc %s ", command->value.Coproc->name);
313 skip_this_indent++;
314 make_command_string_internal (command->value.Coproc->command);
315 break;
317 default:
318 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
319 break;
323 if (command->redirects)
325 cprintf (" ");
326 print_redirection_list (command->redirects);
331 static void
332 _print_word_list (list, separator, pfunc)
333 WORD_LIST *list;
334 char *separator;
335 PFUNC *pfunc;
337 WORD_LIST *w;
339 for (w = list; w; w = w->next)
340 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
343 void
344 print_word_list (list, separator)
345 WORD_LIST *list;
346 char *separator;
348 _print_word_list (list, separator, xprintf);
351 /* Return a string denoting what our indirection level is. */
353 char *
354 indirection_level_string ()
356 register int i, j;
357 char *ps4;
358 char ps4_firstc[MB_LEN_MAX+1];
359 int ps4_firstc_len, ps4_len;
361 indirection_string[0] = '\0';
362 ps4 = get_string_value ("PS4");
364 if (ps4 == 0 || *ps4 == '\0')
365 return (indirection_string);
367 change_flag ('x', FLAG_OFF);
368 ps4 = decode_prompt_string (ps4);
369 change_flag ('x', FLAG_ON);
371 if (ps4 == 0 || *ps4 == '\0')
372 return (indirection_string);
374 #if defined (HANDLE_MULTIBYTE)
375 ps4_len = strnlen (ps4, MB_CUR_MAX);
376 ps4_firstc_len = MBLEN (ps4, ps4_len);
377 if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
379 ps4_firstc[0] = ps4[0];
380 ps4_firstc[ps4_firstc_len = 1] = '\0';
382 else
383 memcpy (ps4_firstc, ps4, ps4_firstc_len);
384 #else
385 ps4_firstc[0] = ps4[0];
386 ps4_firstc[ps4_firstc_len = 1] = '\0';
387 #endif
389 for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
391 if (ps4_firstc_len == 1)
392 indirection_string[i] = ps4_firstc[0];
393 else
394 memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
397 for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
398 indirection_string[i] = ps4[j];
400 indirection_string[i] = '\0';
401 free (ps4);
402 return (indirection_string);
405 void
406 xtrace_print_assignment (name, value, assign_list, xflags)
407 char *name, *value;
408 int assign_list, xflags;
410 char *nval;
412 if (xflags)
413 fprintf (stderr, "%s", indirection_level_string ());
415 /* VALUE should not be NULL when this is called. */
416 if (*value == '\0' || assign_list)
417 nval = value;
418 else if (sh_contains_shell_metas (value))
419 nval = sh_single_quote (value);
420 else if (ansic_shouldquote (value))
421 nval = ansic_quote (value, 0, (int *)0);
422 else
423 nval = value;
425 if (assign_list)
426 fprintf (stderr, "%s=(%s)\n", name, nval);
427 else
428 fprintf (stderr, "%s=%s\n", name, nval);
430 if (nval != value)
431 FREE (nval);
433 fflush (stderr);
436 /* A function to print the words of a simple command when set -x is on. */
437 void
438 xtrace_print_word_list (list, xtflags)
439 WORD_LIST *list;
440 int xtflags;
442 WORD_LIST *w;
443 char *t, *x;
445 if (xtflags)
446 fprintf (stderr, "%s", indirection_level_string ());
448 for (w = list; w; w = w->next)
450 t = w->word->word;
451 if (t == 0 || *t == '\0')
452 fprintf (stderr, "''%s", w->next ? " " : "");
453 else if (sh_contains_shell_metas (t))
455 x = sh_single_quote (t);
456 fprintf (stderr, "%s%s", x, w->next ? " " : "");
457 free (x);
459 else if (ansic_shouldquote (t))
461 x = ansic_quote (t, 0, (int *)0);
462 fprintf (stderr, "%s%s", x, w->next ? " " : "");
463 free (x);
465 else
466 fprintf (stderr, "%s%s", t, w->next ? " " : "");
468 fprintf (stderr, "\n");
471 static void
472 command_print_word_list (list, separator)
473 WORD_LIST *list;
474 char *separator;
476 _print_word_list (list, separator, cprintf);
479 void
480 print_for_command_head (for_command)
481 FOR_COM *for_command;
483 cprintf ("for %s in ", for_command->name->word);
484 command_print_word_list (for_command->map_list, " ");
487 void
488 xtrace_print_for_command_head (for_command)
489 FOR_COM *for_command;
491 fprintf (stderr, "%s", indirection_level_string ());
492 fprintf (stderr, "for %s in ", for_command->name->word);
493 xtrace_print_word_list (for_command->map_list, 0);
496 static void
497 print_for_command (for_command)
498 FOR_COM *for_command;
500 print_for_command_head (for_command);
502 cprintf (";");
503 newline ("do\n");
504 indentation += indentation_amount;
505 make_command_string_internal (for_command->action);
506 semicolon ();
507 indentation -= indentation_amount;
508 newline ("done");
511 #if defined (ARITH_FOR_COMMAND)
512 static void
513 print_arith_for_command (arith_for_command)
514 ARITH_FOR_COM *arith_for_command;
516 cprintf ("for ((");
517 command_print_word_list (arith_for_command->init, " ");
518 cprintf ("; ");
519 command_print_word_list (arith_for_command->test, " ");
520 cprintf ("; ");
521 command_print_word_list (arith_for_command->step, " ");
522 cprintf ("))");
523 newline ("do\n");
524 indentation += indentation_amount;
525 make_command_string_internal (arith_for_command->action);
526 semicolon ();
527 indentation -= indentation_amount;
528 newline ("done");
530 #endif /* ARITH_FOR_COMMAND */
532 #if defined (SELECT_COMMAND)
533 void
534 print_select_command_head (select_command)
535 SELECT_COM *select_command;
537 cprintf ("select %s in ", select_command->name->word);
538 command_print_word_list (select_command->map_list, " ");
541 void
542 xtrace_print_select_command_head (select_command)
543 SELECT_COM *select_command;
545 fprintf (stderr, "%s", indirection_level_string ());
546 fprintf (stderr, "select %s in ", select_command->name->word);
547 xtrace_print_word_list (select_command->map_list, 0);
550 static void
551 print_select_command (select_command)
552 SELECT_COM *select_command;
554 print_select_command_head (select_command);
556 cprintf (";");
557 newline ("do\n");
558 indentation += indentation_amount;
559 make_command_string_internal (select_command->action);
560 semicolon ();
561 indentation -= indentation_amount;
562 newline ("done");
564 #endif /* SELECT_COMMAND */
566 static void
567 print_group_command (group_command)
568 GROUP_COM *group_command;
570 group_command_nesting++;
571 cprintf ("{ ");
573 if (inside_function_def == 0)
574 skip_this_indent++;
575 else
577 /* This is a group command { ... } inside of a function
578 definition, and should be printed as a multiline group
579 command, using the current indentation. */
580 cprintf ("\n");
581 indentation += indentation_amount;
584 make_command_string_internal (group_command->command);
586 if (inside_function_def)
588 cprintf ("\n");
589 indentation -= indentation_amount;
590 indent (indentation);
592 else
594 semicolon ();
595 cprintf (" ");
598 cprintf ("}");
600 group_command_nesting--;
603 void
604 print_case_command_head (case_command)
605 CASE_COM *case_command;
607 cprintf ("case %s in ", case_command->word->word);
610 void
611 xtrace_print_case_command_head (case_command)
612 CASE_COM *case_command;
614 fprintf (stderr, "%s", indirection_level_string ());
615 fprintf (stderr, "case %s in\n", case_command->word->word);
618 static void
619 print_case_command (case_command)
620 CASE_COM *case_command;
622 print_case_command_head (case_command);
624 if (case_command->clauses)
625 print_case_clauses (case_command->clauses);
626 newline ("esac");
629 static void
630 print_case_clauses (clauses)
631 PATTERN_LIST *clauses;
633 indentation += indentation_amount;
634 while (clauses)
636 newline ("");
637 command_print_word_list (clauses->patterns, " | ");
638 cprintf (")\n");
639 indentation += indentation_amount;
640 make_command_string_internal (clauses->action);
641 indentation -= indentation_amount;
642 if (clauses->flags & CASEPAT_FALLTHROUGH)
643 newline (";&");
644 else if (clauses->flags & CASEPAT_TESTNEXT)
645 newline (";;&");
646 else
647 newline (";;");
648 clauses = clauses->next;
650 indentation -= indentation_amount;
653 static void
654 print_while_command (while_command)
655 WHILE_COM *while_command;
657 print_until_or_while (while_command, "while");
660 static void
661 print_until_command (while_command)
662 WHILE_COM *while_command;
664 print_until_or_while (while_command, "until");
667 static void
668 print_until_or_while (while_command, which)
669 WHILE_COM *while_command;
670 char *which;
672 cprintf ("%s ", which);
673 skip_this_indent++;
674 make_command_string_internal (while_command->test);
675 semicolon ();
676 cprintf (" do\n"); /* was newline ("do\n"); */
677 indentation += indentation_amount;
678 make_command_string_internal (while_command->action);
679 indentation -= indentation_amount;
680 semicolon ();
681 newline ("done");
684 static void
685 print_if_command (if_command)
686 IF_COM *if_command;
688 cprintf ("if ");
689 skip_this_indent++;
690 make_command_string_internal (if_command->test);
691 semicolon ();
692 cprintf (" then\n");
693 indentation += indentation_amount;
694 make_command_string_internal (if_command->true_case);
695 indentation -= indentation_amount;
697 if (if_command->false_case)
699 semicolon ();
700 newline ("else\n");
701 indentation += indentation_amount;
702 make_command_string_internal (if_command->false_case);
703 indentation -= indentation_amount;
705 semicolon ();
706 newline ("fi");
709 #if defined (DPAREN_ARITHMETIC)
710 void
711 print_arith_command (arith_cmd_list)
712 WORD_LIST *arith_cmd_list;
714 cprintf ("((");
715 command_print_word_list (arith_cmd_list, " ");
716 cprintf ("))");
718 #endif
720 #if defined (COND_COMMAND)
721 static void
722 print_cond_node (cond)
723 COND_COM *cond;
725 if (cond->flags & CMD_INVERT_RETURN)
726 cprintf ("! ");
728 if (cond->type == COND_EXPR)
730 cprintf ("( ");
731 print_cond_node (cond->left);
732 cprintf (" )");
734 else if (cond->type == COND_AND)
736 print_cond_node (cond->left);
737 cprintf (" && ");
738 print_cond_node (cond->right);
740 else if (cond->type == COND_OR)
742 print_cond_node (cond->left);
743 cprintf (" || ");
744 print_cond_node (cond->right);
746 else if (cond->type == COND_UNARY)
748 cprintf ("%s", cond->op->word);
749 cprintf (" ");
750 print_cond_node (cond->left);
752 else if (cond->type == COND_BINARY)
754 print_cond_node (cond->left);
755 cprintf (" ");
756 cprintf ("%s", cond->op->word);
757 cprintf (" ");
758 print_cond_node (cond->right);
760 else if (cond->type == COND_TERM)
762 cprintf ("%s", cond->op->word); /* need to add quoting here */
766 void
767 print_cond_command (cond)
768 COND_COM *cond;
770 cprintf ("[[ ");
771 print_cond_node (cond);
772 cprintf (" ]]");
775 #ifdef DEBUG
776 void
777 debug_print_cond_command (cond)
778 COND_COM *cond;
780 fprintf (stderr, "DEBUG: ");
781 command_string_index = 0;
782 print_cond_command (cond);
783 fprintf (stderr, "%s\n", the_printed_command);
785 #endif
787 void
788 xtrace_print_cond_term (type, invert, op, arg1, arg2)
789 int type, invert;
790 WORD_DESC *op;
791 char *arg1, *arg2;
793 command_string_index = 0;
794 fprintf (stderr, "%s", indirection_level_string ());
795 fprintf (stderr, "[[ ");
796 if (invert)
797 fprintf (stderr, "! ");
799 if (type == COND_UNARY)
801 fprintf (stderr, "%s ", op->word);
802 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
804 else if (type == COND_BINARY)
806 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
807 fprintf (stderr, " %s ", op->word);
808 fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
811 fprintf (stderr, " ]]\n");
813 #endif /* COND_COMMAND */
815 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
816 /* A function to print the words of an arithmetic command when set -x is on. */
817 void
818 xtrace_print_arith_cmd (list)
819 WORD_LIST *list;
821 WORD_LIST *w;
823 fprintf (stderr, "%s", indirection_level_string ());
824 fprintf (stderr, "(( ");
825 for (w = list; w; w = w->next)
826 fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
827 fprintf (stderr, " ))\n");
829 #endif
831 void
832 print_simple_command (simple_command)
833 SIMPLE_COM *simple_command;
835 command_print_word_list (simple_command->words, " ");
837 if (simple_command->redirects)
839 cprintf (" ");
840 print_redirection_list (simple_command->redirects);
844 static void
845 print_heredocs (heredocs)
846 REDIRECT *heredocs;
848 REDIRECT *hdtail;
850 cprintf (" ");
851 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
853 print_redirection (hdtail);
854 cprintf ("\n");
856 was_heredoc = 1;
859 /* Print heredocs that are attached to the command before the connector
860 represented by CSTRING. The parsing semantics require us to print the
861 here-doc delimiters, then the connector (CSTRING), then the here-doc
862 bodies. We don't print the connector if it's a `;', but we use it to
863 note not to print an extra space after the last heredoc body and
864 newline. */
865 static void
866 print_deferred_heredocs (cstring)
867 const char *cstring;
869 REDIRECT *hdtail;
871 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
873 cprintf (" ");
874 print_heredoc_header (hdtail);
876 if (cstring[0] != ';' || cstring[1])
877 cprintf ("%s", cstring);
878 if (deferred_heredocs)
879 cprintf ("\n");
880 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
882 print_heredoc_body (hdtail);
883 cprintf ("\n");
885 if (deferred_heredocs)
887 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
888 cprintf (" "); /* make sure there's at least one space */
889 dispose_redirects (deferred_heredocs);
890 was_heredoc = 1;
892 deferred_heredocs = (REDIRECT *)NULL;
895 static void
896 print_redirection_list (redirects)
897 REDIRECT *redirects;
899 REDIRECT *heredocs, *hdtail, *newredir;
901 heredocs = (REDIRECT *)NULL;
902 hdtail = heredocs;
904 was_heredoc = 0;
905 while (redirects)
907 /* Defer printing the here documents until we've printed the
908 rest of the redirections. */
909 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
911 newredir = copy_redirect (redirects);
912 newredir->next = (REDIRECT *)NULL;
913 if (heredocs)
915 hdtail->next = newredir;
916 hdtail = newredir;
918 else
919 hdtail = heredocs = newredir;
921 else if (redirects->instruction == r_duplicating_output_word && redirects->redirector == 1)
923 /* Temporarily translate it as the execution code does. */
924 redirects->instruction = r_err_and_out;
925 print_redirection (redirects);
926 redirects->instruction = r_duplicating_output_word;
928 else
929 print_redirection (redirects);
931 redirects = redirects->next;
932 if (redirects)
933 cprintf (" ");
936 /* Now that we've printed all the other redirections (on one line),
937 print the here documents. */
938 if (heredocs && printing_connection)
939 deferred_heredocs = heredocs;
940 else if (heredocs)
942 print_heredocs (heredocs);
943 dispose_redirects (heredocs);
947 static void
948 print_heredoc_header (redirect)
949 REDIRECT *redirect;
951 int kill_leading;
952 char *x;
954 kill_leading = redirect->instruction == r_deblank_reading_until;
956 /* Here doc header */
957 if (redirect->redirector != 0)
958 cprintf ("%d", redirect->redirector);
960 /* If the here document delimiter is quoted, single-quote it. */
961 if (redirect->redirectee.filename->flags & W_QUOTED)
963 x = sh_single_quote (redirect->here_doc_eof);
964 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
965 free (x);
967 else
968 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
971 static void
972 print_heredoc_body (redirect)
973 REDIRECT *redirect;
975 /* Here doc body */
976 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
979 static void
980 print_redirection (redirect)
981 REDIRECT *redirect;
983 int kill_leading, redirector, redir_fd;
984 WORD_DESC *redirectee;
986 kill_leading = 0;
987 redirectee = redirect->redirectee.filename;
988 redirector = redirect->redirector;
989 redir_fd = redirect->redirectee.dest;
991 switch (redirect->instruction)
993 case r_output_direction:
994 if (redirector != 1)
995 cprintf ("%d", redirector);
996 cprintf ("> %s", redirectee->word);
997 break;
999 case r_input_direction:
1000 if (redirector != 0)
1001 cprintf ("%d", redirector);
1002 cprintf ("< %s", redirectee->word);
1003 break;
1005 case r_inputa_direction: /* Redirection created by the shell. */
1006 cprintf ("&");
1007 break;
1009 case r_appending_to:
1010 if (redirector != 1)
1011 cprintf ("%d", redirector);
1012 cprintf (">> %s", redirectee->word);
1013 break;
1015 case r_deblank_reading_until:
1016 case r_reading_until:
1017 print_heredoc_header (redirect);
1018 cprintf ("\n");
1019 print_heredoc_body (redirect);
1020 break;
1022 case r_reading_string:
1023 if (redirector != 0)
1024 cprintf ("%d", redirector);
1025 if (ansic_shouldquote (redirect->redirectee.filename->word))
1027 char *x;
1028 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1029 cprintf ("<<< %s", x);
1030 free (x);
1032 else
1033 cprintf ("<<< %s", redirect->redirectee.filename->word);
1034 break;
1036 case r_duplicating_input:
1037 cprintf ("%d<&%d", redirector, redir_fd);
1038 break;
1040 case r_duplicating_output:
1041 cprintf ("%d>&%d", redirector, redir_fd);
1042 break;
1044 case r_duplicating_input_word:
1045 cprintf ("%d<&%s", redirector, redirectee->word);
1046 break;
1048 case r_duplicating_output_word:
1049 cprintf ("%d>&%s", redirector, redirectee->word);
1050 break;
1052 case r_move_input:
1053 cprintf ("%d<&%d-", redirector, redir_fd);
1054 break;
1056 case r_move_output:
1057 cprintf ("%d>&%d-", redirector, redir_fd);
1058 break;
1060 case r_move_input_word:
1061 cprintf ("%d<&%s-", redirector, redirectee->word);
1062 break;
1064 case r_move_output_word:
1065 cprintf ("%d>&%s-", redirector, redirectee->word);
1066 break;
1068 case r_close_this:
1069 cprintf ("%d>&-", redirector);
1070 break;
1072 case r_err_and_out:
1073 cprintf ("&>%s", redirectee->word);
1074 break;
1076 case r_append_err_and_out:
1077 cprintf ("&>>%s", redirectee->word);
1078 break;
1080 case r_input_output:
1081 if (redirector != 1)
1082 cprintf ("%d", redirector);
1083 cprintf ("<> %s", redirectee->word);
1084 break;
1086 case r_output_force:
1087 if (redirector != 1)
1088 cprintf ("%d", redirector);
1089 cprintf (">|%s", redirectee->word);
1090 break;
1094 static void
1095 reset_locals ()
1097 inside_function_def = 0;
1098 indentation = 0;
1099 printing_connection = 0;
1100 deferred_heredocs = 0;
1103 static void
1104 print_function_def (func)
1105 FUNCTION_DEF *func;
1107 COMMAND *cmdcopy;
1108 REDIRECT *func_redirects;
1110 func_redirects = NULL;
1111 cprintf ("function %s () \n", func->name->word);
1112 add_unwind_protect (reset_locals, 0);
1114 indent (indentation);
1115 cprintf ("{ \n");
1117 inside_function_def++;
1118 indentation += indentation_amount;
1120 cmdcopy = copy_command (func->command);
1121 if (cmdcopy->type == cm_group)
1123 func_redirects = cmdcopy->redirects;
1124 cmdcopy->redirects = (REDIRECT *)NULL;
1126 make_command_string_internal (cmdcopy->type == cm_group
1127 ? cmdcopy->value.Group->command
1128 : cmdcopy);
1130 remove_unwind_protect ();
1131 indentation -= indentation_amount;
1132 inside_function_def--;
1134 if (func_redirects)
1135 { /* { */
1136 newline ("} ");
1137 print_redirection_list (func_redirects);
1138 cmdcopy->redirects = func_redirects;
1140 else
1141 newline ("}");
1143 dispose_command (cmdcopy);
1146 /* Return the string representation of the named function.
1147 NAME is the name of the function.
1148 COMMAND is the function body. It should be a GROUP_COM.
1149 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1150 flags&FUNC_EXTERNAL means convert from internal to external form
1152 char *
1153 named_function_string (name, command, flags)
1154 char *name;
1155 COMMAND *command;
1156 int flags;
1158 char *result;
1159 int old_indent, old_amount;
1160 COMMAND *cmdcopy;
1161 REDIRECT *func_redirects;
1163 old_indent = indentation;
1164 old_amount = indentation_amount;
1165 command_string_index = was_heredoc = 0;
1166 deferred_heredocs = 0;
1168 if (name && *name)
1169 cprintf ("%s ", name);
1171 cprintf ("() ");
1173 if ((flags & FUNC_MULTILINE) == 0)
1175 indentation = 1;
1176 indentation_amount = 0;
1178 else
1180 cprintf ("\n");
1181 indentation += indentation_amount;
1184 inside_function_def++;
1186 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1188 cmdcopy = copy_command (command);
1189 /* Take any redirections specified in the function definition (which should
1190 apply to the function as a whole) and save them for printing later. */
1191 func_redirects = (REDIRECT *)NULL;
1192 if (cmdcopy->type == cm_group)
1194 func_redirects = cmdcopy->redirects;
1195 cmdcopy->redirects = (REDIRECT *)NULL;
1197 make_command_string_internal (cmdcopy->type == cm_group
1198 ? cmdcopy->value.Group->command
1199 : cmdcopy);
1201 indentation = old_indent;
1202 indentation_amount = old_amount;
1203 inside_function_def--;
1205 if (func_redirects)
1206 { /* { */
1207 newline ("} ");
1208 print_redirection_list (func_redirects);
1209 cmdcopy->redirects = func_redirects;
1211 else
1212 newline ("}");
1214 result = the_printed_command;
1216 if ((flags & FUNC_MULTILINE) == 0)
1218 #if 0
1219 register int i;
1220 for (i = 0; result[i]; i++)
1221 if (result[i] == '\n')
1223 strcpy (result + i, result + i + 1);
1224 --i;
1226 #else
1227 if (result[2] == '\n') /* XXX -- experimental */
1228 strcpy (result + 2, result + 3);
1229 #endif
1232 dispose_command (cmdcopy);
1234 if (flags & FUNC_EXTERNAL)
1235 result = remove_quoted_escapes (result);
1237 return (result);
1240 static void
1241 newline (string)
1242 char *string;
1244 cprintf ("\n");
1245 indent (indentation);
1246 if (string && *string)
1247 cprintf ("%s", string);
1250 static char *indentation_string;
1251 static int indentation_size;
1253 static void
1254 indent (amount)
1255 int amount;
1257 register int i;
1259 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1261 for (i = 0; amount > 0; amount--)
1262 indentation_string[i++] = ' ';
1263 indentation_string[i] = '\0';
1264 cprintf (indentation_string);
1267 static void
1268 semicolon ()
1270 if (command_string_index > 0 &&
1271 (the_printed_command[command_string_index - 1] == '&' ||
1272 the_printed_command[command_string_index - 1] == '\n'))
1273 return;
1274 cprintf (";");
1277 /* How to make the string. */
1278 static void
1279 #if defined (PREFER_STDARG)
1280 cprintf (const char *control, ...)
1281 #else
1282 cprintf (control, va_alist)
1283 const char *control;
1284 va_dcl
1285 #endif
1287 register const char *s;
1288 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1289 int digit_arg, arg_len, c;
1290 va_list args;
1292 SH_VA_START (args, control);
1294 arg_len = strlen (control);
1295 the_printed_command_resize (arg_len + 1);
1297 char_arg[1] = '\0';
1298 s = control;
1299 while (s && *s)
1301 c = *s++;
1302 argp = (char *)NULL;
1303 if (c != '%' || !*s)
1305 char_arg[0] = c;
1306 argp = char_arg;
1307 arg_len = 1;
1309 else
1311 c = *s++;
1312 switch (c)
1314 case '%':
1315 char_arg[0] = c;
1316 argp = char_arg;
1317 arg_len = 1;
1318 break;
1320 case 's':
1321 argp = va_arg (args, char *);
1322 arg_len = strlen (argp);
1323 break;
1325 case 'd':
1326 /* Represent an out-of-range file descriptor with an out-of-range
1327 integer value. We can do this because the only use of `%d' in
1328 the calls to cprintf is to output a file descriptor number for
1329 a redirection. */
1330 digit_arg = va_arg (args, int);
1331 if (digit_arg < 0)
1333 sprintf (intbuf, "%u", (unsigned)-1);
1334 argp = intbuf;
1336 else
1337 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1338 arg_len = strlen (argp);
1339 break;
1341 case 'c':
1342 char_arg[0] = va_arg (args, int);
1343 argp = char_arg;
1344 arg_len = 1;
1345 break;
1347 default:
1348 programming_error (_("cprintf: `%c': invalid format character"), c);
1349 /*NOTREACHED*/
1353 if (argp && arg_len)
1355 the_printed_command_resize (arg_len + 1);
1356 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1357 command_string_index += arg_len;
1361 the_printed_command[command_string_index] = '\0';
1364 /* Ensure that there is enough space to stuff LENGTH characters into
1365 THE_PRINTED_COMMAND. */
1366 static void
1367 the_printed_command_resize (length)
1368 int length;
1370 if (the_printed_command == 0)
1372 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1373 the_printed_command = (char *)xmalloc (the_printed_command_size);
1374 command_string_index = 0;
1376 else if ((command_string_index + length) >= the_printed_command_size)
1378 int new;
1379 new = command_string_index + length + 1;
1381 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1382 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1383 the_printed_command_size = new;
1385 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1389 #if defined (HAVE_VPRINTF)
1390 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1391 also available.'' */
1393 static void
1394 #if defined (PREFER_STDARG)
1395 xprintf (const char *format, ...)
1396 #else
1397 xprintf (format, va_alist)
1398 const char *format;
1399 va_dcl
1400 #endif
1402 va_list args;
1404 SH_VA_START (args, format);
1406 vfprintf (stdout, format, args);
1407 va_end (args);
1410 #else
1412 static void
1413 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1414 const char *format;
1416 printf (format, arg1, arg2, arg3, arg4, arg5);
1419 #endif /* !HAVE_VPRINTF */