]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/stdio/vfwprintf.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / lib / libc / stdio / vfwprintf.c
1 /*-
2  * Copyright (c) 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Chris Torek.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #if 0
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid[] = "@(#)vfprintf.c  8.1 (Berkeley) 6/4/93";
36 #endif /* LIBC_SCCS and not lint */
37 #endif
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 /*
42  * Actual wprintf innards.
43  *
44  * Avoid making gratuitous changes to this source file; it should be kept
45  * as close as possible to vfprintf.c for ease of maintenance.
46  */
47
48 #include "namespace.h"
49 #include <sys/types.h>
50
51 #include <ctype.h>
52 #include <limits.h>
53 #include <locale.h>
54 #include <stdarg.h>
55 #include <stddef.h>
56 #include <stdint.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <wchar.h>
61 #include <wctype.h>
62 #include "un-namespace.h"
63
64 #include "libc_private.h"
65 #include "local.h"
66 #include "fvwrite.h"
67 #include "printflocal.h"
68
69 static int      __sbprintf(FILE *, const wchar_t *, va_list);
70 static wint_t   __xfputwc(wchar_t, FILE *);
71 static wchar_t  *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
72                     char, const char *);
73 static wchar_t  *__ultoa(u_long, wchar_t *, int, int, const char *, int,
74                     char, const char *);
75 static wchar_t  *__mbsconv(char *, int);
76
77 /*
78  * Helper function for `fprintf to unbuffered unix file': creates a
79  * temporary buffer.  We only work on write-only files; this avoids
80  * worries about ungetc buffers and so forth.
81  */
82 static int
83 __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
84 {
85         int ret;
86         FILE fake;
87         unsigned char buf[BUFSIZ];
88
89         /* copy the important variables */
90         fake._flags = fp->_flags & ~__SNBF;
91         fake._file = fp->_file;
92         fake._cookie = fp->_cookie;
93         fake._write = fp->_write;
94         fake._orientation = fp->_orientation;
95         fake._mbstate = fp->_mbstate;
96
97         /* set up the buffer */
98         fake._bf._base = fake._p = buf;
99         fake._bf._size = fake._w = sizeof(buf);
100         fake._lbfsize = 0;      /* not actually used, but Just In Case */
101
102         /* do the work, then copy any error status */
103         ret = __vfwprintf(&fake, fmt, ap);
104         if (ret >= 0 && __fflush(&fake))
105                 ret = WEOF;
106         if (fake._flags & __SERR)
107                 fp->_flags |= __SERR;
108         return (ret);
109 }
110
111 /*
112  * Like __fputwc, but handles fake string (__SSTR) files properly.
113  * File must already be locked.
114  */
115 static wint_t
116 __xfputwc(wchar_t wc, FILE *fp)
117 {
118         static const mbstate_t initial;
119         mbstate_t mbs;
120         char buf[MB_LEN_MAX];
121         struct __suio uio;
122         struct __siov iov;
123         size_t len;
124
125         if ((fp->_flags & __SSTR) == 0)
126                 return (__fputwc(wc, fp));
127
128         mbs = initial;
129         if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
130                 fp->_flags |= __SERR;
131                 return (WEOF);
132         }
133         uio.uio_iov = &iov;
134         uio.uio_resid = len;
135         uio.uio_iovcnt = 1;
136         iov.iov_base = buf;
137         iov.iov_len = len;
138         return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF);
139 }
140
141 /*
142  * Convert an unsigned long to ASCII for printf purposes, returning
143  * a pointer to the first character of the string representation.
144  * Octal numbers can be forced to have a leading zero; hex numbers
145  * use the given digits.
146  */
147 static wchar_t *
148 __ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs,
149         int needgrp, char thousep, const char *grp)
150 {
151         wchar_t *cp = endp;
152         long sval;
153         int ndig;
154
155         /*
156          * Handle the three cases separately, in the hope of getting
157          * better/faster code.
158          */
159         switch (base) {
160         case 10:
161                 if (val < 10) { /* many numbers are 1 digit */
162                         *--cp = to_char(val);
163                         return (cp);
164                 }
165                 ndig = 0;
166                 /*
167                  * On many machines, unsigned arithmetic is harder than
168                  * signed arithmetic, so we do at most one unsigned mod and
169                  * divide; this is sufficient to reduce the range of
170                  * the incoming value to where signed arithmetic works.
171                  */
172                 if (val > LONG_MAX) {
173                         *--cp = to_char(val % 10);
174                         ndig++;
175                         sval = val / 10;
176                 } else
177                         sval = val;
178                 do {
179                         *--cp = to_char(sval % 10);
180                         ndig++;
181                         /*
182                          * If (*grp == CHAR_MAX) then no more grouping
183                          * should be performed.
184                          */
185                         if (needgrp && ndig == *grp && *grp != CHAR_MAX
186                                         && sval > 9) {
187                                 *--cp = thousep;
188                                 ndig = 0;
189                                 /*
190                                  * If (*(grp+1) == '\0') then we have to
191                                  * use *grp character (last grouping rule)
192                                  * for all next cases
193                                  */
194                                 if (*(grp+1) != '\0')
195                                         grp++;
196                         }
197                         sval /= 10;
198                 } while (sval != 0);
199                 break;
200
201         case 8:
202                 do {
203                         *--cp = to_char(val & 7);
204                         val >>= 3;
205                 } while (val);
206                 if (octzero && *cp != '0')
207                         *--cp = '0';
208                 break;
209
210         case 16:
211                 do {
212                         *--cp = xdigs[val & 15];
213                         val >>= 4;
214                 } while (val);
215                 break;
216
217         default:                        /* oops */
218                 abort();
219         }
220         return (cp);
221 }
222
223 /* Identical to __ultoa, but for intmax_t. */
224 static wchar_t *
225 __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
226         const char *xdigs, int needgrp, char thousep, const char *grp)
227 {
228         wchar_t *cp = endp;
229         intmax_t sval;
230         int ndig;
231
232         /* quick test for small values; __ultoa is typically much faster */
233         /* (perhaps instead we should run until small, then call __ultoa?) */
234         if (val <= ULONG_MAX)
235                 return (__ultoa((u_long)val, endp, base, octzero, xdigs,
236                     needgrp, thousep, grp));
237         switch (base) {
238         case 10:
239                 if (val < 10) {
240                         *--cp = to_char(val % 10);
241                         return (cp);
242                 }
243                 ndig = 0;
244                 if (val > INTMAX_MAX) {
245                         *--cp = to_char(val % 10);
246                         ndig++;
247                         sval = val / 10;
248                 } else
249                         sval = val;
250                 do {
251                         *--cp = to_char(sval % 10);
252                         ndig++;
253                         /*
254                          * If (*grp == CHAR_MAX) then no more grouping
255                          * should be performed.
256                          */
257                         if (needgrp && *grp != CHAR_MAX && ndig == *grp
258                                         && sval > 9) {
259                                 *--cp = thousep;
260                                 ndig = 0;
261                                 /*
262                                  * If (*(grp+1) == '\0') then we have to
263                                  * use *grp character (last grouping rule)
264                                  * for all next cases
265                                  */
266                                 if (*(grp+1) != '\0')
267                                         grp++;
268                         }
269                         sval /= 10;
270                 } while (sval != 0);
271                 break;
272
273         case 8:
274                 do {
275                         *--cp = to_char(val & 7);
276                         val >>= 3;
277                 } while (val);
278                 if (octzero && *cp != '0')
279                         *--cp = '0';
280                 break;
281
282         case 16:
283                 do {
284                         *--cp = xdigs[val & 15];
285                         val >>= 4;
286                 } while (val);
287                 break;
288
289         default:
290                 abort();
291         }
292         return (cp);
293 }
294
295 /*
296  * Convert a multibyte character string argument for the %s format to a wide
297  * string representation. ``prec'' specifies the maximum number of bytes
298  * to output. If ``prec'' is greater than or equal to zero, we can't assume
299  * that the multibyte char. string ends in a null character.
300  */
301 static wchar_t *
302 __mbsconv(char *mbsarg, int prec)
303 {
304         static const mbstate_t initial;
305         mbstate_t mbs;
306         wchar_t *convbuf, *wcp;
307         const char *p;
308         size_t insize, nchars, nconv;
309
310         if (mbsarg == NULL)
311                 return (NULL);
312
313         /*
314          * Supplied argument is a multibyte string; convert it to wide
315          * characters first.
316          */
317         if (prec >= 0) {
318                 /*
319                  * String is not guaranteed to be NUL-terminated. Find the
320                  * number of characters to print.
321                  */
322                 p = mbsarg;
323                 insize = nchars = 0;
324                 mbs = initial;
325                 while (nchars != (size_t)prec) {
326                         nconv = mbrlen(p, MB_CUR_MAX, &mbs);
327                         if (nconv == 0 || nconv == (size_t)-1 ||
328                             nconv == (size_t)-2)
329                                 break;
330                         p += nconv;
331                         nchars++;
332                         insize += nconv;
333                 }
334                 if (nconv == (size_t)-1 || nconv == (size_t)-2)
335                         return (NULL);
336         } else {
337                 insize = strlen(mbsarg);
338                 nconv = 0;
339         }
340
341         /*
342          * Allocate buffer for the result and perform the conversion,
343          * converting at most `size' bytes of the input multibyte string to
344          * wide characters for printing.
345          */
346         convbuf = malloc((insize + 1) * sizeof(*convbuf));
347         if (convbuf == NULL)
348                 return (NULL);
349         wcp = convbuf;
350         p = mbsarg;
351         mbs = initial;
352         while (insize != 0) {
353                 nconv = mbrtowc(wcp, p, insize, &mbs);
354                 if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
355                         break;
356                 wcp++;
357                 p += nconv;
358                 insize -= nconv;
359         }
360         if (nconv == (size_t)-1 || nconv == (size_t)-2) {
361                 free(convbuf);
362                 return (NULL);
363         }
364         *wcp = L'\0';
365
366         return (convbuf);
367 }
368
369 /*
370  * MT-safe version
371  */
372 int
373 vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
374
375 {
376         int ret;
377
378         FLOCKFILE(fp);
379         ret = __vfwprintf(fp, fmt0, ap);
380         FUNLOCKFILE(fp);
381         return (ret);
382 }
383
384 #ifndef NO_FLOATING_POINT
385
386 #define dtoa            __dtoa
387 #define freedtoa        __freedtoa
388
389 #include <float.h>
390 #include <math.h>
391 #include "floatio.h"
392 #include "gdtoa.h"
393
394 #define DEFPREC         6
395
396 static int exponent(wchar_t *, int, wchar_t);
397
398 #endif /* !NO_FLOATING_POINT */
399
400 /*
401  * The size of the buffer we use as scratch space for integer
402  * conversions, among other things.  Technically, we would need the
403  * most space for base 10 conversions with thousands' grouping
404  * characters between each pair of digits.  100 bytes is a
405  * conservative overestimate even for a 128-bit uintmax_t.
406  */
407 #define BUF     100
408
409 /*
410  * Non-MT-safe version
411  */
412 int
413 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
414 {
415         wchar_t *fmt;           /* format string */
416         wchar_t ch;             /* character from fmt */
417         int n, n2, n3;          /* handy integer (short term usage) */
418         wchar_t *cp;            /* handy char pointer (short term usage) */
419         int flags;              /* flags as above */
420         int ret;                /* return value accumulator */
421         int width;              /* width from format (%8d), or 0 */
422         int prec;               /* precision from format; <0 for N/A */
423         wchar_t sign;           /* sign prefix (' ', '+', '-', or \0) */
424         char thousands_sep;     /* locale specific thousands separator */
425         const char *grouping;   /* locale specific numeric grouping rules */
426 #ifndef NO_FLOATING_POINT
427         /*
428          * We can decompose the printed representation of floating
429          * point numbers into several parts, some of which may be empty:
430          *
431          * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
432          *    A       B     ---C---      D       E   F
433          *
434          * A:   'sign' holds this value if present; '\0' otherwise
435          * B:   ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
436          * C:   cp points to the string MMMNNN.  Leading and trailing
437          *      zeros are not in the string and must be added.
438          * D:   expchar holds this character; '\0' if no exponent, e.g. %f
439          * F:   at least two digits for decimal, at least one digit for hex
440          */
441         char *decimal_point;    /* locale specific decimal point */
442         int signflag;           /* true if float is negative */
443         union {                 /* floating point arguments %[aAeEfFgG] */
444                 double dbl;
445                 long double ldbl;
446         } fparg;
447         int expt;               /* integer value of exponent */
448         char expchar;           /* exponent character: [eEpP\0] */
449         char *dtoaend;          /* pointer to end of converted digits */
450         int expsize;            /* character count for expstr */
451         int lead;               /* sig figs before decimal or group sep */
452         int ndig;               /* actual number of digits returned by dtoa */
453         wchar_t expstr[MAXEXPDIG+2];    /* buffer for exponent string: e+ZZZ */
454         char *dtoaresult;       /* buffer allocated by dtoa */
455         int nseps;              /* number of group separators with ' */
456         int nrepeats;           /* number of repeats of the last group */
457 #endif
458         u_long  ulval;          /* integer arguments %[diouxX] */
459         uintmax_t ujval;        /* %j, %ll, %q, %t, %z integers */
460         int base;               /* base for [diouxX] conversion */
461         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
462         int realsz;             /* field size expanded by dprec, sign, etc */
463         int size;               /* size of converted field or string */
464         int prsize;             /* max size of printed field */
465         const char *xdigs;      /* digits for [xX] conversion */
466         wchar_t buf[BUF];       /* buffer with space for digits of uintmax_t */
467         wchar_t ox[2];          /* space for 0x hex-prefix */
468         union arg *argtable;    /* args, built due to positional arg */
469         union arg statargtable [STATIC_ARG_TBL_SIZE];
470         int nextarg;            /* 1-based argument index */
471         va_list orgap;          /* original argument pointer */
472         wchar_t *convbuf;       /* multibyte to wide conversion result */
473
474         /*
475          * Choose PADSIZE to trade efficiency vs. size.  If larger printf
476          * fields occur frequently, increase PADSIZE and make the initialisers
477          * below longer.
478          */
479 #define PADSIZE 16              /* pad chunk size */
480         static wchar_t blanks[PADSIZE] =
481          {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
482         static wchar_t zeroes[PADSIZE] =
483          {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
484
485         static const char xdigs_lower[16] = "0123456789abcdef";
486         static const char xdigs_upper[16] = "0123456789ABCDEF";
487
488         /*
489          * BEWARE, these `goto error' on error, PRINT uses `n2' and
490          * PAD uses `n'.
491          */
492 #define PRINT(ptr, len) do {                    \
493         for (n3 = 0; n3 < (len); n3++)          \
494                 __xfputwc((ptr)[n3], fp);       \
495 } while (0)
496 #define PAD(howmany, with)      do {            \
497         if ((n = (howmany)) > 0) {              \
498                 while (n > PADSIZE) {           \
499                         PRINT(with, PADSIZE);   \
500                         n -= PADSIZE;           \
501                 }                               \
502                 PRINT(with, n);                 \
503         }                                       \
504 } while (0)
505 #define PRINTANDPAD(p, ep, len, with) do {      \
506         n2 = (ep) - (p);                        \
507         if (n2 > (len))                         \
508                 n2 = (len);                     \
509         if (n2 > 0)                             \
510                 PRINT((p), n2);                 \
511         PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
512 } while(0)
513
514         /*
515          * Get the argument indexed by nextarg.   If the argument table is
516          * built, use it to get the argument.  If its not, get the next
517          * argument (and arguments must be gotten sequentially).
518          */
519 #define GETARG(type) \
520         ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
521             (nextarg++, va_arg(ap, type)))
522
523         /*
524          * To extend shorts properly, we need both signed and unsigned
525          * argument extraction methods.
526          */
527 #define SARG() \
528         (flags&LONGINT ? GETARG(long) : \
529             flags&SHORTINT ? (long)(short)GETARG(int) : \
530             flags&CHARINT ? (long)(signed char)GETARG(int) : \
531             (long)GETARG(int))
532 #define UARG() \
533         (flags&LONGINT ? GETARG(u_long) : \
534             flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
535             flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
536             (u_long)GETARG(u_int))
537 #define INTMAX_SIZE     (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
538 #define SJARG() \
539         (flags&INTMAXT ? GETARG(intmax_t) : \
540             flags&SIZET ? (intmax_t)GETARG(size_t) : \
541             flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
542             (intmax_t)GETARG(long long))
543 #define UJARG() \
544         (flags&INTMAXT ? GETARG(uintmax_t) : \
545             flags&SIZET ? (uintmax_t)GETARG(size_t) : \
546             flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
547             (uintmax_t)GETARG(unsigned long long))
548
549         /*
550          * Get * arguments, including the form *nn$.  Preserve the nextarg
551          * that the argument can be gotten once the type is determined.
552          */
553 #define GETASTER(val) \
554         n2 = 0; \
555         cp = fmt; \
556         while (is_digit(*cp)) { \
557                 n2 = 10 * n2 + to_digit(*cp); \
558                 cp++; \
559         } \
560         if (*cp == '$') { \
561                 int hold = nextarg; \
562                 if (argtable == NULL) { \
563                         argtable = statargtable; \
564                         if (__find_warguments (fmt0, orgap, &argtable)) { \
565                                 ret = EOF; \
566                                 goto error; \
567                         } \
568                 } \
569                 nextarg = n2; \
570                 val = GETARG (int); \
571                 nextarg = hold; \
572                 fmt = ++cp; \
573         } else { \
574                 val = GETARG (int); \
575         }
576
577
578         thousands_sep = '\0';
579         grouping = NULL;
580 #ifndef NO_FLOATING_POINT
581         decimal_point = localeconv()->decimal_point;
582 #endif
583         convbuf = NULL;
584         /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */
585         if (prepwrite(fp) != 0)
586                 return (EOF);
587
588         /* optimise fprintf(stderr) (and other unbuffered Unix files) */
589         if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
590             fp->_file >= 0)
591                 return (__sbprintf(fp, fmt0, ap));
592
593         fmt = (wchar_t *)fmt0;
594         argtable = NULL;
595         nextarg = 1;
596         va_copy(orgap, ap);
597         ret = 0;
598
599         /*
600          * Scan the format for conversions (`%' character).
601          */
602         for (;;) {
603                 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
604                         /* void */;
605                 if ((n = fmt - cp) != 0) {
606                         if ((unsigned)ret + n > INT_MAX) {
607                                 ret = EOF;
608                                 goto error;
609                         }
610                         PRINT(cp, n);
611                         ret += n;
612                 }
613                 if (ch == '\0')
614                         goto done;
615                 fmt++;          /* skip over '%' */
616
617                 flags = 0;
618                 dprec = 0;
619                 width = 0;
620                 prec = -1;
621                 sign = '\0';
622                 ox[1] = '\0';
623
624 rflag:          ch = *fmt++;
625 reswitch:       switch (ch) {
626                 case ' ':
627                         /*-
628                          * ``If the space and + flags both appear, the space
629                          * flag will be ignored.''
630                          *      -- ANSI X3J11
631                          */
632                         if (!sign)
633                                 sign = ' ';
634                         goto rflag;
635                 case '#':
636                         flags |= ALT;
637                         goto rflag;
638                 case '*':
639                         /*-
640                          * ``A negative field width argument is taken as a
641                          * - flag followed by a positive field width.''
642                          *      -- ANSI X3J11
643                          * They don't exclude field widths read from args.
644                          */
645                         GETASTER (width);
646                         if (width >= 0)
647                                 goto rflag;
648                         width = -width;
649                         /* FALLTHROUGH */
650                 case '-':
651                         flags |= LADJUST;
652                         goto rflag;
653                 case '+':
654                         sign = '+';
655                         goto rflag;
656                 case '\'':
657                         flags |= GROUPING;
658                         thousands_sep = *(localeconv()->thousands_sep);
659                         grouping = localeconv()->grouping;
660                         goto rflag;
661                 case '.':
662                         if ((ch = *fmt++) == '*') {
663                                 GETASTER (prec);
664                                 goto rflag;
665                         }
666                         prec = 0;
667                         while (is_digit(ch)) {
668                                 prec = 10 * prec + to_digit(ch);
669                                 ch = *fmt++;
670                         }
671                         goto reswitch;
672                 case '0':
673                         /*-
674                          * ``Note that 0 is taken as a flag, not as the
675                          * beginning of a field width.''
676                          *      -- ANSI X3J11
677                          */
678                         flags |= ZEROPAD;
679                         goto rflag;
680                 case '1': case '2': case '3': case '4':
681                 case '5': case '6': case '7': case '8': case '9':
682                         n = 0;
683                         do {
684                                 n = 10 * n + to_digit(ch);
685                                 ch = *fmt++;
686                         } while (is_digit(ch));
687                         if (ch == '$') {
688                                 nextarg = n;
689                                 if (argtable == NULL) {
690                                         argtable = statargtable;
691                                         if (__find_warguments (fmt0, orgap,
692                                                                &argtable)) {
693                                                 ret = EOF;
694                                                 goto error;
695                                         }
696                                 }
697                                 goto rflag;
698                         }
699                         width = n;
700                         goto reswitch;
701 #ifndef NO_FLOATING_POINT
702                 case 'L':
703                         flags |= LONGDBL;
704                         goto rflag;
705 #endif
706                 case 'h':
707                         if (flags & SHORTINT) {
708                                 flags &= ~SHORTINT;
709                                 flags |= CHARINT;
710                         } else
711                                 flags |= SHORTINT;
712                         goto rflag;
713                 case 'j':
714                         flags |= INTMAXT;
715                         goto rflag;
716                 case 'l':
717                         if (flags & LONGINT) {
718                                 flags &= ~LONGINT;
719                                 flags |= LLONGINT;
720                         } else
721                                 flags |= LONGINT;
722                         goto rflag;
723                 case 'q':
724                         flags |= LLONGINT;      /* not necessarily */
725                         goto rflag;
726                 case 't':
727                         flags |= PTRDIFFT;
728                         goto rflag;
729                 case 'z':
730                         flags |= SIZET;
731                         goto rflag;
732                 case 'C':
733                         flags |= LONGINT;
734                         /*FALLTHROUGH*/
735                 case 'c':
736                         if (flags & LONGINT)
737                                 *(cp = buf) = (wchar_t)GETARG(wint_t);
738                         else
739                                 *(cp = buf) = (wchar_t)btowc(GETARG(int));
740                         size = 1;
741                         sign = '\0';
742                         break;
743                 case 'D':
744                         flags |= LONGINT;
745                         /*FALLTHROUGH*/
746                 case 'd':
747                 case 'i':
748                         if (flags & INTMAX_SIZE) {
749                                 ujval = SJARG();
750                                 if ((intmax_t)ujval < 0) {
751                                         ujval = -ujval;
752                                         sign = '-';
753                                 }
754                         } else {
755                                 ulval = SARG();
756                                 if ((long)ulval < 0) {
757                                         ulval = -ulval;
758                                         sign = '-';
759                                 }
760                         }
761                         base = 10;
762                         goto number;
763 #ifndef NO_FLOATING_POINT
764                 case 'a':
765                 case 'A':
766                         if (ch == 'a') {
767                                 ox[1] = 'x';
768                                 xdigs = xdigs_lower;
769                                 expchar = 'p';
770                         } else {
771                                 ox[1] = 'X';
772                                 xdigs = xdigs_upper;
773                                 expchar = 'P';
774                         }
775                         if (prec >= 0)
776                                 prec++;
777                         if (flags & LONGDBL) {
778                                 fparg.ldbl = GETARG(long double);
779                                 dtoaresult =
780                                     __hldtoa(fparg.ldbl, xdigs, prec,
781                                         &expt, &signflag, &dtoaend);
782                         } else {
783                                 fparg.dbl = GETARG(double);
784                                 dtoaresult =
785                                     __hdtoa(fparg.dbl, xdigs, prec,
786                                         &expt, &signflag, &dtoaend);
787                         }
788                         if (prec < 0)
789                                 prec = dtoaend - dtoaresult;
790                         if (expt == INT_MAX)
791                                 ox[1] = '\0';
792                         if (convbuf != NULL)
793                                 free(convbuf);
794                         ndig = dtoaend - dtoaresult;
795                         cp = convbuf = __mbsconv(dtoaresult, -1);
796                         freedtoa(dtoaresult);
797                         goto fp_common;
798                 case 'e':
799                 case 'E':
800                         expchar = ch;
801                         if (prec < 0)   /* account for digit before decpt */
802                                 prec = DEFPREC + 1;
803                         else
804                                 prec++;
805                         goto fp_begin;
806                 case 'f':
807                 case 'F':
808                         expchar = '\0';
809                         goto fp_begin;
810                 case 'g':
811                 case 'G':
812                         expchar = ch - ('g' - 'e');
813                         if (prec == 0)
814                                 prec = 1;
815 fp_begin:
816                         if (prec < 0)
817                                 prec = DEFPREC;
818                         if (convbuf != NULL)
819                                 free(convbuf);
820                         if (flags & LONGDBL) {
821                                 fparg.ldbl = GETARG(long double);
822                                 dtoaresult =
823                                     __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
824                                     &expt, &signflag, &dtoaend);
825                         } else {
826                                 fparg.dbl = GETARG(double);
827                                 dtoaresult =
828                                     dtoa(fparg.dbl, expchar ? 2 : 3, prec,
829                                     &expt, &signflag, &dtoaend);
830                                 if (expt == 9999)
831                                         expt = INT_MAX;
832                         }
833                         ndig = dtoaend - dtoaresult;
834                         cp = convbuf = __mbsconv(dtoaresult, -1);
835                         freedtoa(dtoaresult);
836 fp_common:
837                         if (signflag)
838                                 sign = '-';
839                         if (expt == INT_MAX) {  /* inf or nan */
840                                 if (*cp == 'N') {
841                                         cp = (ch >= 'a') ? L"nan" : L"NAN";
842                                         sign = '\0';
843                                 } else
844                                         cp = (ch >= 'a') ? L"inf" : L"INF";
845                                 size = 3;
846                                 flags &= ~ZEROPAD;
847                                 break;
848                         }
849                         flags |= FPT;
850                         if (ch == 'g' || ch == 'G') {
851                                 if (expt > -4 && expt <= prec) {
852                                         /* Make %[gG] smell like %[fF] */
853                                         expchar = '\0';
854                                         if (flags & ALT)
855                                                 prec -= expt;
856                                         else
857                                                 prec = ndig - expt;
858                                         if (prec < 0)
859                                                 prec = 0;
860                                 } else {
861                                         /*
862                                          * Make %[gG] smell like %[eE], but
863                                          * trim trailing zeroes if no # flag.
864                                          */
865                                         if (!(flags & ALT))
866                                                 prec = ndig;
867                                 }
868                         }
869                         if (expchar) {
870                                 expsize = exponent(expstr, expt - 1, expchar);
871                                 size = expsize + prec;
872                                 if (prec > 1 || flags & ALT)
873                                         ++size;
874                         } else {
875                                 /* space for digits before decimal point */
876                                 if (expt > 0)
877                                         size = expt;
878                                 else    /* "0" */
879                                         size = 1;
880                                 /* space for decimal pt and following digits */
881                                 if (prec || flags & ALT)
882                                         size += prec + 1;
883                                 if (grouping && expt > 0) {
884                                         /* space for thousands' grouping */
885                                         nseps = nrepeats = 0;
886                                         lead = expt;
887                                         while (*grouping != CHAR_MAX) {
888                                                 if (lead <= *grouping)
889                                                         break;
890                                                 lead -= *grouping;
891                                                 if (*(grouping+1)) {
892                                                         nseps++;
893                                                         grouping++;
894                                                 } else
895                                                         nrepeats++;
896                                         }
897                                         size += nseps + nrepeats;
898                                 } else
899                                         lead = expt;
900                         }
901                         break;
902 #endif /* !NO_FLOATING_POINT */
903                 case 'n':
904                         /*
905                          * Assignment-like behavior is specified if the
906                          * value overflows or is otherwise unrepresentable.
907                          * C99 says to use `signed char' for %hhn conversions.
908                          */
909                         if (flags & LLONGINT)
910                                 *GETARG(long long *) = ret;
911                         else if (flags & SIZET)
912                                 *GETARG(ssize_t *) = (ssize_t)ret;
913                         else if (flags & PTRDIFFT)
914                                 *GETARG(ptrdiff_t *) = ret;
915                         else if (flags & INTMAXT)
916                                 *GETARG(intmax_t *) = ret;
917                         else if (flags & LONGINT)
918                                 *GETARG(long *) = ret;
919                         else if (flags & SHORTINT)
920                                 *GETARG(short *) = ret;
921                         else if (flags & CHARINT)
922                                 *GETARG(signed char *) = ret;
923                         else
924                                 *GETARG(int *) = ret;
925                         continue;       /* no output */
926                 case 'O':
927                         flags |= LONGINT;
928                         /*FALLTHROUGH*/
929                 case 'o':
930                         if (flags & INTMAX_SIZE)
931                                 ujval = UJARG();
932                         else
933                                 ulval = UARG();
934                         base = 8;
935                         goto nosign;
936                 case 'p':
937                         /*-
938                          * ``The argument shall be a pointer to void.  The
939                          * value of the pointer is converted to a sequence
940                          * of printable characters, in an implementation-
941                          * defined manner.''
942                          *      -- ANSI X3J11
943                          */
944                         ujval = (uintmax_t)(uintptr_t)GETARG(void *);
945                         base = 16;
946                         xdigs = xdigs_lower;
947                         flags = flags | INTMAXT;
948                         ox[1] = 'x';
949                         goto nosign;
950                 case 'S':
951                         flags |= LONGINT;
952                         /*FALLTHROUGH*/
953                 case 's':
954                         if (flags & LONGINT) {
955                                 if ((cp = GETARG(wchar_t *)) == NULL)
956                                         cp = L"(null)";
957                         } else {
958                                 char *mbp;
959
960                                 if (convbuf != NULL)
961                                         free(convbuf);
962                                 if ((mbp = GETARG(char *)) == NULL)
963                                         cp = L"(null)";
964                                 else {
965                                         convbuf = __mbsconv(mbp, prec);
966                                         if (convbuf == NULL) {
967                                                 fp->_flags |= __SERR;
968                                                 goto error;
969                                         }
970                                         cp = convbuf;
971                                 }
972                         }
973
974                         if (prec >= 0) {
975                                 /*
976                                  * can't use wcslen; can only look for the
977                                  * NUL in the first `prec' characters, and
978                                  * wcslen() will go further.
979                                  */
980                                 wchar_t *p = wmemchr(cp, 0, (size_t)prec);
981
982                                 if (p != NULL) {
983                                         size = p - cp;
984                                         if (size > prec)
985                                                 size = prec;
986                                 } else
987                                         size = prec;
988                         } else
989                                 size = wcslen(cp);
990                         sign = '\0';
991                         break;
992                 case 'U':
993                         flags |= LONGINT;
994                         /*FALLTHROUGH*/
995                 case 'u':
996                         if (flags & INTMAX_SIZE)
997                                 ujval = UJARG();
998                         else
999                                 ulval = UARG();
1000                         base = 10;
1001                         goto nosign;
1002                 case 'X':
1003                         xdigs = xdigs_upper;
1004                         goto hex;
1005                 case 'x':
1006                         xdigs = xdigs_lower;
1007 hex:
1008                         if (flags & INTMAX_SIZE)
1009                                 ujval = UJARG();
1010                         else
1011                                 ulval = UARG();
1012                         base = 16;
1013                         /* leading 0x/X only if non-zero */
1014                         if (flags & ALT &&
1015                             (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
1016                                 ox[1] = ch;
1017
1018                         flags &= ~GROUPING;
1019                         /* unsigned conversions */
1020 nosign:                 sign = '\0';
1021                         /*-
1022                          * ``... diouXx conversions ... if a precision is
1023                          * specified, the 0 flag will be ignored.''
1024                          *      -- ANSI X3J11
1025                          */
1026 number:                 if ((dprec = prec) >= 0)
1027                                 flags &= ~ZEROPAD;
1028
1029                         /*-
1030                          * ``The result of converting a zero value with an
1031                          * explicit precision of zero is no characters.''
1032                          *      -- ANSI X3J11
1033                          *
1034                          * ``The C Standard is clear enough as is.  The call
1035                          * printf("%#.0o", 0) should print 0.''
1036                          *      -- Defect Report #151
1037                          */
1038                         cp = buf + BUF;
1039                         if (flags & INTMAX_SIZE) {
1040                                 if (ujval != 0 || prec != 0 ||
1041                                     (flags & ALT && base == 8))
1042                                         cp = __ujtoa(ujval, cp, base,
1043                                             flags & ALT, xdigs,
1044                                             flags & GROUPING, thousands_sep,
1045                                             grouping);
1046                         } else {
1047                                 if (ulval != 0 || prec != 0 ||
1048                                     (flags & ALT && base == 8))
1049                                         cp = __ultoa(ulval, cp, base,
1050                                             flags & ALT, xdigs,
1051                                             flags & GROUPING, thousands_sep,
1052                                             grouping);
1053                         }
1054                         size = buf + BUF - cp;
1055                         if (size > BUF) /* should never happen */
1056                                 abort();
1057                         break;
1058                 default:        /* "%?" prints ?, unless ? is NUL */
1059                         if (ch == '\0')
1060                                 goto done;
1061                         /* pretend it was %c with argument ch */
1062                         cp = buf;
1063                         *cp = ch;
1064                         size = 1;
1065                         sign = '\0';
1066                         break;
1067                 }
1068
1069                 /*
1070                  * All reasonable formats wind up here.  At this point, `cp'
1071                  * points to a string which (if not flags&LADJUST) should be
1072                  * padded out to `width' places.  If flags&ZEROPAD, it should
1073                  * first be prefixed by any sign or other prefix; otherwise,
1074                  * it should be blank padded before the prefix is emitted.
1075                  * After any left-hand padding and prefixing, emit zeroes
1076                  * required by a decimal [diouxX] precision, then print the
1077                  * string proper, then emit zeroes required by any leftover
1078                  * floating precision; finally, if LADJUST, pad with blanks.
1079                  *
1080                  * Compute actual size, so we know how much to pad.
1081                  * size excludes decimal prec; realsz includes it.
1082                  */
1083                 realsz = dprec > size ? dprec : size;
1084                 if (sign)
1085                         realsz++;
1086                 if (ox[1])
1087                         realsz += 2;
1088
1089                 prsize = width > realsz ? width : realsz;
1090                 if ((unsigned)ret + prsize > INT_MAX) {
1091                         ret = EOF;
1092                         goto error;
1093                 }
1094
1095                 /* right-adjusting blank padding */
1096                 if ((flags & (LADJUST|ZEROPAD)) == 0)
1097                         PAD(width - realsz, blanks);
1098
1099                 /* prefix */
1100                 if (sign)
1101                         PRINT(&sign, 1);
1102
1103                 if (ox[1]) {    /* ox[1] is either x, X, or \0 */
1104                         ox[0] = '0';
1105                         PRINT(ox, 2);
1106                 }
1107
1108                 /* right-adjusting zero padding */
1109                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1110                         PAD(width - realsz, zeroes);
1111
1112                 /* leading zeroes from decimal precision */
1113                 PAD(dprec - size, zeroes);
1114
1115                 /* the string or number proper */
1116 #ifndef NO_FLOATING_POINT
1117                 if ((flags & FPT) == 0) {
1118                         PRINT(cp, size);
1119                 } else {        /* glue together f_p fragments */
1120                         if (!expchar) { /* %[fF] or sufficiently short %[gG] */
1121                                 if (expt <= 0) {
1122                                         PRINT(zeroes, 1);
1123                                         if (prec || flags & ALT)
1124                                                 PRINT(decimal_point, 1);
1125                                         PAD(-expt, zeroes);
1126                                         /* already handled initial 0's */
1127                                         prec += expt;
1128                                 } else {
1129                                         PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
1130                                         cp += lead;
1131                                         if (grouping) {
1132                                                 while (nseps>0 || nrepeats>0) {
1133                                                         if (nrepeats > 0)
1134                                                                 nrepeats--;
1135                                                         else {
1136                                                                 grouping--;
1137                                                                 nseps--;
1138                                                         }
1139                                                         PRINT(&thousands_sep,
1140                                                             1);
1141                                                         PRINTANDPAD(cp,
1142                                                             convbuf + ndig,
1143                                                             *grouping, zeroes);
1144                                                         cp += *grouping;
1145                                                 }
1146                                                 if (cp > convbuf + ndig)
1147                                                         cp = convbuf + ndig;
1148                                         }
1149                                         if (prec || flags & ALT) {
1150                                                 buf[0] = *decimal_point;
1151                                                 PRINT(buf, 1);
1152                                         }
1153                                 }
1154                                 PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
1155                         } else {        /* %[eE] or sufficiently long %[gG] */
1156                                 if (prec > 1 || flags & ALT) {
1157                                         buf[0] = *cp++;
1158                                         buf[1] = *decimal_point;
1159                                         PRINT(buf, 2);
1160                                         PRINT(cp, ndig-1);
1161                                         PAD(prec - ndig, zeroes);
1162                                 } else  /* XeYYY */
1163                                         PRINT(cp, 1);
1164                                 PRINT(expstr, expsize);
1165                         }
1166                 }
1167 #else
1168                 PRINT(cp, size);
1169 #endif
1170                 /* left-adjusting padding (always blank) */
1171                 if (flags & LADJUST)
1172                         PAD(width - realsz, blanks);
1173
1174                 /* finally, adjust ret */
1175                 ret += prsize;
1176         }
1177 done:
1178 error:
1179         va_end(orgap);
1180         if (convbuf != NULL)
1181                 free(convbuf);
1182         if (__sferror(fp))
1183                 ret = EOF;
1184         if ((argtable != NULL) && (argtable != statargtable))
1185                 free (argtable);
1186         return (ret);
1187         /* NOTREACHED */
1188 }
1189
1190
1191 #ifndef NO_FLOATING_POINT
1192
1193 static int
1194 exponent(wchar_t *p0, int exp, wchar_t fmtch)
1195 {
1196         wchar_t *p, *t;
1197         wchar_t expbuf[MAXEXPDIG];
1198
1199         p = p0;
1200         *p++ = fmtch;
1201         if (exp < 0) {
1202                 exp = -exp;
1203                 *p++ = '-';
1204         }
1205         else
1206                 *p++ = '+';
1207         t = expbuf + MAXEXPDIG;
1208         if (exp > 9) {
1209                 do {
1210                         *--t = to_char(exp % 10);
1211                 } while ((exp /= 10) > 9);
1212                 *--t = to_char(exp);
1213                 for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
1214         }
1215         else {
1216                 /*
1217                  * Exponents for decimal floating point conversions
1218                  * (%[eEgG]) must be at least two characters long,
1219                  * whereas exponents for hexadecimal conversions can
1220                  * be only one character long.
1221                  */
1222                 if (fmtch == 'e' || fmtch == 'E')
1223                         *p++ = '0';
1224                 *p++ = to_char(exp);
1225         }
1226         return (p - p0);
1227 }
1228 #endif /* !NO_FLOATING_POINT */