]> git.ipfire.org Git - thirdparty/bash.git/blob - print_cmd.c
Imported from ../bash-2.01.tar.gz.
[thirdparty/bash.git] / 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "config.h"
21
22 #include <stdio.h>
23
24 #if defined (HAVE_UNISTD_H)
25 # include <unistd.h>
26 #endif
27
28 #if defined (PREFER_STDARG)
29 # include <stdarg.h>
30 #else
31 # if defined (PREFER_VARARGS)
32 # include <varargs.h>
33 # endif
34 #endif
35
36 #include "bashansi.h"
37
38 #include "shell.h"
39 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
40 #include "stdc.h"
41 #include "builtins/common.h"
42
43 #if !defined (PRINTF_DECLARED)
44 extern int printf __P((const char *, ...)); /* Yuck. Double yuck. */
45 #endif
46
47 static int indentation;
48 static int indentation_amount = 4;
49
50 #if defined (PREFER_STDARG)
51 static void cprintf __P((char *, ...));
52 #else
53 static void cprintf ();
54 #endif
55
56 static void newline (), indent (), the_printed_command_resize ();
57 static void semicolon ();
58 static void xprintf ();
59
60 static void make_command_string_internal ();
61 static void command_print_word_list ();
62 static void print_case_clauses ();
63 static void print_redirection_list ();
64 static void print_redirection ();
65
66 static void print_for_command ();
67 #if defined (SELECT_COMMAND)
68 static void print_select_command ();
69 #endif
70 static void print_group_command ();
71 static void print_case_command ();
72 static void print_while_command ();
73 static void print_until_command ();
74 static void print_until_or_while ();
75 static void print_if_command ();
76 static void print_function_def ();
77
78 #define PRINTED_COMMAND_INITIAL_SIZE 64
79 #define PRINTED_COMMAND_GROW_SIZE 128
80
81 char *the_printed_command = (char *)NULL;
82 int the_printed_command_size = 0;
83 int command_string_index = 0;
84
85 /* Non-zero means the stuff being printed is inside of a function def. */
86 static int inside_function_def;
87 static int skip_this_indent;
88 static int was_heredoc;
89
90 /* The depth of the group commands that we are currently printing. This
91 includes the group command that is a function body. */
92 static int group_command_nesting;
93
94 /* Print COMMAND (a command tree) on standard output. */
95 void
96 print_command (command)
97 COMMAND *command;
98 {
99 command_string_index = 0;
100 printf ("%s", make_command_string (command));
101 }
102
103 /* Make a string which is the printed representation of the command
104 tree in COMMAND. We return this string. However, the string is
105 not consed, so you have to do that yourself if you want it to
106 remain around. */
107 char *
108 make_command_string (command)
109 COMMAND *command;
110 {
111 command_string_index = was_heredoc = 0;
112 make_command_string_internal (command);
113 return (the_printed_command);
114 }
115
116 /* The internal function. This is the real workhorse. */
117 static void
118 make_command_string_internal (command)
119 COMMAND *command;
120 {
121 if (command == 0)
122 cprintf ("");
123 else
124 {
125 if (skip_this_indent)
126 skip_this_indent--;
127 else
128 indent (indentation);
129
130 if (command->flags & CMD_WANT_SUBSHELL)
131 cprintf ("( ");
132
133 if (command->flags & CMD_TIME_PIPELINE)
134 {
135 cprintf ("time ");
136 if (command->flags & CMD_TIME_POSIX)
137 cprintf ("-p ");
138 }
139
140 if (command->flags & CMD_INVERT_RETURN)
141 cprintf ("! ");
142
143 switch (command->type)
144 {
145 case cm_for:
146 print_for_command (command->value.For);
147 break;
148
149 #if defined (SELECT_COMMAND)
150 case cm_select:
151 print_select_command (command->value.Select);
152 break;
153 #endif
154
155 case cm_case:
156 print_case_command (command->value.Case);
157 break;
158
159 case cm_while:
160 print_while_command (command->value.While);
161 break;
162
163 case cm_until:
164 print_until_command (command->value.While);
165 break;
166
167 case cm_if:
168 print_if_command (command->value.If);
169 break;
170
171 case cm_simple:
172 print_simple_command (command->value.Simple);
173 break;
174
175 case cm_connection:
176
177 skip_this_indent++;
178 make_command_string_internal (command->value.Connection->first);
179
180 switch (command->value.Connection->connector)
181 {
182 case '&':
183 case '|':
184 {
185 char c = command->value.Connection->connector;
186 cprintf (" %c", c);
187 if (c != '&' || command->value.Connection->second)
188 {
189 cprintf (" ");
190 skip_this_indent++;
191 }
192 }
193 break;
194
195 case AND_AND:
196 cprintf (" && ");
197 if (command->value.Connection->second)
198 skip_this_indent++;
199 break;
200
201 case OR_OR:
202 cprintf (" || ");
203 if (command->value.Connection->second)
204 skip_this_indent++;
205 break;
206
207 case ';':
208 if (was_heredoc == 0)
209 cprintf (";");
210 else
211 was_heredoc = 0;
212
213 if (inside_function_def)
214 cprintf ("\n");
215 else
216 {
217 cprintf (" ");
218 if (command->value.Connection->second)
219 skip_this_indent++;
220 }
221 break;
222
223 default:
224 cprintf ("print_command: bad connector `%d'",
225 command->value.Connection->connector);
226 break;
227 }
228
229 make_command_string_internal (command->value.Connection->second);
230 break;
231
232 case cm_function_def:
233 print_function_def (command->value.Function_def);
234 break;
235
236 case cm_group:
237 print_group_command (command->value.Group);
238 break;
239
240 default:
241 programming_error ("print_command: bad command type `%d'", command->type);
242 break;
243 }
244
245 if (command->flags & CMD_WANT_SUBSHELL)
246 cprintf (" )");
247
248 if (command->redirects)
249 print_redirection_list (command->redirects);
250 }
251 }
252
253 static void
254 _print_word_list (list, separator, pfunc)
255 WORD_LIST *list;
256 char *separator;
257 VFunction *pfunc;
258 {
259 WORD_LIST *w;
260
261 for (w = list; w; w = w->next)
262 (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
263 }
264
265 void
266 print_word_list (list, separator)
267 WORD_LIST *list;
268 char *separator;
269 {
270 _print_word_list (list, separator, xprintf);
271 }
272
273 /* A function to print the words of a simple command when set -x is on. */
274 void
275 xtrace_print_word_list (list)
276 WORD_LIST *list;
277 {
278 WORD_LIST *w;
279 char *t;
280
281 fprintf (stderr, "%s", indirection_level_string ());
282 for (w = list; w; w = w->next)
283 {
284 t = w->word->word;
285 if (t == 0 || *t == '\0')
286 fprintf (stderr, "''%s", w->next ? " " : "");
287 else if (contains_shell_metas (t))
288 fprintf (stderr, "'%s'%s", t, w->next ? " " : "");
289 else
290 fprintf (stderr, "%s%s", t, w->next ? " " : "");
291 }
292 fprintf (stderr, "\n");
293 }
294
295 static void
296 command_print_word_list (list, separator)
297 WORD_LIST *list;
298 char *separator;
299 {
300 _print_word_list (list, separator, cprintf);
301 }
302
303 static void
304 print_for_command (for_command)
305 FOR_COM *for_command;
306 {
307 cprintf ("for %s in ", for_command->name->word);
308 command_print_word_list (for_command->map_list, " ");
309 cprintf (";");
310 newline ("do\n");
311 indentation += indentation_amount;
312 make_command_string_internal (for_command->action);
313 semicolon ();
314 indentation -= indentation_amount;
315 newline ("done");
316 }
317
318 #if defined (SELECT_COMMAND)
319 static void
320 print_select_command (select_command)
321 SELECT_COM *select_command;
322 {
323 cprintf ("select %s in ", select_command->name->word);
324 command_print_word_list (select_command->map_list, " ");
325 cprintf (";");
326 newline ("do\n");
327 indentation += indentation_amount;
328 make_command_string_internal (select_command->action);
329 semicolon ();
330 indentation -= indentation_amount;
331 newline ("done");
332 }
333 #endif /* SELECT_COMMAND */
334
335 static void
336 print_group_command (group_command)
337 GROUP_COM *group_command;
338 {
339 group_command_nesting++;
340 cprintf ("{ ");
341
342 if (inside_function_def == 0)
343 skip_this_indent++;
344 else
345 {
346 /* This is a group command { ... } inside of a function
347 definition, and should be printed as a multiline group
348 command, using the current indentation. */
349 cprintf ("\n");
350 indentation += indentation_amount;
351 }
352
353 make_command_string_internal (group_command->command);
354
355 if (inside_function_def)
356 {
357 cprintf ("\n");
358 indentation -= indentation_amount;
359 indent (indentation);
360 }
361 else
362 {
363 semicolon ();
364 cprintf (" ");
365 }
366
367 cprintf ("}");
368
369 group_command_nesting--;
370 }
371
372 static void
373 print_case_command (case_command)
374 CASE_COM *case_command;
375 {
376 cprintf ("case %s in ", case_command->word->word);
377 if (case_command->clauses)
378 print_case_clauses (case_command->clauses);
379 newline ("esac");
380 }
381
382 static void
383 print_case_clauses (clauses)
384 PATTERN_LIST *clauses;
385 {
386 indentation += indentation_amount;
387 while (clauses)
388 {
389 newline ("");
390 command_print_word_list (clauses->patterns, " | ");
391 cprintf (")\n");
392 indentation += indentation_amount;
393 make_command_string_internal (clauses->action);
394 indentation -= indentation_amount;
395 newline (";;");
396 clauses = clauses->next;
397 }
398 indentation -= indentation_amount;
399 }
400
401 static void
402 print_while_command (while_command)
403 WHILE_COM *while_command;
404 {
405 print_until_or_while (while_command, "while");
406 }
407
408 static void
409 print_until_command (while_command)
410 WHILE_COM *while_command;
411 {
412 print_until_or_while (while_command, "until");
413 }
414
415 static void
416 print_until_or_while (while_command, which)
417 WHILE_COM *while_command;
418 char *which;
419 {
420 cprintf ("%s ", which);
421 skip_this_indent++;
422 make_command_string_internal (while_command->test);
423 semicolon ();
424 cprintf (" do\n"); /* was newline ("do\n"); */
425 indentation += indentation_amount;
426 make_command_string_internal (while_command->action);
427 indentation -= indentation_amount;
428 semicolon ();
429 newline ("done");
430 }
431
432 static void
433 print_if_command (if_command)
434 IF_COM *if_command;
435 {
436 cprintf ("if ");
437 skip_this_indent++;
438 make_command_string_internal (if_command->test);
439 semicolon ();
440 cprintf (" then\n");
441 indentation += indentation_amount;
442 make_command_string_internal (if_command->true_case);
443 indentation -= indentation_amount;
444
445 if (if_command->false_case)
446 {
447 semicolon ();
448 newline ("else\n");
449 indentation += indentation_amount;
450 make_command_string_internal (if_command->false_case);
451 indentation -= indentation_amount;
452 }
453 semicolon ();
454 newline ("fi");
455 }
456
457 void
458 print_simple_command (simple_command)
459 SIMPLE_COM *simple_command;
460 {
461 command_print_word_list (simple_command->words, " ");
462
463 if (simple_command->redirects)
464 {
465 cprintf (" ");
466 print_redirection_list (simple_command->redirects);
467 }
468 }
469
470 static void
471 print_redirection_list (redirects)
472 REDIRECT *redirects;
473 {
474 REDIRECT *heredocs, *hdtail, *newredir;
475
476 heredocs = (REDIRECT *)NULL;
477 hdtail = heredocs;
478
479 was_heredoc = 0;
480 while (redirects)
481 {
482 /* Defer printing the here documents until we've printed the
483 rest of the redirections. */
484 if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
485 {
486 newredir = copy_redirect (redirects);
487 newredir->next = (REDIRECT *)NULL;
488 if (heredocs)
489 {
490 hdtail->next = newredir;
491 hdtail = newredir;
492 }
493 else
494 hdtail = heredocs = newredir;
495 }
496 else
497 print_redirection (redirects);
498
499 redirects = redirects->next;
500 if (redirects)
501 cprintf (" ");
502 }
503
504 /* Now that we've printed all the other redirections (on one line),
505 print the here documents. */
506 if (heredocs)
507 {
508 cprintf (" ");
509 for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
510 {
511 print_redirection (hdtail);
512 cprintf ("\n");
513 }
514 dispose_redirects (heredocs);
515 was_heredoc = 1;
516 }
517 }
518
519 static void
520 print_redirection (redirect)
521 REDIRECT *redirect;
522 {
523 int kill_leading, redirector, redir_fd;
524 WORD_DESC *redirectee;
525
526 kill_leading = 0;
527 redirectee = redirect->redirectee.filename;
528 redirector = redirect->redirector;
529 redir_fd = redirect->redirectee.dest;
530
531 switch (redirect->instruction)
532 {
533 case r_output_direction:
534 if (redirector != 1)
535 cprintf ("%d", redirector);
536 cprintf (">%s", redirectee->word);
537 break;
538
539 case r_input_direction:
540 if (redirector != 0)
541 cprintf ("%d", redirector);
542 cprintf ("<%s", redirectee->word);
543 break;
544
545 case r_inputa_direction: /* Redirection created by the shell. */
546 cprintf ("&");
547 break;
548
549 case r_appending_to:
550 if (redirector != 1)
551 cprintf ("%d", redirector);
552 cprintf (">>%s", redirectee->word);
553 break;
554
555 case r_deblank_reading_until:
556 kill_leading++;
557 /* ... */
558 case r_reading_until:
559 if (redirector != 0)
560 cprintf ("%d", redirector);
561 /* If the here document delimiter is quoted, single-quote it. */
562 if (redirect->redirectee.filename->flags & W_QUOTED)
563 {
564 char *x;
565 x = single_quote (redirect->here_doc_eof);
566 cprintf ("<<%s%s\n", kill_leading? "-" : "", x);
567 free (x);
568 }
569 else
570 cprintf ("<<%s%s\n", kill_leading? "-" : "", redirect->here_doc_eof);
571 cprintf ("%s%s",
572 redirect->redirectee.filename->word, redirect->here_doc_eof);
573 break;
574
575 case r_duplicating_input:
576 cprintf ("%d<&%d", redirector, redir_fd);
577 break;
578
579 case r_duplicating_output:
580 cprintf ("%d>&%d", redirector, redir_fd);
581 break;
582
583 case r_duplicating_input_word:
584 cprintf ("%d<&%s", redirector, redirectee->word);
585 break;
586
587 case r_duplicating_output_word:
588 cprintf ("%d>&%s", redirector, redirectee->word);
589 break;
590
591 case r_close_this:
592 cprintf ("%d>&-", redirector);
593 break;
594
595 case r_err_and_out:
596 cprintf (">&%s", redirectee->word);
597 break;
598
599 case r_input_output:
600 if (redirector != 1)
601 cprintf ("%d", redirector);
602 cprintf ("<>%s", redirectee->word);
603 break;
604
605 case r_output_force:
606 if (redirector != 1)
607 cprintf ("%d", redirector);
608 cprintf (">|%s", redirectee->word);
609 break;
610 }
611 }
612
613 static void
614 reset_locals ()
615 {
616 inside_function_def = 0;
617 indentation = 0;
618 }
619
620 static void
621 print_function_def (func)
622 FUNCTION_DEF *func;
623 {
624 cprintf ("function %s () \n", func->name->word);
625 add_unwind_protect (reset_locals, 0);
626
627 indent (indentation);
628 cprintf ("{ \n");
629
630 inside_function_def++;
631 indentation += indentation_amount;
632
633 make_command_string_internal (func->command->type == cm_group
634 ? func->command->value.Group->command
635 : func->command);
636
637 remove_unwind_protect ();
638 indentation -= indentation_amount;
639 inside_function_def--;
640
641 newline ("}");
642 }
643
644 /* Return the string representation of the named function.
645 NAME is the name of the function.
646 COMMAND is the function body. It should be a GROUP_COM.
647 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
648 */
649 char *
650 named_function_string (name, command, multi_line)
651 char *name;
652 COMMAND *command;
653 int multi_line;
654 {
655 char *result;
656 int old_indent, old_amount;
657
658 old_indent = indentation;
659 old_amount = indentation_amount;
660 command_string_index = was_heredoc = 0;
661
662 if (name && *name)
663 cprintf ("%s ", name);
664
665 cprintf ("() ");
666
667 if (multi_line == 0)
668 {
669 indentation = 1;
670 indentation_amount = 0;
671 }
672 else
673 {
674 cprintf ("\n");
675 indentation += indentation_amount;
676 }
677
678 inside_function_def++;
679
680 cprintf (multi_line ? "{ \n" : "{ ");
681
682 make_command_string_internal (command->type == cm_group
683 ? command->value.Group->command
684 : command);
685
686 indentation = old_indent;
687 indentation_amount = old_amount;
688 inside_function_def--;
689
690 newline ("}");
691
692 result = the_printed_command;
693
694 if (!multi_line)
695 {
696 #if 0
697 register int i;
698 for (i = 0; result[i]; i++)
699 if (result[i] == '\n')
700 {
701 strcpy (result + i, result + i + 1);
702 --i;
703 }
704 #else
705 if (result[2] == '\n') /* XXX -- experimental */
706 strcpy (result + 2, result + 3);
707 #endif
708 }
709
710 return (result);
711 }
712
713 static void
714 newline (string)
715 char *string;
716 {
717 cprintf ("\n");
718 indent (indentation);
719 if (string && *string)
720 cprintf ("%s", string);
721 }
722
723 static char *indentation_string;
724 static int indentation_size;
725
726 static void
727 indent (amount)
728 int amount;
729 {
730 register int i;
731
732 RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
733
734 for (i = 0; amount > 0; amount--)
735 indentation_string[i++] = ' ';
736 indentation_string[i] = '\0';
737 cprintf (indentation_string);
738 }
739
740 static void
741 semicolon ()
742 {
743 if (command_string_index > 0 && the_printed_command[command_string_index - 1] == '&')
744 return;
745 cprintf (";");
746 }
747
748 #if !defined (USE_VARARGS)
749 /* How to make the string. */
750 static void
751 cprintf (format, arg1, arg2)
752 char *format, *arg1, *arg2;
753 {
754 register char *s;
755 char char_arg[2], *argp, *args[2];
756 int arg_len, c, arg_index;
757
758 args[arg_index = 0] = arg1;
759 args[1] = arg2;
760
761 arg_len = strlen (format);
762 the_printed_command_resize (arg_len + 1);
763
764 char_arg[1] = '\0';
765 s = format;
766 while (s && *s)
767 {
768 int free_argp = 0;
769 c = *s++;
770 if (c != '%' || !*s)
771 {
772 argp = s;
773 arg_len = 1;
774 }
775 else
776 {
777 c = *s++;
778 switch (c)
779 {
780 case '%':
781 char_arg[0] = c;
782 argp = char_arg;
783 arg_len = 1;
784 break;
785
786 case 's':
787 argp = (char *)args[arg_index++];
788 arg_len = strlen (argp);
789 break;
790
791 case 'd':
792 argp = itos (pointer_to_int (args[arg_index]));
793 arg_index++;
794 arg_len = strlen (argp);
795 free_argp = 1;
796 break;
797
798 case 'c':
799 char_arg[0] = pointer_to_int (args[arg_index]);
800 arg_index++;
801 argp = char_arg;
802 arg_len = 1;
803 break;
804
805 default:
806 programming_error ("cprintf: bad `%%' argument (%c)", c);
807 }
808 }
809 if (argp)
810 {
811 the_printed_command_resize (arg_len + 1);
812 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
813 command_string_index += arg_len;
814 if (free_argp)
815 free (argp);
816 }
817 }
818
819 the_printed_command[command_string_index] = '\0';
820 }
821
822 #else /* We have support for varargs. */
823
824 /* How to make the string. */
825 static void
826 #if defined (PREFER_STDARG)
827 cprintf (char *control, ...)
828 #else
829 cprintf (control, va_alist)
830 char *control;
831 va_dcl
832 #endif
833 {
834 register char *s;
835 char char_arg[2], *argp;
836 int digit_arg, arg_len, c;
837 va_list args;
838
839 #if defined (PREFER_STDARG)
840 va_start (args, control);
841 #else
842 va_start (args);
843 #endif
844
845 arg_len = strlen (control);
846 the_printed_command_resize (arg_len + 1);
847
848 char_arg[1] = '\0';
849 s = control;
850 while (s && *s)
851 {
852 int free_argp;
853 free_argp = 0;
854 c = *s++;
855 argp = (char *)NULL;
856 if (c != '%' || !*s)
857 {
858 argp = s - 1;
859 arg_len = 1;
860 }
861 else
862 {
863 c = *s++;
864 switch (c)
865 {
866 case '%':
867 char_arg[0] = c;
868 argp = char_arg;
869 arg_len = 1;
870 break;
871
872 case 's':
873 argp = va_arg (args, char *);
874 arg_len = strlen (argp);
875 break;
876
877 case 'd':
878 digit_arg = va_arg (args, int);
879 argp = itos (digit_arg);
880 arg_len = strlen (argp);
881 free_argp = 1;
882 break;
883
884 case 'c':
885 char_arg[0] = va_arg (args, int);
886 argp = char_arg;
887 arg_len = 1;
888 break;
889
890 default:
891 programming_error ("cprintf: bad `%%' argument (%c)", c);
892 /*NOTREACHED*/
893 }
894 }
895
896 if (argp && arg_len)
897 {
898 the_printed_command_resize (arg_len + 1);
899 FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
900 command_string_index += arg_len;
901 if (free_argp)
902 free (argp);
903 }
904 }
905
906 the_printed_command[command_string_index] = '\0';
907 }
908 #endif /* HAVE_VARARGS_H */
909
910 /* Ensure that there is enough space to stuff LENGTH characters into
911 THE_PRINTED_COMMAND. */
912 static void
913 the_printed_command_resize (length)
914 int length;
915 {
916 if (the_printed_command == 0)
917 {
918 the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
919 the_printed_command = xmalloc (the_printed_command_size);
920 command_string_index = 0;
921 }
922 else if ((command_string_index + length) >= the_printed_command_size)
923 {
924 int new;
925 new = command_string_index + length + 1;
926 #if 1
927 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
928 new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
929 #else
930 new = new + 2 * PRINTED_COMMAND_GROW_SIZE - 1;
931 new -= new % PRINTED_COMMAND_GROW_SIZE;
932 #endif
933 the_printed_command_size = new;
934 the_printed_command = xrealloc (the_printed_command, the_printed_command_size);
935 }
936 }
937
938 #if defined (HAVE_VFPRINTF)
939
940 static void
941 #if defined (PREFER_STDARG)
942 xprintf (const char *format, ...)
943 #else
944 xprintf (format, va_alist)
945 const char *format;
946 va_dcl
947 #endif
948 {
949 va_list args;
950
951 #if defined (PREFER_STDARG)
952 va_start (args, format);
953 #else
954 va_start (args);
955 #endif
956
957 vfprintf (stdout, format, args);
958 va_end (args);
959 }
960
961 #else
962
963 static void
964 xprintf (format, arg1, arg2, arg3, arg4, arg5)
965 char *format;
966 {
967 printf (format, arg1, arg2, arg3, arg4, arg5);
968 }
969
970 #endif /* !HAVE_VFPRINTF */