1 /****************************************************************
2 Copyright (C) 1997, 1999, 2001 Lucent Technologies
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name of Lucent or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23 ****************************************************************/
25 /* This implements most of ANSI C's printf, fprintf, and sprintf,
26 * omitting L, with %.0g and %.0G giving the shortest decimal string
27 * that rounds to the number being converted, and with negative
28 * precisions allowed for %f.
39 #ifdef Use_GDTOA_for_i386_long_double /*{{*/
42 #ifndef NO_PRINTF_A_FMT /*{*/
48 #define NO_GDTOA_i386_Quad
51 #ifdef Use_GDTOA_for_i386_long_double /*{*/
52 #ifndef NO_GDTOA_i386_Quad /*{*/
54 #define Use_GDTOA_Qtype
55 #ifdef __ICC__ /* or __INTEL_COMPILER__ or __INTEL_COMPILER ?? */
56 #define GDTOA_Qtype _Quad
58 #define GDTOA_Qtype __float128
60 #endif /*} NO_GDTOA_i386_Quad */
61 #endif /*} Use_GDTOA_for_i386_long_double */
63 #ifdef Use_GDTOA_Qtype /*{*/
64 #ifndef GDTOA_H_INCLUDED
68 #define GDTOA_Qtype long double
72 #ifndef GDTOA_H_INCLUDED /*{*/
74 enum { /* return values from strtodg */
93 enum { /* FPI.rounding values: same as FLT_ROUNDS */
101 #ifdef NO_PRINTF_A_FMT /*{{*/
102 #define WANT_A_FMT(x) /*nothing*/
104 #define WANT_A_FMT(x) x
113 union { FILE *cf; char *sf; } u;
118 typedef char *(*pgdtoa) ANSI((FPI*, int be, ULong *bits, int *kind, int mode, int ndigits, int *decpt, char **rve));
122 ULong bits[4]; /* sufficient for quad; modify if considering wider types */
126 int ex; /* exponent */
138 unsigned short us[5];
141 typedef char *(*Putfunc) ANSI((Finfo*, int*));
142 typedef void (*Fpbits) ANSI((U*, FPBits*));
144 /* Would have preferred typedef void (*Fpbits)(va_list*, FPBits*)
145 * but gcc is buggy in this regard.
148 #ifdef Use_GDTOA_for_i386_long_double /*{*/
166 xfpbits(U *u, FPBits *b)
170 static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
174 b->sign = u->us[_0] & 0x8000;
176 bits[1] = (u->us[_1] << 16) | u->us[_2];
177 bits[0] = (u->us[_3] << 16) | u->us[_4];
178 if ( (ex = u->us[_0] & 0x7fff) !=0) {
181 /* Infinity or NaN */
182 i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
184 else if (bits[0] | bits[1]) {
191 b->ex = ex - (0x3fff + 63);
199 #define GDTOA_LD_fpbits xfpbits
200 #endif /*} Use_GDTOA_for_i386_long_double */
202 #ifdef Use_GDTOA_Qtype /*{*/
205 #define GDTOA_Qtype long double
207 #ifdef GDTOA_LD_fpbits
208 #define GDTOA_Q_fpbits Qfpbits
210 #define GDTOA_LD_fpbits Qfpbits
227 Qfpbits(U *u, FPBits *b)
231 static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
235 b->sign = u->ui[_0] & 0x80000000L;
237 bits[3] = u->ui[_0] & 0xffff;
241 if ( (ex = (u->ui[_0] & 0x7fff0000L) >> 16) !=0) {
243 /* Infinity or NaN */
244 i = bits[0] | bits[1] | bits[2] | bits[3]
245 ? STRTOG_NaN : STRTOG_Infinite;
252 else if (bits[0] | bits[1] | bits[2] | bits[3]) {
259 b->ex = ex - (0x3fff + 112);
266 #endif /*} GDTOA_Qtype */
269 #define Const /* const */
270 #define Voidptr char*
279 #define Voidptr void*
285 #define Stderr stderr
292 #define stdout_or_err(f) (f == stdout)
294 #define stdout_or_err(f) (f == Stderr || f == stdout)
301 extern char *dtoa ANSI((double, int, int, int*, int*, char **));
302 extern void freedtoa ANSI((char*));
307 /* This is for avoiding 64-bit divisions on the DEC Alpha, since */
308 /* they are not portable among variants of OSF1 (DEC's Unix). */
310 #define ULDIV(a,b) uldiv_ASL(a,(unsigned long)(b))
316 #define ULONG unsigned long
325 for(k = 1 << LLBITS-1;;) {
326 if (x >= (1L << k)) {
337 uldiv_ASL(ULONG a, ULONG b)
351 if ((ka = klog(a) - kb) > 0) {
369 #define ULDIV(a,b) a / b
370 #endif /* USE_ULDIV */
373 FILE *stderr_ASL = (FILE*)&stderr_ASL;
374 void (*pfbuf_print_ASL) ANSI((char*));
376 static char *pfbuf_next;
377 static size_t pfbuf_len;
378 extern Char *mymalloc_ASL ANSI((size_t));
379 extern Char *myralloc_ASL ANSI((void *, size_t));
382 #ifdef old_fflush_ASL
383 #define fflush old_fflush_ASL
389 if (f == stderr_ASL) {
390 if (pfbuf_ASL && pfbuf_print_ASL) {
391 (*pfbuf_print_ASL)(pfbuf_ASL);
401 pf_put(char *buf, int len)
408 pfbuf_ASL = pfbuf_next = (char*)mymalloc_ASL(pfbuf_len = x);
410 else if ((y = (pfbuf_next - pfbuf_ASL) + len) >= pfbuf_len) {
412 while((x <<= 1) <= y);
413 y = pfbuf_next - pfbuf_ASL;
414 pfbuf_ASL = (char*)myralloc_ASL(pfbuf_ASL, x);
415 pfbuf_next = pfbuf_ASL + y;
418 memcpy(pfbuf_next, buf, len);
424 pfput(Finfo *f, int *rvp)
428 *rvp += n = (int)(f->obe1 - ob0);
437 (f, rvp) Finfo *f; int *rvp;
444 *rvp += f->obe1 - ob0;
452 int stdout_fileno_ASL = 1;
457 (f, rvp) Finfo *f; int *rvp;
464 *rvp += f->obe1 - ob0;
466 mwrite(ob0, f->obe1 - ob0);
482 dfpbits(U *u, FPBits *b)
486 static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
490 b->sign = u->ui[_0] & 0x80000000L;
492 bits[1] = u->ui[_0] & 0xfffff;
494 if ( (ex = (u->ui[_0] & 0x7ff00000L) >> 20) !=0) {
496 /* Infinity or NaN */
497 i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
504 else if (bits[0] | bits[1]) {
511 b->ex = ex - (0x3ff + 52);
517 #ifdef Honor_FLT_ROUNDS /*{{*/
518 #ifdef Trust_FLT_ROUNDS /*{{*/
519 #define RoundCheck if (Rounding == -1) Rounding = Flt_Rounds; if (Rounding != 1){\
520 fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
522 #define RoundCheck if (Rounding == -1) { Rounding = 1; switch((fegetround()) {\
523 case FE_TOWARDZERO: Rounding = 0; break;\
524 case FE_UPWARD: Rounding = 2; break;\
525 case FE_DOWNWARD: Rounding = 3; }}\
527 fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
530 #define RoundCheck /*nothing*/
533 #ifndef NO_PRINTF_A_FMT /*{*/
535 fpiprec(FPBits *b) /* return number of hex digits minus 1, or 0 for zero */
541 if (b->kind == STRTOG_Zero)
545 for(k = (fpi->nbits - 1) >> 2; k > 0; --k)
546 if ((bits[k >> 3] >> 4*(k & 7)) & 0xf) {
548 for(i = 0; i <= m; ++i)
553 for(j = i; j <= m; ++j)
558 for(i = 0; i < 28 && !((bits[0] >> i) & 0xf); i += 4);
567 bits[j] |= bits[j+1] << (32 - i);
576 bround(FPBits *b, int prec, int prec1) /* round to prec hex digits after the "." */
577 { /* prec1 = incoming precision (after ".") */
580 int i, inc, j, k, m, n;
581 #ifdef Honor_FLT_ROUNDS
582 int rounding = fpi->rounding;
584 if (rounding > FPI_Round_near && b->sign)
585 rounding = FPI_Round_up + FPI_Round_down - rounding;
586 if (rounding == FPI_Round_down)
587 rounding = FPI_Round_zero;
592 #ifdef Honor_FLT_ROUNDS
595 for(i = 0; i < m; i += 8)
598 if ((j = i - m) > 0 && bits[(i-8)>>3] << j*4)
604 if ((t = bits[k >> 3] >> (j = (k&7)*4)) & 8) {
607 if (j && bits[k >> 3] << (32 - j))
618 #ifdef Honor_FLT_ROUNDS
628 bits[j-i] = bits[j] >> n;
631 bits[j-i] |= bits[j+1] << (32-n);
641 for(j = 0; !(++bits[j] & 0xffffffff); ++j);
648 if ((j = prec & 7) < 7 && bits[k] >> (j+1)*4)
651 for(i = 0; !(bits[i >> 3] & (0xf << 4*(i&7))); ++i);
659 bits[m-j] = bits[m] >> i;
662 bits[m-j] |= bits[m+1] << (32 - i);
667 #endif /*}NO_PRINTF_A_FMT*/
669 #define put(x) { *outbuf++ = x; if (outbuf == obe) outbuf = (*fput)(f,&rv); }
674 (obe, fput, f, fmt, ap)
675 char *obe, *fmt; Finfo *f; Putfunc fput; va_list ap;
677 (char *obe, Putfunc fput, Finfo *f, const char *fmt, va_list ap)
683 char *digits, *ob0, *outbuf, *s, *s0, *se;
689 int alt, base, c, decpt, dot, conv, i1, k, lead0, left,
690 len, prec, prec1, psign, rv, sign, width;
695 #ifdef Honor_FLT_ROUNDS
699 #ifndef NO_PRINTF_A_FMT /*{*/
701 #endif /*} NO_PRINTF_A_FMT */
702 static char hex[] = "0123456789abcdefpx";
703 static char Hex[] = "0123456789ABCDEFPX";
705 ob0 = outbuf = f->ob0;
720 alt=dot=lead0=left=len=prec=psign=sign=width=0;
724 switch(conv = *fmt++) {
739 if (!lead0 && !dot) {
753 while((c = *fmt) >= '0' && c <= '9') {
758 prec = psign ? -k : k;
766 #ifdef GDTOA_LD_fpbits /*{*/
767 fpbits = GDTOA_LD_fpbits;
768 #ifdef GDTOA_Q_fpbits
804 ui = va_arg(ap, int);
808 i = va_arg(ap, long);
811 us = va_arg(ap, int);
824 i = va_arg(ap, long);
827 sh = va_arg(ap, int);
846 *s++ = digits[ul - base*j];
850 if (alt && conv == 'o' && prec <= 0)
852 if ((width -= c) > 0) {
862 put('0') /* for 0x */
898 ip = va_arg(ap, long*);
901 c = outbuf - ob0 + rv;
932 ui = va_arg(ap, int);
936 ul = va_arg(ap, long);
939 us = va_arg(ap, int);
951 s = va_arg(ap, char*);
958 for(c = 0; c < prec; c++)
979 #ifdef GDTOA_H_INCLUDED
980 if (fpbits == dfpbits) {
982 x = va_arg(ap, double);
983 s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
984 #ifdef GDTOA_H_INCLUDED
988 if (fpbits == GDTOA_LD_fpbits)
989 u.ld = va_arg(ap, long double);
991 u.Qd = va_arg(ap, GDTOA_Qtype);
993 u.ld = va_arg(ap, long double);
997 s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
998 &fpb.kind, 3, prec, &decpt, &se);
1001 if (decpt == 9999) {
1003 dot = prec = alt = 0;
1009 if (fpb.sign && (x||sign))
1025 if (prec > 0 || alt)
1029 if (width > 0 && !left) {
1044 if (prec > 0 || alt)
1061 if (prec > 0 || alt)
1064 while(--prec >= 0) {
1082 #ifdef GDTOA_H_INCLUDED
1083 if (fpbits == dfpbits) {
1085 x = va_arg(ap, double);
1086 s = s0 = dtoa(x, prec ? 2 : 0, prec, &decpt,
1088 #ifdef GDTOA_H_INCLUDED
1092 if (fpbits == GDTOA_LD_fpbits)
1093 u.ld = va_arg(ap, long double);
1095 u.Qd = va_arg(ap, GDTOA_Qtype);
1097 u.ld = va_arg(ap, long double);
1101 s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
1102 &fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
1111 prec1 = c + (s[1] || alt ? 5 : 4);
1112 /* %.0g gives 10 rather than 1e1 */
1114 if (decpt > -4 && decpt <= prec1) {
1124 if (!alt && prec > c)
1134 #ifdef GDTOA_H_INCLUDED
1135 if (fpbits == dfpbits) {
1137 x = va_arg(ap, double);
1138 s = s0 = dtoa(x, prec ? 2 : 0, prec+1, &decpt,
1140 #ifdef GDTOA_H_INCLUDED
1144 if (fpbits == GDTOA_LD_fpbits)
1145 u.ld = va_arg(ap, long double);
1147 u.Qd = va_arg(ap, GDTOA_Qtype);
1149 u.ld = va_arg(ap, long double);
1153 s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
1154 &fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
1160 if (fpb.sign && (x||sign))
1162 if ((width -= prec + 5) > 0) {
1168 if ((c = --decpt) < 0)
1174 if (width > 0 && !left) {
1190 while(--prec >= 0) {
1204 for(c = 2, k = 10; 10*k <= decpt; c++, k *= 10);
1217 #ifndef NO_PRINTF_A_FMT
1224 #ifdef GDTOA_H_INCLUDED /*{{*/
1225 if (fpbits == dfpbits)
1226 u.d = va_arg(ap, double);
1227 #ifdef GDTOA_both /*{*/
1228 else if (fpbits == GDTOA_LD_fpbits)
1229 u.ld = va_arg(ap, long double);
1231 u.Qd = va_arg(ap, GDTOA_Qtype);
1234 u.ld = va_arg(ap, long double);
1237 u.d = va_arg(ap, double);
1240 if (fpb.kind == STRTOG_Infinite) {
1245 if (fpb.kind == STRTOG_NaN) {
1250 prec1 = fpiprec(&fpb);
1251 if (dot && prec < prec1)
1252 prec1 = bround(&fpb, prec, prec1);
1254 bex = fpb.ex + 4*prec1;
1263 if (fpb.sign && (sign || fpb.kind != STRTOG_Zero))
1265 if ((width -= bw + 5) > 0) {
1271 if ((width -= prec1) > 0 && !left && !lead0) {
1279 if (lead0 && width > 0 && !left) {
1285 put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
1286 if (prec1 > 0 || alt)
1296 put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
1299 if (alt && prec > 0)
1310 for(c = 1; 10*c <= bex; c *= 10);
1322 #endif /* NO_PRINTF_A_FMT */
1332 return (f->lastlen = outbuf - ob0) + rv;
1351 fmt = va_arg(ap, char*);
1354 (const char *fmt, ...)
1365 f.obe1 = buf + Bsize - 1;
1367 if (fileno(stdout) == stdout_fileno_ASL) {
1368 rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1369 mwrite(buf, f.lastlen);
1374 if (stdout == stderr_ASL) {
1375 rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1376 pf_put(buf, f.lastlen);
1381 rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1391 (f, rvp) Finfo *f; int *rvp;
1393 (Finfo *f, int *rvp)
1396 if (Printf("\nBUG! Sput called!\n", f, rvp))
1397 /* pass vp, rvp and return 0 to shut diagnostics off */
1414 s = va_arg(ap, char*);
1415 fmt = va_arg(ap, char*);
1418 (char *s, const char *fmt, ...)
1427 rv = x_sprintf(s, Sput, &f, fmt, ap);
1446 F = va_arg(ap, FILE*);
1447 fmt = va_arg(ap, char*);
1450 (FILE *F, const char *fmt, ...)
1461 f.obe1 = buf + Bsize - 1;
1463 if (stdout_or_err(F)) {
1465 if (fileno(stdout) == stdout_fileno_ASL) {
1466 rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1467 mwrite(buf, f.lastlen);
1472 if (F == stderr_ASL) {
1473 rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1474 pf_put(buf, f.lastlen);
1479 rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1487 if (F == stderr_ASL) {
1488 rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1489 pf_put(buf, f.lastlen);
1494 rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1505 (s, fmt, ap) char *s, *fmt; va_list ap;
1507 (char *s, const char *fmt, va_list ap)
1511 return x_sprintf(f.ob0 = s, Sput, &f, fmt, ap);
1517 (F, fmt, ap) FILE *F; char *fmt; va_list ap;
1519 (FILE *F, const char *fmt, va_list ap)
1528 f.obe1 = buf + Bsize - 1;
1530 if (stdout_or_err(F)) {
1532 if (fileno(stdout) == stdout_fileno_ASL) {
1533 rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1534 mwrite(buf, f.lastlen);
1539 if (F == stderr_ASL) {
1540 rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1541 pf_put(buf, f.lastlen);
1546 rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1554 if (F == stderr_ASL) {
1555 rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1556 pf_put(buf, f.lastlen);
1561 rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1578 Fprintf(Stderr, "%s: ", s);
1579 Fprintf(Stderr, "%s\n", strerror(errno));
1585 (f, rvp) Finfo *f; int *rvp;
1587 (Finfo *f, int *rvp)
1596 if ((L = f->obe1 - s) > Bsize) {
1611 (s, n, fmt, ap) char *s; size_t n; char *fmt; va_list ap;
1613 (char *s, size_t n, const char *fmt, va_list ap)
1627 rv = x_sprintf(buf + Bsize, Snput, &f, fmt, ap);
1628 if (f.lastlen > (L = f.obe1 - f.u.sf))
1630 if (f.lastlen > 0) {
1631 memcpy(f.u.sf, buf, f.lastlen);
1632 f.u.sf += f.lastlen;
1649 s = va_arg(ap, char*);
1650 n = va_arg(ap, size_t);
1651 fmt = va_arg(ap, char*);
1654 (char *s, size_t n, const char *fmt, ...)
1661 rv = Vsnprintf(s, n, fmt, ap);