]> git.ipfire.org Git - thirdparty/bash.git/blob - print_cmd.c
Bash-4.2 patch 28
[thirdparty/bash.git] / print_cmd.c
1 /* print_command -- A way to make readable commands from a command tree. */
2
3 /* Copyright (C) 1989-2010 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];
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 PRINT_DEFERRED_HEREDOCS ("");
303 printing_connection--;
304 break;
305
306 case cm_function_def:
307 print_function_def (command->value.Function_def);
308 break;
309
310 case cm_group:
311 print_group_command (command->value.Group);
312 break;
313
314 case cm_subshell:
315 cprintf ("( ");
316 skip_this_indent++;
317 make_command_string_internal (command->value.Subshell->command);
318 PRINT_DEFERRED_HEREDOCS ("");
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 PRINT_DEFERRED_HEREDOCS ("");
597 semicolon ();
598 indentation -= indentation_amount;
599 newline ("done");
600 }
601 #endif /* ARITH_FOR_COMMAND */
602
603 #if defined (SELECT_COMMAND)
604 void
605 print_select_command_head (select_command)
606 SELECT_COM *select_command;
607 {
608 cprintf ("select %s in ", select_command->name->word);
609 command_print_word_list (select_command->map_list, " ");
610 }
611
612 void
613 xtrace_print_select_command_head (select_command)
614 SELECT_COM *select_command;
615 {
616 CHECK_XTRACE_FP;
617 fprintf (xtrace_fp, "%s", indirection_level_string ());
618 fprintf (xtrace_fp, "select %s in ", select_command->name->word);
619 xtrace_print_word_list (select_command->map_list, 0);
620 }
621
622 static void
623 print_select_command (select_command)
624 SELECT_COM *select_command;
625 {
626 print_select_command_head (select_command);
627
628 cprintf (";");
629 newline ("do\n");
630 indentation += indentation_amount;
631 make_command_string_internal (select_command->action);
632 PRINT_DEFERRED_HEREDOCS ("");
633 semicolon ();
634 indentation -= indentation_amount;
635 newline ("done");
636 }
637 #endif /* SELECT_COMMAND */
638
639 static void
640 print_group_command (group_command)
641 GROUP_COM *group_command;
642 {
643 group_command_nesting++;
644 cprintf ("{ ");
645
646 if (inside_function_def == 0)
647 skip_this_indent++;
648 else
649 {
650 /* This is a group command { ... } inside of a function
651 definition, and should be printed as a multiline group
652 command, using the current indentation. */
653 cprintf ("\n");
654 indentation += indentation_amount;
655 }
656
657 make_command_string_internal (group_command->command);
658 PRINT_DEFERRED_HEREDOCS ("");
659
660 if (inside_function_def)
661 {
662 cprintf ("\n");
663 indentation -= indentation_amount;
664 indent (indentation);
665 }
666 else
667 {
668 semicolon ();
669 cprintf (" ");
670 }
671
672 cprintf ("}");
673
674 group_command_nesting--;
675 }
676
677 void
678 print_case_command_head (case_command)
679 CASE_COM *case_command;
680 {
681 cprintf ("case %s in ", case_command->word->word);
682 }
683
684 void
685 xtrace_print_case_command_head (case_command)
686 CASE_COM *case_command;
687 {
688 CHECK_XTRACE_FP;
689 fprintf (xtrace_fp, "%s", indirection_level_string ());
690 fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
691 }
692
693 static void
694 print_case_command (case_command)
695 CASE_COM *case_command;
696 {
697 print_case_command_head (case_command);
698
699 if (case_command->clauses)
700 print_case_clauses (case_command->clauses);
701 newline ("esac");
702 }
703
704 static void
705 print_case_clauses (clauses)
706 PATTERN_LIST *clauses;
707 {
708 indentation += indentation_amount;
709 while (clauses)
710 {
711 newline ("");
712 command_print_word_list (clauses->patterns, " | ");
713 cprintf (")\n");
714 indentation += indentation_amount;
715 make_command_string_internal (clauses->action);
716 indentation -= indentation_amount;
717 PRINT_DEFERRED_HEREDOCS ("");
718 if (clauses->flags & CASEPAT_FALLTHROUGH)
719 newline (";&");
720 else if (clauses->flags & CASEPAT_TESTNEXT)
721 newline (";;&");
722 else
723 newline (";;");
724 clauses = clauses->next;
725 }
726 indentation -= indentation_amount;
727 }
728
729 static void
730 print_while_command (while_command)
731 WHILE_COM *while_command;
732 {
733 print_until_or_while (while_command, "while");
734 }
735
736 static void
737 print_until_command (while_command)
738 WHILE_COM *while_command;
739 {
740 print_until_or_while (while_command, "until");
741 }
742
743 static void
744 print_until_or_while (while_command, which)
745 WHILE_COM *while_command;
746 char *which;
747 {
748 cprintf ("%s ", which);
749 skip_this_indent++;
750 make_command_string_internal (while_command->test);
751 PRINT_DEFERRED_HEREDOCS ("");
752 semicolon ();
753 cprintf (" do\n"); /* was newline ("do\n"); */
754 indentation += indentation_amount;
755 make_command_string_internal (while_command->action);
756 PRINT_DEFERRED_HEREDOCS ("");
757 indentation -= indentation_amount;
758 semicolon ();
759 newline ("done");
760 }
761
762 static void
763 print_if_command (if_command)
764 IF_COM *if_command;
765 {
766 cprintf ("if ");
767 skip_this_indent++;
768 make_command_string_internal (if_command->test);
769 semicolon ();
770 cprintf (" then\n");
771 indentation += indentation_amount;
772 make_command_string_internal (if_command->true_case);
773 PRINT_DEFERRED_HEREDOCS ("");
774 indentation -= indentation_amount;
775
776 if (if_command->false_case)
777 {
778 semicolon ();
779 newline ("else\n");
780 indentation += indentation_amount;
781 make_command_string_internal (if_command->false_case);
782 PRINT_DEFERRED_HEREDOCS ("");
783 indentation -= indentation_amount;
784 }
785 semicolon ();
786 newline ("fi");
787 }
788
789 #if defined (DPAREN_ARITHMETIC)
790 void
791 print_arith_command (arith_cmd_list)
792 WORD_LIST *arith_cmd_list;
793 {
794 cprintf ("((");
795 command_print_word_list (arith_cmd_list, " ");
796 cprintf ("))");
797 }
798 #endif
799
800 #if defined (COND_COMMAND)
801 static void
802 print_cond_node (cond)
803 COND_COM *cond;
804 {
805 if (cond->flags & CMD_INVERT_RETURN)
806 cprintf ("! ");
807
808 if (cond->type == COND_EXPR)
809 {
810 cprintf ("( ");
811 print_cond_node (cond->left);
812 cprintf (" )");
813 }
814 else if (cond->type == COND_AND)
815 {
816 print_cond_node (cond->left);
817 cprintf (" && ");
818 print_cond_node (cond->right);
819 }
820 else if (cond->type == COND_OR)
821 {
822 print_cond_node (cond->left);
823 cprintf (" || ");
824 print_cond_node (cond->right);
825 }
826 else if (cond->type == COND_UNARY)
827 {
828 cprintf ("%s", cond->op->word);
829 cprintf (" ");
830 print_cond_node (cond->left);
831 }
832 else if (cond->type == COND_BINARY)
833 {
834 print_cond_node (cond->left);
835 cprintf (" ");
836 cprintf ("%s", cond->op->word);
837 cprintf (" ");
838 print_cond_node (cond->right);
839 }
840 else if (cond->type == COND_TERM)
841 {
842 cprintf ("%s", cond->op->word); /* need to add quoting here */
843 }
844 }
845
846 void
847 print_cond_command (cond)
848 COND_COM *cond;
849 {
850 cprintf ("[[ ");
851 print_cond_node (cond);
852 cprintf (" ]]");
853 }
854
855 #ifdef DEBUG
856 void
857 debug_print_cond_command (cond)
858 COND_COM *cond;
859 {
860 fprintf (stderr, "DEBUG: ");
861 command_string_index = 0;
862 print_cond_command (cond);
863 fprintf (stderr, "%s\n", the_printed_command);
864 }
865 #endif
866
867 void
868 xtrace_print_cond_term (type, invert, op, arg1, arg2)
869 int type, invert;
870 WORD_DESC *op;
871 char *arg1, *arg2;
872 {
873 CHECK_XTRACE_FP;
874 command_string_index = 0;
875 fprintf (xtrace_fp, "%s", indirection_level_string ());
876 fprintf (xtrace_fp, "[[ ");
877 if (invert)
878 fprintf (xtrace_fp, "! ");
879
880 if (type == COND_UNARY)
881 {
882 fprintf (xtrace_fp, "%s ", op->word);
883 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
884 }
885 else if (type == COND_BINARY)
886 {
887 fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
888 fprintf (xtrace_fp, " %s ", op->word);
889 fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
890 }
891
892 fprintf (xtrace_fp, " ]]\n");
893
894 fflush (xtrace_fp);
895 }
896 #endif /* COND_COMMAND */
897
898 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
899 /* A function to print the words of an arithmetic command when set -x is on. */
900 void
901 xtrace_print_arith_cmd (list)
902 WORD_LIST *list;
903 {
904 WORD_LIST *w;
905
906 CHECK_XTRACE_FP;
907 fprintf (xtrace_fp, "%s", indirection_level_string ());
908 fprintf (xtrace_fp, "(( ");
909 for (w = list; w; w = w->next)
910 fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
911 fprintf (xtrace_fp, " ))\n");
912
913 fflush (xtrace_fp);
914 }
915 #endif
916
917 void
918 print_simple_command (simple_command)
919 SIMPLE_COM *simple_command;
920 {
921 command_print_word_list (simple_command->words, " ");
922
923 if (simple_command->redirects)
924 {
925 cprintf (" ");
926 print_redirection_list (simple_command->redirects);
927 }
928 }
929
930 static void
931 print_heredocs (heredocs)
932 REDIRECT *heredocs;
933 {
934 REDIRECT *hdtail;
935
936 cprintf (" ");
937 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
938 {
939 print_redirection (hdtail);
940 cprintf ("\n");
941 }
942 was_heredoc = 1;
943 }
944
945 /* Print heredocs that are attached to the command before the connector
946 represented by CSTRING. The parsing semantics require us to print the
947 here-doc delimiters, then the connector (CSTRING), then the here-doc
948 bodies. We don't print the connector if it's a `;', but we use it to
949 note not to print an extra space after the last heredoc body and
950 newline. */
951 static void
952 print_deferred_heredocs (cstring)
953 const char *cstring;
954 {
955 REDIRECT *hdtail;
956
957 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
958 {
959 cprintf (" ");
960 print_heredoc_header (hdtail);
961 }
962 if (cstring[0] && (cstring[0] != ';' || cstring[1]))
963 cprintf ("%s", cstring);
964 if (deferred_heredocs)
965 cprintf ("\n");
966 for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
967 {
968 print_heredoc_body (hdtail);
969 cprintf ("\n");
970 }
971 if (deferred_heredocs)
972 {
973 if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
974 cprintf (" "); /* make sure there's at least one space */
975 dispose_redirects (deferred_heredocs);
976 was_heredoc = 1;
977 }
978 deferred_heredocs = (REDIRECT *)NULL;
979 }
980
981 static void
982 print_redirection_list (redirects)
983 REDIRECT *redirects;
984 {
985 REDIRECT *heredocs, *hdtail, *newredir;
986
987 heredocs = (REDIRECT *)NULL;
988 hdtail = heredocs;
989
990 was_heredoc = 0;
991 while (redirects)
992 {
993 /* Defer printing the here documents until we've printed the
994 rest of the redirections. */
995 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
996 {
997 newredir = copy_redirect (redirects);
998 newredir->next = (REDIRECT *)NULL;
999 if (heredocs)
1000 {
1001 hdtail->next = newredir;
1002 hdtail = newredir;
1003 }
1004 else
1005 hdtail = heredocs = newredir;
1006 }
1007 else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
1008 {
1009 /* Temporarily translate it as the execution code does. */
1010 redirects->instruction = r_err_and_out;
1011 print_redirection (redirects);
1012 redirects->instruction = r_duplicating_output_word;
1013 }
1014 else
1015 print_redirection (redirects);
1016
1017 redirects = redirects->next;
1018 if (redirects)
1019 cprintf (" ");
1020 }
1021
1022 /* Now that we've printed all the other redirections (on one line),
1023 print the here documents. */
1024 if (heredocs && printing_connection)
1025 deferred_heredocs = heredocs;
1026 else if (heredocs)
1027 {
1028 print_heredocs (heredocs);
1029 dispose_redirects (heredocs);
1030 }
1031 }
1032
1033 static void
1034 print_heredoc_header (redirect)
1035 REDIRECT *redirect;
1036 {
1037 int kill_leading;
1038 char *x;
1039
1040 kill_leading = redirect->instruction == r_deblank_reading_until;
1041
1042 /* Here doc header */
1043 if (redirect->rflags & REDIR_VARASSIGN)
1044 cprintf ("{%s}", redirect->redirector.filename->word);
1045 else if (redirect->redirector.dest != 0)
1046 cprintf ("%d", redirect->redirector.dest);
1047
1048 /* If the here document delimiter is quoted, single-quote it. */
1049 if (redirect->redirectee.filename->flags & W_QUOTED)
1050 {
1051 x = sh_single_quote (redirect->here_doc_eof);
1052 cprintf ("<<%s%s", kill_leading ? "-" : "", x);
1053 free (x);
1054 }
1055 else
1056 cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
1057 }
1058
1059 static void
1060 print_heredoc_body (redirect)
1061 REDIRECT *redirect;
1062 {
1063 /* Here doc body */
1064 cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
1065 }
1066
1067 static void
1068 print_redirection (redirect)
1069 REDIRECT *redirect;
1070 {
1071 int redirector, redir_fd;
1072 WORD_DESC *redirectee, *redir_word;
1073
1074 redirectee = redirect->redirectee.filename;
1075 redir_fd = redirect->redirectee.dest;
1076
1077 redir_word = redirect->redirector.filename;
1078 redirector = redirect->redirector.dest;
1079
1080 switch (redirect->instruction)
1081 {
1082 case r_input_direction:
1083 if (redirect->rflags & REDIR_VARASSIGN)
1084 cprintf ("{%s}", redir_word->word);
1085 else if (redirector != 0)
1086 cprintf ("%d", redirector);
1087 cprintf ("< %s", redirectee->word);
1088 break;
1089
1090 case r_output_direction:
1091 if (redirect->rflags & REDIR_VARASSIGN)
1092 cprintf ("{%s}", redir_word->word);
1093 else if (redirector != 1)
1094 cprintf ("%d", redirector);
1095 cprintf ("> %s", redirectee->word);
1096 break;
1097
1098 case r_inputa_direction: /* Redirection created by the shell. */
1099 cprintf ("&");
1100 break;
1101
1102 case r_output_force:
1103 if (redirect->rflags & REDIR_VARASSIGN)
1104 cprintf ("{%s}", redir_word->word);
1105 else if (redirector != 1)
1106 cprintf ("%d", redirector);
1107 cprintf (">|%s", redirectee->word);
1108 break;
1109
1110 case r_appending_to:
1111 if (redirect->rflags & REDIR_VARASSIGN)
1112 cprintf ("{%s}", redir_word->word);
1113 else if (redirector != 1)
1114 cprintf ("%d", redirector);
1115 cprintf (">> %s", redirectee->word);
1116 break;
1117
1118 case r_input_output:
1119 if (redirect->rflags & REDIR_VARASSIGN)
1120 cprintf ("{%s}", redir_word->word);
1121 else if (redirector != 1)
1122 cprintf ("%d", redirector);
1123 cprintf ("<> %s", redirectee->word);
1124 break;
1125
1126 case r_deblank_reading_until:
1127 case r_reading_until:
1128 print_heredoc_header (redirect);
1129 cprintf ("\n");
1130 print_heredoc_body (redirect);
1131 break;
1132
1133 case r_reading_string:
1134 if (redirect->rflags & REDIR_VARASSIGN)
1135 cprintf ("{%s}", redir_word->word);
1136 else if (redirector != 0)
1137 cprintf ("%d", redirector);
1138 #if 0
1139 /* Don't need to check whether or not to requote, since original quotes
1140 are still intact. The only thing that has happened is that $'...'
1141 has been replaced with 'expanded ...'. */
1142 if (ansic_shouldquote (redirect->redirectee.filename->word))
1143 {
1144 char *x;
1145 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
1146 cprintf ("<<< %s", x);
1147 free (x);
1148 }
1149 else
1150 #endif
1151 cprintf ("<<< %s", redirect->redirectee.filename->word);
1152 break;
1153
1154 case r_duplicating_input:
1155 if (redirect->rflags & REDIR_VARASSIGN)
1156 cprintf ("{%s}<&%d", redir_word->word, redir_fd);
1157 else
1158 cprintf ("%d<&%d", redirector, redir_fd);
1159 break;
1160
1161 case r_duplicating_output:
1162 if (redirect->rflags & REDIR_VARASSIGN)
1163 cprintf ("{%s}>&%d", redir_word->word, redir_fd);
1164 else
1165 cprintf ("%d>&%d", redirector, redir_fd);
1166 break;
1167
1168 case r_duplicating_input_word:
1169 if (redirect->rflags & REDIR_VARASSIGN)
1170 cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
1171 else
1172 cprintf ("%d<&%s", redirector, redirectee->word);
1173 break;
1174
1175 case r_duplicating_output_word:
1176 if (redirect->rflags & REDIR_VARASSIGN)
1177 cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
1178 else
1179 cprintf ("%d>&%s", redirector, redirectee->word);
1180 break;
1181
1182 case r_move_input:
1183 if (redirect->rflags & REDIR_VARASSIGN)
1184 cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
1185 else
1186 cprintf ("%d<&%d-", redirector, redir_fd);
1187 break;
1188
1189 case r_move_output:
1190 if (redirect->rflags & REDIR_VARASSIGN)
1191 cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
1192 else
1193 cprintf ("%d>&%d-", redirector, redir_fd);
1194 break;
1195
1196 case r_move_input_word:
1197 if (redirect->rflags & REDIR_VARASSIGN)
1198 cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
1199 else
1200 cprintf ("%d<&%s-", redirector, redirectee->word);
1201 break;
1202
1203 case r_move_output_word:
1204 if (redirect->rflags & REDIR_VARASSIGN)
1205 cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
1206 else
1207 cprintf ("%d>&%s-", redirector, redirectee->word);
1208 break;
1209
1210 case r_close_this:
1211 if (redirect->rflags & REDIR_VARASSIGN)
1212 cprintf ("{%s}>&-", redir_word->word);
1213 else
1214 cprintf ("%d>&-", redirector);
1215 break;
1216
1217 case r_err_and_out:
1218 cprintf ("&>%s", redirectee->word);
1219 break;
1220
1221 case r_append_err_and_out:
1222 cprintf ("&>>%s", redirectee->word);
1223 break;
1224 }
1225 }
1226
1227 static void
1228 reset_locals ()
1229 {
1230 inside_function_def = 0;
1231 indentation = 0;
1232 printing_connection = 0;
1233 deferred_heredocs = 0;
1234 }
1235
1236 static void
1237 print_function_def (func)
1238 FUNCTION_DEF *func;
1239 {
1240 COMMAND *cmdcopy;
1241 REDIRECT *func_redirects;
1242
1243 func_redirects = NULL;
1244 cprintf ("function %s () \n", func->name->word);
1245 add_unwind_protect (reset_locals, 0);
1246
1247 indent (indentation);
1248 cprintf ("{ \n");
1249
1250 inside_function_def++;
1251 indentation += indentation_amount;
1252
1253 cmdcopy = copy_command (func->command);
1254 if (cmdcopy->type == cm_group)
1255 {
1256 func_redirects = cmdcopy->redirects;
1257 cmdcopy->redirects = (REDIRECT *)NULL;
1258 }
1259 make_command_string_internal (cmdcopy->type == cm_group
1260 ? cmdcopy->value.Group->command
1261 : cmdcopy);
1262
1263 remove_unwind_protect ();
1264 indentation -= indentation_amount;
1265 inside_function_def--;
1266
1267 if (func_redirects)
1268 { /* { */
1269 newline ("} ");
1270 print_redirection_list (func_redirects);
1271 cmdcopy->redirects = func_redirects;
1272 }
1273 else
1274 newline ("}");
1275
1276 dispose_command (cmdcopy);
1277 }
1278
1279 /* Return the string representation of the named function.
1280 NAME is the name of the function.
1281 COMMAND is the function body. It should be a GROUP_COM.
1282 flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
1283 flags&FUNC_EXTERNAL means convert from internal to external form
1284 */
1285 char *
1286 named_function_string (name, command, flags)
1287 char *name;
1288 COMMAND *command;
1289 int flags;
1290 {
1291 char *result;
1292 int old_indent, old_amount;
1293 COMMAND *cmdcopy;
1294 REDIRECT *func_redirects;
1295
1296 old_indent = indentation;
1297 old_amount = indentation_amount;
1298 command_string_index = was_heredoc = 0;
1299 deferred_heredocs = 0;
1300
1301 if (name && *name)
1302 cprintf ("%s ", name);
1303
1304 cprintf ("() ");
1305
1306 if ((flags & FUNC_MULTILINE) == 0)
1307 {
1308 indentation = 1;
1309 indentation_amount = 0;
1310 }
1311 else
1312 {
1313 cprintf ("\n");
1314 indentation += indentation_amount;
1315 }
1316
1317 inside_function_def++;
1318
1319 cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
1320
1321 cmdcopy = copy_command (command);
1322 /* Take any redirections specified in the function definition (which should
1323 apply to the function as a whole) and save them for printing later. */
1324 func_redirects = (REDIRECT *)NULL;
1325 if (cmdcopy->type == cm_group)
1326 {
1327 func_redirects = cmdcopy->redirects;
1328 cmdcopy->redirects = (REDIRECT *)NULL;
1329 }
1330 make_command_string_internal (cmdcopy->type == cm_group
1331 ? cmdcopy->value.Group->command
1332 : cmdcopy);
1333
1334 indentation = old_indent;
1335 indentation_amount = old_amount;
1336 inside_function_def--;
1337
1338 if (func_redirects)
1339 { /* { */
1340 newline ("} ");
1341 print_redirection_list (func_redirects);
1342 cmdcopy->redirects = func_redirects;
1343 }
1344 else
1345 newline ("}");
1346
1347 result = the_printed_command;
1348
1349 if ((flags & FUNC_MULTILINE) == 0)
1350 {
1351 #if 0
1352 register int i;
1353 for (i = 0; result[i]; i++)
1354 if (result[i] == '\n')
1355 {
1356 strcpy (result + i, result + i + 1);
1357 --i;
1358 }
1359 #else
1360 if (result[2] == '\n') /* XXX -- experimental */
1361 strcpy (result + 2, result + 3);
1362 #endif
1363 }
1364
1365 dispose_command (cmdcopy);
1366
1367 if (flags & FUNC_EXTERNAL)
1368 result = remove_quoted_escapes (result);
1369
1370 return (result);
1371 }
1372
1373 static void
1374 newline (string)
1375 char *string;
1376 {
1377 cprintf ("\n");
1378 indent (indentation);
1379 if (string && *string)
1380 cprintf ("%s", string);
1381 }
1382
1383 static char *indentation_string;
1384 static int indentation_size;
1385
1386 static void
1387 indent (amount)
1388 int amount;
1389 {
1390 register int i;
1391
1392 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1393
1394 for (i = 0; amount > 0; amount--)
1395 indentation_string[i++] = ' ';
1396 indentation_string[i] = '\0';
1397 cprintf (indentation_string);
1398 }
1399
1400 static void
1401 semicolon ()
1402 {
1403 if (command_string_index > 0 &&
1404 (the_printed_command[command_string_index - 1] == '&' ||
1405 the_printed_command[command_string_index - 1] == '\n'))
1406 return;
1407 cprintf (";");
1408 }
1409
1410 /* How to make the string. */
1411 static void
1412 #if defined (PREFER_STDARG)
1413 cprintf (const char *control, ...)
1414 #else
1415 cprintf (control, va_alist)
1416 const char *control;
1417 va_dcl
1418 #endif
1419 {
1420 register const char *s;
1421 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
1422 int digit_arg, arg_len, c;
1423 va_list args;
1424
1425 SH_VA_START (args, control);
1426
1427 arg_len = strlen (control);
1428 the_printed_command_resize (arg_len + 1);
1429
1430 char_arg[1] = '\0';
1431 s = control;
1432 while (s && *s)
1433 {
1434 c = *s++;
1435 argp = (char *)NULL;
1436 if (c != '%' || !*s)
1437 {
1438 char_arg[0] = c;
1439 argp = char_arg;
1440 arg_len = 1;
1441 }
1442 else
1443 {
1444 c = *s++;
1445 switch (c)
1446 {
1447 case '%':
1448 char_arg[0] = c;
1449 argp = char_arg;
1450 arg_len = 1;
1451 break;
1452
1453 case 's':
1454 argp = va_arg (args, char *);
1455 arg_len = strlen (argp);
1456 break;
1457
1458 case 'd':
1459 /* Represent an out-of-range file descriptor with an out-of-range
1460 integer value. We can do this because the only use of `%d' in
1461 the calls to cprintf is to output a file descriptor number for
1462 a redirection. */
1463 digit_arg = va_arg (args, int);
1464 if (digit_arg < 0)
1465 {
1466 sprintf (intbuf, "%u", (unsigned)-1);
1467 argp = intbuf;
1468 }
1469 else
1470 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1471 arg_len = strlen (argp);
1472 break;
1473
1474 case 'c':
1475 char_arg[0] = va_arg (args, int);
1476 argp = char_arg;
1477 arg_len = 1;
1478 break;
1479
1480 default:
1481 programming_error (_("cprintf: `%c': invalid format character"), c);
1482 /*NOTREACHED*/
1483 }
1484 }
1485
1486 if (argp && arg_len)
1487 {
1488 the_printed_command_resize (arg_len + 1);
1489 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1490 command_string_index += arg_len;
1491 }
1492 }
1493
1494 the_printed_command[command_string_index] = '\0';
1495 }
1496
1497 /* Ensure that there is enough space to stuff LENGTH characters into
1498 THE_PRINTED_COMMAND. */
1499 static void
1500 the_printed_command_resize (length)
1501 int length;
1502 {
1503 if (the_printed_command == 0)
1504 {
1505 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1506 the_printed_command = (char *)xmalloc (the_printed_command_size);
1507 command_string_index = 0;
1508 }
1509 else if ((command_string_index + length) >= the_printed_command_size)
1510 {
1511 int new;
1512 new = command_string_index + length + 1;
1513
1514 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1515 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1516 the_printed_command_size = new;
1517
1518 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
1519 }
1520 }
1521
1522 #if defined (HAVE_VPRINTF)
1523 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1524 also available.'' */
1525
1526 static void
1527 #if defined (PREFER_STDARG)
1528 xprintf (const char *format, ...)
1529 #else
1530 xprintf (format, va_alist)
1531 const char *format;
1532 va_dcl
1533 #endif
1534 {
1535 va_list args;
1536
1537 SH_VA_START (args, format);
1538
1539 vfprintf (stdout, format, args);
1540 va_end (args);
1541 }
1542
1543 #else
1544
1545 static void
1546 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1547 const char *format;
1548 {
1549 printf (format, arg1, arg2, arg3, arg4, arg5);
1550 }
1551
1552 #endif /* !HAVE_VPRINTF */