1 /* printf - format and print data
2 Copyright (C) 1990-2005 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 2, or (at your option)
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, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 /* Usage: printf format [argument...]
20 A front end to the printf function that lets it be used from the shell.
28 \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 The `format' argument is re-used as many times as necessary
45 to convert all of the given arguments.
47 David MacKenzie <djm@gnu.ai.mit.edu> */
51 #include <sys/types.h>
57 #include "long-options.h"
59 #include "unicodeio.h"
61 #if ! (HAVE_DECL_STRTOIMAX || defined strtoimax)
62 intmax_t strtoimax ();
64 #if ! (HAVE_DECL_STRTOUMAX || defined strtoumax)
65 uintmax_t strtoumax ();
68 /* The official name of this program (e.g., no `g' prefix). */
69 #define PROGRAM_NAME "printf"
71 #define AUTHORS "David MacKenzie"
73 #define isodigit(c) ((c) >= '0' && (c) <= '7')
74 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
75 (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
76 #define octtobin(c) ((c) - '0')
78 /* The value to return to the calling program. */
79 static int exit_status;
81 /* True if the POSIXLY_CORRECT environment variable is set. */
82 static bool posixly_correct;
84 /* This message appears in N_() here rather than just in _() below because
85 the sole use would have been in a #define. */
86 static char *const cfcc_msg =
87 N_("warning: %s: character(s) following character constant have been ignored");
89 /* The name this program was run with. */
95 if (status != EXIT_SUCCESS)
96 fprintf (stderr, _("Try `%s --help' for more information.\n"),
101 Usage: %s FORMAT [ARGUMENT]...\n\
104 program_name, program_name);
106 Print ARGUMENT(s) according to FORMAT.\n\
109 fputs (HELP_OPTION_DESCRIPTION, stdout);
110 fputs (VERSION_OPTION_DESCRIPTION, stdout);
113 FORMAT controls the output as in C printf. Interpreted sequences are:\n\
116 \\NNN character with octal value NNN (1 to 3 digits)\n\
122 \\c produce no further output\n\
127 \\r carriage return\n\
128 \\t horizontal tab\n\
132 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
133 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
134 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
138 %b ARGUMENT as a string with `\\' escapes interpreted,\n\
139 except that octal escapes are of the form \\0 or \\0NNN\n\
141 and all C format specifications ending with one of diouxXfeEgGcs, with\n\
142 ARGUMENTs converted to proper type first. Variable widths are handled.\n\
144 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
145 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
151 verify_numeric (const char *s, const char *end)
155 error (0, errno, "%s", s);
156 exit_status = EXIT_FAILURE;
161 error (0, 0, _("%s: expected a numeric value"), s);
163 error (0, 0, _("%s: value not completely converted"), s);
164 exit_status = EXIT_FAILURE;
168 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
170 FUNC_NAME (char const *s) \
175 if (*s == '\"' || *s == '\'') \
177 unsigned char ch = *++s; \
179 /* If POSIXLY_CORRECT is not set, then give a warning that there \
180 are characters following the character constant and that GNU \
181 printf is ignoring those characters. If POSIXLY_CORRECT *is* \
182 set, then don't give the warning. */ \
183 if (*++s != 0 && !posixly_correct) \
184 error (0, 0, _(cfcc_msg), s); \
189 val = (LIB_FUNC_EXPR); \
190 verify_numeric (s, end); \
195 STRTOX (intmax_t, vstrtoimax, strtoimax (s, &end, 0))
196 STRTOX (uintmax_t, vstrtoumax, strtoumax (s, &end, 0))
197 STRTOX (long double, vstrtold, c_strtold (s, &end))
199 /* Output a single-character \ escape. */
202 print_esc_char (char c)
206 case 'a': /* Alert. */
209 case 'b': /* Backspace. */
212 case 'c': /* Cancel the rest of the output. */
215 case 'f': /* Form feed. */
218 case 'n': /* New line. */
221 case 'r': /* Carriage return. */
224 case 't': /* Horizontal tab. */
227 case 'v': /* Vertical tab. */
236 /* Print a \ escape sequence starting at ESCSTART.
237 Return the number of characters in the escape sequence
238 besides the backslash.
239 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
240 is an octal digit; otherwise they are of the form \ooo. */
243 print_esc (const char *escstart, bool octal_0)
245 const char *p = escstart + 1;
246 int esc_value = 0; /* Value of \nnn escape. */
247 int esc_length; /* Length of \nnn escape. */
251 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
252 for (esc_length = 0, ++p;
253 esc_length < 2 && ISXDIGIT (*p);
255 esc_value = esc_value * 16 + hextobin (*p);
257 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
260 else if (isodigit (*p))
262 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
263 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
264 extension to POSIX that is compatible with Bash 2.05b. */
265 for (esc_length = 0, p += octal_0 && *p == '0';
266 esc_length < 3 && isodigit (*p);
268 esc_value = esc_value * 8 + octtobin (*p);
271 else if (*p && strchr ("\"\\abcfnrtv", *p))
272 print_esc_char (*p++);
273 else if (*p == 'u' || *p == 'U')
276 unsigned int uni_value;
279 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
284 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
285 uni_value = uni_value * 16 + hextobin (*p);
288 /* A universal character name shall not specify a character short
289 identifier in the range 00000000 through 00000020, 0000007F through
290 0000009F, or 0000D800 through 0000DFFF inclusive. A universal
291 character name shall not designate a character in the required
293 if ((uni_value <= 0x9f
294 && uni_value != 0x24 && uni_value != 0x40 && uni_value != 0x60)
295 || (uni_value >= 0xd800 && uni_value <= 0xdfff))
296 error (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"),
297 esc_char, (esc_char == 'u' ? 4 : 8), uni_value);
299 print_unicode_char (stdout, uni_value, 0);
310 return p - escstart - 1;
313 /* Print string STR, evaluating \ escapes. */
316 print_esc_string (const char *str)
320 str += print_esc (str, true);
325 /* Evaluate a printf conversion specification. START is the start of
326 the directive, LENGTH is its length, and CONVERSION specifies the
327 type of conversion. LENGTH does not include any length modifier or
328 the conversion specifier itself. FIELD_WIDTH and PRECISION are the
329 field width and precision for '*' values, if HAVE_FIELD_WIDTH and
330 HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
334 print_direc (const char *start, size_t length, char conversion,
335 bool have_field_width, int field_width,
336 bool have_precision, int precision,
337 char const *argument)
339 char *p; /* Null-terminated copy of % directive. */
341 /* Create a null-terminated copy of the % directive, with an
342 intmax_t-wide length modifier substituted for any existing
343 integer length modifier. */
346 char const *length_modifier;
347 size_t length_modifier_len;
351 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
352 length_modifier = PRIdMAX;
353 length_modifier_len = sizeof PRIdMAX - 2;
356 case 'a': case 'e': case 'f': case 'g':
357 case 'A': case 'E': case 'F': case 'G':
358 length_modifier = "L";
359 length_modifier_len = 1;
363 length_modifier = start; /* Any valid pointer will do. */
364 length_modifier_len = 0;
368 p = xmalloc (length + length_modifier_len + 2);
369 q = mempcpy (p, start, length);
370 q = mempcpy (q, length_modifier, length_modifier_len);
380 intmax_t arg = vstrtoimax (argument);
381 if (!have_field_width)
386 printf (p, precision, arg);
391 printf (p, field_width, arg);
393 printf (p, field_width, precision, arg);
403 uintmax_t arg = vstrtoumax (argument);
404 if (!have_field_width)
409 printf (p, precision, arg);
414 printf (p, field_width, arg);
416 printf (p, field_width, precision, arg);
430 long double arg = vstrtold (argument);
431 if (!have_field_width)
436 printf (p, precision, arg);
441 printf (p, field_width, arg);
443 printf (p, field_width, precision, arg);
449 if (!have_field_width)
450 printf (p, *argument);
452 printf (p, field_width, *argument);
456 if (!have_field_width)
459 printf (p, argument);
461 printf (p, precision, argument);
466 printf (p, field_width, argument);
468 printf (p, field_width, precision, argument);
476 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
477 arguments to any `%' directives.
478 Return the number of elements of ARGV used. */
481 print_formatted (const char *format, int argc, char **argv)
483 int save_argc = argc; /* Preserve original value. */
484 const char *f; /* Pointer into `format'. */
485 const char *direc_start; /* Start of % directive. */
486 size_t direc_length; /* Length of % directive. */
487 bool have_field_width; /* True if FIELD_WIDTH is valid. */
488 int field_width = 0; /* Arg to first '*'. */
489 bool have_precision; /* True if PRECISION is valid. */
490 int precision = 0; /* Arg to second '*'. */
491 char ok[UCHAR_MAX + 1]; /* ok['x'] is true if %x is allowed. */
493 for (f = format; *f; ++f)
500 have_field_width = have_precision = false;
508 /* FIXME: Field width and precision are not supported
509 for %b, even though POSIX requires it. */
512 print_esc_string (*argv);
519 memset (ok, 0, sizeof ok);
520 ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
521 ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
522 ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
524 for (;; f++, direc_length++)
528 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
529 ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
531 case '-': case '+': case ' ':
534 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
537 ok['c'] = ok['s'] = 0;
540 goto no_more_flag_characters;
542 no_more_flag_characters:;
550 intmax_t width = vstrtoimax (*argv);
551 if (INT_MIN <= width && width <= INT_MAX)
554 error (EXIT_FAILURE, 0, _("invalid field width: %s"),
561 have_field_width = true;
580 intmax_t prec = vstrtoimax (*argv);
583 /* A negative precision is taken as if the
584 precision were omitted, so -1 is safe
585 here even if prec < INT_MIN. */
588 else if (INT_MAX < prec)
589 error (EXIT_FAILURE, 0, _("invalid precision: %s"),
598 have_precision = true;
608 while (*f == 'l' || *f == 'L' || *f == 'h'
609 || *f == 'j' || *f == 't' || *f == 'z')
613 unsigned char conversion = *f;
614 if (! ok[conversion])
615 error (EXIT_FAILURE, 0,
616 _("%.*s: invalid conversion specification"),
617 (int) (f + 1 - direc_start), direc_start);
620 print_direc (direc_start, direc_length, *f,
621 have_field_width, field_width,
622 have_precision, precision,
623 (argc <= 0 ? "" : (argc--, *argv++)));
627 f += print_esc (f, false);
635 return save_argc - argc;
639 main (int argc, char **argv)
644 initialize_main (&argc, &argv);
645 program_name = argv[0];
646 setlocale (LC_ALL, "");
647 bindtextdomain (PACKAGE, LOCALEDIR);
648 textdomain (PACKAGE);
650 atexit (close_stdout);
652 exit_status = EXIT_SUCCESS;
654 posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
656 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
657 usage, AUTHORS, (char const *) NULL);
659 /* The above handles --help and --version.
660 Since there is no other invocation of getopt, handle `--' here. */
661 if (1 < argc && STREQ (argv[1], "--"))
669 error (0, 0, _("missing operand"));
670 usage (EXIT_FAILURE);
679 args_used = print_formatted (format, argc, argv);
683 while (args_used > 0 && argc > 0);
687 _("warning: ignoring excess arguments, starting with %s"),