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