vfwprintf.c (124174) | vfwprintf.c (124887) |
---|---|
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.58 2003/04/14 11:24:53 das Exp"); | 42__FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.62 2004/01/18 10:32:49 das Exp"); |
43#endif | 43#endif |
44__FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 124174 2004-01-06 18:26:15Z nectar $"); | 44__FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 124887 2004-01-23 22:48:16Z das $"); |
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 --- 12 unchanged lines hidden (view full) --- 65#include <wchar.h> 66#include <wctype.h> 67#include "un-namespace.h" 68 69#include "libc_private.h" 70#include "local.h" 71#include "fvwrite.h" 72 | 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 --- 12 unchanged lines hidden (view full) --- 65#include <wchar.h> 66#include <wctype.h> 67#include "un-namespace.h" 68 69#include "libc_private.h" 70#include "local.h" 71#include "fvwrite.h" 72 |
73/* Define FLOATING_POINT to get floating point. */ | 73/* Define FLOATING_POINT to get floating point, HEXFLOAT to get %a. */ |
74#define FLOATING_POINT | 74#define FLOATING_POINT |
75#define HEXFLOAT |
|
75 76union arg { 77 int intarg; 78 u_int uintarg; 79 long longarg; 80 u_long ulongarg; 81 long long longlongarg; 82 unsigned long long ulonglongarg; --- 27 unchanged lines hidden (view full) --- 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 wint_t __xfputwc(wchar_t, FILE *); | 76 77union arg { 78 int intarg; 79 u_int uintarg; 80 long longarg; 81 u_long ulongarg; 82 long long longlongarg; 83 unsigned long long ulonglongarg; --- 27 unchanged lines hidden (view full) --- 111 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, 112 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, 113 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, 114 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR 115}; 116 117static int __sbprintf(FILE *, const wchar_t *, va_list); 118static wint_t __xfputwc(wchar_t, FILE *); |
118static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int, | 119static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, |
119 char, const char *); | 120 char, const char *); |
120static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int, | 121static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, |
121 char, const char *); 122static wchar_t *__mbsconv(char *, int); 123static void __find_arguments(const wchar_t *, va_list, union arg **); 124static void __grow_type_table(int, enum typeid **, int *); 125 126/* 127 * Helper function for `fprintf to unbuffered unix file': creates a 128 * temporary buffer. We only work on write-only files; this avoids --- 63 unchanged lines hidden (view full) --- 192 193/* 194 * Convert an unsigned long to ASCII for printf purposes, returning 195 * a pointer to the first character of the string representation. 196 * Octal numbers can be forced to have a leading zero; hex numbers 197 * use the given digits. 198 */ 199static wchar_t * | 122 char, const char *); 123static wchar_t *__mbsconv(char *, int); 124static void __find_arguments(const wchar_t *, va_list, union arg **); 125static void __grow_type_table(int, enum typeid **, int *); 126 127/* 128 * Helper function for `fprintf to unbuffered unix file': creates a 129 * temporary buffer. We only work on write-only files; this avoids --- 63 unchanged lines hidden (view full) --- 193 194/* 195 * Convert an unsigned long to ASCII for printf purposes, returning 196 * a pointer to the first character of the string representation. 197 * Octal numbers can be forced to have a leading zero; hex numbers 198 * use the given digits. 199 */ 200static wchar_t * |
200__ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *xdigs, | 201__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs, |
201 int needgrp, char thousep, const char *grp) 202{ 203 wchar_t *cp = endp; 204 long sval; 205 int ndig; 206 207 /* 208 * Handle the three cases separately, in the hope of getting --- 61 unchanged lines hidden (view full) --- 270 abort(); 271 } 272 return (cp); 273} 274 275/* Identical to __ultoa, but for intmax_t. */ 276static wchar_t * 277__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, | 202 int needgrp, char thousep, const char *grp) 203{ 204 wchar_t *cp = endp; 205 long sval; 206 int ndig; 207 208 /* 209 * Handle the three cases separately, in the hope of getting --- 61 unchanged lines hidden (view full) --- 271 abort(); 272 } 273 return (cp); 274} 275 276/* Identical to __ultoa, but for intmax_t. */ 277static wchar_t * 278__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, |
278 const wchar_t *xdigs, int needgrp, char thousep, const char *grp) | 279 const char *xdigs, int needgrp, char thousep, const char *grp) |
279{ 280 wchar_t *cp = endp; 281 intmax_t sval; 282 int ndig; 283 284 /* quick test for small values; __ultoa is typically much faster */ 285 /* (perhaps instead we should run until small, then call __ultoa?) */ 286 if (val <= ULONG_MAX) --- 236 unchanged lines hidden (view full) --- 523#endif 524 u_long ulval; /* integer arguments %[diouxX] */ 525 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 526 int base; /* base for [diouxX] conversion */ 527 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 528 int realsz; /* field size expanded by dprec, sign, etc */ 529 int size; /* size of converted field or string */ 530 int prsize; /* max size of printed field */ | 280{ 281 wchar_t *cp = endp; 282 intmax_t sval; 283 int ndig; 284 285 /* quick test for small values; __ultoa is typically much faster */ 286 /* (perhaps instead we should run until small, then call __ultoa?) */ 287 if (val <= ULONG_MAX) --- 236 unchanged lines hidden (view full) --- 524#endif 525 u_long ulval; /* integer arguments %[diouxX] */ 526 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ 527 int base; /* base for [diouxX] conversion */ 528 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 529 int realsz; /* field size expanded by dprec, sign, etc */ 530 int size; /* size of converted field or string */ 531 int prsize; /* max size of printed field */ |
531 const wchar_t *xdigs; /* digits for [xX] conversion */ | 532 const char *xdigs; /* digits for [xX] conversion */ |
532 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 533 wchar_t ox[2]; /* space for 0x hex-prefix */ 534 union arg *argtable; /* args, built due to positional arg */ 535 union arg statargtable [STATIC_ARG_TBL_SIZE]; 536 int nextarg; /* 1-based argument index */ 537 va_list orgap; /* original argument pointer */ 538 wchar_t *convbuf; /* multibyte to wide conversion result */ 539 540 /* 541 * Choose PADSIZE to trade efficiency vs. size. If larger printf 542 * fields occur frequently, increase PADSIZE and make the initialisers 543 * below longer. 544 */ 545#define PADSIZE 16 /* pad chunk size */ 546 static wchar_t blanks[PADSIZE] = 547 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 548 static wchar_t zeroes[PADSIZE] = 549 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 550 | 533 wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ 534 wchar_t ox[2]; /* space for 0x hex-prefix */ 535 union arg *argtable; /* args, built due to positional arg */ 536 union arg statargtable [STATIC_ARG_TBL_SIZE]; 537 int nextarg; /* 1-based argument index */ 538 va_list orgap; /* original argument pointer */ 539 wchar_t *convbuf; /* multibyte to wide conversion result */ 540 541 /* 542 * Choose PADSIZE to trade efficiency vs. size. If larger printf 543 * fields occur frequently, increase PADSIZE and make the initialisers 544 * below longer. 545 */ 546#define PADSIZE 16 /* pad chunk size */ 547 static wchar_t blanks[PADSIZE] = 548 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 549 static wchar_t zeroes[PADSIZE] = 550 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 551 |
551 static const wchar_t xdigs_lower[16] = L"0123456789abcdef"; 552 static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF"; | 552 static const char xdigs_lower[16] = "0123456789abcdef"; 553 static const char xdigs_upper[16] = "0123456789ABCDEF"; |
553 554 /* 555 * BEWARE, these `goto error' on error, PRINT uses `n2' and 556 * PAD uses `n'. 557 */ 558#define PRINT(ptr, len) do { \ 559 for (n3 = 0; n3 < (len); n3++) \ 560 __xfputwc((ptr)[n3], fp); \ --- 267 unchanged lines hidden (view full) --- 828 ox[1] = 'x'; 829 xdigs = xdigs_lower; 830 expchar = 'p'; 831 } else { 832 ox[1] = 'X'; 833 xdigs = xdigs_upper; 834 expchar = 'P'; 835 } | 554 555 /* 556 * BEWARE, these `goto error' on error, PRINT uses `n2' and 557 * PAD uses `n'. 558 */ 559#define PRINT(ptr, len) do { \ 560 for (n3 = 0; n3 < (len); n3++) \ 561 __xfputwc((ptr)[n3], fp); \ --- 267 unchanged lines hidden (view full) --- 829 ox[1] = 'x'; 830 xdigs = xdigs_lower; 831 expchar = 'p'; 832 } else { 833 ox[1] = 'X'; 834 xdigs = xdigs_upper; 835 expchar = 'P'; 836 } |
836 /* 837 * XXX We don't actually have a conversion 838 * XXX routine for this yet. 839 */ | 837 if (prec >= 0) 838 prec++; |
840 if (flags & LONGDBL) { | 839 if (flags & LONGDBL) { |
841 fparg.ldbl = (double)GETARG(long double); | 840 fparg.ldbl = GETARG(long double); |
842 dtoaresult = 843 __hldtoa(fparg.ldbl, xdigs, prec, 844 &expt, &signflag, &dtoaend); 845 } else { 846 fparg.dbl = GETARG(double); 847 dtoaresult = 848 __hdtoa(fparg.dbl, xdigs, prec, 849 &expt, &signflag, &dtoaend); 850 } | 841 dtoaresult = 842 __hldtoa(fparg.ldbl, xdigs, prec, 843 &expt, &signflag, &dtoaend); 844 } else { 845 fparg.dbl = GETARG(double); 846 dtoaresult = 847 __hdtoa(fparg.dbl, xdigs, prec, 848 &expt, &signflag, &dtoaend); 849 } |
850 if (prec < 0) 851 prec = dtoaend - dtoaresult; 852 if (expt == INT_MAX) 853 ox[1] = '\0'; |
|
851 if (convbuf != NULL) 852 free(convbuf); | 854 if (convbuf != NULL) 855 free(convbuf); |
856 ndig = dtoaend - dtoaresult; |
|
853 cp = convbuf = __mbsconv(dtoaresult, -1); 854 freedtoa(dtoaresult); | 857 cp = convbuf = __mbsconv(dtoaresult, -1); 858 freedtoa(dtoaresult); |
855 goto fp_begin; 856#endif | 859 goto fp_common; 860#endif /* HEXFLOAT */ |
857 case 'e': 858 case 'E': 859 expchar = ch; 860 if (prec < 0) /* account for digit before decpt */ 861 prec = DEFPREC + 1; 862 else 863 prec++; 864 goto fp_begin; --- 22 unchanged lines hidden (view full) --- 887 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 888 &expt, &signflag, &dtoaend); 889 if (expt == 9999) 890 expt = INT_MAX; 891 } 892 ndig = dtoaend - dtoaresult; 893 cp = convbuf = __mbsconv(dtoaresult, -1); 894 freedtoa(dtoaresult); | 861 case 'e': 862 case 'E': 863 expchar = ch; 864 if (prec < 0) /* account for digit before decpt */ 865 prec = DEFPREC + 1; 866 else 867 prec++; 868 goto fp_begin; --- 22 unchanged lines hidden (view full) --- 891 dtoa(fparg.dbl, expchar ? 2 : 3, prec, 892 &expt, &signflag, &dtoaend); 893 if (expt == 9999) 894 expt = INT_MAX; 895 } 896 ndig = dtoaend - dtoaresult; 897 cp = convbuf = __mbsconv(dtoaresult, -1); 898 freedtoa(dtoaresult); |
899fp_common: |
|
895 if (signflag) 896 sign = '-'; 897 if (expt == INT_MAX) { /* inf or nan */ 898 if (*cp == 'N') { 899 cp = (ch >= 'a') ? L"nan" : L"NAN"; 900 sign = '\0'; 901 } else 902 cp = (ch >= 'a') ? L"inf" : L"INF"; --- 226 unchanged lines hidden (view full) --- 1129 * floating precision; finally, if LADJUST, pad with blanks. 1130 * 1131 * Compute actual size, so we know how much to pad. 1132 * size excludes decimal prec; realsz includes it. 1133 */ 1134 realsz = dprec > size ? dprec : size; 1135 if (sign) 1136 realsz++; | 900 if (signflag) 901 sign = '-'; 902 if (expt == INT_MAX) { /* inf or nan */ 903 if (*cp == 'N') { 904 cp = (ch >= 'a') ? L"nan" : L"NAN"; 905 sign = '\0'; 906 } else 907 cp = (ch >= 'a') ? L"inf" : L"INF"; --- 226 unchanged lines hidden (view full) --- 1134 * floating precision; finally, if LADJUST, pad with blanks. 1135 * 1136 * Compute actual size, so we know how much to pad. 1137 * size excludes decimal prec; realsz includes it. 1138 */ 1139 realsz = dprec > size ? dprec : size; 1140 if (sign) 1141 realsz++; |
1137 else if (ox[1]) | 1142 if (ox[1]) |
1138 realsz += 2; 1139 1140 prsize = width > realsz ? width : realsz; 1141 if ((unsigned)ret + prsize > INT_MAX) { 1142 ret = EOF; 1143 goto error; 1144 } 1145 1146 /* right-adjusting blank padding */ 1147 if ((flags & (LADJUST|ZEROPAD)) == 0) 1148 PAD(width - realsz, blanks); 1149 1150 /* prefix */ | 1143 realsz += 2; 1144 1145 prsize = width > realsz ? width : realsz; 1146 if ((unsigned)ret + prsize > INT_MAX) { 1147 ret = EOF; 1148 goto error; 1149 } 1150 1151 /* right-adjusting blank padding */ 1152 if ((flags & (LADJUST|ZEROPAD)) == 0) 1153 PAD(width - realsz, blanks); 1154 1155 /* prefix */ |
1151 if (sign) { | 1156 if (sign) |
1152 PRINT(&sign, 1); | 1157 PRINT(&sign, 1); |
1153 } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ | 1158 1159 if (ox[1]) { /* ox[1] is either x, X, or \0 */ |
1154 ox[0] = '0'; 1155 PRINT(ox, 2); 1156 } 1157 1158 /* right-adjusting zero padding */ 1159 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1160 PAD(width - realsz, zeroes); 1161 --- 471 unchanged lines hidden --- | 1160 ox[0] = '0'; 1161 PRINT(ox, 2); 1162 } 1163 1164 /* right-adjusting zero padding */ 1165 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 1166 PAD(width - realsz, zeroes); 1167 --- 471 unchanged lines hidden --- |