1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library 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 GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
31 #include "../locale/localeinfo.h"
33 /* Include the shared code for parsing the format string. */
34 #include "printf-parse.h"
37 /* This function from the GNU C library is also used in libio.
38 To compile for use in libio, compile with -DUSE_IN_LIBIO. */
41 /* This code is for use in libio. */
43 #define PUT(f, s, n) _IO_sputn (f, s, n)
44 #define PAD(padchar) \
45 if (specs[cnt].info.width > 0) \
46 done += _IO_padn (s, padchar, specs[cnt].info.width)
47 #define PUTC(c, f) _IO_putc (c, f)
48 #define vfprintf _IO_vfprintf
49 #define size_t _IO_size_t
51 #define va_list _IO_va_list
53 #define BUFSIZ _IO_BUFSIZ
54 #define ARGCHECK(s, format) \
57 /* Check file argument for consistence. */ \
59 if (s->_flags & _IO_NO_WRITES || format == NULL) \
65 #define UNBUFFERED_P(s) ((s)->_IO_file_flags & _IO_UNBUFFERED)
66 #else /* ! USE_IN_LIBIO */
67 /* This code is for use in the GNU C library. */
69 #define PUTC(c, f) putc (c, f)
70 #define PUT(f, s, n) fwrite (s, 1, n, f)
71 ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
72 #define PAD(padchar) \
73 if (specs[cnt].info.width > 0) \
74 { if (__printf_pad (s, padchar, specs[cnt].info.width) == -1) \
75 return -1; else done += specs[cnt].info.width; }
76 #define ARGCHECK(s, format) \
79 /* Check file argument for consistence. */ \
80 if (!__validfp(s) || !s->__mode.__write || format == NULL) \
87 if (__flshfp (s, EOF) == EOF) \
91 #define UNBUFFERED_P(s) ((s)->__buffer == NULL)
92 #endif /* USE_IN_LIBIO */
98 register const int outc = (x); \
99 if (PUTC (outc, s) == EOF) \
105 #define outstring(string, len) \
110 if (PUT (s, string, len) != len) \
116 register const char *cp = string; \
117 register int l = len; \
123 /* Helper function to provide temporary buffering for unbuffered streams. */
124 static int buffered_vfprintf __P ((FILE *stream, const char *fmt, va_list));
126 static printf_function printf_unknown;
128 extern printf_function **__printf_function_table;
130 static char *group_number __P ((char *, char *, const char *, wchar_t));
134 vfprintf (s, format, ap)
139 /* The character used as thousands separator. */
140 wchar_t thousands_sep;
142 /* The string describing the size of groups of digits. */
143 const char *grouping;
145 /* Array with information about the needed arguments. This has to be
146 dynamically extendable. */
149 struct printf_spec *specs;
151 /* The number of arguments the format string requests. This will
152 determine the size of the array needed to store the argument
156 union printf_arg *args_value;
158 /* Positional parameters refer to arguments directly. This could also
159 determine the maximum number of arguments. Track the maximum number. */
162 /* End of leading constant string. */
163 const char *lead_str_end;
165 /* Number of characters written. */
166 register size_t done = 0;
168 /* Running pointer through format string. */
171 /* Just a counter. */
174 ARGCHECK (s, format);
176 if (UNBUFFERED_P (s))
177 /* Use a helper function which will allocate a local temporary buffer
178 for the stream and then call us again. */
179 return buffered_vfprintf (s, format, ap);
181 /* Reset multibyte characters to their initial state. */
182 (void) mblen ((char *) NULL, 0);
184 /* Figure out the thousands separator character. */
185 if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
186 strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
187 thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
188 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
189 if (*grouping == '\0' || *grouping == CHAR_MAX || thousands_sep == L'\0')
192 nspecs_max = 32; /* A more or less arbitrary start value. */
193 specs = alloca (nspecs_max * sizeof (struct printf_spec));
198 /* Find the first format specifier. */
199 lead_str_end = find_spec (format);
201 for (f = lead_str_end; *f != '\0'; f = specs[nspecs++].next_fmt)
203 if (nspecs >= nspecs_max)
205 /* Extend the array of format specifiers. */
206 struct printf_spec *old = specs;
209 specs = alloca (nspecs_max * sizeof (struct printf_spec));
210 if (specs == &old[nspecs])
211 /* Stack grows up, OLD was the last thing allocated; extend it. */
212 nspecs_max += nspecs_max / 2;
215 /* Copy the old array's elements to the new space. */
216 memcpy (specs, old, nspecs * sizeof (struct printf_spec));
217 if (old == &specs[nspecs])
218 /* Stack grows down, OLD was just below the new SPECS.
219 We can use that space when the new space runs out. */
220 nspecs_max += nspecs_max / 2;
224 /* Parse the format specifier. */
225 nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg);
228 /* Determine the number of arguments the format string consumes. */
229 nargs = MAX (nargs, max_ref_arg);
231 /* Allocate memory for the argument descriptions. */
232 args_type = alloca (nargs * sizeof (int));
233 memset (args_type, 0, nargs * sizeof (int));
234 args_value = alloca (nargs * sizeof (union printf_arg));
236 /* XXX Could do sanity check here: If any element in ARGS_TYPE is
237 still zero after this loop, format is invalid. For now we simply
238 use 0 as the value. */
240 /* Fill in the types of all the arguments. */
241 for (cnt = 0; cnt < nspecs; ++cnt)
243 /* If the width is determined by an argument this is an int. */
244 if (specs[cnt].width_arg != -1)
245 args_type[specs[cnt].width_arg] = PA_INT;
247 /* If the precision is determined by an argument this is an int. */
248 if (specs[cnt].prec_arg != -1)
249 args_type[specs[cnt].prec_arg] = PA_INT;
251 switch (specs[cnt].ndata_args)
253 case 0: /* No arguments. */
255 case 1: /* One argument; we already have the type. */
256 args_type[specs[cnt].data_arg] = specs[cnt].data_arg_type;
259 /* We have more than one argument for this format spec. We must
260 call the arginfo function again to determine all the types. */
261 (void) (*__printf_arginfo_table[specs[cnt].info.spec])
263 specs[cnt].ndata_args, &args_type[specs[cnt].data_arg]);
268 /* Now we know all the types and the order. Fill in the argument values. */
269 for (cnt = 0; cnt < nargs; ++cnt)
270 switch (args_type[cnt])
272 #define T(tag, mem, type) \
274 args_value[cnt].mem = va_arg (ap, type); \
277 T (PA_CHAR, pa_char, int); /* Promoted. */
278 T (PA_INT|PA_FLAG_SHORT, pa_short_int, int); /* Promoted. */
279 T (PA_INT, pa_int, int);
280 T (PA_INT|PA_FLAG_LONG, pa_long_int, long int);
281 T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int);
282 T (PA_FLOAT, pa_float, double); /* Promoted. */
283 T (PA_DOUBLE, pa_double, double);
284 T (PA_DOUBLE|PA_FLAG_LONG_DOUBLE, pa_long_double, long double);
285 T (PA_STRING, pa_string, const char *);
286 T (PA_POINTER, pa_pointer, void *);
289 if ((args_type[cnt] & PA_FLAG_PTR) != 0)
290 args_value[cnt].pa_pointer = va_arg (ap, void *);
292 args_value[cnt].pa_long_double = 0.0;
296 /* Write the literal text before the first format. */
297 outstring (format, lead_str_end - format);
299 /* Now walk through all format specifiers and process them. */
300 for (cnt = 0; cnt < nspecs; ++cnt)
302 printf_function *function; /* Auxiliary function to do output. */
303 int is_neg; /* Decimal integer is negative. */
304 int base; /* Base of a number to be written. */
305 unsigned long long int num; /* Integral number to be written. */
306 const char *str; /* String to be written. */
307 char errorbuf[1024]; /* Buffer sometimes used by %m. */
309 if (specs[cnt].width_arg != -1)
311 /* Extract the field width from an argument. */
312 specs[cnt].info.width = args_value[specs[cnt].width_arg].pa_int;
314 if (specs[cnt].info.width < 0)
315 /* If the width value is negative left justification is selected
316 and the value is taken as being positive. */
318 specs[cnt].info.width = -specs[cnt].info.width;
319 specs[cnt].info.left = 1;
323 if (specs[cnt].prec_arg != -1)
325 /* Extract the precision from an argument. */
326 specs[cnt].info.prec = args_value[specs[cnt].prec_arg].pa_int;
328 if (specs[cnt].info.prec < 0)
329 /* If the precision is negative the precision is omitted. */
330 specs[cnt].info.prec = -1;
333 /* Check for a user-defined handler for this spec. */
334 function = (__printf_function_table == NULL ? NULL :
335 __printf_function_table[specs[cnt].info.spec]);
337 if (function != NULL)
338 use_function: /* Built-in formats with helpers use this. */
342 const void *ptr[specs[cnt].ndata_args];
344 /* Fill in an array of pointers to the argument values. */
345 for (i = 0; i < specs[cnt].ndata_args; ++i)
346 ptr[i] = &args_value[specs[cnt].data_arg + i];
348 /* Call the function. */
349 function_done = (*function) (s, &specs[cnt].info, ptr);
351 /* If an error occured don't do any further work. */
352 if (function_done < 0)
355 done += function_done;
358 switch (specs[cnt].info.spec)
361 /* Write a literal "%". */
367 long long int signed_num;
369 /* Decimal integer. */
371 if (specs[cnt].info.is_longlong)
372 signed_num = args_value[specs[cnt].data_arg].pa_long_long_int;
373 else if (specs[cnt].info.is_long)
374 signed_num = args_value[specs[cnt].data_arg].pa_long_int;
375 else if (!specs[cnt].info.is_short)
376 signed_num = args_value[specs[cnt].data_arg].pa_int;
378 signed_num = args_value[specs[cnt].data_arg].pa_short_int;
380 is_neg = signed_num < 0;
381 num = is_neg ? (- signed_num) : signed_num;
386 /* Decimal unsigned integer. */
388 goto unsigned_number;
391 /* Octal unsigned integer. */
393 goto unsigned_number;
396 /* Hexadecimal unsigned integer. */
398 /* Hex with lower-case digits. */
402 /* Unsigned number of base BASE. */
404 if (specs[cnt].info.is_longlong)
405 num = args_value[specs[cnt].data_arg].pa_u_long_long_int;
406 else if (specs[cnt].info.is_long)
407 num = args_value[specs[cnt].data_arg].pa_u_long_int;
408 else if (!specs[cnt].info.is_short)
409 num = args_value[specs[cnt].data_arg].pa_u_int;
411 num = args_value[specs[cnt].data_arg].pa_u_short_int;
413 /* ANSI only specifies the `+' and
414 ` ' flags for signed conversions. */
416 specs[cnt].info.showsign = 0;
417 specs[cnt].info.space = 0;
420 /* Number of base BASE. */
423 char *const workend = &work[sizeof(work) - 1];
426 if (specs[cnt].info.prec == -1)
427 /* Supply a default precision if none was given. */
428 specs[cnt].info.prec = 1;
430 /* We have to take care for the '0' flag. If a
431 precision is given it must be ignored. */
432 specs[cnt].info.pad = ' ';
434 /* If the precision is 0 and the number is 0 nothing has
435 to be written for the number. */
436 if (specs[cnt].info.prec == 0 && num == 0)
440 /* Put the number in WORK. */
441 w = _itoa (num, workend + 1, base,
442 specs[cnt].info.spec == 'X');
444 if (specs[cnt].info.group && grouping)
445 w = group_number (w, workend, grouping, thousands_sep);
447 specs[cnt].info.width -= workend - w;
448 specs[cnt].info.prec -= workend - w;
450 if (num != 0 && specs[cnt].info.alt && base == 8
451 && specs[cnt].info.prec <= 0)
453 /* Add octal marker. */
455 --specs[cnt].info.width;
458 if (specs[cnt].info.prec > 0)
460 /* Add zeros to the precision. */
461 specs[cnt].info.width -= specs[cnt].info.prec;
462 while (specs[cnt].info.prec-- > 0)
466 if (num != 0 && specs[cnt].info.alt && base == 16)
467 /* Account for 0X hex marker. */
468 specs[cnt].info.width -= 2;
470 if (is_neg || specs[cnt].info.showsign || specs[cnt].info.space)
471 --specs[cnt].info.width;
473 if (!specs[cnt].info.left && specs[cnt].info.pad == ' ')
478 else if (specs[cnt].info.showsign)
480 else if (specs[cnt].info.space)
483 if (num != 0 && specs[cnt].info.alt && base == 16)
486 outchar (specs[cnt].info.spec);
489 if (!specs[cnt].info.left && specs[cnt].info.pad == '0')
492 /* Write the number. */
493 while (++w <= workend)
496 if (specs[cnt].info.left)
507 /* Floating-point number. This is handled by printf_fp.c. */
508 extern printf_function __printf_fp;
509 function = __printf_fp;
515 --specs[cnt].info.width;/* Account for the character itself. */
516 if (!specs[cnt].info.left)
518 outchar ((unsigned char) args_value[specs[cnt].data_arg].pa_char);
519 if (specs[cnt].info.left)
525 static const char null[] = "(null)";
528 str = args_value[specs[cnt].data_arg].pa_string;
534 /* Write "(null)" if there's space. */
535 if (specs[cnt].info.prec == -1
536 || specs[cnt].info.prec >= (int) sizeof (null) - 1)
539 len = sizeof (null) - 1;
547 else if (specs[cnt].info.prec != -1)
549 /* Search for the end of the string, but don't search
550 past the length specified by the precision. */
551 const char *end = memchr (str, '\0', specs[cnt].info.prec);
555 len = specs[cnt].info.prec;
560 specs[cnt].info.width -= len;
562 if (!specs[cnt].info.left)
564 outstring (str, len);
565 if (specs[cnt].info.left)
571 /* Generic pointer. */
574 ptr = args_value[specs[cnt].data_arg].pa_pointer;
577 /* If the pointer is not NULL, write it as a %#x spec. */
579 num = (unsigned long long int) (unsigned long int) ptr;
581 specs[cnt].info.alt = 1;
582 specs[cnt].info.spec = 'x';
583 specs[cnt].info.group = 0;
588 /* Write "(nil)" for a nil pointer. */
590 /* Make sure the full string "(nil)" is printed. */
591 if (specs[cnt].info.prec < 5)
592 specs[cnt].info.prec = 5;
599 /* Answer the count of characters written. */
600 if (specs[cnt].info.is_longlong)
602 args_value[specs[cnt].data_arg].pa_pointer = done;
603 else if (specs[cnt].info.is_long)
605 args_value[specs[cnt].data_arg].pa_pointer = done;
606 else if (!specs[cnt].info.is_short)
608 args_value[specs[cnt].data_arg].pa_pointer = done;
611 args_value[specs[cnt].data_arg].pa_pointer = done;
616 extern char *_strerror_internal __P ((int, char *buf, size_t));
617 str = _strerror_internal (errno, errorbuf, sizeof errorbuf);
622 /* Unrecognized format specifier. */
623 function = printf_unknown;
627 /* Write the following constant string. */
628 outstring (specs[cnt].end_of_fmt,
629 specs[cnt].next_fmt - specs[cnt].end_of_fmt);
638 /* This is for glibc. */
639 strong_alias (_IO_vfprintf, vfprintf)
641 # if defined __ELF__ || defined __GNU_LIBRARY__
642 # include <gnu-stabs.h>
644 weak_alias (_IO_vfprintf, vfprintf);
651 /* Handle an unknown format specifier. This prints out a canonicalized
652 representation of the format spec itself. */
655 printf_unknown (s, info, args)
657 const struct printf_info *info;
658 const void **const args;
662 char *const workend = &work[sizeof(work) - 1];
673 else if (info->space)
677 if (info->pad == '0')
680 if (info->width != 0)
682 w = _itoa (info->width, workend + 1, 10, 0);
683 while (++w <= workend)
687 if (info->prec != -1)
690 w = _itoa (info->prec, workend + 1, 10, 0);
691 while (++w <= workend)
695 if (info->spec != '\0')
696 outchar (info->spec);
701 /* Group the digits according to the grouping rules of the current locale.
702 The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */
705 group_number (char *w, char *workend, const char *grouping,
706 wchar_t thousands_sep)
711 /* We treat all negative values like CHAR_MAX. */
713 if (*grouping == CHAR_MAX || *grouping < 0)
714 /* No grouping should be done. */
719 /* Copy existing string so that nothing gets overwritten. */
720 src = (char *) alloca (workend - w);
721 memcpy (src, w + 1, workend - w);
722 s = &src[workend - w - 1];
725 /* Process all characters in the string. */
730 if (--len == 0 && s >= src)
732 /* A new group begins. */
733 *w-- = thousands_sep;
736 if (*grouping == '\0')
737 /* The previous grouping repeats ad infinitum. */
739 else if (*grouping == CHAR_MAX || *grouping < 0)
741 /* No further grouping to be done.
742 Copy the rest of the number. */
754 /* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */
757 struct _IO_FILE_plus _f;
758 _IO_FILE *_put_stream;
762 _IO_helper_overflow (s, c)
766 _IO_FILE *target = ((struct helper_file*) s)->_put_stream;
767 int used = s->_IO_write_ptr - s->_IO_write_base;
770 _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used);
771 s->_IO_write_ptr -= written;
773 return _IO_putc (c, s);
776 static const struct _IO_jump_t _IO_helper_jumps =
779 JUMP_INIT (finish, _IO_default_finish),
780 JUMP_INIT (overflow, _IO_helper_overflow),
781 JUMP_INIT (underflow, _IO_default_underflow),
782 JUMP_INIT (uflow, _IO_default_uflow),
783 JUMP_INIT (pbackfail, _IO_default_pbackfail),
784 JUMP_INIT (xsputn, _IO_default_xsputn),
785 JUMP_INIT (xsgetn, _IO_default_xsgetn),
786 JUMP_INIT (seekoff, _IO_default_seekoff),
787 JUMP_INIT (seekpos, _IO_default_seekpos),
788 JUMP_INIT (setbuf, _IO_default_setbuf),
789 JUMP_INIT (sync, _IO_default_sync),
790 JUMP_INIT (doallocate, _IO_default_doallocate),
791 JUMP_INIT (read, _IO_default_read),
792 JUMP_INIT (write, _IO_default_write),
793 JUMP_INIT (seek, _IO_default_seek),
794 JUMP_INIT (close, _IO_default_close),
795 JUMP_INIT (stat, _IO_default_stat)
799 buffered_vfprintf (s, format, args)
800 register _IO_FILE *s;
804 char buf[_IO_BUFSIZ];
805 struct helper_file helper;
806 register _IO_FILE *hp = (_IO_FILE *) &helper;
807 int result, to_flush;
809 /* Initialize helper. */
810 helper._put_stream = s;
811 hp->_IO_write_base = buf;
812 hp->_IO_write_ptr = buf;
813 hp->_IO_write_end = buf + sizeof buf;
814 hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
815 _IO_JUMPS (hp) = (struct _IO_jump_t *) &_IO_helper_jumps;
817 /* Now print to helper instead. */
818 result = _IO_vfprintf (hp, format, args);
820 /* Now flush anything from the helper to the S. */
821 if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
823 if (_IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush)
830 #else /* !USE_IN_LIBIO */
833 buffered_vfprintf (s, format, args)
841 s->__bufp = s->__buffer = buf;
842 s->__bufsize = sizeof buf;
843 s->__put_limit = s->__buffer + s->__bufsize;
844 s->__get_limit = s->__buffer;
846 /* Now use buffer to print. */
847 result = vfprintf (s, format, args);
849 if (fflush (s) == EOF)
851 s->__buffer = s->__bufp = s->__get_limit = s->__put_limit = NULL;
858 /* Pads string with given number of a specified character.
859 This code is taken from iopadn.c of the GNU I/O library. */
861 static const char blanks[PADSIZE] =
862 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
863 static const char zeroes[PADSIZE] =
864 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
867 __printf_pad (s, pad, count)
875 padptr = pad == ' ' ? blanks : zeroes;
877 for (i = count; i >= PADSIZE; i -= PADSIZE)
878 if (PUT (s, padptr, PADSIZE) != PADSIZE)
881 if (PUT (s, padptr, i) != i)
887 #endif /* USE_IN_LIBIO */