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