]> git.ipfire.org Git - thirdparty/bash.git/blob - print_cmd.c
Imported from ../bash-4.0.tar.gz.
[thirdparty/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 */