kill: with -l,-t list signal 0
[coreutils.git] / src / printf.c
blobbb5a7c72310bf48e78e3d3ed120447a6b00df597
1 /* printf - format and print data
2 Copyright (C) 1990-2024 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 #include <config.h>
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <wchar.h>
22 #include "system.h"
23 #include "c-ctype.h"
24 #include "cl-strtod.h"
25 #include "octhexdigits.h"
26 #include "quote.h"
27 #include "unicodeio.h"
28 #include "xprintf.h"
30 /* The official name of this program (e.g., no 'g' prefix). */
31 #define PROGRAM_NAME "printf"
33 #define AUTHORS proper_name ("David MacKenzie")
35 /* The value to return to the calling program. */
36 static int exit_status;
38 /* True if the POSIXLY_CORRECT environment variable is set. */
39 static bool posixly_correct;
41 /* This message appears in N_() here rather than just in _() below because
42 the sole use would have been in a #define. */
43 static char const *const cfcc_msg =
44 N_("warning: %s: character(s) following character constant have been ignored");
46 void
47 usage (int status)
49 if (status != EXIT_SUCCESS)
50 emit_try_help ();
51 else
53 printf (_("\
54 Usage: %s FORMAT [ARGUMENT]...\n\
55 or: %s OPTION\n\
56 "),
57 program_name, program_name);
58 fputs (_("\
59 Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:\n\
60 \n\
61 "), stdout);
62 fputs (HELP_OPTION_DESCRIPTION, stdout);
63 fputs (VERSION_OPTION_DESCRIPTION, stdout);
64 fputs (_("\
65 \n\
66 FORMAT controls the output as in C printf. Interpreted sequences are:\n\
67 \n\
68 \\\" double quote\n\
69 "), stdout);
70 fputs (_("\
71 \\\\ backslash\n\
72 \\a alert (BEL)\n\
73 \\b backspace\n\
74 \\c produce no further output\n\
75 \\e escape\n\
76 \\f form feed\n\
77 \\n new line\n\
78 \\r carriage return\n\
79 \\t horizontal tab\n\
80 \\v vertical tab\n\
81 "), stdout);
82 fputs (_("\
83 \\NNN byte with octal value NNN (1 to 3 digits)\n\
84 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
85 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
86 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
87 "), stdout);
88 fputs (_("\
89 %% a single %\n\
90 %b ARGUMENT as a string with '\\' escapes interpreted,\n\
91 except that octal escapes should have a leading 0 like \\0NNN\n\
92 %q ARGUMENT is printed in a format that can be reused as shell input,\n\
93 escaping non-printable characters with the POSIX $'' syntax\
94 \n\n\
95 and all C format specifications ending with one of diouxXfeEgGcs, with\n\
96 ARGUMENTs converted to proper type first. Variable widths are handled.\n\
97 "), stdout);
98 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
99 emit_ancillary_info (PROGRAM_NAME);
101 exit (status);
104 static void
105 verify_numeric (char const *s, char const *end)
107 if (s == end)
109 error (0, 0, _("%s: expected a numeric value"), quote (s));
110 exit_status = EXIT_FAILURE;
112 else if (errno)
114 error (0, errno, "%s", quote (s));
115 exit_status = EXIT_FAILURE;
117 else if (*end)
119 error (0, 0, _("%s: value not completely converted"), quote (s));
120 exit_status = EXIT_FAILURE;
124 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
125 static TYPE \
126 FUNC_NAME (char const *s) \
128 char *end; \
129 TYPE val; \
131 if ((*s == '\"' || *s == '\'') && *(s + 1)) \
133 unsigned char ch = *++s; \
134 val = ch; \
136 if (MB_CUR_MAX > 1 && *(s + 1)) \
138 mbstate_t mbstate; mbszero (&mbstate); \
139 wchar_t wc; \
140 size_t slen = strlen (s); \
141 ssize_t bytes; \
142 /* Use mbrtowc not mbrtoc32, as per POSIX. */ \
143 bytes = mbrtowc (&wc, s, slen, &mbstate); \
144 if (0 < bytes) \
146 val = wc; \
147 s += bytes - 1; \
151 /* If POSIXLY_CORRECT is not set, then give a warning that there \
152 are characters following the character constant and that GNU \
153 printf is ignoring those characters. If POSIXLY_CORRECT *is* \
154 set, then don't give the warning. */ \
155 if (*++s != 0 && !posixly_correct) \
156 error (0, 0, _(cfcc_msg), s); \
158 else \
160 errno = 0; \
161 val = (LIB_FUNC_EXPR); \
162 verify_numeric (s, end); \
164 return val; \
167 STRTOX (intmax_t, vstrtoimax, strtoimax (s, &end, 0))
168 STRTOX (uintmax_t, vstrtoumax, strtoumax (s, &end, 0))
169 STRTOX (long double, vstrtold, cl_strtold (s, &end))
171 /* Output a single-character \ escape. */
173 static void
174 print_esc_char (char c)
176 switch (c)
178 case 'a': /* Alert. */
179 putchar ('\a');
180 break;
181 case 'b': /* Backspace. */
182 putchar ('\b');
183 break;
184 case 'c': /* Cancel the rest of the output. */
185 exit (EXIT_SUCCESS);
186 break;
187 case 'e': /* Escape. */
188 putchar ('\x1B');
189 break;
190 case 'f': /* Form feed. */
191 putchar ('\f');
192 break;
193 case 'n': /* New line. */
194 putchar ('\n');
195 break;
196 case 'r': /* Carriage return. */
197 putchar ('\r');
198 break;
199 case 't': /* Horizontal tab. */
200 putchar ('\t');
201 break;
202 case 'v': /* Vertical tab. */
203 putchar ('\v');
204 break;
205 default:
206 putchar (c);
207 break;
211 /* Print a \ escape sequence starting at ESCSTART.
212 Return the number of characters in the escape sequence
213 besides the backslash.
214 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
215 is an octal digit; otherwise they are of the form \ooo. */
217 static int
218 print_esc (char const *escstart, bool octal_0)
220 char const *p = escstart + 1;
221 int esc_value = 0; /* Value of \nnn escape. */
222 int esc_length; /* Length of \nnn escape. */
224 if (*p == 'x')
226 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
227 for (esc_length = 0, ++p;
228 esc_length < 2 && c_isxdigit (*p);
229 ++esc_length, ++p)
230 esc_value = esc_value * 16 + fromhex (*p);
231 if (esc_length == 0)
232 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
233 putchar (esc_value);
235 else if (isoct (*p))
237 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
238 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
239 extension to POSIX that is compatible with Bash 2.05b. */
240 for (esc_length = 0, p += octal_0 && *p == '0';
241 esc_length < 3 && isoct (*p);
242 ++esc_length, ++p)
243 esc_value = esc_value * 8 + fromoct (*p);
244 putchar (esc_value);
246 else if (*p && strchr ("\"\\abcefnrtv", *p))
247 print_esc_char (*p++);
248 else if (*p == 'u' || *p == 'U')
250 char esc_char = *p;
251 unsigned int uni_value;
253 uni_value = 0;
254 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
255 esc_length > 0;
256 --esc_length, ++p)
258 if (! c_isxdigit (*p))
259 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
260 uni_value = uni_value * 16 + fromhex (*p);
263 /* Error for invalid code points 0000D800 through 0000DFFF inclusive.
264 Note print_unicode_char() would print the literal \u.. in this case. */
265 if (uni_value >= 0xd800 && uni_value <= 0xdfff)
266 error (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"),
267 esc_char, (esc_char == 'u' ? 4 : 8), uni_value);
269 print_unicode_char (stdout, uni_value, 0);
271 else
273 putchar ('\\');
274 if (*p)
276 putchar (*p);
277 p++;
280 return p - escstart - 1;
283 /* Print string STR, evaluating \ escapes. */
285 static void
286 print_esc_string (char const *str)
288 for (; *str; str++)
289 if (*str == '\\')
290 str += print_esc (str, true);
291 else
292 putchar (*str);
295 /* Evaluate a printf conversion specification. START is the start of
296 the directive, and CONVERSION specifies the type of conversion.
297 FIELD_WIDTH and PRECISION are the field width and precision for '*'
298 values, if HAVE_FIELD_WIDTH and HAVE_PRECISION are true, respectively.
299 ARGUMENT is the argument to be formatted. */
301 static void
302 print_direc (char const *start, char conversion,
303 bool have_field_width, int field_width,
304 bool have_precision, int precision,
305 char const *argument)
307 char *p; /* Null-terminated copy of % directive. */
309 /* Create a null-terminated copy of the % directive, with an
310 intmax_t-wide length modifier substituted for any existing
311 integer length modifier. */
313 char *q;
314 char const *length_modifier;
315 size_t length_modifier_len;
317 switch (conversion)
319 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
320 length_modifier = "j";
321 length_modifier_len = 1;
322 break;
324 case 'a': case 'e': case 'f': case 'g':
325 case 'A': case 'E': case 'F': case 'G':
326 length_modifier = "L";
327 length_modifier_len = 1;
328 break;
330 default:
331 length_modifier = start; /* Any valid pointer will do. */
332 length_modifier_len = 0;
333 break;
336 size_t length = strlen (start);
337 p = xmalloc (length + length_modifier_len + 2);
338 q = mempcpy (p, start, length);
339 q = mempcpy (q, length_modifier, length_modifier_len);
340 *q++ = conversion;
341 *q = '\0';
344 switch (conversion)
346 case 'd':
347 case 'i':
349 intmax_t arg = argument ? vstrtoimax (argument) : 0;
350 if (!have_field_width)
352 if (!have_precision)
353 xprintf (p, arg);
354 else
355 xprintf (p, precision, arg);
357 else
359 if (!have_precision)
360 xprintf (p, field_width, arg);
361 else
362 xprintf (p, field_width, precision, arg);
365 break;
367 case 'o':
368 case 'u':
369 case 'x':
370 case 'X':
372 uintmax_t arg = argument ? vstrtoumax (argument) : 0;
373 if (!have_field_width)
375 if (!have_precision)
376 xprintf (p, arg);
377 else
378 xprintf (p, precision, arg);
380 else
382 if (!have_precision)
383 xprintf (p, field_width, arg);
384 else
385 xprintf (p, field_width, precision, arg);
388 break;
390 case 'a':
391 case 'A':
392 case 'e':
393 case 'E':
394 case 'f':
395 case 'F':
396 case 'g':
397 case 'G':
399 long double arg = argument ? vstrtold (argument) : 0;
400 if (!have_field_width)
402 if (!have_precision)
403 xprintf (p, arg);
404 else
405 xprintf (p, precision, arg);
407 else
409 if (!have_precision)
410 xprintf (p, field_width, arg);
411 else
412 xprintf (p, field_width, precision, arg);
415 break;
417 case 'c':
419 char c = argument ? *argument : '\0';
420 if (!have_field_width)
421 xprintf (p, c);
422 else
423 xprintf (p, field_width, c);
425 break;
427 case 's':
428 if (!argument)
429 argument = "";
430 if (!have_field_width)
432 if (!have_precision)
433 xprintf (p, argument);
434 else
435 xprintf (p, precision, argument);
437 else
439 if (!have_precision)
440 xprintf (p, field_width, argument);
441 else
442 xprintf (p, field_width, precision, argument);
444 break;
447 free (p);
450 /* Set curr_arg from indexed %i$ or otherwise next in sequence.
451 POS can be 0,1,2,3 corresponding to
452 [%][width][.precision][conversion] respectively. */
454 struct arg_cursor
456 char const *f; /* Pointer into 'format'. */
457 int curr_arg; /* Current offset. */
458 int curr_s_arg; /* Current sequential offset. */
459 int end_arg; /* End arg processed. */
460 int direc_arg; /* Arg for main directive. */
462 ATTRIBUTE_PURE static struct arg_cursor
463 get_curr_arg (int pos, struct arg_cursor ac)
465 /* Convert sequences like "123$" by hand to avoid problems with strtol,
466 which might treat "$" as part of the number in some locales. */
467 int arg = 0;
468 char const *f = ac.f;
469 if (pos < 3 && c_isdigit (*f))
471 bool v = false;
472 int a = *f++ - '0';
473 for (; c_isdigit (*f); f++)
475 v |= ckd_mul (&a, a, 10);
476 v |= ckd_add (&a, a, *f - '0');
478 if (*f == '$')
479 arg = v ? INT_MAX : a;
482 if (0 < arg)
484 /* Process indexed %i$ format. */
485 arg--;
486 ac.f = f + 1;
487 if (pos == 0)
488 ac.direc_arg = arg;
490 else
492 /* Process sequential arg. */
493 arg = (pos == 0 ? (ac.direc_arg = -1)
494 : pos < 3 || ac.direc_arg < 0 ? ++ac.curr_s_arg
495 : ac.direc_arg);
498 if (0 <= arg)
500 ac.curr_arg = arg;
501 ac.end_arg = MAX (ac.end_arg, arg);
503 return ac;
506 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
507 arguments to any '%' directives.
508 Return the number of elements of ARGV used. */
510 static int
511 print_formatted (char const *format, int argc, char **argv)
513 struct arg_cursor ac;
514 ac.curr_arg = ac.curr_s_arg = ac.end_arg = ac.direc_arg = -1;
515 char const *direc_start; /* Start of % directive. */
516 char *direc; /* Generated % directive. */
517 char *pdirec; /* Pointer to current end of directive. */
518 bool have_field_width; /* True if FIELD_WIDTH is valid. */
519 int field_width = 0; /* Arg to first '*'. */
520 bool have_precision; /* True if PRECISION is valid. */
521 int precision = 0; /* Arg to second '*'. */
522 char ok[UCHAR_MAX + 1]; /* ok['x'] is true if %x is allowed. */
524 direc = xmalloc (strlen (format) + 1);
526 for (ac.f = format; *ac.f; ac.f++)
528 switch (*ac.f)
530 case '%':
531 direc_start = ac.f;
532 pdirec = direc;
533 *pdirec++ = *ac.f++;
534 have_field_width = have_precision = false;
535 if (*ac.f == '%')
537 putchar ('%');
538 break;
541 ac = get_curr_arg (0, ac);
543 if (*ac.f == 'b')
545 /* FIXME: Field width and precision are not supported
546 for %b, even though POSIX requires it. */
547 ac = get_curr_arg (3, ac);
548 if (ac.curr_arg < argc)
549 print_esc_string (argv[ac.curr_arg]);
550 break;
553 if (*ac.f == 'q')
555 ac = get_curr_arg (3, ac);
556 if (ac.curr_arg < argc)
558 fputs (quotearg_style (shell_escape_quoting_style,
559 argv[ac.curr_arg]), stdout);
561 break;
564 memset (ok, 0, sizeof ok);
565 ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
566 ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
567 ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
569 for (;; ac.f++)
571 switch (*ac.f)
573 #if (__GLIBC__ == 2 && 2 <= __GLIBC_MINOR__) || 3 <= __GLIBC__
574 case 'I':
575 #endif
576 case '\'':
577 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
578 ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
579 break;
580 case '-': case '+': case ' ':
581 break;
582 case '#':
583 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
584 break;
585 case '0':
586 ok['c'] = ok['s'] = 0;
587 break;
588 default:
589 goto no_more_flag_characters;
591 *pdirec++ = *ac.f;
593 no_more_flag_characters:
595 if (*ac.f == '*')
597 *pdirec++ = *ac.f++;
599 ac = get_curr_arg (1, ac);
601 if (ac.curr_arg < argc)
603 intmax_t width = vstrtoimax (argv[ac.curr_arg]);
604 if (INT_MIN <= width && width <= INT_MAX)
605 field_width = width;
606 else
607 error (EXIT_FAILURE, 0, _("invalid field width: %s"),
608 quote (argv[ac.curr_arg]));
610 else
611 field_width = 0;
612 have_field_width = true;
614 else
615 while (ISDIGIT (*ac.f))
616 *pdirec++ = *ac.f++;
617 if (*ac.f == '.')
619 *pdirec++ = *ac.f++;
620 ok['c'] = 0;
621 if (*ac.f == '*')
623 *pdirec++ = *ac.f++;
625 ac = get_curr_arg (2, ac);
627 if (ac.curr_arg < argc)
629 intmax_t prec = vstrtoimax (argv[ac.curr_arg]);
630 if (prec < 0)
632 /* A negative precision is taken as if the
633 precision were omitted, so -1 is safe
634 here even if prec < INT_MIN. */
635 precision = -1;
637 else if (INT_MAX < prec)
638 error (EXIT_FAILURE, 0, _("invalid precision: %s"),
639 quote (argv[ac.curr_arg]));
640 else
641 precision = prec;
643 else
644 precision = 0;
645 have_precision = true;
647 else
648 while (ISDIGIT (*ac.f))
649 *pdirec++ = *ac.f++;
652 *pdirec++ = '\0';
654 while (*ac.f == 'l' || *ac.f == 'L' || *ac.f == 'h'
655 || *ac.f == 'j' || *ac.f == 't' || *ac.f == 'z')
656 ++ac.f;
659 unsigned char conversion = *ac.f;
660 int speclen = MIN (ac.f + 1 - direc_start, INT_MAX);
661 if (! ok[conversion])
662 error (EXIT_FAILURE, 0,
663 _("%.*s: invalid conversion specification"),
664 speclen, direc_start);
667 ac = get_curr_arg (3, ac);
669 print_direc (direc, *ac.f,
670 have_field_width, field_width,
671 have_precision, precision,
672 ac.curr_arg < argc ? argv[ac.curr_arg] : nullptr);
674 break;
676 case '\\':
677 ac.f += print_esc (ac.f, false);
678 break;
680 default:
681 putchar (*ac.f);
685 free (direc);
686 return MIN (argc, ac.end_arg + 1);
690 main (int argc, char **argv)
692 char *format;
693 int args_used;
695 initialize_main (&argc, &argv);
696 set_program_name (argv[0]);
697 setlocale (LC_ALL, "");
698 bindtextdomain (PACKAGE, LOCALEDIR);
699 textdomain (PACKAGE);
701 atexit (close_stdout);
703 exit_status = EXIT_SUCCESS;
705 posixly_correct = (getenv ("POSIXLY_CORRECT") != nullptr);
707 /* We directly parse options, rather than use parse_long_options, in
708 order to avoid accepting abbreviations. */
709 if (argc == 2)
711 if (STREQ (argv[1], "--help"))
712 usage (EXIT_SUCCESS);
714 if (STREQ (argv[1], "--version"))
716 version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
717 (char *) nullptr);
718 return EXIT_SUCCESS;
722 /* The above handles --help and --version.
723 Since there is no other invocation of getopt, handle '--' here. */
724 if (1 < argc && STREQ (argv[1], "--"))
726 --argc;
727 ++argv;
730 if (argc <= 1)
732 error (0, 0, _("missing operand"));
733 usage (EXIT_FAILURE);
736 format = argv[1];
737 argc -= 2;
738 argv += 2;
742 args_used = print_formatted (format, argc, argv);
743 argc -= args_used;
744 argv += args_used;
746 while (args_used > 0 && argc > 0);
748 if (argc > 0)
749 error (0, 0,
750 _("warning: ignoring excess arguments, starting with %s"),
751 quote (argv[0]));
753 return exit_status;