initial import
[glibc.git] / stdio / vfprintf.c
blobc480a93ab9dbe67e1c42bd4b7ab44017ae89b49e
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. */
19 #include <ansidecl.h>
20 #include <localeinfo.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <float.h>
24 #include <limits.h>
25 #include <math.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <printf.h>
30 #include <assert.h>
31 #include <stddef.h>
32 #include "_itoa.h"
34 /* This function from the GNU C library is also used in libio.
35 To compile for use in libio, compile with -DUSE_IN_LIBIO. */
37 #ifdef USE_IN_LIBIO
38 /* This code is for use in libio. */
39 #include <libioP.h>
40 #define PUT(f, s, n) _IO_sputn (f, s, n)
41 #define PAD(padchar) _IO_padn (s, padchar, width)
42 #define PUTC(c, f) _IO_putc(c, f)
43 #define vfprintf _IO_vfprintf
44 #define size_t _IO_size_t
45 #define FILE _IO_FILE
46 #define va_list _IO_va_list
47 #undef BUFSIZ
48 #define BUFSIZ _IO_BUFSIZ
49 #define ARGCHECK(s, format) \
50 do \
51 { \
52 /* Check file argument for consistence. */ \
53 CHECK_FILE(s, -1); \
54 if (s->_flags & _IO_NO_WRITES || format == NULL) \
55 { \
56 MAYBE_SET_EINVAL; \
57 return -1; \
58 } \
59 } while (0)
60 #define UNBUFFERED_P(s) ((s)->_IO_file_flags & _IO_UNBUFFERED)
61 #else /* ! USE_IN_LIBIO */
62 /* This code is for use in the GNU C library. */
63 #include <stdio.h>
64 #define PUTC(c, f) putc (c, f)
65 #define PUT(f, s, n) fwrite (s, 1, n, f)
66 ssize_t __printf_pad __P ((FILE *, char pad, int n));
67 #define PAD(padchar) __printf_pad (s, padchar, width)
68 #define ARGCHECK(s, format) \
69 do \
70 { \
71 /* Check file argument for consistence. */ \
72 if (!__validfp(s) || !s->__mode.__write || format == NULL) \
73 { \
74 errno = EINVAL; \
75 return -1; \
76 } \
77 if (!s->__seen) \
78 { \
79 if (__flshfp (s, EOF) == EOF) \
80 return -1; \
81 } \
82 } while (0)
83 #define UNBUFFERED_P(s) ((s)->__buffer == NULL)
84 #endif /* USE_IN_LIBIO */
87 #define outchar(x) \
88 do \
89 { \
90 register CONST int outc = (x); \
91 if (putc(outc, s) == EOF) \
92 return -1; \
93 else \
94 ++done; \
95 } while (0)
97 /* Advances STRING after writing LEN chars of it. */
98 #define outstring(string, len) \
99 do \
101 if (len > 20) \
103 if (PUT (s, string, len) != len) \
104 return -1; \
105 done += len; \
106 string += len; \
108 else \
109 while (len-- > 0) \
110 outchar (*string++); \
111 } while (0)
113 /* Helper function to provide temporary buffering for unbuffered streams. */
114 static int buffered_vfprintf __P ((FILE *stream, const char *fmt, va_list));
116 /* Cast the next arg, of type ARGTYPE, into CASTTYPE, and put it in VAR. */
117 #define castarg(var, argtype, casttype) \
118 var = (casttype) va_arg(args, argtype)
119 /* Get the next arg, of type TYPE, and put it in VAR. */
120 #define nextarg(var, type) castarg(var, type, type)
122 static printf_function printf_unknown;
124 extern printf_function **__printf_function_table;
126 #ifdef __GNUC__
127 #define HAVE_LONGLONG
128 #define LONGLONG long long
129 #else
130 #define LONGLONG long
131 #endif
133 static char *group_number __P ((char *, char *, const char *, wchar_t));
136 DEFUN(vfprintf, (s, format, args),
137 register FILE *s AND CONST char *format AND va_list args)
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 /* Pointer into the format string. */
146 register CONST char *f;
148 /* Number of characters written. */
149 register size_t done = 0;
151 ARGCHECK (s, format);
153 if (UNBUFFERED_P (s))
154 /* Use a helper function which will allocate a local temporary buffer
155 for the stream and then call us again. */
156 return buffered_vfprintf (s, format, args);
158 /* Reset multibyte characters to their initial state. */
159 (void) mblen ((char *) NULL, 0);
161 /* Figure out the thousands seperator character. */
162 if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
163 strlen (_numeric_info->thousands_sep)) <= 0)
164 thousands_sep = (wchar_t) *_numeric_info->thousands_sep;
165 grouping = _numeric_info->grouping; /* Cache the grouping info array. */
166 if (*grouping == '\0' || thousands_sep == L'\0')
167 grouping = NULL;
169 f = format;
170 while (*f != '\0')
172 /* Type modifiers. */
173 char is_short, is_long, is_long_double;
174 #ifdef HAVE_LONGLONG
175 /* We use the `L' modifier for `long long int'. */
176 #define is_longlong is_long_double
177 #else
178 #define is_longlong 0
179 #endif
180 /* Format spec modifiers. */
181 char space, showsign, left, alt, group;
183 /* Padding character: ' ' or '0'. */
184 char pad;
185 /* Width of a field. */
186 register int width;
187 /* Precision of a field. */
188 int prec;
190 /* Decimal integer is negative. */
191 char is_neg;
193 /* Current character of the format. */
194 char fc;
196 /* Base of a number to be written. */
197 int base;
198 /* Integral values to be written. */
199 unsigned LONGLONG int num;
200 LONGLONG int signed_num;
202 /* String to be written. */
203 CONST char *str;
204 char errorbuf[1024]; /* Buffer sometimes used by %m. */
206 /* Auxiliary function to do output. */
207 printf_function *function;
209 if (!isascii(*f))
211 /* Non-ASCII, may be a multibyte. */
212 int len = mblen (f, strlen (f));
213 if (len > 0)
215 outstring (f, len);
216 continue;
220 if (*f != '%')
222 /* This isn't a format spec, so write everything out until the
223 next one. To properly handle multibyte characters, we cannot
224 just search for a '%'. Since multibyte characters are hairy
225 (and dealt with above), if we hit any byte above 127 (only
226 those can start a multibyte character) we just punt back to
227 that code. */
229 outchar (*f++);
230 while (*f != '\0' && *f != '%' && isascii (*f));
231 continue;
234 ++f;
236 /* Check for "%%". Note that although the ANSI standard lists
237 '%' as a conversion specifier, it says "The complete format
238 specification shall be `%%'," so we can avoid all the width
239 and precision processing. */
240 if (*f == '%')
242 ++f;
243 outchar('%');
244 continue;
247 /* Check for spec modifiers. */
248 space = showsign = left = alt = group = 0;
249 pad = ' ';
250 while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0' ||
251 *f == '\'')
252 switch (*f++)
254 case ' ':
255 /* Output a space in place of a sign, when there is no sign. */
256 space = 1;
257 break;
258 case '+':
259 /* Always output + or - for numbers. */
260 showsign = 1;
261 break;
262 case '-':
263 /* Left-justify things. */
264 left = 1;
265 break;
266 case '#':
267 /* Use the "alternate form":
268 Hex has 0x or 0X, FP always has a decimal point. */
269 alt = 1;
270 break;
271 case '0':
272 /* Pad with 0s. */
273 pad = '0';
274 break;
275 case '\'':
276 /* Show grouping in numbers if the locale information
277 indicates any. */
278 group = 1;
279 break;
281 if (left)
282 pad = ' ';
284 /* Get the field width. */
285 width = 0;
286 if (*f == '*')
288 /* The field width is given in an argument.
289 A negative field width indicates left justification. */
290 nextarg(width, int);
291 if (width < 0)
293 width = - width;
294 left = 1;
296 ++f;
298 else
299 while (isdigit (*f))
301 width *= 10;
302 width += *f++ - '0';
305 /* Get the precision. */
306 /* -1 means none given; 0 means explicit 0. */
307 prec = -1;
308 if (*f == '.')
310 ++f;
311 if (*f == '*')
313 /* The precision is given in an argument. */
314 nextarg(prec, int);
315 /* Avoid idiocy. */
316 if (prec < 0)
317 prec = -1;
318 ++f;
320 else if (isdigit (*f))
322 prec = *f++ - '0';
323 while (*f != '\0' && isdigit (*f))
325 prec *= 10;
326 prec += *f++ - '0';
329 else
330 /* "%.?" is treated like "%.0?". */
331 prec = 0;
334 /* If there was a precision specified, ignore the 0 flag and always
335 pad with spaces. */
336 if (prec != -1)
337 pad = ' ';
339 /* Check for type modifiers. */
340 is_short = is_long = is_long_double = 0;
341 while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'q')
342 switch (*f++)
344 case 'h':
345 /* int's are short int's. */
346 is_short = 1;
347 break;
348 case 'l':
349 #ifdef HAVE_LONGLONG
350 if (is_long)
351 /* A double `l' is equivalent to an `L'. */
352 is_longlong = 1;
353 else
354 #endif
355 /* int's are long int's. */
356 is_long = 1;
357 break;
358 case 'L':
359 /* double's are long double's, and int's are long long int's. */
360 is_long_double = 1;
361 break;
363 case 'Z':
364 /* int's are size_t's. */
365 #ifdef HAVE_LONGLONG
366 assert (sizeof(size_t) <= sizeof(unsigned long long int));
367 is_longlong = sizeof(size_t) > sizeof(unsigned long int);
368 #endif
369 is_long = sizeof(size_t) > sizeof(unsigned int);
370 break;
372 case 'q':
373 /* 4.4 uses this for long long. */
374 #ifdef HAVE_LONGLONG
375 is_longlong = 1;
376 #else
377 is_long = 1;
378 #endif
379 break;
382 /* Format specification. */
383 fc = *f++;
384 function = (__printf_function_table == NULL ? NULL :
385 __printf_function_table[fc]);
386 if (function == NULL)
387 switch (fc)
389 case 'i':
390 case 'd':
391 /* Decimal integer. */
392 base = 10;
393 if (is_longlong)
394 nextarg(signed_num, LONGLONG int);
395 else if (is_long)
396 nextarg(signed_num, long int);
397 else if (!is_short)
398 castarg(signed_num, int, long int);
399 else
400 castarg(signed_num, int, short int);
402 is_neg = signed_num < 0;
403 num = is_neg ? (- signed_num) : signed_num;
404 goto number;
406 case 'u':
407 /* Decimal unsigned integer. */
408 base = 10;
409 goto unsigned_number;
411 case 'o':
412 /* Octal unsigned integer. */
413 base = 8;
414 goto unsigned_number;
416 case 'X':
417 /* Hexadecimal unsigned integer. */
418 case 'x':
419 /* Hex with lower-case digits. */
421 base = 16;
423 unsigned_number:
424 /* Unsigned number of base BASE. */
426 if (is_longlong)
427 castarg(num, LONGLONG int, unsigned LONGLONG int);
428 else if (is_long)
429 castarg(num, long int, unsigned long int);
430 else if (!is_short)
431 castarg(num, int, unsigned int);
432 else
433 castarg(num, int, unsigned short int);
435 /* ANSI only specifies the `+' and
436 ` ' flags for signed conversions. */
437 is_neg = showsign = space = 0;
439 number:
440 /* Number of base BASE. */
442 char work[BUFSIZ];
443 char *CONST workend = &work[sizeof(work) - 1];
444 register char *w;
446 /* Supply a default precision if none was given. */
447 if (prec == -1)
448 prec = 1;
450 /* Put the number in WORK. */
451 w = _itoa (num, workend + 1, base, fc == 'X') - 1;
452 if (group && grouping)
453 w = group_number (w, workend, grouping, thousands_sep);
454 width -= workend - w;
455 prec -= workend - w;
457 if (alt && base == 8 && prec <= 0)
459 *w-- = '0';
460 --width;
463 if (prec > 0)
465 width -= prec;
466 while (prec-- > 0)
467 *w-- = '0';
470 if (alt && base == 16)
471 width -= 2;
473 if (is_neg || showsign || space)
474 --width;
476 if (!left && pad == ' ')
477 PAD (' ');
479 if (is_neg)
480 outchar('-');
481 else if (showsign)
482 outchar('+');
483 else if (space)
484 outchar(' ');
486 if (alt && base == 16)
488 outchar ('0');
489 outchar (fc);
492 if (!left && pad == '0')
493 PAD ('0');
495 /* Write the number. */
496 while (++w <= workend)
497 outchar(*w);
499 if (left)
500 PAD (' ');
502 break;
504 case 'e':
505 case 'E':
506 case 'f':
507 case 'g':
508 case 'G':
510 /* Floating-point number. */
511 extern printf_function __printf_fp;
512 function = __printf_fp;
513 goto use_function;
516 case 'c':
517 /* Character. */
518 nextarg(num, int);
519 if (!left)
521 --width;
522 PAD (' ');
524 outchar ((unsigned char) num);
525 if (left)
526 PAD (' ');
527 break;
529 case 's':
531 static CONST char null[] = "(null)";
532 size_t len;
534 nextarg(str, CONST char *);
536 string:
538 if (str == NULL)
539 /* Write "(null)" if there's space. */
540 if (prec == -1 || prec >= (int) sizeof(null) - 1)
542 str = null;
543 len = sizeof(null) - 1;
545 else
547 str = "";
548 len = 0;
550 else
551 len = strlen(str);
553 if (prec != -1 && (size_t) prec < len)
554 len = prec;
555 width -= len;
557 if (!left)
558 PAD (' ');
559 outstring (str, len);
560 if (left)
561 PAD (' ');
563 break;
565 case 'p':
566 /* Generic pointer. */
568 CONST PTR ptr;
569 nextarg(ptr, CONST PTR);
570 if (ptr != NULL)
572 /* If the pointer is not NULL, write it as a %#x spec. */
573 base = 16;
574 fc = 'x';
575 alt = 1;
576 num = (unsigned LONGLONG int) (unsigned long int) ptr;
577 is_neg = 0;
578 group = 0;
579 goto number;
581 else
583 /* Write "(nil)" for a nil pointer. */
584 static CONST char nil[] = "(nil)";
585 register CONST char *p;
587 width -= sizeof (nil) - 1;
588 if (!left)
589 PAD (' ');
590 for (p = nil; *p != '\0'; ++p)
591 outchar (*p);
592 if (left)
593 PAD (' ');
596 break;
598 case 'n':
599 /* Answer the count of characters written. */
600 if (is_longlong)
602 LONGLONG int *p;
603 nextarg(p, LONGLONG int *);
604 *p = done;
606 else if (is_long)
608 long int *p;
609 nextarg(p, long int *);
610 *p = done;
612 else if (!is_short)
614 int *p;
615 nextarg(p, int *);
616 *p = done;
618 else
620 short int *p;
621 nextarg(p, short int *);
622 *p = done;
624 break;
626 case 'm':
628 extern char *_strerror_internal __P ((int, char buf[1024]));
629 str = _strerror_internal (errno, errorbuf);
630 goto string;
633 default:
634 /* Unrecognized format specifier. */
635 function = printf_unknown;
636 goto use_function;
638 else
639 use_function:
641 int function_done;
642 struct printf_info info;
644 info.prec = prec;
645 info.width = width;
646 info.spec = fc;
647 info.is_long_double = is_long_double;
648 info.is_short = is_short;
649 info.is_long = is_long;
650 info.alt = alt;
651 info.space = space;
652 info.left = left;
653 info.showsign = showsign;
654 info.group = group;
655 info.pad = pad;
657 function_done = (*function) (s, &info, &args);
658 if (function_done < 0)
659 return -1;
661 done += function_done;
665 return done;
669 static int
670 DEFUN(printf_unknown, (s, info, arg),
671 FILE *s AND CONST struct printf_info *info AND va_list *arg)
673 int done = 0;
674 char work[BUFSIZ];
675 char *CONST workend = &work[sizeof(work) - 1];
676 register char *w;
677 register int prec = info->prec, width = info->width;
679 outchar('%');
681 if (info->alt)
682 outchar ('#');
683 if (info->group)
684 outchar ('\'');
685 if (info->showsign)
686 outchar ('+');
687 else if (info->space)
688 outchar (' ');
689 if (info->left)
690 outchar ('-');
691 if (info->pad == '0')
692 outchar ('0');
694 w = workend;
695 while (width > 0)
697 *w-- = '0' + (width % 10);
698 width /= 10;
700 while (++w <= workend)
701 outchar(*w);
703 if (info->prec != -1)
705 outchar('.');
706 w = workend;
707 while (prec > 0)
709 *w-- = '0' + (prec % 10);
710 prec /= 10;
712 while (++w <= workend)
713 outchar(*w);
716 outchar(info->spec);
718 return done;
721 /* Group the digits according to the grouping rules of the current locale.
722 The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */
724 static char *
725 group_number (char *w, char *workend, const char *grouping,
726 wchar_t thousands_sep)
728 int len;
729 char *src, *s;
731 /* We treat all negative values like CHAR_MAX. */
733 if (*grouping == CHAR_MAX || *grouping < 0)
734 /* No grouping should be done. */
735 return w;
737 len = *grouping;
739 /* Copy existing string so that nothing gets overwritten. */
740 src = (char *) alloca (workend - w);
741 memcpy (src, w + 1, workend - w);
742 s = &src[workend - w - 1];
743 w = workend;
745 /* Process all characters in the string. */
746 while (s >= src)
748 *w-- = *s--;
750 if (--len == 0 && s >= src)
752 /* A new group begins. */
753 *w-- = thousands_sep;
755 len = *grouping++;
756 if (*grouping == '\0')
757 /* The previous grouping repeats ad infinitum. */
758 --grouping;
759 else if (*grouping == CHAR_MAX || *grouping < 0)
761 /* No further grouping to be done.
762 Copy the rest of the number. */
764 *w-- = *s--;
765 while (s >= src);
766 break;
771 return w;
774 #ifdef USE_IN_LIBIO
775 /* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */
776 struct helper_file
778 struct _IO_FILE_plus _f;
779 _IO_FILE *_put_stream;
782 static int
783 DEFUN(_IO_helper_overflow, (s, c), _IO_FILE *s AND int c)
785 _IO_FILE *target = ((struct helper_file*) s)->_put_stream;
786 int used = s->_IO_write_ptr - s->_IO_write_base;
787 if (used)
789 _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used);
790 s->_IO_write_ptr -= written;
792 return _IO_putc (c, s);
795 static const struct _IO_jump_t _IO_helper_jumps =
797 _IO_helper_overflow,
798 _IO_default_underflow,
799 _IO_default_xsputn,
800 _IO_default_xsgetn,
801 _IO_default_read,
802 _IO_default_write,
803 _IO_default_doallocate,
804 _IO_default_pbackfail,
805 _IO_default_setbuf,
806 _IO_default_sync,
807 _IO_default_finish,
808 _IO_default_close,
809 _IO_default_stat,
810 _IO_default_seek,
811 _IO_default_seekoff,
812 _IO_default_seekpos,
813 _IO_default_uflow
816 static int
817 DEFUN(buffered_vfprintf, (s, format, args),
818 register _IO_FILE *s AND char CONST *format AND _IO_va_list args)
820 char buf[_IO_BUFSIZ];
821 struct helper_file helper;
822 register _IO_FILE *hp = (_IO_FILE *) &helper;
823 int result, to_flush;
825 /* Initialize helper. */
826 helper._put_stream = s;
827 hp->_IO_write_base = buf;
828 hp->_IO_write_ptr = buf;
829 hp->_IO_write_end = buf + sizeof buf;
830 hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
831 hp->_jumps = (struct _IO_jump_t *) &_IO_helper_jumps;
833 /* Now print to helper instead. */
834 result = _IO_vfprintf (hp, format, args);
836 /* Now flush anything from the helper to the S. */
837 if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
839 if (_IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush)
840 return -1;
843 return result;
846 #else /* !USE_IN_LIBIO */
848 static int
849 DEFUN(buffered_vfprintf, (s, format, args),
850 register FILE *s AND char CONST *format AND va_list args)
852 char buf[BUFSIZ];
853 int result;
855 s->__bufp = s->__buffer = buf;
856 s->__bufsize = sizeof buf;
857 s->__put_limit = s->__buffer + s->__bufsize;
858 s->__get_limit = s->__buffer;
860 /* Now use buffer to print. */
861 result = vfprintf (s, format, args);
863 if (fflush (s) == EOF)
864 return -1;
865 s->__buffer = s->__bufp = s->__get_limit = s->__put_limit = NULL;
866 s->__bufsize = 0;
868 return result;
872 /* Pads string with given number of a specified character.
873 This code is taken from iopadn.c of the GNU I/O library. */
874 #define PADSIZE 16
875 static const char blanks[PADSIZE] =
876 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
877 static const char zeroes[PADSIZE] =
878 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
880 ssize_t
881 __printf_pad (s, pad, count)
882 FILE *s;
883 char pad;
884 int count;
886 CONST char *padptr;
887 register int i;
888 size_t written = 0, w;
890 padptr = pad == ' ' ? blanks : zeroes;
892 for (i = count; i >= PADSIZE; i -= PADSIZE)
894 w = PUT(s, padptr, PADSIZE);
895 written += w;
896 if (w != PADSIZE)
897 return written;
899 if (i > 0)
901 w = PUT(s, padptr, i);
902 written += w;
904 return written;
906 #undef PADSIZE
907 #endif /* USE_IN_LIBIO */