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