285d8fffc8c39d5626ec950529c49a90d6032029
[platform/upstream/bash.git] / print_cmd.c
1 /* print_command -- A way to make readable commands from a command tree. */
2
3 /* Copyright (C) 1989-2009 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
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.
11
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.
16
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/>.
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24
25 #if defined (HAVE_UNISTD_H)
26 #  ifdef _MINIX
27 #    include <sys/types.h>
28 #  endif
29 #  include <unistd.h>
30 #endif
31
32 #if defined (PREFER_STDARG)
33 #  include <stdarg.h>
34 #else
35 #  include <varargs.h>
36 #endif
37
38 #include "bashansi.h"
39 #include "bashintl.h"
40
41 #include "shell.h"
42 #include "flags.h"
43 #include <y.tab.h>      /* use <...> so we pick it up from the build directory */
44
45 #include "shmbutil.h"
46
47 #include "builtins/common.h"
48
49 #if !HAVE_DECL_PRINTF
50 extern int printf __P((const char *, ...));     /* Yuck.  Double yuck. */
51 #endif
52
53 extern int indirection_level;
54
55 static int indentation;
56 static int indentation_amount = 4;
57
58 #if defined (PREFER_STDARG)
59 typedef void PFUNC __P((const char *, ...));
60
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
68
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));
74
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 *));
85
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 *));
103
104 #define PRINTED_COMMAND_INITIAL_SIZE 64
105 #define PRINTED_COMMAND_GROW_SIZE 128
106
107 char *the_printed_command = (char *)NULL;
108 int the_printed_command_size = 0;
109 int command_string_index = 0;
110
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;
117
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;
121
122 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
123 static char indirection_string[100];
124
125 /* Print COMMAND (a command tree) on standard output. */
126 void
127 print_command (command)
128      COMMAND *command;
129 {
130   command_string_index = 0;
131   printf ("%s", make_command_string (command));
132 }
133
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;
141 {
142   command_string_index = was_heredoc = 0;
143   deferred_heredocs = 0;
144   make_command_string_internal (command);
145   return (the_printed_command);
146 }
147
148 /* The internal function.  This is the real workhorse. */
149 static void
150 make_command_string_internal (command)
151      COMMAND *command;
152 {
153   char s[3], *op;
154
155   if (command == 0)
156     cprintf ("");
157   else
158     {
159       if (skip_this_indent)
160         skip_this_indent--;
161       else
162         indent (indentation);
163
164       if (command->flags & CMD_TIME_PIPELINE)
165         {
166           cprintf ("time ");
167           if (command->flags & CMD_TIME_POSIX)
168             cprintf ("-p ");
169         }
170
171       if (command->flags & CMD_INVERT_RETURN)
172         cprintf ("! ");
173
174       switch (command->type)
175         {
176         case cm_for:
177           print_for_command (command->value.For);
178           break;
179
180 #if defined (ARITH_FOR_COMMAND)
181         case cm_arith_for:
182           print_arith_for_command (command->value.ArithFor);
183           break;
184 #endif
185
186 #if defined (SELECT_COMMAND)
187         case cm_select:
188           print_select_command (command->value.Select);
189           break;
190 #endif
191
192         case cm_case:
193           print_case_command (command->value.Case);
194           break;
195
196         case cm_while:
197           print_while_command (command->value.While);
198           break;
199
200         case cm_until:
201           print_until_command (command->value.While);
202           break;
203
204         case cm_if:
205           print_if_command (command->value.If);
206           break;
207
208 #if defined (DPAREN_ARITHMETIC)
209         case cm_arith:
210           print_arith_command (command->value.Arith->exp);
211           break;
212 #endif
213
214 #if defined (COND_COMMAND)
215         case cm_cond:
216           print_cond_command (command->value.Cond);
217           break;
218 #endif
219
220         case cm_simple:
221           print_simple_command (command->value.Simple);
222           break;
223
224         case cm_connection:
225
226           skip_this_indent++;
227           printing_connection++;
228           make_command_string_internal (command->value.Connection->first);
229
230           switch (command->value.Connection->connector)
231             {
232             case '&':
233             case '|':
234               {
235                 char c = command->value.Connection->connector;
236
237                 s[0] = ' ';
238                 s[1] = c;
239                 s[2] = '\0';
240                 
241                 print_deferred_heredocs (s);
242
243                 if (c != '&' || command->value.Connection->second)
244                   {
245                     cprintf (" ");
246                     skip_this_indent++;
247                   }
248               }
249               break;
250
251             case AND_AND:
252               print_deferred_heredocs (" && ");
253               if (command->value.Connection->second)
254                 skip_this_indent++;
255               break;
256
257             case OR_OR:
258               print_deferred_heredocs (" || ");
259               if (command->value.Connection->second)
260                 skip_this_indent++;
261               break;
262
263             case ';':
264               if (deferred_heredocs == 0)
265                 {
266                   if (was_heredoc == 0)
267                     cprintf (";");
268                   else
269                     was_heredoc = 0;
270                 }
271               else
272                 print_deferred_heredocs (inside_function_def ? "" : ";");
273
274               if (inside_function_def)
275                 cprintf ("\n");
276               else
277                 {
278                   cprintf (" ");
279                   if (command->value.Connection->second)
280                     skip_this_indent++;
281                 }
282               break;
283
284             default:
285               cprintf (_("print_command: bad connector `%d'"),
286                        command->value.Connection->connector);
287               break;
288             }
289
290           make_command_string_internal (command->value.Connection->second);
291           if (deferred_heredocs)
292             print_deferred_heredocs ("");
293           printing_connection--;                  
294           break;
295
296         case cm_function_def:
297           print_function_def (command->value.Function_def);
298           break;
299
300         case cm_group:
301           print_group_command (command->value.Group);
302           break;
303
304         case cm_subshell:
305           cprintf ("( ");
306           skip_this_indent++;
307           make_command_string_internal (command->value.Subshell->command);
308           cprintf (" )");
309           break;
310
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;
316
317         default:
318           command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
319           break;
320         }
321
322
323       if (command->redirects)
324         {
325           cprintf (" ");
326           print_redirection_list (command->redirects);
327         }
328     }
329 }
330
331 static void
332 _print_word_list (list, separator, pfunc)
333      WORD_LIST *list;
334      char *separator;
335      PFUNC *pfunc;
336 {
337   WORD_LIST *w;
338
339   for (w = list; w; w = w->next)
340     (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
341 }
342
343 void
344 print_word_list (list, separator)
345      WORD_LIST *list;
346      char *separator;
347 {
348   _print_word_list (list, separator, xprintf);
349 }
350
351 /* Return a string denoting what our indirection level is. */
352
353 char *
354 indirection_level_string ()
355 {
356   register int i, j;
357   char *ps4;
358   char ps4_firstc[MB_LEN_MAX+1];
359   int ps4_firstc_len, ps4_len;
360
361   indirection_string[0] = '\0';
362   ps4 = get_string_value ("PS4");
363
364   if (ps4 == 0 || *ps4 == '\0')
365     return (indirection_string);
366
367   change_flag ('x', FLAG_OFF);
368   ps4 = decode_prompt_string (ps4);
369   change_flag ('x', FLAG_ON);
370
371   if (ps4 == 0 || *ps4 == '\0')
372     return (indirection_string);
373
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))
378     {
379       ps4_firstc[0] = ps4[0];
380       ps4_firstc[ps4_firstc_len = 1] = '\0';
381     }
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
388       
389   for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
390     {
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);
395     }      
396
397   for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
398     indirection_string[i] = ps4[j];
399
400   indirection_string[i] = '\0';
401   free (ps4);
402   return (indirection_string);
403 }
404
405 void
406 xtrace_print_assignment (name, value, assign_list, xflags)
407      char *name, *value;
408      int assign_list, xflags;
409 {
410   char *nval;
411
412   if (xflags)
413     fprintf (stderr, "%s", indirection_level_string ());
414
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;
424
425   if (assign_list)
426     fprintf (stderr, "%s=(%s)\n", name, nval);
427   else
428     fprintf (stderr, "%s=%s\n", name, nval);
429
430   if (nval != value)
431     FREE (nval);
432
433   fflush (stderr);
434 }
435
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;
441 {
442   WORD_LIST *w;
443   char *t, *x;
444
445   if (xtflags)
446     fprintf (stderr, "%s", indirection_level_string ());
447
448   for (w = list; w; w = w->next)
449     {
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))
454         {
455           x = sh_single_quote (t);
456           fprintf (stderr, "%s%s", x, w->next ? " " : "");
457           free (x);
458         }
459       else if (ansic_shouldquote (t))
460         {
461           x = ansic_quote (t, 0, (int *)0);
462           fprintf (stderr, "%s%s", x, w->next ? " " : "");
463           free (x);
464         }
465       else
466         fprintf (stderr, "%s%s", t, w->next ? " " : "");
467     }
468   fprintf (stderr, "\n");
469 }
470
471 static void
472 command_print_word_list (list, separator)
473      WORD_LIST *list;
474      char *separator;
475 {
476   _print_word_list (list, separator, cprintf);
477 }
478
479 void
480 print_for_command_head (for_command)
481      FOR_COM *for_command;
482 {
483   cprintf ("for %s in ", for_command->name->word);
484   command_print_word_list (for_command->map_list, " ");
485 }
486
487 void
488 xtrace_print_for_command_head (for_command)
489      FOR_COM *for_command;
490 {
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);
494 }
495
496 static void
497 print_for_command (for_command)
498      FOR_COM *for_command;
499 {
500   print_for_command_head (for_command);
501
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");
509 }
510
511 #if defined (ARITH_FOR_COMMAND)
512 static void
513 print_arith_for_command (arith_for_command)
514      ARITH_FOR_COM *arith_for_command;
515 {
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");
529 }
530 #endif /* ARITH_FOR_COMMAND */
531
532 #if defined (SELECT_COMMAND)
533 void
534 print_select_command_head (select_command)
535      SELECT_COM *select_command;
536 {
537   cprintf ("select %s in ", select_command->name->word);
538   command_print_word_list (select_command->map_list, " ");
539 }
540
541 void
542 xtrace_print_select_command_head (select_command)
543      SELECT_COM *select_command;
544 {
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);
548 }
549
550 static void
551 print_select_command (select_command)
552      SELECT_COM *select_command;
553 {
554   print_select_command_head (select_command);
555
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");
563 }
564 #endif /* SELECT_COMMAND */
565
566 static void
567 print_group_command (group_command)
568      GROUP_COM *group_command;
569 {
570   group_command_nesting++;
571   cprintf ("{ ");
572
573   if (inside_function_def == 0)
574     skip_this_indent++;
575   else
576     {
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;
582     }
583
584   make_command_string_internal (group_command->command);
585
586   if (inside_function_def)
587     {
588       cprintf ("\n");
589       indentation -= indentation_amount;
590       indent (indentation);
591     }
592   else
593     {
594       semicolon ();
595       cprintf (" ");
596     }
597
598   cprintf ("}");
599
600   group_command_nesting--;
601 }
602
603 void
604 print_case_command_head (case_command)
605      CASE_COM *case_command;
606 {
607   cprintf ("case %s in ", case_command->word->word);
608 }
609
610 void
611 xtrace_print_case_command_head (case_command)
612      CASE_COM *case_command;
613 {
614   fprintf (stderr, "%s", indirection_level_string ());
615   fprintf (stderr, "case %s in\n", case_command->word->word);
616 }
617
618 static void
619 print_case_command (case_command)
620      CASE_COM *case_command;
621 {
622   print_case_command_head (case_command);
623
624   if (case_command->clauses)
625     print_case_clauses (case_command->clauses);
626   newline ("esac");
627 }
628
629 static void
630 print_case_clauses (clauses)
631      PATTERN_LIST *clauses;
632 {
633   indentation += indentation_amount;
634   while (clauses)
635     {
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;
649     }
650   indentation -= indentation_amount;
651 }
652
653 static void
654 print_while_command (while_command)
655      WHILE_COM *while_command;
656 {
657   print_until_or_while (while_command, "while");
658 }
659
660 static void
661 print_until_command (while_command)
662      WHILE_COM *while_command;
663 {
664   print_until_or_while (while_command, "until");
665 }
666
667 static void
668 print_until_or_while (while_command, which)
669      WHILE_COM *while_command;
670      char *which;
671 {
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");
682 }
683
684 static void
685 print_if_command (if_command)
686      IF_COM *if_command;
687 {
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;
696
697   if (if_command->false_case)
698     {
699       semicolon ();
700       newline ("else\n");
701       indentation += indentation_amount;
702       make_command_string_internal (if_command->false_case);
703       indentation -= indentation_amount;
704     }
705   semicolon ();
706   newline ("fi");
707 }
708
709 #if defined (DPAREN_ARITHMETIC)
710 void
711 print_arith_command (arith_cmd_list)
712      WORD_LIST *arith_cmd_list;
713 {
714   cprintf ("((");
715   command_print_word_list (arith_cmd_list, " ");
716   cprintf ("))");
717 }
718 #endif
719
720 #if defined (COND_COMMAND)
721 static void
722 print_cond_node (cond)
723      COND_COM *cond;
724 {
725   if (cond->flags & CMD_INVERT_RETURN)
726     cprintf ("! ");
727
728   if (cond->type == COND_EXPR)
729     {
730       cprintf ("( ");
731       print_cond_node (cond->left);
732       cprintf (" )");
733     }
734   else if (cond->type == COND_AND)
735     {
736       print_cond_node (cond->left);
737       cprintf (" && ");
738       print_cond_node (cond->right);
739     }
740   else if (cond->type == COND_OR)
741     {
742       print_cond_node (cond->left);
743       cprintf (" || ");
744       print_cond_node (cond->right);
745     }
746   else if (cond->type == COND_UNARY)
747     {
748       cprintf ("%s", cond->op->word);
749       cprintf (" ");
750       print_cond_node (cond->left);
751     }
752   else if (cond->type == COND_BINARY)
753     {
754       print_cond_node (cond->left);
755       cprintf (" ");
756       cprintf ("%s", cond->op->word);
757       cprintf (" ");
758       print_cond_node (cond->right);
759     }
760   else if (cond->type == COND_TERM)
761     {
762       cprintf ("%s", cond->op->word);           /* need to add quoting here */
763     }
764 }
765
766 void
767 print_cond_command (cond)
768      COND_COM *cond;
769 {
770   cprintf ("[[ ");
771   print_cond_node (cond);
772   cprintf (" ]]");
773 }
774
775 #ifdef DEBUG
776 void
777 debug_print_cond_command (cond)
778      COND_COM *cond;
779 {
780   fprintf (stderr, "DEBUG: ");
781   command_string_index = 0;
782   print_cond_command (cond);
783   fprintf (stderr, "%s\n", the_printed_command);
784 }
785 #endif
786
787 void
788 xtrace_print_cond_term (type, invert, op, arg1, arg2)
789      int type, invert;
790      WORD_DESC *op;
791      char *arg1, *arg2;
792 {
793   command_string_index = 0;
794   fprintf (stderr, "%s", indirection_level_string ());
795   fprintf (stderr, "[[ ");
796   if (invert)
797     fprintf (stderr, "! ");
798
799   if (type == COND_UNARY)
800     {
801       fprintf (stderr, "%s ", op->word);
802       fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
803     }
804   else if (type == COND_BINARY)
805     {
806       fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
807       fprintf (stderr, " %s ", op->word);
808       fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
809     }
810
811   fprintf (stderr, " ]]\n");
812 }         
813 #endif /* COND_COMMAND */
814
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;
820 {
821   WORD_LIST *w;
822
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");
828 }
829 #endif
830
831 void
832 print_simple_command (simple_command)
833      SIMPLE_COM *simple_command;
834 {
835   command_print_word_list (simple_command->words, " ");
836
837   if (simple_command->redirects)
838     {
839       cprintf (" ");
840       print_redirection_list (simple_command->redirects);
841     }
842 }
843
844 static void
845 print_heredocs (heredocs)
846      REDIRECT *heredocs;
847 {
848   REDIRECT *hdtail;
849
850   cprintf (" "); 
851   for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
852     {
853       print_redirection (hdtail);
854       cprintf ("\n");
855     }
856   was_heredoc = 1;
857 }
858
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;
868 {
869   REDIRECT *hdtail;     
870
871   for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
872     {
873       cprintf (" ");
874       print_heredoc_header (hdtail);
875     }
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)
881     {
882       print_heredoc_body (hdtail);
883       cprintf ("\n");
884     }
885   if (deferred_heredocs)
886     {
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;
891     }
892   deferred_heredocs = (REDIRECT *)NULL;
893 }
894       
895 static void
896 print_redirection_list (redirects)
897      REDIRECT *redirects;
898 {
899   REDIRECT *heredocs, *hdtail, *newredir;
900
901   heredocs = (REDIRECT *)NULL;
902   hdtail = heredocs;
903
904   was_heredoc = 0;
905   while (redirects)
906     {
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)
910         {
911           newredir = copy_redirect (redirects);
912           newredir->next = (REDIRECT *)NULL;
913           if (heredocs)
914             {
915               hdtail->next = newredir;
916               hdtail = newredir;
917             }
918           else
919             hdtail = heredocs = newredir;
920         }
921       else if (redirects->instruction == r_duplicating_output_word && redirects->redirector == 1)
922         {
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;
927         }
928       else
929         print_redirection (redirects);
930
931       redirects = redirects->next;
932       if (redirects)
933         cprintf (" ");
934     }
935
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)
941     {
942       print_heredocs (heredocs);
943       dispose_redirects (heredocs);
944     }
945 }
946
947 static void
948 print_heredoc_header (redirect)
949      REDIRECT *redirect;
950 {
951   int kill_leading;
952   char *x;
953
954   kill_leading = redirect->instruction == r_deblank_reading_until;
955
956   /* Here doc header */
957   if (redirect->redirector != 0)
958     cprintf ("%d", redirect->redirector);
959
960   /* If the here document delimiter is quoted, single-quote it. */
961   if (redirect->redirectee.filename->flags & W_QUOTED)
962     {
963       x = sh_single_quote (redirect->here_doc_eof);
964       cprintf ("<<%s%s", kill_leading ? "-" : "", x);
965       free (x);
966     }
967   else
968     cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
969 }
970
971 static void
972 print_heredoc_body (redirect)
973      REDIRECT *redirect;
974 {
975   /* Here doc body */
976   cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
977 }
978
979 static void
980 print_redirection (redirect)
981      REDIRECT *redirect;
982 {
983   int kill_leading, redirector, redir_fd;
984   WORD_DESC *redirectee;
985
986   kill_leading = 0;
987   redirectee = redirect->redirectee.filename;
988   redirector = redirect->redirector;
989   redir_fd = redirect->redirectee.dest;
990
991   switch (redirect->instruction)
992     {
993     case r_output_direction:
994       if (redirector != 1)
995         cprintf ("%d", redirector);
996       cprintf ("> %s", redirectee->word);
997       break;
998
999     case r_input_direction:
1000       if (redirector != 0)
1001         cprintf ("%d", redirector);
1002       cprintf ("< %s", redirectee->word);
1003       break;
1004
1005     case r_inputa_direction:    /* Redirection created by the shell. */
1006       cprintf ("&");
1007       break;
1008
1009     case r_appending_to:
1010       if (redirector != 1)
1011         cprintf ("%d", redirector);
1012       cprintf (">> %s", redirectee->word);
1013       break;
1014
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;
1021
1022     case r_reading_string:
1023       if (redirector != 0)
1024         cprintf ("%d", redirector);
1025       if (ansic_shouldquote (redirect->redirectee.filename->word))
1026         {
1027           char *x;
1028           x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1029           cprintf ("<<< %s", x);
1030           free (x);
1031         }
1032       else
1033         cprintf ("<<< %s", redirect->redirectee.filename->word);
1034       break;
1035
1036     case r_duplicating_input:
1037       cprintf ("%d<&%d", redirector, redir_fd);
1038       break;
1039
1040     case r_duplicating_output:
1041       cprintf ("%d>&%d", redirector, redir_fd);
1042       break;
1043
1044     case r_duplicating_input_word:
1045       cprintf ("%d<&%s", redirector, redirectee->word);
1046       break;
1047
1048     case r_duplicating_output_word:
1049       cprintf ("%d>&%s", redirector, redirectee->word);
1050       break;
1051
1052     case r_move_input:
1053       cprintf ("%d<&%d-", redirector, redir_fd);
1054       break;
1055
1056     case r_move_output:
1057       cprintf ("%d>&%d-", redirector, redir_fd);
1058       break;
1059
1060     case r_move_input_word:
1061       cprintf ("%d<&%s-", redirector, redirectee->word);
1062       break;
1063
1064     case r_move_output_word:
1065       cprintf ("%d>&%s-", redirector, redirectee->word);
1066       break;
1067
1068     case r_close_this:
1069       cprintf ("%d>&-", redirector);
1070       break;
1071
1072     case r_err_and_out:
1073       cprintf ("&>%s", redirectee->word);
1074       break;
1075
1076     case r_append_err_and_out:
1077       cprintf ("&>>%s", redirectee->word);
1078       break;
1079
1080     case r_input_output:
1081       if (redirector != 1)
1082         cprintf ("%d", redirector);
1083       cprintf ("<> %s", redirectee->word);
1084       break;
1085
1086     case r_output_force:
1087       if (redirector != 1)
1088         cprintf ("%d", redirector);
1089       cprintf (">|%s", redirectee->word);
1090       break;
1091     }
1092 }
1093
1094 static void
1095 reset_locals ()
1096 {
1097   inside_function_def = 0;
1098   indentation = 0;
1099   printing_connection = 0;
1100   deferred_heredocs = 0;
1101 }
1102
1103 static void
1104 print_function_def (func)
1105      FUNCTION_DEF *func;
1106 {
1107   COMMAND *cmdcopy;
1108   REDIRECT *func_redirects;
1109
1110   func_redirects = NULL;
1111   cprintf ("function %s () \n", func->name->word);
1112   add_unwind_protect (reset_locals, 0);
1113
1114   indent (indentation);
1115   cprintf ("{ \n");
1116
1117   inside_function_def++;
1118   indentation += indentation_amount;
1119
1120   cmdcopy = copy_command (func->command);
1121   if (cmdcopy->type == cm_group)
1122     {
1123       func_redirects = cmdcopy->redirects;
1124       cmdcopy->redirects = (REDIRECT *)NULL;
1125     }
1126   make_command_string_internal (cmdcopy->type == cm_group
1127                                         ? cmdcopy->value.Group->command
1128                                         : cmdcopy);
1129
1130   remove_unwind_protect ();
1131   indentation -= indentation_amount;
1132   inside_function_def--;
1133
1134   if (func_redirects)
1135     { /* { */
1136       newline ("} ");
1137       print_redirection_list (func_redirects);
1138       cmdcopy->redirects = func_redirects;
1139     }
1140   else
1141     newline ("}");
1142
1143   dispose_command (cmdcopy);
1144 }
1145
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
1151   */
1152 char *
1153 named_function_string (name, command, flags)
1154      char *name;
1155      COMMAND *command;
1156      int flags;
1157 {
1158   char *result;
1159   int old_indent, old_amount;
1160   COMMAND *cmdcopy;
1161   REDIRECT *func_redirects;
1162
1163   old_indent = indentation;
1164   old_amount = indentation_amount;
1165   command_string_index = was_heredoc = 0;
1166   deferred_heredocs = 0;
1167
1168   if (name && *name)
1169     cprintf ("%s ", name);
1170
1171   cprintf ("() ");
1172
1173   if ((flags & FUNC_MULTILINE) == 0)
1174     {
1175       indentation = 1;
1176       indentation_amount = 0;
1177     }
1178   else
1179     {
1180       cprintf ("\n");
1181       indentation += indentation_amount;
1182     }
1183
1184   inside_function_def++;
1185
1186   cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1187
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)
1193     {
1194       func_redirects = cmdcopy->redirects;
1195       cmdcopy->redirects = (REDIRECT *)NULL;
1196     }
1197   make_command_string_internal (cmdcopy->type == cm_group
1198                                         ? cmdcopy->value.Group->command
1199                                         : cmdcopy);
1200
1201   indentation = old_indent;
1202   indentation_amount = old_amount;
1203   inside_function_def--;
1204
1205   if (func_redirects)
1206     { /* { */
1207       newline ("} ");
1208       print_redirection_list (func_redirects);
1209       cmdcopy->redirects = func_redirects;
1210     }
1211   else
1212     newline ("}");
1213
1214   result = the_printed_command;
1215
1216   if ((flags & FUNC_MULTILINE) == 0)
1217     {
1218 #if 0
1219       register int i;
1220       for (i = 0; result[i]; i++)
1221         if (result[i] == '\n')
1222           {
1223             strcpy (result + i, result + i + 1);
1224             --i;
1225           }
1226 #else
1227       if (result[2] == '\n')    /* XXX -- experimental */
1228         strcpy (result + 2, result + 3);
1229 #endif
1230     }
1231
1232   dispose_command (cmdcopy);
1233
1234   if (flags & FUNC_EXTERNAL)
1235     result = remove_quoted_escapes (result);
1236
1237   return (result);
1238 }
1239
1240 static void
1241 newline (string)
1242      char *string;
1243 {
1244   cprintf ("\n");
1245   indent (indentation);
1246   if (string && *string)
1247     cprintf ("%s", string);
1248 }
1249
1250 static char *indentation_string;
1251 static int indentation_size;
1252
1253 static void
1254 indent (amount)
1255      int amount;
1256 {
1257   register int i;
1258
1259   RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1260
1261   for (i = 0; amount > 0; amount--)
1262     indentation_string[i++] = ' ';
1263   indentation_string[i] = '\0';
1264   cprintf (indentation_string);
1265 }
1266
1267 static void
1268 semicolon ()
1269 {
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 (";");
1275 }
1276
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
1286 {
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;
1291
1292   SH_VA_START (args, control);
1293
1294   arg_len = strlen (control);
1295   the_printed_command_resize (arg_len + 1);
1296
1297   char_arg[1] = '\0';
1298   s = control;
1299   while (s && *s)
1300     {
1301       c = *s++;
1302       argp = (char *)NULL;
1303       if (c != '%' || !*s)
1304         {
1305           char_arg[0] = c;
1306           argp = char_arg;
1307           arg_len = 1;
1308         }
1309       else
1310         {
1311           c = *s++;
1312           switch (c)
1313             {
1314             case '%':
1315               char_arg[0] = c;
1316               argp = char_arg;
1317               arg_len = 1;
1318               break;
1319
1320             case 's':
1321               argp = va_arg (args, char *);
1322               arg_len = strlen (argp);
1323               break;
1324
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)
1332                 {
1333                   sprintf (intbuf, "%u", (unsigned)-1);
1334                   argp = intbuf;
1335                 }
1336               else
1337                 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1338               arg_len = strlen (argp);
1339               break;
1340
1341             case 'c':
1342               char_arg[0] = va_arg (args, int);
1343               argp = char_arg;
1344               arg_len = 1;
1345               break;
1346
1347             default:
1348               programming_error (_("cprintf: `%c': invalid format character"), c);
1349               /*NOTREACHED*/
1350             }
1351         }
1352
1353       if (argp && arg_len)
1354         {
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;
1358         }
1359     }
1360
1361   the_printed_command[command_string_index] = '\0';
1362 }
1363
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;
1369 {
1370   if (the_printed_command == 0)
1371     {
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;
1375     }
1376   else if ((command_string_index + length) >= the_printed_command_size)
1377     {
1378       int new;
1379       new = command_string_index + length + 1;
1380
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;
1384
1385       the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1386     }
1387 }
1388
1389 #if defined (HAVE_VPRINTF)
1390 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1391      also available.'' */
1392
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
1401 {
1402   va_list args;
1403
1404   SH_VA_START (args, format);
1405
1406   vfprintf (stdout, format, args);
1407   va_end (args);
1408 }
1409
1410 #else
1411
1412 static void
1413 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1414      const char *format;
1415 {
1416   printf (format, arg1, arg2, arg3, arg4, arg5);
1417 }
1418
1419 #endif /* !HAVE_VPRINTF */