*** empty log message ***
[platform/upstream/coreutils.git] / src / printf.c
1 /* printf - format and print data
2    Copyright (C) 1990-2005 Free Software Foundation, Inc.
3
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.
8
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.
13
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.  */
17
18 /* Usage: printf format [argument...]
19
20    A front end to the printf function that lets it be used from the shell.
21
22    Backslash escapes:
23
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)
38
39    Additional directive:
40
41    %b = print an argument string, interpreting backslash escapes,
42      except that octal escapes are of the form \0 or \0ooo.
43
44    The `format' argument is re-used as many times as necessary
45    to convert all of the given arguments.
46
47    David MacKenzie <djm@gnu.ai.mit.edu> */
48
49 #include <config.h>
50 #include <stdio.h>
51 #include <sys/types.h>
52 #include <getopt.h>
53
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"
60
61 #if ! (HAVE_DECL_STRTOIMAX || defined strtoimax)
62 intmax_t strtoimax ();
63 #endif
64 #if ! (HAVE_DECL_STRTOUMAX || defined strtoumax)
65 uintmax_t strtoumax ();
66 #endif
67
68 /* The official name of this program (e.g., no `g' prefix).  */
69 #define PROGRAM_NAME "printf"
70
71 #define AUTHORS "David MacKenzie"
72
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')
77
78 /* The value to return to the calling program.  */
79 static int exit_status;
80
81 /* True if the POSIXLY_CORRECT environment variable is set.  */
82 static bool posixly_correct;
83
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");
88
89 /* The name this program was run with. */
90 char *program_name;
91
92 void
93 usage (int status)
94 {
95   if (status != EXIT_SUCCESS)
96     fprintf (stderr, _("Try `%s --help' for more information.\n"),
97              program_name);
98   else
99     {
100       printf (_("\
101 Usage: %s FORMAT [ARGUMENT]...\n\
102   or:  %s OPTION\n\
103 "),
104               program_name, program_name);
105       fputs (_("\
106 Print ARGUMENT(s) according to FORMAT.\n\
107 \n\
108 "), stdout);
109       fputs (HELP_OPTION_DESCRIPTION, stdout);
110       fputs (VERSION_OPTION_DESCRIPTION, stdout);
111       fputs (_("\
112 \n\
113 FORMAT controls the output as in C printf.  Interpreted sequences are:\n\
114 \n\
115   \\\"      double quote\n\
116   \\NNN    character with octal value NNN (1 to 3 digits)\n\
117   \\\\      backslash\n\
118 "), stdout);
119       fputs (_("\
120   \\a      alert (BEL)\n\
121   \\b      backspace\n\
122   \\c      produce no further output\n\
123   \\f      form feed\n\
124 "), stdout);
125       fputs (_("\
126   \\n      new line\n\
127   \\r      carriage return\n\
128   \\t      horizontal tab\n\
129   \\v      vertical tab\n\
130 "), stdout);
131       fputs (_("\
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\
135 "), stdout);
136       fputs (_("\
137   %%      a single %\n\
138   %b      ARGUMENT as a string with `\\' escapes interpreted,\n\
139             except that octal escapes are of the form \\0 or \\0NNN\n\
140 \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\
143 "), stdout);
144       printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
145       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
146     }
147   exit (status);
148 }
149
150 static void
151 verify_numeric (const char *s, const char *end)
152 {
153   if (errno)
154     {
155       error (0, errno, "%s", s);
156       exit_status = EXIT_FAILURE;
157     }
158   else if (*end)
159     {
160       if (s == end)
161         error (0, 0, _("%s: expected a numeric value"), s);
162       else
163         error (0, 0, _("%s: value not completely converted"), s);
164       exit_status = EXIT_FAILURE;
165     }
166 }
167
168 #define STRTOX(TYPE, FUNC_NAME, LIB_FUNC_EXPR)                           \
169 static TYPE                                                              \
170 FUNC_NAME (char const *s)                                                \
171 {                                                                        \
172   char *end;                                                             \
173   TYPE val;                                                              \
174                                                                          \
175   if (*s == '\"' || *s == '\'')                                          \
176     {                                                                    \
177       unsigned char ch = *++s;                                           \
178       val = ch;                                                          \
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);                                    \
185     }                                                                    \
186   else                                                                   \
187     {                                                                    \
188       errno = 0;                                                         \
189       val = (LIB_FUNC_EXPR);                                             \
190       verify_numeric (s, end);                                           \
191     }                                                                    \
192   return val;                                                            \
193 }                                                                        \
194
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))
198
199 /* Output a single-character \ escape.  */
200
201 static void
202 print_esc_char (char c)
203 {
204   switch (c)
205     {
206     case 'a':                   /* Alert. */
207       putchar ('\a');
208       break;
209     case 'b':                   /* Backspace. */
210       putchar ('\b');
211       break;
212     case 'c':                   /* Cancel the rest of the output. */
213       exit (EXIT_SUCCESS);
214       break;
215     case 'f':                   /* Form feed. */
216       putchar ('\f');
217       break;
218     case 'n':                   /* New line. */
219       putchar ('\n');
220       break;
221     case 'r':                   /* Carriage return. */
222       putchar ('\r');
223       break;
224     case 't':                   /* Horizontal tab. */
225       putchar ('\t');
226       break;
227     case 'v':                   /* Vertical tab. */
228       putchar ('\v');
229       break;
230     default:
231       putchar (c);
232       break;
233     }
234 }
235
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.  */
241
242 static int
243 print_esc (const char *escstart, bool octal_0)
244 {
245   const char *p = escstart + 1;
246   int esc_value = 0;            /* Value of \nnn escape. */
247   int esc_length;               /* Length of \nnn escape. */
248
249   if (*p == 'x')
250     {
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);
254            ++esc_length, ++p)
255         esc_value = esc_value * 16 + hextobin (*p);
256       if (esc_length == 0)
257         error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
258       putchar (esc_value);
259     }
260   else if (isodigit (*p))
261     {
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);
267            ++esc_length, ++p)
268         esc_value = esc_value * 8 + octtobin (*p);
269       putchar (esc_value);
270     }
271   else if (*p && strchr ("\"\\abcfnrtv", *p))
272     print_esc_char (*p++);
273   else if (*p == 'u' || *p == 'U')
274     {
275       char esc_char = *p;
276       unsigned int uni_value;
277
278       uni_value = 0;
279       for (esc_length = (esc_char == 'u' ? 4 : 8), ++p;
280            esc_length > 0;
281            --esc_length, ++p)
282         {
283           if (!ISXDIGIT (*p))
284             error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
285           uni_value = uni_value * 16 + hextobin (*p);
286         }
287
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
292          character set.  */
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);
298
299       print_unicode_char (stdout, uni_value, 0);
300     }
301   else
302     {
303       putchar ('\\');
304       if (*p)
305         {
306           putchar (*p);
307           p++;
308         }
309     }
310   return p - escstart - 1;
311 }
312
313 /* Print string STR, evaluating \ escapes. */
314
315 static void
316 print_esc_string (const char *str)
317 {
318   for (; *str; str++)
319     if (*str == '\\')
320       str += print_esc (str, true);
321     else
322       putchar (*str);
323 }
324
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
331    be formatted.  */
332
333 static void
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)
338 {
339   char *p;              /* Null-terminated copy of % directive. */
340
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.  */
344   {
345     char *q;
346     char const *length_modifier;
347     size_t length_modifier_len;
348
349     switch (conversion)
350       {
351       case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
352         length_modifier = PRIdMAX;
353         length_modifier_len = sizeof PRIdMAX - 2;
354         break;
355
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;
360         break;
361
362       default:
363         length_modifier = start;  /* Any valid pointer will do.  */
364         length_modifier_len = 0;
365         break;
366       }
367
368     p = xmalloc (length + length_modifier_len + 2);
369     q = mempcpy (p, start, length);
370     q = mempcpy (q, length_modifier, length_modifier_len);
371     *q++ = conversion;
372     *q = '\0';
373   }
374
375   switch (conversion)
376     {
377     case 'd':
378     case 'i':
379       {
380         intmax_t arg = vstrtoimax (argument);
381         if (!have_field_width)
382           {
383             if (!have_precision)
384               printf (p, arg);
385             else
386               printf (p, precision, arg);
387           }
388         else
389           {
390             if (!have_precision)
391               printf (p, field_width, arg);
392             else
393               printf (p, field_width, precision, arg);
394           }
395       }
396       break;
397
398     case 'o':
399     case 'u':
400     case 'x':
401     case 'X':
402       {
403         uintmax_t arg = vstrtoumax (argument);
404         if (!have_field_width)
405           {
406             if (!have_precision)
407               printf (p, arg);
408             else
409               printf (p, precision, arg);
410           }
411         else
412           {
413             if (!have_precision)
414               printf (p, field_width, arg);
415             else
416               printf (p, field_width, precision, arg);
417           }
418       }
419       break;
420
421     case 'a':
422     case 'A':
423     case 'e':
424     case 'E':
425     case 'f':
426     case 'F':
427     case 'g':
428     case 'G':
429       {
430         long double arg = vstrtold (argument);
431         if (!have_field_width)
432           {
433             if (!have_precision)
434               printf (p, arg);
435             else
436               printf (p, precision, arg);
437           }
438         else
439           {
440             if (!have_precision)
441               printf (p, field_width, arg);
442             else
443               printf (p, field_width, precision, arg);
444           }
445       }
446       break;
447
448     case 'c':
449       if (!have_field_width)
450         printf (p, *argument);
451       else
452         printf (p, field_width, *argument);
453       break;
454
455     case 's':
456       if (!have_field_width)
457         {
458           if (!have_precision)
459             printf (p, argument);
460           else
461             printf (p, precision, argument);
462         }
463       else
464         {
465           if (!have_precision)
466             printf (p, field_width, argument);
467           else
468             printf (p, field_width, precision, argument);
469         }
470       break;
471     }
472
473   free (p);
474 }
475
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.  */
479
480 static int
481 print_formatted (const char *format, int argc, char **argv)
482 {
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.  */
492
493   for (f = format; *f; ++f)
494     {
495       switch (*f)
496         {
497         case '%':
498           direc_start = f++;
499           direc_length = 1;
500           have_field_width = have_precision = false;
501           if (*f == '%')
502             {
503               putchar ('%');
504               break;
505             }
506           if (*f == 'b')
507             {
508               /* FIXME: Field width and precision are not supported
509                  for %b, even though POSIX requires it.  */
510               if (argc > 0)
511                 {
512                   print_esc_string (*argv);
513                   ++argv;
514                   --argc;
515                 }
516               break;
517             }
518
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;
523
524           for (;; f++, direc_length++)
525             switch (*f)
526               {
527               case '\'':
528                 ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
529                   ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
530                 break;
531               case '-': case '+': case ' ':
532                 break;
533               case '#':
534                 ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
535                 break;
536               case '0':
537                 ok['c'] = ok['s'] = 0;
538                 break;
539               default:
540                 goto no_more_flag_characters;
541               }
542         no_more_flag_characters:;
543
544           if (*f == '*')
545             {
546               ++f;
547               ++direc_length;
548               if (argc > 0)
549                 {
550                   intmax_t width = vstrtoimax (*argv);
551                   if (INT_MIN <= width && width <= INT_MAX)
552                     field_width = width;
553                   else
554                     error (EXIT_FAILURE, 0, _("invalid field width: %s"),
555                            *argv);
556                   ++argv;
557                   --argc;
558                 }
559               else
560                 field_width = 0;
561               have_field_width = true;
562             }
563           else
564             while (ISDIGIT (*f))
565               {
566                 ++f;
567                 ++direc_length;
568               }
569           if (*f == '.')
570             {
571               ++f;
572               ++direc_length;
573               ok['c'] = 0;
574               if (*f == '*')
575                 {
576                   ++f;
577                   ++direc_length;
578                   if (argc > 0)
579                     {
580                       intmax_t prec = vstrtoimax (*argv);
581                       if (prec < 0)
582                         {
583                           /* A negative precision is taken as if the
584                              precision were omitted, so -1 is safe
585                              here even if prec < INT_MIN.  */
586                           precision = -1;
587                         }
588                       else if (INT_MAX < prec)
589                         error (EXIT_FAILURE, 0, _("invalid precision: %s"),
590                                *argv);
591                       else
592                         precision = prec;
593                       ++argv;
594                       --argc;
595                     }
596                   else
597                     precision = 0;
598                   have_precision = true;
599                 }
600               else
601                 while (ISDIGIT (*f))
602                   {
603                     ++f;
604                     ++direc_length;
605                   }
606             }
607
608           while (*f == 'l' || *f == 'L' || *f == 'h'
609                  || *f == 'j' || *f == 't' || *f == 'z')
610             ++f;
611
612           {
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);
618           }
619
620           print_direc (direc_start, direc_length, *f,
621                        have_field_width, field_width,
622                        have_precision, precision,
623                        (argc <= 0 ? "" : (argc--, *argv++)));
624           break;
625
626         case '\\':
627           f += print_esc (f, false);
628           break;
629
630         default:
631           putchar (*f);
632         }
633     }
634
635   return save_argc - argc;
636 }
637
638 int
639 main (int argc, char **argv)
640 {
641   char *format;
642   int args_used;
643
644   initialize_main (&argc, &argv);
645   program_name = argv[0];
646   setlocale (LC_ALL, "");
647   bindtextdomain (PACKAGE, LOCALEDIR);
648   textdomain (PACKAGE);
649
650   atexit (close_stdout);
651
652   exit_status = EXIT_SUCCESS;
653
654   posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
655
656   parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
657                       usage, AUTHORS, (char const *) NULL);
658
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], "--"))
662     {
663       --argc;
664       ++argv;
665     }
666
667   if (argc <= 1)
668     {
669       error (0, 0, _("missing operand"));
670       usage (EXIT_FAILURE);
671     }
672
673   format = argv[1];
674   argc -= 2;
675   argv += 2;
676
677   do
678     {
679       args_used = print_formatted (format, argc, argv);
680       argc -= args_used;
681       argv += args_used;
682     }
683   while (args_used > 0 && argc > 0);
684
685   if (argc > 0)
686     error (0, 0,
687            _("warning: ignoring excess arguments, starting with %s"),
688            quote (argv[0]));
689
690   exit (exit_status);
691 }