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