1 /* print_command -- A way to make readable commands from a command tree. */
3 /* Copyright (C) 1989-2004 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
25 #if defined (HAVE_UNISTD_H)
27 # include <sys/types.h>
32 #if defined (PREFER_STDARG)
43 #include <y.tab.h> /* use <...> so we pick it up from the build directory */
44 #include "builtins/common.h"
47 extern int printf
__P((const char *, ...)); /* Yuck. Double yuck. */
50 extern int indirection_level
;
52 static int indentation
;
53 static int indentation_amount
= 4;
55 #if defined (PREFER_STDARG)
56 typedef void PFUNC
__P((const char *, ...));
58 static void cprintf
__P((const char *, ...)) __attribute__((__format__ (printf
, 1, 2)));
59 static void xprintf
__P((const char *, ...)) __attribute__((__format__ (printf
, 1, 2)));
61 #define PFUNC VFunction
62 static void cprintf ();
63 static void xprintf ();
66 static void reset_locals
__P((void));
67 static void newline
__P((char *));
68 static void indent
__P((int));
69 static void semicolon
__P((void));
70 static void the_printed_command_resize
__P((int));
72 static void make_command_string_internal
__P((COMMAND
*));
73 static void _print_word_list
__P((WORD_LIST
*, char *, PFUNC
*));
74 static void command_print_word_list
__P((WORD_LIST
*, char *));
75 static void print_case_clauses
__P((PATTERN_LIST
*));
76 static void print_redirection_list
__P((REDIRECT
*));
77 static void print_redirection
__P((REDIRECT
*));
79 static void print_for_command
__P((FOR_COM
*));
80 #if defined (ARITH_FOR_COMMAND)
81 static void print_arith_for_command
__P((ARITH_FOR_COM
*));
83 #if defined (SELECT_COMMAND)
84 static void print_select_command
__P((SELECT_COM
*));
86 static void print_group_command
__P((GROUP_COM
*));
87 static void print_case_command
__P((CASE_COM
*));
88 static void print_while_command
__P((WHILE_COM
*));
89 static void print_until_command
__P((WHILE_COM
*));
90 static void print_until_or_while
__P((WHILE_COM
*, char *));
91 static void print_if_command
__P((IF_COM
*));
92 #if defined (COND_COMMAND)
93 static void print_cond_node
__P((COND_COM
*));
95 static void print_function_def
__P((FUNCTION_DEF
*));
97 #define PRINTED_COMMAND_INITIAL_SIZE 64
98 #define PRINTED_COMMAND_GROW_SIZE 128
100 char *the_printed_command
= (char *)NULL
;
101 int the_printed_command_size
= 0;
102 int command_string_index
= 0;
104 /* Non-zero means the stuff being printed is inside of a function def. */
105 static int inside_function_def
;
106 static int skip_this_indent
;
107 static int was_heredoc
;
109 /* The depth of the group commands that we are currently printing. This
110 includes the group command that is a function body. */
111 static int group_command_nesting
;
113 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
114 static char indirection_string
[100];
116 /* Print COMMAND (a command tree) on standard output. */
118 print_command (command
)
121 command_string_index
= 0;
122 printf ("%s", make_command_string (command
));
125 /* Make a string which is the printed representation of the command
126 tree in COMMAND. We return this string. However, the string is
127 not consed, so you have to do that yourself if you want it to
130 make_command_string (command
)
133 command_string_index
= was_heredoc
= 0;
134 make_command_string_internal (command
);
135 return (the_printed_command
);
138 /* The internal function. This is the real workhorse. */
140 make_command_string_internal (command
)
147 if (skip_this_indent
)
150 indent (indentation
);
152 if (command
->flags
& CMD_TIME_PIPELINE
)
155 if (command
->flags
& CMD_TIME_POSIX
)
159 if (command
->flags
& CMD_INVERT_RETURN
)
162 switch (command
->type
)
165 print_for_command (command
->value
.For
);
168 #if defined (ARITH_FOR_COMMAND)
170 print_arith_for_command (command
->value
.ArithFor
);
174 #if defined (SELECT_COMMAND)
176 print_select_command (command
->value
.Select
);
181 print_case_command (command
->value
.Case
);
185 print_while_command (command
->value
.While
);
189 print_until_command (command
->value
.While
);
193 print_if_command (command
->value
.If
);
196 #if defined (DPAREN_ARITHMETIC)
198 print_arith_command (command
->value
.Arith
->exp
);
202 #if defined (COND_COMMAND)
204 print_cond_command (command
->value
.Cond
);
209 print_simple_command (command
->value
.Simple
);
215 make_command_string_internal (command
->value
.Connection
->first
);
217 switch (command
->value
.Connection
->connector
)
222 char c
= command
->value
.Connection
->connector
;
224 if (c
!= '&' || command
->value
.Connection
->second
)
234 if (command
->value
.Connection
->second
)
240 if (command
->value
.Connection
->second
)
245 if (was_heredoc
== 0)
250 if (inside_function_def
)
255 if (command
->value
.Connection
->second
)
261 cprintf (_("print_command: bad connector `%d'"),
262 command
->value
.Connection
->connector
);
266 make_command_string_internal (command
->value
.Connection
->second
);
269 case cm_function_def
:
270 print_function_def (command
->value
.Function_def
);
274 print_group_command (command
->value
.Group
);
280 make_command_string_internal (command
->value
.Subshell
->command
);
285 command_error ("print_command", CMDERR_BADTYPE
, command
->type
, 0);
290 if (command
->redirects
)
293 print_redirection_list (command
->redirects
);
299 _print_word_list (list
, separator
, pfunc
)
306 for (w
= list
; w
; w
= w
->next
)
307 (*pfunc
) ("%s%s", w
->word
->word
, w
->next
? separator
: "");
311 print_word_list (list
, separator
)
315 _print_word_list (list
, separator
, xprintf
);
318 /* Return a string denoting what our indirection level is. */
321 indirection_level_string ()
326 indirection_string
[0] = '\0';
327 ps4
= get_string_value ("PS4");
329 if (ps4
== 0 || *ps4
== '\0')
330 return (indirection_string
);
332 change_flag ('x', FLAG_OFF
);
333 ps4
= decode_prompt_string (ps4
);
334 change_flag ('x', FLAG_ON
);
336 if (ps4
== 0 || *ps4
== '\0')
337 return (indirection_string
);
339 for (i
= 0; *ps4
&& i
< indirection_level
&& i
< 99; i
++)
340 indirection_string
[i
] = *ps4
;
342 for (j
= 1; *ps4
&& ps4
[j
] && i
< 99; i
++, j
++)
343 indirection_string
[i
] = ps4
[j
];
345 indirection_string
[i
] = '\0';
347 return (indirection_string
);
351 xtrace_print_assignment (name
, value
, assign_list
, xflags
)
353 int assign_list
, xflags
;
358 fprintf (stderr
, "%s", indirection_level_string ());
360 /* VALUE should not be NULL when this is called. */
361 if (*value
== '\0' || assign_list
)
363 else if (sh_contains_shell_metas (value
))
364 nval
= sh_single_quote (value
);
365 else if (ansic_shouldquote (value
))
366 nval
= ansic_quote (value
, 0, (int *)0);
371 fprintf (stderr
, "%s=(%s)\n", name
, nval
);
373 fprintf (stderr
, "%s=%s\n", name
, nval
);
381 /* A function to print the words of a simple command when set -x is on. */
383 xtrace_print_word_list (list
, xtflags
)
391 fprintf (stderr
, "%s", indirection_level_string ());
393 for (w
= list
; w
; w
= w
->next
)
396 if (t
== 0 || *t
== '\0')
397 fprintf (stderr
, "''%s", w
->next
? " " : "");
398 else if (sh_contains_shell_metas (t
))
400 x
= sh_single_quote (t
);
401 fprintf (stderr
, "%s%s", x
, w
->next
? " " : "");
404 else if (ansic_shouldquote (t
))
406 x
= ansic_quote (t
, 0, (int *)0);
407 fprintf (stderr
, "%s%s", x
, w
->next
? " " : "");
411 fprintf (stderr
, "%s%s", t
, w
->next
? " " : "");
413 fprintf (stderr
, "\n");
417 command_print_word_list (list
, separator
)
421 _print_word_list (list
, separator
, cprintf
);
425 print_for_command_head (for_command
)
426 FOR_COM
*for_command
;
428 cprintf ("for %s in ", for_command
->name
->word
);
429 command_print_word_list (for_command
->map_list
, " ");
433 xtrace_print_for_command_head (for_command
)
434 FOR_COM
*for_command
;
436 fprintf (stderr
, "%s", indirection_level_string ());
437 fprintf (stderr
, "for %s in ", for_command
->name
->word
);
438 xtrace_print_word_list (for_command
->map_list
, 0);
442 print_for_command (for_command
)
443 FOR_COM
*for_command
;
445 print_for_command_head (for_command
);
449 indentation
+= indentation_amount
;
450 make_command_string_internal (for_command
->action
);
452 indentation
-= indentation_amount
;
456 #if defined (ARITH_FOR_COMMAND)
458 print_arith_for_command (arith_for_command
)
459 ARITH_FOR_COM
*arith_for_command
;
462 command_print_word_list (arith_for_command
->init
, " ");
464 command_print_word_list (arith_for_command
->test
, " ");
466 command_print_word_list (arith_for_command
->step
, " ");
469 indentation
+= indentation_amount
;
470 make_command_string_internal (arith_for_command
->action
);
472 indentation
-= indentation_amount
;
475 #endif /* ARITH_FOR_COMMAND */
477 #if defined (SELECT_COMMAND)
479 print_select_command_head (select_command
)
480 SELECT_COM
*select_command
;
482 cprintf ("select %s in ", select_command
->name
->word
);
483 command_print_word_list (select_command
->map_list
, " ");
487 xtrace_print_select_command_head (select_command
)
488 SELECT_COM
*select_command
;
490 fprintf (stderr
, "%s", indirection_level_string ());
491 fprintf (stderr
, "select %s in ", select_command
->name
->word
);
492 xtrace_print_word_list (select_command
->map_list
, 0);
496 print_select_command (select_command
)
497 SELECT_COM
*select_command
;
499 print_select_command_head (select_command
);
503 indentation
+= indentation_amount
;
504 make_command_string_internal (select_command
->action
);
506 indentation
-= indentation_amount
;
509 #endif /* SELECT_COMMAND */
512 print_group_command (group_command
)
513 GROUP_COM
*group_command
;
515 group_command_nesting
++;
518 if (inside_function_def
== 0)
522 /* This is a group command { ... } inside of a function
523 definition, and should be printed as a multiline group
524 command, using the current indentation. */
526 indentation
+= indentation_amount
;
529 make_command_string_internal (group_command
->command
);
531 if (inside_function_def
)
534 indentation
-= indentation_amount
;
535 indent (indentation
);
545 group_command_nesting
--;
549 print_case_command_head (case_command
)
550 CASE_COM
*case_command
;
552 cprintf ("case %s in ", case_command
->word
->word
);
556 xtrace_print_case_command_head (case_command
)
557 CASE_COM
*case_command
;
559 fprintf (stderr
, "%s", indirection_level_string ());
560 fprintf (stderr
, "case %s in\n", case_command
->word
->word
);
564 print_case_command (case_command
)
565 CASE_COM
*case_command
;
567 print_case_command_head (case_command
);
569 if (case_command
->clauses
)
570 print_case_clauses (case_command
->clauses
);
575 print_case_clauses (clauses
)
576 PATTERN_LIST
*clauses
;
578 indentation
+= indentation_amount
;
582 command_print_word_list (clauses
->patterns
, " | ");
584 indentation
+= indentation_amount
;
585 make_command_string_internal (clauses
->action
);
586 indentation
-= indentation_amount
;
588 clauses
= clauses
->next
;
590 indentation
-= indentation_amount
;
594 print_while_command (while_command
)
595 WHILE_COM
*while_command
;
597 print_until_or_while (while_command
, "while");
601 print_until_command (while_command
)
602 WHILE_COM
*while_command
;
604 print_until_or_while (while_command
, "until");
608 print_until_or_while (while_command
, which
)
609 WHILE_COM
*while_command
;
612 cprintf ("%s ", which
);
614 make_command_string_internal (while_command
->test
);
616 cprintf (" do\n"); /* was newline ("do\n"); */
617 indentation
+= indentation_amount
;
618 make_command_string_internal (while_command
->action
);
619 indentation
-= indentation_amount
;
625 print_if_command (if_command
)
630 make_command_string_internal (if_command
->test
);
633 indentation
+= indentation_amount
;
634 make_command_string_internal (if_command
->true_case
);
635 indentation
-= indentation_amount
;
637 if (if_command
->false_case
)
641 indentation
+= indentation_amount
;
642 make_command_string_internal (if_command
->false_case
);
643 indentation
-= indentation_amount
;
649 #if defined (DPAREN_ARITHMETIC)
651 print_arith_command (arith_cmd_list
)
652 WORD_LIST
*arith_cmd_list
;
655 command_print_word_list (arith_cmd_list
, " ");
660 #if defined (COND_COMMAND)
662 print_cond_node (cond
)
665 if (cond
->flags
& CMD_INVERT_RETURN
)
668 if (cond
->type
== COND_EXPR
)
671 print_cond_node (cond
->left
);
674 else if (cond
->type
== COND_AND
)
676 print_cond_node (cond
->left
);
678 print_cond_node (cond
->right
);
680 else if (cond
->type
== COND_OR
)
682 print_cond_node (cond
->left
);
684 print_cond_node (cond
->right
);
686 else if (cond
->type
== COND_UNARY
)
688 cprintf ("%s", cond
->op
->word
);
690 print_cond_node (cond
->left
);
692 else if (cond
->type
== COND_BINARY
)
694 print_cond_node (cond
->left
);
696 cprintf ("%s", cond
->op
->word
);
698 print_cond_node (cond
->right
);
700 else if (cond
->type
== COND_TERM
)
702 cprintf ("%s", cond
->op
->word
); /* need to add quoting here */
707 print_cond_command (cond
)
711 print_cond_node (cond
);
717 debug_print_cond_command (cond
)
720 fprintf (stderr
, "DEBUG: ");
721 command_string_index
= 0;
722 print_cond_command (cond
);
723 fprintf (stderr
, "%s\n", the_printed_command
);
728 xtrace_print_cond_term (type
, invert
, op
, arg1
, arg2
)
733 command_string_index
= 0;
734 fprintf (stderr
, "%s", indirection_level_string ());
735 fprintf (stderr
, "[[ ");
737 fprintf (stderr
, "! ");
739 if (type
== COND_UNARY
)
741 fprintf (stderr
, "%s ", op
->word
);
742 fprintf (stderr
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
744 else if (type
== COND_BINARY
)
746 fprintf (stderr
, "%s", (arg1
&& *arg1
) ? arg1
: "''");
747 fprintf (stderr
, " %s ", op
->word
);
748 fprintf (stderr
, "%s", (arg2
&& *arg2
) ? arg2
: "''");
751 fprintf (stderr
, " ]]\n");
753 #endif /* COND_COMMAND */
755 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
756 /* A function to print the words of an arithmetic command when set -x is on. */
758 xtrace_print_arith_cmd (list
)
763 fprintf (stderr
, "%s", indirection_level_string ());
764 fprintf (stderr
, "(( ");
765 for (w
= list
; w
; w
= w
->next
)
766 fprintf (stderr
, "%s%s", w
->word
->word
, w
->next
? " " : "");
767 fprintf (stderr
, " ))\n");
772 print_simple_command (simple_command
)
773 SIMPLE_COM
*simple_command
;
775 command_print_word_list (simple_command
->words
, " ");
777 if (simple_command
->redirects
)
780 print_redirection_list (simple_command
->redirects
);
785 print_redirection_list (redirects
)
788 REDIRECT
*heredocs
, *hdtail
, *newredir
;
790 heredocs
= (REDIRECT
*)NULL
;
796 /* Defer printing the here documents until we've printed the
797 rest of the redirections. */
798 if (redirects
->instruction
== r_reading_until
|| redirects
->instruction
== r_deblank_reading_until
)
800 newredir
= copy_redirect (redirects
);
801 newredir
->next
= (REDIRECT
*)NULL
;
804 hdtail
->next
= newredir
;
808 hdtail
= heredocs
= newredir
;
810 else if (redirects
->instruction
== r_duplicating_output_word
&& redirects
->redirector
== 1)
812 /* Temporarily translate it as the execution code does. */
813 redirects
->instruction
= r_err_and_out
;
814 print_redirection (redirects
);
815 redirects
->instruction
= r_duplicating_output_word
;
818 print_redirection (redirects
);
820 redirects
= redirects
->next
;
825 /* Now that we've printed all the other redirections (on one line),
826 print the here documents. */
830 for (hdtail
= heredocs
; hdtail
; hdtail
= hdtail
->next
)
832 print_redirection (hdtail
);
835 dispose_redirects (heredocs
);
841 print_redirection (redirect
)
844 int kill_leading
, redirector
, redir_fd
;
845 WORD_DESC
*redirectee
;
848 redirectee
= redirect
->redirectee
.filename
;
849 redirector
= redirect
->redirector
;
850 redir_fd
= redirect
->redirectee
.dest
;
852 switch (redirect
->instruction
)
854 case r_output_direction
:
856 cprintf ("%d", redirector
);
857 cprintf (">%s", redirectee
->word
);
860 case r_input_direction
:
862 cprintf ("%d", redirector
);
863 cprintf ("<%s", redirectee
->word
);
866 case r_inputa_direction
: /* Redirection created by the shell. */
872 cprintf ("%d", redirector
);
873 cprintf (">>%s", redirectee
->word
);
876 case r_deblank_reading_until
:
879 case r_reading_until
:
881 cprintf ("%d", redirector
);
882 /* If the here document delimiter is quoted, single-quote it. */
883 if (redirect
->redirectee
.filename
->flags
& W_QUOTED
)
886 x
= sh_single_quote (redirect
->here_doc_eof
);
887 cprintf ("<<%s%s\n", kill_leading
? "-" : "", x
);
891 cprintf ("<<%s%s\n", kill_leading
? "-" : "", redirect
->here_doc_eof
);
893 redirect
->redirectee
.filename
->word
, redirect
->here_doc_eof
);
896 case r_reading_string
:
898 cprintf ("%d", redirector
);
899 if (ansic_shouldquote (redirect
->redirectee
.filename
->word
))
902 x
= ansic_quote (redirect
->redirectee
.filename
->word
, 0, (int *)0);
903 cprintf ("<<< %s", x
);
907 cprintf ("<<< %s", redirect
->redirectee
.filename
->word
);
910 case r_duplicating_input
:
911 cprintf ("%d<&%d", redirector
, redir_fd
);
914 case r_duplicating_output
:
915 cprintf ("%d>&%d", redirector
, redir_fd
);
918 case r_duplicating_input_word
:
919 cprintf ("%d<&%s", redirector
, redirectee
->word
);
922 case r_duplicating_output_word
:
923 cprintf ("%d>&%s", redirector
, redirectee
->word
);
927 cprintf ("%d<&%d-", redirector
, redir_fd
);
931 cprintf ("%d>&%d-", redirector
, redir_fd
);
934 case r_move_input_word
:
935 cprintf ("%d<&%s-", redirector
, redirectee
->word
);
938 case r_move_output_word
:
939 cprintf ("%d>&%s-", redirector
, redirectee
->word
);
943 cprintf ("%d>&-", redirector
);
947 cprintf (">&%s", redirectee
->word
);
952 cprintf ("%d", redirector
);
953 cprintf ("<>%s", redirectee
->word
);
958 cprintf ("%d", redirector
);
959 cprintf (">|%s", redirectee
->word
);
967 inside_function_def
= 0;
972 print_function_def (func
)
976 REDIRECT
*func_redirects
;
978 func_redirects
= NULL
;
979 cprintf ("function %s () \n", func
->name
->word
);
980 add_unwind_protect (reset_locals
, 0);
982 indent (indentation
);
985 inside_function_def
++;
986 indentation
+= indentation_amount
;
988 cmdcopy
= copy_command (func
->command
);
989 if (cmdcopy
->type
== cm_group
)
991 func_redirects
= cmdcopy
->redirects
;
992 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
994 make_command_string_internal (cmdcopy
->type
== cm_group
995 ? cmdcopy
->value
.Group
->command
998 remove_unwind_protect ();
999 indentation
-= indentation_amount
;
1000 inside_function_def
--;
1005 print_redirection_list (func_redirects
);
1006 cmdcopy
->redirects
= func_redirects
;
1011 dispose_command (cmdcopy
);
1014 /* Return the string representation of the named function.
1015 NAME is the name of the function.
1016 COMMAND is the function body. It should be a GROUP_COM.
1017 MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
1020 named_function_string (name
, command
, multi_line
)
1026 int old_indent
, old_amount
;
1028 REDIRECT
*func_redirects
;
1030 old_indent
= indentation
;
1031 old_amount
= indentation_amount
;
1032 command_string_index
= was_heredoc
= 0;
1035 cprintf ("%s ", name
);
1039 if (multi_line
== 0)
1042 indentation_amount
= 0;
1047 indentation
+= indentation_amount
;
1050 inside_function_def
++;
1052 cprintf (multi_line
? "{ \n" : "{ ");
1054 cmdcopy
= copy_command (command
);
1055 /* Take any redirections specified in the function definition (which should
1056 apply to the function as a whole) and save them for printing later. */
1057 func_redirects
= (REDIRECT
*)NULL
;
1058 if (cmdcopy
->type
== cm_group
)
1060 func_redirects
= cmdcopy
->redirects
;
1061 cmdcopy
->redirects
= (REDIRECT
*)NULL
;
1063 make_command_string_internal (cmdcopy
->type
== cm_group
1064 ? cmdcopy
->value
.Group
->command
1067 indentation
= old_indent
;
1068 indentation_amount
= old_amount
;
1069 inside_function_def
--;
1074 print_redirection_list (func_redirects
);
1075 cmdcopy
->redirects
= func_redirects
;
1080 result
= the_printed_command
;
1086 for (i
= 0; result
[i
]; i
++)
1087 if (result
[i
] == '\n')
1089 strcpy (result
+ i
, result
+ i
+ 1);
1093 if (result
[2] == '\n') /* XXX -- experimental */
1094 strcpy (result
+ 2, result
+ 3);
1098 dispose_command (cmdcopy
);
1108 indent (indentation
);
1109 if (string
&& *string
)
1110 cprintf ("%s", string
);
1113 static char *indentation_string
;
1114 static int indentation_size
;
1122 RESIZE_MALLOCED_BUFFER (indentation_string
, 0, amount
, indentation_size
, 16);
1124 for (i
= 0; amount
> 0; amount
--)
1125 indentation_string
[i
++] = ' ';
1126 indentation_string
[i
] = '\0';
1127 cprintf (indentation_string
);
1133 if (command_string_index
> 0 &&
1134 (the_printed_command
[command_string_index
- 1] == '&' ||
1135 the_printed_command
[command_string_index
- 1] == '\n'))
1140 /* How to make the string. */
1142 #if defined (PREFER_STDARG)
1143 cprintf (const char *control
, ...)
1145 cprintf (control
, va_alist
)
1146 const char *control
;
1150 register const char *s
;
1151 char char_arg
[2], *argp
, intbuf
[INT_STRLEN_BOUND (int) + 1];
1152 int digit_arg
, arg_len
, c
;
1155 SH_VA_START (args
, control
);
1157 arg_len
= strlen (control
);
1158 the_printed_command_resize (arg_len
+ 1);
1165 argp
= (char *)NULL
;
1166 if (c
!= '%' || !*s
)
1184 argp
= va_arg (args
, char *);
1185 arg_len
= strlen (argp
);
1189 /* Represent an out-of-range file descriptor with an out-of-range
1190 integer value. We can do this because the only use of `%d' in
1191 the calls to cprintf is to output a file descriptor number for
1193 digit_arg
= va_arg (args
, int);
1196 sprintf (intbuf
, "%u", (unsigned)-1);
1200 argp
= inttostr (digit_arg
, intbuf
, sizeof (intbuf
));
1201 arg_len
= strlen (argp
);
1205 char_arg
[0] = va_arg (args
, int);
1211 programming_error (_("cprintf: `%c': invalid format character"), c
);
1216 if (argp
&& arg_len
)
1218 the_printed_command_resize (arg_len
+ 1);
1219 FASTCOPY (argp
, the_printed_command
+ command_string_index
, arg_len
);
1220 command_string_index
+= arg_len
;
1224 the_printed_command
[command_string_index
] = '\0';
1227 /* Ensure that there is enough space to stuff LENGTH characters into
1228 THE_PRINTED_COMMAND. */
1230 the_printed_command_resize (length
)
1233 if (the_printed_command
== 0)
1235 the_printed_command_size
= (length
+ PRINTED_COMMAND_INITIAL_SIZE
- 1) & ~(PRINTED_COMMAND_INITIAL_SIZE
- 1);
1236 the_printed_command
= (char *)xmalloc (the_printed_command_size
);
1237 command_string_index
= 0;
1239 else if ((command_string_index
+ length
) >= the_printed_command_size
)
1242 new = command_string_index
+ length
+ 1;
1244 /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
1245 new = (new + PRINTED_COMMAND_GROW_SIZE
- 1) & ~(PRINTED_COMMAND_GROW_SIZE
- 1);
1246 the_printed_command_size
= new;
1248 the_printed_command
= (char *)xrealloc (the_printed_command
, the_printed_command_size
);
1252 #if defined (HAVE_VPRINTF)
1253 /* ``If vprintf is available, you may assume that vfprintf and vsprintf are
1254 also available.'' */
1257 #if defined (PREFER_STDARG)
1258 xprintf (const char *format
, ...)
1260 xprintf (format
, va_alist
)
1267 SH_VA_START (args
, format
);
1269 vfprintf (stdout
, format
, args
);
1276 xprintf (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1279 printf (format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1282 #endif /* !HAVE_VPRINTF */