Deleted Added
full compact
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 */