Added a git ignore file
[bash.git] / print_cmd.c
blob0d646ec5cbd524f856b500e44c624067f0823bb5
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/>.
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 int xtrace_fd = -1;
112 FILE *xtrace_fp = 0;
114 #define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
116 #define PRINT_DEFERRED_HEREDOCS(x) \
117 do { \
118 if (deferred_heredocs) \
119 print_deferred_heredocs (x); \
120 } while (0)
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. */
137 void
138 print_command (command)
139 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
148 remain around. */
149 char *
150 make_command_string (command)
151 COMMAND *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. */
160 static void
161 make_command_string_internal (command)
162 COMMAND *command;
164 char s[3];
166 if (command == 0)
167 cprintf ("");
168 else
170 if (skip_this_indent)
171 skip_this_indent--;
172 else
173 indent (indentation);
175 if (command->flags & CMD_TIME_PIPELINE)
177 cprintf ("time ");
178 if (command->flags & CMD_TIME_POSIX)
179 cprintf ("-p ");
182 if (command->flags & CMD_INVERT_RETURN)
183 cprintf ("! ");
185 switch (command->type)
187 case cm_for:
188 print_for_command (command->value.For);
189 break;
191 #if defined (ARITH_FOR_COMMAND)
192 case cm_arith_for:
193 print_arith_for_command (command->value.ArithFor);
194 break;
195 #endif
197 #if defined (SELECT_COMMAND)
198 case cm_select:
199 print_select_command (command->value.Select);
200 break;
201 #endif
203 case cm_case:
204 print_case_command (command->value.Case);
205 break;
207 case cm_while:
208 print_while_command (command->value.While);
209 break;
211 case cm_until:
212 print_until_command (command->value.While);
213 break;
215 case cm_if:
216 print_if_command (command->value.If);
217 break;
219 #if defined (DPAREN_ARITHMETIC)
220 case cm_arith:
221 print_arith_command (command->value.Arith->exp);
222 break;
223 #endif
225 #if defined (COND_COMMAND)
226 case cm_cond:
227 print_cond_command (command->value.Cond);
228 break;
229 #endif
231 case cm_simple:
232 print_simple_command (command->value.Simple);
233 break;
235 case cm_connection:
237 skip_this_indent++;
238 printing_connection++;
239 make_command_string_internal (command->value.Connection->first);
241 switch (command->value.Connection->connector)
243 case '&':
244 case '|':
246 char c = command->value.Connection->connector;
248 s[0] = ' ';
249 s[1] = c;
250 s[2] = '\0';
252 print_deferred_heredocs (s);
254 if (c != '&' || command->value.Connection->second)
256 cprintf (" ");
257 skip_this_indent++;
260 break;
262 case AND_AND:
263 print_deferred_heredocs (" && ");
264 if (command->value.Connection->second)
265 skip_this_indent++;
266 break;
268 case OR_OR:
269 print_deferred_heredocs (" || ");
270 if (command->value.Connection->second)
271 skip_this_indent++;
272 break;
274 case ';':
275 if (deferred_heredocs == 0)
277 if (was_heredoc == 0)
278 cprintf (";");
279 else
280 was_heredoc = 0;
282 else
283 print_deferred_heredocs (inside_function_def ? "" : ";");
285 if (inside_function_def)
286 cprintf ("\n");
287 else
289 cprintf (" ");
290 if (command->value.Connection->second)
291 skip_this_indent++;
293 break;
295 default:
296 cprintf (_("print_command: bad connector `%d'"),
297 command->value.Connection->connector);
298 break;
301 make_command_string_internal (command->value.Connection->second);
302 PRINT_DEFERRED_HEREDOCS ("");
303 printing_connection--;
304 break;
306 case cm_function_def:
307 print_function_def (command->value.Function_def);
308 break;
310 case cm_group:
311 print_group_command (command->value.Group);
312 break;
314 case cm_subshell:
315 cprintf ("( ");
316 skip_this_indent++;
317 make_command_string_internal (command->value.Subshell->command);
318 cprintf (" )");
319 break;
321 case cm_coproc:
322 cprintf ("coproc %s ", command->value.Coproc->name);
323 skip_this_indent++;
324 make_command_string_internal (command->value.Coproc->command);
325 break;
327 default:
328 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
329 break;
333 if (command->redirects)
335 cprintf (" ");
336 print_redirection_list (command->redirects);
341 static void
342 _print_word_list (list, separator, pfunc)
343 WORD_LIST *list;
344 char *separator;
345 PFUNC *pfunc;
347 WORD_LIST *w;
349 for (w = list; w; w = w->next)
350 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
353 void
354 print_word_list (list, separator)
355 WORD_LIST *list;
356 char *separator;
358 _print_word_list (list, separator, xprintf);
361 void
362 xtrace_set (fd, fp)
363 int fd;
364 FILE *fp;
366 if (fd >= 0 && sh_validfd (fd) == 0)
368 internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
369 return;
371 if (fp == 0)
373 internal_error (_("xtrace_set: NULL file pointer"));
374 return;
376 if (fd >= 0 && fileno (fp) != fd)
377 internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
379 xtrace_fd = fd;
380 xtrace_fp = fp;
383 void
384 xtrace_init ()
386 xtrace_set (-1, stderr);
389 void
390 xtrace_reset ()
392 if (xtrace_fd >= 0 && xtrace_fp)
394 fflush (xtrace_fp);
395 fclose (xtrace_fp);
397 else if (xtrace_fd >= 0)
398 close (xtrace_fd);
400 xtrace_fd = -1;
401 xtrace_fp = stderr;
404 void
405 xtrace_fdchk (fd)
406 int fd;
408 if (fd == xtrace_fd)
409 xtrace_reset ();
412 /* Return a string denoting what our indirection level is. */
414 char *
415 indirection_level_string ()
417 register int i, j;
418 char *ps4;
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';
443 else
444 memcpy (ps4_firstc, ps4, ps4_firstc_len);
445 #else
446 ps4_firstc[0] = ps4[0];
447 ps4_firstc[ps4_firstc_len = 1] = '\0';
448 #endif
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];
454 else
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';
462 free (ps4);
463 return (indirection_string);
466 void
467 xtrace_print_assignment (name, value, assign_list, xflags)
468 char *name, *value;
469 int assign_list, xflags;
471 char *nval;
473 CHECK_XTRACE_FP;
475 if (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)
480 nval = value;
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);
485 else
486 nval = value;
488 if (assign_list)
489 fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
490 else
491 fprintf (xtrace_fp, "%s=%s\n", name, nval);
493 if (nval != value)
494 FREE (nval);
496 fflush (xtrace_fp);
499 /* A function to print the words of a simple command when set -x is on. */
500 void
501 xtrace_print_word_list (list, xtflags)
502 WORD_LIST *list;
503 int xtflags;
505 WORD_LIST *w;
506 char *t, *x;
508 CHECK_XTRACE_FP;
510 if (xtflags)
511 fprintf (xtrace_fp, "%s", indirection_level_string ());
513 for (w = list; w; w = w->next)
515 t = w->word->word;
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 ? " " : "");
522 free (x);
524 else if (ansic_shouldquote (t))
526 x = ansic_quote (t, 0, (int *)0);
527 fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
528 free (x);
530 else
531 fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
533 fprintf (xtrace_fp, "\n");
534 fflush (xtrace_fp);
537 static void
538 command_print_word_list (list, separator)
539 WORD_LIST *list;
540 char *separator;
542 _print_word_list (list, separator, cprintf);
545 void
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, " ");
553 void
554 xtrace_print_for_command_head (for_command)
555 FOR_COM *for_command;
557 CHECK_XTRACE_FP;
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);
563 static void
564 print_for_command (for_command)
565 FOR_COM *for_command;
567 print_for_command_head (for_command);
568 cprintf (";");
569 newline ("do\n");
571 indentation += indentation_amount;
572 make_command_string_internal (for_command->action);
573 PRINT_DEFERRED_HEREDOCS ("");
574 semicolon ();
575 indentation -= indentation_amount;
577 newline ("done");
580 #if defined (ARITH_FOR_COMMAND)
581 static void
582 print_arith_for_command (arith_for_command)
583 ARITH_FOR_COM *arith_for_command;
585 cprintf ("for ((");
586 command_print_word_list (arith_for_command->init, " ");
587 cprintf ("; ");
588 command_print_word_list (arith_for_command->test, " ");
589 cprintf ("; ");
590 command_print_word_list (arith_for_command->step, " ");
591 cprintf ("))");
592 newline ("do\n");
593 indentation += indentation_amount;
594 make_command_string_internal (arith_for_command->action);
595 semicolon ();
596 indentation -= indentation_amount;
597 newline ("done");
599 #endif /* ARITH_FOR_COMMAND */
601 #if defined (SELECT_COMMAND)
602 void
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, " ");
610 void
611 xtrace_print_select_command_head (select_command)
612 SELECT_COM *select_command;
614 CHECK_XTRACE_FP;
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);
620 static void
621 print_select_command (select_command)
622 SELECT_COM *select_command;
624 print_select_command_head (select_command);
626 cprintf (";");
627 newline ("do\n");
628 indentation += indentation_amount;
629 make_command_string_internal (select_command->action);
630 PRINT_DEFERRED_HEREDOCS ("");
631 semicolon ();
632 indentation -= indentation_amount;
633 newline ("done");
635 #endif /* SELECT_COMMAND */
637 static void
638 print_group_command (group_command)
639 GROUP_COM *group_command;
641 group_command_nesting++;
642 cprintf ("{ ");
644 if (inside_function_def == 0)
645 skip_this_indent++;
646 else
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. */
651 cprintf ("\n");
652 indentation += indentation_amount;
655 make_command_string_internal (group_command->command);
657 if (inside_function_def)
659 cprintf ("\n");
660 indentation -= indentation_amount;
661 indent (indentation);
663 else
665 semicolon ();
666 cprintf (" ");
669 cprintf ("}");
671 group_command_nesting--;
674 void
675 print_case_command_head (case_command)
676 CASE_COM *case_command;
678 cprintf ("case %s in ", case_command->word->word);
681 void
682 xtrace_print_case_command_head (case_command)
683 CASE_COM *case_command;
685 CHECK_XTRACE_FP;
686 fprintf (xtrace_fp, "%s", indirection_level_string ());
687 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
690 static void
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);
698 newline ("esac");
701 static void
702 print_case_clauses (clauses)
703 PATTERN_LIST *clauses;
705 indentation += indentation_amount;
706 while (clauses)
708 newline ("");
709 command_print_word_list (clauses->patterns, " | ");
710 cprintf (")\n");
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)
716 newline (";&");
717 else if (clauses->flags & CASEPAT_TESTNEXT)
718 newline (";;&");
719 else
720 newline (";;");
721 clauses = clauses->next;
723 indentation -= indentation_amount;
726 static void
727 print_while_command (while_command)
728 WHILE_COM *while_command;
730 print_until_or_while (while_command, "while");
733 static void
734 print_until_command (while_command)
735 WHILE_COM *while_command;
737 print_until_or_while (while_command, "until");
740 static void
741 print_until_or_while (while_command, which)
742 WHILE_COM *while_command;
743 char *which;
745 cprintf ("%s ", which);
746 skip_this_indent++;
747 make_command_string_internal (while_command->test);
748 PRINT_DEFERRED_HEREDOCS ("");
749 semicolon ();
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;
755 semicolon ();
756 newline ("done");
759 static void
760 print_if_command (if_command)
761 IF_COM *if_command;
763 cprintf ("if ");
764 skip_this_indent++;
765 make_command_string_internal (if_command->test);
766 semicolon ();
767 cprintf (" then\n");
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)
775 semicolon ();
776 newline ("else\n");
777 indentation += indentation_amount;
778 make_command_string_internal (if_command->false_case);
779 PRINT_DEFERRED_HEREDOCS ("");
780 indentation -= indentation_amount;
782 semicolon ();
783 newline ("fi");
786 #if defined (DPAREN_ARITHMETIC)
787 void
788 print_arith_command (arith_cmd_list)
789 WORD_LIST *arith_cmd_list;
791 cprintf ("((");
792 command_print_word_list (arith_cmd_list, " ");
793 cprintf ("))");
795 #endif
797 #if defined (COND_COMMAND)
798 static void
799 print_cond_node (cond)
800 COND_COM *cond;
802 if (cond->flags & CMD_INVERT_RETURN)
803 cprintf ("! ");
805 if (cond->type == COND_EXPR)
807 cprintf ("( ");
808 print_cond_node (cond->left);
809 cprintf (" )");
811 else if (cond->type == COND_AND)
813 print_cond_node (cond->left);
814 cprintf (" && ");
815 print_cond_node (cond->right);
817 else if (cond->type == COND_OR)
819 print_cond_node (cond->left);
820 cprintf (" || ");
821 print_cond_node (cond->right);
823 else if (cond->type == COND_UNARY)
825 cprintf ("%s", cond->op->word);
826 cprintf (" ");
827 print_cond_node (cond->left);
829 else if (cond->type == COND_BINARY)
831 print_cond_node (cond->left);
832 cprintf (" ");
833 cprintf ("%s", cond->op->word);
834 cprintf (" ");
835 print_cond_node (cond->right);
837 else if (cond->type == COND_TERM)
839 cprintf ("%s", cond->op->word); /* need to add quoting here */
843 void
844 print_cond_command (cond)
845 COND_COM *cond;
847 cprintf ("[[ ");
848 print_cond_node (cond);
849 cprintf (" ]]");
852 #ifdef DEBUG
853 void
854 debug_print_cond_command (cond)
855 COND_COM *cond;
857 fprintf (stderr, "DEBUG: ");
858 command_string_index = 0;
859 print_cond_command (cond);
860 fprintf (stderr, "%s\n", the_printed_command);
862 #endif
864 void
865 xtrace_print_cond_term (type, invert, op, arg1, arg2)
866 int type, invert;
867 WORD_DESC *op;
868 char *arg1, *arg2;
870 CHECK_XTRACE_FP;
871 command_string_index = 0;
872 fprintf (xtrace_fp, "%s", indirection_level_string ());
873 fprintf (xtrace_fp, "[[ ");
874 if (invert)
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");
891 fflush (xtrace_fp);
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. */
897 void
898 xtrace_print_arith_cmd (list)
899 WORD_LIST *list;
901 WORD_LIST *w;
903 CHECK_XTRACE_FP;
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");
910 fflush (xtrace_fp);
912 #endif
914 void
915 print_simple_command (simple_command)
916 SIMPLE_COM *simple_command;
918 command_print_word_list (simple_command->words, " ");
920 if (simple_command->redirects)
922 cprintf (" ");
923 print_redirection_list (simple_command->redirects);
927 static void
928 print_heredocs (heredocs)
929 REDIRECT *heredocs;
931 REDIRECT *hdtail;
933 cprintf (" ");
934 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
936 print_redirection (hdtail);
937 cprintf ("\n");
939 was_heredoc = 1;
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
947 newline. */
948 static void
949 print_deferred_heredocs (cstring)
950 const char *cstring;
952 REDIRECT *hdtail;
954 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
956 cprintf (" ");
957 print_heredoc_header (hdtail);
959 if (cstring[0] && (cstring[0] != ';' || cstring[1]))
960 cprintf ("%s", cstring);
961 if (deferred_heredocs)
962 cprintf ("\n");
963 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
965 print_heredoc_body (hdtail);
966 cprintf ("\n");
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);
973 was_heredoc = 1;
975 deferred_heredocs = (REDIRECT *)NULL;
978 static void
979 print_redirection_list (redirects)
980 REDIRECT *redirects;
982 REDIRECT *heredocs, *hdtail, *newredir;
984 heredocs = (REDIRECT *)NULL;
985 hdtail = heredocs;
987 was_heredoc = 0;
988 while (redirects)
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;
996 if (heredocs)
998 hdtail->next = newredir;
999 hdtail = newredir;
1001 else
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;
1011 else
1012 print_redirection (redirects);
1014 redirects = redirects->next;
1015 if (redirects)
1016 cprintf (" ");
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;
1023 else if (heredocs)
1025 print_heredocs (heredocs);
1026 dispose_redirects (heredocs);
1030 static void
1031 print_heredoc_header (redirect)
1032 REDIRECT *redirect;
1034 int kill_leading;
1035 char *x;
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);
1050 free (x);
1052 else
1053 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1056 static void
1057 print_heredoc_body (redirect)
1058 REDIRECT *redirect;
1060 /* Here doc body */
1061 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1064 static void
1065 print_redirection (redirect)
1066 REDIRECT *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);
1085 break;
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);
1093 break;
1095 case r_inputa_direction: /* Redirection created by the shell. */
1096 cprintf ("&");
1097 break;
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);
1105 break;
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);
1113 break;
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);
1121 break;
1123 case r_deblank_reading_until:
1124 case r_reading_until:
1125 print_heredoc_header (redirect);
1126 cprintf ("\n");
1127 print_heredoc_body (redirect);
1128 break;
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);
1135 #if 0
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))
1141 char *x;
1142 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1143 cprintf ("<<< %s", x);
1144 free (x);
1146 else
1147 #endif
1148 cprintf ("<<< %s", redirect->redirectee.filename->word);
1149 break;
1151 case r_duplicating_input:
1152 if (redirect->rflags & REDIR_VARASSIGN)
1153 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1154 else
1155 cprintf ("%d<&%d", redirector, redir_fd);
1156 break;
1158 case r_duplicating_output:
1159 if (redirect->rflags & REDIR_VARASSIGN)
1160 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1161 else
1162 cprintf ("%d>&%d", redirector, redir_fd);
1163 break;
1165 case r_duplicating_input_word:
1166 if (redirect->rflags & REDIR_VARASSIGN)
1167 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1168 else
1169 cprintf ("%d<&%s", redirector, redirectee->word);
1170 break;
1172 case r_duplicating_output_word:
1173 if (redirect->rflags & REDIR_VARASSIGN)
1174 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1175 else
1176 cprintf ("%d>&%s", redirector, redirectee->word);
1177 break;
1179 case r_move_input:
1180 if (redirect->rflags & REDIR_VARASSIGN)
1181 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1182 else
1183 cprintf ("%d<&%d-", redirector, redir_fd);
1184 break;
1186 case r_move_output:
1187 if (redirect->rflags & REDIR_VARASSIGN)
1188 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1189 else
1190 cprintf ("%d>&%d-", redirector, redir_fd);
1191 break;
1193 case r_move_input_word:
1194 if (redirect->rflags & REDIR_VARASSIGN)
1195 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1196 else
1197 cprintf ("%d<&%s-", redirector, redirectee->word);
1198 break;
1200 case r_move_output_word:
1201 if (redirect->rflags & REDIR_VARASSIGN)
1202 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1203 else
1204 cprintf ("%d>&%s-", redirector, redirectee->word);
1205 break;
1207 case r_close_this:
1208 if (redirect->rflags & REDIR_VARASSIGN)
1209 cprintf ("{%s}>&-", redir_word->word);
1210 else
1211 cprintf ("%d>&-", redirector);
1212 break;
1214 case r_err_and_out:
1215 cprintf ("&>%s", redirectee->word);
1216 break;
1218 case r_append_err_and_out:
1219 cprintf ("&>>%s", redirectee->word);
1220 break;
1224 static void
1225 reset_locals ()
1227 inside_function_def = 0;
1228 indentation = 0;
1229 printing_connection = 0;
1230 deferred_heredocs = 0;
1233 static void
1234 print_function_def (func)
1235 FUNCTION_DEF *func;
1237 COMMAND *cmdcopy;
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);
1245 cprintf ("{ \n");
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
1258 : cmdcopy);
1260 remove_unwind_protect ();
1261 indentation -= indentation_amount;
1262 inside_function_def--;
1264 if (func_redirects)
1265 { /* { */
1266 newline ("} ");
1267 print_redirection_list (func_redirects);
1268 cmdcopy->redirects = func_redirects;
1270 else
1271 newline ("}");
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
1282 char *
1283 named_function_string (name, command, flags)
1284 char *name;
1285 COMMAND *command;
1286 int flags;
1288 char *result;
1289 int old_indent, old_amount;
1290 COMMAND *cmdcopy;
1291 REDIRECT *func_redirects;
1293 old_indent = indentation;
1294 old_amount = indentation_amount;
1295 command_string_index = was_heredoc = 0;
1296 deferred_heredocs = 0;
1298 if (name && *name)
1299 cprintf ("%s ", name);
1301 cprintf ("() ");
1303 if ((flags & FUNC_MULTILINE) == 0)
1305 indentation = 1;
1306 indentation_amount = 0;
1308 else
1310 cprintf ("\n");
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
1329 : cmdcopy);
1331 indentation = old_indent;
1332 indentation_amount = old_amount;
1333 inside_function_def--;
1335 if (func_redirects)
1336 { /* { */
1337 newline ("} ");
1338 print_redirection_list (func_redirects);
1339 cmdcopy->redirects = func_redirects;
1341 else
1342 newline ("}");
1344 result = the_printed_command;
1346 if ((flags & FUNC_MULTILINE) == 0)
1348 #if 0
1349 register int i;
1350 for (i = 0; result[i]; i++)
1351 if (result[i] == '\n')
1353 strcpy (result + i, result + i + 1);
1354 --i;
1356 #else
1357 if (result[2] == '\n') /* XXX -- experimental */
1358 strcpy (result + 2, result + 3);
1359 #endif
1362 dispose_command (cmdcopy);
1364 if (flags & FUNC_EXTERNAL)
1365 result = remove_quoted_escapes (result);
1367 return (result);
1370 static void
1371 newline (string)
1372 char *string;
1374 cprintf ("\n");
1375 indent (indentation);
1376 if (string && *string)
1377 cprintf ("%s", string);
1380 static char *indentation_string;
1381 static int indentation_size;
1383 static void
1384 indent (amount)
1385 int amount;
1387 register int i;
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);
1397 static void
1398 semicolon ()
1400 if (command_string_index > 0 &&
1401 (the_printed_command[command_string_index - 1] == '&' ||
1402 the_printed_command[command_string_index - 1] == '\n'))
1403 return;
1404 cprintf (";");
1407 /* How to make the string. */
1408 static void
1409 #if defined (PREFER_STDARG)
1410 cprintf (const char *control, ...)
1411 #else
1412 cprintf (control, va_alist)
1413 const char *control;
1414 va_dcl
1415 #endif
1417 register const char *s;
1418 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1419 int digit_arg, arg_len, c;
1420 va_list args;
1422 SH_VA_START (args, control);
1424 arg_len = strlen (control);
1425 the_printed_command_resize (arg_len + 1);
1427 char_arg[1] = '\0';
1428 s = control;
1429 while (s && *s)
1431 c = *s++;
1432 argp = (char *)NULL;
1433 if (c != '%' || !*s)
1435 char_arg[0] = c;
1436 argp = char_arg;
1437 arg_len = 1;
1439 else
1441 c = *s++;
1442 switch (c)
1444 case '%':
1445 char_arg[0] = c;
1446 argp = char_arg;
1447 arg_len = 1;
1448 break;
1450 case 's':
1451 argp = va_arg (args, char *);
1452 arg_len = strlen (argp);
1453 break;
1455 case 'd':
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
1459 a redirection. */
1460 digit_arg = va_arg (args, int);
1461 if (digit_arg < 0)
1463 sprintf (intbuf, "%u", (unsigned)-1);
1464 argp = intbuf;
1466 else
1467 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1468 arg_len = strlen (argp);
1469 break;
1471 case 'c':
1472 char_arg[0] = va_arg (args, int);
1473 argp = char_arg;
1474 arg_len = 1;
1475 break;
1477 default:
1478 programming_error (_("cprintf: `%c': invalid format character"), c);
1479 /*NOTREACHED*/
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. */
1496 static void
1497 the_printed_command_resize (length)
1498 int 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)
1508 int new;
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.'' */
1523 static void
1524 #if defined (PREFER_STDARG)
1525 xprintf (const char *format, ...)
1526 #else
1527 xprintf (format, va_alist)
1528 const char *format;
1529 va_dcl
1530 #endif
1532 va_list args;
1534 SH_VA_START (args, format);
1536 vfprintf (stdout, format, args);
1537 va_end (args);
1540 #else
1542 static void
1543 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1544 const char *format;
1546 printf (format, arg1, arg2, arg3, arg4, arg5);
1549 #endif /* !HAVE_VPRINTF */