global: convert indentation-TABs to spaces
[coreutils.git] / src / printf.c
blob5fa25dee8238b61794868f216dfcac4427bafe9d
1 /* printf - format and print data
2 Copyright (C) 1990-2009 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.
21 Backslash escapes:
23 \" = double quote
24 \\ = backslash
25 \a = alert (bell)
26 \b = backspace
27 \c = produce no further output
28 \f = form feed
29 \n = new line
30 \r = carriage return
31 \t = horizontal tab
32 \v = vertical tab
33 \ooo = octal number (ooo is 1 to 3 digits)
34 \xhh = hexadecimal number (hhh is 1 to 2 digits)
35 \uhhhh = 16-bit Unicode character (hhhh is 4 digits)
36 \Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits)
38 Additional directive:
40 %b = print an argument string, interpreting backslash escapes,
41 except that octal escapes are of the form \0 or \0ooo.
43 The `format' argument is re-used as many times as necessary
44 to convert all of the given arguments.
46 David MacKenzie <djm@gnu.ai.mit.edu> */
48 #include <config.h>
49 #include <stdio.h>
50 #include <sys/types.h>
52 #include "system.h"
53 #include "c-strtod.h"
54 #include "error.h"
55 #include "quote.h"
56 #include "unicodeio.h"
57 #include "xprintf.h"
59 /* The official name of this program (e.g., no `g' prefix). */
60 #define PROGRAM_NAME "printf"
62 #define AUTHORS proper_name ("David MacKenzie")
64 #define isodigit(c) ((c) >= '0' && (c) <= '7')
65 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
66 (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
67 #define octtobin(c) ((c) - '0')
69 /* The value to return to the calling program. */
70 static int exit_status;
72 /* True if the POSIXLY_CORRECT environment variable is set. */
73 static bool posixly_correct;
75 /* This message appears in N_() here rather than just in _() below because
76 the sole use would have been in a #define. */
77 static char const *const cfcc_msg =
78 N_("warning: %s: character(s) following character constant have been ignored");
80 void
81 usage (int status)
83 if (status != EXIT_SUCCESS)
84 fprintf (stderr, _("Try `%s --help' for more information.\n"),
85 program_name);
86 else
88 printf (_("\
89 Usage: %s FORMAT [ARGUMENT]...\n\
90 or: %s OPTION\n\
91 "),
92 program_name, program_name);
93 fputs (_("\
94 Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:\n\
95 \n\
96 "), stdout);
97 fputs (HELP_OPTION_DESCRIPTION, stdout);
98 fputs (VERSION_OPTION_DESCRIPTION, stdout);
99 fputs (_("\
101 FORMAT controls the output as in C printf. Interpreted sequences are:\n\
103 \\\" double quote\n\
104 \\NNN character with octal value NNN (1 to 3 digits)\n\
105 \\\\ backslash\n\
106 "), stdout);
107 fputs (_("\
108 \\a alert (BEL)\n\
109 \\b backspace\n\
110 \\c produce no further output\n\
111 \\f form feed\n\
112 "), stdout);
113 fputs (_("\
114 \\n new line\n\
115 \\r carriage return\n\
116 \\t horizontal tab\n\
117 \\v vertical tab\n\
118 "), stdout);
119 fputs (_("\
120 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
121 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
122 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
123 "), stdout);
124 fputs (_("\
125 %% a single %\n\
126 %b ARGUMENT as a string with `\\' escapes interpreted,\n\
127 except that octal escapes are of the form \\0 or \\0NNN\n\
129 and all C format specifications ending with one of diouxXfeEgGcs, with\n\
130 ARGUMENTs converted to proper type first. Variable widths are handled.\n\
131 "), stdout);
132 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
133 emit_bug_reporting_address ();
135 exit (status);
138 static void
139 verify_numeric (const char *s, const char *end)
141 if (errno)
143 error (0, errno, "%s", s);
144 exit_status = EXIT_FAILURE;
146 else if (*end)
148 if (s == end)
149 error (0, 0, _("%s: expected a numeric value"), s);
150 else
151 error (0, 0, _("%s: value not completely converted"), s);
152 exit_status = EXIT_FAILURE;
156 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
157 static TYPE \
158 FUNC_NAME (char const *s) \
160 char *end; \
161 TYPE val; \
163 if (*s == '\"' || *s == '\'') \
165 unsigned char ch = *++s; \
166 val = ch; \
167 /* If POSIXLY_CORRECT is not set, then give a warning that there \
168 are characters following the character constant and that GNU \
169 printf is ignoring those characters. If POSIXLY_CORRECT *is* \
170 set, then don't give the warning. */ \
171 if (*++s != 0 && !posixly_correct) \
172 error (0, 0, _(cfcc_msg), s); \
174 else \
176 errno = 0; \
177 val = (LIB_FUNC_EXPR); \
178 verify_numeric (s, end); \
180 return val; \
183 STRTOX (intmax_t, vstrtoimax, strtoimax (s, &end, 0))
184 STRTOX (uintmax_t, vstrtoumax, strtoumax (s, &end, 0))
185 STRTOX (long double, vstrtold, c_strtold (s, &end))
187 /* Output a single-character \ escape. */
189 static void
190 print_esc_char (char c)
192 switch (c)
194 case 'a': /* Alert. */
195 putchar ('\a');
196 break;
197 case 'b': /* Backspace. */
198 putchar ('\b');
199 break;
200 case 'c': /* Cancel the rest of the output. */
201 exit (EXIT_SUCCESS);
202 break;
203 case 'f': /* Form feed. */
204 putchar ('\f');
205 break;
206 case 'n': /* New line. */
207 putchar ('\n');
208 break;
209 case 'r': /* Carriage return. */
210 putchar ('\r');
211 break;
212 case 't': /* Horizontal tab. */
213 putchar ('\t');
214 break;
215 case 'v': /* Vertical tab. */
216 putchar ('\v');
217 break;
218 default:
219 putchar (c);
220 break;
224 /* Print a \ escape sequence starting at ESCSTART.
225 Return the number of characters in the escape sequence
226 besides the backslash.
227 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
228 is an octal digit; otherwise they are of the form \ooo. */
230 static int
231 print_esc (const char *escstart, bool octal_0)
233 const char *p = escstart + 1;
234 int esc_value = 0; /* Value of \nnn escape. */
235 int esc_length; /* Length of \nnn escape. */
237 if (*p == 'x')
239 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
240 for (esc_length = 0, ++p;
241 esc_length < 2 && isxdigit (to_uchar (*p));
242 ++esc_length, ++p)
243 esc_value = esc_value * 16 + hextobin (*p);
244 if (esc_length == 0)
245 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
246 putchar (esc_value);
248 else if (isodigit (*p))
250 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
251 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
252 extension to POSIX that is compatible with Bash 2.05b. */
253 for (esc_length = 0, p += octal_0 && *p == '0';
254 esc_length < 3 && isodigit (*p);
255 ++esc_length, ++p)
256 esc_value = esc_value * 8 + octtobin (*p);
257 putchar (esc_value);
259 else if (*p && strchr ("\"\\abcfnrtv", *p))
260 print_esc_char (*p++);
261 else if (*p == 'u' || *p == 'U')
263 char esc_char = *p;
264 unsigned int uni_value;
266 uni_value = 0;
267 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
268 esc_length > 0;
269 --esc_length, ++p)
271 if (! isxdigit (to_uchar (*p)))
272 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
273 uni_value = uni_value * 16 + hextobin (*p);
276 /* A universal character name shall not specify a character short
277 identifier in the range 00000000 through 00000020, 0000007F through
278 0000009F, or 0000D800 through 0000DFFF inclusive. A universal
279 character name shall not designate a character in the required
280 character set. */
281 if ((uni_value <= 0x9f
282 && uni_value != 0x24 && uni_value != 0x40 && uni_value != 0x60)
283 || (uni_value >= 0xd800 && uni_value <= 0xdfff))
284 error (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"),
285 esc_char, (esc_char == 'u' ? 4 : 8), uni_value);
287 print_unicode_char (stdout, uni_value, 0);
289 else
291 putchar ('\\');
292 if (*p)
294 putchar (*p);
295 p++;
298 return p - escstart - 1;
301 /* Print string STR, evaluating \ escapes. */
303 static void
304 print_esc_string (const char *str)
306 for (; *str; str++)
307 if (*str == '\\')
308 str += print_esc (str, true);
309 else
310 putchar (*str);
313 /* Evaluate a printf conversion specification. START is the start of
314 the directive, LENGTH is its length, and CONVERSION specifies the
315 type of conversion. LENGTH does not include any length modifier or
316 the conversion specifier itself. FIELD_WIDTH and PRECISION are the
317 field width and precision for '*' values, if HAVE_FIELD_WIDTH and
318 HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
319 be formatted. */
321 static void
322 print_direc (const char *start, size_t length, char conversion,
323 bool have_field_width, int field_width,
324 bool have_precision, int precision,
325 char const *argument)
327 char *p; /* Null-terminated copy of % directive. */
329 /* Create a null-terminated copy of the % directive, with an
330 intmax_t-wide length modifier substituted for any existing
331 integer length modifier. */
333 char *q;
334 char const *length_modifier;
335 size_t length_modifier_len;
337 switch (conversion)
339 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
340 length_modifier = PRIdMAX;
341 length_modifier_len = sizeof PRIdMAX - 2;
342 break;
344 case 'a': case 'e': case 'f': case 'g':
345 case 'A': case 'E': case 'F': case 'G':
346 length_modifier = "L";
347 length_modifier_len = 1;
348 break;
350 default:
351 length_modifier = start; /* Any valid pointer will do. */
352 length_modifier_len = 0;
353 break;
356 p = xmalloc (length + length_modifier_len + 2);
357 q = mempcpy (p, start, length);
358 q = mempcpy (q, length_modifier, length_modifier_len);
359 *q++ = conversion;
360 *q = '\0';
363 switch (conversion)
365 case 'd':
366 case 'i':
368 intmax_t arg = vstrtoimax (argument);
369 if (!have_field_width)
371 if (!have_precision)
372 xprintf (p, arg);
373 else
374 xprintf (p, precision, arg);
376 else
378 if (!have_precision)
379 xprintf (p, field_width, arg);
380 else
381 xprintf (p, field_width, precision, arg);
384 break;
386 case 'o':
387 case 'u':
388 case 'x':
389 case 'X':
391 uintmax_t arg = vstrtoumax (argument);
392 if (!have_field_width)
394 if (!have_precision)
395 xprintf (p, arg);
396 else
397 xprintf (p, precision, arg);
399 else
401 if (!have_precision)
402 xprintf (p, field_width, arg);
403 else
404 xprintf (p, field_width, precision, arg);
407 break;
409 case 'a':
410 case 'A':
411 case 'e':
412 case 'E':
413 case 'f':
414 case 'F':
415 case 'g':
416 case 'G':
418 long double arg = vstrtold (argument);
419 if (!have_field_width)
421 if (!have_precision)
422 xprintf (p, arg);
423 else
424 xprintf (p, precision, arg);
426 else
428 if (!have_precision)
429 xprintf (p, field_width, arg);
430 else
431 xprintf (p, field_width, precision, arg);
434 break;
436 case 'c':
437 if (!have_field_width)
438 xprintf (p, *argument);
439 else
440 xprintf (p, field_width, *argument);
441 break;
443 case 's':
444 if (!have_field_width)
446 if (!have_precision)
447 xprintf (p, argument);
448 else
449 xprintf (p, precision, argument);
451 else
453 if (!have_precision)
454 xprintf (p, field_width, argument);
455 else
456 xprintf (p, field_width, precision, argument);
458 break;
461 free (p);
464 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
465 arguments to any `%' directives.
466 Return the number of elements of ARGV used. */
468 static int
469 print_formatted (const char *format, int argc, char **argv)
471 int save_argc = argc; /* Preserve original value. */
472 const char *f; /* Pointer into `format'. */
473 const char *direc_start; /* Start of % directive. */
474 size_t direc_length; /* Length of % directive. */
475 bool have_field_width; /* True if FIELD_WIDTH is valid. */
476 int field_width = 0; /* Arg to first '*'. */
477 bool have_precision; /* True if PRECISION is valid. */
478 int precision = 0; /* Arg to second '*'. */
479 char ok[UCHAR_MAX + 1]; /* ok['x'] is true if %x is allowed. */
481 for (f = format; *f; ++f)
483 switch (*f)
485 case '%':
486 direc_start = f++;
487 direc_length = 1;
488 have_field_width = have_precision = false;
489 if (*f == '%')
491 putchar ('%');
492 break;
494 if (*f == 'b')
496 /* FIXME: Field width and precision are not supported
497 for %b, even though POSIX requires it. */
498 if (argc > 0)
500 print_esc_string (*argv);
501 ++argv;
502 --argc;
504 break;
507 memset (ok, 0, sizeof ok);
508 ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
509 ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
510 ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
512 for (;; f++, direc_length++)
513 switch (*f)
515 #if (__GLIBC__ == 2 && 2 <= __GLIBC_MINOR__) || 3 <= __GLIBC__
516 case 'I':
517 #endif
518 case '\'':
519 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
520 ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
521 break;
522 case '-': case '+': case ' ':
523 break;
524 case '#':
525 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
526 break;
527 case '0':
528 ok['c'] = ok['s'] = 0;
529 break;
530 default:
531 goto no_more_flag_characters;
533 no_more_flag_characters:;
535 if (*f == '*')
537 ++f;
538 ++direc_length;
539 if (argc > 0)
541 intmax_t width = vstrtoimax (*argv);
542 if (INT_MIN <= width && width <= INT_MAX)
543 field_width = width;
544 else
545 error (EXIT_FAILURE, 0, _("invalid field width: %s"),
546 *argv);
547 ++argv;
548 --argc;
550 else
551 field_width = 0;
552 have_field_width = true;
554 else
555 while (ISDIGIT (*f))
557 ++f;
558 ++direc_length;
560 if (*f == '.')
562 ++f;
563 ++direc_length;
564 ok['c'] = 0;
565 if (*f == '*')
567 ++f;
568 ++direc_length;
569 if (argc > 0)
571 intmax_t prec = vstrtoimax (*argv);
572 if (prec < 0)
574 /* A negative precision is taken as if the
575 precision were omitted, so -1 is safe
576 here even if prec < INT_MIN. */
577 precision = -1;
579 else if (INT_MAX < prec)
580 error (EXIT_FAILURE, 0, _("invalid precision: %s"),
581 *argv);
582 else
583 precision = prec;
584 ++argv;
585 --argc;
587 else
588 precision = 0;
589 have_precision = true;
591 else
592 while (ISDIGIT (*f))
594 ++f;
595 ++direc_length;
599 while (*f == 'l' || *f == 'L' || *f == 'h'
600 || *f == 'j' || *f == 't' || *f == 'z')
601 ++f;
604 unsigned char conversion = *f;
605 if (! ok[conversion])
606 error (EXIT_FAILURE, 0,
607 _("%.*s: invalid conversion specification"),
608 (int) (f + 1 - direc_start), direc_start);
611 print_direc (direc_start, direc_length, *f,
612 have_field_width, field_width,
613 have_precision, precision,
614 (argc <= 0 ? "" : (argc--, *argv++)));
615 break;
617 case '\\':
618 f += print_esc (f, false);
619 break;
621 default:
622 putchar (*f);
626 return save_argc - argc;
630 main (int argc, char **argv)
632 char *format;
633 int args_used;
635 initialize_main (&argc, &argv);
636 set_program_name (argv[0]);
637 setlocale (LC_ALL, "");
638 bindtextdomain (PACKAGE, LOCALEDIR);
639 textdomain (PACKAGE);
641 atexit (close_stdout);
643 exit_status = EXIT_SUCCESS;
645 posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
647 /* We directly parse options, rather than use parse_long_options, in
648 order to avoid accepting abbreviations. */
649 if (argc == 2)
651 if (STREQ (argv[1], "--help"))
652 usage (EXIT_SUCCESS);
654 if (STREQ (argv[1], "--version"))
656 version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
657 (char *) NULL);
658 exit (EXIT_SUCCESS);
662 /* The above handles --help and --version.
663 Since there is no other invocation of getopt, handle `--' here. */
664 if (1 < argc && STREQ (argv[1], "--"))
666 --argc;
667 ++argv;
670 if (argc <= 1)
672 error (0, 0, _("missing operand"));
673 usage (EXIT_FAILURE);
676 format = argv[1];
677 argc -= 2;
678 argv += 2;
682 args_used = print_formatted (format, argc, argv);
683 argc -= args_used;
684 argv += args_used;
686 while (args_used > 0 && argc > 0);
688 if (argc > 0)
689 error (0, 0,
690 _("warning: ignoring excess arguments, starting with %s"),
691 quote (argv[0]));
693 exit (exit_status);