Bash-4.1 distribution source
[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 int xtrace_fd = -1;
112 FILE *xtrace_fp = 0;
113
114 #define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
115
116 /* Non-zero means the stuff being printed is inside of a function def. */
117 static int inside_function_def;
118 static int skip_this_indent;
119 static int was_heredoc;
120 static int printing_connection;
121 static REDIRECT *deferred_heredocs;
122
123 /* The depth of the group commands that we are currently printing.  This
124    includes the group command that is a function body. */
125 static int group_command_nesting;
126
127 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
128 static char indirection_string[100];
129
130 /* Print COMMAND (a command tree) on standard output. */
131 void
132 print_command (command)
133      COMMAND *command;
134 {
135   command_string_index = 0;
136   printf ("%s", make_command_string (command));
137 }
138
139 /* Make a string which is the printed representation of the command
140    tree in COMMAND.  We return this string.  However, the string is
141    not consed, so you have to do that yourself if you want it to
142    remain around. */
143 char *
144 make_command_string (command)
145      COMMAND *command;
146 {
147   command_string_index = was_heredoc = 0;
148   deferred_heredocs = 0;
149   make_command_string_internal (command);
150   return (the_printed_command);
151 }
152
153 /* The internal function.  This is the real workhorse. */
154 static void
155 make_command_string_internal (command)
156      COMMAND *command;
157 {
158   char s[3], *op;
159
160   if (command == 0)
161     cprintf ("");
162   else
163     {
164       if (skip_this_indent)
165         skip_this_indent--;
166       else
167         indent (indentation);
168
169       if (command->flags & CMD_TIME_PIPELINE)
170         {
171           cprintf ("time ");
172           if (command->flags & CMD_TIME_POSIX)
173             cprintf ("-p ");
174         }
175
176       if (command->flags & CMD_INVERT_RETURN)
177         cprintf ("! ");
178
179       switch (command->type)
180         {
181         case cm_for:
182           print_for_command (command->value.For);
183           break;
184
185 #if defined (ARITH_FOR_COMMAND)
186         case cm_arith_for:
187           print_arith_for_command (command->value.ArithFor);
188           break;
189 #endif
190
191 #if defined (SELECT_COMMAND)
192         case cm_select:
193           print_select_command (command->value.Select);
194           break;
195 #endif
196
197         case cm_case:
198           print_case_command (command->value.Case);
199           break;
200
201         case cm_while:
202           print_while_command (command->value.While);
203           break;
204
205         case cm_until:
206           print_until_command (command->value.While);
207           break;
208
209         case cm_if:
210           print_if_command (command->value.If);
211           break;
212
213 #if defined (DPAREN_ARITHMETIC)
214         case cm_arith:
215           print_arith_command (command->value.Arith->exp);
216           break;
217 #endif
218
219 #if defined (COND_COMMAND)
220         case cm_cond:
221           print_cond_command (command->value.Cond);
222           break;
223 #endif
224
225         case cm_simple:
226           print_simple_command (command->value.Simple);
227           break;
228
229         case cm_connection:
230
231           skip_this_indent++;
232           printing_connection++;
233           make_command_string_internal (command->value.Connection->first);
234
235           switch (command->value.Connection->connector)
236             {
237             case '&':
238             case '|':
239               {
240                 char c = command->value.Connection->connector;
241
242                 s[0] = ' ';
243                 s[1] = c;
244                 s[2] = '\0';
245                 
246                 print_deferred_heredocs (s);
247
248                 if (c != '&' || command->value.Connection->second)
249                   {
250                     cprintf (" ");
251                     skip_this_indent++;
252                   }
253               }
254               break;
255
256             case AND_AND:
257               print_deferred_heredocs (" && ");
258               if (command->value.Connection->second)
259                 skip_this_indent++;
260               break;
261
262             case OR_OR:
263               print_deferred_heredocs (" || ");
264               if (command->value.Connection->second)
265                 skip_this_indent++;
266               break;
267
268             case ';':
269               if (deferred_heredocs == 0)
270                 {
271                   if (was_heredoc == 0)
272                     cprintf (";");
273                   else
274                     was_heredoc = 0;
275                 }
276               else
277                 print_deferred_heredocs (inside_function_def ? "" : ";");
278
279               if (inside_function_def)
280                 cprintf ("\n");
281               else
282                 {
283                   cprintf (" ");
284                   if (command->value.Connection->second)
285                     skip_this_indent++;
286                 }
287               break;
288
289             default:
290               cprintf (_("print_command: bad connector `%d'"),
291                        command->value.Connection->connector);
292               break;
293             }
294
295           make_command_string_internal (command->value.Connection->second);
296           if (deferred_heredocs)
297             print_deferred_heredocs ("");
298           printing_connection--;                  
299           break;
300
301         case cm_function_def:
302           print_function_def (command->value.Function_def);
303           break;
304
305         case cm_group:
306           print_group_command (command->value.Group);
307           break;
308
309         case cm_subshell:
310           cprintf ("( ");
311           skip_this_indent++;
312           make_command_string_internal (command->value.Subshell->command);
313           cprintf (" )");
314           break;
315
316         case cm_coproc:
317           cprintf ("coproc %s ", command->value.Coproc->name);
318           skip_this_indent++;
319           make_command_string_internal (command->value.Coproc->command);
320           break;
321
322         default:
323           command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
324           break;
325         }
326
327
328       if (command->redirects)
329         {
330           cprintf (" ");
331           print_redirection_list (command->redirects);
332         }
333     }
334 }
335
336 static void
337 _print_word_list (list, separator, pfunc)
338      WORD_LIST *list;
339      char *separator;
340      PFUNC *pfunc;
341 {
342   WORD_LIST *w;
343
344   for (w = list; w; w = w->next)
345     (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
346 }
347
348 void
349 print_word_list (list, separator)
350      WORD_LIST *list;
351      char *separator;
352 {
353   _print_word_list (list, separator, xprintf);
354 }
355
356 void
357 xtrace_set (fd, fp)
358      int fd;
359      FILE *fp;
360 {
361   if (fd >= 0 && sh_validfd (fd) == 0)
362     {
363       internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
364       return;
365     }
366   if (fp == 0)
367     {
368       internal_error (_("xtrace_set: NULL file pointer"));
369       return;
370     }
371   if (fd >= 0 && fileno (fp) != fd)
372     internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
373   
374   xtrace_fd = fd;
375   xtrace_fp = fp;
376 }
377
378 void
379 xtrace_init ()
380 {
381   xtrace_set (-1, stderr);
382 }
383
384 void
385 xtrace_reset ()
386 {
387   if (xtrace_fd >= 0 && xtrace_fp)
388     {
389       fflush (xtrace_fp);
390       fclose (xtrace_fp);
391     }
392   else if (xtrace_fd >= 0)
393     close (xtrace_fd);
394
395   xtrace_fd = -1;
396   xtrace_fp = stderr;
397 }
398
399 void
400 xtrace_fdchk (fd)
401      int fd;
402 {
403   if (fd == xtrace_fd)
404     xtrace_reset ();
405 }
406
407 /* Return a string denoting what our indirection level is. */
408
409 char *
410 indirection_level_string ()
411 {
412   register int i, j;
413   char *ps4;
414   char ps4_firstc[MB_LEN_MAX+1];
415   int ps4_firstc_len, ps4_len;
416
417   indirection_string[0] = '\0';
418   ps4 = get_string_value ("PS4");
419
420   if (ps4 == 0 || *ps4 == '\0')
421     return (indirection_string);
422
423   change_flag ('x', FLAG_OFF);
424   ps4 = decode_prompt_string (ps4);
425   change_flag ('x', FLAG_ON);
426
427   if (ps4 == 0 || *ps4 == '\0')
428     return (indirection_string);
429
430 #if defined (HANDLE_MULTIBYTE)
431   ps4_len = strnlen (ps4, MB_CUR_MAX);
432   ps4_firstc_len = MBLEN (ps4, ps4_len);
433   if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
434     {
435       ps4_firstc[0] = ps4[0];
436       ps4_firstc[ps4_firstc_len = 1] = '\0';
437     }
438   else
439     memcpy (ps4_firstc, ps4, ps4_firstc_len);
440 #else
441   ps4_firstc[0] = ps4[0];
442   ps4_firstc[ps4_firstc_len = 1] = '\0';
443 #endif
444       
445   for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
446     {
447       if (ps4_firstc_len == 1)
448         indirection_string[i] = ps4_firstc[0];
449       else
450         memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
451     }      
452
453   for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
454     indirection_string[i] = ps4[j];
455
456   indirection_string[i] = '\0';
457   free (ps4);
458   return (indirection_string);
459 }
460
461 void
462 xtrace_print_assignment (name, value, assign_list, xflags)
463      char *name, *value;
464      int assign_list, xflags;
465 {
466   char *nval;
467
468   CHECK_XTRACE_FP;
469
470   if (xflags)
471     fprintf (xtrace_fp, "%s", indirection_level_string ());
472
473   /* VALUE should not be NULL when this is called. */
474   if (*value == '\0' || assign_list)
475     nval = value;
476   else if (sh_contains_shell_metas (value))
477     nval = sh_single_quote (value);
478   else if (ansic_shouldquote (value))
479     nval = ansic_quote (value, 0, (int *)0);
480   else
481     nval = value;
482
483   if (assign_list)
484     fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
485   else
486     fprintf (xtrace_fp, "%s=%s\n", name, nval);
487
488   if (nval != value)
489     FREE (nval);
490
491   fflush (xtrace_fp);
492 }
493
494 /* A function to print the words of a simple command when set -x is on. */
495 void
496 xtrace_print_word_list (list, xtflags)
497      WORD_LIST *list;
498      int xtflags;
499 {
500   WORD_LIST *w;
501   char *t, *x;
502
503   CHECK_XTRACE_FP;
504
505   if (xtflags)
506     fprintf (xtrace_fp, "%s", indirection_level_string ());
507
508   for (w = list; w; w = w->next)
509     {
510       t = w->word->word;
511       if (t == 0 || *t == '\0')
512         fprintf (xtrace_fp, "''%s", w->next ? " " : "");
513       else if (sh_contains_shell_metas (t))
514         {
515           x = sh_single_quote (t);
516           fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
517           free (x);
518         }
519       else if (ansic_shouldquote (t))
520         {
521           x = ansic_quote (t, 0, (int *)0);
522           fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
523           free (x);
524         }
525       else
526         fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
527     }
528   fprintf (xtrace_fp, "\n");
529   fflush (xtrace_fp);
530 }
531
532 static void
533 command_print_word_list (list, separator)
534      WORD_LIST *list;
535      char *separator;
536 {
537   _print_word_list (list, separator, cprintf);
538 }
539
540 void
541 print_for_command_head (for_command)
542      FOR_COM *for_command;
543 {
544   cprintf ("for %s in ", for_command->name->word);
545   command_print_word_list (for_command->map_list, " ");
546 }
547
548 void
549 xtrace_print_for_command_head (for_command)
550      FOR_COM *for_command;
551 {
552   CHECK_XTRACE_FP;
553   fprintf (xtrace_fp, "%s", indirection_level_string ());
554   fprintf (xtrace_fp, "for %s in ", for_command->name->word);
555   xtrace_print_word_list (for_command->map_list, 0);
556 }
557
558 static void
559 print_for_command (for_command)
560      FOR_COM *for_command;
561 {
562   print_for_command_head (for_command);
563
564   cprintf (";");
565   newline ("do\n");
566   indentation += indentation_amount;
567   make_command_string_internal (for_command->action);
568   semicolon ();
569   indentation -= indentation_amount;
570   newline ("done");
571 }
572
573 #if defined (ARITH_FOR_COMMAND)
574 static void
575 print_arith_for_command (arith_for_command)
576      ARITH_FOR_COM *arith_for_command;
577 {
578   cprintf ("for ((");
579   command_print_word_list (arith_for_command->init, " ");
580   cprintf ("; ");
581   command_print_word_list (arith_for_command->test, " ");
582   cprintf ("; ");
583   command_print_word_list (arith_for_command->step, " ");
584   cprintf ("))");
585   newline ("do\n");
586   indentation += indentation_amount;
587   make_command_string_internal (arith_for_command->action);
588   semicolon ();
589   indentation -= indentation_amount;
590   newline ("done");
591 }
592 #endif /* ARITH_FOR_COMMAND */
593
594 #if defined (SELECT_COMMAND)
595 void
596 print_select_command_head (select_command)
597      SELECT_COM *select_command;
598 {
599   cprintf ("select %s in ", select_command->name->word);
600   command_print_word_list (select_command->map_list, " ");
601 }
602
603 void
604 xtrace_print_select_command_head (select_command)
605      SELECT_COM *select_command;
606 {
607   CHECK_XTRACE_FP;
608   fprintf (xtrace_fp, "%s", indirection_level_string ());
609   fprintf (xtrace_fp, "select %s in ", select_command->name->word);
610   xtrace_print_word_list (select_command->map_list, 0);
611 }
612
613 static void
614 print_select_command (select_command)
615      SELECT_COM *select_command;
616 {
617   print_select_command_head (select_command);
618
619   cprintf (";");
620   newline ("do\n");
621   indentation += indentation_amount;
622   make_command_string_internal (select_command->action);
623   semicolon ();
624   indentation -= indentation_amount;
625   newline ("done");
626 }
627 #endif /* SELECT_COMMAND */
628
629 static void
630 print_group_command (group_command)
631      GROUP_COM *group_command;
632 {
633   group_command_nesting++;
634   cprintf ("{ ");
635
636   if (inside_function_def == 0)
637     skip_this_indent++;
638   else
639     {
640       /* This is a group command { ... } inside of a function
641          definition, and should be printed as a multiline group
642          command, using the current indentation. */
643       cprintf ("\n");
644       indentation += indentation_amount;
645     }
646
647   make_command_string_internal (group_command->command);
648
649   if (inside_function_def)
650     {
651       cprintf ("\n");
652       indentation -= indentation_amount;
653       indent (indentation);
654     }
655   else
656     {
657       semicolon ();
658       cprintf (" ");
659     }
660
661   cprintf ("}");
662
663   group_command_nesting--;
664 }
665
666 void
667 print_case_command_head (case_command)
668      CASE_COM *case_command;
669 {
670   cprintf ("case %s in ", case_command->word->word);
671 }
672
673 void
674 xtrace_print_case_command_head (case_command)
675      CASE_COM *case_command;
676 {
677   CHECK_XTRACE_FP;
678   fprintf (xtrace_fp, "%s", indirection_level_string ());
679   fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
680 }
681
682 static void
683 print_case_command (case_command)
684      CASE_COM *case_command;
685 {
686   print_case_command_head (case_command);
687
688   if (case_command->clauses)
689     print_case_clauses (case_command->clauses);
690   newline ("esac");
691 }
692
693 static void
694 print_case_clauses (clauses)
695      PATTERN_LIST *clauses;
696 {
697   indentation += indentation_amount;
698   while (clauses)
699     {
700       newline ("");
701       command_print_word_list (clauses->patterns, " | ");
702       cprintf (")\n");
703       indentation += indentation_amount;
704       make_command_string_internal (clauses->action);
705       indentation -= indentation_amount;
706       if (clauses->flags & CASEPAT_FALLTHROUGH)
707         newline (";&");
708       else if (clauses->flags & CASEPAT_TESTNEXT)
709         newline (";;&");
710       else
711         newline (";;");
712       clauses = clauses->next;
713     }
714   indentation -= indentation_amount;
715 }
716
717 static void
718 print_while_command (while_command)
719      WHILE_COM *while_command;
720 {
721   print_until_or_while (while_command, "while");
722 }
723
724 static void
725 print_until_command (while_command)
726      WHILE_COM *while_command;
727 {
728   print_until_or_while (while_command, "until");
729 }
730
731 static void
732 print_until_or_while (while_command, which)
733      WHILE_COM *while_command;
734      char *which;
735 {
736   cprintf ("%s ", which);
737   skip_this_indent++;
738   make_command_string_internal (while_command->test);
739   semicolon ();
740   cprintf (" do\n");    /* was newline ("do\n"); */
741   indentation += indentation_amount;
742   make_command_string_internal (while_command->action);
743   indentation -= indentation_amount;
744   semicolon ();
745   newline ("done");
746 }
747
748 static void
749 print_if_command (if_command)
750      IF_COM *if_command;
751 {
752   cprintf ("if ");
753   skip_this_indent++;
754   make_command_string_internal (if_command->test);
755   semicolon ();
756   cprintf (" then\n");
757   indentation += indentation_amount;
758   make_command_string_internal (if_command->true_case);
759   indentation -= indentation_amount;
760
761   if (if_command->false_case)
762     {
763       semicolon ();
764       newline ("else\n");
765       indentation += indentation_amount;
766       make_command_string_internal (if_command->false_case);
767       indentation -= indentation_amount;
768     }
769   semicolon ();
770   newline ("fi");
771 }
772
773 #if defined (DPAREN_ARITHMETIC)
774 void
775 print_arith_command (arith_cmd_list)
776      WORD_LIST *arith_cmd_list;
777 {
778   cprintf ("((");
779   command_print_word_list (arith_cmd_list, " ");
780   cprintf ("))");
781 }
782 #endif
783
784 #if defined (COND_COMMAND)
785 static void
786 print_cond_node (cond)
787      COND_COM *cond;
788 {
789   if (cond->flags & CMD_INVERT_RETURN)
790     cprintf ("! ");
791
792   if (cond->type == COND_EXPR)
793     {
794       cprintf ("( ");
795       print_cond_node (cond->left);
796       cprintf (" )");
797     }
798   else if (cond->type == COND_AND)
799     {
800       print_cond_node (cond->left);
801       cprintf (" && ");
802       print_cond_node (cond->right);
803     }
804   else if (cond->type == COND_OR)
805     {
806       print_cond_node (cond->left);
807       cprintf (" || ");
808       print_cond_node (cond->right);
809     }
810   else if (cond->type == COND_UNARY)
811     {
812       cprintf ("%s", cond->op->word);
813       cprintf (" ");
814       print_cond_node (cond->left);
815     }
816   else if (cond->type == COND_BINARY)
817     {
818       print_cond_node (cond->left);
819       cprintf (" ");
820       cprintf ("%s", cond->op->word);
821       cprintf (" ");
822       print_cond_node (cond->right);
823     }
824   else if (cond->type == COND_TERM)
825     {
826       cprintf ("%s", cond->op->word);           /* need to add quoting here */
827     }
828 }
829
830 void
831 print_cond_command (cond)
832      COND_COM *cond;
833 {
834   cprintf ("[[ ");
835   print_cond_node (cond);
836   cprintf (" ]]");
837 }
838
839 #ifdef DEBUG
840 void
841 debug_print_cond_command (cond)
842      COND_COM *cond;
843 {
844   fprintf (stderr, "DEBUG: ");
845   command_string_index = 0;
846   print_cond_command (cond);
847   fprintf (stderr, "%s\n", the_printed_command);
848 }
849 #endif
850
851 void
852 xtrace_print_cond_term (type, invert, op, arg1, arg2)
853      int type, invert;
854      WORD_DESC *op;
855      char *arg1, *arg2;
856 {
857   CHECK_XTRACE_FP;
858   command_string_index = 0;
859   fprintf (xtrace_fp, "%s", indirection_level_string ());
860   fprintf (xtrace_fp, "[[ ");
861   if (invert)
862     fprintf (xtrace_fp, "! ");
863
864   if (type == COND_UNARY)
865     {
866       fprintf (xtrace_fp, "%s ", op->word);
867       fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
868     }
869   else if (type == COND_BINARY)
870     {
871       fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
872       fprintf (xtrace_fp, " %s ", op->word);
873       fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
874     }
875
876   fprintf (xtrace_fp, " ]]\n");
877
878   fflush (xtrace_fp);
879 }         
880 #endif /* COND_COMMAND */
881
882 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
883 /* A function to print the words of an arithmetic command when set -x is on. */
884 void
885 xtrace_print_arith_cmd (list)
886      WORD_LIST *list;
887 {
888   WORD_LIST *w;
889
890   CHECK_XTRACE_FP;
891   fprintf (xtrace_fp, "%s", indirection_level_string ());
892   fprintf (xtrace_fp, "(( ");
893   for (w = list; w; w = w->next)
894     fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
895   fprintf (xtrace_fp, " ))\n");
896
897   fflush (xtrace_fp);
898 }
899 #endif
900
901 void
902 print_simple_command (simple_command)
903      SIMPLE_COM *simple_command;
904 {
905   command_print_word_list (simple_command->words, " ");
906
907   if (simple_command->redirects)
908     {
909       cprintf (" ");
910       print_redirection_list (simple_command->redirects);
911     }
912 }
913
914 static void
915 print_heredocs (heredocs)
916      REDIRECT *heredocs;
917 {
918   REDIRECT *hdtail;
919
920   cprintf (" "); 
921   for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
922     {
923       print_redirection (hdtail);
924       cprintf ("\n");
925     }
926   was_heredoc = 1;
927 }
928
929 /* Print heredocs that are attached to the command before the connector
930    represented by CSTRING.  The parsing semantics require us to print the
931    here-doc delimiters, then the connector (CSTRING), then the here-doc
932    bodies.  We don't print the connector if it's a `;', but we use it to
933    note not to print an extra space after the last heredoc body and
934    newline. */
935 static void
936 print_deferred_heredocs (cstring)
937      const char *cstring;
938 {
939   REDIRECT *hdtail;     
940
941   for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
942     {
943       cprintf (" ");
944       print_heredoc_header (hdtail);
945     }
946   if (cstring[0] != ';' || cstring[1])
947     cprintf ("%s", cstring); 
948   if (deferred_heredocs)
949     cprintf ("\n");
950   for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
951     {
952       print_heredoc_body (hdtail);
953       cprintf ("\n");
954     }
955   if (deferred_heredocs)
956     {
957       if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
958         cprintf (" ");  /* make sure there's at least one space */
959       dispose_redirects (deferred_heredocs);
960       was_heredoc = 1;
961     }
962   deferred_heredocs = (REDIRECT *)NULL;
963 }
964       
965 static void
966 print_redirection_list (redirects)
967      REDIRECT *redirects;
968 {
969   REDIRECT *heredocs, *hdtail, *newredir;
970
971   heredocs = (REDIRECT *)NULL;
972   hdtail = heredocs;
973
974   was_heredoc = 0;
975   while (redirects)
976     {
977       /* Defer printing the here documents until we've printed the
978          rest of the redirections. */
979       if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
980         {
981           newredir = copy_redirect (redirects);
982           newredir->next = (REDIRECT *)NULL;
983           if (heredocs)
984             {
985               hdtail->next = newredir;
986               hdtail = newredir;
987             }
988           else
989             hdtail = heredocs = newredir;
990         }
991       else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
992         {
993           /* Temporarily translate it as the execution code does. */
994           redirects->instruction = r_err_and_out;
995           print_redirection (redirects);
996           redirects->instruction = r_duplicating_output_word;
997         }
998       else
999         print_redirection (redirects);
1000
1001       redirects = redirects->next;
1002       if (redirects)
1003         cprintf (" ");
1004     }
1005
1006   /* Now that we've printed all the other redirections (on one line),
1007      print the here documents. */
1008   if (heredocs && printing_connection)
1009     deferred_heredocs = heredocs;
1010   else if (heredocs)
1011     {
1012       print_heredocs (heredocs);
1013       dispose_redirects (heredocs);
1014     }
1015 }
1016
1017 static void
1018 print_heredoc_header (redirect)
1019      REDIRECT *redirect;
1020 {
1021   int kill_leading;
1022   char *x;
1023
1024   kill_leading = redirect->instruction == r_deblank_reading_until;
1025
1026   /* Here doc header */
1027   if (redirect->rflags & REDIR_VARASSIGN)
1028     cprintf ("{%s}", redirect->redirector.filename->word);
1029   else if (redirect->redirector.dest != 0)
1030     cprintf ("%d", redirect->redirector.dest);
1031
1032   /* If the here document delimiter is quoted, single-quote it. */
1033   if (redirect->redirectee.filename->flags & W_QUOTED)
1034     {
1035       x = sh_single_quote (redirect->here_doc_eof);
1036       cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1037       free (x);
1038     }
1039   else
1040     cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1041 }
1042
1043 static void
1044 print_heredoc_body (redirect)
1045      REDIRECT *redirect;
1046 {
1047   /* Here doc body */
1048   cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1049 }
1050
1051 static void
1052 print_redirection (redirect)
1053      REDIRECT *redirect;
1054 {
1055   int kill_leading, redirector, redir_fd;
1056   WORD_DESC *redirectee, *redir_word;
1057
1058   kill_leading = 0;
1059   redirectee = redirect->redirectee.filename;
1060   redir_fd = redirect->redirectee.dest;
1061
1062   redir_word = redirect->redirector.filename;
1063   redirector = redirect->redirector.dest;
1064
1065   switch (redirect->instruction)
1066     {
1067     case r_input_direction:
1068       if (redirect->rflags & REDIR_VARASSIGN)
1069         cprintf ("{%s}", redir_word->word);
1070       else if (redirector != 0)
1071         cprintf ("%d", redirector);
1072       cprintf ("< %s", redirectee->word);
1073       break;
1074
1075     case r_output_direction:
1076       if (redirect->rflags & REDIR_VARASSIGN)
1077         cprintf ("{%s}", redir_word->word);
1078       else if (redirector != 1)
1079         cprintf ("%d", redirector);
1080       cprintf ("> %s", redirectee->word);
1081       break;
1082
1083     case r_inputa_direction:    /* Redirection created by the shell. */
1084       cprintf ("&");
1085       break;
1086
1087     case r_output_force:
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;
1094
1095     case r_appending_to:
1096       if (redirect->rflags & REDIR_VARASSIGN)
1097         cprintf ("{%s}", redir_word->word);
1098       else if (redirector != 1)
1099         cprintf ("%d", redirector);
1100       cprintf (">> %s", redirectee->word);
1101       break;
1102
1103     case r_input_output:
1104       if (redirect->rflags & REDIR_VARASSIGN)
1105         cprintf ("{%s}", redir_word->word);
1106       else if (redirector != 1)
1107         cprintf ("%d", redirector);
1108       cprintf ("<> %s", redirectee->word);
1109       break;
1110
1111     case r_deblank_reading_until:
1112     case r_reading_until:
1113       print_heredoc_header (redirect);
1114       cprintf ("\n");
1115       print_heredoc_body (redirect);
1116       break;
1117
1118     case r_reading_string:
1119       if (redirect->rflags & REDIR_VARASSIGN)
1120         cprintf ("{%s}", redir_word->word);
1121       else if (redirector != 0)
1122         cprintf ("%d", redirector);
1123       if (ansic_shouldquote (redirect->redirectee.filename->word))
1124         {
1125           char *x;
1126           x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1127           cprintf ("<<< %s", x);
1128           free (x);
1129         }
1130       else
1131         cprintf ("<<< %s", redirect->redirectee.filename->word);
1132       break;
1133
1134     case r_duplicating_input:
1135       if (redirect->rflags & REDIR_VARASSIGN)
1136         cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1137       else
1138         cprintf ("%d<&%d", redirector, redir_fd);
1139       break;
1140
1141     case r_duplicating_output:
1142       if (redirect->rflags & REDIR_VARASSIGN)
1143         cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1144       else
1145         cprintf ("%d>&%d", redirector, redir_fd);
1146       break;
1147
1148     case r_duplicating_input_word:
1149       if (redirect->rflags & REDIR_VARASSIGN)
1150         cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1151       else
1152         cprintf ("%d<&%s", redirector, redirectee->word);
1153       break;
1154
1155     case r_duplicating_output_word:
1156       if (redirect->rflags & REDIR_VARASSIGN)
1157         cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1158       else
1159         cprintf ("%d>&%s", redirector, redirectee->word);
1160       break;
1161
1162     case r_move_input:
1163       if (redirect->rflags & REDIR_VARASSIGN)
1164         cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1165       else
1166         cprintf ("%d<&%d-", redirector, redir_fd);
1167       break;
1168
1169     case r_move_output:
1170       if (redirect->rflags & REDIR_VARASSIGN)
1171         cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1172       else
1173         cprintf ("%d>&%d-", redirector, redir_fd);
1174       break;
1175
1176     case r_move_input_word:
1177       if (redirect->rflags & REDIR_VARASSIGN)
1178         cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1179       else
1180         cprintf ("%d<&%s-", redirector, redirectee->word);
1181       break;
1182
1183     case r_move_output_word:
1184       if (redirect->rflags & REDIR_VARASSIGN)
1185         cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1186       else
1187         cprintf ("%d>&%s-", redirector, redirectee->word);
1188       break;
1189
1190     case r_close_this:
1191       if (redirect->rflags & REDIR_VARASSIGN)
1192         cprintf ("{%s}>&-", redir_word->word);
1193       else
1194         cprintf ("%d>&-", redirector);
1195       break;
1196
1197     case r_err_and_out:
1198       cprintf ("&>%s", redirectee->word);
1199       break;
1200
1201     case r_append_err_and_out:
1202       cprintf ("&>>%s", redirectee->word);
1203       break;
1204     }
1205 }
1206
1207 static void
1208 reset_locals ()
1209 {
1210   inside_function_def = 0;
1211   indentation = 0;
1212   printing_connection = 0;
1213   deferred_heredocs = 0;
1214 }
1215
1216 static void
1217 print_function_def (func)
1218      FUNCTION_DEF *func;
1219 {
1220   COMMAND *cmdcopy;
1221   REDIRECT *func_redirects;
1222
1223   func_redirects = NULL;
1224   cprintf ("function %s () \n", func->name->word);
1225   add_unwind_protect (reset_locals, 0);
1226
1227   indent (indentation);
1228   cprintf ("{ \n");
1229
1230   inside_function_def++;
1231   indentation += indentation_amount;
1232
1233   cmdcopy = copy_command (func->command);
1234   if (cmdcopy->type == cm_group)
1235     {
1236       func_redirects = cmdcopy->redirects;
1237       cmdcopy->redirects = (REDIRECT *)NULL;
1238     }
1239   make_command_string_internal (cmdcopy->type == cm_group
1240                                         ? cmdcopy->value.Group->command
1241                                         : cmdcopy);
1242
1243   remove_unwind_protect ();
1244   indentation -= indentation_amount;
1245   inside_function_def--;
1246
1247   if (func_redirects)
1248     { /* { */
1249       newline ("} ");
1250       print_redirection_list (func_redirects);
1251       cmdcopy->redirects = func_redirects;
1252     }
1253   else
1254     newline ("}");
1255
1256   dispose_command (cmdcopy);
1257 }
1258
1259 /* Return the string representation of the named function.
1260    NAME is the name of the function.
1261    COMMAND is the function body.  It should be a GROUP_COM.
1262    flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1263    flags&FUNC_EXTERNAL means convert from internal to external form
1264   */
1265 char *
1266 named_function_string (name, command, flags)
1267      char *name;
1268      COMMAND *command;
1269      int flags;
1270 {
1271   char *result;
1272   int old_indent, old_amount;
1273   COMMAND *cmdcopy;
1274   REDIRECT *func_redirects;
1275
1276   old_indent = indentation;
1277   old_amount = indentation_amount;
1278   command_string_index = was_heredoc = 0;
1279   deferred_heredocs = 0;
1280
1281   if (name && *name)
1282     cprintf ("%s ", name);
1283
1284   cprintf ("() ");
1285
1286   if ((flags & FUNC_MULTILINE) == 0)
1287     {
1288       indentation = 1;
1289       indentation_amount = 0;
1290     }
1291   else
1292     {
1293       cprintf ("\n");
1294       indentation += indentation_amount;
1295     }
1296
1297   inside_function_def++;
1298
1299   cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1300
1301   cmdcopy = copy_command (command);
1302   /* Take any redirections specified in the function definition (which should
1303      apply to the function as a whole) and save them for printing later. */
1304   func_redirects = (REDIRECT *)NULL;
1305   if (cmdcopy->type == cm_group)
1306     {
1307       func_redirects = cmdcopy->redirects;
1308       cmdcopy->redirects = (REDIRECT *)NULL;
1309     }
1310   make_command_string_internal (cmdcopy->type == cm_group
1311                                         ? cmdcopy->value.Group->command
1312                                         : cmdcopy);
1313
1314   indentation = old_indent;
1315   indentation_amount = old_amount;
1316   inside_function_def--;
1317
1318   if (func_redirects)
1319     { /* { */
1320       newline ("} ");
1321       print_redirection_list (func_redirects);
1322       cmdcopy->redirects = func_redirects;
1323     }
1324   else
1325     newline ("}");
1326
1327   result = the_printed_command;
1328
1329   if ((flags & FUNC_MULTILINE) == 0)
1330     {
1331 #if 0
1332       register int i;
1333       for (i = 0; result[i]; i++)
1334         if (result[i] == '\n')
1335           {
1336             strcpy (result + i, result + i + 1);
1337             --i;
1338           }
1339 #else
1340       if (result[2] == '\n')    /* XXX -- experimental */
1341         strcpy (result + 2, result + 3);
1342 #endif
1343     }
1344
1345   dispose_command (cmdcopy);
1346
1347   if (flags & FUNC_EXTERNAL)
1348     result = remove_quoted_escapes (result);
1349
1350   return (result);
1351 }
1352
1353 static void
1354 newline (string)
1355      char *string;
1356 {
1357   cprintf ("\n");
1358   indent (indentation);
1359   if (string && *string)
1360     cprintf ("%s", string);
1361 }
1362
1363 static char *indentation_string;
1364 static int indentation_size;
1365
1366 static void
1367 indent (amount)
1368      int amount;
1369 {
1370   register int i;
1371
1372   RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1373
1374   for (i = 0; amount > 0; amount--)
1375     indentation_string[i++] = ' ';
1376   indentation_string[i] = '\0';
1377   cprintf (indentation_string);
1378 }
1379
1380 static void
1381 semicolon ()
1382 {
1383   if (command_string_index > 0 &&
1384        (the_printed_command[command_string_index - 1] == '&' ||
1385         the_printed_command[command_string_index - 1] == '\n'))
1386     return;
1387   cprintf (";");
1388 }
1389
1390 /* How to make the string. */
1391 static void
1392 #if defined (PREFER_STDARG)
1393 cprintf (const char *control, ...)
1394 #else
1395 cprintf (control, va_alist)
1396      const char *control;
1397      va_dcl
1398 #endif
1399 {
1400   register const char *s;
1401   char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1402   int digit_arg, arg_len, c;
1403   va_list args;
1404
1405   SH_VA_START (args, control);
1406
1407   arg_len = strlen (control);
1408   the_printed_command_resize (arg_len + 1);
1409
1410   char_arg[1] = '\0';
1411   s = control;
1412   while (s && *s)
1413     {
1414       c = *s++;
1415       argp = (char *)NULL;
1416       if (c != '%' || !*s)
1417         {
1418           char_arg[0] = c;
1419           argp = char_arg;
1420           arg_len = 1;
1421         }
1422       else
1423         {
1424           c = *s++;
1425           switch (c)
1426             {
1427             case '%':
1428               char_arg[0] = c;
1429               argp = char_arg;
1430               arg_len = 1;
1431               break;
1432
1433             case 's':
1434               argp = va_arg (args, char *);
1435               arg_len = strlen (argp);
1436               break;
1437
1438             case 'd':
1439               /* Represent an out-of-range file descriptor with an out-of-range
1440                  integer value.  We can do this because the only use of `%d' in
1441                  the calls to cprintf is to output a file descriptor number for
1442                  a redirection. */
1443               digit_arg = va_arg (args, int);
1444               if (digit_arg < 0)
1445                 {
1446                   sprintf (intbuf, "%u", (unsigned)-1);
1447                   argp = intbuf;
1448                 }
1449               else
1450                 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1451               arg_len = strlen (argp);
1452               break;
1453
1454             case 'c':
1455               char_arg[0] = va_arg (args, int);
1456               argp = char_arg;
1457               arg_len = 1;
1458               break;
1459
1460             default:
1461               programming_error (_("cprintf: `%c': invalid format character"), c);
1462               /*NOTREACHED*/
1463             }
1464         }
1465
1466       if (argp && arg_len)
1467         {
1468           the_printed_command_resize (arg_len + 1);
1469           FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1470           command_string_index += arg_len;
1471         }
1472     }
1473
1474   the_printed_command[command_string_index] = '\0';
1475 }
1476
1477 /* Ensure that there is enough space to stuff LENGTH characters into
1478    THE_PRINTED_COMMAND. */
1479 static void
1480 the_printed_command_resize (length)
1481      int length;
1482 {
1483   if (the_printed_command == 0)
1484     {
1485       the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1486       the_printed_command = (char *)xmalloc (the_printed_command_size);
1487       command_string_index = 0;
1488     }
1489   else if ((command_string_index + length) >= the_printed_command_size)
1490     {
1491       int new;
1492       new = command_string_index + length + 1;
1493
1494       /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1495       new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1496       the_printed_command_size = new;
1497
1498       the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1499     }
1500 }
1501
1502 #if defined (HAVE_VPRINTF)
1503 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1504      also available.'' */
1505
1506 static void
1507 #if defined (PREFER_STDARG)
1508 xprintf (const char *format, ...)
1509 #else
1510 xprintf (format, va_alist)
1511      const char *format;
1512      va_dcl
1513 #endif
1514 {
1515   va_list args;
1516
1517   SH_VA_START (args, format);
1518
1519   vfprintf (stdout, format, args);
1520   va_end (args);
1521 }
1522
1523 #else
1524
1525 static void
1526 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1527      const char *format;
1528 {
1529   printf (format, arg1, arg2, arg3, arg4, arg5);
1530 }
1531
1532 #endif /* !HAVE_VPRINTF */