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 * 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. 12 * 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. 24 * 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. 36 * 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 $ 39 */ 40 41 /* 42 * Actual printf innards. 43 * 44 * This code is large and complicated... 45 */ 46 47 #include "namespace.h" 48 #include <sys/types.h> 49 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> 62 63 #include <stdarg.h> 64 #include "xlocale_private.h" 65 #include "un-namespace.h" 66 67 #include "libc_private.h" 68 #include "local.h" 69 #include "printflocal.h" 70 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); 75 76 #define CHAR char 77 #include "printfcommon.h" 78 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 */ 86 }; 87 88 /* 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. 92 */ 93 static int 94 grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) 95 { 96 struct lconv *locale; 97 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); 102 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++; 114 } 115 return ((gs->nseps + gs->nrepeats) * gs->thousep_len); 116 } 117 118 /* 119 * Print a number with thousands' separators. 120 */ 121 static int 122 grouping_print(struct grouping_state *gs, struct io_state *iop, 123 const CHAR *cp, const CHAR *ep, locale_t locale) 124 { 125 const CHAR *cp0 = cp; 126 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--; 136 } 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; 142 } 143 if (cp > ep) 144 cp = ep; 145 return (cp - cp0); 146 } 147 148 /* 149 * Flush out all the vectors defined by the given uio, 150 * then reset it so that it can be reused. 151 */ 152 static int 153 __sprint(FILE *fp, struct __suio *uio, locale_t locale __unused) 154 { 155 int err; 156 157 if (uio->uio_resid == 0) { 158 uio->uio_iovcnt = 0; 159 return (0); 160 } 161 err = __sfvwrite(fp, uio); 162 uio->uio_resid = 0; 163 uio->uio_iovcnt = 0; 164 return (err); 165 } 166 167 /* 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. 171 */ 172 static int 173 __sbprintf(FILE *fp, locale_t locale, const char *fmt, va_list ap) 174 { 175 int ret; 176 FILE fake = FAKE_FILE; 177 unsigned char buf[BUFSIZ]; 178 179 /* XXX This is probably not needed. */ 180 if (prepwrite(fp) != 0) 181 return (EOF); 182 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; 188 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 */ 193 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); 201 } 202 203 /* 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. 208 */ 209 static char * 210 __wcsconv(wchar_t *wcsarg, int prec) 211 { 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; 218 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 { 227 /* 228 * Optimisation: if the output precision is small enough, 229 * just allocate enough memory for the maximum instead of 230 * scanning the string. 231 */ 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; 244 } 245 } 246 } 247 if ((convbuf = malloc(nbytes + 1)) == NULL) 248 return (NULL); 249 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); 257 } 258 convbuf[nbytes] = '\0'; 259 return (convbuf); 260 } 261 262 /* 263 * MT-safe version 264 */ 265 int 266 vfprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt0, 267 va_list ap) 268 { 269 int ret; 270 FIX_LOCALE(locale); 271 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); 281 } 282 int 283 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) 284 { 285 return vfprintf_l(fp, __get_locale(), fmt0, ap); 286 } 287 288 /* 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). 292 */ 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 298 299 /* 300 * Non-MT-safe version 301 */ 302 int 303 __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) 304 { 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 */ 315 316 #ifndef NO_FLOATING_POINT 317 /* 318 * We can decompose the printed representation of floating 319 * point numbers into several parts, some of which may be empty: 320 * 321 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ 322 * A B ---C--- D E F 323 * 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 330 */ 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 */ 362 363 static const char xdigs_lower[16] = "0123456789abcdef"; 364 static const char xdigs_upper[16] = "0123456789ABCDEF"; 365 366 /* BEWARE, these `goto error' on error. */ 367 #define PRINT(ptr, len) { \ 368 if (io_print(&io, (ptr), (len), locale)) \ 369 goto error; \ 370 } 371 #define PAD(howmany, with) { \ 372 if (io_pad(&io, (howmany), (with), locale)) \ 373 goto error; \ 374 } 375 #define PRINTANDPAD(p, ep, len, with) { \ 376 if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \ 377 goto error; \ 378 } 379 #define FLUSH() { \ 380 if (io_flush(&io, locale)) \ 381 goto error; \ 382 } 383 384 /* 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). 388 */ 389 #define GETARG(type) \ 390 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ 391 (nextarg++, va_arg(ap, type))) 392 393 /* 394 * To extend shorts properly, we need both signed and unsigned 395 * argument extraction methods. 396 */ 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)) 418 419 /* 420 * Get * arguments, including the form *nn$. Preserve the nextarg 421 * that the argument can be gotten once the type is determined. 422 */ 423 #define GETASTER(val) \ 424 n2 = 0; \ 425 cp = fmt; \ 426 while (is_digit(*cp)) { \ 427 n2 = 10 * n2 + to_digit(*cp); \ 428 cp++; \ 429 } \ 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; \ 437 } \ 438 } \ 439 nextarg = n2; \ 440 val = GETARG (int); \ 441 nextarg = hold; \ 442 fmt = ++cp; \ 443 } else { \ 444 val = GETARG (int); \ 445 } 446 447 if (__use_xprintf == 0 && getenv("USE_XPRINTF")) 448 __use_xprintf = 1; 449 if (__use_xprintf > 0) 450 return (__xvprintf(fp, fmt0, ap)); 451 452 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ 453 if (prepwrite(fp) != 0) { 454 errno = EBADF; 455 return (EOF); 456 } 457 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 471 472 /* 473 * Scan the format for conversions (`%' character). 474 */ 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; 483 } 484 PRINT(cp, n); 485 ret += n; 486 } 487 if (ch == '\0') 488 goto done; 489 fmt++; /* skip over '%' */ 490 491 flags = 0; 492 dprec = 0; 493 width = 0; 494 prec = -1; 495 gs.grouping = NULL; 496 sign = '\0'; 497 ox[1] = '\0'; 498 499 rflag: ch = *fmt++; 500 reswitch: switch (ch) { 501 case ' ': 502 /*- 503 * ``If the space and + flags both appear, the space 504 * flag will be ignored.'' 505 * -- ANSI X3J11 506 */ 507 if (!sign) 508 sign = ' '; 509 goto rflag; 510 case '#': 511 flags |= ALT; 512 goto rflag; 513 case '*': 514 /*- 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. 519 */ 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; 538 } 539 prec = 0; 540 while (is_digit(ch)) { 541 prec = 10 * prec + to_digit(ch); 542 ch = *fmt++; 543 } 544 goto reswitch; 545 case '0': 546 /*- 547 * ``Note that 0 is taken as a flag, not as the 548 * beginning of a field width.'' 549 * -- ANSI X3J11 550 */ 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; 568 } 569 } 570 goto rflag; 571 } 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; 613 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; 620 } 621 size = (int)mbseqlen; 622 } else { 623 *(cp = buf) = GETARG(int); 624 size = 1; 625 } 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 = '-'; 638 } 639 } else { 640 ulval = SARG(); 641 if ((long)ulval < 0) { 642 ulval = -ulval; 643 sign = '-'; 644 } 645 } 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'; 659 } 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); 674 } 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; 714 } 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; 727 } 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 { 741 /* 742 * Make %[gG] smell like %[eE], but 743 * trim trailing zeroes if no # flag. 744 */ 745 if (!(flags & ALT)) 746 prec = ndig; 747 } 748 } 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); 765 } 766 break; 767 #endif /* !NO_FLOATING_POINT */ 768 case 'n': 769 /* 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. 773 */ 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': 802 /*- 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 808 */ 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; 821 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; 831 } 832 cp = convbuf; 833 } 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; 864 865 flags &= ~GROUPING; 866 /* unsigned conversions */ 867 nosign: sign = '\0'; 868 /*- 869 * ``... diouXx conversions ... if a precision is 870 * specified, the 0 flag will be ignored.'' 871 * -- ANSI X3J11 872 */ 873 number: if ((dprec = prec) >= 0) 874 flags &= ~ZEROPAD; 875 876 /*- 877 * ``The result of converting a zero value with an 878 * explicit precision of zero is no characters.'' 879 * -- ANSI X3J11 880 * 881 * ``The C Standard is clear enough as is. The call 882 * printf("%#.0o", 0) should print 0.'' 883 * -- Defect Report #151 884 */ 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); 896 } 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; 912 } 913 914 /* 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. 924 * 925 * Compute actual size, so we know how much to pad. 926 * size excludes decimal prec; realsz includes it. 927 */ 928 realsz = dprec > size ? dprec : size; 929 if (sign) 930 realsz++; 931 if (ox[1]) 932 realsz += 2; 933 934 prsize = width > realsz ? width : realsz; 935 if ((unsigned)ret + prsize > INT_MAX) { 936 ret = EOF; 937 errno = EOVERFLOW; 938 goto error; 939 } 940 941 /* right-adjusting blank padding */ 942 if ((flags & (LADJUST|ZEROPAD)) == 0) 943 PAD(width - realsz, blanks); 944 945 /* prefix */ 946 if (sign) 947 PRINT(&sign, 1); 948 949 if (ox[1]) { /* ox[1] is either x, X, or \0 */ 950 ox[0] = '0'; 951 PRINT(ox, 2); 952 } 953 954 /* right-adjusting zero padding */ 955 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 956 PAD(width - realsz, zeroes); 957 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); 969 } 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; 991 } 992 if (prec || flags & ALT) 993 PRINT(decimal_point,decpt_len); 994 } 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); 1005 } 1006 } 1007 #endif 1008 /* left-adjusting padding (always blank) */ 1009 if (flags & LADJUST) 1010 PAD(width - realsz, blanks); 1011 1012 /* finally, adjust ret */ 1013 ret += prsize; 1014 1015 FLUSH(); /* copy out the I/O vectors */ 1016 } 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 */ 1033 } 1034 1035