OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / user / bash / print_cmd.c
1 /* print_command -- A way to make readable commands from a command tree. */
2 /* Copyright (C) 1989 Free Software Foundation, Inc.
3
4 This file is part of GNU Bash, the Bourne Again SHell.
5
6 Bash is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with Bash; see the file COPYING.  If not, write to the Free Software
18 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
19
20 #include "config.h"
21
22 #include <stdio.h>
23
24 #if defined (HAVE_UNISTD_H)
25 #  ifdef _MINIX
26 #    include <sys/types.h>
27 #  endif
28 #  include <unistd.h>
29 #endif
30
31 #if defined (PREFER_STDARG)
32 #  include <stdarg.h>
33 #else
34 #  if defined (PREFER_VARARGS)
35 #    include <varargs.h>
36 #  endif
37 #endif
38
39 #include "bashansi.h"
40
41 #include "shell.h"
42 #include <y.tab.h>      /* use <...> so we pick it up from the build directory */
43 #include "stdc.h"
44 #include "builtins/common.h"
45
46 #if !defined (PRINTF_DECLARED)
47 extern int printf __P((const char *, ...));     /* Yuck.  Double yuck. */
48 #endif
49
50 static int indentation;
51 static int indentation_amount = 4;
52
53 #if defined (PREFER_STDARG)
54 static void cprintf __P((char *, ...));
55 #else
56 static void cprintf ();
57 #endif
58
59 static void newline (), indent (), the_printed_command_resize ();
60 static void semicolon ();
61 static void xprintf ();
62
63 static void make_command_string_internal ();
64 static void command_print_word_list ();
65 static void print_case_clauses ();
66 static void print_redirection_list ();
67 static void print_redirection ();
68
69 static void print_for_command ();
70 #if defined (SELECT_COMMAND)
71 static void print_select_command ();
72 #endif
73 static void print_group_command ();
74 static void print_case_command ();
75 static void print_while_command ();
76 static void print_until_command ();
77 static void print_until_or_while ();
78 static void print_if_command ();
79 static void print_function_def ();
80 #if defined (DPAREN_ARITHMETIC)
81 static void print_arith_command ();
82 #endif
83 #if defined (COND_COMMAND)
84 static void print_cond_node ();
85 static void print_cond_command ();
86 #endif
87 #if defined (ARITH_FOR_COMMAND)
88 static void print_arith_for_command ();
89 #endif
90
91 #define PRINTED_COMMAND_INITIAL_SIZE 64
92 #define PRINTED_COMMAND_GROW_SIZE 128
93
94 char *the_printed_command = (char *)NULL;
95 int the_printed_command_size = 0;
96 int command_string_index = 0;
97
98 /* Non-zero means the stuff being printed is inside of a function def. */
99 static int inside_function_def;
100 static int skip_this_indent;
101 static int was_heredoc;
102
103 /* The depth of the group commands that we are currently printing.  This
104    includes the group command that is a function body. */
105 static int group_command_nesting;
106
107 /* Print COMMAND (a command tree) on standard output. */
108 void
109 print_command (command)
110      COMMAND *command;
111 {
112   command_string_index = 0;
113   printf ("%s", make_command_string (command));
114 }
115
116 /* Make a string which is the printed representation of the command
117    tree in COMMAND.  We return this string.  However, the string is
118    not consed, so you have to do that yourself if you want it to
119    remain around. */
120 char *
121 make_command_string (command)
122      COMMAND *command;
123 {
124   command_string_index = was_heredoc = 0;
125   make_command_string_internal (command);
126   return (the_printed_command);
127 }
128
129 /* The internal function.  This is the real workhorse. */
130 static void
131 make_command_string_internal (command)
132      COMMAND *command;
133 {
134   if (command == 0)
135     cprintf ("");
136   else
137     {
138       if (skip_this_indent)
139         skip_this_indent--;
140       else
141         indent (indentation);
142
143       if (command->flags & CMD_TIME_PIPELINE)
144         {
145           cprintf ("time ");
146           if (command->flags & CMD_TIME_POSIX)
147             cprintf ("-p ");
148         }
149
150       if (command->flags & CMD_INVERT_RETURN)
151         cprintf ("! ");
152
153       switch (command->type)
154         {
155         case cm_for:
156           print_for_command (command->value.For);
157           break;
158
159 #if defined (ARITH_FOR_COMMAND)
160         case cm_arith_for:
161           print_arith_for_command (command->value.ArithFor);
162           break;
163 #endif
164
165 #if defined (SELECT_COMMAND)
166         case cm_select:
167           print_select_command (command->value.Select);
168           break;
169 #endif
170
171         case cm_case:
172           print_case_command (command->value.Case);
173           break;
174
175         case cm_while:
176           print_while_command (command->value.While);
177           break;
178
179         case cm_until:
180           print_until_command (command->value.While);
181           break;
182
183         case cm_if:
184           print_if_command (command->value.If);
185           break;
186
187 #if defined (DPAREN_ARITHMETIC)
188         case cm_arith:
189           print_arith_command (command->value.Arith);
190           break;
191 #endif
192
193 #if defined (COND_COMMAND)
194         case cm_cond:
195           print_cond_command (command->value.Cond);
196           break;
197 #endif
198
199         case cm_simple:
200           print_simple_command (command->value.Simple);
201           break;
202
203         case cm_connection:
204
205           skip_this_indent++;
206           make_command_string_internal (command->value.Connection->first);
207
208           switch (command->value.Connection->connector)
209             {
210             case '&':
211             case '|':
212               {
213                 char c = command->value.Connection->connector;
214                 cprintf (" %c", c);
215                 if (c != '&' || command->value.Connection->second)
216                   {
217                     cprintf (" ");
218                     skip_this_indent++;
219                   }
220               }
221               break;
222
223             case AND_AND:
224               cprintf (" && ");
225               if (command->value.Connection->second)
226                 skip_this_indent++;
227               break;
228
229             case OR_OR:
230               cprintf (" || ");
231               if (command->value.Connection->second)
232                 skip_this_indent++;
233               break;
234
235             case ';':
236               if (was_heredoc == 0)
237                 cprintf (";");
238               else
239                 was_heredoc = 0;
240
241               if (inside_function_def)
242                 cprintf ("\n");
243               else
244                 {
245                   cprintf (" ");
246                   if (command->value.Connection->second)
247                     skip_this_indent++;
248                 }
249               break;
250
251             default:
252               cprintf ("print_command: bad connector `%d'",
253                        command->value.Connection->connector);
254               break;
255             }
256
257           make_command_string_internal (command->value.Connection->second);
258           break;
259
260         case cm_function_def:
261           print_function_def (command->value.Function_def);
262           break;
263
264         case cm_group:
265           print_group_command (command->value.Group);
266           break;
267
268         case cm_subshell:
269           cprintf ("( ");
270           skip_this_indent++;
271           make_command_string_internal (command->value.Subshell->command);
272           cprintf (" )");
273           break;
274
275         default:
276           command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
277           break;
278         }
279
280
281       if (command->redirects)
282         {
283           cprintf (" ");
284           print_redirection_list (command->redirects);
285         }
286     }
287 }
288
289 static void
290 _print_word_list (list, separator, pfunc)
291      WORD_LIST *list;
292      char *separator;
293      VFunction *pfunc;
294 {
295   WORD_LIST *w;
296
297   for (w = list; w; w = w->next)
298     (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
299 }
300
301 void
302 print_word_list (list, separator)
303      WORD_LIST *list;
304      char *separator;
305 {
306   _print_word_list (list, separator, xprintf);
307 }
308
309 /* A function to print the words of a simple command when set -x is on. */
310 void
311 xtrace_print_word_list (list)
312      WORD_LIST *list;
313 {
314   WORD_LIST *w;
315   char *t, *x;
316
317   fprintf (stderr, "%s", indirection_level_string ());
318   for (w = list; w; w = w->next)
319     {
320       t = w->word->word;
321       if (t == 0 || *t == '\0')
322         fprintf (stderr, "''%s", w->next ? " " : "");
323       else if (sh_contains_shell_metas (t))
324         {
325           x = sh_single_quote (t);
326           fprintf (stderr, "%s%s", x, w->next ? " " : "");
327           free (x);
328         }
329       else
330         fprintf (stderr, "%s%s", t, w->next ? " " : "");
331     }
332   fprintf (stderr, "\n");
333 }
334
335 static void
336 command_print_word_list (list, separator)
337      WORD_LIST *list;
338      char *separator;
339 {
340   _print_word_list (list, separator, cprintf);
341 }
342
343 static void
344 print_for_command (for_command)
345      FOR_COM *for_command;
346 {
347   cprintf ("for %s in ", for_command->name->word);
348   command_print_word_list (for_command->map_list, " ");
349   cprintf (";");
350   newline ("do\n");
351   indentation += indentation_amount;
352   make_command_string_internal (for_command->action);
353   semicolon ();
354   indentation -= indentation_amount;
355   newline ("done");
356 }
357
358 #if defined (ARITH_FOR_COMMAND)
359 static void
360 print_arith_for_command (arith_for_command)
361      ARITH_FOR_COM *arith_for_command;
362 {
363   cprintf ("for (( ");
364   command_print_word_list (arith_for_command->init, " ");
365   cprintf (" ; ");
366   command_print_word_list (arith_for_command->test, " ");
367   cprintf (" ; ");
368   command_print_word_list (arith_for_command->step, " ");
369   cprintf (" ))");
370   newline ("do\n");
371   indentation += indentation_amount;
372   make_command_string_internal (arith_for_command->action);
373   semicolon ();
374   indentation -= indentation_amount;
375   newline ("done");
376 }
377 #endif /* ARITH_FOR_COMMAND */
378
379 #if defined (SELECT_COMMAND)
380 static void
381 print_select_command (select_command)
382      SELECT_COM *select_command;
383 {
384   cprintf ("select %s in ", select_command->name->word);
385   command_print_word_list (select_command->map_list, " ");
386   cprintf (";");
387   newline ("do\n");
388   indentation += indentation_amount;
389   make_command_string_internal (select_command->action);
390   semicolon ();
391   indentation -= indentation_amount;
392   newline ("done");
393 }
394 #endif /* SELECT_COMMAND */
395
396 static void
397 print_group_command (group_command)
398      GROUP_COM *group_command;
399 {
400   group_command_nesting++;
401   cprintf ("{ ");
402
403   if (inside_function_def == 0)
404     skip_this_indent++;
405   else
406     {
407       /* This is a group command { ... } inside of a function
408          definition, and should be printed as a multiline group
409          command, using the current indentation. */
410       cprintf ("\n");
411       indentation += indentation_amount;
412     }
413
414   make_command_string_internal (group_command->command);
415
416   if (inside_function_def)
417     {
418       cprintf ("\n");
419       indentation -= indentation_amount;
420       indent (indentation);
421     }
422   else
423     {
424       semicolon ();
425       cprintf (" ");
426     }
427
428   cprintf ("}");
429
430   group_command_nesting--;
431 }
432
433 static void
434 print_case_command (case_command)
435      CASE_COM *case_command;
436 {
437   cprintf ("case %s in ", case_command->word->word);
438   if (case_command->clauses)
439     print_case_clauses (case_command->clauses);
440   newline ("esac");
441 }
442
443 static void
444 print_case_clauses (clauses)
445      PATTERN_LIST *clauses;
446 {
447   indentation += indentation_amount;
448   while (clauses)
449     {
450       newline ("");
451       command_print_word_list (clauses->patterns, " | ");
452       cprintf (")\n");
453       indentation += indentation_amount;
454       make_command_string_internal (clauses->action);
455       indentation -= indentation_amount;
456       newline (";;");
457       clauses = clauses->next;
458     }
459   indentation -= indentation_amount;
460 }
461
462 static void
463 print_while_command (while_command)
464      WHILE_COM *while_command;
465 {
466   print_until_or_while (while_command, "while");
467 }
468
469 static void
470 print_until_command (while_command)
471      WHILE_COM *while_command;
472 {
473   print_until_or_while (while_command, "until");
474 }
475
476 static void
477 print_until_or_while (while_command, which)
478      WHILE_COM *while_command;
479      char *which;
480 {
481   cprintf ("%s ", which);
482   skip_this_indent++;
483   make_command_string_internal (while_command->test);
484   semicolon ();
485   cprintf (" do\n");    /* was newline ("do\n"); */
486   indentation += indentation_amount;
487   make_command_string_internal (while_command->action);
488   indentation -= indentation_amount;
489   semicolon ();
490   newline ("done");
491 }
492
493 static void
494 print_if_command (if_command)
495      IF_COM *if_command;
496 {
497   cprintf ("if ");
498   skip_this_indent++;
499   make_command_string_internal (if_command->test);
500   semicolon ();
501   cprintf (" then\n");
502   indentation += indentation_amount;
503   make_command_string_internal (if_command->true_case);
504   indentation -= indentation_amount;
505
506   if (if_command->false_case)
507     {
508       semicolon ();
509       newline ("else\n");
510       indentation += indentation_amount;
511       make_command_string_internal (if_command->false_case);
512       indentation -= indentation_amount;
513     }
514   semicolon ();
515   newline ("fi");
516 }
517
518 #if defined (DPAREN_ARITHMETIC)
519 static void
520 print_arith_command (arith_command)
521      ARITH_COM *arith_command;
522 {
523   cprintf ("(( ");
524   command_print_word_list (arith_command->exp, " ");
525   cprintf (" ))");
526 }
527 #endif
528
529 #if defined (COND_COMMAND)
530 static void
531 print_cond_node (cond)
532      COND_COM *cond;
533 {
534   if (cond->flags & CMD_INVERT_RETURN)
535     cprintf ("! ");
536
537   if (cond->type == COND_EXPR)
538     {
539       cprintf ("( ");
540       print_cond_node (cond->left);
541       cprintf (" )");
542     }
543   else if (cond->type == COND_AND)
544     {
545       print_cond_node (cond->left);
546       cprintf (" && ");
547       print_cond_node (cond->right);
548     }
549   else if (cond->type == COND_OR)
550     {
551       print_cond_node (cond->left);
552       cprintf (" || ");
553       print_cond_node (cond->right);
554     }
555   else if (cond->type == COND_UNARY)
556     {
557       cprintf ("%s", cond->op->word);
558       cprintf (" ");
559       print_cond_node (cond->left);
560     }
561   else if (cond->type == COND_BINARY)
562     {
563       print_cond_node (cond->left);
564       cprintf (" ");
565       cprintf ("%s", cond->op->word);
566       cprintf (" ");
567       print_cond_node (cond->right);
568     }
569   else if (cond->type == COND_TERM)
570     {
571       cprintf ("%s", cond->op->word);           /* need to add quoting here */
572     }
573 }
574
575 static void
576 print_cond_command (cond)
577      COND_COM *cond;
578 {
579   cprintf ("[[ ");
580   print_cond_node (cond);
581   cprintf (" ]]");
582 }
583
584 #ifdef DEBUG
585 void
586 debug_print_cond_command (cond)
587      COND_COM *cond;
588 {
589   fprintf (stderr, "DEBUG: ");
590   command_string_index = 0;
591   print_cond_command (cond);
592   fprintf (stderr, "%s\n", the_printed_command);
593 }
594 #endif
595
596 void
597 xtrace_print_cond_term (type, invert, op, arg1, arg2)
598      int type, invert;
599      WORD_DESC *op;
600      char *arg1, *arg2;
601 {
602   command_string_index = 0;
603   fprintf (stderr, "%s", indirection_level_string ());
604   fprintf (stderr, "[[ ");
605   if (invert)
606     fprintf (stderr, "! ");
607
608   if (type == COND_UNARY)
609     {
610       fprintf (stderr, "%s ", op->word);
611       fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
612     }
613   else if (type == COND_BINARY)
614     {
615       fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
616       fprintf (stderr, " %s ", op->word);
617       fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
618     }
619
620   fprintf (stderr, " ]]\n");
621 }         
622 #endif /* COND_COMMAND */
623
624 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
625 /* A function to print the words of an arithmetic command when set -x is on. */
626 void
627 xtrace_print_arith_cmd (list)
628      WORD_LIST *list;
629 {
630   WORD_LIST *w;
631
632   fprintf (stderr, "%s", indirection_level_string ());
633   fprintf (stderr, "(( ");
634   for (w = list; w; w = w->next)
635     fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
636   fprintf (stderr, " ))\n");
637 }
638 #endif
639
640 void
641 print_simple_command (simple_command)
642      SIMPLE_COM *simple_command;
643 {
644   command_print_word_list (simple_command->words, " ");
645
646   if (simple_command->redirects)
647     {
648       cprintf (" ");
649       print_redirection_list (simple_command->redirects);
650     }
651 }
652
653 static void
654 print_redirection_list (redirects)
655      REDIRECT *redirects;
656 {
657   REDIRECT *heredocs, *hdtail, *newredir;
658
659   heredocs = (REDIRECT *)NULL;
660   hdtail = heredocs;
661
662   was_heredoc = 0;
663   while (redirects)
664     {
665       /* Defer printing the here documents until we've printed the
666          rest of the redirections. */
667       if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
668         {
669           newredir = copy_redirect (redirects);
670           newredir->next = (REDIRECT *)NULL;
671           if (heredocs)
672             {
673               hdtail->next = newredir;
674               hdtail = newredir;
675             }
676           else
677             hdtail = heredocs = newredir;
678         }
679       else
680         print_redirection (redirects);
681
682       redirects = redirects->next;
683       if (redirects)
684         cprintf (" ");
685     }
686
687   /* Now that we've printed all the other redirections (on one line),
688      print the here documents. */
689   if (heredocs)
690     {
691       cprintf (" "); 
692       for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
693         {
694           print_redirection (hdtail);
695           cprintf ("\n");
696         }
697       dispose_redirects (heredocs);
698       was_heredoc = 1;
699     }
700 }
701
702 static void
703 print_redirection (redirect)
704      REDIRECT *redirect;
705 {
706   int kill_leading, redirector, redir_fd;
707   WORD_DESC *redirectee;
708
709   kill_leading = 0;
710   redirectee = redirect->redirectee.filename;
711   redirector = redirect->redirector;
712   redir_fd = redirect->redirectee.dest;
713
714   switch (redirect->instruction)
715     {
716     case r_output_direction:
717       if (redirector != 1)
718         cprintf ("%d", redirector);
719       cprintf (">%s", redirectee->word);
720       break;
721
722     case r_input_direction:
723       if (redirector != 0)
724         cprintf ("%d", redirector);
725       cprintf ("<%s", redirectee->word);
726       break;
727
728     case r_inputa_direction:    /* Redirection created by the shell. */
729       cprintf ("&");
730       break;
731
732     case r_appending_to:
733       if (redirector != 1)
734         cprintf ("%d", redirector);
735       cprintf (">>%s", redirectee->word);
736       break;
737
738     case r_deblank_reading_until:
739       kill_leading++;
740       /* ... */
741     case r_reading_until:
742       if (redirector != 0)
743         cprintf ("%d", redirector);
744       /* If the here document delimiter is quoted, single-quote it. */
745       if (redirect->redirectee.filename->flags & W_QUOTED)
746         {
747           char *x;
748           x = sh_single_quote (redirect->here_doc_eof);
749           cprintf ("<<%s%s\n", kill_leading? "-" : "", x);
750           free (x);
751         }
752       else
753         cprintf ("<<%s%s\n", kill_leading? "-" : "", redirect->here_doc_eof);
754       cprintf ("%s%s",
755                redirect->redirectee.filename->word, redirect->here_doc_eof);
756       break;
757
758     case r_duplicating_input:
759       cprintf ("%d<&%d", redirector, redir_fd);
760       break;
761
762     case r_duplicating_output:
763       cprintf ("%d>&%d", redirector, redir_fd);
764       break;
765
766     case r_duplicating_input_word:
767       cprintf ("%d<&%s", redirector, redirectee->word);
768       break;
769
770     case r_duplicating_output_word:
771       cprintf ("%d>&%s", redirector, redirectee->word);
772       break;
773
774     case r_close_this:
775       cprintf ("%d>&-", redirector);
776       break;
777
778     case r_err_and_out:
779       cprintf (">&%s", redirectee->word);
780       break;
781
782     case r_input_output:
783       if (redirector != 1)
784         cprintf ("%d", redirector);
785       cprintf ("<>%s", redirectee->word);
786       break;
787
788     case r_output_force:
789       if (redirector != 1)
790         cprintf ("%d", redirector);
791       cprintf (">|%s", redirectee->word);
792       break;
793     }
794 }
795
796 static void
797 reset_locals ()
798 {
799   inside_function_def = 0;
800   indentation = 0;
801 }
802
803 static void
804 print_function_def (func)
805      FUNCTION_DEF *func;
806 {
807   COMMAND *cmdcopy;
808   REDIRECT *func_redirects;
809
810   cprintf ("function %s () \n", func->name->word);
811   add_unwind_protect (reset_locals, 0);
812
813   indent (indentation);
814   cprintf ("{ \n");
815
816   inside_function_def++;
817   indentation += indentation_amount;
818
819   cmdcopy = copy_command (func->command);
820   if (cmdcopy->type == cm_group)
821     {
822       func_redirects = cmdcopy->redirects;
823       cmdcopy->redirects = (REDIRECT *)NULL;
824     }
825   make_command_string_internal (cmdcopy->type == cm_group
826                                         ? cmdcopy->value.Group->command
827                                         : cmdcopy);
828
829   remove_unwind_protect ();
830   indentation -= indentation_amount;
831   inside_function_def--;
832
833   if (func_redirects)
834     { /* { */
835       newline ("} ");
836       print_redirection_list (func_redirects);
837       cmdcopy->redirects = func_redirects;
838     }
839   else
840     newline ("}");
841
842   dispose_command (cmdcopy);
843 }
844
845 /* Return the string representation of the named function.
846    NAME is the name of the function.
847    COMMAND is the function body.  It should be a GROUP_COM.
848    MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
849   */
850 char *
851 named_function_string (name, command, multi_line)
852      char *name;
853      COMMAND *command;
854      int multi_line;
855 {
856   char *result;
857   int old_indent, old_amount;
858   COMMAND *cmdcopy;
859   REDIRECT *func_redirects;
860
861   old_indent = indentation;
862   old_amount = indentation_amount;
863   command_string_index = was_heredoc = 0;
864
865   if (name && *name)
866     cprintf ("%s ", name);
867
868   cprintf ("() ");
869
870   if (multi_line == 0)
871     {
872       indentation = 1;
873       indentation_amount = 0;
874     }
875   else
876     {
877       cprintf ("\n");
878       indentation += indentation_amount;
879     }
880
881   inside_function_def++;
882
883   cprintf (multi_line ? "{ \n" : "{ ");
884
885   cmdcopy = copy_command (command);
886   /* Take any redirections specified in the function definition (which should
887      apply to the function as a whole) and save them for printing later. */
888   func_redirects = (REDIRECT *)NULL;
889   if (cmdcopy->type == cm_group)
890     {
891       func_redirects = cmdcopy->redirects;
892       cmdcopy->redirects = (REDIRECT *)NULL;
893     }
894   make_command_string_internal (cmdcopy->type == cm_group
895                                         ? cmdcopy->value.Group->command
896                                         : cmdcopy);
897
898   indentation = old_indent;
899   indentation_amount = old_amount;
900   inside_function_def--;
901
902   if (func_redirects)
903     { /* { */
904       newline ("} ");
905       print_redirection_list (func_redirects);
906       cmdcopy->redirects = func_redirects;
907     }
908   else
909     newline ("}");
910
911   result = the_printed_command;
912
913   if (!multi_line)
914     {
915 #if 0
916       register int i;
917       for (i = 0; result[i]; i++)
918         if (result[i] == '\n')
919           {
920             strcpy (result + i, result + i + 1);
921             --i;
922           }
923 #else
924       if (result[2] == '\n')    /* XXX -- experimental */
925         strcpy (result + 2, result + 3);
926 #endif
927     }
928
929   dispose_command (cmdcopy);
930
931   return (result);
932 }
933
934 static void
935 newline (string)
936      char *string;
937 {
938   cprintf ("\n");
939   indent (indentation);
940   if (string && *string)
941     cprintf ("%s", string);
942 }
943
944 static char *indentation_string;
945 static int indentation_size;
946
947 static void
948 indent (amount)
949      int amount;
950 {
951   register int i;
952
953   RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
954
955   for (i = 0; amount > 0; amount--)
956     indentation_string[i++] = ' ';
957   indentation_string[i] = '\0';
958   cprintf (indentation_string);
959 }
960
961 static void
962 semicolon ()
963 {
964   if (command_string_index > 0 && the_printed_command[command_string_index - 1] == '&')
965     return;
966   cprintf (";");
967 }
968
969 #if !defined (USE_VARARGS)
970 /* How to make the string. */
971 static void
972 cprintf (format, arg1, arg2)
973      char *format, *arg1, *arg2;
974 {
975   register char *s;
976   char char_arg[2], *argp, *args[2], intbuf[32];
977   int arg_len, c, arg_index;
978
979   args[arg_index = 0] = arg1;
980   args[1] = arg2;
981
982   arg_len = strlen (format);
983   the_printed_command_resize (arg_len + 1);
984
985   char_arg[1] = '\0';
986   s = format;
987   while (s && *s)
988     {
989       int free_argp = 0;
990       c = *s++;
991       if (c != '%' || !*s)
992         {
993           argp = s;
994           arg_len = 1;
995         }
996       else
997         {
998           c = *s++;
999           switch (c)
1000             {
1001             case '%':
1002               char_arg[0] = c;
1003               argp = char_arg;
1004               arg_len = 1;
1005               break;
1006
1007             case 's':
1008               argp = (char *)args[arg_index++];
1009               arg_len = strlen (argp);
1010               break;
1011
1012             case 'd':
1013               argp = inttostr (pointer_to_int (args[arg_index]), intbuf, sizeof (intbuf));
1014               arg_index++;
1015               arg_len = strlen (argp);
1016               break;
1017
1018             case 'c':
1019               char_arg[0] = pointer_to_int (args[arg_index]);
1020               arg_index++;
1021               argp = char_arg;
1022               arg_len = 1;
1023               break;
1024
1025             default:
1026               programming_error ("cprintf: bad `%%' argument (%c)", c);
1027             }
1028         }
1029       if (argp)
1030         {
1031           the_printed_command_resize (arg_len + 1);
1032           FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1033           command_string_index += arg_len;
1034           if (free_argp)
1035             free (argp);
1036         }
1037     }
1038
1039   the_printed_command[command_string_index] = '\0';
1040 }
1041
1042 #else /* We have support for varargs. */
1043
1044 /* How to make the string. */
1045 static void
1046 #if defined (PREFER_STDARG)
1047 cprintf (char *control, ...)
1048 #else
1049 cprintf (control, va_alist)
1050      char *control;
1051      va_dcl
1052 #endif
1053 {
1054   register char *s;
1055   char char_arg[2], *argp, intbuf[32];
1056   int digit_arg, arg_len, c;
1057   va_list args;
1058
1059 #if defined (PREFER_STDARG)
1060   va_start (args, control);
1061 #else
1062   va_start (args);
1063 #endif
1064
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     {
1072       int free_argp;
1073       free_argp = 0;
1074       c = *s++;
1075       argp = (char *)NULL;
1076       if (c != '%' || !*s)
1077         {
1078           argp = s - 1;
1079           arg_len = 1;
1080         }
1081       else
1082         {
1083           c = *s++;
1084           switch (c)
1085             {
1086             case '%':
1087               char_arg[0] = c;
1088               argp = char_arg;
1089               arg_len = 1;
1090               break;
1091
1092             case 's':
1093               argp = va_arg (args, char *);
1094               arg_len = strlen (argp);
1095               break;
1096
1097             case 'd':
1098               digit_arg = va_arg (args, int);
1099               argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
1100               arg_len = strlen (argp);
1101               break;
1102
1103             case 'c':
1104               char_arg[0] = va_arg (args, int);
1105               argp = char_arg;
1106               arg_len = 1;
1107               break;
1108
1109             default:
1110               programming_error ("cprintf: bad `%%' argument (%c)", c);
1111               /*NOTREACHED*/
1112             }
1113         }
1114
1115       if (argp && arg_len)
1116         {
1117           the_printed_command_resize (arg_len + 1);
1118           FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
1119           command_string_index += arg_len;
1120           if (free_argp)
1121             free (argp);
1122         }
1123     }
1124
1125   the_printed_command[command_string_index] = '\0';
1126 }
1127 #endif /* HAVE_VARARGS_H */
1128
1129 /* Ensure that there is enough space to stuff LENGTH characters into
1130    THE_PRINTED_COMMAND. */
1131 static void
1132 the_printed_command_resize (length)
1133      int length;
1134 {
1135   if (the_printed_command == 0)
1136     {
1137       the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
1138       the_printed_command = xmalloc (the_printed_command_size);
1139       command_string_index = 0;
1140     }
1141   else if ((command_string_index + length) >= the_printed_command_size)
1142     {
1143       int new;
1144       new = command_string_index + length + 1;
1145
1146       /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1147       new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
1148       the_printed_command_size = new;
1149
1150       the_printed_command = xrealloc (the_printed_command, the_printed_command_size);
1151     }
1152 }
1153
1154 #if defined (HAVE_VFPRINTF)
1155
1156 static void
1157 #if defined (PREFER_STDARG)
1158 xprintf (const char *format, ...)
1159 #else
1160 xprintf (format, va_alist)
1161      const char *format;
1162      va_dcl
1163 #endif
1164 {
1165   va_list args;
1166
1167 #if defined (PREFER_STDARG)
1168   va_start (args, format);
1169 #else
1170   va_start (args);
1171 #endif
1172
1173   vfprintf (stdout, format, args);
1174   va_end (args);
1175 }
1176
1177 #else
1178
1179 static void
1180 xprintf (format, arg1, arg2, arg3, arg4, arg5)
1181      char *format;
1182 {
1183   printf (format, arg1, arg2, arg3, arg4, arg5);
1184 }
1185
1186 #endif /* !HAVE_VFPRINTF */