]> git.ipfire.org Git - thirdparty/bash.git/blob - print_cmd.c~
commit bash-20100204 snapshot
[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 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 0
1124 /* Don't need to check whether or not to requote, since original quotes
1125 are still intact. The only thing that has happened is that $'...'
1126 has been replaced with 'expanded ...'. */
1127 if (ansic_shouldquote (redirect->redirectee.filename->word))
1128 {
1129 char *x;
1130 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1131 cprintf ("<<< %s", x);
1132 free (x);
1133 }
1134 else
1135 #endif
1136 cprintf ("<<< %s", redirect->redirectee.filename->word);
1137 break;
1138
1139 case r_duplicating_input:
1140 if (redirect->rflags & REDIR_VARASSIGN)
1141 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1142 else
1143 cprintf ("%d<&%d", redirector, redir_fd);
1144 break;
1145
1146 case r_duplicating_output:
1147 if (redirect->rflags & REDIR_VARASSIGN)
1148 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1149 else
1150 cprintf ("%d>&%d", redirector, redir_fd);
1151 break;
1152
1153 case r_duplicating_input_word:
1154 if (redirect->rflags & REDIR_VARASSIGN)
1155 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1156 else
1157 cprintf ("%d<&%s", redirector, redirectee->word);
1158 break;
1159
1160 case r_duplicating_output_word:
1161 if (redirect->rflags & REDIR_VARASSIGN)
1162 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1163 else
1164 cprintf ("%d>&%s", redirector, redirectee->word);
1165 break;
1166
1167 case r_move_input:
1168 if (redirect->rflags & REDIR_VARASSIGN)
1169 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1170 else
1171 cprintf ("%d<&%d-", redirector, redir_fd);
1172 break;
1173
1174 case r_move_output:
1175 if (redirect->rflags & REDIR_VARASSIGN)
1176 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1177 else
1178 cprintf ("%d>&%d-", redirector, redir_fd);
1179 break;
1180
1181 case r_move_input_word:
1182 if (redirect->rflags & REDIR_VARASSIGN)
1183 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1184 else
1185 cprintf ("%d<&%s-", redirector, redirectee->word);
1186 break;
1187
1188 case r_move_output_word:
1189 if (redirect->rflags & REDIR_VARASSIGN)
1190 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1191 else
1192 cprintf ("%d>&%s-", redirector, redirectee->word);
1193 break;
1194
1195 case r_close_this:
1196 if (redirect->rflags & REDIR_VARASSIGN)
1197 cprintf ("{%s}>&-", redir_word->word);
1198 else
1199 cprintf ("%d>&-", redirector);
1200 break;
1201
1202 case r_err_and_out:
1203 cprintf ("&>%s", redirectee->word);
1204 break;
1205
1206 case r_append_err_and_out:
1207 cprintf ("&>>%s", redirectee->word);
1208 break;
1209 }
1210 }
1211
1212 static void
1213 reset_locals ()
1214 {
1215 inside_function_def = 0;
1216 indentation = 0;
1217 printing_connection = 0;
1218 deferred_heredocs = 0;
1219 }
1220
1221 static void
1222 print_function_def (func)
1223 FUNCTION_DEF *func;
1224 {
1225 COMMAND *cmdcopy;
1226 REDIRECT *func_redirects;
1227
1228 func_redirects = NULL;
1229 cprintf ("function %s () \n", func->name->word);
1230 add_unwind_protect (reset_locals, 0);
1231
1232 indent (indentation);
1233 cprintf ("{ \n");
1234
1235 inside_function_def++;
1236 indentation += indentation_amount;
1237
1238 cmdcopy = copy_command (func->command);
1239 if (cmdcopy->type == cm_group)
1240 {
1241 func_redirects = cmdcopy->redirects;
1242 cmdcopy->redirects = (REDIRECT *)NULL;
1243 }
1244 make_command_string_internal (cmdcopy->type == cm_group
1245 ? cmdcopy->value.Group->command
1246 : cmdcopy);
1247
1248 remove_unwind_protect ();
1249 indentation -= indentation_amount;
1250 inside_function_def--;
1251
1252 if (func_redirects)
1253 { /* { */
1254 newline ("} ");
1255 print_redirection_list (func_redirects);
1256 cmdcopy->redirects = func_redirects;
1257 }
1258 else
1259 newline ("}");
1260
1261 dispose_command (cmdcopy);
1262 }
1263
1264 /* Return the string representation of the named function.
1265 NAME is the name of the function.
1266 COMMAND is the function body. It should be a GROUP_COM.
1267 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1268 flags&FUNC_EXTERNAL means convert from internal to external form
1269 */
1270 char *
1271 named_function_string (name, command, flags)
1272 char *name;
1273 COMMAND *command;
1274 int flags;
1275 {
1276 char *result;
1277 int old_indent, old_amount;
1278 COMMAND *cmdcopy;
1279 REDIRECT *func_redirects;
1280
1281 old_indent = indentation;
1282 old_amount = indentation_amount;
1283 command_string_index = was_heredoc = 0;
1284 deferred_heredocs = 0;
1285
1286 if (name && *name)
1287 cprintf ("%s ", name);
1288
1289 cprintf ("() ");
1290
1291 if ((flags & FUNC_MULTILINE) == 0)
1292 {
1293 indentation = 1;
1294 indentation_amount = 0;
1295 }
1296 else
1297 {
1298 cprintf ("\n");
1299 indentation += indentation_amount;
1300 }
1301
1302 inside_function_def++;
1303
1304 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1305
1306 cmdcopy = copy_command (command);
1307 /* Take any redirections specified in the function definition (which should
1308 apply to the function as a whole) and save them for printing later. */
1309 func_redirects = (REDIRECT *)NULL;
1310 if (cmdcopy->type == cm_group)
1311 {
1312 func_redirects = cmdcopy->redirects;
1313 cmdcopy->redirects = (REDIRECT *)NULL;
1314 }
1315 make_command_string_internal (cmdcopy->type == cm_group
1316 ? cmdcopy->value.Group->command
1317 : cmdcopy);
1318
1319 indentation = old_indent;
1320 indentation_amount = old_amount;
1321 inside_function_def--;
1322
1323 if (func_redirects)
1324 { /* { */
1325 newline ("} ");
1326 print_redirection_list (func_redirects);
1327 cmdcopy->redirects = func_redirects;
1328 }
1329 else
1330 newline ("}");
1331
1332 result = the_printed_command;
1333
1334 if ((flags & FUNC_MULTILINE) == 0)
1335 {
1336 #if 0
1337 register int i;
1338 for (i = 0; result[i]; i++)
1339 if (result[i] == '\n')
1340 {
1341 strcpy (result + i, result + i + 1);
1342 --i;
1343 }
1344 #else
1345 if (result[2] == '\n') /* XXX -- experimental */
1346 strcpy (result + 2, result + 3);
1347 #endif
1348 }
1349
1350 dispose_command (cmdcopy);
1351
1352 if (flags & FUNC_EXTERNAL)
1353 result = remove_quoted_escapes (result);
1354
1355 return (result);
1356 }
1357
1358 static void
1359 newline (string)
1360 char *string;
1361 {
1362 cprintf ("\n");
1363 indent (indentation);
1364 if (string && *string)
1365 cprintf ("%s", string);
1366 }
1367
1368 static char *indentation_string;
1369 static int indentation_size;
1370
1371 static void
1372 indent (amount)
1373 int amount;
1374 {
1375 register int i;
1376
1377 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1378
1379 for (i = 0; amount > 0; amount--)
1380 indentation_string[i++] = ' ';
1381 indentation_string[i] = '\0';
1382 cprintf (indentation_string);
1383 }
1384
1385 static void
1386 semicolon ()
1387 {
1388 if (command_string_index > 0 &&
1389 (the_printed_command[command_string_index - 1] == '&' ||
1390 the_printed_command[command_string_index - 1] == '\n'))
1391 return;
1392 cprintf (";");
1393 }
1394
1395 /* How to make the string. */
1396 static void
1397 #if defined (PREFER_STDARG)
1398 cprintf (const char *control, ...)
1399 #else
1400 cprintf (control, va_alist)
1401 const char *control;
1402 va_dcl
1403 #endif
1404 {
1405 register const char *s;
1406 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1407 int digit_arg, arg_len, c;
1408 va_list args;
1409
1410 SH_VA_START (args, control);
1411
1412 arg_len = strlen (control);
1413 the_printed_command_resize (arg_len + 1);
1414
1415 char_arg[1] = '\0';
1416 s = control;
1417 while (s && *s)
1418 {
1419 c = *s++;
1420 argp = (char *)NULL;
1421 if (c != '%' || !*s)
1422 {
1423 char_arg[0] = c;
1424 argp = char_arg;
1425 arg_len = 1;
1426 }
1427 else
1428 {
1429 c = *s++;
1430 switch (c)
1431 {
1432 case '%':
1433 char_arg[0] = c;
1434 argp = char_arg;
1435 arg_len = 1;
1436 break;
1437
1438 case 's':
1439 argp = va_arg (args, char *);
1440 arg_len = strlen (argp);
1441 break;
1442
1443 case 'd':
1444 /* Represent an out-of-range file descriptor with an out-of-range
1445 integer value. We can do this because the only use of `%d' in
1446 the calls to cprintf is to output a file descriptor number for
1447 a redirection. */
1448 digit_arg = va_arg (args, int);
1449 if (digit_arg < 0)
1450 {
1451 sprintf (intbuf, "%u", (unsigned)-1);
1452 argp = intbuf;
1453 }
1454 else
1455 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1456 arg_len = strlen (argp);
1457 break;
1458
1459 case 'c':
1460 char_arg[0] = va_arg (args, int);
1461 argp = char_arg;
1462 arg_len = 1;
1463 break;
1464
1465 default:
1466 programming_error (_("cprintf: `%c': invalid format character"), c);
1467 /*NOTREACHED*/
1468 }
1469 }
1470
1471 if (argp && arg_len)
1472 {
1473 the_printed_command_resize (arg_len + 1);
1474 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1475 command_string_index += arg_len;
1476 }
1477 }
1478
1479 the_printed_command[command_string_index] = '\0';
1480 }
1481
1482 /* Ensure that there is enough space to stuff LENGTH characters into
1483 THE_PRINTED_COMMAND. */
1484 static void
1485 the_printed_command_resize (length)
1486 int length;
1487 {
1488 if (the_printed_command == 0)
1489 {
1490 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1491 the_printed_command = (char *)xmalloc (the_printed_command_size);
1492 command_string_index = 0;
1493 }
1494 else if ((command_string_index + length) >= the_printed_command_size)
1495 {
1496 int new;
1497 new = command_string_index + length + 1;
1498
1499 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1500 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1501 the_printed_command_size = new;
1502
1503 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1504 }
1505 }
1506
1507 #if defined (HAVE_VPRINTF)
1508 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1509 also available.'' */
1510
1511 static void
1512 #if defined (PREFER_STDARG)
1513 xprintf (const char *format, ...)
1514 #else
1515 xprintf (format, va_alist)
1516 const char *format;
1517 va_dcl
1518 #endif
1519 {
1520 va_list args;
1521
1522 SH_VA_START (args, format);
1523
1524 vfprintf (stdout, format, args);
1525 va_end (args);
1526 }
1527
1528 #else
1529
1530 static void
1531 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1532 const char *format;
1533 {
1534 printf (format, arg1, arg2, arg3, arg4, arg5);
1535 }
1536
1537 #endif /* !HAVE_VPRINTF */