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