dd: synchronize output after write errors
[coreutils.git] / src / printf.c
blob5f84475fdcc6b55ee5e7184d9c0b07b9b26425e3
1 /* printf - format and print data
2 Copyright (C) 1990-2022 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 <https://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.
21 Backslash escapes:
23 \" = double quote
24 \\ = backslash
25 \a = alert (bell)
26 \b = backspace
27 \c = produce no further output
28 \e = escape
29 \f = form feed
30 \n = new line
31 \r = carriage return
32 \t = horizontal tab
33 \v = vertical tab
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)
39 Additional directive:
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> */
53 #include <config.h>
54 #include <stdio.h>
55 #include <sys/types.h>
57 #include "system.h"
58 #include "cl-strtod.h"
59 #include "die.h"
60 #include "error.h"
61 #include "quote.h"
62 #include "unicodeio.h"
63 #include "xprintf.h"
65 /* The official name of this program (e.g., no 'g' prefix). */
66 #define PROGRAM_NAME "printf"
68 #define AUTHORS proper_name ("David MacKenzie")
70 #define isodigit(c) ((c) >= '0' && (c) <= '7')
71 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
72 (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
73 #define octtobin(c) ((c) - '0')
75 /* The value to return to the calling program. */
76 static int exit_status;
78 /* True if the POSIXLY_CORRECT environment variable is set. */
79 static bool posixly_correct;
81 /* This message appears in N_() here rather than just in _() below because
82 the sole use would have been in a #define. */
83 static char const *const cfcc_msg =
84 N_("warning: %s: character(s) following character constant have been ignored");
86 void
87 usage (int status)
89 if (status != EXIT_SUCCESS)
90 emit_try_help ();
91 else
93 printf (_("\
94 Usage: %s FORMAT [ARGUMENT]...\n\
95 or: %s OPTION\n\
96 "),
97 program_name, program_name);
98 fputs (_("\
99 Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:\n\
101 "), stdout);
102 fputs (HELP_OPTION_DESCRIPTION, stdout);
103 fputs (VERSION_OPTION_DESCRIPTION, stdout);
104 fputs (_("\
106 FORMAT controls the output as in C printf. Interpreted sequences are:\n\
108 \\\" double quote\n\
109 "), stdout);
110 fputs (_("\
111 \\\\ backslash\n\
112 \\a alert (BEL)\n\
113 \\b backspace\n\
114 \\c produce no further output\n\
115 \\e escape\n\
116 \\f form feed\n\
117 \\n new line\n\
118 \\r carriage return\n\
119 \\t horizontal tab\n\
120 \\v vertical tab\n\
121 "), stdout);
122 fputs (_("\
123 \\NNN byte with octal value NNN (1 to 3 digits)\n\
124 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
125 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
126 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
127 "), stdout);
128 fputs (_("\
129 %% a single %\n\
130 %b ARGUMENT as a string with '\\' escapes interpreted,\n\
131 except that octal escapes are of the form \\0 or \\0NNN\n\
132 %q ARGUMENT is printed in a format that can be reused as shell input,\n\
133 escaping non-printable characters with the proposed POSIX $'' syntax.\
134 \n\n\
135 and all C format specifications ending with one of diouxXfeEgGcs, with\n\
136 ARGUMENTs converted to proper type first. Variable widths are handled.\n\
137 "), stdout);
138 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
139 emit_ancillary_info (PROGRAM_NAME);
141 exit (status);
144 static void
145 verify_numeric (char const *s, char const *end)
147 if (errno)
149 error (0, errno, "%s", quote (s));
150 exit_status = EXIT_FAILURE;
152 else if (*end)
154 if (s == end)
155 error (0, 0, _("%s: expected a numeric value"), quote (s));
156 else
157 error (0, 0, _("%s: value not completely converted"), quote (s));
158 exit_status = EXIT_FAILURE;
162 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
163 static TYPE \
164 FUNC_NAME (char const *s) \
166 char *end; \
167 TYPE val; \
169 if ((*s == '\"' || *s == '\'') && *(s + 1)) \
171 unsigned char ch = *++s; \
172 val = ch; \
173 /* If POSIXLY_CORRECT is not set, then give a warning that there \
174 are characters following the character constant and that GNU \
175 printf is ignoring those characters. If POSIXLY_CORRECT *is* \
176 set, then don't give the warning. */ \
177 if (*++s != 0 && !posixly_correct) \
178 error (0, 0, _(cfcc_msg), s); \
180 else \
182 errno = 0; \
183 val = (LIB_FUNC_EXPR); \
184 verify_numeric (s, end); \
186 return val; \
189 STRTOX (intmax_t, vstrtoimax, strtoimax (s, &end, 0))
190 STRTOX (uintmax_t, vstrtoumax, strtoumax (s, &end, 0))
191 STRTOX (long double, vstrtold, cl_strtold (s, &end))
193 /* Output a single-character \ escape. */
195 static void
196 print_esc_char (char c)
198 switch (c)
200 case 'a': /* Alert. */
201 putchar ('\a');
202 break;
203 case 'b': /* Backspace. */
204 putchar ('\b');
205 break;
206 case 'c': /* Cancel the rest of the output. */
207 exit (EXIT_SUCCESS);
208 break;
209 case 'e': /* Escape. */
210 putchar ('\x1B');
211 break;
212 case 'f': /* Form feed. */
213 putchar ('\f');
214 break;
215 case 'n': /* New line. */
216 putchar ('\n');
217 break;
218 case 'r': /* Carriage return. */
219 putchar ('\r');
220 break;
221 case 't': /* Horizontal tab. */
222 putchar ('\t');
223 break;
224 case 'v': /* Vertical tab. */
225 putchar ('\v');
226 break;
227 default:
228 putchar (c);
229 break;
233 /* Print a \ escape sequence starting at ESCSTART.
234 Return the number of characters in the escape sequence
235 besides the backslash.
236 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
237 is an octal digit; otherwise they are of the form \ooo. */
239 static int
240 print_esc (char const *escstart, bool octal_0)
242 char const *p = escstart + 1;
243 int esc_value = 0; /* Value of \nnn escape. */
244 int esc_length; /* Length of \nnn escape. */
246 if (*p == 'x')
248 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
249 for (esc_length = 0, ++p;
250 esc_length < 2 && isxdigit (to_uchar (*p));
251 ++esc_length, ++p)
252 esc_value = esc_value * 16 + hextobin (*p);
253 if (esc_length == 0)
254 die (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
255 putchar (esc_value);
257 else if (isodigit (*p))
259 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
260 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
261 extension to POSIX that is compatible with Bash 2.05b. */
262 for (esc_length = 0, p += octal_0 && *p == '0';
263 esc_length < 3 && isodigit (*p);
264 ++esc_length, ++p)
265 esc_value = esc_value * 8 + octtobin (*p);
266 putchar (esc_value);
268 else if (*p && strchr ("\"\\abcefnrtv", *p))
269 print_esc_char (*p++);
270 else if (*p == 'u' || *p == 'U')
272 char esc_char = *p;
273 unsigned int uni_value;
275 uni_value = 0;
276 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
277 esc_length > 0;
278 --esc_length, ++p)
280 if (! isxdigit (to_uchar (*p)))
281 die (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
282 uni_value = uni_value * 16 + hextobin (*p);
285 /* A universal character name shall not specify a character short
286 identifier in the range 00000000 through 00000020, 0000007F through
287 0000009F, or 0000D800 through 0000DFFF inclusive. A universal
288 character name shall not designate a character in the required
289 character set. */
290 if ((uni_value <= 0x9f
291 && uni_value != 0x24 && uni_value != 0x40 && uni_value != 0x60)
292 || (uni_value >= 0xd800 && uni_value <= 0xdfff))
293 die (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"),
294 esc_char, (esc_char == 'u' ? 4 : 8), uni_value);
296 print_unicode_char (stdout, uni_value, 0);
298 else
300 putchar ('\\');
301 if (*p)
303 putchar (*p);
304 p++;
307 return p - escstart - 1;
310 /* Print string STR, evaluating \ escapes. */
312 static void
313 print_esc_string (char const *str)
315 for (; *str; str++)
316 if (*str == '\\')
317 str += print_esc (str, true);
318 else
319 putchar (*str);
322 /* Evaluate a printf conversion specification. START is the start of
323 the directive, LENGTH is its length, and CONVERSION specifies the
324 type of conversion. LENGTH does not include any length modifier or
325 the conversion specifier itself. FIELD_WIDTH and PRECISION are the
326 field width and precision for '*' values, if HAVE_FIELD_WIDTH and
327 HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
328 be formatted. */
330 static void
331 print_direc (char const *start, size_t length, char conversion,
332 bool have_field_width, int field_width,
333 bool have_precision, int precision,
334 char const *argument)
336 char *p; /* Null-terminated copy of % directive. */
338 /* Create a null-terminated copy of the % directive, with an
339 intmax_t-wide length modifier substituted for any existing
340 integer length modifier. */
342 char *q;
343 char const *length_modifier;
344 size_t length_modifier_len;
346 switch (conversion)
348 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
349 length_modifier = PRIdMAX;
350 length_modifier_len = sizeof PRIdMAX - 2;
351 break;
353 case 'a': case 'e': case 'f': case 'g':
354 case 'A': case 'E': case 'F': case 'G':
355 length_modifier = "L";
356 length_modifier_len = 1;
357 break;
359 default:
360 length_modifier = start; /* Any valid pointer will do. */
361 length_modifier_len = 0;
362 break;
365 p = xmalloc (length + length_modifier_len + 2);
366 q = mempcpy (p, start, length);
367 q = mempcpy (q, length_modifier, length_modifier_len);
368 *q++ = conversion;
369 *q = '\0';
372 switch (conversion)
374 case 'd':
375 case 'i':
377 intmax_t arg = vstrtoimax (argument);
378 if (!have_field_width)
380 if (!have_precision)
381 xprintf (p, arg);
382 else
383 xprintf (p, precision, arg);
385 else
387 if (!have_precision)
388 xprintf (p, field_width, arg);
389 else
390 xprintf (p, field_width, precision, arg);
393 break;
395 case 'o':
396 case 'u':
397 case 'x':
398 case 'X':
400 uintmax_t arg = vstrtoumax (argument);
401 if (!have_field_width)
403 if (!have_precision)
404 xprintf (p, arg);
405 else
406 xprintf (p, precision, arg);
408 else
410 if (!have_precision)
411 xprintf (p, field_width, arg);
412 else
413 xprintf (p, field_width, precision, arg);
416 break;
418 case 'a':
419 case 'A':
420 case 'e':
421 case 'E':
422 case 'f':
423 case 'F':
424 case 'g':
425 case 'G':
427 long double arg = vstrtold (argument);
428 if (!have_field_width)
430 if (!have_precision)
431 xprintf (p, arg);
432 else
433 xprintf (p, precision, arg);
435 else
437 if (!have_precision)
438 xprintf (p, field_width, arg);
439 else
440 xprintf (p, field_width, precision, arg);
443 break;
445 case 'c':
446 if (!have_field_width)
447 xprintf (p, *argument);
448 else
449 xprintf (p, field_width, *argument);
450 break;
452 case 's':
453 if (!have_field_width)
455 if (!have_precision)
456 xprintf (p, argument);
457 else
458 xprintf (p, precision, argument);
460 else
462 if (!have_precision)
463 xprintf (p, field_width, argument);
464 else
465 xprintf (p, field_width, precision, argument);
467 break;
470 free (p);
473 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
474 arguments to any '%' directives.
475 Return the number of elements of ARGV used. */
477 static int
478 print_formatted (char const *format, int argc, char **argv)
480 int save_argc = argc; /* Preserve original value. */
481 char const *f; /* Pointer into 'format'. */
482 char const *direc_start; /* Start of % directive. */
483 size_t direc_length; /* Length of % directive. */
484 bool have_field_width; /* True if FIELD_WIDTH is valid. */
485 int field_width = 0; /* Arg to first '*'. */
486 bool have_precision; /* True if PRECISION is valid. */
487 int precision = 0; /* Arg to second '*'. */
488 char ok[UCHAR_MAX + 1]; /* ok['x'] is true if %x is allowed. */
490 for (f = format; *f; ++f)
492 switch (*f)
494 case '%':
495 direc_start = f++;
496 direc_length = 1;
497 have_field_width = have_precision = false;
498 if (*f == '%')
500 putchar ('%');
501 break;
503 if (*f == 'b')
505 /* FIXME: Field width and precision are not supported
506 for %b, even though POSIX requires it. */
507 if (argc > 0)
509 print_esc_string (*argv);
510 ++argv;
511 --argc;
513 break;
516 if (*f == 'q')
518 if (argc > 0)
520 fputs (quotearg_style (shell_escape_quoting_style, *argv),
521 stdout);
522 ++argv;
523 --argc;
525 break;
528 memset (ok, 0, sizeof ok);
529 ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
530 ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
531 ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
533 for (;; f++, direc_length++)
534 switch (*f)
536 #if (__GLIBC__ == 2 && 2 <= __GLIBC_MINOR__) || 3 <= __GLIBC__
537 case 'I':
538 #endif
539 case '\'':
540 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
541 ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
542 break;
543 case '-': case '+': case ' ':
544 break;
545 case '#':
546 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
547 break;
548 case '0':
549 ok['c'] = ok['s'] = 0;
550 break;
551 default:
552 goto no_more_flag_characters;
554 no_more_flag_characters:
556 if (*f == '*')
558 ++f;
559 ++direc_length;
560 if (argc > 0)
562 intmax_t width = vstrtoimax (*argv);
563 if (INT_MIN <= width && width <= INT_MAX)
564 field_width = width;
565 else
566 die (EXIT_FAILURE, 0, _("invalid field width: %s"),
567 quote (*argv));
568 ++argv;
569 --argc;
571 else
572 field_width = 0;
573 have_field_width = true;
575 else
576 while (ISDIGIT (*f))
578 ++f;
579 ++direc_length;
581 if (*f == '.')
583 ++f;
584 ++direc_length;
585 ok['c'] = 0;
586 if (*f == '*')
588 ++f;
589 ++direc_length;
590 if (argc > 0)
592 intmax_t prec = vstrtoimax (*argv);
593 if (prec < 0)
595 /* A negative precision is taken as if the
596 precision were omitted, so -1 is safe
597 here even if prec < INT_MIN. */
598 precision = -1;
600 else if (INT_MAX < prec)
601 die (EXIT_FAILURE, 0, _("invalid precision: %s"),
602 quote (*argv));
603 else
604 precision = prec;
605 ++argv;
606 --argc;
608 else
609 precision = 0;
610 have_precision = true;
612 else
613 while (ISDIGIT (*f))
615 ++f;
616 ++direc_length;
620 while (*f == 'l' || *f == 'L' || *f == 'h'
621 || *f == 'j' || *f == 't' || *f == 'z')
622 ++f;
625 unsigned char conversion = *f;
626 if (! ok[conversion])
627 die (EXIT_FAILURE, 0,
628 _("%.*s: invalid conversion specification"),
629 (int) (f + 1 - direc_start), direc_start);
632 print_direc (direc_start, direc_length, *f,
633 have_field_width, field_width,
634 have_precision, precision,
635 (argc <= 0 ? "" : (argc--, *argv++)));
636 break;
638 case '\\':
639 f += print_esc (f, false);
640 break;
642 default:
643 putchar (*f);
647 return save_argc - argc;
651 main (int argc, char **argv)
653 char *format;
654 int args_used;
656 initialize_main (&argc, &argv);
657 set_program_name (argv[0]);
658 setlocale (LC_ALL, "");
659 bindtextdomain (PACKAGE, LOCALEDIR);
660 textdomain (PACKAGE);
662 atexit (close_stdout);
664 exit_status = EXIT_SUCCESS;
666 posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
668 /* We directly parse options, rather than use parse_long_options, in
669 order to avoid accepting abbreviations. */
670 if (argc == 2)
672 if (STREQ (argv[1], "--help"))
673 usage (EXIT_SUCCESS);
675 if (STREQ (argv[1], "--version"))
677 version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
678 (char *) NULL);
679 return EXIT_SUCCESS;
683 /* The above handles --help and --version.
684 Since there is no other invocation of getopt, handle '--' here. */
685 if (1 < argc && STREQ (argv[1], "--"))
687 --argc;
688 ++argv;
691 if (argc <= 1)
693 error (0, 0, _("missing operand"));
694 usage (EXIT_FAILURE);
697 format = argv[1];
698 argc -= 2;
699 argv += 2;
703 args_used = print_formatted (format, argc, argv);
704 argc -= args_used;
705 argv += args_used;
707 while (args_used > 0 && argc > 0);
709 if (argc > 0)
710 error (0, 0,
711 _("warning: ignoring excess arguments, starting with %s"),
712 quote (argv[0]));
714 return exit_status;