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 __sprint(FILE *, struct __suio *); 70 static int __sbprintf(FILE *, const wchar_t *, va_list) __noinline; 71 static wint_t __xfputwc(wchar_t, FILE *); 72 static wchar_t *__mbsconv(char *, int); 73 74 #define CHAR wchar_t 75 #include "printfcommon.h" 76 77 struct grouping_state { 78 wchar_t thousands_sep; /* locale-specific thousands separator */ 79 const char *grouping; /* locale-specific numeric grouping rules */ 80 int lead; /* sig figs before decimal or group sep */ 81 int nseps; /* number of group separators with ' */ 82 int nrepeats; /* number of repeats of the last group */ 83 }; 84 85 static const mbstate_t initial_mbs; 86 87 static inline wchar_t 88 get_decpt(void) 89 { 90 mbstate_t mbs; 91 wchar_t decpt; 92 int nconv; 93 94 mbs = initial_mbs; 95 nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); 96 if (nconv == (size_t)-1 || nconv == (size_t)-2) 97 decpt = '.'; /* failsafe */ 98 return (decpt); 99 } 100 101 static inline wchar_t 102 get_thousep(void) 103 { 104 mbstate_t mbs; 105 wchar_t thousep; 106 int nconv; 107 108 mbs = initial_mbs; 109 nconv = mbrtowc(&thousep, localeconv()->thousands_sep, 110 MB_CUR_MAX, &mbs); 111 if (nconv == (size_t)-1 || nconv == (size_t)-2) 112 thousep = '\0'; /* failsafe */ 113 return (thousep); 114 } 115 116 /* 117 * Initialize the thousands' grouping state in preparation to print a 118 * number with ndigits digits. This routine returns the total number 119 * of wide characters that will be printed. 120 */ 121 static int 122 grouping_init(struct grouping_state *gs, int ndigits) 123 { 124 125 gs->grouping = localeconv()->grouping; 126 gs->thousands_sep = get_thousep(); 127 128 gs->nseps = gs->nrepeats = 0; 129 gs->lead = ndigits; 130 while (*gs->grouping != CHAR_MAX) { 131 if (gs->lead <= *gs->grouping) 132 break; 133 gs->lead -= *gs->grouping; 134 if (*(gs->grouping+1)) { 135 gs->nseps++; 136 gs->grouping++; 137 } else 138 gs->nrepeats++; 139 } 140 return (gs->nseps + gs->nrepeats); 141 } 142 143 /* 144 * Print a number with thousands' separators. 145 */ 146 static int 147 grouping_print(struct grouping_state *gs, struct io_state *iop, 148 const CHAR *cp, const CHAR *ep) 149 { 150 const CHAR *cp0 = cp; 151 152 if (io_printandpad(iop, cp, ep, gs->lead, zeroes)) 153 return (-1); 154 cp += gs->lead; 155 while (gs->nseps > 0 || gs->nrepeats > 0) { 156 if (gs->nrepeats > 0) 157 gs->nrepeats--; 158 else { 159 gs->grouping--; 160 gs->nseps--; 161 } 162 if (io_print(iop, &gs->thousands_sep, 1)) 163 return (-1); 164 if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes)) 165 return (-1); 166 cp += *gs->grouping; 167 } 168 if (cp > ep) 169 cp = ep; 170 return (cp - cp0); 171 } 172 173 174 /* 175 * Flush out all the vectors defined by the given uio, 176 * then reset it so that it can be reused. 177 * 178 * XXX The fact that we do this a character at a time and convert to a 179 * multibyte character sequence even if the destination is a wide 180 * string eclipses the benefits of buffering. 181 */ 182 static int 183 __sprint(FILE *fp, struct __suio *uio) 184 { 185 struct __siov *iov; 186 wchar_t *p; 187 int i, len; 188 189 iov = uio->uio_iov; 190 for (; uio->uio_resid != 0; uio->uio_resid -= len, iov++) { 191 p = (wchar_t *)iov->iov_base; 192 len = iov->iov_len; 193 for (i = 0; i < len; i++) { 194 if (__xfputwc(p[i], fp) == WEOF) 195 return (-1); 196 } 197 } 198 uio->uio_iovcnt = 0; 199 return (0); 200 } 201 202 /* 203 * Helper function for `fprintf to unbuffered unix file': creates a 204 * temporary buffer. We only work on write-only files; this avoids 205 * worries about ungetc buffers and so forth. 206 */ 207 static int 208 __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) 209 { 210 int ret; 211 FILE fake; 212 unsigned char buf[BUFSIZ]; 213 214 /* XXX This is probably not needed. */ 215 if (prepwrite(fp) != 0) 216 return (EOF); 217 218 /* copy the important variables */ 219 fake._flags = fp->_flags & ~__SNBF; 220 fake._file = fp->_file; 221 fake._cookie = fp->_cookie; 222 fake._write = fp->_write; 223 fake._orientation = fp->_orientation; 224 fake._mbstate = fp->_mbstate; 225 226 /* set up the buffer */ 227 fake._bf._base = fake._p = buf; 228 fake._bf._size = fake._w = sizeof(buf); 229 fake._lbfsize = 0; /* not actually used, but Just In Case */ 230 231 /* do the work, then copy any error status */ 232 ret = __vfwprintf(&fake, fmt, ap); 233 if (ret >= 0 && __fflush(&fake)) 234 ret = WEOF; 235 if (fake._flags & __SERR) 236 fp->_flags |= __SERR; 237 return (ret); 238 } 239 240 /* 241 * Like __fputwc, but handles fake string (__SSTR) files properly. 242 * File must already be locked. 243 */ 244 static wint_t 245 __xfputwc(wchar_t wc, FILE *fp) 246 { 247 mbstate_t mbs; 248 char buf[MB_LEN_MAX]; 249 struct __suio uio; 250 struct __siov iov; 251 size_t len; 252 253 if ((fp->_flags & __SSTR) == 0) 254 return (__fputwc(wc, fp)); 255 256 mbs = initial_mbs; 257 if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { 258 fp->_flags |= __SERR; 259 return (WEOF); 260 } 261 uio.uio_iov = &iov; 262 uio.uio_resid = len; 263 uio.uio_iovcnt = 1; 264 iov.iov_base = buf; 265 iov.iov_len = len; 266 return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF); 267 } 268 269 /* 270 * Convert a multibyte character string argument for the %s format to a wide 271 * string representation. ``prec'' specifies the maximum number of bytes 272 * to output. If ``prec'' is greater than or equal to zero, we can't assume 273 * that the multibyte char. string ends in a null character. 274 */ 275 static wchar_t * 276 __mbsconv(char *mbsarg, int prec) 277 { 278 mbstate_t mbs; 279 wchar_t *convbuf, *wcp; 280 const char *p; 281 size_t insize, nchars, nconv; 282 283 if (mbsarg == NULL) 284 return (NULL); 285 286 /* 287 * Supplied argument is a multibyte string; convert it to wide 288 * characters first. 289 */ 290 if (prec >= 0) { 291 /* 292 * String is not guaranteed to be NUL-terminated. Find the 293 * number of characters to print. 294 */ 295 p = mbsarg; 296 insize = nchars = 0; 297 mbs = initial_mbs; 298 while (nchars != (size_t)prec) { 299 nconv = mbrlen(p, MB_CUR_MAX, &mbs); 300 if (nconv == 0 || nconv == (size_t)-1 || 301 nconv == (size_t)-2) 302 break; 303 p += nconv; 304 nchars++; 305 insize += nconv; 306 } 307 if (nconv == (size_t)-1 || nconv == (size_t)-2) 308 return (NULL); 309 } else { 310 insize = strlen(mbsarg); 311 nconv = 0; 312 } 313 314 /* 315 * Allocate buffer for the result and perform the conversion, 316 * converting at most `size' bytes of the input multibyte string to 317 * wide characters for printing. 318 */ 319 convbuf = malloc((insize + 1) * sizeof(*convbuf)); 320 if (convbuf == NULL) 321 return (NULL); 322 wcp = convbuf; 323 p = mbsarg; 324 mbs = initial_mbs; 325 while (insize != 0) { 326 nconv = mbrtowc(wcp, p, insize, &mbs); 327 if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) 328 break; 329 wcp++; 330 p += nconv; 331 insize -= nconv; 332 } 333 if (nconv == (size_t)-1 || nconv == (size_t)-2) { 334 free(convbuf); 335 return (NULL); 336 } 337 *wcp = L'\0'; 338 339 return (convbuf); 340 } 341 342 /* 343 * MT-safe version 344 */ 345 int 346 vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) 347 348 { 349 int ret; 350 351 FLOCKFILE(fp); 352 /* optimise fprintf(stderr) (and other unbuffered Unix files) */ 353 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && 354 fp->_file >= 0) 355 ret = __sbprintf(fp, fmt0, ap); 356 else 357 ret = __vfwprintf(fp, fmt0, ap); 358 FUNLOCKFILE(fp); 359 return (ret); 360 } 361 362 /* 363 * The size of the buffer we use as scratch space for integer 364 * conversions, among other things. We need enough space to 365 * write a uintmax_t in octal (plus one byte). 366 */ 367 #if UINTMAX_MAX <= UINT64_MAX 368 #define BUF 32 369 #else 370 #error "BUF must be large enough to format a uintmax_t" 371 #endif 372 373 /* 374 * Non-MT-safe version 375 */ 376 int 377 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 378 { 379 wchar_t *fmt; /* format string */ 380 wchar_t ch; /* character from fmt */ 381 int n, n2; /* handy integer (short term usage) */ 382 wchar_t *cp; /* handy char pointer (short term usage) */ 383 int flags; /* flags as above */ 384 int ret; /* return value accumulator */ 385 int width; /* width from format (%8d), or 0 */ 386 int prec; /* precision from format; <0 for N/A */ 387 wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ 388 struct grouping_state gs; /* thousands' grouping info */ 389 #ifndef NO_FLOATING_POINT 390 /* 391 * We can decompose the printed representation of floating 392 * point numbers into several parts, some of which may be empty: 393 * 394 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ 395 * A B ---C--- D E F 396 * 397 * A: 'sign' holds this value if present; '\0' otherwise 398 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal 399 * C: cp points to the string MMMNNN. Leading and trailing 400 * zeros are not in the string and must be added. 401 * D: expchar holds this character; '\0' if no exponent, e.g. %f 402 * F: at least two digits for decimal, at least one digit for hex 403 */ 404 wchar_t decimal_point; /* locale specific decimal point */ 405 int signflag; /* true if float is negative */ 406 union { /* floating point arguments %[aAeEfFgG] */ 407 double dbl; 408 long double ldbl; 409 } fparg; 410 int expt; /* integer value of exponent */ 411 char expchar; /* exponent character: [eEpP\0] */ 412 char *dtoaend; /* pointer to end of converted digits */ 413 int expsize; /* character count for expstr */ 414 int ndig; /* actual number of digits returned by dtoa */ 415 wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ 416 char *dtoaresult; /* buffer allocated by dtoa */ 417 #endif 418 u_long ulval; /* integer arguments %[diouxX] */ 419 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 420 int base; /* base for [diouxX] conversion */ 421 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 422 int realsz; /* field size expanded by dprec, sign, etc */ 423 int size; /* size of converted field or string */ 424 int prsize; /* max size of printed field */ 425 const char *xdigs; /* digits for [xX] conversion */ 426 struct io_state io; /* I/O buffering state */ 427 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 428 wchar_t ox[2]; /* space for 0x hex-prefix */ 429 union arg *argtable; /* args, built due to positional arg */ 430 union arg statargtable [STATIC_ARG_TBL_SIZE]; 431 int nextarg; /* 1-based argument index */ 432 va_list orgap; /* original argument pointer */ 433 wchar_t *convbuf; /* multibyte to wide conversion result */ 434 435 static const char xdigs_lower[16] = "0123456789abcdef"; 436 static const char xdigs_upper[16] = "0123456789ABCDEF"; 437 438 /* BEWARE, these `goto error' on error. */ 439 #define PRINT(ptr, len) do { \ 440 if (io_print(&io, (ptr), (len))) \ 441 goto error; \ 442 } while (0) 443 #define PAD(howmany, with) { \ 444 if (io_pad(&io, (howmany), (with))) \ 445 goto error; \ 446 } 447 #define PRINTANDPAD(p, ep, len, with) { \ 448 if (io_printandpad(&io, (p), (ep), (len), (with))) \ 449 goto error; \ 450 } 451 #define FLUSH() { \ 452 if (io_flush(&io)) \ 453 goto error; \ 454 } 455 456 /* 457 * Get the argument indexed by nextarg. If the argument table is 458 * built, use it to get the argument. If its not, get the next 459 * argument (and arguments must be gotten sequentially). 460 */ 461 #define GETARG(type) \ 462 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ 463 (nextarg++, va_arg(ap, type))) 464 465 /* 466 * To extend shorts properly, we need both signed and unsigned 467 * argument extraction methods. 468 */ 469 #define SARG() \ 470 (flags&LONGINT ? GETARG(long) : \ 471 flags&SHORTINT ? (long)(short)GETARG(int) : \ 472 flags&CHARINT ? (long)(signed char)GETARG(int) : \ 473 (long)GETARG(int)) 474 #define UARG() \ 475 (flags&LONGINT ? GETARG(u_long) : \ 476 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ 477 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ 478 (u_long)GETARG(u_int)) 479 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) 480 #define SJARG() \ 481 (flags&INTMAXT ? GETARG(intmax_t) : \ 482 flags&SIZET ? (intmax_t)GETARG(size_t) : \ 483 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ 484 (intmax_t)GETARG(long long)) 485 #define UJARG() \ 486 (flags&INTMAXT ? GETARG(uintmax_t) : \ 487 flags&SIZET ? (uintmax_t)GETARG(size_t) : \ 488 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ 489 (uintmax_t)GETARG(unsigned long long)) 490 491 /* 492 * Get * arguments, including the form *nn$. Preserve the nextarg 493 * that the argument can be gotten once the type is determined. 494 */ 495 #define GETASTER(val) \ 496 n2 = 0; \ 497 cp = fmt; \ 498 while (is_digit(*cp)) { \ 499 n2 = 10 * n2 + to_digit(*cp); \ 500 cp++; \ 501 } \ 502 if (*cp == '$') { \ 503 int hold = nextarg; \ 504 if (argtable == NULL) { \ 505 argtable = statargtable; \ 506 if (__find_warguments (fmt0, orgap, &argtable)) { \ 507 ret = EOF; \ 508 goto error; \ 509 } \ 510 } \ 511 nextarg = n2; \ 512 val = GETARG (int); \ 513 nextarg = hold; \ 514 fmt = ++cp; \ 515 } else { \ 516 val = GETARG (int); \ 517 } 518 519 520 /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ 521 if (prepwrite(fp) != 0) 522 return (EOF); 523 524 convbuf = NULL; 525 fmt = (wchar_t *)fmt0; 526 argtable = NULL; 527 nextarg = 1; 528 va_copy(orgap, ap); 529 io_init(&io, fp); 530 ret = 0; 531 #ifndef NO_FLOATING_POINT 532 decimal_point = get_decpt(); 533 #endif 534 535 /* 536 * Scan the format for conversions (`%' character). 537 */ 538 for (;;) { 539 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) 540 /* void */; 541 if ((n = fmt - cp) != 0) { 542 if ((unsigned)ret + n > INT_MAX) { 543 ret = EOF; 544 goto error; 545 } 546 PRINT(cp, n); 547 ret += n; 548 } 549 if (ch == '\0') 550 goto done; 551 fmt++; /* skip over '%' */ 552 553 flags = 0; 554 dprec = 0; 555 width = 0; 556 prec = -1; 557 gs.grouping = NULL; 558 sign = '\0'; 559 ox[1] = '\0'; 560 561 rflag: ch = *fmt++; 562 reswitch: switch (ch) { 563 case ' ': 564 /*- 565 * ``If the space and + flags both appear, the space 566 * flag will be ignored.'' 567 * -- ANSI X3J11 568 */ 569 if (!sign) 570 sign = ' '; 571 goto rflag; 572 case '#': 573 flags |= ALT; 574 goto rflag; 575 case '*': 576 /*- 577 * ``A negative field width argument is taken as a 578 * - flag followed by a positive field width.'' 579 * -- ANSI X3J11 580 * They don't exclude field widths read from args. 581 */ 582 GETASTER (width); 583 if (width >= 0) 584 goto rflag; 585 width = -width; 586 /* FALLTHROUGH */ 587 case '-': 588 flags |= LADJUST; 589 goto rflag; 590 case '+': 591 sign = '+'; 592 goto rflag; 593 case '\'': 594 flags |= GROUPING; 595 goto rflag; 596 case '.': 597 if ((ch = *fmt++) == '*') { 598 GETASTER (prec); 599 goto rflag; 600 } 601 prec = 0; 602 while (is_digit(ch)) { 603 prec = 10 * prec + to_digit(ch); 604 ch = *fmt++; 605 } 606 goto reswitch; 607 case '0': 608 /*- 609 * ``Note that 0 is taken as a flag, not as the 610 * beginning of a field width.'' 611 * -- ANSI X3J11 612 */ 613 flags |= ZEROPAD; 614 goto rflag; 615 case '1': case '2': case '3': case '4': 616 case '5': case '6': case '7': case '8': case '9': 617 n = 0; 618 do { 619 n = 10 * n + to_digit(ch); 620 ch = *fmt++; 621 } while (is_digit(ch)); 622 if (ch == '$') { 623 nextarg = n; 624 if (argtable == NULL) { 625 argtable = statargtable; 626 if (__find_warguments (fmt0, orgap, 627 &argtable)) { 628 ret = EOF; 629 goto error; 630 } 631 } 632 goto rflag; 633 } 634 width = n; 635 goto reswitch; 636 #ifndef NO_FLOATING_POINT 637 case 'L': 638 flags |= LONGDBL; 639 goto rflag; 640 #endif 641 case 'h': 642 if (flags & SHORTINT) { 643 flags &= ~SHORTINT; 644 flags |= CHARINT; 645 } else 646 flags |= SHORTINT; 647 goto rflag; 648 case 'j': 649 flags |= INTMAXT; 650 goto rflag; 651 case 'l': 652 if (flags & LONGINT) { 653 flags &= ~LONGINT; 654 flags |= LLONGINT; 655 } else 656 flags |= LONGINT; 657 goto rflag; 658 case 'q': 659 flags |= LLONGINT; /* not necessarily */ 660 goto rflag; 661 case 't': 662 flags |= PTRDIFFT; 663 goto rflag; 664 case 'z': 665 flags |= SIZET; 666 goto rflag; 667 case 'C': 668 flags |= LONGINT; 669 /*FALLTHROUGH*/ 670 case 'c': 671 if (flags & LONGINT) 672 *(cp = buf) = (wchar_t)GETARG(wint_t); 673 else 674 *(cp = buf) = (wchar_t)btowc(GETARG(int)); 675 size = 1; 676 sign = '\0'; 677 break; 678 case 'D': 679 flags |= LONGINT; 680 /*FALLTHROUGH*/ 681 case 'd': 682 case 'i': 683 if (flags & INTMAX_SIZE) { 684 ujval = SJARG(); 685 if ((intmax_t)ujval < 0) { 686 ujval = -ujval; 687 sign = '-'; 688 } 689 } else { 690 ulval = SARG(); 691 if ((long)ulval < 0) { 692 ulval = -ulval; 693 sign = '-'; 694 } 695 } 696 base = 10; 697 goto number; 698 #ifndef NO_FLOATING_POINT 699 case 'a': 700 case 'A': 701 if (ch == 'a') { 702 ox[1] = 'x'; 703 xdigs = xdigs_lower; 704 expchar = 'p'; 705 } else { 706 ox[1] = 'X'; 707 xdigs = xdigs_upper; 708 expchar = 'P'; 709 } 710 if (prec >= 0) 711 prec++; 712 if (flags & LONGDBL) { 713 fparg.ldbl = GETARG(long double); 714 dtoaresult = 715 __hldtoa(fparg.ldbl, xdigs, prec, 716 &expt, &signflag, &dtoaend); 717 } else { 718 fparg.dbl = GETARG(double); 719 dtoaresult = 720 __hdtoa(fparg.dbl, xdigs, prec, 721 &expt, &signflag, &dtoaend); 722 } 723 if (prec < 0) 724 prec = dtoaend - dtoaresult; 725 if (expt == INT_MAX) 726 ox[1] = '\0'; 727 if (convbuf != NULL) 728 free(convbuf); 729 ndig = dtoaend - dtoaresult; 730 cp = convbuf = __mbsconv(dtoaresult, -1); 731 freedtoa(dtoaresult); 732 goto fp_common; 733 case 'e': 734 case 'E': 735 expchar = ch; 736 if (prec < 0) /* account for digit before decpt */ 737 prec = DEFPREC + 1; 738 else 739 prec++; 740 goto fp_begin; 741 case 'f': 742 case 'F': 743 expchar = '\0'; 744 goto fp_begin; 745 case 'g': 746 case 'G': 747 expchar = ch - ('g' - 'e'); 748 if (prec == 0) 749 prec = 1; 750 fp_begin: 751 if (prec < 0) 752 prec = DEFPREC; 753 if (convbuf != NULL) 754 free(convbuf); 755 if (flags & LONGDBL) { 756 fparg.ldbl = GETARG(long double); 757 dtoaresult = 758 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, 759 &expt, &signflag, &dtoaend); 760 } else { 761 fparg.dbl = GETARG(double); 762 dtoaresult = 763 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 764 &expt, &signflag, &dtoaend); 765 if (expt == 9999) 766 expt = INT_MAX; 767 } 768 ndig = dtoaend - dtoaresult; 769 cp = convbuf = __mbsconv(dtoaresult, -1); 770 freedtoa(dtoaresult); 771 fp_common: 772 if (signflag) 773 sign = '-'; 774 if (expt == INT_MAX) { /* inf or nan */ 775 if (*cp == 'N') { 776 cp = (ch >= 'a') ? L"nan" : L"NAN"; 777 sign = '\0'; 778 } else 779 cp = (ch >= 'a') ? L"inf" : L"INF"; 780 size = 3; 781 flags &= ~ZEROPAD; 782 break; 783 } 784 flags |= FPT; 785 if (ch == 'g' || ch == 'G') { 786 if (expt > -4 && expt <= prec) { 787 /* Make %[gG] smell like %[fF] */ 788 expchar = '\0'; 789 if (flags & ALT) 790 prec -= expt; 791 else 792 prec = ndig - expt; 793 if (prec < 0) 794 prec = 0; 795 } else { 796 /* 797 * Make %[gG] smell like %[eE], but 798 * trim trailing zeroes if no # flag. 799 */ 800 if (!(flags & ALT)) 801 prec = ndig; 802 } 803 } 804 if (expchar) { 805 expsize = exponent(expstr, expt - 1, expchar); 806 size = expsize + prec; 807 if (prec > 1 || flags & ALT) 808 ++size; 809 } else { 810 /* space for digits before decimal point */ 811 if (expt > 0) 812 size = expt; 813 else /* "0" */ 814 size = 1; 815 /* space for decimal pt and following digits */ 816 if (prec || flags & ALT) 817 size += prec + 1; 818 if ((flags & GROUPING) && expt > 0) 819 size += grouping_init(&gs, expt); 820 } 821 break; 822 #endif /* !NO_FLOATING_POINT */ 823 case 'n': 824 /* 825 * Assignment-like behavior is specified if the 826 * value overflows or is otherwise unrepresentable. 827 * C99 says to use `signed char' for %hhn conversions. 828 */ 829 if (flags & LLONGINT) 830 *GETARG(long long *) = ret; 831 else if (flags & SIZET) 832 *GETARG(ssize_t *) = (ssize_t)ret; 833 else if (flags & PTRDIFFT) 834 *GETARG(ptrdiff_t *) = ret; 835 else if (flags & INTMAXT) 836 *GETARG(intmax_t *) = ret; 837 else if (flags & LONGINT) 838 *GETARG(long *) = ret; 839 else if (flags & SHORTINT) 840 *GETARG(short *) = ret; 841 else if (flags & CHARINT) 842 *GETARG(signed char *) = ret; 843 else 844 *GETARG(int *) = ret; 845 continue; /* no output */ 846 case 'O': 847 flags |= LONGINT; 848 /*FALLTHROUGH*/ 849 case 'o': 850 if (flags & INTMAX_SIZE) 851 ujval = UJARG(); 852 else 853 ulval = UARG(); 854 base = 8; 855 goto nosign; 856 case 'p': 857 /*- 858 * ``The argument shall be a pointer to void. The 859 * value of the pointer is converted to a sequence 860 * of printable characters, in an implementation- 861 * defined manner.'' 862 * -- ANSI X3J11 863 */ 864 ujval = (uintmax_t)(uintptr_t)GETARG(void *); 865 base = 16; 866 xdigs = xdigs_lower; 867 flags = flags | INTMAXT; 868 ox[1] = 'x'; 869 goto nosign; 870 case 'S': 871 flags |= LONGINT; 872 /*FALLTHROUGH*/ 873 case 's': 874 if (flags & LONGINT) { 875 if ((cp = GETARG(wchar_t *)) == NULL) 876 cp = L"(null)"; 877 } else { 878 char *mbp; 879 880 if (convbuf != NULL) 881 free(convbuf); 882 if ((mbp = GETARG(char *)) == NULL) 883 cp = L"(null)"; 884 else { 885 convbuf = __mbsconv(mbp, prec); 886 if (convbuf == NULL) { 887 fp->_flags |= __SERR; 888 goto error; 889 } 890 cp = convbuf; 891 } 892 } 893 894 if (prec >= 0) { 895 /* 896 * can't use wcslen; can only look for the 897 * NUL in the first `prec' characters, and 898 * wcslen() will go further. 899 */ 900 wchar_t *p = wmemchr(cp, 0, (size_t)prec); 901 902 if (p != NULL) { 903 size = p - cp; 904 if (size > prec) 905 size = prec; 906 } else 907 size = prec; 908 } else 909 size = wcslen(cp); 910 sign = '\0'; 911 break; 912 case 'U': 913 flags |= LONGINT; 914 /*FALLTHROUGH*/ 915 case 'u': 916 if (flags & INTMAX_SIZE) 917 ujval = UJARG(); 918 else 919 ulval = UARG(); 920 base = 10; 921 goto nosign; 922 case 'X': 923 xdigs = xdigs_upper; 924 goto hex; 925 case 'x': 926 xdigs = xdigs_lower; 927 hex: 928 if (flags & INTMAX_SIZE) 929 ujval = UJARG(); 930 else 931 ulval = UARG(); 932 base = 16; 933 /* leading 0x/X only if non-zero */ 934 if (flags & ALT && 935 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) 936 ox[1] = ch; 937 938 flags &= ~GROUPING; 939 /* unsigned conversions */ 940 nosign: sign = '\0'; 941 /*- 942 * ``... diouXx conversions ... if a precision is 943 * specified, the 0 flag will be ignored.'' 944 * -- ANSI X3J11 945 */ 946 number: if ((dprec = prec) >= 0) 947 flags &= ~ZEROPAD; 948 949 /*- 950 * ``The result of converting a zero value with an 951 * explicit precision of zero is no characters.'' 952 * -- ANSI X3J11 953 * 954 * ``The C Standard is clear enough as is. The call 955 * printf("%#.0o", 0) should print 0.'' 956 * -- Defect Report #151 957 */ 958 cp = buf + BUF; 959 if (flags & INTMAX_SIZE) { 960 if (ujval != 0 || prec != 0 || 961 (flags & ALT && base == 8)) 962 cp = __ujtoa(ujval, cp, base, 963 flags & ALT, xdigs); 964 } else { 965 if (ulval != 0 || prec != 0 || 966 (flags & ALT && base == 8)) 967 cp = __ultoa(ulval, cp, base, 968 flags & ALT, xdigs); 969 } 970 size = buf + BUF - cp; 971 if (size > BUF) /* should never happen */ 972 abort(); 973 if ((flags & GROUPING) && size != 0) 974 size += grouping_init(&gs, size); 975 break; 976 default: /* "%?" prints ?, unless ? is NUL */ 977 if (ch == '\0') 978 goto done; 979 /* pretend it was %c with argument ch */ 980 cp = buf; 981 *cp = ch; 982 size = 1; 983 sign = '\0'; 984 break; 985 } 986 987 /* 988 * All reasonable formats wind up here. At this point, `cp' 989 * points to a string which (if not flags&LADJUST) should be 990 * padded out to `width' places. If flags&ZEROPAD, it should 991 * first be prefixed by any sign or other prefix; otherwise, 992 * it should be blank padded before the prefix is emitted. 993 * After any left-hand padding and prefixing, emit zeroes 994 * required by a decimal [diouxX] precision, then print the 995 * string proper, then emit zeroes required by any leftover 996 * floating precision; finally, if LADJUST, pad with blanks. 997 * 998 * Compute actual size, so we know how much to pad. 999 * size excludes decimal prec; realsz includes it. 1000 */ 1001 realsz = dprec > size ? dprec : size; 1002 if (sign) 1003 realsz++; 1004 if (ox[1]) 1005 realsz += 2; 1006 1007 prsize = width > realsz ? width : realsz; 1008 if ((unsigned)ret + prsize > INT_MAX) { 1009 ret = EOF; 1010 goto error; 1011 } 1012 1013 /* right-adjusting blank padding */ 1014 if ((flags & (LADJUST|ZEROPAD)) == 0) 1015 PAD(width - realsz, blanks); 1016 1017 /* prefix */ 1018 if (sign) 1019 PRINT(&sign, 1); 1020 1021 if (ox[1]) { /* ox[1] is either x, X, or \0 */ 1022 ox[0] = '0'; 1023 PRINT(ox, 2); 1024 } 1025 1026 /* right-adjusting zero padding */ 1027 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1028 PAD(width - realsz, zeroes); 1029 1030 /* the string or number proper */ 1031 #ifndef NO_FLOATING_POINT 1032 if ((flags & FPT) == 0) { 1033 #endif 1034 /* leading zeroes from decimal precision */ 1035 PAD(dprec - size, zeroes); 1036 if (gs.grouping) { 1037 if (grouping_print(&gs, &io, cp, buf+BUF) < 0) 1038 goto error; 1039 } else { 1040 PRINT(cp, size); 1041 } 1042 #ifndef NO_FLOATING_POINT 1043 } else { /* glue together f_p fragments */ 1044 if (!expchar) { /* %[fF] or sufficiently short %[gG] */ 1045 if (expt <= 0) { 1046 PRINT(zeroes, 1); 1047 if (prec || flags & ALT) 1048 PRINT(&decimal_point, 1); 1049 PAD(-expt, zeroes); 1050 /* already handled initial 0's */ 1051 prec += expt; 1052 } else { 1053 if (gs.grouping) { 1054 n = grouping_print(&gs, &io, 1055 cp, convbuf + ndig); 1056 if (n < 0) 1057 goto error; 1058 cp += n; 1059 } else { 1060 PRINTANDPAD(cp, convbuf + ndig, 1061 expt, zeroes); 1062 cp += expt; 1063 } 1064 if (prec || flags & ALT) 1065 PRINT(&decimal_point, 1); 1066 } 1067 PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); 1068 } else { /* %[eE] or sufficiently long %[gG] */ 1069 if (prec > 1 || flags & ALT) { 1070 buf[0] = *cp++; 1071 buf[1] = decimal_point; 1072 PRINT(buf, 2); 1073 PRINT(cp, ndig-1); 1074 PAD(prec - ndig, zeroes); 1075 } else /* XeYYY */ 1076 PRINT(cp, 1); 1077 PRINT(expstr, expsize); 1078 } 1079 } 1080 #endif 1081 /* left-adjusting padding (always blank) */ 1082 if (flags & LADJUST) 1083 PAD(width - realsz, blanks); 1084 1085 /* finally, adjust ret */ 1086 ret += prsize; 1087 1088 FLUSH(); /* copy out the I/O vectors */ 1089 } 1090 done: 1091 FLUSH(); 1092 error: 1093 va_end(orgap); 1094 if (convbuf != NULL) 1095 free(convbuf); 1096 if (__sferror(fp)) 1097 ret = EOF; 1098 if ((argtable != NULL) && (argtable != statargtable)) 1099 free (argtable); 1100 return (ret); 1101 /* NOTREACHED */ 1102 } 1103