blob: 9429472eff691ba24cd7bcd8a3babf44cf377aae [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* print_command -- A way to make readable commands from a command tree. */
2/* Copyright (C) 1989 Free Software Foundation, Inc.
3
4This file is part of GNU Bash, the Bourne Again SHell.
5
6Bash is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
Jari Aaltobb706242000-03-17 21:46:59 +00008Software Foundation; either version 2, or (at your option) any later
Jari Aalto726f6381996-08-26 18:22:31 +00009version.
10
11Bash is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License along
17with Bash; see the file COPYING. If not, write to the Free Software
Jari Aaltobb706242000-03-17 21:46:59 +000018Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
Jari Aalto726f6381996-08-26 18:22:31 +000019
Jari Aaltoccc6cda1996-12-23 17:02:34 +000020#include "config.h"
21
Jari Aalto726f6381996-08-26 18:22:31 +000022#include <stdio.h>
23
Jari Aaltoccc6cda1996-12-23 17:02:34 +000024#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000025# ifdef _MINIX
26# include <sys/types.h>
27# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000028# include <unistd.h>
Jari Aalto726f6381996-08-26 18:22:31 +000029#endif
30
Jari Aaltoccc6cda1996-12-23 17:02:34 +000031#if defined (PREFER_STDARG)
32# include <stdarg.h>
33#else
Jari Aalto7117c2d2002-07-17 14:10:11 +000034# include <varargs.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000035#endif
36
37#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000038
39#include "shell.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000040#include "flags.h"
Jari Aaltod166f041997-06-05 14:59:13 +000041#include <y.tab.h> /* use <...> so we pick it up from the build directory */
Jari Aalto726f6381996-08-26 18:22:31 +000042#include "builtins/common.h"
43
Jari Aaltof73dda02001-11-13 17:56:06 +000044#if !HAVE_DECL_PRINTF
Jari Aalto726f6381996-08-26 18:22:31 +000045extern int printf __P((const char *, ...)); /* Yuck. Double yuck. */
46#endif
47
Jari Aalto7117c2d2002-07-17 14:10:11 +000048extern int indirection_level;
49
Jari Aaltoccc6cda1996-12-23 17:02:34 +000050static int indentation;
Jari Aalto726f6381996-08-26 18:22:31 +000051static int indentation_amount = 4;
52
Jari Aaltod166f041997-06-05 14:59:13 +000053#if defined (PREFER_STDARG)
Jari Aaltof73dda02001-11-13 17:56:06 +000054typedef void PFUNC __P((const char *, ...));
55
56static void cprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
57static void xprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
Jari Aaltod166f041997-06-05 14:59:13 +000058#else
Jari Aaltof73dda02001-11-13 17:56:06 +000059#define PFUNC VFunction
Jari Aaltod166f041997-06-05 14:59:13 +000060static void cprintf ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +000061static void xprintf ();
Jari Aalto726f6381996-08-26 18:22:31 +000062#endif
Jari Aaltof73dda02001-11-13 17:56:06 +000063
64static void reset_locals __P((void));
65static void newline __P((char *));
66static void indent __P((int));
67static void semicolon __P((void));
68static void the_printed_command_resize __P((int));
69
70static void make_command_string_internal __P((COMMAND *));
71static void _print_word_list __P((WORD_LIST *, char *, PFUNC *));
72static void command_print_word_list __P((WORD_LIST *, char *));
73static void print_case_clauses __P((PATTERN_LIST *));
74static void print_redirection_list __P((REDIRECT *));
75static void print_redirection __P((REDIRECT *));
76
77static void print_for_command __P((FOR_COM *));
78#if defined (ARITH_FOR_COMMAND)
79static void print_arith_for_command __P((ARITH_FOR_COM *));
80#endif
81#if defined (SELECT_COMMAND)
82static void print_select_command __P((SELECT_COM *));
83#endif
84static void print_group_command __P((GROUP_COM *));
85static void print_case_command __P((CASE_COM *));
86static void print_while_command __P((WHILE_COM *));
87static void print_until_command __P((WHILE_COM *));
88static void print_until_or_while __P((WHILE_COM *, char *));
89static void print_if_command __P((IF_COM *));
Jari Aaltocce855b1998-04-17 19:52:44 +000090#if defined (DPAREN_ARITHMETIC)
Jari Aaltof73dda02001-11-13 17:56:06 +000091static void print_arith_command __P((ARITH_COM *));
Jari Aaltocce855b1998-04-17 19:52:44 +000092#endif
93#if defined (COND_COMMAND)
Jari Aaltof73dda02001-11-13 17:56:06 +000094static void print_cond_node __P((COND_COM *));
95static void print_cond_command __P((COND_COM *));
Jari Aaltocce855b1998-04-17 19:52:44 +000096#endif
Jari Aaltof73dda02001-11-13 17:56:06 +000097static void print_function_def __P((FUNCTION_DEF *));
Jari Aalto726f6381996-08-26 18:22:31 +000098
Jari Aaltod166f041997-06-05 14:59:13 +000099#define PRINTED_COMMAND_INITIAL_SIZE 64
100#define PRINTED_COMMAND_GROW_SIZE 128
Jari Aalto726f6381996-08-26 18:22:31 +0000101
102char *the_printed_command = (char *)NULL;
103int the_printed_command_size = 0;
104int command_string_index = 0;
105
106/* Non-zero means the stuff being printed is inside of a function def. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000107static int inside_function_def;
108static int skip_this_indent;
Jari Aaltod166f041997-06-05 14:59:13 +0000109static int was_heredoc;
Jari Aalto726f6381996-08-26 18:22:31 +0000110
111/* The depth of the group commands that we are currently printing. This
112 includes the group command that is a function body. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000113static int group_command_nesting;
Jari Aalto726f6381996-08-26 18:22:31 +0000114
Jari Aalto7117c2d2002-07-17 14:10:11 +0000115/* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
116static char indirection_string[100];
117
Jari Aalto726f6381996-08-26 18:22:31 +0000118/* Print COMMAND (a command tree) on standard output. */
119void
120print_command (command)
121 COMMAND *command;
122{
123 command_string_index = 0;
124 printf ("%s", make_command_string (command));
125}
126
127/* Make a string which is the printed representation of the command
128 tree in COMMAND. We return this string. However, the string is
129 not consed, so you have to do that yourself if you want it to
130 remain around. */
131char *
132make_command_string (command)
133 COMMAND *command;
134{
Jari Aaltod166f041997-06-05 14:59:13 +0000135 command_string_index = was_heredoc = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000136 make_command_string_internal (command);
137 return (the_printed_command);
138}
139
140/* The internal function. This is the real workhorse. */
141static void
142make_command_string_internal (command)
143 COMMAND *command;
144{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000145 if (command == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000146 cprintf ("");
147 else
148 {
149 if (skip_this_indent)
150 skip_this_indent--;
151 else
152 indent (indentation);
153
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000154 if (command->flags & CMD_TIME_PIPELINE)
Jari Aaltod166f041997-06-05 14:59:13 +0000155 {
156 cprintf ("time ");
157 if (command->flags & CMD_TIME_POSIX)
158 cprintf ("-p ");
159 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000160
Jari Aalto726f6381996-08-26 18:22:31 +0000161 if (command->flags & CMD_INVERT_RETURN)
162 cprintf ("! ");
163
164 switch (command->type)
165 {
166 case cm_for:
167 print_for_command (command->value.For);
168 break;
169
Jari Aaltobb706242000-03-17 21:46:59 +0000170#if defined (ARITH_FOR_COMMAND)
171 case cm_arith_for:
172 print_arith_for_command (command->value.ArithFor);
173 break;
174#endif
175
Jari Aalto726f6381996-08-26 18:22:31 +0000176#if defined (SELECT_COMMAND)
177 case cm_select:
178 print_select_command (command->value.Select);
179 break;
180#endif
181
182 case cm_case:
183 print_case_command (command->value.Case);
184 break;
185
186 case cm_while:
187 print_while_command (command->value.While);
188 break;
189
190 case cm_until:
191 print_until_command (command->value.While);
192 break;
193
194 case cm_if:
195 print_if_command (command->value.If);
196 break;
197
Jari Aaltocce855b1998-04-17 19:52:44 +0000198#if defined (DPAREN_ARITHMETIC)
199 case cm_arith:
200 print_arith_command (command->value.Arith);
201 break;
202#endif
203
204#if defined (COND_COMMAND)
205 case cm_cond:
206 print_cond_command (command->value.Cond);
207 break;
208#endif
209
Jari Aalto726f6381996-08-26 18:22:31 +0000210 case cm_simple:
211 print_simple_command (command->value.Simple);
212 break;
213
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000214 case cm_connection:
Jari Aalto726f6381996-08-26 18:22:31 +0000215
216 skip_this_indent++;
217 make_command_string_internal (command->value.Connection->first);
218
219 switch (command->value.Connection->connector)
220 {
221 case '&':
222 case '|':
223 {
224 char c = command->value.Connection->connector;
225 cprintf (" %c", c);
226 if (c != '&' || command->value.Connection->second)
227 {
228 cprintf (" ");
229 skip_this_indent++;
230 }
231 }
232 break;
233
234 case AND_AND:
235 cprintf (" && ");
236 if (command->value.Connection->second)
237 skip_this_indent++;
238 break;
239
240 case OR_OR:
241 cprintf (" || ");
242 if (command->value.Connection->second)
243 skip_this_indent++;
244 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000245
Jari Aalto726f6381996-08-26 18:22:31 +0000246 case ';':
Jari Aaltod166f041997-06-05 14:59:13 +0000247 if (was_heredoc == 0)
248 cprintf (";");
249 else
250 was_heredoc = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000251
252 if (inside_function_def)
253 cprintf ("\n");
254 else
255 {
256 cprintf (" ");
257 if (command->value.Connection->second)
258 skip_this_indent++;
259 }
260 break;
261
262 default:
263 cprintf ("print_command: bad connector `%d'",
264 command->value.Connection->connector);
265 break;
266 }
267
268 make_command_string_internal (command->value.Connection->second);
269 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000270
Jari Aalto726f6381996-08-26 18:22:31 +0000271 case cm_function_def:
272 print_function_def (command->value.Function_def);
273 break;
274
275 case cm_group:
276 print_group_command (command->value.Group);
277 break;
278
Jari Aaltobb706242000-03-17 21:46:59 +0000279 case cm_subshell:
280 cprintf ("( ");
281 skip_this_indent++;
282 make_command_string_internal (command->value.Subshell->command);
283 cprintf (" )");
284 break;
285
Jari Aalto726f6381996-08-26 18:22:31 +0000286 default:
Jari Aaltob72432f1999-02-19 17:11:39 +0000287 command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000288 break;
289 }
290
Jari Aalto726f6381996-08-26 18:22:31 +0000291
292 if (command->redirects)
Jari Aaltob72432f1999-02-19 17:11:39 +0000293 {
294 cprintf (" ");
295 print_redirection_list (command->redirects);
296 }
Jari Aalto726f6381996-08-26 18:22:31 +0000297 }
298}
299
300static void
301_print_word_list (list, separator, pfunc)
302 WORD_LIST *list;
303 char *separator;
Jari Aaltof73dda02001-11-13 17:56:06 +0000304 PFUNC *pfunc;
Jari Aalto726f6381996-08-26 18:22:31 +0000305{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000306 WORD_LIST *w;
307
308 for (w = list; w; w = w->next)
309 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
Jari Aalto726f6381996-08-26 18:22:31 +0000310}
311
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000312void
313print_word_list (list, separator)
Jari Aalto726f6381996-08-26 18:22:31 +0000314 WORD_LIST *list;
315 char *separator;
316{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000317 _print_word_list (list, separator, xprintf);
318}
319
Jari Aalto7117c2d2002-07-17 14:10:11 +0000320/* Return a string denoting what our indirection level is. */
321
322char *
323indirection_level_string ()
324{
325 register int i, j;
326 char *ps4;
327
328 indirection_string[0] = '\0';
329 ps4 = get_string_value ("PS4");
330
331 if (ps4 == 0 || *ps4 == '\0')
332 return (indirection_string);
333
334 change_flag ('x', FLAG_OFF);
335 ps4 = decode_prompt_string (ps4);
336 change_flag ('x', FLAG_ON);
337
338 for (i = 0; *ps4 && i < indirection_level && i < 99; i++)
339 indirection_string[i] = *ps4;
340
341 for (j = 1; *ps4 && ps4[j] && i < 99; i++, j++)
342 indirection_string[i] = ps4[j];
343
344 indirection_string[i] = '\0';
345 free (ps4);
346 return (indirection_string);
347}
348
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000349/* A function to print the words of a simple command when set -x is on. */
350void
351xtrace_print_word_list (list)
352 WORD_LIST *list;
353{
354 WORD_LIST *w;
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000355 char *t, *x;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000356
357 fprintf (stderr, "%s", indirection_level_string ());
358 for (w = list; w; w = w->next)
359 {
360 t = w->word->word;
361 if (t == 0 || *t == '\0')
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000362 fprintf (stderr, "''%s", w->next ? " " : "");
Jari Aalto28ef6c32001-04-06 19:14:31 +0000363 else if (sh_contains_shell_metas (t))
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000364 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000365 x = sh_single_quote (t);
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000366 fprintf (stderr, "%s%s", x, w->next ? " " : "");
367 free (x);
368 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000369 else if (ansic_shouldquote (t))
370 {
371 x = ansic_quote (t, 0, (int *)0);
372 fprintf (stderr, "%s%s", x, w->next ? " " : "");
373 free (x);
374 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000375 else
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000376 fprintf (stderr, "%s%s", t, w->next ? " " : "");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000377 }
378 fprintf (stderr, "\n");
Jari Aalto726f6381996-08-26 18:22:31 +0000379}
380
381static void
382command_print_word_list (list, separator)
383 WORD_LIST *list;
384 char *separator;
385{
386 _print_word_list (list, separator, cprintf);
387}
388
389static void
390print_for_command (for_command)
391 FOR_COM *for_command;
392{
393 cprintf ("for %s in ", for_command->name->word);
394 command_print_word_list (for_command->map_list, " ");
395 cprintf (";");
396 newline ("do\n");
397 indentation += indentation_amount;
398 make_command_string_internal (for_command->action);
399 semicolon ();
400 indentation -= indentation_amount;
401 newline ("done");
402}
403
Jari Aaltobb706242000-03-17 21:46:59 +0000404#if defined (ARITH_FOR_COMMAND)
405static void
406print_arith_for_command (arith_for_command)
407 ARITH_FOR_COM *arith_for_command;
408{
409 cprintf ("for (( ");
410 command_print_word_list (arith_for_command->init, " ");
411 cprintf (" ; ");
412 command_print_word_list (arith_for_command->test, " ");
413 cprintf (" ; ");
414 command_print_word_list (arith_for_command->step, " ");
415 cprintf (" ))");
416 newline ("do\n");
417 indentation += indentation_amount;
418 make_command_string_internal (arith_for_command->action);
419 semicolon ();
420 indentation -= indentation_amount;
421 newline ("done");
422}
423#endif /* ARITH_FOR_COMMAND */
424
Jari Aalto726f6381996-08-26 18:22:31 +0000425#if defined (SELECT_COMMAND)
426static void
427print_select_command (select_command)
428 SELECT_COM *select_command;
429{
430 cprintf ("select %s in ", select_command->name->word);
431 command_print_word_list (select_command->map_list, " ");
432 cprintf (";");
433 newline ("do\n");
434 indentation += indentation_amount;
435 make_command_string_internal (select_command->action);
436 semicolon ();
437 indentation -= indentation_amount;
438 newline ("done");
439}
440#endif /* SELECT_COMMAND */
441
442static void
443print_group_command (group_command)
444 GROUP_COM *group_command;
445{
446 group_command_nesting++;
447 cprintf ("{ ");
448
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000449 if (inside_function_def == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000450 skip_this_indent++;
451 else
452 {
453 /* This is a group command { ... } inside of a function
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000454 definition, and should be printed as a multiline group
Jari Aalto726f6381996-08-26 18:22:31 +0000455 command, using the current indentation. */
456 cprintf ("\n");
457 indentation += indentation_amount;
458 }
459
460 make_command_string_internal (group_command->command);
461
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000462 if (inside_function_def)
Jari Aalto726f6381996-08-26 18:22:31 +0000463 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000464 cprintf ("\n");
Jari Aalto726f6381996-08-26 18:22:31 +0000465 indentation -= indentation_amount;
466 indent (indentation);
Jari Aalto726f6381996-08-26 18:22:31 +0000467 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000468 else
469 {
470 semicolon ();
471 cprintf (" ");
472 }
473
Jari Aalto726f6381996-08-26 18:22:31 +0000474 cprintf ("}");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000475
Jari Aalto726f6381996-08-26 18:22:31 +0000476 group_command_nesting--;
477}
478
479static void
480print_case_command (case_command)
481 CASE_COM *case_command;
482{
483 cprintf ("case %s in ", case_command->word->word);
484 if (case_command->clauses)
485 print_case_clauses (case_command->clauses);
486 newline ("esac");
487}
488
489static void
490print_case_clauses (clauses)
491 PATTERN_LIST *clauses;
492{
493 indentation += indentation_amount;
494 while (clauses)
495 {
496 newline ("");
497 command_print_word_list (clauses->patterns, " | ");
498 cprintf (")\n");
499 indentation += indentation_amount;
500 make_command_string_internal (clauses->action);
501 indentation -= indentation_amount;
502 newline (";;");
503 clauses = clauses->next;
504 }
505 indentation -= indentation_amount;
506}
507
508static void
509print_while_command (while_command)
510 WHILE_COM *while_command;
511{
512 print_until_or_while (while_command, "while");
513}
514
515static void
516print_until_command (while_command)
517 WHILE_COM *while_command;
518{
519 print_until_or_while (while_command, "until");
520}
521
522static void
523print_until_or_while (while_command, which)
524 WHILE_COM *while_command;
525 char *which;
526{
527 cprintf ("%s ", which);
528 skip_this_indent++;
529 make_command_string_internal (while_command->test);
530 semicolon ();
531 cprintf (" do\n"); /* was newline ("do\n"); */
532 indentation += indentation_amount;
533 make_command_string_internal (while_command->action);
534 indentation -= indentation_amount;
535 semicolon ();
536 newline ("done");
537}
538
539static void
540print_if_command (if_command)
541 IF_COM *if_command;
542{
543 cprintf ("if ");
544 skip_this_indent++;
545 make_command_string_internal (if_command->test);
546 semicolon ();
547 cprintf (" then\n");
548 indentation += indentation_amount;
549 make_command_string_internal (if_command->true_case);
550 indentation -= indentation_amount;
551
552 if (if_command->false_case)
553 {
554 semicolon ();
555 newline ("else\n");
556 indentation += indentation_amount;
557 make_command_string_internal (if_command->false_case);
558 indentation -= indentation_amount;
559 }
560 semicolon ();
561 newline ("fi");
562}
563
Jari Aaltocce855b1998-04-17 19:52:44 +0000564#if defined (DPAREN_ARITHMETIC)
565static void
566print_arith_command (arith_command)
567 ARITH_COM *arith_command;
568{
569 cprintf ("(( ");
570 command_print_word_list (arith_command->exp, " ");
571 cprintf (" ))");
572}
Jari Aaltobb706242000-03-17 21:46:59 +0000573#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000574
575#if defined (COND_COMMAND)
576static void
577print_cond_node (cond)
578 COND_COM *cond;
579{
580 if (cond->flags & CMD_INVERT_RETURN)
581 cprintf ("! ");
582
583 if (cond->type == COND_EXPR)
584 {
585 cprintf ("( ");
586 print_cond_node (cond->left);
587 cprintf (" )");
588 }
589 else if (cond->type == COND_AND)
590 {
591 print_cond_node (cond->left);
592 cprintf (" && ");
593 print_cond_node (cond->right);
594 }
595 else if (cond->type == COND_OR)
596 {
597 print_cond_node (cond->left);
598 cprintf (" || ");
599 print_cond_node (cond->right);
600 }
601 else if (cond->type == COND_UNARY)
602 {
Jari Aaltob72432f1999-02-19 17:11:39 +0000603 cprintf ("%s", cond->op->word);
Jari Aaltocce855b1998-04-17 19:52:44 +0000604 cprintf (" ");
605 print_cond_node (cond->left);
606 }
607 else if (cond->type == COND_BINARY)
608 {
609 print_cond_node (cond->left);
610 cprintf (" ");
Jari Aaltob72432f1999-02-19 17:11:39 +0000611 cprintf ("%s", cond->op->word);
Jari Aaltocce855b1998-04-17 19:52:44 +0000612 cprintf (" ");
613 print_cond_node (cond->right);
614 }
615 else if (cond->type == COND_TERM)
616 {
Jari Aaltob72432f1999-02-19 17:11:39 +0000617 cprintf ("%s", cond->op->word); /* need to add quoting here */
Jari Aaltocce855b1998-04-17 19:52:44 +0000618 }
619}
620
621static void
622print_cond_command (cond)
623 COND_COM *cond;
624{
625 cprintf ("[[ ");
626 print_cond_node (cond);
627 cprintf (" ]]");
628}
629
Jari Aalto28ef6c32001-04-06 19:14:31 +0000630#ifdef DEBUG
Jari Aaltocce855b1998-04-17 19:52:44 +0000631void
632debug_print_cond_command (cond)
633 COND_COM *cond;
634{
635 fprintf (stderr, "DEBUG: ");
636 command_string_index = 0;
637 print_cond_command (cond);
638 fprintf (stderr, "%s\n", the_printed_command);
639}
Jari Aalto28ef6c32001-04-06 19:14:31 +0000640#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000641
642void
643xtrace_print_cond_term (type, invert, op, arg1, arg2)
644 int type, invert;
645 WORD_DESC *op;
646 char *arg1, *arg2;
647{
648 command_string_index = 0;
649 fprintf (stderr, "%s", indirection_level_string ());
650 fprintf (stderr, "[[ ");
651 if (invert)
652 fprintf (stderr, "! ");
653
654 if (type == COND_UNARY)
655 {
656 fprintf (stderr, "%s ", op->word);
657 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
658 }
659 else if (type == COND_BINARY)
660 {
661 fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
662 fprintf (stderr, " %s ", op->word);
663 fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
664 }
665
666 fprintf (stderr, " ]]\n");
667}
668#endif /* COND_COMMAND */
669
Jari Aaltobb706242000-03-17 21:46:59 +0000670#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
Jari Aaltocce855b1998-04-17 19:52:44 +0000671/* A function to print the words of an arithmetic command when set -x is on. */
672void
673xtrace_print_arith_cmd (list)
674 WORD_LIST *list;
675{
676 WORD_LIST *w;
677
678 fprintf (stderr, "%s", indirection_level_string ());
679 fprintf (stderr, "(( ");
680 for (w = list; w; w = w->next)
681 fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
682 fprintf (stderr, " ))\n");
683}
684#endif
685
Jari Aalto726f6381996-08-26 18:22:31 +0000686void
687print_simple_command (simple_command)
688 SIMPLE_COM *simple_command;
689{
690 command_print_word_list (simple_command->words, " ");
691
692 if (simple_command->redirects)
693 {
694 cprintf (" ");
695 print_redirection_list (simple_command->redirects);
696 }
697}
698
699static void
700print_redirection_list (redirects)
701 REDIRECT *redirects;
702{
Jari Aaltod166f041997-06-05 14:59:13 +0000703 REDIRECT *heredocs, *hdtail, *newredir;
704
705 heredocs = (REDIRECT *)NULL;
706 hdtail = heredocs;
707
708 was_heredoc = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000709 while (redirects)
710 {
Jari Aaltod166f041997-06-05 14:59:13 +0000711 /* Defer printing the here documents until we've printed the
712 rest of the redirections. */
713 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
714 {
715 newredir = copy_redirect (redirects);
716 newredir->next = (REDIRECT *)NULL;
717 if (heredocs)
718 {
719 hdtail->next = newredir;
720 hdtail = newredir;
721 }
722 else
723 hdtail = heredocs = newredir;
724 }
725 else
726 print_redirection (redirects);
727
Jari Aalto726f6381996-08-26 18:22:31 +0000728 redirects = redirects->next;
729 if (redirects)
730 cprintf (" ");
731 }
Jari Aaltod166f041997-06-05 14:59:13 +0000732
733 /* Now that we've printed all the other redirections (on one line),
734 print the here documents. */
735 if (heredocs)
736 {
737 cprintf (" ");
738 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000739 {
Jari Aaltod166f041997-06-05 14:59:13 +0000740 print_redirection (hdtail);
741 cprintf ("\n");
Jari Aalto28ef6c32001-04-06 19:14:31 +0000742 }
Jari Aaltod166f041997-06-05 14:59:13 +0000743 dispose_redirects (heredocs);
744 was_heredoc = 1;
745 }
Jari Aalto726f6381996-08-26 18:22:31 +0000746}
747
748static void
749print_redirection (redirect)
750 REDIRECT *redirect;
751{
Jari Aaltod166f041997-06-05 14:59:13 +0000752 int kill_leading, redirector, redir_fd;
753 WORD_DESC *redirectee;
754
755 kill_leading = 0;
756 redirectee = redirect->redirectee.filename;
757 redirector = redirect->redirector;
758 redir_fd = redirect->redirectee.dest;
Jari Aalto726f6381996-08-26 18:22:31 +0000759
760 switch (redirect->instruction)
761 {
762 case r_output_direction:
763 if (redirector != 1)
764 cprintf ("%d", redirector);
765 cprintf (">%s", redirectee->word);
766 break;
767
768 case r_input_direction:
769 if (redirector != 0)
770 cprintf ("%d", redirector);
771 cprintf ("<%s", redirectee->word);
772 break;
773
774 case r_inputa_direction: /* Redirection created by the shell. */
775 cprintf ("&");
776 break;
777
778 case r_appending_to:
779 if (redirector != 1)
780 cprintf ("%d", redirector);
781 cprintf (">>%s", redirectee->word);
782 break;
783
784 case r_deblank_reading_until:
785 kill_leading++;
786 /* ... */
787 case r_reading_until:
788 if (redirector != 0)
789 cprintf ("%d", redirector);
790 /* If the here document delimiter is quoted, single-quote it. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000791 if (redirect->redirectee.filename->flags & W_QUOTED)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000792 {
793 char *x;
794 x = sh_single_quote (redirect->here_doc_eof);
Jari Aalto726f6381996-08-26 18:22:31 +0000795 cprintf ("<<%s%s\n", kill_leading? "-" : "", x);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000796 free (x);
797 }
Jari Aalto726f6381996-08-26 18:22:31 +0000798 else
799 cprintf ("<<%s%s\n", kill_leading? "-" : "", redirect->here_doc_eof);
800 cprintf ("%s%s",
801 redirect->redirectee.filename->word, redirect->here_doc_eof);
802 break;
803
Jari Aalto7117c2d2002-07-17 14:10:11 +0000804 case r_reading_string:
805 if (redirector != 0)
806 cprintf ("%d", redirector);
807 if (ansic_shouldquote (redirect->redirectee.filename->word))
808 {
809 char *x;
810 x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
811 cprintf ("<<< %s", x);
812 free (x);
813 }
814 else
815 cprintf ("<<< %s", redirect->redirectee.filename->word);
816 break;
817
Jari Aalto726f6381996-08-26 18:22:31 +0000818 case r_duplicating_input:
819 cprintf ("%d<&%d", redirector, redir_fd);
820 break;
821
822 case r_duplicating_output:
823 cprintf ("%d>&%d", redirector, redir_fd);
824 break;
825
826 case r_duplicating_input_word:
827 cprintf ("%d<&%s", redirector, redirectee->word);
828 break;
829
830 case r_duplicating_output_word:
831 cprintf ("%d>&%s", redirector, redirectee->word);
832 break;
833
Jari Aalto7117c2d2002-07-17 14:10:11 +0000834 case r_move_input:
835 cprintf ("%d<&%d-", redirector, redir_fd);
836 break;
837
838 case r_move_output:
839 cprintf ("%d>&%d-", redirector, redir_fd);
840 break;
841
842 case r_move_input_word:
843 cprintf ("%d<&%s-", redirector, redirectee->word);
844 break;
845
846 case r_move_output_word:
847 cprintf ("%d>&%s-", redirector, redirectee->word);
848 break;
849
Jari Aalto726f6381996-08-26 18:22:31 +0000850 case r_close_this:
851 cprintf ("%d>&-", redirector);
852 break;
853
854 case r_err_and_out:
855 cprintf (">&%s", redirectee->word);
856 break;
857
858 case r_input_output:
859 if (redirector != 1)
860 cprintf ("%d", redirector);
861 cprintf ("<>%s", redirectee->word);
862 break;
863
864 case r_output_force:
865 if (redirector != 1)
866 cprintf ("%d", redirector);
867 cprintf (">|%s", redirectee->word);
868 break;
869 }
870}
871
872static void
873reset_locals ()
874{
875 inside_function_def = 0;
876 indentation = 0;
877}
878
879static void
880print_function_def (func)
881 FUNCTION_DEF *func;
882{
Jari Aaltobb706242000-03-17 21:46:59 +0000883 COMMAND *cmdcopy;
884 REDIRECT *func_redirects;
885
Jari Aaltof73dda02001-11-13 17:56:06 +0000886 func_redirects = NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000887 cprintf ("function %s () \n", func->name->word);
888 add_unwind_protect (reset_locals, 0);
889
890 indent (indentation);
891 cprintf ("{ \n");
892
893 inside_function_def++;
894 indentation += indentation_amount;
895
Jari Aaltobb706242000-03-17 21:46:59 +0000896 cmdcopy = copy_command (func->command);
897 if (cmdcopy->type == cm_group)
898 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000899 func_redirects = cmdcopy->redirects;
900 cmdcopy->redirects = (REDIRECT *)NULL;
Jari Aaltobb706242000-03-17 21:46:59 +0000901 }
902 make_command_string_internal (cmdcopy->type == cm_group
903 ? cmdcopy->value.Group->command
904 : cmdcopy);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000905
Jari Aalto726f6381996-08-26 18:22:31 +0000906 remove_unwind_protect ();
907 indentation -= indentation_amount;
908 inside_function_def--;
909
Jari Aaltobb706242000-03-17 21:46:59 +0000910 if (func_redirects)
911 { /* { */
912 newline ("} ");
913 print_redirection_list (func_redirects);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000914 cmdcopy->redirects = func_redirects;
Jari Aaltobb706242000-03-17 21:46:59 +0000915 }
916 else
917 newline ("}");
918
919 dispose_command (cmdcopy);
Jari Aalto726f6381996-08-26 18:22:31 +0000920}
921
922/* Return the string representation of the named function.
923 NAME is the name of the function.
924 COMMAND is the function body. It should be a GROUP_COM.
925 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
926 */
927char *
928named_function_string (name, command, multi_line)
929 char *name;
930 COMMAND *command;
931 int multi_line;
932{
933 char *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000934 int old_indent, old_amount;
Jari Aaltobb706242000-03-17 21:46:59 +0000935 COMMAND *cmdcopy;
936 REDIRECT *func_redirects;
Jari Aalto726f6381996-08-26 18:22:31 +0000937
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000938 old_indent = indentation;
939 old_amount = indentation_amount;
Jari Aaltod166f041997-06-05 14:59:13 +0000940 command_string_index = was_heredoc = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000941
942 if (name && *name)
943 cprintf ("%s ", name);
944
945 cprintf ("() ");
946
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000947 if (multi_line == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000948 {
949 indentation = 1;
950 indentation_amount = 0;
951 }
952 else
953 {
954 cprintf ("\n");
955 indentation += indentation_amount;
956 }
957
958 inside_function_def++;
959
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000960 cprintf (multi_line ? "{ \n" : "{ ");
Jari Aalto726f6381996-08-26 18:22:31 +0000961
Jari Aaltobb706242000-03-17 21:46:59 +0000962 cmdcopy = copy_command (command);
963 /* Take any redirections specified in the function definition (which should
964 apply to the function as a whole) and save them for printing later. */
965 func_redirects = (REDIRECT *)NULL;
966 if (cmdcopy->type == cm_group)
967 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000968 func_redirects = cmdcopy->redirects;
969 cmdcopy->redirects = (REDIRECT *)NULL;
Jari Aaltobb706242000-03-17 21:46:59 +0000970 }
971 make_command_string_internal (cmdcopy->type == cm_group
972 ? cmdcopy->value.Group->command
973 : cmdcopy);
Jari Aalto726f6381996-08-26 18:22:31 +0000974
975 indentation = old_indent;
976 indentation_amount = old_amount;
977 inside_function_def--;
978
Jari Aaltobb706242000-03-17 21:46:59 +0000979 if (func_redirects)
980 { /* { */
981 newline ("} ");
982 print_redirection_list (func_redirects);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000983 cmdcopy->redirects = func_redirects;
Jari Aaltobb706242000-03-17 21:46:59 +0000984 }
985 else
986 newline ("}");
Jari Aalto726f6381996-08-26 18:22:31 +0000987
988 result = the_printed_command;
989
990 if (!multi_line)
991 {
992#if 0
993 register int i;
994 for (i = 0; result[i]; i++)
995 if (result[i] == '\n')
996 {
997 strcpy (result + i, result + i + 1);
998 --i;
999 }
1000#else
1001 if (result[2] == '\n') /* XXX -- experimental */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001002 strcpy (result + 2, result + 3);
Jari Aalto726f6381996-08-26 18:22:31 +00001003#endif
1004 }
1005
Jari Aaltobb706242000-03-17 21:46:59 +00001006 dispose_command (cmdcopy);
1007
Jari Aalto726f6381996-08-26 18:22:31 +00001008 return (result);
1009}
1010
1011static void
1012newline (string)
1013 char *string;
1014{
1015 cprintf ("\n");
1016 indent (indentation);
1017 if (string && *string)
1018 cprintf ("%s", string);
1019}
1020
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001021static char *indentation_string;
1022static int indentation_size;
1023
Jari Aalto726f6381996-08-26 18:22:31 +00001024static void
1025indent (amount)
1026 int amount;
1027{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001028 register int i;
1029
1030 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
1031
1032 for (i = 0; amount > 0; amount--)
1033 indentation_string[i++] = ' ';
1034 indentation_string[i] = '\0';
1035 cprintf (indentation_string);
Jari Aalto726f6381996-08-26 18:22:31 +00001036}
1037
1038static void
1039semicolon ()
1040{
Jari Aalto7117c2d2002-07-17 14:10:11 +00001041 if (command_string_index > 0 &&
1042 (the_printed_command[command_string_index - 1] == '&' ||
1043 the_printed_command[command_string_index - 1] == '\n'))
Jari Aalto726f6381996-08-26 18:22:31 +00001044 return;
1045 cprintf (";");
1046}
1047
Jari Aalto726f6381996-08-26 18:22:31 +00001048/* How to make the string. */
1049static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001050#if defined (PREFER_STDARG)
Jari Aaltof73dda02001-11-13 17:56:06 +00001051cprintf (const char *control, ...)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001052#else
1053cprintf (control, va_alist)
Jari Aaltof73dda02001-11-13 17:56:06 +00001054 const char *control;
Jari Aalto726f6381996-08-26 18:22:31 +00001055 va_dcl
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001056#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001057{
Jari Aaltof73dda02001-11-13 17:56:06 +00001058 register const char *s;
1059 char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
Jari Aalto726f6381996-08-26 18:22:31 +00001060 int digit_arg, arg_len, c;
1061 va_list args;
1062
Jari Aalto7117c2d2002-07-17 14:10:11 +00001063 SH_VA_START (args, control);
Jari Aalto726f6381996-08-26 18:22:31 +00001064
1065 arg_len = strlen (control);
1066 the_printed_command_resize (arg_len + 1);
1067
1068 char_arg[1] = '\0';
1069 s = control;
1070 while (s && *s)
1071 {
Jari Aalto726f6381996-08-26 18:22:31 +00001072 c = *s++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001073 argp = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001074 if (c != '%' || !*s)
1075 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001076 char_arg[0] = c;
1077 argp = char_arg;
Jari Aalto726f6381996-08-26 18:22:31 +00001078 arg_len = 1;
1079 }
1080 else
1081 {
1082 c = *s++;
1083 switch (c)
1084 {
1085 case '%':
1086 char_arg[0] = c;
1087 argp = char_arg;
1088 arg_len = 1;
1089 break;
1090
1091 case 's':
1092 argp = va_arg (args, char *);
1093 arg_len = strlen (argp);
1094 break;
1095
1096 case 'd':
Jari Aaltof73dda02001-11-13 17:56:06 +00001097 /* Represent an out-of-range file descriptor with an out-of-range
1098 integer value. We can do this because the only use of `%d' in
1099 the calls to cprintf is to output a file descriptor number for
1100 a redirection. */
Jari Aalto726f6381996-08-26 18:22:31 +00001101 digit_arg = va_arg (args, int);
Jari Aaltof73dda02001-11-13 17:56:06 +00001102 if (digit_arg < 0)
1103 {
1104 sprintf (intbuf, "%u", (unsigned)-1);
1105 argp = intbuf;
1106 }
1107 else
1108 argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
Jari Aalto726f6381996-08-26 18:22:31 +00001109 arg_len = strlen (argp);
Jari Aalto726f6381996-08-26 18:22:31 +00001110 break;
1111
1112 case 'c':
1113 char_arg[0] = va_arg (args, int);
1114 argp = char_arg;
1115 arg_len = 1;
1116 break;
1117
1118 default:
1119 programming_error ("cprintf: bad `%%' argument (%c)", c);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001120 /*NOTREACHED*/
Jari Aalto726f6381996-08-26 18:22:31 +00001121 }
1122 }
1123
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001124 if (argp && arg_len)
Jari Aalto726f6381996-08-26 18:22:31 +00001125 {
1126 the_printed_command_resize (arg_len + 1);
1127 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1128 command_string_index += arg_len;
Jari Aalto726f6381996-08-26 18:22:31 +00001129 }
1130 }
1131
1132 the_printed_command[command_string_index] = '\0';
1133}
Jari Aalto726f6381996-08-26 18:22:31 +00001134
1135/* Ensure that there is enough space to stuff LENGTH characters into
1136 THE_PRINTED_COMMAND. */
1137static void
1138the_printed_command_resize (length)
1139 int length;
1140{
Jari Aaltod166f041997-06-05 14:59:13 +00001141 if (the_printed_command == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001142 {
Jari Aaltod166f041997-06-05 14:59:13 +00001143 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
Jari Aaltof73dda02001-11-13 17:56:06 +00001144 the_printed_command = (char *)xmalloc (the_printed_command_size);
Jari Aalto726f6381996-08-26 18:22:31 +00001145 command_string_index = 0;
1146 }
1147 else if ((command_string_index + length) >= the_printed_command_size)
1148 {
1149 int new;
1150 new = command_string_index + length + 1;
Jari Aaltobb706242000-03-17 21:46:59 +00001151
Jari Aaltod166f041997-06-05 14:59:13 +00001152 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1153 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
Jari Aalto726f6381996-08-26 18:22:31 +00001154 the_printed_command_size = new;
Jari Aaltobb706242000-03-17 21:46:59 +00001155
Jari Aaltof73dda02001-11-13 17:56:06 +00001156 the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
Jari Aalto726f6381996-08-26 18:22:31 +00001157 }
1158}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001159
Jari Aaltof73dda02001-11-13 17:56:06 +00001160#if defined (HAVE_VPRINTF)
1161/* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1162 also available.'' */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001163
1164static void
Jari Aaltod166f041997-06-05 14:59:13 +00001165#if defined (PREFER_STDARG)
1166xprintf (const char *format, ...)
1167#else
1168xprintf (format, va_alist)
1169 const char *format;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001170 va_dcl
Jari Aaltod166f041997-06-05 14:59:13 +00001171#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001172{
1173 va_list args;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001174
Jari Aalto7117c2d2002-07-17 14:10:11 +00001175 SH_VA_START (args, format);
Jari Aaltod166f041997-06-05 14:59:13 +00001176
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001177 vfprintf (stdout, format, args);
1178 va_end (args);
1179}
1180
1181#else
1182
1183static void
1184xprintf (format, arg1, arg2, arg3, arg4, arg5)
Jari Aaltof73dda02001-11-13 17:56:06 +00001185 const char *format;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001186{
1187 printf (format, arg1, arg2, arg3, arg4, arg5);
1188}
1189
Jari Aaltof73dda02001-11-13 17:56:06 +00001190#endif /* !HAVE_VPRINTF */