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 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #if defined(LIBC_SCCS) && !defined(lint) 38 static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; 39 #endif /* LIBC_SCCS and not lint */ 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD$"); 42 43 /* 44 * Actual printf innards. 45 * 46 * This code is large and complicated... 47 */ 48 49 #include "namespace.h" 50 #include <sys/types.h> 51 52 #include <ctype.h> 53 #include <limits.h> 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 62 #include <stdarg.h> 63 #include "un-namespace.h" 64 65 #include "libc_private.h" 66 #include "local.h" 67 #include "fvwrite.h" 68 69 /* Define FLOATING_POINT to get floating point, HEXFLOAT to get %a. */ 70 #define FLOATING_POINT 71 #define HEXFLOAT 72 73 union arg { 74 int intarg; 75 u_int uintarg; 76 long longarg; 77 u_long ulongarg; 78 long long longlongarg; 79 unsigned long long ulonglongarg; 80 ptrdiff_t ptrdiffarg; 81 size_t sizearg; 82 intmax_t intmaxarg; 83 uintmax_t uintmaxarg; 84 void *pvoidarg; 85 char *pchararg; 86 signed char *pschararg; 87 short *pshortarg; 88 int *pintarg; 89 long *plongarg; 90 long long *plonglongarg; 91 ptrdiff_t *pptrdiffarg; 92 size_t *psizearg; 93 intmax_t *pintmaxarg; 94 #ifdef FLOATING_POINT 95 double doublearg; 96 long double longdoublearg; 97 #endif 98 wint_t wintarg; 99 wchar_t *pwchararg; 100 }; 101 102 /* 103 * Type ids for argument type table. 104 */ 105 enum typeid { 106 T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, 107 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, 108 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, 109 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, 110 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR 111 }; 112 113 static int __sprint(FILE *, struct __suio *); 114 static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); 115 static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, 116 const char *); 117 static char *__ultoa(u_long, char *, int, int, const char *, int, char, 118 const char *); 119 static char *__wcsconv(wchar_t *, int); 120 static void __find_arguments(const char *, va_list, union arg **); 121 static void __grow_type_table(int, enum typeid **, int *); 122 123 /* 124 * Flush out all the vectors defined by the given uio, 125 * then reset it so that it can be reused. 126 */ 127 static int 128 __sprint(FILE *fp, struct __suio *uio) 129 { 130 int err; 131 132 if (uio->uio_resid == 0) { 133 uio->uio_iovcnt = 0; 134 return (0); 135 } 136 err = __sfvwrite(fp, uio); 137 uio->uio_resid = 0; 138 uio->uio_iovcnt = 0; 139 return (err); 140 } 141 142 /* 143 * Helper function for `fprintf to unbuffered unix file': creates a 144 * temporary buffer. We only work on write-only files; this avoids 145 * worries about ungetc buffers and so forth. 146 */ 147 static int 148 __sbprintf(FILE *fp, const char *fmt, va_list ap) 149 { 150 int ret; 151 FILE fake; 152 unsigned char buf[BUFSIZ]; 153 154 /* copy the important variables */ 155 fake._flags = fp->_flags & ~__SNBF; 156 fake._file = fp->_file; 157 fake._cookie = fp->_cookie; 158 fake._write = fp->_write; 159 fake._extra = fp->_extra; 160 161 /* set up the buffer */ 162 fake._bf._base = fake._p = buf; 163 fake._bf._size = fake._w = sizeof(buf); 164 fake._lbfsize = 0; /* not actually used, but Just In Case */ 165 166 /* do the work, then copy any error status */ 167 ret = __vfprintf(&fake, fmt, ap); 168 if (ret >= 0 && __fflush(&fake)) 169 ret = EOF; 170 if (fake._flags & __SERR) 171 fp->_flags |= __SERR; 172 return (ret); 173 } 174 175 /* 176 * Macros for converting digits to letters and vice versa 177 */ 178 #define to_digit(c) ((c) - '0') 179 #define is_digit(c) ((unsigned)to_digit(c) <= 9) 180 #define to_char(n) ((n) + '0') 181 182 /* 183 * Convert an unsigned long to ASCII for printf purposes, returning 184 * a pointer to the first character of the string representation. 185 * Octal numbers can be forced to have a leading zero; hex numbers 186 * use the given digits. 187 */ 188 static char * 189 __ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs, 190 int needgrp, char thousep, const char *grp) 191 { 192 char *cp = endp; 193 long sval; 194 int ndig; 195 196 /* 197 * Handle the three cases separately, in the hope of getting 198 * better/faster code. 199 */ 200 switch (base) { 201 case 10: 202 if (val < 10) { /* many numbers are 1 digit */ 203 *--cp = to_char(val); 204 return (cp); 205 } 206 ndig = 0; 207 /* 208 * On many machines, unsigned arithmetic is harder than 209 * signed arithmetic, so we do at most one unsigned mod and 210 * divide; this is sufficient to reduce the range of 211 * the incoming value to where signed arithmetic works. 212 */ 213 if (val > LONG_MAX) { 214 *--cp = to_char(val % 10); 215 ndig++; 216 sval = val / 10; 217 } else 218 sval = val; 219 do { 220 *--cp = to_char(sval % 10); 221 ndig++; 222 /* 223 * If (*grp == CHAR_MAX) then no more grouping 224 * should be performed. 225 */ 226 if (needgrp && ndig == *grp && *grp != CHAR_MAX 227 && sval > 9) { 228 *--cp = thousep; 229 ndig = 0; 230 /* 231 * If (*(grp+1) == '\0') then we have to 232 * use *grp character (last grouping rule) 233 * for all next cases 234 */ 235 if (*(grp+1) != '\0') 236 grp++; 237 } 238 sval /= 10; 239 } while (sval != 0); 240 break; 241 242 case 8: 243 do { 244 *--cp = to_char(val & 7); 245 val >>= 3; 246 } while (val); 247 if (octzero && *cp != '0') 248 *--cp = '0'; 249 break; 250 251 case 16: 252 do { 253 *--cp = xdigs[val & 15]; 254 val >>= 4; 255 } while (val); 256 break; 257 258 default: /* oops */ 259 abort(); 260 } 261 return (cp); 262 } 263 264 /* Identical to __ultoa, but for intmax_t. */ 265 static char * 266 __ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, 267 int needgrp, char thousep, const char *grp) 268 { 269 char *cp = endp; 270 intmax_t sval; 271 int ndig; 272 273 /* quick test for small values; __ultoa is typically much faster */ 274 /* (perhaps instead we should run until small, then call __ultoa?) */ 275 if (val <= ULONG_MAX) 276 return (__ultoa((u_long)val, endp, base, octzero, xdigs, 277 needgrp, thousep, grp)); 278 switch (base) { 279 case 10: 280 if (val < 10) { 281 *--cp = to_char(val % 10); 282 return (cp); 283 } 284 ndig = 0; 285 if (val > INTMAX_MAX) { 286 *--cp = to_char(val % 10); 287 ndig++; 288 sval = val / 10; 289 } else 290 sval = val; 291 do { 292 *--cp = to_char(sval % 10); 293 ndig++; 294 /* 295 * If (*grp == CHAR_MAX) then no more grouping 296 * should be performed. 297 */ 298 if (needgrp && *grp != CHAR_MAX && ndig == *grp 299 && sval > 9) { 300 *--cp = thousep; 301 ndig = 0; 302 /* 303 * If (*(grp+1) == '\0') then we have to 304 * use *grp character (last grouping rule) 305 * for all next cases 306 */ 307 if (*(grp+1) != '\0') 308 grp++; 309 } 310 sval /= 10; 311 } while (sval != 0); 312 break; 313 314 case 8: 315 do { 316 *--cp = to_char(val & 7); 317 val >>= 3; 318 } while (val); 319 if (octzero && *cp != '0') 320 *--cp = '0'; 321 break; 322 323 case 16: 324 do { 325 *--cp = xdigs[val & 15]; 326 val >>= 4; 327 } while (val); 328 break; 329 330 default: 331 abort(); 332 } 333 return (cp); 334 } 335 336 /* 337 * Convert a wide character string argument for the %ls format to a multibyte 338 * string representation. ``prec'' specifies the maximum number of bytes 339 * to output. If ``prec'' is greater than or equal to zero, we can't assume 340 * that the wide char. string ends in a null character. 341 */ 342 static char * 343 __wcsconv(wchar_t *wcsarg, int prec) 344 { 345 char buf[MB_LEN_MAX]; 346 wchar_t *p; 347 char *convbuf, *mbp; 348 size_t clen, nbytes; 349 350 /* 351 * Determine the number of bytes to output and allocate space for 352 * the output. 353 */ 354 if (prec >= 0) { 355 nbytes = 0; 356 p = wcsarg; 357 for (;;) { 358 clen = wcrtomb(buf, *p++, NULL); 359 if (clen == 0 || clen == (size_t)-1 || 360 nbytes + clen > prec) 361 break; 362 nbytes += clen; 363 } 364 } else { 365 p = wcsarg; 366 nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, NULL); 367 if (nbytes == (size_t)-1) 368 return (NULL); 369 } 370 if ((convbuf = malloc(nbytes + 1)) == NULL) 371 return (NULL); 372 373 /* 374 * Fill the output buffer with the multibyte representations of as 375 * many wide characters as will fit. 376 */ 377 mbp = convbuf; 378 p = wcsarg; 379 while (mbp - convbuf < nbytes) { 380 clen = wcrtomb(mbp, *p++, NULL); 381 if (clen == 0 || clen == (size_t)-1) 382 break; 383 mbp += clen; 384 } 385 if (clen == (size_t)-1) { 386 free(convbuf); 387 return (NULL); 388 } 389 *mbp = '\0'; 390 391 return (convbuf); 392 } 393 394 /* 395 * MT-safe version 396 */ 397 int 398 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) 399 400 { 401 int ret; 402 403 FLOCKFILE(fp); 404 ret = __vfprintf(fp, fmt0, ap); 405 FUNLOCKFILE(fp); 406 return (ret); 407 } 408 409 #ifdef FLOATING_POINT 410 411 #define dtoa __dtoa 412 #define freedtoa __freedtoa 413 414 #include <float.h> 415 #include <math.h> 416 #include "floatio.h" 417 #include "gdtoa.h" 418 419 #define DEFPREC 6 420 421 static int exponent(char *, int, int); 422 423 #endif /* FLOATING_POINT */ 424 425 /* 426 * The size of the buffer we use as scratch space for integer 427 * conversions, among other things. Technically, we would need the 428 * most space for base 10 conversions with thousands' grouping 429 * characters between each pair of digits. 100 bytes is a 430 * conservative overestimate even for a 128-bit uintmax_t. 431 */ 432 #define BUF 100 433 434 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ 435 436 /* 437 * Flags used during conversion. 438 */ 439 #define ALT 0x001 /* alternate form */ 440 #define LADJUST 0x004 /* left adjustment */ 441 #define LONGDBL 0x008 /* long double */ 442 #define LONGINT 0x010 /* long integer */ 443 #define LLONGINT 0x020 /* long long integer */ 444 #define SHORTINT 0x040 /* short integer */ 445 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 446 #define FPT 0x100 /* Floating point number */ 447 #define GROUPING 0x200 /* use grouping ("'" flag) */ 448 /* C99 additional size modifiers: */ 449 #define SIZET 0x400 /* size_t */ 450 #define PTRDIFFT 0x800 /* ptrdiff_t */ 451 #define INTMAXT 0x1000 /* intmax_t */ 452 #define CHARINT 0x2000 /* print char using int format */ 453 454 /* 455 * Non-MT-safe version 456 */ 457 int 458 __vfprintf(FILE *fp, const char *fmt0, va_list ap) 459 { 460 char *fmt; /* format string */ 461 int ch; /* character from fmt */ 462 int n, n2; /* handy integer (short term usage) */ 463 char *cp; /* handy char pointer (short term usage) */ 464 struct __siov *iovp; /* for PRINT macro */ 465 int flags; /* flags as above */ 466 int ret; /* return value accumulator */ 467 int width; /* width from format (%8d), or 0 */ 468 int prec; /* precision from format; <0 for N/A */ 469 char sign; /* sign prefix (' ', '+', '-', or \0) */ 470 char thousands_sep; /* locale specific thousands separator */ 471 const char *grouping; /* locale specific numeric grouping rules */ 472 #ifdef FLOATING_POINT 473 /* 474 * We can decompose the printed representation of floating 475 * point numbers into several parts, some of which may be empty: 476 * 477 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ 478 * A B ---C--- D E F 479 * 480 * A: 'sign' holds this value if present; '\0' otherwise 481 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal 482 * C: cp points to the string MMMNNN. Leading and trailing 483 * zeros are not in the string and must be added. 484 * D: expchar holds this character; '\0' if no exponent, e.g. %f 485 * F: at least two digits for decimal, at least one digit for hex 486 */ 487 char *decimal_point; /* locale specific decimal point */ 488 int signflag; /* true if float is negative */ 489 union { /* floating point arguments %[aAeEfFgG] */ 490 double dbl; 491 long double ldbl; 492 } fparg; 493 int expt; /* integer value of exponent */ 494 char expchar; /* exponent character: [eEpP\0] */ 495 char *dtoaend; /* pointer to end of converted digits */ 496 int expsize; /* character count for expstr */ 497 int lead; /* sig figs before decimal or group sep */ 498 int ndig; /* actual number of digits returned by dtoa */ 499 char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ 500 char *dtoaresult; /* buffer allocated by dtoa */ 501 int nseps; /* number of group separators with ' */ 502 int nrepeats; /* number of repeats of the last group */ 503 #endif 504 u_long ulval; /* integer arguments %[diouxX] */ 505 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 506 int base; /* base for [diouxX] conversion */ 507 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 508 int realsz; /* field size expanded by dprec, sign, etc */ 509 int size; /* size of converted field or string */ 510 int prsize; /* max size of printed field */ 511 const char *xdigs; /* digits for %[xX] conversion */ 512 #define NIOV 8 513 struct __suio uio; /* output information: summary */ 514 struct __siov iov[NIOV];/* ... and individual io vectors */ 515 char buf[BUF]; /* buffer with space for digits of uintmax_t */ 516 char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ 517 union arg *argtable; /* args, built due to positional arg */ 518 union arg statargtable [STATIC_ARG_TBL_SIZE]; 519 int nextarg; /* 1-based argument index */ 520 va_list orgap; /* original argument pointer */ 521 char *convbuf; /* wide to multibyte conversion result */ 522 523 /* 524 * Choose PADSIZE to trade efficiency vs. size. If larger printf 525 * fields occur frequently, increase PADSIZE and make the initialisers 526 * below longer. 527 */ 528 #define PADSIZE 16 /* pad chunk size */ 529 static char blanks[PADSIZE] = 530 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 531 static char zeroes[PADSIZE] = 532 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 533 534 static const char xdigs_lower[16] = "0123456789abcdef"; 535 static const char xdigs_upper[16] = "0123456789ABCDEF"; 536 537 /* 538 * BEWARE, these `goto error' on error, and PAD uses `n'. 539 */ 540 #define PRINT(ptr, len) { \ 541 iovp->iov_base = (ptr); \ 542 iovp->iov_len = (len); \ 543 uio.uio_resid += (len); \ 544 iovp++; \ 545 if (++uio.uio_iovcnt >= NIOV) { \ 546 if (__sprint(fp, &uio)) \ 547 goto error; \ 548 iovp = iov; \ 549 } \ 550 } 551 #define PAD(howmany, with) { \ 552 if ((n = (howmany)) > 0) { \ 553 while (n > PADSIZE) { \ 554 PRINT(with, PADSIZE); \ 555 n -= PADSIZE; \ 556 } \ 557 PRINT(with, n); \ 558 } \ 559 } 560 #define PRINTANDPAD(p, ep, len, with) do { \ 561 n2 = (ep) - (p); \ 562 if (n2 > (len)) \ 563 n2 = (len); \ 564 if (n2 > 0) \ 565 PRINT((p), n2); \ 566 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ 567 } while(0) 568 #define FLUSH() { \ 569 if (uio.uio_resid && __sprint(fp, &uio)) \ 570 goto error; \ 571 uio.uio_iovcnt = 0; \ 572 iovp = iov; \ 573 } 574 575 /* 576 * Get the argument indexed by nextarg. If the argument table is 577 * built, use it to get the argument. If its not, get the next 578 * argument (and arguments must be gotten sequentially). 579 */ 580 #define GETARG(type) \ 581 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ 582 (nextarg++, va_arg(ap, type))) 583 584 /* 585 * To extend shorts properly, we need both signed and unsigned 586 * argument extraction methods. 587 */ 588 #define SARG() \ 589 (flags&LONGINT ? GETARG(long) : \ 590 flags&SHORTINT ? (long)(short)GETARG(int) : \ 591 flags&CHARINT ? (long)(signed char)GETARG(int) : \ 592 (long)GETARG(int)) 593 #define UARG() \ 594 (flags&LONGINT ? GETARG(u_long) : \ 595 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ 596 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ 597 (u_long)GETARG(u_int)) 598 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) 599 #define SJARG() \ 600 (flags&INTMAXT ? GETARG(intmax_t) : \ 601 flags&SIZET ? (intmax_t)GETARG(size_t) : \ 602 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ 603 (intmax_t)GETARG(long long)) 604 #define UJARG() \ 605 (flags&INTMAXT ? GETARG(uintmax_t) : \ 606 flags&SIZET ? (uintmax_t)GETARG(size_t) : \ 607 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ 608 (uintmax_t)GETARG(unsigned long long)) 609 610 /* 611 * Get * arguments, including the form *nn$. Preserve the nextarg 612 * that the argument can be gotten once the type is determined. 613 */ 614 #define GETASTER(val) \ 615 n2 = 0; \ 616 cp = fmt; \ 617 while (is_digit(*cp)) { \ 618 n2 = 10 * n2 + to_digit(*cp); \ 619 cp++; \ 620 } \ 621 if (*cp == '$') { \ 622 int hold = nextarg; \ 623 if (argtable == NULL) { \ 624 argtable = statargtable; \ 625 __find_arguments (fmt0, orgap, &argtable); \ 626 } \ 627 nextarg = n2; \ 628 val = GETARG (int); \ 629 nextarg = hold; \ 630 fmt = ++cp; \ 631 } else { \ 632 val = GETARG (int); \ 633 } 634 635 636 thousands_sep = '\0'; 637 grouping = NULL; 638 convbuf = NULL; 639 #ifdef FLOATING_POINT 640 dtoaresult = NULL; 641 decimal_point = localeconv()->decimal_point; 642 #endif 643 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ 644 if (cantwrite(fp)) 645 return (EOF); 646 647 /* optimise fprintf(stderr) (and other unbuffered Unix files) */ 648 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && 649 fp->_file >= 0) 650 return (__sbprintf(fp, fmt0, ap)); 651 652 fmt = (char *)fmt0; 653 argtable = NULL; 654 nextarg = 1; 655 va_copy(orgap, ap); 656 uio.uio_iov = iovp = iov; 657 uio.uio_resid = 0; 658 uio.uio_iovcnt = 0; 659 ret = 0; 660 661 /* 662 * Scan the format for conversions (`%' character). 663 */ 664 for (;;) { 665 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) 666 /* void */; 667 if ((n = fmt - cp) != 0) { 668 if ((unsigned)ret + n > INT_MAX) { 669 ret = EOF; 670 goto error; 671 } 672 PRINT(cp, n); 673 ret += n; 674 } 675 if (ch == '\0') 676 goto done; 677 fmt++; /* skip over '%' */ 678 679 flags = 0; 680 dprec = 0; 681 width = 0; 682 prec = -1; 683 sign = '\0'; 684 ox[1] = '\0'; 685 686 rflag: ch = *fmt++; 687 reswitch: switch (ch) { 688 case ' ': 689 /*- 690 * ``If the space and + flags both appear, the space 691 * flag will be ignored.'' 692 * -- ANSI X3J11 693 */ 694 if (!sign) 695 sign = ' '; 696 goto rflag; 697 case '#': 698 flags |= ALT; 699 goto rflag; 700 case '*': 701 /*- 702 * ``A negative field width argument is taken as a 703 * - flag followed by a positive field width.'' 704 * -- ANSI X3J11 705 * They don't exclude field widths read from args. 706 */ 707 GETASTER (width); 708 if (width >= 0) 709 goto rflag; 710 width = -width; 711 /* FALLTHROUGH */ 712 case '-': 713 flags |= LADJUST; 714 goto rflag; 715 case '+': 716 sign = '+'; 717 goto rflag; 718 case '\'': 719 flags |= GROUPING; 720 thousands_sep = *(localeconv()->thousands_sep); 721 grouping = localeconv()->grouping; 722 goto rflag; 723 case '.': 724 if ((ch = *fmt++) == '*') { 725 GETASTER (prec); 726 goto rflag; 727 } 728 prec = 0; 729 while (is_digit(ch)) { 730 prec = 10 * prec + to_digit(ch); 731 ch = *fmt++; 732 } 733 goto reswitch; 734 case '0': 735 /*- 736 * ``Note that 0 is taken as a flag, not as the 737 * beginning of a field width.'' 738 * -- ANSI X3J11 739 */ 740 flags |= ZEROPAD; 741 goto rflag; 742 case '1': case '2': case '3': case '4': 743 case '5': case '6': case '7': case '8': case '9': 744 n = 0; 745 do { 746 n = 10 * n + to_digit(ch); 747 ch = *fmt++; 748 } while (is_digit(ch)); 749 if (ch == '$') { 750 nextarg = n; 751 if (argtable == NULL) { 752 argtable = statargtable; 753 __find_arguments (fmt0, orgap, 754 &argtable); 755 } 756 goto rflag; 757 } 758 width = n; 759 goto reswitch; 760 #ifdef FLOATING_POINT 761 case 'L': 762 flags |= LONGDBL; 763 goto rflag; 764 #endif 765 case 'h': 766 if (flags & SHORTINT) { 767 flags &= ~SHORTINT; 768 flags |= CHARINT; 769 } else 770 flags |= SHORTINT; 771 goto rflag; 772 case 'j': 773 flags |= INTMAXT; 774 goto rflag; 775 case 'l': 776 if (flags & LONGINT) { 777 flags &= ~LONGINT; 778 flags |= LLONGINT; 779 } else 780 flags |= LONGINT; 781 goto rflag; 782 case 'q': 783 flags |= LLONGINT; /* not necessarily */ 784 goto rflag; 785 case 't': 786 flags |= PTRDIFFT; 787 goto rflag; 788 case 'z': 789 flags |= SIZET; 790 goto rflag; 791 case 'C': 792 flags |= LONGINT; 793 /*FALLTHROUGH*/ 794 case 'c': 795 if (flags & LONGINT) { 796 size_t mbseqlen; 797 798 mbseqlen = wcrtomb(cp = buf, 799 (wchar_t)GETARG(wint_t), NULL); 800 if (mbseqlen == (size_t)-1) { 801 fp->_flags |= __SERR; 802 goto error; 803 } 804 size = (int)mbseqlen; 805 } else { 806 *(cp = buf) = GETARG(int); 807 size = 1; 808 } 809 sign = '\0'; 810 break; 811 case 'D': 812 flags |= LONGINT; 813 /*FALLTHROUGH*/ 814 case 'd': 815 case 'i': 816 if (flags & INTMAX_SIZE) { 817 ujval = SJARG(); 818 if ((intmax_t)ujval < 0) { 819 ujval = -ujval; 820 sign = '-'; 821 } 822 } else { 823 ulval = SARG(); 824 if ((long)ulval < 0) { 825 ulval = -ulval; 826 sign = '-'; 827 } 828 } 829 base = 10; 830 goto number; 831 #ifdef FLOATING_POINT 832 #ifdef HEXFLOAT 833 case 'a': 834 case 'A': 835 if (ch == 'a') { 836 ox[1] = 'x'; 837 xdigs = xdigs_lower; 838 expchar = 'p'; 839 } else { 840 ox[1] = 'X'; 841 xdigs = xdigs_upper; 842 expchar = 'P'; 843 } 844 if (prec >= 0) 845 prec++; 846 if (dtoaresult != NULL) 847 freedtoa(dtoaresult); 848 if (flags & LONGDBL) { 849 fparg.ldbl = GETARG(long double); 850 dtoaresult = cp = 851 __hldtoa(fparg.ldbl, xdigs, prec, 852 &expt, &signflag, &dtoaend); 853 } else { 854 fparg.dbl = GETARG(double); 855 dtoaresult = cp = 856 __hdtoa(fparg.dbl, xdigs, prec, 857 &expt, &signflag, &dtoaend); 858 } 859 if (prec < 0) 860 prec = dtoaend - cp; 861 if (expt == INT_MAX) 862 ox[1] = '\0'; 863 goto fp_common; 864 #endif /* HEXFLOAT */ 865 case 'e': 866 case 'E': 867 expchar = ch; 868 if (prec < 0) /* account for digit before decpt */ 869 prec = DEFPREC + 1; 870 else 871 prec++; 872 goto fp_begin; 873 case 'f': 874 case 'F': 875 expchar = '\0'; 876 goto fp_begin; 877 case 'g': 878 case 'G': 879 expchar = ch - ('g' - 'e'); 880 if (prec == 0) 881 prec = 1; 882 fp_begin: 883 if (prec < 0) 884 prec = DEFPREC; 885 if (dtoaresult != NULL) 886 freedtoa(dtoaresult); 887 if (flags & LONGDBL) { 888 fparg.ldbl = GETARG(long double); 889 dtoaresult = cp = 890 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, 891 &expt, &signflag, &dtoaend); 892 } else { 893 fparg.dbl = GETARG(double); 894 dtoaresult = cp = 895 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 896 &expt, &signflag, &dtoaend); 897 if (expt == 9999) 898 expt = INT_MAX; 899 } 900 fp_common: 901 if (signflag) 902 sign = '-'; 903 if (expt == INT_MAX) { /* inf or nan */ 904 if (*cp == 'N') { 905 cp = (ch >= 'a') ? "nan" : "NAN"; 906 sign = '\0'; 907 } else 908 cp = (ch >= 'a') ? "inf" : "INF"; 909 size = 3; 910 break; 911 } 912 flags |= FPT; 913 ndig = dtoaend - cp; 914 if (ch == 'g' || ch == 'G') { 915 if (expt > -4 && expt <= prec) { 916 /* Make %[gG] smell like %[fF] */ 917 expchar = '\0'; 918 if (flags & ALT) 919 prec -= expt; 920 else 921 prec = ndig - expt; 922 if (prec < 0) 923 prec = 0; 924 } else { 925 /* 926 * Make %[gG] smell like %[eE], but 927 * trim trailing zeroes if no # flag. 928 */ 929 if (!(flags & ALT)) 930 prec = ndig; 931 } 932 } 933 if (expchar) { 934 expsize = exponent(expstr, expt - 1, expchar); 935 size = expsize + prec; 936 if (prec > 1 || flags & ALT) 937 ++size; 938 } else { 939 /* space for digits before decimal point */ 940 if (expt > 0) 941 size = expt; 942 else /* "0" */ 943 size = 1; 944 /* space for decimal pt and following digits */ 945 if (prec || flags & ALT) 946 size += prec + 1; 947 if (grouping && expt > 0) { 948 /* space for thousands' grouping */ 949 nseps = nrepeats = 0; 950 lead = expt; 951 while (*grouping != CHAR_MAX) { 952 if (lead <= *grouping) 953 break; 954 lead -= *grouping; 955 if (*(grouping+1)) { 956 nseps++; 957 grouping++; 958 } else 959 nrepeats++; 960 } 961 size += nseps + nrepeats; 962 } else 963 lead = expt; 964 } 965 break; 966 #endif /* FLOATING_POINT */ 967 case 'n': 968 /* 969 * Assignment-like behavior is specified if the 970 * value overflows or is otherwise unrepresentable. 971 * C99 says to use `signed char' for %hhn conversions. 972 */ 973 if (flags & LLONGINT) 974 *GETARG(long long *) = ret; 975 else if (flags & SIZET) 976 *GETARG(ssize_t *) = (ssize_t)ret; 977 else if (flags & PTRDIFFT) 978 *GETARG(ptrdiff_t *) = ret; 979 else if (flags & INTMAXT) 980 *GETARG(intmax_t *) = ret; 981 else if (flags & LONGINT) 982 *GETARG(long *) = ret; 983 else if (flags & SHORTINT) 984 *GETARG(short *) = ret; 985 else if (flags & CHARINT) 986 *GETARG(signed char *) = ret; 987 else 988 *GETARG(int *) = ret; 989 continue; /* no output */ 990 case 'O': 991 flags |= LONGINT; 992 /*FALLTHROUGH*/ 993 case 'o': 994 if (flags & INTMAX_SIZE) 995 ujval = UJARG(); 996 else 997 ulval = UARG(); 998 base = 8; 999 goto nosign; 1000 case 'p': 1001 /*- 1002 * ``The argument shall be a pointer to void. The 1003 * value of the pointer is converted to a sequence 1004 * of printable characters, in an implementation- 1005 * defined manner.'' 1006 * -- ANSI X3J11 1007 */ 1008 ujval = (uintmax_t)(uintptr_t)GETARG(void *); 1009 base = 16; 1010 xdigs = xdigs_lower; 1011 flags = flags | INTMAXT; 1012 ox[1] = 'x'; 1013 goto nosign; 1014 case 'S': 1015 flags |= LONGINT; 1016 /*FALLTHROUGH*/ 1017 case 's': 1018 if (flags & LONGINT) { 1019 wchar_t *wcp; 1020 1021 if (convbuf != NULL) 1022 free(convbuf); 1023 if ((wcp = GETARG(wchar_t *)) == NULL) 1024 cp = "(null)"; 1025 else { 1026 convbuf = __wcsconv(wcp, prec); 1027 if (convbuf == NULL) { 1028 fp->_flags |= __SERR; 1029 goto error; 1030 } 1031 cp = convbuf; 1032 } 1033 } else if ((cp = GETARG(char *)) == NULL) 1034 cp = "(null)"; 1035 if (prec >= 0) { 1036 /* 1037 * can't use strlen; can only look for the 1038 * NUL in the first `prec' characters, and 1039 * strlen() will go further. 1040 */ 1041 char *p = memchr(cp, 0, (size_t)prec); 1042 1043 if (p != NULL) { 1044 size = p - cp; 1045 if (size > prec) 1046 size = prec; 1047 } else 1048 size = prec; 1049 } else 1050 size = strlen(cp); 1051 sign = '\0'; 1052 break; 1053 case 'U': 1054 flags |= LONGINT; 1055 /*FALLTHROUGH*/ 1056 case 'u': 1057 if (flags & INTMAX_SIZE) 1058 ujval = UJARG(); 1059 else 1060 ulval = UARG(); 1061 base = 10; 1062 goto nosign; 1063 case 'X': 1064 xdigs = xdigs_upper; 1065 goto hex; 1066 case 'x': 1067 xdigs = xdigs_lower; 1068 hex: 1069 if (flags & INTMAX_SIZE) 1070 ujval = UJARG(); 1071 else 1072 ulval = UARG(); 1073 base = 16; 1074 /* leading 0x/X only if non-zero */ 1075 if (flags & ALT && 1076 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) 1077 ox[1] = ch; 1078 1079 flags &= ~GROUPING; 1080 /* unsigned conversions */ 1081 nosign: sign = '\0'; 1082 /*- 1083 * ``... diouXx conversions ... if a precision is 1084 * specified, the 0 flag will be ignored.'' 1085 * -- ANSI X3J11 1086 */ 1087 number: if ((dprec = prec) >= 0) 1088 flags &= ~ZEROPAD; 1089 1090 /*- 1091 * ``The result of converting a zero value with an 1092 * explicit precision of zero is no characters.'' 1093 * -- ANSI X3J11 1094 */ 1095 cp = buf + BUF; 1096 if (flags & INTMAX_SIZE) { 1097 if (ujval != 0 || prec != 0) 1098 cp = __ujtoa(ujval, cp, base, 1099 flags & ALT, xdigs, 1100 flags & GROUPING, thousands_sep, 1101 grouping); 1102 } else { 1103 if (ulval != 0 || prec != 0) 1104 cp = __ultoa(ulval, cp, base, 1105 flags & ALT, xdigs, 1106 flags & GROUPING, thousands_sep, 1107 grouping); 1108 } 1109 size = buf + BUF - cp; 1110 if (size > BUF) /* should never happen */ 1111 abort(); 1112 break; 1113 default: /* "%?" prints ?, unless ? is NUL */ 1114 if (ch == '\0') 1115 goto done; 1116 /* pretend it was %c with argument ch */ 1117 cp = buf; 1118 *cp = ch; 1119 size = 1; 1120 sign = '\0'; 1121 break; 1122 } 1123 1124 /* 1125 * All reasonable formats wind up here. At this point, `cp' 1126 * points to a string which (if not flags&LADJUST) should be 1127 * padded out to `width' places. If flags&ZEROPAD, it should 1128 * first be prefixed by any sign or other prefix; otherwise, 1129 * it should be blank padded before the prefix is emitted. 1130 * After any left-hand padding and prefixing, emit zeroes 1131 * required by a decimal [diouxX] precision, then print the 1132 * string proper, then emit zeroes required by any leftover 1133 * floating precision; finally, if LADJUST, pad with blanks. 1134 * 1135 * Compute actual size, so we know how much to pad. 1136 * size excludes decimal prec; realsz includes it. 1137 */ 1138 realsz = dprec > size ? dprec : size; 1139 if (sign) 1140 realsz++; 1141 if (ox[1]) 1142 realsz += 2; 1143 1144 prsize = width > realsz ? width : realsz; 1145 if ((unsigned)ret + prsize > INT_MAX) { 1146 ret = EOF; 1147 goto error; 1148 } 1149 1150 /* right-adjusting blank padding */ 1151 if ((flags & (LADJUST|ZEROPAD)) == 0) 1152 PAD(width - realsz, blanks); 1153 1154 /* prefix */ 1155 if (sign) 1156 PRINT(&sign, 1); 1157 1158 if (ox[1]) { /* ox[1] is either x, X, or \0 */ 1159 ox[0] = '0'; 1160 PRINT(ox, 2); 1161 } 1162 1163 /* right-adjusting zero padding */ 1164 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1165 PAD(width - realsz, zeroes); 1166 1167 /* leading zeroes from decimal precision */ 1168 PAD(dprec - size, zeroes); 1169 1170 /* the string or number proper */ 1171 #ifdef FLOATING_POINT 1172 if ((flags & FPT) == 0) { 1173 PRINT(cp, size); 1174 } else { /* glue together f_p fragments */ 1175 if (!expchar) { /* %[fF] or sufficiently short %[gG] */ 1176 if (expt <= 0) { 1177 PRINT(zeroes, 1); 1178 if (prec || flags & ALT) 1179 PRINT(decimal_point, 1); 1180 PAD(-expt, zeroes); 1181 /* already handled initial 0's */ 1182 prec += expt; 1183 } else { 1184 PRINTANDPAD(cp, dtoaend, lead, zeroes); 1185 cp += lead; 1186 if (grouping) { 1187 while (nseps>0 || nrepeats>0) { 1188 if (nrepeats > 0) 1189 nrepeats--; 1190 else { 1191 grouping--; 1192 nseps--; 1193 } 1194 PRINT(&thousands_sep, 1195 1); 1196 PRINTANDPAD(cp,dtoaend, 1197 *grouping, zeroes); 1198 cp += *grouping; 1199 } 1200 if (cp > dtoaend) 1201 cp = dtoaend; 1202 } 1203 if (prec || flags & ALT) 1204 PRINT(decimal_point,1); 1205 } 1206 PRINTANDPAD(cp, dtoaend, prec, zeroes); 1207 } else { /* %[eE] or sufficiently long %[gG] */ 1208 if (prec > 1 || flags & ALT) { 1209 buf[0] = *cp++; 1210 buf[1] = *decimal_point; 1211 PRINT(buf, 2); 1212 PRINT(cp, ndig-1); 1213 PAD(prec - ndig, zeroes); 1214 } else /* XeYYY */ 1215 PRINT(cp, 1); 1216 PRINT(expstr, expsize); 1217 } 1218 } 1219 #else 1220 PRINT(cp, size); 1221 #endif 1222 /* left-adjusting padding (always blank) */ 1223 if (flags & LADJUST) 1224 PAD(width - realsz, blanks); 1225 1226 /* finally, adjust ret */ 1227 ret += prsize; 1228 1229 FLUSH(); /* copy out the I/O vectors */ 1230 } 1231 done: 1232 FLUSH(); 1233 error: 1234 #ifdef FLOATING_POINT 1235 if (dtoaresult != NULL) 1236 freedtoa(dtoaresult); 1237 #endif 1238 if (convbuf != NULL) 1239 free(convbuf); 1240 if (__sferror(fp)) 1241 ret = EOF; 1242 if ((argtable != NULL) && (argtable != statargtable)) 1243 free (argtable); 1244 return (ret); 1245 /* NOTREACHED */ 1246 } 1247 1248 /* 1249 * Find all arguments when a positional parameter is encountered. Returns a 1250 * table, indexed by argument number, of pointers to each arguments. The 1251 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. 1252 * It will be replaces with a malloc-ed one if it overflows. 1253 */ 1254 static void 1255 __find_arguments (const char *fmt0, va_list ap, union arg **argtable) 1256 { 1257 char *fmt; /* format string */ 1258 int ch; /* character from fmt */ 1259 int n, n2; /* handy integer (short term usage) */ 1260 char *cp; /* handy char pointer (short term usage) */ 1261 int flags; /* flags as above */ 1262 int width; /* width from format (%8d), or 0 */ 1263 enum typeid *typetable; /* table of types */ 1264 enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; 1265 int tablesize; /* current size of type table */ 1266 int tablemax; /* largest used index in table */ 1267 int nextarg; /* 1-based argument index */ 1268 1269 /* 1270 * Add an argument type to the table, expanding if necessary. 1271 */ 1272 #define ADDTYPE(type) \ 1273 ((nextarg >= tablesize) ? \ 1274 __grow_type_table(nextarg, &typetable, &tablesize) : 0, \ 1275 (nextarg > tablemax) ? tablemax = nextarg : 0, \ 1276 typetable[nextarg++] = type) 1277 1278 #define ADDSARG() \ 1279 ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ 1280 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ 1281 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ 1282 ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ 1283 ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) 1284 1285 #define ADDUARG() \ 1286 ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ 1287 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ 1288 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ 1289 ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ 1290 ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) 1291 1292 /* 1293 * Add * arguments to the type array. 1294 */ 1295 #define ADDASTER() \ 1296 n2 = 0; \ 1297 cp = fmt; \ 1298 while (is_digit(*cp)) { \ 1299 n2 = 10 * n2 + to_digit(*cp); \ 1300 cp++; \ 1301 } \ 1302 if (*cp == '$') { \ 1303 int hold = nextarg; \ 1304 nextarg = n2; \ 1305 ADDTYPE (T_INT); \ 1306 nextarg = hold; \ 1307 fmt = ++cp; \ 1308 } else { \ 1309 ADDTYPE (T_INT); \ 1310 } 1311 fmt = (char *)fmt0; 1312 typetable = stattypetable; 1313 tablesize = STATIC_ARG_TBL_SIZE; 1314 tablemax = 0; 1315 nextarg = 1; 1316 memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE); 1317 1318 /* 1319 * Scan the format for conversions (`%' character). 1320 */ 1321 for (;;) { 1322 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) 1323 /* void */; 1324 if (ch == '\0') 1325 goto done; 1326 fmt++; /* skip over '%' */ 1327 1328 flags = 0; 1329 width = 0; 1330 1331 rflag: ch = *fmt++; 1332 reswitch: switch (ch) { 1333 case ' ': 1334 case '#': 1335 goto rflag; 1336 case '*': 1337 ADDASTER (); 1338 goto rflag; 1339 case '-': 1340 case '+': 1341 case '\'': 1342 goto rflag; 1343 case '.': 1344 if ((ch = *fmt++) == '*') { 1345 ADDASTER (); 1346 goto rflag; 1347 } 1348 while (is_digit(ch)) { 1349 ch = *fmt++; 1350 } 1351 goto reswitch; 1352 case '0': 1353 goto rflag; 1354 case '1': case '2': case '3': case '4': 1355 case '5': case '6': case '7': case '8': case '9': 1356 n = 0; 1357 do { 1358 n = 10 * n + to_digit(ch); 1359 ch = *fmt++; 1360 } while (is_digit(ch)); 1361 if (ch == '$') { 1362 nextarg = n; 1363 goto rflag; 1364 } 1365 width = n; 1366 goto reswitch; 1367 #ifdef FLOATING_POINT 1368 case 'L': 1369 flags |= LONGDBL; 1370 goto rflag; 1371 #endif 1372 case 'h': 1373 if (flags & SHORTINT) { 1374 flags &= ~SHORTINT; 1375 flags |= CHARINT; 1376 } else 1377 flags |= SHORTINT; 1378 goto rflag; 1379 case 'j': 1380 flags |= INTMAXT; 1381 goto rflag; 1382 case 'l': 1383 if (flags & LONGINT) { 1384 flags &= ~LONGINT; 1385 flags |= LLONGINT; 1386 } else 1387 flags |= LONGINT; 1388 goto rflag; 1389 case 'q': 1390 flags |= LLONGINT; /* not necessarily */ 1391 goto rflag; 1392 case 't': 1393 flags |= PTRDIFFT; 1394 goto rflag; 1395 case 'z': 1396 flags |= SIZET; 1397 goto rflag; 1398 case 'C': 1399 flags |= LONGINT; 1400 /*FALLTHROUGH*/ 1401 case 'c': 1402 if (flags & LONGINT) 1403 ADDTYPE(T_WINT); 1404 else 1405 ADDTYPE(T_INT); 1406 break; 1407 case 'D': 1408 flags |= LONGINT; 1409 /*FALLTHROUGH*/ 1410 case 'd': 1411 case 'i': 1412 ADDSARG(); 1413 break; 1414 #ifdef FLOATING_POINT 1415 #ifdef HEXFLOAT 1416 case 'a': 1417 case 'A': 1418 #endif 1419 case 'e': 1420 case 'E': 1421 case 'f': 1422 case 'g': 1423 case 'G': 1424 if (flags & LONGDBL) 1425 ADDTYPE(T_LONG_DOUBLE); 1426 else 1427 ADDTYPE(T_DOUBLE); 1428 break; 1429 #endif /* FLOATING_POINT */ 1430 case 'n': 1431 if (flags & INTMAXT) 1432 ADDTYPE(TP_INTMAXT); 1433 else if (flags & PTRDIFFT) 1434 ADDTYPE(TP_PTRDIFFT); 1435 else if (flags & SIZET) 1436 ADDTYPE(TP_SIZET); 1437 else if (flags & LLONGINT) 1438 ADDTYPE(TP_LLONG); 1439 else if (flags & LONGINT) 1440 ADDTYPE(TP_LONG); 1441 else if (flags & SHORTINT) 1442 ADDTYPE(TP_SHORT); 1443 else if (flags & CHARINT) 1444 ADDTYPE(TP_SCHAR); 1445 else 1446 ADDTYPE(TP_INT); 1447 continue; /* no output */ 1448 case 'O': 1449 flags |= LONGINT; 1450 /*FALLTHROUGH*/ 1451 case 'o': 1452 ADDUARG(); 1453 break; 1454 case 'p': 1455 ADDTYPE(TP_VOID); 1456 break; 1457 case 'S': 1458 flags |= LONGINT; 1459 /*FALLTHROUGH*/ 1460 case 's': 1461 if (flags & LONGINT) 1462 ADDTYPE(TP_WCHAR); 1463 else 1464 ADDTYPE(TP_CHAR); 1465 break; 1466 case 'U': 1467 flags |= LONGINT; 1468 /*FALLTHROUGH*/ 1469 case 'u': 1470 case 'X': 1471 case 'x': 1472 ADDUARG(); 1473 break; 1474 default: /* "%?" prints ?, unless ? is NUL */ 1475 if (ch == '\0') 1476 goto done; 1477 break; 1478 } 1479 } 1480 done: 1481 /* 1482 * Build the argument table. 1483 */ 1484 if (tablemax >= STATIC_ARG_TBL_SIZE) { 1485 *argtable = (union arg *) 1486 malloc (sizeof (union arg) * (tablemax + 1)); 1487 } 1488 1489 (*argtable) [0].intarg = 0; 1490 for (n = 1; n <= tablemax; n++) { 1491 switch (typetable [n]) { 1492 case T_UNUSED: /* whoops! */ 1493 (*argtable) [n].intarg = va_arg (ap, int); 1494 break; 1495 case TP_SCHAR: 1496 (*argtable) [n].pschararg = va_arg (ap, signed char *); 1497 break; 1498 case TP_SHORT: 1499 (*argtable) [n].pshortarg = va_arg (ap, short *); 1500 break; 1501 case T_INT: 1502 (*argtable) [n].intarg = va_arg (ap, int); 1503 break; 1504 case T_U_INT: 1505 (*argtable) [n].uintarg = va_arg (ap, unsigned int); 1506 break; 1507 case TP_INT: 1508 (*argtable) [n].pintarg = va_arg (ap, int *); 1509 break; 1510 case T_LONG: 1511 (*argtable) [n].longarg = va_arg (ap, long); 1512 break; 1513 case T_U_LONG: 1514 (*argtable) [n].ulongarg = va_arg (ap, unsigned long); 1515 break; 1516 case TP_LONG: 1517 (*argtable) [n].plongarg = va_arg (ap, long *); 1518 break; 1519 case T_LLONG: 1520 (*argtable) [n].longlongarg = va_arg (ap, long long); 1521 break; 1522 case T_U_LLONG: 1523 (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); 1524 break; 1525 case TP_LLONG: 1526 (*argtable) [n].plonglongarg = va_arg (ap, long long *); 1527 break; 1528 case T_PTRDIFFT: 1529 (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); 1530 break; 1531 case TP_PTRDIFFT: 1532 (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); 1533 break; 1534 case T_SIZET: 1535 (*argtable) [n].sizearg = va_arg (ap, size_t); 1536 break; 1537 case TP_SIZET: 1538 (*argtable) [n].psizearg = va_arg (ap, ssize_t *); 1539 break; 1540 case T_INTMAXT: 1541 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); 1542 break; 1543 case T_UINTMAXT: 1544 (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); 1545 break; 1546 case TP_INTMAXT: 1547 (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); 1548 break; 1549 #ifdef FLOATING_POINT 1550 case T_DOUBLE: 1551 (*argtable) [n].doublearg = va_arg (ap, double); 1552 break; 1553 case T_LONG_DOUBLE: 1554 (*argtable) [n].longdoublearg = va_arg (ap, long double); 1555 break; 1556 #endif 1557 case TP_CHAR: 1558 (*argtable) [n].pchararg = va_arg (ap, char *); 1559 break; 1560 case TP_VOID: 1561 (*argtable) [n].pvoidarg = va_arg (ap, void *); 1562 break; 1563 case T_WINT: 1564 (*argtable) [n].wintarg = va_arg (ap, wint_t); 1565 break; 1566 case TP_WCHAR: 1567 (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); 1568 break; 1569 } 1570 } 1571 1572 if ((typetable != NULL) && (typetable != stattypetable)) 1573 free (typetable); 1574 } 1575 1576 /* 1577 * Increase the size of the type table. 1578 */ 1579 static void 1580 __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) 1581 { 1582 enum typeid *const oldtable = *typetable; 1583 const int oldsize = *tablesize; 1584 enum typeid *newtable; 1585 int newsize = oldsize * 2; 1586 1587 if (newsize < nextarg + 1) 1588 newsize = nextarg + 1; 1589 if (oldsize == STATIC_ARG_TBL_SIZE) { 1590 if ((newtable = malloc(newsize)) == NULL) 1591 abort(); /* XXX handle better */ 1592 bcopy(oldtable, newtable, oldsize); 1593 } else { 1594 if ((newtable = reallocf(oldtable, newsize)) == NULL) 1595 abort(); /* XXX handle better */ 1596 } 1597 memset(&newtable[oldsize], T_UNUSED, newsize - oldsize); 1598 1599 *typetable = newtable; 1600 *tablesize = newsize; 1601 } 1602 1603 1604 #ifdef FLOATING_POINT 1605 1606 static int 1607 exponent(char *p0, int exp, int fmtch) 1608 { 1609 char *p, *t; 1610 char expbuf[MAXEXPDIG]; 1611 1612 p = p0; 1613 *p++ = fmtch; 1614 if (exp < 0) { 1615 exp = -exp; 1616 *p++ = '-'; 1617 } 1618 else 1619 *p++ = '+'; 1620 t = expbuf + MAXEXPDIG; 1621 if (exp > 9) { 1622 do { 1623 *--t = to_char(exp % 10); 1624 } while ((exp /= 10) > 9); 1625 *--t = to_char(exp); 1626 for (; t < expbuf + MAXEXPDIG; *p++ = *t++); 1627 } 1628 else { 1629 /* 1630 * Exponents for decimal floating point conversions 1631 * (%[eEgG]) must be at least two characters long, 1632 * whereas exponents for hexadecimal conversions can 1633 * be only one character long. 1634 */ 1635 if (fmtch == 'e' || fmtch == 'E') 1636 *p++ = '0'; 1637 *p++ = to_char(exp); 1638 } 1639 return (p - p0); 1640 } 1641 #endif /* FLOATING_POINT */ 1642