1 /* printf - format and print data
2 Copyright (C) 1990-2015 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Usage: printf format [argument...]
19 A front end to the printf function that lets it be used from the shell.
27 \c = produce no further output
34 \ooo = octal number (ooo is 1 to 3 digits)
35 \xhh = hexadecimal number (hhh is 1 to 2 digits)
36 \uhhhh = 16-bit Unicode character (hhhh is 4 digits)
37 \Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits)
41 %b = print an argument string, interpreting backslash escapes,
42 except that octal escapes are of the form \0 or \0ooo.
44 %q = print an argument string in a format that can be
45 reused as shell input. Escaped characters used the proposed
46 POSIX $'' syntax supported by most shells.
48 The 'format' argument is re-used as many times as necessary
49 to convert all of the given arguments.
51 David MacKenzie <djm@gnu.ai.mit.edu> */
55 #include <sys/types.h>
61 #include "unicodeio.h"
64 /* The official name of this program (e.g., no 'g' prefix). */
65 #define PROGRAM_NAME "printf"
67 #define AUTHORS proper_name ("David MacKenzie")
69 #define isodigit(c) ((c) >= '0' && (c) <= '7')
70 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
71 (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
72 #define octtobin(c) ((c) - '0')
74 /* The value to return to the calling program. */
75 static int exit_status
;
77 /* True if the POSIXLY_CORRECT environment variable is set. */
78 static bool posixly_correct
;
80 /* This message appears in N_() here rather than just in _() below because
81 the sole use would have been in a #define. */
82 static char const *const cfcc_msg
=
83 N_("warning: %s: character(s) following character constant have been ignored");
88 if (status
!= EXIT_SUCCESS
)
93 Usage: %s FORMAT [ARGUMENT]...\n\
96 program_name
, program_name
);
98 Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:\n\
101 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
102 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
105 FORMAT controls the output as in C printf. Interpreted sequences are:\n\
113 \\c produce no further output\n\
117 \\r carriage return\n\
118 \\t horizontal tab\n\
122 \\NNN byte with octal value NNN (1 to 3 digits)\n\
123 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
124 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
125 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
129 %b ARGUMENT as a string with '\\' escapes interpreted,\n\
130 except that octal escapes are of the form \\0 or \\0NNN\n\
131 %q ARGUMENT is printed in a format that can be reused as shell input,\n\
132 escaping non-printable characters with the proposed POSIX $'' syntax.\
134 and all C format specifications ending with one of diouxXfeEgGcs, with\n\
135 ARGUMENTs converted to proper type first. Variable widths are handled.\n\
137 printf (USAGE_BUILTIN_WARNING
, PROGRAM_NAME
);
138 emit_ancillary_info (PROGRAM_NAME
);
144 verify_numeric (const char *s
, const char *end
)
148 error (0, errno
, "%s", quote (s
));
149 exit_status
= EXIT_FAILURE
;
154 error (0, 0, _("%s: expected a numeric value"), quote (s
));
156 error (0, 0, _("%s: value not completely converted"), quote (s
));
157 exit_status
= EXIT_FAILURE
;
161 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
163 FUNC_NAME (char const *s) \
168 if ((*s == '\"' || *s == '\'') && *(s + 1)) \
170 unsigned char ch = *++s; \
172 /* If POSIXLY_CORRECT is not set, then give a warning that there \
173 are characters following the character constant and that GNU \
174 printf is ignoring those characters. If POSIXLY_CORRECT *is* \
175 set, then don't give the warning. */ \
176 if (*++s != 0 && !posixly_correct) \
177 error (0, 0, _(cfcc_msg), s); \
182 val = (LIB_FUNC_EXPR); \
183 verify_numeric (s, end); \
188 STRTOX (intmax_t, vstrtoimax, strtoimax (s, &end, 0))
189 STRTOX (uintmax_t, vstrtoumax
, strtoumax (s
, &end
, 0))
190 STRTOX (long double, vstrtold
, c_strtold (s
, &end
))
192 /* Output a single-character \ escape. */
195 print_esc_char (char c
)
199 case 'a': /* Alert. */
202 case 'b': /* Backspace. */
205 case 'c': /* Cancel the rest of the output. */
208 case 'e': /* Escape. */
211 case 'f': /* Form feed. */
214 case 'n': /* New line. */
217 case 'r': /* Carriage return. */
220 case 't': /* Horizontal tab. */
223 case 'v': /* Vertical tab. */
232 /* Print a \ escape sequence starting at ESCSTART.
233 Return the number of characters in the escape sequence
234 besides the backslash.
235 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
236 is an octal digit; otherwise they are of the form \ooo. */
239 print_esc (const char *escstart
, bool octal_0
)
241 const char *p
= escstart
+ 1;
242 int esc_value
= 0; /* Value of \nnn escape. */
243 int esc_length
; /* Length of \nnn escape. */
247 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
248 for (esc_length
= 0, ++p
;
249 esc_length
< 2 && isxdigit (to_uchar (*p
));
251 esc_value
= esc_value
* 16 + hextobin (*p
);
253 error (EXIT_FAILURE
, 0, _("missing hexadecimal number in escape"));
256 else if (isodigit (*p
))
258 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
259 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
260 extension to POSIX that is compatible with Bash 2.05b. */
261 for (esc_length
= 0, p
+= octal_0
&& *p
== '0';
262 esc_length
< 3 && isodigit (*p
);
264 esc_value
= esc_value
* 8 + octtobin (*p
);
267 else if (*p
&& strchr ("\"\\abcefnrtv", *p
))
268 print_esc_char (*p
++);
269 else if (*p
== 'u' || *p
== 'U')
272 unsigned int uni_value
;
275 for (esc_length
= (esc_char
== 'u' ? 4 : 8), ++p
;
279 if (! isxdigit (to_uchar (*p
)))
280 error (EXIT_FAILURE
, 0, _("missing hexadecimal number in escape"));
281 uni_value
= uni_value
* 16 + hextobin (*p
);
284 /* A universal character name shall not specify a character short
285 identifier in the range 00000000 through 00000020, 0000007F through
286 0000009F, or 0000D800 through 0000DFFF inclusive. A universal
287 character name shall not designate a character in the required
289 if ((uni_value
<= 0x9f
290 && uni_value
!= 0x24 && uni_value
!= 0x40 && uni_value
!= 0x60)
291 || (uni_value
>= 0xd800 && uni_value
<= 0xdfff))
292 error (EXIT_FAILURE
, 0, _("invalid universal character name \\%c%0*x"),
293 esc_char
, (esc_char
== 'u' ? 4 : 8), uni_value
);
295 print_unicode_char (stdout
, uni_value
, 0);
306 return p
- escstart
- 1;
309 /* Print string STR, evaluating \ escapes. */
312 print_esc_string (const char *str
)
316 str
+= print_esc (str
, true);
321 /* Evaluate a printf conversion specification. START is the start of
322 the directive, LENGTH is its length, and CONVERSION specifies the
323 type of conversion. LENGTH does not include any length modifier or
324 the conversion specifier itself. FIELD_WIDTH and PRECISION are the
325 field width and precision for '*' values, if HAVE_FIELD_WIDTH and
326 HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
330 print_direc (const char *start
, size_t length
, char conversion
,
331 bool have_field_width
, int field_width
,
332 bool have_precision
, int precision
,
333 char const *argument
)
335 char *p
; /* Null-terminated copy of % directive. */
337 /* Create a null-terminated copy of the % directive, with an
338 intmax_t-wide length modifier substituted for any existing
339 integer length modifier. */
342 char const *length_modifier
;
343 size_t length_modifier_len
;
347 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
348 length_modifier
= PRIdMAX
;
349 length_modifier_len
= sizeof PRIdMAX
- 2;
352 case 'a': case 'e': case 'f': case 'g':
353 case 'A': case 'E': case 'F': case 'G':
354 length_modifier
= "L";
355 length_modifier_len
= 1;
359 length_modifier
= start
; /* Any valid pointer will do. */
360 length_modifier_len
= 0;
364 p
= xmalloc (length
+ length_modifier_len
+ 2);
365 q
= mempcpy (p
, start
, length
);
366 q
= mempcpy (q
, length_modifier
, length_modifier_len
);
376 intmax_t arg
= vstrtoimax (argument
);
377 if (!have_field_width
)
382 xprintf (p
, precision
, arg
);
387 xprintf (p
, field_width
, arg
);
389 xprintf (p
, field_width
, precision
, arg
);
399 uintmax_t arg
= vstrtoumax (argument
);
400 if (!have_field_width
)
405 xprintf (p
, precision
, arg
);
410 xprintf (p
, field_width
, arg
);
412 xprintf (p
, field_width
, precision
, arg
);
426 long double arg
= vstrtold (argument
);
427 if (!have_field_width
)
432 xprintf (p
, precision
, arg
);
437 xprintf (p
, field_width
, arg
);
439 xprintf (p
, field_width
, precision
, arg
);
445 if (!have_field_width
)
446 xprintf (p
, *argument
);
448 xprintf (p
, field_width
, *argument
);
452 if (!have_field_width
)
455 xprintf (p
, argument
);
457 xprintf (p
, precision
, argument
);
462 xprintf (p
, field_width
, argument
);
464 xprintf (p
, field_width
, precision
, argument
);
472 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
473 arguments to any '%' directives.
474 Return the number of elements of ARGV used. */
477 print_formatted (const char *format
, int argc
, char **argv
)
479 int save_argc
= argc
; /* Preserve original value. */
480 const char *f
; /* Pointer into 'format'. */
481 const char *direc_start
; /* Start of % directive. */
482 size_t direc_length
; /* Length of % directive. */
483 bool have_field_width
; /* True if FIELD_WIDTH is valid. */
484 int field_width
= 0; /* Arg to first '*'. */
485 bool have_precision
; /* True if PRECISION is valid. */
486 int precision
= 0; /* Arg to second '*'. */
487 char ok
[UCHAR_MAX
+ 1]; /* ok['x'] is true if %x is allowed. */
489 for (f
= format
; *f
; ++f
)
496 have_field_width
= have_precision
= false;
504 /* FIXME: Field width and precision are not supported
505 for %b, even though POSIX requires it. */
508 print_esc_string (*argv
);
519 fputs (quotearg_style (shell_escape_quoting_style
, *argv
),
527 memset (ok
, 0, sizeof ok
);
528 ok
['a'] = ok
['A'] = ok
['c'] = ok
['d'] = ok
['e'] = ok
['E'] =
529 ok
['f'] = ok
['F'] = ok
['g'] = ok
['G'] = ok
['i'] = ok
['o'] =
530 ok
['s'] = ok
['u'] = ok
['x'] = ok
['X'] = 1;
532 for (;; f
++, direc_length
++)
535 #if (__GLIBC__ == 2 && 2 <= __GLIBC_MINOR__) || 3 <= __GLIBC__
539 ok
['a'] = ok
['A'] = ok
['c'] = ok
['e'] = ok
['E'] =
540 ok
['o'] = ok
['s'] = ok
['x'] = ok
['X'] = 0;
542 case '-': case '+': case ' ':
545 ok
['c'] = ok
['d'] = ok
['i'] = ok
['s'] = ok
['u'] = 0;
548 ok
['c'] = ok
['s'] = 0;
551 goto no_more_flag_characters
;
553 no_more_flag_characters
:
561 intmax_t width
= vstrtoimax (*argv
);
562 if (INT_MIN
<= width
&& width
<= INT_MAX
)
565 error (EXIT_FAILURE
, 0, _("invalid field width: %s"),
572 have_field_width
= true;
591 intmax_t prec
= vstrtoimax (*argv
);
594 /* A negative precision is taken as if the
595 precision were omitted, so -1 is safe
596 here even if prec < INT_MIN. */
599 else if (INT_MAX
< prec
)
600 error (EXIT_FAILURE
, 0, _("invalid precision: %s"),
609 have_precision
= true;
619 while (*f
== 'l' || *f
== 'L' || *f
== 'h'
620 || *f
== 'j' || *f
== 't' || *f
== 'z')
624 unsigned char conversion
= *f
;
625 if (! ok
[conversion
])
626 error (EXIT_FAILURE
, 0,
627 _("%.*s: invalid conversion specification"),
628 (int) (f
+ 1 - direc_start
), direc_start
);
631 print_direc (direc_start
, direc_length
, *f
,
632 have_field_width
, field_width
,
633 have_precision
, precision
,
634 (argc
<= 0 ? "" : (argc
--, *argv
++)));
638 f
+= print_esc (f
, false);
646 return save_argc
- argc
;
650 main (int argc
, char **argv
)
655 initialize_main (&argc
, &argv
);
656 set_program_name (argv
[0]);
657 setlocale (LC_ALL
, "");
658 bindtextdomain (PACKAGE
, LOCALEDIR
);
659 textdomain (PACKAGE
);
661 atexit (close_stdout
);
663 exit_status
= EXIT_SUCCESS
;
665 posixly_correct
= (getenv ("POSIXLY_CORRECT") != NULL
);
667 /* We directly parse options, rather than use parse_long_options, in
668 order to avoid accepting abbreviations. */
671 if (STREQ (argv
[1], "--help"))
672 usage (EXIT_SUCCESS
);
674 if (STREQ (argv
[1], "--version"))
676 version_etc (stdout
, PROGRAM_NAME
, PACKAGE_NAME
, Version
, AUTHORS
,
682 /* The above handles --help and --version.
683 Since there is no other invocation of getopt, handle '--' here. */
684 if (1 < argc
&& STREQ (argv
[1], "--"))
692 error (0, 0, _("missing operand"));
693 usage (EXIT_FAILURE
);
702 args_used
= print_formatted (format
, argc
, argv
);
706 while (args_used
> 0 && argc
> 0);
710 _("warning: ignoring excess arguments, starting with %s"),