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 339 /* 340 * Allocate buffer for the result and perform the conversion, 341 * converting at most `size' bytes of the input multibyte string to 342 * wide characters for printing. 343 */ 344 convbuf = malloc((insize + 1) * sizeof(*convbuf)); 345 if (convbuf == NULL) 346 return (NULL); 347 wcp = convbuf; 348 p = mbsarg; 349 mbs = initial; 350 while (insize != 0) { 351 nconv = mbrtowc(wcp, p, insize, &mbs); 352 if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) 353 break; 354 wcp++; 355 p += nconv; 356 insize -= nconv; 357 } 358 if (nconv == (size_t)-1 || nconv == (size_t)-2) { 359 free(convbuf); 360 return (NULL); 361 } 362 *wcp = L'\0'; 363 364 return (convbuf); 365 } 366 367 /* 368 * MT-safe version 369 */ 370 int 371 vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) 372 373 { 374 int ret; 375 376 FLOCKFILE(fp); 377 ret = __vfwprintf(fp, fmt0, ap); 378 FUNLOCKFILE(fp); 379 return (ret); 380 } 381 382 #ifndef NO_FLOATING_POINT 383 384 #define dtoa __dtoa 385 #define freedtoa __freedtoa 386 387 #include <float.h> 388 #include <math.h> 389 #include "floatio.h" 390 #include "gdtoa.h" 391 392 #define DEFPREC 6 393 394 static int exponent(wchar_t *, int, wchar_t); 395 396 #endif /* !NO_FLOATING_POINT */ 397 398 /* 399 * The size of the buffer we use as scratch space for integer 400 * conversions, among other things. Technically, we would need the 401 * most space for base 10 conversions with thousands' grouping 402 * characters between each pair of digits. 100 bytes is a 403 * conservative overestimate even for a 128-bit uintmax_t. 404 */ 405 #define BUF 100 406 407 /* 408 * Non-MT-safe version 409 */ 410 int 411 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 412 { 413 wchar_t *fmt; /* format string */ 414 wchar_t ch; /* character from fmt */ 415 int n, n2, n3; /* handy integer (short term usage) */ 416 wchar_t *cp; /* handy char pointer (short term usage) */ 417 int flags; /* flags as above */ 418 int ret; /* return value accumulator */ 419 int width; /* width from format (%8d), or 0 */ 420 int prec; /* precision from format; <0 for N/A */ 421 wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ 422 char thousands_sep; /* locale specific thousands separator */ 423 const char *grouping; /* locale specific numeric grouping rules */ 424 #ifndef NO_FLOATING_POINT 425 /* 426 * We can decompose the printed representation of floating 427 * point numbers into several parts, some of which may be empty: 428 * 429 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ 430 * A B ---C--- D E F 431 * 432 * A: 'sign' holds this value if present; '\0' otherwise 433 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal 434 * C: cp points to the string MMMNNN. Leading and trailing 435 * zeros are not in the string and must be added. 436 * D: expchar holds this character; '\0' if no exponent, e.g. %f 437 * F: at least two digits for decimal, at least one digit for hex 438 */ 439 char *decimal_point; /* locale specific decimal point */ 440 int signflag; /* true if float is negative */ 441 union { /* floating point arguments %[aAeEfFgG] */ 442 double dbl; 443 long double ldbl; 444 } fparg; 445 int expt; /* integer value of exponent */ 446 char expchar; /* exponent character: [eEpP\0] */ 447 char *dtoaend; /* pointer to end of converted digits */ 448 int expsize; /* character count for expstr */ 449 int lead; /* sig figs before decimal or group sep */ 450 int ndig; /* actual number of digits returned by dtoa */ 451 wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ 452 char *dtoaresult; /* buffer allocated by dtoa */ 453 int nseps; /* number of group separators with ' */ 454 int nrepeats; /* number of repeats of the last group */ 455 #endif 456 u_long ulval; /* integer arguments %[diouxX] */ 457 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 458 int base; /* base for [diouxX] conversion */ 459 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 460 int realsz; /* field size expanded by dprec, sign, etc */ 461 int size; /* size of converted field or string */ 462 int prsize; /* max size of printed field */ 463 const char *xdigs; /* digits for [xX] conversion */ 464 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 465 wchar_t ox[2]; /* space for 0x hex-prefix */ 466 union arg *argtable; /* args, built due to positional arg */ 467 union arg statargtable [STATIC_ARG_TBL_SIZE]; 468 int nextarg; /* 1-based argument index */ 469 va_list orgap; /* original argument pointer */ 470 wchar_t *convbuf; /* multibyte to wide conversion result */ 471 472 /* 473 * Choose PADSIZE to trade efficiency vs. size. If larger printf 474 * fields occur frequently, increase PADSIZE and make the initialisers 475 * below longer. 476 */ 477 #define PADSIZE 16 /* pad chunk size */ 478 static wchar_t blanks[PADSIZE] = 479 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 480 static wchar_t zeroes[PADSIZE] = 481 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 482 483 static const char xdigs_lower[16] = "0123456789abcdef"; 484 static const char xdigs_upper[16] = "0123456789ABCDEF"; 485 486 /* 487 * BEWARE, these `goto error' on error, PRINT uses `n2' and 488 * PAD uses `n'. 489 */ 490 #define PRINT(ptr, len) do { \ 491 for (n3 = 0; n3 < (len); n3++) \ 492 __xfputwc((ptr)[n3], fp); \ 493 } while (0) 494 #define PAD(howmany, with) do { \ 495 if ((n = (howmany)) > 0) { \ 496 while (n > PADSIZE) { \ 497 PRINT(with, PADSIZE); \ 498 n -= PADSIZE; \ 499 } \ 500 PRINT(with, n); \ 501 } \ 502 } while (0) 503 #define PRINTANDPAD(p, ep, len, with) do { \ 504 n2 = (ep) - (p); \ 505 if (n2 > (len)) \ 506 n2 = (len); \ 507 if (n2 > 0) \ 508 PRINT((p), n2); \ 509 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ 510 } while(0) 511 512 /* 513 * Get the argument indexed by nextarg. If the argument table is 514 * built, use it to get the argument. If its not, get the next 515 * argument (and arguments must be gotten sequentially). 516 */ 517 #define GETARG(type) \ 518 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ 519 (nextarg++, va_arg(ap, type))) 520 521 /* 522 * To extend shorts properly, we need both signed and unsigned 523 * argument extraction methods. 524 */ 525 #define SARG() \ 526 (flags&LONGINT ? GETARG(long) : \ 527 flags&SHORTINT ? (long)(short)GETARG(int) : \ 528 flags&CHARINT ? (long)(signed char)GETARG(int) : \ 529 (long)GETARG(int)) 530 #define UARG() \ 531 (flags&LONGINT ? GETARG(u_long) : \ 532 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ 533 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ 534 (u_long)GETARG(u_int)) 535 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) 536 #define SJARG() \ 537 (flags&INTMAXT ? GETARG(intmax_t) : \ 538 flags&SIZET ? (intmax_t)GETARG(size_t) : \ 539 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ 540 (intmax_t)GETARG(long long)) 541 #define UJARG() \ 542 (flags&INTMAXT ? GETARG(uintmax_t) : \ 543 flags&SIZET ? (uintmax_t)GETARG(size_t) : \ 544 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ 545 (uintmax_t)GETARG(unsigned long long)) 546 547 /* 548 * Get * arguments, including the form *nn$. Preserve the nextarg 549 * that the argument can be gotten once the type is determined. 550 */ 551 #define GETASTER(val) \ 552 n2 = 0; \ 553 cp = fmt; \ 554 while (is_digit(*cp)) { \ 555 n2 = 10 * n2 + to_digit(*cp); \ 556 cp++; \ 557 } \ 558 if (*cp == '$') { \ 559 int hold = nextarg; \ 560 if (argtable == NULL) { \ 561 argtable = statargtable; \ 562 if (__find_warguments (fmt0, orgap, &argtable)) { \ 563 ret = EOF; \ 564 goto error; \ 565 } \ 566 } \ 567 nextarg = n2; \ 568 val = GETARG (int); \ 569 nextarg = hold; \ 570 fmt = ++cp; \ 571 } else { \ 572 val = GETARG (int); \ 573 } 574 575 576 thousands_sep = '\0'; 577 grouping = NULL; 578 #ifndef NO_FLOATING_POINT 579 decimal_point = localeconv()->decimal_point; 580 #endif 581 convbuf = NULL; 582 /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ 583 if (prepwrite(fp) != 0) 584 return (EOF); 585 586 /* optimise fprintf(stderr) (and other unbuffered Unix files) */ 587 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && 588 fp->_file >= 0) 589 return (__sbprintf(fp, fmt0, ap)); 590 591 fmt = (wchar_t *)fmt0; 592 argtable = NULL; 593 nextarg = 1; 594 va_copy(orgap, ap); 595 ret = 0; 596 597 /* 598 * Scan the format for conversions (`%' character). 599 */ 600 for (;;) { 601 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) 602 /* void */; 603 if ((n = fmt - cp) != 0) { 604 if ((unsigned)ret + n > INT_MAX) { 605 ret = EOF; 606 goto error; 607 } 608 PRINT(cp, n); 609 ret += n; 610 } 611 if (ch == '\0') 612 goto done; 613 fmt++; /* skip over '%' */ 614 615 flags = 0; 616 dprec = 0; 617 width = 0; 618 prec = -1; 619 sign = '\0'; 620 ox[1] = '\0'; 621 622 rflag: ch = *fmt++; 623 reswitch: switch (ch) { 624 case ' ': 625 /*- 626 * ``If the space and + flags both appear, the space 627 * flag will be ignored.'' 628 * -- ANSI X3J11 629 */ 630 if (!sign) 631 sign = ' '; 632 goto rflag; 633 case '#': 634 flags |= ALT; 635 goto rflag; 636 case '*': 637 /*- 638 * ``A negative field width argument is taken as a 639 * - flag followed by a positive field width.'' 640 * -- ANSI X3J11 641 * They don't exclude field widths read from args. 642 */ 643 GETASTER (width); 644 if (width >= 0) 645 goto rflag; 646 width = -width; 647 /* FALLTHROUGH */ 648 case '-': 649 flags |= LADJUST; 650 goto rflag; 651 case '+': 652 sign = '+'; 653 goto rflag; 654 case '\'': 655 flags |= GROUPING; 656 thousands_sep = *(localeconv()->thousands_sep); 657 grouping = localeconv()->grouping; 658 goto rflag; 659 case '.': 660 if ((ch = *fmt++) == '*') { 661 GETASTER (prec); 662 goto rflag; 663 } 664 prec = 0; 665 while (is_digit(ch)) { 666 prec = 10 * prec + to_digit(ch); 667 ch = *fmt++; 668 } 669 goto reswitch; 670 case '0': 671 /*- 672 * ``Note that 0 is taken as a flag, not as the 673 * beginning of a field width.'' 674 * -- ANSI X3J11 675 */ 676 flags |= ZEROPAD; 677 goto rflag; 678 case '1': case '2': case '3': case '4': 679 case '5': case '6': case '7': case '8': case '9': 680 n = 0; 681 do { 682 n = 10 * n + to_digit(ch); 683 ch = *fmt++; 684 } while (is_digit(ch)); 685 if (ch == '$') { 686 nextarg = n; 687 if (argtable == NULL) { 688 argtable = statargtable; 689 if (__find_warguments (fmt0, orgap, 690 &argtable)) { 691 ret = EOF; 692 goto error; 693 } 694 } 695 goto rflag; 696 } 697 width = n; 698 goto reswitch; 699 #ifndef NO_FLOATING_POINT 700 case 'L': 701 flags |= LONGDBL; 702 goto rflag; 703 #endif 704 case 'h': 705 if (flags & SHORTINT) { 706 flags &= ~SHORTINT; 707 flags |= CHARINT; 708 } else 709 flags |= SHORTINT; 710 goto rflag; 711 case 'j': 712 flags |= INTMAXT; 713 goto rflag; 714 case 'l': 715 if (flags & LONGINT) { 716 flags &= ~LONGINT; 717 flags |= LLONGINT; 718 } else 719 flags |= LONGINT; 720 goto rflag; 721 case 'q': 722 flags |= LLONGINT; /* not necessarily */ 723 goto rflag; 724 case 't': 725 flags |= PTRDIFFT; 726 goto rflag; 727 case 'z': 728 flags |= SIZET; 729 goto rflag; 730 case 'C': 731 flags |= LONGINT; 732 /*FALLTHROUGH*/ 733 case 'c': 734 if (flags & LONGINT) 735 *(cp = buf) = (wchar_t)GETARG(wint_t); 736 else 737 *(cp = buf) = (wchar_t)btowc(GETARG(int)); 738 size = 1; 739 sign = '\0'; 740 break; 741 case 'D': 742 flags |= LONGINT; 743 /*FALLTHROUGH*/ 744 case 'd': 745 case 'i': 746 if (flags & INTMAX_SIZE) { 747 ujval = SJARG(); 748 if ((intmax_t)ujval < 0) { 749 ujval = -ujval; 750 sign = '-'; 751 } 752 } else { 753 ulval = SARG(); 754 if ((long)ulval < 0) { 755 ulval = -ulval; 756 sign = '-'; 757 } 758 } 759 base = 10; 760 goto number; 761 #ifndef NO_FLOATING_POINT 762 case 'a': 763 case 'A': 764 if (ch == 'a') { 765 ox[1] = 'x'; 766 xdigs = xdigs_lower; 767 expchar = 'p'; 768 } else { 769 ox[1] = 'X'; 770 xdigs = xdigs_upper; 771 expchar = 'P'; 772 } 773 if (prec >= 0) 774 prec++; 775 if (flags & LONGDBL) { 776 fparg.ldbl = GETARG(long double); 777 dtoaresult = 778 __hldtoa(fparg.ldbl, xdigs, prec, 779 &expt, &signflag, &dtoaend); 780 } else { 781 fparg.dbl = GETARG(double); 782 dtoaresult = 783 __hdtoa(fparg.dbl, xdigs, prec, 784 &expt, &signflag, &dtoaend); 785 } 786 if (prec < 0) 787 prec = dtoaend - dtoaresult; 788 if (expt == INT_MAX) 789 ox[1] = '\0'; 790 if (convbuf != NULL) 791 free(convbuf); 792 ndig = dtoaend - dtoaresult; 793 cp = convbuf = __mbsconv(dtoaresult, -1); 794 freedtoa(dtoaresult); 795 goto fp_common; 796 case 'e': 797 case 'E': 798 expchar = ch; 799 if (prec < 0) /* account for digit before decpt */ 800 prec = DEFPREC + 1; 801 else 802 prec++; 803 goto fp_begin; 804 case 'f': 805 case 'F': 806 expchar = '\0'; 807 goto fp_begin; 808 case 'g': 809 case 'G': 810 expchar = ch - ('g' - 'e'); 811 if (prec == 0) 812 prec = 1; 813 fp_begin: 814 if (prec < 0) 815 prec = DEFPREC; 816 if (convbuf != NULL) 817 free(convbuf); 818 if (flags & LONGDBL) { 819 fparg.ldbl = GETARG(long double); 820 dtoaresult = 821 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, 822 &expt, &signflag, &dtoaend); 823 } else { 824 fparg.dbl = GETARG(double); 825 dtoaresult = 826 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 827 &expt, &signflag, &dtoaend); 828 if (expt == 9999) 829 expt = INT_MAX; 830 } 831 ndig = dtoaend - dtoaresult; 832 cp = convbuf = __mbsconv(dtoaresult, -1); 833 freedtoa(dtoaresult); 834 fp_common: 835 if (signflag) 836 sign = '-'; 837 if (expt == INT_MAX) { /* inf or nan */ 838 if (*cp == 'N') { 839 cp = (ch >= 'a') ? L"nan" : L"NAN"; 840 sign = '\0'; 841 } else 842 cp = (ch >= 'a') ? L"inf" : L"INF"; 843 size = 3; 844 flags &= ~ZEROPAD; 845 break; 846 } 847 flags |= FPT; 848 if (ch == 'g' || ch == 'G') { 849 if (expt > -4 && expt <= prec) { 850 /* Make %[gG] smell like %[fF] */ 851 expchar = '\0'; 852 if (flags & ALT) 853 prec -= expt; 854 else 855 prec = ndig - expt; 856 if (prec < 0) 857 prec = 0; 858 } else { 859 /* 860 * Make %[gG] smell like %[eE], but 861 * trim trailing zeroes if no # flag. 862 */ 863 if (!(flags & ALT)) 864 prec = ndig; 865 } 866 } 867 if (expchar) { 868 expsize = exponent(expstr, expt - 1, expchar); 869 size = expsize + prec; 870 if (prec > 1 || flags & ALT) 871 ++size; 872 } else { 873 /* space for digits before decimal point */ 874 if (expt > 0) 875 size = expt; 876 else /* "0" */ 877 size = 1; 878 /* space for decimal pt and following digits */ 879 if (prec || flags & ALT) 880 size += prec + 1; 881 if (grouping && expt > 0) { 882 /* space for thousands' grouping */ 883 nseps = nrepeats = 0; 884 lead = expt; 885 while (*grouping != CHAR_MAX) { 886 if (lead <= *grouping) 887 break; 888 lead -= *grouping; 889 if (*(grouping+1)) { 890 nseps++; 891 grouping++; 892 } else 893 nrepeats++; 894 } 895 size += nseps + nrepeats; 896 } else 897 lead = expt; 898 } 899 break; 900 #endif /* !NO_FLOATING_POINT */ 901 case 'n': 902 /* 903 * Assignment-like behavior is specified if the 904 * value overflows or is otherwise unrepresentable. 905 * C99 says to use `signed char' for %hhn conversions. 906 */ 907 if (flags & LLONGINT) 908 *GETARG(long long *) = ret; 909 else if (flags & SIZET) 910 *GETARG(ssize_t *) = (ssize_t)ret; 911 else if (flags & PTRDIFFT) 912 *GETARG(ptrdiff_t *) = ret; 913 else if (flags & INTMAXT) 914 *GETARG(intmax_t *) = ret; 915 else if (flags & LONGINT) 916 *GETARG(long *) = ret; 917 else if (flags & SHORTINT) 918 *GETARG(short *) = ret; 919 else if (flags & CHARINT) 920 *GETARG(signed char *) = ret; 921 else 922 *GETARG(int *) = ret; 923 continue; /* no output */ 924 case 'O': 925 flags |= LONGINT; 926 /*FALLTHROUGH*/ 927 case 'o': 928 if (flags & INTMAX_SIZE) 929 ujval = UJARG(); 930 else 931 ulval = UARG(); 932 base = 8; 933 goto nosign; 934 case 'p': 935 /*- 936 * ``The argument shall be a pointer to void. The 937 * value of the pointer is converted to a sequence 938 * of printable characters, in an implementation- 939 * defined manner.'' 940 * -- ANSI X3J11 941 */ 942 ujval = (uintmax_t)(uintptr_t)GETARG(void *); 943 base = 16; 944 xdigs = xdigs_lower; 945 flags = flags | INTMAXT; 946 ox[1] = 'x'; 947 goto nosign; 948 case 'S': 949 flags |= LONGINT; 950 /*FALLTHROUGH*/ 951 case 's': 952 if (flags & LONGINT) { 953 if ((cp = GETARG(wchar_t *)) == NULL) 954 cp = L"(null)"; 955 } else { 956 char *mbp; 957 958 if (convbuf != NULL) 959 free(convbuf); 960 if ((mbp = GETARG(char *)) == NULL) 961 cp = L"(null)"; 962 else { 963 convbuf = __mbsconv(mbp, prec); 964 if (convbuf == NULL) { 965 fp->_flags |= __SERR; 966 goto error; 967 } 968 cp = convbuf; 969 } 970 } 971 972 if (prec >= 0) { 973 /* 974 * can't use wcslen; can only look for the 975 * NUL in the first `prec' characters, and 976 * wcslen() will go further. 977 */ 978 wchar_t *p = wmemchr(cp, 0, (size_t)prec); 979 980 if (p != NULL) { 981 size = p - cp; 982 if (size > prec) 983 size = prec; 984 } else 985 size = prec; 986 } else 987 size = wcslen(cp); 988 sign = '\0'; 989 break; 990 case 'U': 991 flags |= LONGINT; 992 /*FALLTHROUGH*/ 993 case 'u': 994 if (flags & INTMAX_SIZE) 995 ujval = UJARG(); 996 else 997 ulval = UARG(); 998 base = 10; 999 goto nosign; 1000 case 'X': 1001 xdigs = xdigs_upper; 1002 goto hex; 1003 case 'x': 1004 xdigs = xdigs_lower; 1005 hex: 1006 if (flags & INTMAX_SIZE) 1007 ujval = UJARG(); 1008 else 1009 ulval = UARG(); 1010 base = 16; 1011 /* leading 0x/X only if non-zero */ 1012 if (flags & ALT && 1013 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) 1014 ox[1] = ch; 1015 1016 flags &= ~GROUPING; 1017 /* unsigned conversions */ 1018 nosign: sign = '\0'; 1019 /*- 1020 * ``... diouXx conversions ... if a precision is 1021 * specified, the 0 flag will be ignored.'' 1022 * -- ANSI X3J11 1023 */ 1024 number: if ((dprec = prec) >= 0) 1025 flags &= ~ZEROPAD; 1026 1027 /*- 1028 * ``The result of converting a zero value with an 1029 * explicit precision of zero is no characters.'' 1030 * -- ANSI X3J11 1031 * 1032 * ``The C Standard is clear enough as is. The call 1033 * printf("%#.0o", 0) should print 0.'' 1034 * -- Defect Report #151 1035 */ 1036 cp = buf + BUF; 1037 if (flags & INTMAX_SIZE) { 1038 if (ujval != 0 || prec != 0 || 1039 (flags & ALT && base == 8)) 1040 cp = __ujtoa(ujval, cp, base, 1041 flags & ALT, xdigs, 1042 flags & GROUPING, thousands_sep, 1043 grouping); 1044 } else { 1045 if (ulval != 0 || prec != 0 || 1046 (flags & ALT && base == 8)) 1047 cp = __ultoa(ulval, cp, base, 1048 flags & ALT, xdigs, 1049 flags & GROUPING, thousands_sep, 1050 grouping); 1051 } 1052 size = buf + BUF - cp; 1053 if (size > BUF) /* should never happen */ 1054 abort(); 1055 break; 1056 default: /* "%?" prints ?, unless ? is NUL */ 1057 if (ch == '\0') 1058 goto done; 1059 /* pretend it was %c with argument ch */ 1060 cp = buf; 1061 *cp = ch; 1062 size = 1; 1063 sign = '\0'; 1064 break; 1065 } 1066 1067 /* 1068 * All reasonable formats wind up here. At this point, `cp' 1069 * points to a string which (if not flags&LADJUST) should be 1070 * padded out to `width' places. If flags&ZEROPAD, it should 1071 * first be prefixed by any sign or other prefix; otherwise, 1072 * it should be blank padded before the prefix is emitted. 1073 * After any left-hand padding and prefixing, emit zeroes 1074 * required by a decimal [diouxX] precision, then print the 1075 * string proper, then emit zeroes required by any leftover 1076 * floating precision; finally, if LADJUST, pad with blanks. 1077 * 1078 * Compute actual size, so we know how much to pad. 1079 * size excludes decimal prec; realsz includes it. 1080 */ 1081 realsz = dprec > size ? dprec : size; 1082 if (sign) 1083 realsz++; 1084 if (ox[1]) 1085 realsz += 2; 1086 1087 prsize = width > realsz ? width : realsz; 1088 if ((unsigned)ret + prsize > INT_MAX) { 1089 ret = EOF; 1090 goto error; 1091 } 1092 1093 /* right-adjusting blank padding */ 1094 if ((flags & (LADJUST|ZEROPAD)) == 0) 1095 PAD(width - realsz, blanks); 1096 1097 /* prefix */ 1098 if (sign) 1099 PRINT(&sign, 1); 1100 1101 if (ox[1]) { /* ox[1] is either x, X, or \0 */ 1102 ox[0] = '0'; 1103 PRINT(ox, 2); 1104 } 1105 1106 /* right-adjusting zero padding */ 1107 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1108 PAD(width - realsz, zeroes); 1109 1110 /* leading zeroes from decimal precision */ 1111 PAD(dprec - size, zeroes); 1112 1113 /* the string or number proper */ 1114 #ifndef NO_FLOATING_POINT 1115 if ((flags & FPT) == 0) { 1116 PRINT(cp, size); 1117 } else { /* glue together f_p fragments */ 1118 if (!expchar) { /* %[fF] or sufficiently short %[gG] */ 1119 if (expt <= 0) { 1120 PRINT(zeroes, 1); 1121 if (prec || flags & ALT) 1122 PRINT(decimal_point, 1); 1123 PAD(-expt, zeroes); 1124 /* already handled initial 0's */ 1125 prec += expt; 1126 } else { 1127 PRINTANDPAD(cp, convbuf + ndig, lead, zeroes); 1128 cp += lead; 1129 if (grouping) { 1130 while (nseps>0 || nrepeats>0) { 1131 if (nrepeats > 0) 1132 nrepeats--; 1133 else { 1134 grouping--; 1135 nseps--; 1136 } 1137 PRINT(&thousands_sep, 1138 1); 1139 PRINTANDPAD(cp, 1140 convbuf + ndig, 1141 *grouping, zeroes); 1142 cp += *grouping; 1143 } 1144 if (cp > convbuf + ndig) 1145 cp = convbuf + ndig; 1146 } 1147 if (prec || flags & ALT) { 1148 buf[0] = *decimal_point; 1149 PRINT(buf, 1); 1150 } 1151 } 1152 PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); 1153 } else { /* %[eE] or sufficiently long %[gG] */ 1154 if (prec > 1 || flags & ALT) { 1155 buf[0] = *cp++; 1156 buf[1] = *decimal_point; 1157 PRINT(buf, 2); 1158 PRINT(cp, ndig-1); 1159 PAD(prec - ndig, zeroes); 1160 } else /* XeYYY */ 1161 PRINT(cp, 1); 1162 PRINT(expstr, expsize); 1163 } 1164 } 1165 #else 1166 PRINT(cp, size); 1167 #endif 1168 /* left-adjusting padding (always blank) */ 1169 if (flags & LADJUST) 1170 PAD(width - realsz, blanks); 1171 1172 /* finally, adjust ret */ 1173 ret += prsize; 1174 } 1175 done: 1176 error: 1177 va_end(orgap); 1178 if (convbuf != NULL) 1179 free(convbuf); 1180 if (__sferror(fp)) 1181 ret = EOF; 1182 if ((argtable != NULL) && (argtable != statargtable)) 1183 free (argtable); 1184 return (ret); 1185 /* NOTREACHED */ 1186 } 1187 1188 1189 #ifndef NO_FLOATING_POINT 1190 1191 static int 1192 exponent(wchar_t *p0, int exp, wchar_t fmtch) 1193 { 1194 wchar_t *p, *t; 1195 wchar_t expbuf[MAXEXPDIG]; 1196 1197 p = p0; 1198 *p++ = fmtch; 1199 if (exp < 0) { 1200 exp = -exp; 1201 *p++ = '-'; 1202 } 1203 else 1204 *p++ = '+'; 1205 t = expbuf + MAXEXPDIG; 1206 if (exp > 9) { 1207 do { 1208 *--t = to_char(exp % 10); 1209 } while ((exp /= 10) > 9); 1210 *--t = to_char(exp); 1211 for (; t < expbuf + MAXEXPDIG; *p++ = *t++); 1212 } 1213 else { 1214 /* 1215 * Exponents for decimal floating point conversions 1216 * (%[eEgG]) must be at least two characters long, 1217 * whereas exponents for hexadecimal conversions can 1218 * be only one character long. 1219 */ 1220 if (fmtch == 'e' || fmtch == 'E') 1221 *p++ = '0'; 1222 *p++ = to_char(exp); 1223 } 1224 return (p - p0); 1225 } 1226 #endif /* !NO_FLOATING_POINT */ 1227