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