* src/dd.c (flags): noatime and nofollow now depend on
[coreutils/bo.git] / src / printf.c
blobbfb40728c9b5ca83fe67bdbca54bdb96b8906a29
1 /* printf - format and print data
2 Copyright (C) 1990-2006 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)
7 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, 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.
22 Backslash escapes:
24 \" = double quote
25 \\ = backslash
26 \a = alert (bell)
27 \b = backspace
28 \c = produce no further output
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 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> */
49 #include <config.h>
50 #include <stdio.h>
51 #include <sys/types.h>
52 #include <getopt.h>
54 #include "system.h"
55 #include "c-strtod.h"
56 #include "error.h"
57 #include "long-options.h"
58 #include "quote.h"
59 #include "unicodeio.h"
61 /* The official name of this program (e.g., no `g' prefix). */
62 #define PROGRAM_NAME "printf"
64 #define AUTHORS "David MacKenzie"
66 #define isodigit(c) ((c) >= '0' && (c) <= '7')
67 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
68 (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
69 #define octtobin(c) ((c) - '0')
71 /* The value to return to the calling program. */
72 static int exit_status;
74 /* True if the POSIXLY_CORRECT environment variable is set. */
75 static bool posixly_correct;
77 /* This message appears in N_() here rather than just in _() below because
78 the sole use would have been in a #define. */
79 static char *const cfcc_msg =
80 N_("warning: %s: character(s) following character constant have been ignored");
82 /* The name this program was run with. */
83 char *program_name;
85 void
86 usage (int status)
88 if (status != EXIT_SUCCESS)
89 fprintf (stderr, _("Try `%s --help' for more information.\n"),
90 program_name);
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.\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 \\NNN character with octal value NNN (1 to 3 digits)\n\
110 \\\\ backslash\n\
111 "), stdout);
112 fputs (_("\
113 \\a alert (BEL)\n\
114 \\b backspace\n\
115 \\c produce no further output\n\
116 \\f form feed\n\
117 "), stdout);
118 fputs (_("\
119 \\n new line\n\
120 \\r carriage return\n\
121 \\t horizontal tab\n\
122 \\v vertical tab\n\
123 "), stdout);
124 fputs (_("\
125 \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
126 \\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)\n\
127 \\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)\n\
128 "), stdout);
129 fputs (_("\
130 %% a single %\n\
131 %b ARGUMENT as a string with `\\' escapes interpreted,\n\
132 except that octal escapes are of the form \\0 or \\0NNN\n\
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\
136 "), stdout);
137 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
138 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
140 exit (status);
143 static void
144 verify_numeric (const char *s, const char *end)
146 if (errno)
148 error (0, errno, "%s", s);
149 exit_status = EXIT_FAILURE;
151 else if (*end)
153 if (s == end)
154 error (0, 0, _("%s: expected a numeric value"), s);
155 else
156 error (0, 0, _("%s: value not completely converted"), s);
157 exit_status = EXIT_FAILURE;
161 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR) \
162 static TYPE \
163 FUNC_NAME (char const *s) \
165 char *end; \
166 TYPE val; \
168 if (*s == '\"' || *s == '\'') \
170 unsigned char ch = *++s; \
171 val = ch; \
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); \
179 else \
181 errno = 0; \
182 val = (LIB_FUNC_EXPR); \
183 verify_numeric (s, end); \
185 return val; \
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. */
194 static void
195 print_esc_char (char c)
197 switch (c)
199 case 'a': /* Alert. */
200 putchar ('\a');
201 break;
202 case 'b': /* Backspace. */
203 putchar ('\b');
204 break;
205 case 'c': /* Cancel the rest of the output. */
206 exit (EXIT_SUCCESS);
207 break;
208 case 'f': /* Form feed. */
209 putchar ('\f');
210 break;
211 case 'n': /* New line. */
212 putchar ('\n');
213 break;
214 case 'r': /* Carriage return. */
215 putchar ('\r');
216 break;
217 case 't': /* Horizontal tab. */
218 putchar ('\t');
219 break;
220 case 'v': /* Vertical tab. */
221 putchar ('\v');
222 break;
223 default:
224 putchar (c);
225 break;
229 /* Print a \ escape sequence starting at ESCSTART.
230 Return the number of characters in the escape sequence
231 besides the backslash.
232 If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
233 is an octal digit; otherwise they are of the form \ooo. */
235 static int
236 print_esc (const char *escstart, bool octal_0)
238 const char *p = escstart + 1;
239 int esc_value = 0; /* Value of \nnn escape. */
240 int esc_length; /* Length of \nnn escape. */
242 if (*p == 'x')
244 /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
245 for (esc_length = 0, ++p;
246 esc_length < 2 && isxdigit (to_uchar (*p));
247 ++esc_length, ++p)
248 esc_value = esc_value * 16 + hextobin (*p);
249 if (esc_length == 0)
250 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
251 putchar (esc_value);
253 else if (isodigit (*p))
255 /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise).
256 Allow \ooo if octal_0 && *p != '0'; this is an undocumented
257 extension to POSIX that is compatible with Bash 2.05b. */
258 for (esc_length = 0, p += octal_0 && *p == '0';
259 esc_length < 3 && isodigit (*p);
260 ++esc_length, ++p)
261 esc_value = esc_value * 8 + octtobin (*p);
262 putchar (esc_value);
264 else if (*p && strchr ("\"\\abcfnrtv", *p))
265 print_esc_char (*p++);
266 else if (*p == 'u' || *p == 'U')
268 char esc_char = *p;
269 unsigned int uni_value;
271 uni_value = 0;
272 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
273 esc_length > 0;
274 --esc_length, ++p)
276 if (! isxdigit (to_uchar (*p)))
277 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
278 uni_value = uni_value * 16 + hextobin (*p);
281 /* A universal character name shall not specify a character short
282 identifier in the range 00000000 through 00000020, 0000007F through
283 0000009F, or 0000D800 through 0000DFFF inclusive. A universal
284 character name shall not designate a character in the required
285 character set. */
286 if ((uni_value <= 0x9f
287 && uni_value != 0x24 && uni_value != 0x40 && uni_value != 0x60)
288 || (uni_value >= 0xd800 && uni_value <= 0xdfff))
289 error (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"),
290 esc_char, (esc_char == 'u' ? 4 : 8), uni_value);
292 print_unicode_char (stdout, uni_value, 0);
294 else
296 putchar ('\\');
297 if (*p)
299 putchar (*p);
300 p++;
303 return p - escstart - 1;
306 /* Print string STR, evaluating \ escapes. */
308 static void
309 print_esc_string (const char *str)
311 for (; *str; str++)
312 if (*str == '\\')
313 str += print_esc (str, true);
314 else
315 putchar (*str);
318 /* Evaluate a printf conversion specification. START is the start of
319 the directive, LENGTH is its length, and CONVERSION specifies the
320 type of conversion. LENGTH does not include any length modifier or
321 the conversion specifier itself. FIELD_WIDTH and PRECISION are the
322 field width and precision for '*' values, if HAVE_FIELD_WIDTH and
323 HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
324 be formatted. */
326 static void
327 print_direc (const char *start, size_t length, char conversion,
328 bool have_field_width, int field_width,
329 bool have_precision, int precision,
330 char const *argument)
332 char *p; /* Null-terminated copy of % directive. */
334 /* Create a null-terminated copy of the % directive, with an
335 intmax_t-wide length modifier substituted for any existing
336 integer length modifier. */
338 char *q;
339 char const *length_modifier;
340 size_t length_modifier_len;
342 switch (conversion)
344 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
345 length_modifier = PRIdMAX;
346 length_modifier_len = sizeof PRIdMAX - 2;
347 break;
349 case 'a': case 'e': case 'f': case 'g':
350 case 'A': case 'E': case 'F': case 'G':
351 length_modifier = "L";
352 length_modifier_len = 1;
353 break;
355 default:
356 length_modifier = start; /* Any valid pointer will do. */
357 length_modifier_len = 0;
358 break;
361 p = xmalloc (length + length_modifier_len + 2);
362 q = mempcpy (p, start, length);
363 q = mempcpy (q, length_modifier, length_modifier_len);
364 *q++ = conversion;
365 *q = '\0';
368 switch (conversion)
370 case 'd':
371 case 'i':
373 intmax_t arg = vstrtoimax (argument);
374 if (!have_field_width)
376 if (!have_precision)
377 printf (p, arg);
378 else
379 printf (p, precision, arg);
381 else
383 if (!have_precision)
384 printf (p, field_width, arg);
385 else
386 printf (p, field_width, precision, arg);
389 break;
391 case 'o':
392 case 'u':
393 case 'x':
394 case 'X':
396 uintmax_t arg = vstrtoumax (argument);
397 if (!have_field_width)
399 if (!have_precision)
400 printf (p, arg);
401 else
402 printf (p, precision, arg);
404 else
406 if (!have_precision)
407 printf (p, field_width, arg);
408 else
409 printf (p, field_width, precision, arg);
412 break;
414 case 'a':
415 case 'A':
416 case 'e':
417 case 'E':
418 case 'f':
419 case 'F':
420 case 'g':
421 case 'G':
423 long double arg = vstrtold (argument);
424 if (!have_field_width)
426 if (!have_precision)
427 printf (p, arg);
428 else
429 printf (p, precision, arg);
431 else
433 if (!have_precision)
434 printf (p, field_width, arg);
435 else
436 printf (p, field_width, precision, arg);
439 break;
441 case 'c':
442 if (!have_field_width)
443 printf (p, *argument);
444 else
445 printf (p, field_width, *argument);
446 break;
448 case 's':
449 if (!have_field_width)
451 if (!have_precision)
452 printf (p, argument);
453 else
454 printf (p, precision, argument);
456 else
458 if (!have_precision)
459 printf (p, field_width, argument);
460 else
461 printf (p, field_width, precision, argument);
463 break;
466 free (p);
469 /* Print the text in FORMAT, using ARGV (with ARGC elements) for
470 arguments to any `%' directives.
471 Return the number of elements of ARGV used. */
473 static int
474 print_formatted (const char *format, int argc, char **argv)
476 int save_argc = argc; /* Preserve original value. */
477 const char *f; /* Pointer into `format'. */
478 const char *direc_start; /* Start of % directive. */
479 size_t direc_length; /* Length of % directive. */
480 bool have_field_width; /* True if FIELD_WIDTH is valid. */
481 int field_width = 0; /* Arg to first '*'. */
482 bool have_precision; /* True if PRECISION is valid. */
483 int precision = 0; /* Arg to second '*'. */
484 char ok[UCHAR_MAX + 1]; /* ok['x'] is true if %x is allowed. */
486 for (f = format; *f; ++f)
488 switch (*f)
490 case '%':
491 direc_start = f++;
492 direc_length = 1;
493 have_field_width = have_precision = false;
494 if (*f == '%')
496 putchar ('%');
497 break;
499 if (*f == 'b')
501 /* FIXME: Field width and precision are not supported
502 for %b, even though POSIX requires it. */
503 if (argc > 0)
505 print_esc_string (*argv);
506 ++argv;
507 --argc;
509 break;
512 memset (ok, 0, sizeof ok);
513 ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
514 ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
515 ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
517 for (;; f++, direc_length++)
518 switch (*f)
520 #if (__GLIBC__ == 2 && 2 <= __GLIBC_MINOR__) || 3 <= __GLIBC__
521 case 'I':
522 #endif
523 case '\'':
524 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
525 ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
526 break;
527 case '-': case '+': case ' ':
528 break;
529 case '#':
530 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
531 break;
532 case '0':
533 ok['c'] = ok['s'] = 0;
534 break;
535 default:
536 goto no_more_flag_characters;
538 no_more_flag_characters:;
540 if (*f == '*')
542 ++f;
543 ++direc_length;
544 if (argc > 0)
546 intmax_t width = vstrtoimax (*argv);
547 if (INT_MIN <= width && width <= INT_MAX)
548 field_width = width;
549 else
550 error (EXIT_FAILURE, 0, _("invalid field width: %s"),
551 *argv);
552 ++argv;
553 --argc;
555 else
556 field_width = 0;
557 have_field_width = true;
559 else
560 while (ISDIGIT (*f))
562 ++f;
563 ++direc_length;
565 if (*f == '.')
567 ++f;
568 ++direc_length;
569 ok['c'] = 0;
570 if (*f == '*')
572 ++f;
573 ++direc_length;
574 if (argc > 0)
576 intmax_t prec = vstrtoimax (*argv);
577 if (prec < 0)
579 /* A negative precision is taken as if the
580 precision were omitted, so -1 is safe
581 here even if prec < INT_MIN. */
582 precision = -1;
584 else if (INT_MAX < prec)
585 error (EXIT_FAILURE, 0, _("invalid precision: %s"),
586 *argv);
587 else
588 precision = prec;
589 ++argv;
590 --argc;
592 else
593 precision = 0;
594 have_precision = true;
596 else
597 while (ISDIGIT (*f))
599 ++f;
600 ++direc_length;
604 while (*f == 'l' || *f == 'L' || *f == 'h'
605 || *f == 'j' || *f == 't' || *f == 'z')
606 ++f;
609 unsigned char conversion = *f;
610 if (! ok[conversion])
611 error (EXIT_FAILURE, 0,
612 _("%.*s: invalid conversion specification"),
613 (int) (f + 1 - direc_start), direc_start);
616 print_direc (direc_start, direc_length, *f,
617 have_field_width, field_width,
618 have_precision, precision,
619 (argc <= 0 ? "" : (argc--, *argv++)));
620 break;
622 case '\\':
623 f += print_esc (f, false);
624 break;
626 default:
627 putchar (*f);
631 return save_argc - argc;
635 main (int argc, char **argv)
637 char *format;
638 int args_used;
640 initialize_main (&argc, &argv);
641 program_name = argv[0];
642 setlocale (LC_ALL, "");
643 bindtextdomain (PACKAGE, LOCALEDIR);
644 textdomain (PACKAGE);
646 atexit (close_stdout);
648 exit_status = EXIT_SUCCESS;
650 posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
652 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
653 usage, AUTHORS, (char const *) NULL);
655 /* The above handles --help and --version.
656 Since there is no other invocation of getopt, handle `--' here. */
657 if (1 < argc && STREQ (argv[1], "--"))
659 --argc;
660 ++argv;
663 if (argc <= 1)
665 error (0, 0, _("missing operand"));
666 usage (EXIT_FAILURE);
669 format = argv[1];
670 argc -= 2;
671 argv += 2;
675 args_used = print_formatted (format, argc, argv);
676 argc -= args_used;
677 argv += args_used;
679 while (args_used > 0 && argc > 0);
681 if (argc > 0)
682 error (0, 0,
683 _("warning: ignoring excess arguments, starting with %s"),
684 quote (argv[0]));
686 exit (exit_status);