vfwprintf.c (113143) | vfwprintf.c (113199) |
---|---|
1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37#include <sys/cdefs.h> 38#if 0 39#if defined(LIBC_SCCS) && !defined(lint) 40static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; 41#endif /* LIBC_SCCS and not lint */ | 1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37#include <sys/cdefs.h> 38#if 0 39#if defined(LIBC_SCCS) && !defined(lint) 40static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; 41#endif /* LIBC_SCCS and not lint */ |
42__FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.52 2003/03/14 04:48:09 das Exp"); | 42__FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.57 2003/04/07 03:17:39 ache Exp"); |
43#endif | 43#endif |
44__FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 113143 2003-04-05 22:08:53Z das $"); | 44__FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 113199 2003-04-07 06:36:49Z tjr $"); |
45 46/* 47 * Actual wprintf innards. 48 * 49 * Avoid making gratuitous changes to this source file; it should be kept 50 * as close as possible to vfprintf.c for ease of maintenance. 51 */ 52 --- 56 unchanged lines hidden (view full) --- 109 T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, 110 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, 111 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, 112 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, 113 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR 114}; 115 116static int __sbprintf(FILE *, const wchar_t *, va_list); | 45 46/* 47 * Actual wprintf innards. 48 * 49 * Avoid making gratuitous changes to this source file; it should be kept 50 * as close as possible to vfprintf.c for ease of maintenance. 51 */ 52 --- 56 unchanged lines hidden (view full) --- 109 T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, 110 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, 111 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, 112 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, 113 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR 114}; 115 116static int __sbprintf(FILE *, const wchar_t *, va_list); |
117static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, wchar_t *, int, char, 118 const char *); 119static wchar_t *__ultoa(u_long, wchar_t *, int, int, wchar_t *, int, char, 120 const char *); | 117static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int, 118 char, const char *); 119static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int, 120 char, const char *); |
121static wchar_t *__mbsconv(char *, int); 122static void __find_arguments(const wchar_t *, va_list, union arg **); 123static void __grow_type_table(int, enum typeid **, int *); 124 125/* 126 * Helper function for `fprintf to unbuffered unix file': creates a 127 * temporary buffer. We only work on write-only files; this avoids 128 * worries about ungetc buffers and so forth. --- 35 unchanged lines hidden (view full) --- 164 165/* 166 * Convert an unsigned long to ASCII for printf purposes, returning 167 * a pointer to the first character of the string representation. 168 * Octal numbers can be forced to have a leading zero; hex numbers 169 * use the given digits. 170 */ 171static wchar_t * | 121static wchar_t *__mbsconv(char *, int); 122static void __find_arguments(const wchar_t *, va_list, union arg **); 123static void __grow_type_table(int, enum typeid **, int *); 124 125/* 126 * Helper function for `fprintf to unbuffered unix file': creates a 127 * temporary buffer. We only work on write-only files; this avoids 128 * worries about ungetc buffers and so forth. --- 35 unchanged lines hidden (view full) --- 164 165/* 166 * Convert an unsigned long to ASCII for printf purposes, returning 167 * a pointer to the first character of the string representation. 168 * Octal numbers can be forced to have a leading zero; hex numbers 169 * use the given digits. 170 */ 171static wchar_t * |
172__ultoa(u_long val, wchar_t *endp, int base, int octzero, wchar_t *xdigs, | 172__ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *xdigs, |
173 int needgrp, char thousep, const char *grp) 174{ 175 wchar_t *cp = endp; 176 long sval; 177 int ndig; 178 179 /* 180 * Handle the three cases separately, in the hope of getting --- 60 unchanged lines hidden (view full) --- 241 default: /* oops */ 242 abort(); 243 } 244 return (cp); 245} 246 247/* Identical to __ultoa, but for intmax_t. */ 248static wchar_t * | 173 int needgrp, char thousep, const char *grp) 174{ 175 wchar_t *cp = endp; 176 long sval; 177 int ndig; 178 179 /* 180 * Handle the three cases separately, in the hope of getting --- 60 unchanged lines hidden (view full) --- 241 default: /* oops */ 242 abort(); 243 } 244 return (cp); 245} 246 247/* Identical to __ultoa, but for intmax_t. */ 248static wchar_t * |
249__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, wchar_t *xdigs, 250 int needgrp, char thousep, const char *grp) | 249__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, 250 const wchar_t *xdigs, int needgrp, char thousep, const char *grp) |
251{ 252 wchar_t *cp = endp; 253 intmax_t sval; 254 int ndig; 255 256 /* quick test for small values; __ultoa is typically much faster */ 257 /* (perhaps instead we should run until small, then call __ultoa?) */ 258 if (val <= ULONG_MAX) --- 66 unchanged lines hidden (view full) --- 325static wchar_t * 326__mbsconv(char *mbsarg, int prec) 327{ 328 wchar_t *convbuf, *wcp; 329 const char *p; 330 size_t insize, nchars, nconv; 331 mbstate_t mbs; 332 | 251{ 252 wchar_t *cp = endp; 253 intmax_t sval; 254 int ndig; 255 256 /* quick test for small values; __ultoa is typically much faster */ 257 /* (perhaps instead we should run until small, then call __ultoa?) */ 258 if (val <= ULONG_MAX) --- 66 unchanged lines hidden (view full) --- 325static wchar_t * 326__mbsconv(char *mbsarg, int prec) 327{ 328 wchar_t *convbuf, *wcp; 329 const char *p; 330 size_t insize, nchars, nconv; 331 mbstate_t mbs; 332 |
333 if (mbsarg == NULL) 334 return (NULL); 335 |
|
333 /* 334 * Supplied argument is a multibyte string; convert it to wide 335 * characters first. 336 */ 337 if (prec >= 0) { 338 /* 339 * String is not guaranteed to be NUL-terminated. Find the 340 * number of characters to print. --- 54 unchanged lines hidden (view full) --- 395 396 FLOCKFILE(fp); 397 ret = __vfwprintf(fp, fmt0, ap); 398 FUNLOCKFILE(fp); 399 return (ret); 400} 401 402#ifdef FLOATING_POINT | 336 /* 337 * Supplied argument is a multibyte string; convert it to wide 338 * characters first. 339 */ 340 if (prec >= 0) { 341 /* 342 * String is not guaranteed to be NUL-terminated. Find the 343 * number of characters to print. --- 54 unchanged lines hidden (view full) --- 398 399 FLOCKFILE(fp); 400 ret = __vfwprintf(fp, fmt0, ap); 401 FUNLOCKFILE(fp); 402 return (ret); 403} 404 405#ifdef FLOATING_POINT |
406 407#define dtoa __dtoa 408#define freedtoa __freedtoa 409 |
|
403#include <float.h> 404#include <math.h> 405#include "floatio.h" | 410#include <float.h> 411#include <math.h> 412#include "floatio.h" |
413#include "gdtoa.h" |
|
406 407#define DEFPREC 6 408 | 414 415#define DEFPREC 6 416 |
409extern char *__dtoa(double, int, int, int *, int *, char **); 410extern void __freedtoa(char *s); 411 412static wchar_t *cvt(double, int, int, char *, int *, wchar_t, int *); | |
413static int exponent(wchar_t *, int, wchar_t); 414 415#endif /* FLOATING_POINT */ 416 417/* 418 * The size of the buffer we use as scratch space for integer 419 * conversions, among other things. Technically, we would need the 420 * most space for base 10 conversions with thousands' grouping 421 * characters between each pair of digits. 100 bytes is a 422 * conservative overestimate even for a 128-bit uintmax_t. 423 */ 424#define BUF 100 425 426#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ 427 428/* 429 * Flags used during conversion. 430 */ 431#define ALT 0x001 /* alternate form */ | 417static int exponent(wchar_t *, int, wchar_t); 418 419#endif /* FLOATING_POINT */ 420 421/* 422 * The size of the buffer we use as scratch space for integer 423 * conversions, among other things. Technically, we would need the 424 * most space for base 10 conversions with thousands' grouping 425 * characters between each pair of digits. 100 bytes is a 426 * conservative overestimate even for a 128-bit uintmax_t. 427 */ 428#define BUF 100 429 430#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ 431 432/* 433 * Flags used during conversion. 434 */ 435#define ALT 0x001 /* alternate form */ |
432#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ | |
433#define LADJUST 0x004 /* left adjustment */ 434#define LONGDBL 0x008 /* long double */ 435#define LONGINT 0x010 /* long integer */ 436#define LLONGINT 0x020 /* long long integer */ 437#define SHORTINT 0x040 /* short integer */ 438#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 439#define FPT 0x100 /* Floating point number */ 440#define GROUPING 0x200 /* use grouping ("'" flag) */ --- 6 unchanged lines hidden (view full) --- 447/* 448 * Non-MT-safe version 449 */ 450int 451__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 452{ 453 wchar_t *fmt; /* format string */ 454 wchar_t ch; /* character from fmt */ | 436#define LADJUST 0x004 /* left adjustment */ 437#define LONGDBL 0x008 /* long double */ 438#define LONGINT 0x010 /* long integer */ 439#define LLONGINT 0x020 /* long long integer */ 440#define SHORTINT 0x040 /* short integer */ 441#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 442#define FPT 0x100 /* Floating point number */ 443#define GROUPING 0x200 /* use grouping ("'" flag) */ --- 6 unchanged lines hidden (view full) --- 450/* 451 * Non-MT-safe version 452 */ 453int 454__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 455{ 456 wchar_t *fmt; /* format string */ 457 wchar_t ch; /* character from fmt */ |
455 int n, n2; /* handy integer (short term usage) */ | 458 int n, n2, n3; /* handy integer (short term usage) */ |
456 wchar_t *cp; /* handy char pointer (short term usage) */ 457 int flags; /* flags as above */ 458 int ret; /* return value accumulator */ 459 int width; /* width from format (%8d), or 0 */ | 459 wchar_t *cp; /* handy char pointer (short term usage) */ 460 int flags; /* flags as above */ 461 int ret; /* return value accumulator */ 462 int width; /* width from format (%8d), or 0 */ |
460 int prec; /* precision from format (%.3d), or -1 */ | 463 int prec; /* precision from format; <0 for N/A */ |
461 wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ 462 char thousands_sep; /* locale specific thousands separator */ 463 const char *grouping; /* locale specific numeric grouping rules */ 464#ifdef FLOATING_POINT | 464 wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ 465 char thousands_sep; /* locale specific thousands separator */ 466 const char *grouping; /* locale specific numeric grouping rules */ 467#ifdef FLOATING_POINT |
468 /* 469 * We can decompose the printed representation of floating 470 * point numbers into several parts, some of which may be empty: 471 * 472 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ 473 * A B ---C--- D E F 474 * 475 * A: 'sign' holds this value if present; '\0' otherwise 476 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal 477 * C: cp points to the string MMMNNN. Leading and trailing 478 * zeros are not in the string and must be added. 479 * D: expchar holds this character; '\0' if no exponent, e.g. %f 480 * F: at least two digits for decimal, at least one digit for hex 481 */ |
|
465 char *decimal_point; /* locale specific decimal point */ | 482 char *decimal_point; /* locale specific decimal point */ |
466 char softsign; /* temporary negative sign for floats */ 467 double _double; /* double precision arguments %[eEfgG] */ | 483 int signflag; /* true if float is negative */ 484 union { /* floating point arguments %[aAeEfFgG] */ 485 double dbl; 486 long double ldbl; 487 } fparg; |
468 int expt; /* integer value of exponent */ | 488 int expt; /* integer value of exponent */ |
489 char expchar; /* exponent character: [eEpP\0] */ 490 char *dtoaend; /* pointer to end of converted digits */ |
|
469 int expsize; /* character count for expstr */ | 491 int expsize; /* character count for expstr */ |
470 int ndig; /* actual number of digits returned by cvt */ 471 wchar_t expstr[7]; /* buffer for exponent string */ 472 wchar_t *dtoaresult; /* buffer allocated by dtoa */ | 492 int lead; /* sig figs before decimal or group sep */ 493 int ndig; /* actual number of digits returned by dtoa */ 494 wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ 495 char *dtoaresult; /* buffer allocated by dtoa */ 496 int nseps; /* number of group separators with ' */ 497 int nrepeats; /* number of repeats of the last group */ |
473#endif 474 u_long ulval; /* integer arguments %[diouxX] */ 475 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 476 int base; /* base for [diouxX] conversion */ 477 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 478 int realsz; /* field size expanded by dprec, sign, etc */ 479 int size; /* size of converted field or string */ 480 int prsize; /* max size of printed field */ | 498#endif 499 u_long ulval; /* integer arguments %[diouxX] */ 500 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 501 int base; /* base for [diouxX] conversion */ 502 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 503 int realsz; /* field size expanded by dprec, sign, etc */ 504 int size; /* size of converted field or string */ 505 int prsize; /* max size of printed field */ |
481 wchar_t *xdigs; /* digits for [xX] conversion */ | 506 const wchar_t *xdigs; /* digits for [xX] conversion */ |
482 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 483 wchar_t ox[2]; /* space for 0x hex-prefix */ 484 union arg *argtable; /* args, built due to positional arg */ 485 union arg statargtable [STATIC_ARG_TBL_SIZE]; 486 int nextarg; /* 1-based argument index */ 487 va_list orgap; /* original argument pointer */ 488 wchar_t *convbuf; /* multibyte to wide conversion result */ 489 490 /* 491 * Choose PADSIZE to trade efficiency vs. size. If larger printf 492 * fields occur frequently, increase PADSIZE and make the initialisers 493 * below longer. 494 */ 495#define PADSIZE 16 /* pad chunk size */ 496 static wchar_t blanks[PADSIZE] = 497 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 498 static wchar_t zeroes[PADSIZE] = 499 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 500 | 507 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 508 wchar_t ox[2]; /* space for 0x hex-prefix */ 509 union arg *argtable; /* args, built due to positional arg */ 510 union arg statargtable [STATIC_ARG_TBL_SIZE]; 511 int nextarg; /* 1-based argument index */ 512 va_list orgap; /* original argument pointer */ 513 wchar_t *convbuf; /* multibyte to wide conversion result */ 514 515 /* 516 * Choose PADSIZE to trade efficiency vs. size. If larger printf 517 * fields occur frequently, increase PADSIZE and make the initialisers 518 * below longer. 519 */ 520#define PADSIZE 16 /* pad chunk size */ 521 static wchar_t blanks[PADSIZE] = 522 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 523 static wchar_t zeroes[PADSIZE] = 524 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 525 |
526 static const wchar_t xdigs_lower[16] = L"0123456789abcdef"; 527 static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF"; 528 |
|
501 /* 502 * BEWARE, these `goto error' on error, PRINT uses `n2' and 503 * PAD uses `n'. 504 */ 505#define PRINT(ptr, len) do { \ | 529 /* 530 * BEWARE, these `goto error' on error, PRINT uses `n2' and 531 * PAD uses `n'. 532 */ 533#define PRINT(ptr, len) do { \ |
506 for (n2 = 0; n2 < (len); n2++) \ 507 __fputwc((ptr)[n2], fp); \ | 534 for (n3 = 0; n3 < (len); n3++) \ 535 __fputwc((ptr)[n3], fp); \ |
508} while (0) 509#define PAD(howmany, with) do { \ 510 if ((n = (howmany)) > 0) { \ 511 while (n > PADSIZE) { \ 512 PRINT(with, PADSIZE); \ 513 n -= PADSIZE; \ 514 } \ 515 PRINT(with, n); \ 516 } \ 517} while (0) | 536} while (0) 537#define PAD(howmany, with) do { \ 538 if ((n = (howmany)) > 0) { \ 539 while (n > PADSIZE) { \ 540 PRINT(with, PADSIZE); \ 541 n -= PADSIZE; \ 542 } \ 543 PRINT(with, n); \ 544 } \ 545} while (0) |
546#define PRINTANDPAD(p, ep, len, with) do { \ 547 n2 = (ep) - (p); \ 548 if (n2 > (len)) \ 549 n2 = (len); \ 550 if (n2 > 0) \ 551 PRINT((p), n2); \ 552 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ 553} while(0) |
|
518 519 /* 520 * Get the argument indexed by nextarg. If the argument table is 521 * built, use it to get the argument. If its not, get the next 522 * argument (and arguments must be gotten sequentially). 523 */ 524#define GETARG(type) \ 525 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ --- 49 unchanged lines hidden (view full) --- 575 } else { \ 576 val = GETARG (int); \ 577 } 578 579 580 thousands_sep = '\0'; 581 grouping = NULL; 582#ifdef FLOATING_POINT | 554 555 /* 556 * Get the argument indexed by nextarg. If the argument table is 557 * built, use it to get the argument. If its not, get the next 558 * argument (and arguments must be gotten sequentially). 559 */ 560#define GETARG(type) \ 561 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ --- 49 unchanged lines hidden (view full) --- 611 } else { \ 612 val = GETARG (int); \ 613 } 614 615 616 thousands_sep = '\0'; 617 grouping = NULL; 618#ifdef FLOATING_POINT |
583 dtoaresult = NULL; | |
584 decimal_point = localeconv()->decimal_point; 585#endif 586 convbuf = NULL; 587 /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ 588 if (cantwrite(fp)) 589 return (EOF); 590 591 /* optimise fprintf(stderr) (and other unbuffered Unix files) */ --- 25 unchanged lines hidden (view full) --- 617 goto done; 618 fmt++; /* skip over '%' */ 619 620 flags = 0; 621 dprec = 0; 622 width = 0; 623 prec = -1; 624 sign = '\0'; | 619 decimal_point = localeconv()->decimal_point; 620#endif 621 convbuf = NULL; 622 /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ 623 if (cantwrite(fp)) 624 return (EOF); 625 626 /* optimise fprintf(stderr) (and other unbuffered Unix files) */ --- 25 unchanged lines hidden (view full) --- 652 goto done; 653 fmt++; /* skip over '%' */ 654 655 flags = 0; 656 dprec = 0; 657 width = 0; 658 prec = -1; 659 sign = '\0'; |
660 ox[1] = '\0'; |
|
625 626rflag: ch = *fmt++; 627reswitch: switch (ch) { 628 case ' ': 629 /*- 630 * ``If the space and + flags both appear, the space 631 * flag will be ignored.'' 632 * -- ANSI X3J11 --- 24 unchanged lines hidden (view full) --- 657 goto rflag; 658 case '\'': 659 flags |= GROUPING; 660 thousands_sep = *(localeconv()->thousands_sep); 661 grouping = localeconv()->grouping; 662 goto rflag; 663 case '.': 664 if ((ch = *fmt++) == '*') { | 661 662rflag: ch = *fmt++; 663reswitch: switch (ch) { 664 case ' ': 665 /*- 666 * ``If the space and + flags both appear, the space 667 * flag will be ignored.'' 668 * -- ANSI X3J11 --- 24 unchanged lines hidden (view full) --- 693 goto rflag; 694 case '\'': 695 flags |= GROUPING; 696 thousands_sep = *(localeconv()->thousands_sep); 697 grouping = localeconv()->grouping; 698 goto rflag; 699 case '.': 700 if ((ch = *fmt++) == '*') { |
665 GETASTER (n); 666 prec = n < 0 ? -1 : n; | 701 GETASTER (prec); |
667 goto rflag; 668 } | 702 goto rflag; 703 } |
669 n = 0; | 704 prec = 0; |
670 while (is_digit(ch)) { | 705 while (is_digit(ch)) { |
671 n = 10 * n + to_digit(ch); | 706 prec = 10 * prec + to_digit(ch); |
672 ch = *fmt++; 673 } | 707 ch = *fmt++; 708 } |
674 prec = n < 0 ? -1 : n; | |
675 goto reswitch; 676 case '0': 677 /*- 678 * ``Note that 0 is taken as a flag, not as the 679 * beginning of a field width.'' 680 * -- ANSI X3J11 681 */ 682 flags |= ZEROPAD; --- 77 unchanged lines hidden (view full) --- 760 } 761 } 762 base = 10; 763 goto number; 764#ifdef FLOATING_POINT 765#ifdef HEXFLOAT 766 case 'a': 767 case 'A': | 709 goto reswitch; 710 case '0': 711 /*- 712 * ``Note that 0 is taken as a flag, not as the 713 * beginning of a field width.'' 714 * -- ANSI X3J11 715 */ 716 flags |= ZEROPAD; --- 77 unchanged lines hidden (view full) --- 794 } 795 } 796 base = 10; 797 goto number; 798#ifdef FLOATING_POINT 799#ifdef HEXFLOAT 800 case 'a': 801 case 'A': |
802 if (ch == 'a') { 803 ox[1] = 'x'; 804 xdigs = xdigs_lower; 805 expchar = 'p'; 806 } else { 807 ox[1] = 'X'; 808 xdigs = xdigs_upper; 809 expchar = 'P'; 810 } 811 /* 812 * XXX We don't actually have a conversion 813 * XXX routine for this yet. 814 */ 815 if (flags & LONGDBL) { 816 fparg.ldbl = (double)GETARG(long double); 817 dtoaresult = 818 __hldtoa(fparg.ldbl, xdigs, prec, 819 &expt, &signflag, &dtoaend); 820 } else { 821 fparg.dbl = GETARG(double); 822 dtoaresult = 823 __hdtoa(fparg.dbl, xdigs, prec, 824 &expt, &signflag, &dtoaend); 825 } 826 if (convbuf != NULL) 827 free(convbuf); 828 cp = convbuf = __mbsconv(dtoaresult, -1); 829 freedtoa(dtoaresult); 830 goto fp_begin; |
|
768#endif 769 case 'e': 770 case 'E': | 831#endif 832 case 'e': 833 case 'E': |
771 /*- 772 * Grouping apply to %i, %d, %u, %f, %F, %g, %G 773 * conversion specifiers only. For other conversions 774 * behavior is undefined. 775 * -- POSIX 776 */ 777 flags &= ~GROUPING; 778 /*FALLTHROUGH*/ | 834 expchar = ch; 835 if (prec < 0) /* account for digit before decpt */ 836 prec = DEFPREC + 1; 837 else 838 prec++; 839 goto fp_begin; |
779 case 'f': 780 case 'F': | 840 case 'f': 841 case 'F': |
842 expchar = '\0'; |
|
781 goto fp_begin; 782 case 'g': 783 case 'G': | 843 goto fp_begin; 844 case 'g': 845 case 'G': |
846 expchar = ch - ('g' - 'e'); |
|
784 if (prec == 0) 785 prec = 1; | 847 if (prec == 0) 848 prec = 1; |
786fp_begin: if (prec == -1) | 849fp_begin: 850 if (prec < 0) |
787 prec = DEFPREC; | 851 prec = DEFPREC; |
788 if (flags & LONGDBL) 789 /* XXX this loses precision. */ 790 _double = (double)GETARG(long double); 791 else 792 _double = GETARG(double); 793 /* do this before tricky precision changes */ 794 if (isinf(_double)) { 795 if (_double < 0) 796 sign = '-'; 797 if (iswupper(ch)) 798 cp = L"INF"; 799 else 800 cp = L"inf"; 801 size = 3; 802 break; | 852 if (convbuf != NULL) 853 free(convbuf); 854 if (flags & LONGDBL) { 855 fparg.ldbl = GETARG(long double); 856 dtoaresult = 857 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, 858 &expt, &signflag, &dtoaend); 859 } else { 860 fparg.dbl = GETARG(double); 861 dtoaresult = 862 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 863 &expt, &signflag, &dtoaend); 864 if (expt == 9999) 865 expt = INT_MAX; |
803 } | 866 } |
804 if (isnan(_double)) { 805 if (iswupper(ch)) 806 cp = L"NAN"; 807 else 808 cp = L"nan"; | 867 ndig = dtoaend - dtoaresult; 868 cp = convbuf = __mbsconv(dtoaresult, -1); 869 freedtoa(dtoaresult); 870 if (signflag) 871 sign = '-'; 872 if (expt == INT_MAX) { /* inf or nan */ 873 if (*cp == 'N') { 874 cp = (ch >= 'a') ? L"nan" : L"NAN"; 875 sign = '\0'; 876 } else 877 cp = (ch >= 'a') ? L"inf" : L"INF"; |
809 size = 3; 810 break; 811 } 812 flags |= FPT; | 878 size = 3; 879 break; 880 } 881 flags |= FPT; |
813 if (dtoaresult != NULL) { 814 free(dtoaresult); 815 dtoaresult = NULL; 816 } 817 dtoaresult = cp = cvt(_double, prec, flags, &softsign, 818 &expt, ch, &ndig); | |
819 if (ch == 'g' || ch == 'G') { | 882 if (ch == 'g' || ch == 'G') { |
820 if (expt <= -4 || expt > prec) 821 ch = (ch == 'g') ? 'e' : 'E'; 822 else 823 ch = 'g'; | 883 if (expt > -4 && expt <= prec) { 884 /* Make %[gG] smell like %[fF] */ 885 expchar = '\0'; 886 if (flags & ALT) 887 prec -= expt; 888 else 889 prec = ndig - expt; 890 if (prec < 0) 891 prec = 0; 892 } |
824 } | 893 } |
825 if (ch == 'e' || ch == 'E') { 826 --expt; 827 expsize = exponent(expstr, expt, ch); 828 size = expsize + ndig; 829 if (ndig > 1 || flags & ALT) | 894 if (expchar) { 895 expsize = exponent(expstr, expt - 1, expchar); 896 size = expsize + prec; 897 if (prec > 1 || flags & ALT) |
830 ++size; | 898 ++size; |
831 } else if (ch == 'f' || ch == 'F') { | 899 } else { |
832 if (expt > 0) { 833 size = expt; 834 if (prec || flags & ALT) 835 size += prec + 1; 836 } else /* "0.X" */ 837 size = prec + 2; | 900 if (expt > 0) { 901 size = expt; 902 if (prec || flags & ALT) 903 size += prec + 1; 904 } else /* "0.X" */ 905 size = prec + 2; |
838 } else if (expt >= ndig) { /* fixed g fmt */ 839 size = expt; 840 if (flags & ALT) 841 ++size; 842 } else 843 size = ndig + (expt > 0 ? 844 1 : 2 - expt); 845 846 if (softsign) 847 sign = '-'; | 906 if (grouping && expt > 0) { 907 /* space for thousands' grouping */ 908 nseps = nrepeats = 0; 909 lead = expt; 910 while (*grouping != CHAR_MAX) { 911 if (lead <= *grouping) 912 break; 913 lead -= *grouping; 914 if (*(grouping+1)) { 915 nseps++; 916 grouping++; 917 } else 918 nrepeats++; 919 } 920 size += nseps + nrepeats; 921 } else 922 lead = expt; 923 } |
848 break; 849#endif /* FLOATING_POINT */ 850 case 'n': 851 /* 852 * Assignment-like behavior is specified if the 853 * value overflows or is otherwise unrepresentable. 854 * C99 says to use `signed char' for %hhn conversions. 855 */ --- 29 unchanged lines hidden (view full) --- 885 * ``The argument shall be a pointer to void. The 886 * value of the pointer is converted to a sequence 887 * of printable characters, in an implementation- 888 * defined manner.'' 889 * -- ANSI X3J11 890 */ 891 ujval = (uintmax_t)(uintptr_t)GETARG(void *); 892 base = 16; | 924 break; 925#endif /* FLOATING_POINT */ 926 case 'n': 927 /* 928 * Assignment-like behavior is specified if the 929 * value overflows or is otherwise unrepresentable. 930 * C99 says to use `signed char' for %hhn conversions. 931 */ --- 29 unchanged lines hidden (view full) --- 961 * ``The argument shall be a pointer to void. The 962 * value of the pointer is converted to a sequence 963 * of printable characters, in an implementation- 964 * defined manner.'' 965 * -- ANSI X3J11 966 */ 967 ujval = (uintmax_t)(uintptr_t)GETARG(void *); 968 base = 16; |
893 xdigs = L"0123456789abcdef"; 894 flags = flags | INTMAXT | HEXPREFIX; 895 ch = 'x'; | 969 xdigs = xdigs_lower; 970 flags = flags | INTMAXT; 971 ox[1] = 'x'; |
896 goto nosign; 897 case 'S': 898 flags |= LONGINT; 899 /*FALLTHROUGH*/ 900 case 's': 901 if (flags & LONGINT) { 902 if ((cp = GETARG(wchar_t *)) == NULL) 903 cp = L"(null)"; --- 38 unchanged lines hidden (view full) --- 942 case 'u': 943 if (flags & INTMAX_SIZE) 944 ujval = UJARG(); 945 else 946 ulval = UARG(); 947 base = 10; 948 goto nosign; 949 case 'X': | 972 goto nosign; 973 case 'S': 974 flags |= LONGINT; 975 /*FALLTHROUGH*/ 976 case 's': 977 if (flags & LONGINT) { 978 if ((cp = GETARG(wchar_t *)) == NULL) 979 cp = L"(null)"; --- 38 unchanged lines hidden (view full) --- 1018 case 'u': 1019 if (flags & INTMAX_SIZE) 1020 ujval = UJARG(); 1021 else 1022 ulval = UARG(); 1023 base = 10; 1024 goto nosign; 1025 case 'X': |
950 xdigs = L"0123456789ABCDEF"; | 1026 xdigs = xdigs_upper; |
951 goto hex; 952 case 'x': | 1027 goto hex; 1028 case 'x': |
953 xdigs = L"0123456789abcdef"; | 1029 xdigs = xdigs_lower; |
954hex: 955 if (flags & INTMAX_SIZE) 956 ujval = UJARG(); 957 else 958 ulval = UARG(); 959 base = 16; 960 /* leading 0x/X only if non-zero */ 961 if (flags & ALT && 962 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) | 1030hex: 1031 if (flags & INTMAX_SIZE) 1032 ujval = UJARG(); 1033 else 1034 ulval = UARG(); 1035 base = 16; 1036 /* leading 0x/X only if non-zero */ 1037 if (flags & ALT && 1038 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) |
963 flags |= HEXPREFIX; | 1039 ox[1] = ch; |
964 965 flags &= ~GROUPING; 966 /* unsigned conversions */ 967nosign: sign = '\0'; 968 /*- 969 * ``... diouXx conversions ... if a precision is 970 * specified, the 0 flag will be ignored.'' 971 * -- ANSI X3J11 --- 47 unchanged lines hidden (view full) --- 1019 * floating precision; finally, if LADJUST, pad with blanks. 1020 * 1021 * Compute actual size, so we know how much to pad. 1022 * size excludes decimal prec; realsz includes it. 1023 */ 1024 realsz = dprec > size ? dprec : size; 1025 if (sign) 1026 realsz++; | 1040 1041 flags &= ~GROUPING; 1042 /* unsigned conversions */ 1043nosign: sign = '\0'; 1044 /*- 1045 * ``... diouXx conversions ... if a precision is 1046 * specified, the 0 flag will be ignored.'' 1047 * -- ANSI X3J11 --- 47 unchanged lines hidden (view full) --- 1095 * floating precision; finally, if LADJUST, pad with blanks. 1096 * 1097 * Compute actual size, so we know how much to pad. 1098 * size excludes decimal prec; realsz includes it. 1099 */ 1100 realsz = dprec > size ? dprec : size; 1101 if (sign) 1102 realsz++; |
1027 else if (flags & HEXPREFIX) | 1103 else if (ox[1]) |
1028 realsz += 2; 1029 1030 prsize = width > realsz ? width : realsz; 1031 if ((unsigned)ret + prsize > INT_MAX) { 1032 ret = EOF; 1033 goto error; 1034 } 1035 1036 /* right-adjusting blank padding */ 1037 if ((flags & (LADJUST|ZEROPAD)) == 0) 1038 PAD(width - realsz, blanks); 1039 1040 /* prefix */ 1041 if (sign) { 1042 PRINT(&sign, 1); | 1104 realsz += 2; 1105 1106 prsize = width > realsz ? width : realsz; 1107 if ((unsigned)ret + prsize > INT_MAX) { 1108 ret = EOF; 1109 goto error; 1110 } 1111 1112 /* right-adjusting blank padding */ 1113 if ((flags & (LADJUST|ZEROPAD)) == 0) 1114 PAD(width - realsz, blanks); 1115 1116 /* prefix */ 1117 if (sign) { 1118 PRINT(&sign, 1); |
1043 } else if (flags & HEXPREFIX) { | 1119 } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ |
1044 ox[0] = '0'; | 1120 ox[0] = '0'; |
1045 ox[1] = ch; | |
1046 PRINT(ox, 2); 1047 } 1048 1049 /* right-adjusting zero padding */ 1050 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1051 PAD(width - realsz, zeroes); 1052 1053 /* leading zeroes from decimal precision */ 1054 PAD(dprec - size, zeroes); 1055 1056 /* the string or number proper */ 1057#ifdef FLOATING_POINT 1058 if ((flags & FPT) == 0) { 1059 PRINT(cp, size); 1060 } else { /* glue together f_p fragments */ | 1121 PRINT(ox, 2); 1122 } 1123 1124 /* right-adjusting zero padding */ 1125 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1126 PAD(width - realsz, zeroes); 1127 1128 /* leading zeroes from decimal precision */ 1129 PAD(dprec - size, zeroes); 1130 1131 /* the string or number proper */ 1132#ifdef FLOATING_POINT 1133 if ((flags & FPT) == 0) { 1134 PRINT(cp, size); 1135 } else { /* glue together f_p fragments */ |
1061 if (ch >= 'f') { /* 'f' or 'g' */ 1062 if (_double == 0) { 1063 /* kludge for __dtoa irregularity */ 1064 PRINT(L"0", 1); 1065 if (expt < ndig || (flags & ALT) != 0) { 1066 PRINT(decimal_point, 1); 1067 PAD(ndig - 1, zeroes); 1068 } 1069 } else if (expt <= 0) { 1070 PRINT(L"0", 1); 1071 PRINT(decimal_point, 1); | 1136 if (!expchar) { /* %[fF] or sufficiently short %[gG] */ 1137 if (expt <= 0) { 1138 buf[0] = '0'; 1139 buf[1] = *decimal_point; 1140 PRINT(buf, 2); |
1072 PAD(-expt, zeroes); | 1141 PAD(-expt, zeroes); |
1073 PRINT(cp, ndig); 1074 } else if (expt >= ndig) { 1075 PRINT(cp, ndig); 1076 PAD(expt - ndig, zeroes); 1077 if (flags & ALT) 1078 PRINT(decimal_point, 1); | 1142 /* already handled initial 0's */ 1143 prec += expt; |
1079 } else { | 1144 } else { |
1080 PRINT(cp, expt); 1081 cp += expt; 1082 PRINT(decimal_point, 1); 1083 PRINT(cp, ndig-expt); | 1145 PRINTANDPAD(cp, convbuf + ndig, lead, zeroes); 1146 cp += lead; 1147 if (grouping) { 1148 while (nseps>0 || nrepeats>0) { 1149 if (nrepeats > 0) 1150 nrepeats--; 1151 else { 1152 grouping--; 1153 nseps--; 1154 } 1155 PRINT(&thousands_sep, 1156 1); 1157 PRINTANDPAD(cp, 1158 convbuf + ndig, 1159 *grouping, zeroes); 1160 cp += *grouping; 1161 } 1162 if (cp > convbuf + ndig) 1163 cp = convbuf + ndig; 1164 } 1165 if (prec || flags & ALT) { 1166 buf[0] = *decimal_point; 1167 PRINT(buf, 1); 1168 } |
1084 } | 1169 } |
1085 } else { /* 'e' or 'E' */ 1086 if (ndig > 1 || flags & ALT) { 1087 ox[0] = *cp++; 1088 ox[1] = *decimal_point; 1089 PRINT(ox, 2); 1090 if (_double) { 1091 PRINT(cp, ndig-1); 1092 } else /* 0.[0..] */ 1093 /* __dtoa irregularity */ 1094 PAD(ndig - 1, zeroes); | 1170 PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); 1171 } else { /* %[eE] or sufficiently long %[gG] */ 1172 if (prec > 1 || flags & ALT) { 1173 buf[0] = *cp++; 1174 buf[1] = *decimal_point; 1175 PRINT(buf, 2); 1176 PRINT(cp, ndig-1); 1177 PAD(prec - ndig, zeroes); |
1095 } else /* XeYYY */ 1096 PRINT(cp, 1); 1097 PRINT(expstr, expsize); 1098 } 1099 } 1100#else 1101 PRINT(cp, size); 1102#endif 1103 /* left-adjusting padding (always blank) */ 1104 if (flags & LADJUST) 1105 PAD(width - realsz, blanks); 1106 1107 /* finally, adjust ret */ 1108 ret += prsize; 1109 } 1110done: 1111error: | 1178 } else /* XeYYY */ 1179 PRINT(cp, 1); 1180 PRINT(expstr, expsize); 1181 } 1182 } 1183#else 1184 PRINT(cp, size); 1185#endif 1186 /* left-adjusting padding (always blank) */ 1187 if (flags & LADJUST) 1188 PAD(width - realsz, blanks); 1189 1190 /* finally, adjust ret */ 1191 ret += prsize; 1192 } 1193done: 1194error: |
1112#ifdef FLOATING_POINT 1113 if (dtoaresult != NULL) 1114 free(dtoaresult); 1115#endif | |
1116 if (convbuf != NULL) 1117 free(convbuf); 1118 if (__sferror(fp)) 1119 ret = EOF; 1120 if ((argtable != NULL) && (argtable != statargtable)) 1121 free (argtable); 1122 return (ret); 1123 /* NOTREACHED */ --- 352 unchanged lines hidden (view full) --- 1476 1477 *typetable = newtable; 1478 *tablesize = newsize; 1479} 1480 1481 1482#ifdef FLOATING_POINT 1483 | 1195 if (convbuf != NULL) 1196 free(convbuf); 1197 if (__sferror(fp)) 1198 ret = EOF; 1199 if ((argtable != NULL) && (argtable != statargtable)) 1200 free (argtable); 1201 return (ret); 1202 /* NOTREACHED */ --- 352 unchanged lines hidden (view full) --- 1555 1556 *typetable = newtable; 1557 *tablesize = newsize; 1558} 1559 1560 1561#ifdef FLOATING_POINT 1562 |
1484static wchar_t * 1485cvt(double value, int ndigits, int flags, char *sign, int *decpt, 1486 wchar_t ch, int *length) 1487{ 1488 int i, mode, dsgn; 1489 wchar_t *digits, *bp, *result, *rve; 1490 char *tresult, *trve; 1491 1492 if (ch == 'f') 1493 mode = 3; /* ndigits after the decimal point */ 1494 else { 1495 /* 1496 * To obtain ndigits after the decimal point for the 'e' 1497 * and 'E' formats, round to ndigits + 1 significant 1498 * figures. 1499 */ 1500 if (ch == 'e' || ch == 'E') 1501 ndigits++; 1502 mode = 2; /* ndigits significant digits */ 1503 } 1504 tresult = __dtoa(value, mode, ndigits, decpt, &dsgn, &trve); 1505 if ((result = malloc((trve - tresult + 1) * sizeof(*result))) == NULL) 1506 abort(); /* XXX handle better */ 1507 for (i = 0; i < trve - tresult + 1; i++) 1508 result[i] = (wchar_t)(unsigned char)tresult[i]; 1509 rve = result + (trve - tresult); 1510 __freedtoa(tresult); 1511 digits = result; 1512 *sign = dsgn != 0; 1513 if ((ch != 'g' && ch != 'G') || flags & ALT) { 1514 /* print trailing zeros */ 1515 bp = digits + ndigits; 1516 if (ch == 'f') { 1517 if ((*digits == '0' || *digits == '\0') && value) 1518 *decpt = -ndigits + 1; 1519 bp += *decpt; 1520 } 1521 if (value == 0) /* kludge for __dtoa irregularity */ 1522 rve = bp; 1523 while (rve < bp) 1524 *rve++ = '0'; 1525 } 1526 *length = rve - digits; 1527 return (digits); 1528} 1529 | |
1530static int 1531exponent(wchar_t *p0, int exp, wchar_t fmtch) 1532{ 1533 wchar_t *p, *t; 1534 wchar_t expbuf[MAXEXPDIG]; 1535 1536 p = p0; 1537 *p++ = fmtch; --- 7 unchanged lines hidden (view full) --- 1545 if (exp > 9) { 1546 do { 1547 *--t = to_char(exp % 10); 1548 } while ((exp /= 10) > 9); 1549 *--t = to_char(exp); 1550 for (; t < expbuf + MAXEXPDIG; *p++ = *t++); 1551 } 1552 else { | 1563static int 1564exponent(wchar_t *p0, int exp, wchar_t fmtch) 1565{ 1566 wchar_t *p, *t; 1567 wchar_t expbuf[MAXEXPDIG]; 1568 1569 p = p0; 1570 *p++ = fmtch; --- 7 unchanged lines hidden (view full) --- 1578 if (exp > 9) { 1579 do { 1580 *--t = to_char(exp % 10); 1581 } while ((exp /= 10) > 9); 1582 *--t = to_char(exp); 1583 for (; t < expbuf + MAXEXPDIG; *p++ = *t++); 1584 } 1585 else { |
1553 *p++ = '0'; | 1586 /* 1587 * Exponents for decimal floating point conversions 1588 * (%[eEgG]) must be at least two characters long, 1589 * whereas exponents for hexadecimal conversions can 1590 * be only one character long. 1591 */ 1592 if (fmtch == 'e' || fmtch == 'E') 1593 *p++ = '0'; |
1554 *p++ = to_char(exp); 1555 } 1556 return (p - p0); 1557} 1558#endif /* FLOATING_POINT */ | 1594 *p++ = to_char(exp); 1595 } 1596 return (p - p0); 1597} 1598#endif /* FLOATING_POINT */ |