acpi: Narrow workaround for broken interrupt settings
[dragonfly.git] / lib / libc / stdio / vfprintf.c
blob6215a07df6d7902b79fbd0470d0fe84adb92ced9
1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
8 * Copyright (c) 2011 The FreeBSD Foundation
9 * All rights reserved.
10 * Portions of this software were developed by David Chisnall
11 * under sponsorship from the FreeBSD Foundation.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
37 * @(#)vfprintf.c 8.1 (Berkeley) 6/4/93
38 * $FreeBSD: head/lib/libc/stdio/vfprintf.c 268930 2014-07-20 21:24:29Z pfg $
42 * Actual printf innards.
44 * This code is large and complicated...
47 #include "namespace.h"
48 #include <sys/types.h>
50 #include <ctype.h>
51 #include <errno.h>
52 #include <limits.h>
53 #include <pthread.h> /* for FAKE_FILE PTHREAD_MUTEX_INITIALIZER */
54 #include <locale.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 <printf.h>
63 #include <stdarg.h>
64 #include "xlocale_private.h"
65 #include "un-namespace.h"
67 #include "libc_private.h"
68 #include "local.h"
69 #include "printflocal.h"
71 static int __sprint(FILE *, struct __suio *, locale_t);
72 static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0)
73 __noinline;
74 static char *__wcsconv(wchar_t *, int);
76 #define CHAR char
77 #include "printfcommon.h"
79 struct grouping_state {
80 char *thousands_sep; /* locale-specific thousands separator */
81 int thousep_len; /* length of thousands_sep */
82 const char *grouping; /* locale-specific numeric grouping rules */
83 int lead; /* sig figs before decimal or group sep */
84 int nseps; /* number of group separators with ' */
85 int nrepeats; /* number of repeats of the last group */
89 * Initialize the thousands' grouping state in preparation to print a
90 * number with ndigits digits. This routine returns the total number
91 * of bytes that will be needed.
93 static int
94 grouping_init(struct grouping_state *gs, int ndigits, locale_t loc)
96 struct lconv *locale;
98 locale = localeconv_l(loc);
99 gs->grouping = locale->grouping;
100 gs->thousands_sep = locale->thousands_sep;
101 gs->thousep_len = strlen(gs->thousands_sep);
103 gs->nseps = gs->nrepeats = 0;
104 gs->lead = ndigits;
105 while (*gs->grouping != CHAR_MAX) {
106 if (gs->lead <= *gs->grouping)
107 break;
108 gs->lead -= *gs->grouping;
109 if (*(gs->grouping+1)) {
110 gs->nseps++;
111 gs->grouping++;
112 } else
113 gs->nrepeats++;
115 return ((gs->nseps + gs->nrepeats) * gs->thousep_len);
119 * Print a number with thousands' separators.
121 static int
122 grouping_print(struct grouping_state *gs, struct io_state *iop,
123 const CHAR *cp, const CHAR *ep, locale_t locale)
125 const CHAR *cp0 = cp;
127 if (io_printandpad(iop, cp, ep, gs->lead, zeroes, locale))
128 return (-1);
129 cp += gs->lead;
130 while (gs->nseps > 0 || gs->nrepeats > 0) {
131 if (gs->nrepeats > 0)
132 gs->nrepeats--;
133 else {
134 gs->grouping--;
135 gs->nseps--;
137 if (io_print(iop, gs->thousands_sep, gs->thousep_len, locale))
138 return (-1);
139 if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, locale))
140 return (-1);
141 cp += *gs->grouping;
143 if (cp > ep)
144 cp = ep;
145 return (cp - cp0);
149 * Flush out all the vectors defined by the given uio,
150 * then reset it so that it can be reused.
152 static int
153 __sprint(FILE *fp, struct __suio *uio, locale_t locale __unused)
155 int err;
157 if (uio->uio_resid == 0) {
158 uio->uio_iovcnt = 0;
159 return (0);
161 err = __sfvwrite(fp, uio);
162 uio->uio_resid = 0;
163 uio->uio_iovcnt = 0;
164 return (err);
168 * Helper function for `fprintf to unbuffered unix file': creates a
169 * temporary buffer. We only work on write-only files; this avoids
170 * worries about ungetc buffers and so forth.
172 static int
173 __sbprintf(FILE *fp, locale_t locale, const char *fmt, va_list ap)
175 int ret;
176 FILE fake = FAKE_FILE;
177 unsigned char buf[BUFSIZ];
179 /* XXX This is probably not needed. */
180 if (prepwrite(fp) != 0)
181 return (EOF);
183 /* copy the important variables */
184 fake.pub._flags = fp->pub._flags & ~__SNBF;
185 fake.pub._fileno = fp->pub._fileno;
186 fake._cookie = fp->_cookie;
187 fake._write = fp->_write;
189 /* set up the buffer */
190 fake._bf._base = fake.pub._p = buf;
191 fake._bf._size = fake.pub._w = sizeof(buf);
192 fake.pub._lbfsize = 0; /* not actually used, but Just In Case */
194 /* do the work, then copy any error status */
195 ret = __vfprintf(&fake, locale, fmt, ap);
196 if (ret >= 0 && __fflush(&fake))
197 ret = EOF;
198 if (fake.pub._flags & __SERR)
199 fp->pub._flags |= __SERR;
200 return (ret);
204 * Convert a wide character string argument for the %ls format to a multibyte
205 * string representation. If not -1, prec specifies the maximum number of
206 * bytes to output, and also means that we can't assume that the wide char.
207 * string ends is null-terminated.
209 static char *
210 __wcsconv(wchar_t *wcsarg, int prec)
212 static const mbstate_t initial;
213 mbstate_t mbs;
214 char buf[MB_LEN_MAX];
215 wchar_t *p;
216 char *convbuf;
217 size_t clen, nbytes;
219 /* Allocate space for the maximum number of bytes we could output. */
220 if (prec < 0) {
221 p = wcsarg;
222 mbs = initial;
223 nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
224 if (nbytes == (size_t)-1)
225 return (NULL);
226 } else {
228 * Optimisation: if the output precision is small enough,
229 * just allocate enough memory for the maximum instead of
230 * scanning the string.
232 if (prec < 128)
233 nbytes = prec;
234 else {
235 nbytes = 0;
236 p = wcsarg;
237 mbs = initial;
238 for (;;) {
239 clen = wcrtomb(buf, *p++, &mbs);
240 if (clen == 0 || clen == (size_t)-1 ||
241 nbytes + clen > prec)
242 break;
243 nbytes += clen;
247 if ((convbuf = malloc(nbytes + 1)) == NULL)
248 return (NULL);
250 /* Fill the output buffer. */
251 p = wcsarg;
252 mbs = initial;
253 if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
254 nbytes, &mbs)) == (size_t)-1) {
255 free(convbuf);
256 return (NULL);
258 convbuf[nbytes] = '\0';
259 return (convbuf);
263 * MT-safe version
266 vfprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt0,
267 va_list ap)
269 int ret;
270 FIX_LOCALE(locale);
272 FLOCKFILE(fp);
273 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
274 if ((fp->pub._flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
275 fp->pub._fileno >= 0)
276 ret = __sbprintf(fp, locale, fmt0, ap);
277 else
278 ret = __vfprintf(fp, locale, fmt0, ap);
279 FUNLOCKFILE(fp);
280 return (ret);
283 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
285 return vfprintf_l(fp, __get_locale(), fmt0, ap);
289 * The size of the buffer we use as scratch space for integer
290 * conversions, among other things. We need enough space to
291 * write a uintmax_t in octal (plus one byte).
293 #if UINTMAX_MAX <= UINT64_MAX
294 #define BUF 32
295 #else
296 #error "BUF must be large enough to format a uintmax_t"
297 #endif
300 * Non-MT-safe version
303 __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
305 char *fmt; /* format string */
306 int ch; /* character from fmt */
307 int n, n2; /* handy integer (short term usage) */
308 char *cp; /* handy char pointer (short term usage) */
309 int flags; /* flags as above */
310 int ret; /* return value accumulator */
311 int width; /* width from format (%8d), or 0 */
312 int prec; /* precision from format; <0 for N/A */
313 char sign; /* sign prefix (' ', '+', '-', or \0) */
314 struct grouping_state gs; /* thousands' grouping info */
316 #ifndef NO_FLOATING_POINT
318 * We can decompose the printed representation of floating
319 * point numbers into several parts, some of which may be empty:
321 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
322 * A B ---C--- D E F
324 * A: 'sign' holds this value if present; '\0' otherwise
325 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
326 * C: cp points to the string MMMNNN. Leading and trailing
327 * zeros are not in the string and must be added.
328 * D: expchar holds this character; '\0' if no exponent, e.g. %f
329 * F: at least two digits for decimal, at least one digit for hex
331 char *decimal_point; /* locale specific decimal point */
332 int decpt_len; /* length of decimal_point */
333 int signflag; /* true if float is negative */
334 union { /* floating point arguments %[aAeEfFgG] */
335 double dbl;
336 long double ldbl;
337 } fparg;
338 int expt; /* integer value of exponent */
339 char expchar; /* exponent character: [eEpP\0] */
340 char *dtoaend; /* pointer to end of converted digits */
341 int expsize; /* character count for expstr */
342 int ndig; /* actual number of digits returned by dtoa */
343 char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
344 char *dtoaresult; /* buffer allocated by dtoa */
345 #endif
346 u_long ulval; /* integer arguments %[diouxX] */
347 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
348 int base; /* base for [diouxX] conversion */
349 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
350 int realsz; /* field size expanded by dprec, sign, etc */
351 int size; /* size of converted field or string */
352 int prsize; /* max size of printed field */
353 const char *xdigs; /* digits for %[xX] conversion */
354 struct io_state io; /* I/O buffering state */
355 char buf[BUF]; /* buffer with space for digits of uintmax_t */
356 char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
357 union arg *argtable; /* args, built due to positional arg */
358 union arg statargtable [STATIC_ARG_TBL_SIZE];
359 int nextarg; /* 1-based argument index */
360 va_list orgap; /* original argument pointer */
361 char *convbuf; /* wide to multibyte conversion result */
363 static const char xdigs_lower[16] = "0123456789abcdef";
364 static const char xdigs_upper[16] = "0123456789ABCDEF";
366 /* BEWARE, these `goto error' on error. */
367 #define PRINT(ptr, len) { \
368 if (io_print(&io, (ptr), (len), locale)) \
369 goto error; \
371 #define PAD(howmany, with) { \
372 if (io_pad(&io, (howmany), (with), locale)) \
373 goto error; \
375 #define PRINTANDPAD(p, ep, len, with) { \
376 if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \
377 goto error; \
379 #define FLUSH() { \
380 if (io_flush(&io, locale)) \
381 goto error; \
385 * Get the argument indexed by nextarg. If the argument table is
386 * built, use it to get the argument. If its not, get the next
387 * argument (and arguments must be gotten sequentially).
389 #define GETARG(type) \
390 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
391 (nextarg++, va_arg(ap, type)))
394 * To extend shorts properly, we need both signed and unsigned
395 * argument extraction methods.
397 #define SARG() \
398 (flags&LONGINT ? GETARG(long) : \
399 flags&SHORTINT ? (long)(short)GETARG(int) : \
400 flags&CHARINT ? (long)(signed char)GETARG(int) : \
401 (long)GETARG(int))
402 #define UARG() \
403 (flags&LONGINT ? GETARG(u_long) : \
404 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
405 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
406 (u_long)GETARG(u_int))
407 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
408 #define SJARG() \
409 (flags&INTMAXT ? GETARG(intmax_t) : \
410 flags&SIZET ? (intmax_t)GETARG(ssize_t) : \
411 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
412 (intmax_t)GETARG(long long))
413 #define UJARG() \
414 (flags&INTMAXT ? GETARG(uintmax_t) : \
415 flags&SIZET ? (uintmax_t)GETARG(size_t) : \
416 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
417 (uintmax_t)GETARG(unsigned long long))
420 * Get * arguments, including the form *nn$. Preserve the nextarg
421 * that the argument can be gotten once the type is determined.
423 #define GETASTER(val) \
424 n2 = 0; \
425 cp = fmt; \
426 while (is_digit(*cp)) { \
427 n2 = 10 * n2 + to_digit(*cp); \
428 cp++; \
430 if (*cp == '$') { \
431 int hold = nextarg; \
432 if (argtable == NULL) { \
433 argtable = statargtable; \
434 if (__find_arguments (fmt0, orgap, &argtable)) { \
435 ret = EOF; \
436 goto error; \
439 nextarg = n2; \
440 val = GETARG (int); \
441 nextarg = hold; \
442 fmt = ++cp; \
443 } else { \
444 val = GETARG (int); \
447 if (__use_xprintf == 0 && getenv("USE_XPRINTF"))
448 __use_xprintf = 1;
449 if (__use_xprintf > 0)
450 return (__xvprintf(fp, fmt0, ap));
452 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
453 if (prepwrite(fp) != 0) {
454 errno = EBADF;
455 return (EOF);
458 convbuf = NULL;
459 fmt = (char *)fmt0;
460 argtable = NULL;
461 nextarg = 1;
462 va_copy(orgap, ap);
463 io_init(&io, fp);
464 ret = 0;
465 #ifndef NO_FLOATING_POINT
466 dtoaresult = NULL;
467 decimal_point = localeconv_l(locale)->decimal_point;
468 /* The overwhelmingly common case is decpt_len == 1. */
469 decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point));
470 #endif
473 * Scan the format for conversions (`%' character).
475 for (;;) {
476 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
477 /* void */;
478 if ((n = fmt - cp) != 0) {
479 if ((unsigned)ret + n > INT_MAX) {
480 ret = EOF;
481 errno = EOVERFLOW;
482 goto error;
484 PRINT(cp, n);
485 ret += n;
487 if (ch == '\0')
488 goto done;
489 fmt++; /* skip over '%' */
491 flags = 0;
492 dprec = 0;
493 width = 0;
494 prec = -1;
495 gs.grouping = NULL;
496 sign = '\0';
497 ox[1] = '\0';
499 rflag: ch = *fmt++;
500 reswitch: switch (ch) {
501 case ' ':
503 * ``If the space and + flags both appear, the space
504 * flag will be ignored.''
505 * -- ANSI X3J11
507 if (!sign)
508 sign = ' ';
509 goto rflag;
510 case '#':
511 flags |= ALT;
512 goto rflag;
513 case '*':
515 * ``A negative field width argument is taken as a
516 * - flag followed by a positive field width.''
517 * -- ANSI X3J11
518 * They don't exclude field widths read from args.
520 GETASTER (width);
521 if (width >= 0)
522 goto rflag;
523 width = -width;
524 /* FALLTHROUGH */
525 case '-':
526 flags |= LADJUST;
527 goto rflag;
528 case '+':
529 sign = '+';
530 goto rflag;
531 case '\'':
532 flags |= GROUPING;
533 goto rflag;
534 case '.':
535 if ((ch = *fmt++) == '*') {
536 GETASTER (prec);
537 goto rflag;
539 prec = 0;
540 while (is_digit(ch)) {
541 prec = 10 * prec + to_digit(ch);
542 ch = *fmt++;
544 goto reswitch;
545 case '0':
547 * ``Note that 0 is taken as a flag, not as the
548 * beginning of a field width.''
549 * -- ANSI X3J11
551 flags |= ZEROPAD;
552 goto rflag;
553 case '1': case '2': case '3': case '4':
554 case '5': case '6': case '7': case '8': case '9':
555 n = 0;
556 do {
557 n = 10 * n + to_digit(ch);
558 ch = *fmt++;
559 } while (is_digit(ch));
560 if (ch == '$') {
561 nextarg = n;
562 if (argtable == NULL) {
563 argtable = statargtable;
564 if (__find_arguments (fmt0, orgap,
565 &argtable)) {
566 ret = EOF;
567 goto error;
570 goto rflag;
572 width = n;
573 goto reswitch;
574 #ifndef NO_FLOATING_POINT
575 case 'L':
576 flags |= LONGDBL;
577 goto rflag;
578 #endif
579 case 'h':
580 if (flags & SHORTINT) {
581 flags &= ~SHORTINT;
582 flags |= CHARINT;
583 } else
584 flags |= SHORTINT;
585 goto rflag;
586 case 'j':
587 flags |= INTMAXT;
588 goto rflag;
589 case 'l':
590 if (flags & LONGINT) {
591 flags &= ~LONGINT;
592 flags |= LLONGINT;
593 } else
594 flags |= LONGINT;
595 goto rflag;
596 case 'q':
597 flags |= LLONGINT; /* not necessarily */
598 goto rflag;
599 case 't':
600 flags |= PTRDIFFT;
601 goto rflag;
602 case 'z':
603 flags |= SIZET;
604 goto rflag;
605 case 'C':
606 flags |= LONGINT;
607 /*FALLTHROUGH*/
608 case 'c':
609 if (flags & LONGINT) {
610 static const mbstate_t initial;
611 mbstate_t mbs;
612 size_t mbseqlen;
614 mbs = initial;
615 mbseqlen = wcrtomb(cp = buf,
616 (wchar_t)GETARG(wint_t), &mbs);
617 if (mbseqlen == (size_t)-1) {
618 fp->pub._flags |= __SERR;
619 goto error;
621 size = (int)mbseqlen;
622 } else {
623 *(cp = buf) = GETARG(int);
624 size = 1;
626 sign = '\0';
627 break;
628 case 'D':
629 flags |= LONGINT;
630 /*FALLTHROUGH*/
631 case 'd':
632 case 'i':
633 if (flags & INTMAX_SIZE) {
634 ujval = SJARG();
635 if ((intmax_t)ujval < 0) {
636 ujval = -ujval;
637 sign = '-';
639 } else {
640 ulval = SARG();
641 if ((long)ulval < 0) {
642 ulval = -ulval;
643 sign = '-';
646 base = 10;
647 goto number;
648 #ifndef NO_FLOATING_POINT
649 case 'a':
650 case 'A':
651 if (ch == 'a') {
652 ox[1] = 'x';
653 xdigs = xdigs_lower;
654 expchar = 'p';
655 } else {
656 ox[1] = 'X';
657 xdigs = xdigs_upper;
658 expchar = 'P';
660 if (prec >= 0)
661 prec++;
662 if (dtoaresult != NULL)
663 freedtoa(dtoaresult);
664 if (flags & LONGDBL) {
665 fparg.ldbl = GETARG(long double);
666 dtoaresult = cp =
667 __hldtoa(fparg.ldbl, xdigs, prec,
668 &expt, &signflag, &dtoaend);
669 } else {
670 fparg.dbl = GETARG(double);
671 dtoaresult = cp =
672 __hdtoa(fparg.dbl, xdigs, prec,
673 &expt, &signflag, &dtoaend);
675 if (prec < 0)
676 prec = dtoaend - cp;
677 if (expt == INT_MAX)
678 ox[1] = '\0';
679 goto fp_common;
680 case 'e':
681 case 'E':
682 expchar = ch;
683 if (prec < 0) /* account for digit before decpt */
684 prec = DEFPREC + 1;
685 else
686 prec++;
687 goto fp_begin;
688 case 'f':
689 case 'F':
690 expchar = '\0';
691 goto fp_begin;
692 case 'g':
693 case 'G':
694 expchar = ch - ('g' - 'e');
695 if (prec == 0)
696 prec = 1;
697 fp_begin:
698 if (prec < 0)
699 prec = DEFPREC;
700 if (dtoaresult != NULL)
701 freedtoa(dtoaresult);
702 if (flags & LONGDBL) {
703 fparg.ldbl = GETARG(long double);
704 dtoaresult = cp =
705 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
706 &expt, &signflag, &dtoaend);
707 } else {
708 fparg.dbl = GETARG(double);
709 dtoaresult = cp =
710 dtoa(fparg.dbl, expchar ? 2 : 3, prec,
711 &expt, &signflag, &dtoaend);
712 if (expt == 9999)
713 expt = INT_MAX;
715 fp_common:
716 if (signflag)
717 sign = '-';
718 if (expt == INT_MAX) { /* inf or nan */
719 if (*cp == 'N') {
720 cp = (ch >= 'a') ? "nan" : "NAN";
721 sign = '\0';
722 } else
723 cp = (ch >= 'a') ? "inf" : "INF";
724 size = 3;
725 flags &= ~ZEROPAD;
726 break;
728 flags |= FPT;
729 ndig = dtoaend - cp;
730 if (ch == 'g' || ch == 'G') {
731 if (expt > -4 && expt <= prec) {
732 /* Make %[gG] smell like %[fF] */
733 expchar = '\0';
734 if (flags & ALT)
735 prec -= expt;
736 else
737 prec = ndig - expt;
738 if (prec < 0)
739 prec = 0;
740 } else {
742 * Make %[gG] smell like %[eE], but
743 * trim trailing zeroes if no # flag.
745 if (!(flags & ALT))
746 prec = ndig;
749 if (expchar) {
750 expsize = exponent(expstr, expt - 1, expchar);
751 size = expsize + prec;
752 if (prec > 1 || flags & ALT)
753 size += decpt_len;
754 } else {
755 /* space for digits before decimal point */
756 if (expt > 0)
757 size = expt;
758 else /* "0" */
759 size = 1;
760 /* space for decimal pt and following digits */
761 if (prec || flags & ALT)
762 size += prec + decpt_len;
763 if ((flags & GROUPING) && expt > 0)
764 size += grouping_init(&gs, expt, locale);
766 break;
767 #endif /* !NO_FLOATING_POINT */
768 case 'n':
770 * Assignment-like behavior is specified if the
771 * value overflows or is otherwise unrepresentable.
772 * C99 says to use `signed char' for %hhn conversions.
774 if (flags & LLONGINT)
775 *GETARG(long long *) = ret;
776 else if (flags & SIZET)
777 *GETARG(ssize_t *) = (ssize_t)ret;
778 else if (flags & PTRDIFFT)
779 *GETARG(ptrdiff_t *) = ret;
780 else if (flags & INTMAXT)
781 *GETARG(intmax_t *) = ret;
782 else if (flags & LONGINT)
783 *GETARG(long *) = ret;
784 else if (flags & SHORTINT)
785 *GETARG(short *) = ret;
786 else if (flags & CHARINT)
787 *GETARG(signed char *) = ret;
788 else
789 *GETARG(int *) = ret;
790 continue; /* no output */
791 case 'O':
792 flags |= LONGINT;
793 /*FALLTHROUGH*/
794 case 'o':
795 if (flags & INTMAX_SIZE)
796 ujval = UJARG();
797 else
798 ulval = UARG();
799 base = 8;
800 goto nosign;
801 case 'p':
803 * ``The argument shall be a pointer to void. The
804 * value of the pointer is converted to a sequence
805 * of printable characters, in an implementation-
806 * defined manner.''
807 * -- ANSI X3J11
809 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
810 base = 16;
811 xdigs = xdigs_lower;
812 flags = flags | INTMAXT;
813 ox[1] = 'x';
814 goto nosign;
815 case 'S':
816 flags |= LONGINT;
817 /*FALLTHROUGH*/
818 case 's':
819 if (flags & LONGINT) {
820 wchar_t *wcp;
822 if (convbuf != NULL)
823 free(convbuf);
824 if ((wcp = GETARG(wchar_t *)) == NULL)
825 cp = "(null)";
826 else {
827 convbuf = __wcsconv(wcp, prec);
828 if (convbuf == NULL) {
829 fp->pub._flags |= __SERR;
830 goto error;
832 cp = convbuf;
834 } else if ((cp = GETARG(char *)) == NULL)
835 cp = "(null)";
836 size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
837 sign = '\0';
838 break;
839 case 'U':
840 flags |= LONGINT;
841 /*FALLTHROUGH*/
842 case 'u':
843 if (flags & INTMAX_SIZE)
844 ujval = UJARG();
845 else
846 ulval = UARG();
847 base = 10;
848 goto nosign;
849 case 'X':
850 xdigs = xdigs_upper;
851 goto hex;
852 case 'x':
853 xdigs = xdigs_lower;
854 hex:
855 if (flags & INTMAX_SIZE)
856 ujval = UJARG();
857 else
858 ulval = UARG();
859 base = 16;
860 /* leading 0x/X only if non-zero */
861 if (flags & ALT &&
862 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
863 ox[1] = ch;
865 flags &= ~GROUPING;
866 /* unsigned conversions */
867 nosign: sign = '\0';
869 * ``... diouXx conversions ... if a precision is
870 * specified, the 0 flag will be ignored.''
871 * -- ANSI X3J11
873 number: if ((dprec = prec) >= 0)
874 flags &= ~ZEROPAD;
877 * ``The result of converting a zero value with an
878 * explicit precision of zero is no characters.''
879 * -- ANSI X3J11
881 * ``The C Standard is clear enough as is. The call
882 * printf("%#.0o", 0) should print 0.''
883 * -- Defect Report #151
885 cp = buf + BUF;
886 if (flags & INTMAX_SIZE) {
887 if (ujval != 0 || prec != 0 ||
888 (flags & ALT && base == 8))
889 cp = __ujtoa(ujval, cp, base,
890 flags & ALT, xdigs);
891 } else {
892 if (ulval != 0 || prec != 0 ||
893 (flags & ALT && base == 8))
894 cp = __ultoa(ulval, cp, base,
895 flags & ALT, xdigs);
897 size = buf + BUF - cp;
898 if (size > BUF) /* should never happen */
899 abort();
900 if ((flags & GROUPING) && size != 0)
901 size += grouping_init(&gs, size, locale);
902 break;
903 default: /* "%?" prints ?, unless ? is NUL */
904 if (ch == '\0')
905 goto done;
906 /* pretend it was %c with argument ch */
907 cp = buf;
908 *cp = ch;
909 size = 1;
910 sign = '\0';
911 break;
915 * All reasonable formats wind up here. At this point, `cp'
916 * points to a string which (if not flags&LADJUST) should be
917 * padded out to `width' places. If flags&ZEROPAD, it should
918 * first be prefixed by any sign or other prefix; otherwise,
919 * it should be blank padded before the prefix is emitted.
920 * After any left-hand padding and prefixing, emit zeroes
921 * required by a decimal [diouxX] precision, then print the
922 * string proper, then emit zeroes required by any leftover
923 * floating precision; finally, if LADJUST, pad with blanks.
925 * Compute actual size, so we know how much to pad.
926 * size excludes decimal prec; realsz includes it.
928 realsz = dprec > size ? dprec : size;
929 if (sign)
930 realsz++;
931 if (ox[1])
932 realsz += 2;
934 prsize = width > realsz ? width : realsz;
935 if ((unsigned)ret + prsize > INT_MAX) {
936 ret = EOF;
937 errno = EOVERFLOW;
938 goto error;
941 /* right-adjusting blank padding */
942 if ((flags & (LADJUST|ZEROPAD)) == 0)
943 PAD(width - realsz, blanks);
945 /* prefix */
946 if (sign)
947 PRINT(&sign, 1);
949 if (ox[1]) { /* ox[1] is either x, X, or \0 */
950 ox[0] = '0';
951 PRINT(ox, 2);
954 /* right-adjusting zero padding */
955 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
956 PAD(width - realsz, zeroes);
958 /* the string or number proper */
959 #ifndef NO_FLOATING_POINT
960 if ((flags & FPT) == 0) {
961 #endif
962 /* leading zeroes from decimal precision */
963 PAD(dprec - size, zeroes);
964 if (gs.grouping) {
965 if (grouping_print(&gs, &io, cp, buf+BUF, locale) < 0)
966 goto error;
967 } else {
968 PRINT(cp, size);
970 #ifndef NO_FLOATING_POINT
971 } else { /* glue together f_p fragments */
972 if (!expchar) { /* %[fF] or sufficiently short %[gG] */
973 if (expt <= 0) {
974 PRINT(zeroes, 1);
975 if (prec || flags & ALT)
976 PRINT(decimal_point,decpt_len);
977 PAD(-expt, zeroes);
978 /* already handled initial 0's */
979 prec += expt;
980 } else {
981 if (gs.grouping) {
982 n = grouping_print(&gs, &io,
983 cp, dtoaend, locale);
984 if (n < 0)
985 goto error;
986 cp += n;
987 } else {
988 PRINTANDPAD(cp, dtoaend,
989 expt, zeroes);
990 cp += expt;
992 if (prec || flags & ALT)
993 PRINT(decimal_point,decpt_len);
995 PRINTANDPAD(cp, dtoaend, prec, zeroes);
996 } else { /* %[eE] or sufficiently long %[gG] */
997 if (prec > 1 || flags & ALT) {
998 PRINT(cp++, 1);
999 PRINT(decimal_point, decpt_len);
1000 PRINT(cp, ndig-1);
1001 PAD(prec - ndig, zeroes);
1002 } else /* XeYYY */
1003 PRINT(cp, 1);
1004 PRINT(expstr, expsize);
1007 #endif
1008 /* left-adjusting padding (always blank) */
1009 if (flags & LADJUST)
1010 PAD(width - realsz, blanks);
1012 /* finally, adjust ret */
1013 ret += prsize;
1015 FLUSH(); /* copy out the I/O vectors */
1017 done:
1018 FLUSH();
1019 error:
1020 va_end(orgap);
1021 #ifndef NO_FLOATING_POINT
1022 if (dtoaresult != NULL)
1023 freedtoa(dtoaresult);
1024 #endif
1025 if (convbuf != NULL)
1026 free(convbuf);
1027 if (__sferror(fp))
1028 ret = EOF;
1029 if ((argtable != NULL) && (argtable != statargtable))
1030 free (argtable);
1031 return (ret);
1032 /* NOTREACHED */