xref: /freebsd/contrib/gdtoa/printf.c0 (revision 50dad48bb740a8e56d185d9e8c165e0758f46e25)
1*50dad48bSDavid Schultz/****************************************************************
2*50dad48bSDavid SchultzCopyright (C) 1997, 1999, 2001 Lucent Technologies
3*50dad48bSDavid SchultzAll Rights Reserved
4*50dad48bSDavid Schultz
5*50dad48bSDavid SchultzPermission to use, copy, modify, and distribute this software and
6*50dad48bSDavid Schultzits documentation for any purpose and without fee is hereby
7*50dad48bSDavid Schultzgranted, provided that the above copyright notice appear in all
8*50dad48bSDavid Schultzcopies and that both that the copyright notice and this
9*50dad48bSDavid Schultzpermission notice and warranty disclaimer appear in supporting
10*50dad48bSDavid Schultzdocumentation, and that the name of Lucent or any of its entities
11*50dad48bSDavid Schultznot be used in advertising or publicity pertaining to
12*50dad48bSDavid Schultzdistribution of the software without specific, written prior
13*50dad48bSDavid Schultzpermission.
14*50dad48bSDavid Schultz
15*50dad48bSDavid SchultzLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*50dad48bSDavid SchultzINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17*50dad48bSDavid SchultzIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18*50dad48bSDavid SchultzSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*50dad48bSDavid SchultzWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20*50dad48bSDavid SchultzIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21*50dad48bSDavid SchultzARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22*50dad48bSDavid SchultzTHIS SOFTWARE.
23*50dad48bSDavid Schultz****************************************************************/
24*50dad48bSDavid Schultz
25*50dad48bSDavid Schultz/* This implements most of ANSI C's printf, fprintf, and sprintf,
26*50dad48bSDavid Schultz * omitting L, with %.0g and %.0G giving the shortest decimal string
27*50dad48bSDavid Schultz * that rounds to the number being converted, and with negative
28*50dad48bSDavid Schultz * precisions allowed for %f.
29*50dad48bSDavid Schultz */
30*50dad48bSDavid Schultz
31*50dad48bSDavid Schultz#ifdef KR_headers
32*50dad48bSDavid Schultz#include "varargs.h"
33*50dad48bSDavid Schultz#else
34*50dad48bSDavid Schultz#include "stddef.h"
35*50dad48bSDavid Schultz#include "stdarg.h"
36*50dad48bSDavid Schultz#include "stdlib.h"
37*50dad48bSDavid Schultz#endif
38*50dad48bSDavid Schultz
39*50dad48bSDavid Schultz#ifdef Use_GDTOA_for_i386_long_double /*{{*/
40*50dad48bSDavid Schultz#include "gdtoa.h"
41*50dad48bSDavid Schultz#else /*}{*/
42*50dad48bSDavid Schultz#ifndef NO_PRINTF_A_FMT /*{*/
43*50dad48bSDavid Schultz#include "gdtoa.h"
44*50dad48bSDavid Schultz#endif /*}*/
45*50dad48bSDavid Schultz#endif /*}}*/
46*50dad48bSDavid Schultz
47*50dad48bSDavid Schultz#ifdef __i386
48*50dad48bSDavid Schultz#define NO_GDTOA_i386_Quad
49*50dad48bSDavid Schultz#endif
50*50dad48bSDavid Schultz
51*50dad48bSDavid Schultz#ifdef Use_GDTOA_for_i386_long_double /*{*/
52*50dad48bSDavid Schultz#ifndef NO_GDTOA_i386_Quad /*{*/
53*50dad48bSDavid Schultz#define GDTOA_both
54*50dad48bSDavid Schultz#define Use_GDTOA_Qtype
55*50dad48bSDavid Schultz#ifdef __ICC__ /* or __INTEL_COMPILER__ or __INTEL_COMPILER ?? */
56*50dad48bSDavid Schultz#define GDTOA_Qtype _Quad
57*50dad48bSDavid Schultz#else
58*50dad48bSDavid Schultz#define GDTOA_Qtype __float128
59*50dad48bSDavid Schultz#endif
60*50dad48bSDavid Schultz#endif /*} NO_GDTOA_i386_Quad */
61*50dad48bSDavid Schultz#endif /*} Use_GDTOA_for_i386_long_double */
62*50dad48bSDavid Schultz
63*50dad48bSDavid Schultz#ifdef Use_GDTOA_Qtype /*{*/
64*50dad48bSDavid Schultz#ifndef GDTOA_H_INCLUDED
65*50dad48bSDavid Schultz#include "gdtoa.h"
66*50dad48bSDavid Schultz#endif
67*50dad48bSDavid Schultz#ifndef GDTOA_Qtype
68*50dad48bSDavid Schultz#define GDTOA_Qtype long double
69*50dad48bSDavid Schultz#endif
70*50dad48bSDavid Schultz#endif /*}*/
71*50dad48bSDavid Schultz
72*50dad48bSDavid Schultz#ifndef GDTOA_H_INCLUDED /*{*/
73*50dad48bSDavid Schultz
74*50dad48bSDavid Schultz enum {	/* return values from strtodg */
75*50dad48bSDavid Schultz	STRTOG_Zero	= 0,
76*50dad48bSDavid Schultz	STRTOG_Normal	= 1,
77*50dad48bSDavid Schultz	STRTOG_Denormal	= 2,
78*50dad48bSDavid Schultz	STRTOG_Infinite	= 3,
79*50dad48bSDavid Schultz	STRTOG_NaN	= 4,
80*50dad48bSDavid Schultz	STRTOG_NaNbits	= 5,
81*50dad48bSDavid Schultz	STRTOG_NoNumber	= 6,
82*50dad48bSDavid Schultz	STRTOG_Retmask	= 7};
83*50dad48bSDavid Schultz
84*50dad48bSDavid Schultz typedef struct
85*50dad48bSDavid SchultzFPI {
86*50dad48bSDavid Schultz	int nbits;
87*50dad48bSDavid Schultz	int emin;
88*50dad48bSDavid Schultz	int emax;
89*50dad48bSDavid Schultz	int rounding;
90*50dad48bSDavid Schultz	int sudden_underflow;
91*50dad48bSDavid Schultz	} FPI;
92*50dad48bSDavid Schultz
93*50dad48bSDavid Schultzenum {	/* FPI.rounding values: same as FLT_ROUNDS */
94*50dad48bSDavid Schultz	FPI_Round_zero = 0,
95*50dad48bSDavid Schultz	FPI_Round_near = 1,
96*50dad48bSDavid Schultz	FPI_Round_up = 2,
97*50dad48bSDavid Schultz	FPI_Round_down = 3
98*50dad48bSDavid Schultz	};
99*50dad48bSDavid Schultz#endif /*}*/
100*50dad48bSDavid Schultz
101*50dad48bSDavid Schultz#ifdef NO_PRINTF_A_FMT /*{{*/
102*50dad48bSDavid Schultz#define WANT_A_FMT(x) /*nothing*/
103*50dad48bSDavid Schultz#else /*}{*/
104*50dad48bSDavid Schultz#define WANT_A_FMT(x) x
105*50dad48bSDavid Schultz#endif /*}}*/
106*50dad48bSDavid Schultz
107*50dad48bSDavid Schultz#include "stdio1.h"
108*50dad48bSDavid Schultz#include "string.h"
109*50dad48bSDavid Schultz#include "errno.h"
110*50dad48bSDavid Schultz
111*50dad48bSDavid Schultz typedef struct
112*50dad48bSDavid SchultzFinfo {
113*50dad48bSDavid Schultz	union { FILE *cf; char *sf; } u;
114*50dad48bSDavid Schultz	char *ob0, *obe1;
115*50dad48bSDavid Schultz	size_t lastlen;
116*50dad48bSDavid Schultz	} Finfo;
117*50dad48bSDavid Schultz
118*50dad48bSDavid Schultz typedef char *(*pgdtoa) ANSI((FPI*, int be, ULong *bits, int *kind, int mode, int ndigits, int *decpt, char **rve));
119*50dad48bSDavid Schultz
120*50dad48bSDavid Schultz typedef struct
121*50dad48bSDavid SchultzFPBits {
122*50dad48bSDavid Schultz	ULong bits[4];	/* sufficient for quad; modify if considering wider types */
123*50dad48bSDavid Schultz	FPI *fpi;
124*50dad48bSDavid Schultz	pgdtoa gdtoa;
125*50dad48bSDavid Schultz	int sign;
126*50dad48bSDavid Schultz	int ex;	/* exponent */
127*50dad48bSDavid Schultz	int kind;
128*50dad48bSDavid Schultz	} FPBits;
129*50dad48bSDavid Schultz
130*50dad48bSDavid Schultz typedef union U
131*50dad48bSDavid Schultz{
132*50dad48bSDavid Schultz	double d;
133*50dad48bSDavid Schultz	long double ld;
134*50dad48bSDavid Schultz#ifdef GDTOA_Qtype
135*50dad48bSDavid Schultz	GDTOA_Qtype Qd;
136*50dad48bSDavid Schultz#endif
137*50dad48bSDavid Schultz	unsigned int ui[4];
138*50dad48bSDavid Schultz	unsigned short us[5];
139*50dad48bSDavid Schultz	} U;
140*50dad48bSDavid Schultz
141*50dad48bSDavid Schultz typedef char *(*Putfunc) ANSI((Finfo*, int*));
142*50dad48bSDavid Schultz typedef void (*Fpbits) ANSI((U*, FPBits*));
143*50dad48bSDavid Schultz
144*50dad48bSDavid Schultz/* Would have preferred typedef void (*Fpbits)(va_list*, FPBits*)
145*50dad48bSDavid Schultz * but gcc is buggy in this regard.
146*50dad48bSDavid Schultz */
147*50dad48bSDavid Schultz
148*50dad48bSDavid Schultz#ifdef Use_GDTOA_for_i386_long_double /*{*/
149*50dad48bSDavid Schultz
150*50dad48bSDavid Schultz#ifdef IEEE_MC68k
151*50dad48bSDavid Schultz#define _0 0
152*50dad48bSDavid Schultz#define _1 1
153*50dad48bSDavid Schultz#define _2 2
154*50dad48bSDavid Schultz#define _3 3
155*50dad48bSDavid Schultz#define _4 4
156*50dad48bSDavid Schultz#endif
157*50dad48bSDavid Schultz#ifdef IEEE_8087
158*50dad48bSDavid Schultz#define _0 4
159*50dad48bSDavid Schultz#define _1 3
160*50dad48bSDavid Schultz#define _2 2
161*50dad48bSDavid Schultz#define _3 1
162*50dad48bSDavid Schultz#define _4 0
163*50dad48bSDavid Schultz#endif
164*50dad48bSDavid Schultz
165*50dad48bSDavid Schultz static void
166*50dad48bSDavid Schultzxfpbits(U *u, FPBits *b)
167*50dad48bSDavid Schultz{
168*50dad48bSDavid Schultz	ULong *bits;
169*50dad48bSDavid Schultz	int ex, i;
170*50dad48bSDavid Schultz	static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
171*50dad48bSDavid Schultz
172*50dad48bSDavid Schultz	b->fpi = &fpi0;
173*50dad48bSDavid Schultz	b->gdtoa = gdtoa;
174*50dad48bSDavid Schultz	b->sign = u->us[_0] & 0x8000;
175*50dad48bSDavid Schultz	bits = b->bits;
176*50dad48bSDavid Schultz	bits[1] = (u->us[_1] << 16) | u->us[_2];
177*50dad48bSDavid Schultz	bits[0] = (u->us[_3] << 16) | u->us[_4];
178*50dad48bSDavid Schultz	if ( (ex = u->us[_0] & 0x7fff) !=0) {
179*50dad48bSDavid Schultz		i = STRTOG_Normal;
180*50dad48bSDavid Schultz		if (ex == 0x7fff)
181*50dad48bSDavid Schultz			/* Infinity or NaN */
182*50dad48bSDavid Schultz			i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
183*50dad48bSDavid Schultz		}
184*50dad48bSDavid Schultz	else if (bits[0] | bits[1]) {
185*50dad48bSDavid Schultz		i = STRTOG_Denormal;
186*50dad48bSDavid Schultz		ex = 1;
187*50dad48bSDavid Schultz		}
188*50dad48bSDavid Schultz	else
189*50dad48bSDavid Schultz		i = STRTOG_Zero;
190*50dad48bSDavid Schultz	b->kind = i;
191*50dad48bSDavid Schultz	b->ex = ex - (0x3fff + 63);
192*50dad48bSDavid Schultz	}
193*50dad48bSDavid Schultz
194*50dad48bSDavid Schultz#undef _0
195*50dad48bSDavid Schultz#undef _1
196*50dad48bSDavid Schultz#undef _2
197*50dad48bSDavid Schultz#undef _3
198*50dad48bSDavid Schultz#undef _4
199*50dad48bSDavid Schultz#define GDTOA_LD_fpbits xfpbits
200*50dad48bSDavid Schultz#endif /*} Use_GDTOA_for_i386_long_double */
201*50dad48bSDavid Schultz
202*50dad48bSDavid Schultz#ifdef Use_GDTOA_Qtype /*{*/
203*50dad48bSDavid Schultz#include "gdtoa.h"
204*50dad48bSDavid Schultz#ifndef GDTOA_Qtype
205*50dad48bSDavid Schultz#define GDTOA_Qtype long double
206*50dad48bSDavid Schultz#endif
207*50dad48bSDavid Schultz#ifdef GDTOA_LD_fpbits
208*50dad48bSDavid Schultz#define GDTOA_Q_fpbits Qfpbits
209*50dad48bSDavid Schultz#else
210*50dad48bSDavid Schultz#define GDTOA_LD_fpbits Qfpbits
211*50dad48bSDavid Schultz#endif
212*50dad48bSDavid Schultz
213*50dad48bSDavid Schultz#ifdef IEEE_MC68k
214*50dad48bSDavid Schultz#define _0 0
215*50dad48bSDavid Schultz#define _1 1
216*50dad48bSDavid Schultz#define _2 2
217*50dad48bSDavid Schultz#define _3 3
218*50dad48bSDavid Schultz#endif
219*50dad48bSDavid Schultz#ifdef IEEE_8087
220*50dad48bSDavid Schultz#define _0 3
221*50dad48bSDavid Schultz#define _1 2
222*50dad48bSDavid Schultz#define _2 1
223*50dad48bSDavid Schultz#define _3 0
224*50dad48bSDavid Schultz#endif
225*50dad48bSDavid Schultz
226*50dad48bSDavid Schultz static void
227*50dad48bSDavid SchultzQfpbits(U *u, FPBits *b)
228*50dad48bSDavid Schultz{
229*50dad48bSDavid Schultz	ULong *bits;
230*50dad48bSDavid Schultz	int ex, i;
231*50dad48bSDavid Schultz	static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
232*50dad48bSDavid Schultz
233*50dad48bSDavid Schultz	b->fpi = &fpi0;
234*50dad48bSDavid Schultz	b->gdtoa = gdtoa;
235*50dad48bSDavid Schultz	b->sign = u->ui[_0] & 0x80000000L;
236*50dad48bSDavid Schultz	bits = b->bits;
237*50dad48bSDavid Schultz	bits[3] = u->ui[_0] & 0xffff;
238*50dad48bSDavid Schultz	bits[2] = u->ui[_1];
239*50dad48bSDavid Schultz	bits[1] = u->ui[_2];
240*50dad48bSDavid Schultz	bits[0] = u->ui[_3];
241*50dad48bSDavid Schultz	if ( (ex = (u->ui[_0] & 0x7fff0000L) >> 16) !=0) {
242*50dad48bSDavid Schultz		if (ex == 0x7fff) {
243*50dad48bSDavid Schultz			/* Infinity or NaN */
244*50dad48bSDavid Schultz			i = bits[0] | bits[1] | bits[2] | bits[3]
245*50dad48bSDavid Schultz				? STRTOG_NaN : STRTOG_Infinite;
246*50dad48bSDavid Schultz			}
247*50dad48bSDavid Schultz		else {
248*50dad48bSDavid Schultz			i = STRTOG_Normal;
249*50dad48bSDavid Schultz			bits[3] |= 0x10000;
250*50dad48bSDavid Schultz			}
251*50dad48bSDavid Schultz		}
252*50dad48bSDavid Schultz	else if (bits[0] | bits[1] | bits[2] | bits[3]) {
253*50dad48bSDavid Schultz		i = STRTOG_Denormal;
254*50dad48bSDavid Schultz		ex = 1;
255*50dad48bSDavid Schultz		}
256*50dad48bSDavid Schultz	else
257*50dad48bSDavid Schultz		i = STRTOG_Zero;
258*50dad48bSDavid Schultz	b->kind = i;
259*50dad48bSDavid Schultz	b->ex = ex - (0x3fff + 112);
260*50dad48bSDavid Schultz	}
261*50dad48bSDavid Schultz
262*50dad48bSDavid Schultz#undef _0
263*50dad48bSDavid Schultz#undef _1
264*50dad48bSDavid Schultz#undef _2
265*50dad48bSDavid Schultz#undef _3
266*50dad48bSDavid Schultz#endif /*} GDTOA_Qtype */
267*50dad48bSDavid Schultz
268*50dad48bSDavid Schultz#ifdef KR_headers
269*50dad48bSDavid Schultz#define Const /* const */
270*50dad48bSDavid Schultz#define Voidptr char*
271*50dad48bSDavid Schultz#ifndef size_t__
272*50dad48bSDavid Schultz#define size_t int
273*50dad48bSDavid Schultz#define size_t__
274*50dad48bSDavid Schultz#endif
275*50dad48bSDavid Schultz
276*50dad48bSDavid Schultz#else
277*50dad48bSDavid Schultz
278*50dad48bSDavid Schultz#define Const const
279*50dad48bSDavid Schultz#define Voidptr void*
280*50dad48bSDavid Schultz
281*50dad48bSDavid Schultz#endif
282*50dad48bSDavid Schultz
283*50dad48bSDavid Schultz#undef MESS
284*50dad48bSDavid Schultz#ifndef Stderr
285*50dad48bSDavid Schultz#define Stderr stderr
286*50dad48bSDavid Schultz#endif
287*50dad48bSDavid Schultz
288*50dad48bSDavid Schultz#ifdef _windows_
289*50dad48bSDavid Schultz#undef PF_BUF
290*50dad48bSDavid Schultz#define MESS
291*50dad48bSDavid Schultz#include "mux0.h"
292*50dad48bSDavid Schultz#define stdout_or_err(f) (f == stdout)
293*50dad48bSDavid Schultz#else
294*50dad48bSDavid Schultz#define stdout_or_err(f) (f == Stderr || f == stdout)
295*50dad48bSDavid Schultz#endif
296*50dad48bSDavid Schultz
297*50dad48bSDavid Schultz#ifdef __cplusplus
298*50dad48bSDavid Schultzextern "C" {
299*50dad48bSDavid Schultz#endif
300*50dad48bSDavid Schultz
301*50dad48bSDavid Schultz extern char *dtoa ANSI((double, int, int, int*, int*, char **));
302*50dad48bSDavid Schultz extern void freedtoa ANSI((char*));
303*50dad48bSDavid Schultz
304*50dad48bSDavid Schultz
305*50dad48bSDavid Schultz
306*50dad48bSDavid Schultz#ifdef USE_ULDIV
307*50dad48bSDavid Schultz/* This is for avoiding 64-bit divisions on the DEC Alpha, since */
308*50dad48bSDavid Schultz/* they are not portable among variants of OSF1 (DEC's Unix). */
309*50dad48bSDavid Schultz
310*50dad48bSDavid Schultz#define ULDIV(a,b) uldiv_ASL(a,(unsigned long)(b))
311*50dad48bSDavid Schultz
312*50dad48bSDavid Schultz#ifndef LLBITS
313*50dad48bSDavid Schultz#define LLBITS 6
314*50dad48bSDavid Schultz#endif
315*50dad48bSDavid Schultz#ifndef ULONG
316*50dad48bSDavid Schultz#define ULONG unsigned long
317*50dad48bSDavid Schultz#endif
318*50dad48bSDavid Schultz
319*50dad48bSDavid Schultz static int
320*50dad48bSDavid Schultzklog(ULONG x)
321*50dad48bSDavid Schultz{
322*50dad48bSDavid Schultz	int k, rv = 0;
323*50dad48bSDavid Schultz
324*50dad48bSDavid Schultz	if (x > 1L)
325*50dad48bSDavid Schultz	    for(k = 1 << LLBITS-1;;) {
326*50dad48bSDavid Schultz		if (x >= (1L << k)) {
327*50dad48bSDavid Schultz			rv |= k;
328*50dad48bSDavid Schultz			x >>= k;
329*50dad48bSDavid Schultz			}
330*50dad48bSDavid Schultz		if (!(k >>= 1))
331*50dad48bSDavid Schultz			break;
332*50dad48bSDavid Schultz		}
333*50dad48bSDavid Schultz	return rv;
334*50dad48bSDavid Schultz	}
335*50dad48bSDavid Schultz
336*50dad48bSDavid Schultz ULONG
337*50dad48bSDavid Schultzuldiv_ASL(ULONG a, ULONG b)
338*50dad48bSDavid Schultz{
339*50dad48bSDavid Schultz	int ka;
340*50dad48bSDavid Schultz	ULONG c, k;
341*50dad48bSDavid Schultz	static ULONG b0;
342*50dad48bSDavid Schultz	static int kb;
343*50dad48bSDavid Schultz
344*50dad48bSDavid Schultz	if (a < b)
345*50dad48bSDavid Schultz		return 0;
346*50dad48bSDavid Schultz	if (b != b0) {
347*50dad48bSDavid Schultz		b0 = b;
348*50dad48bSDavid Schultz		kb = klog(b);
349*50dad48bSDavid Schultz		}
350*50dad48bSDavid Schultz	k = 1;
351*50dad48bSDavid Schultz	if ((ka = klog(a) - kb) > 0) {
352*50dad48bSDavid Schultz		k <<= ka;
353*50dad48bSDavid Schultz		b <<= ka;
354*50dad48bSDavid Schultz		}
355*50dad48bSDavid Schultz	c = 0;
356*50dad48bSDavid Schultz	for(;;) {
357*50dad48bSDavid Schultz		if (a >= b) {
358*50dad48bSDavid Schultz			a -= b;
359*50dad48bSDavid Schultz			c |= k;
360*50dad48bSDavid Schultz			}
361*50dad48bSDavid Schultz		if (!(k >>= 1))
362*50dad48bSDavid Schultz			break;
363*50dad48bSDavid Schultz		a <<= 1;
364*50dad48bSDavid Schultz		}
365*50dad48bSDavid Schultz	return c;
366*50dad48bSDavid Schultz	}
367*50dad48bSDavid Schultz
368*50dad48bSDavid Schultz#else
369*50dad48bSDavid Schultz#define ULDIV(a,b) a / b
370*50dad48bSDavid Schultz#endif /* USE_ULDIV */
371*50dad48bSDavid Schultz
372*50dad48bSDavid Schultz#ifdef PF_BUF
373*50dad48bSDavid SchultzFILE *stderr_ASL = (FILE*)&stderr_ASL;
374*50dad48bSDavid Schultzvoid (*pfbuf_print_ASL) ANSI((char*));
375*50dad48bSDavid Schultzchar *pfbuf_ASL;
376*50dad48bSDavid Schultzstatic char *pfbuf_next;
377*50dad48bSDavid Schultzstatic size_t pfbuf_len;
378*50dad48bSDavid Schultzextern Char *mymalloc_ASL ANSI((size_t));
379*50dad48bSDavid Schultzextern Char *myralloc_ASL ANSI((void *, size_t));
380*50dad48bSDavid Schultz
381*50dad48bSDavid Schultz#undef fflush
382*50dad48bSDavid Schultz#ifdef old_fflush_ASL
383*50dad48bSDavid Schultz#define fflush old_fflush_ASL
384*50dad48bSDavid Schultz#endif
385*50dad48bSDavid Schultz
386*50dad48bSDavid Schultz void
387*50dad48bSDavid Schultzfflush_ASL(FILE *f)
388*50dad48bSDavid Schultz{
389*50dad48bSDavid Schultz	if (f == stderr_ASL) {
390*50dad48bSDavid Schultz		if (pfbuf_ASL && pfbuf_print_ASL) {
391*50dad48bSDavid Schultz			(*pfbuf_print_ASL)(pfbuf_ASL);
392*50dad48bSDavid Schultz			free(pfbuf_ASL);
393*50dad48bSDavid Schultz			pfbuf_ASL = 0;
394*50dad48bSDavid Schultz			}
395*50dad48bSDavid Schultz		}
396*50dad48bSDavid Schultz	else
397*50dad48bSDavid Schultz		fflush(f);
398*50dad48bSDavid Schultz	}
399*50dad48bSDavid Schultz
400*50dad48bSDavid Schultz static void
401*50dad48bSDavid Schultzpf_put(char *buf, int len)
402*50dad48bSDavid Schultz{
403*50dad48bSDavid Schultz	size_t x, y;
404*50dad48bSDavid Schultz	if (!pfbuf_ASL) {
405*50dad48bSDavid Schultz		x = len + 256;
406*50dad48bSDavid Schultz		if (x < 512)
407*50dad48bSDavid Schultz			x = 512;
408*50dad48bSDavid Schultz		pfbuf_ASL = pfbuf_next = (char*)mymalloc_ASL(pfbuf_len = x);
409*50dad48bSDavid Schultz		}
410*50dad48bSDavid Schultz	else if ((y = (pfbuf_next - pfbuf_ASL) + len) >= pfbuf_len) {
411*50dad48bSDavid Schultz		x = pfbuf_len;
412*50dad48bSDavid Schultz		while((x <<= 1) <= y);
413*50dad48bSDavid Schultz		y = pfbuf_next - pfbuf_ASL;
414*50dad48bSDavid Schultz		pfbuf_ASL = (char*)myralloc_ASL(pfbuf_ASL, x);
415*50dad48bSDavid Schultz		pfbuf_next = pfbuf_ASL + y;
416*50dad48bSDavid Schultz		pfbuf_len = x;
417*50dad48bSDavid Schultz		}
418*50dad48bSDavid Schultz	memcpy(pfbuf_next, buf, len);
419*50dad48bSDavid Schultz	pfbuf_next += len;
420*50dad48bSDavid Schultz	*pfbuf_next = 0;
421*50dad48bSDavid Schultz	}
422*50dad48bSDavid Schultz
423*50dad48bSDavid Schultz static char *
424*50dad48bSDavid Schultzpfput(Finfo *f, int *rvp)
425*50dad48bSDavid Schultz{
426*50dad48bSDavid Schultz	int n;
427*50dad48bSDavid Schultz	char *ob0 = f->ob0;
428*50dad48bSDavid Schultz	*rvp += n = (int)(f->obe1 - ob0);
429*50dad48bSDavid Schultz	pf_put(ob0, n);
430*50dad48bSDavid Schultz	return ob0;
431*50dad48bSDavid Schultz	}
432*50dad48bSDavid Schultz#endif /* PF_BUF */
433*50dad48bSDavid Schultz
434*50dad48bSDavid Schultz static char *
435*50dad48bSDavid SchultzFput
436*50dad48bSDavid Schultz#ifdef KR_headers
437*50dad48bSDavid Schultz	(f, rvp) Finfo *f; int *rvp;
438*50dad48bSDavid Schultz#else
439*50dad48bSDavid Schultz	(Finfo *f, int *rvp)
440*50dad48bSDavid Schultz#endif
441*50dad48bSDavid Schultz{
442*50dad48bSDavid Schultz	char *ob0 = f->ob0;
443*50dad48bSDavid Schultz
444*50dad48bSDavid Schultz	*rvp += f->obe1 - ob0;
445*50dad48bSDavid Schultz	*f->obe1 = 0;
446*50dad48bSDavid Schultz	fputs(ob0, f->u.cf);
447*50dad48bSDavid Schultz	return ob0;
448*50dad48bSDavid Schultz	}
449*50dad48bSDavid Schultz
450*50dad48bSDavid Schultz
451*50dad48bSDavid Schultz#ifdef _windows_
452*50dad48bSDavid Schultzint stdout_fileno_ASL = 1;
453*50dad48bSDavid Schultz
454*50dad48bSDavid Schultz static char *
455*50dad48bSDavid SchultzWput
456*50dad48bSDavid Schultz#ifdef KR_headers
457*50dad48bSDavid Schultz	(f, rvp) Finfo *f; int *rvp;
458*50dad48bSDavid Schultz#else
459*50dad48bSDavid Schultz	(Finfo *f, int *rvp)
460*50dad48bSDavid Schultz#endif
461*50dad48bSDavid Schultz{
462*50dad48bSDavid Schultz	char *ob0 = f->ob0;
463*50dad48bSDavid Schultz
464*50dad48bSDavid Schultz	*rvp += f->obe1 - ob0;
465*50dad48bSDavid Schultz	*f->obe1 = 0;
466*50dad48bSDavid Schultz	mwrite(ob0, f->obe1 - ob0);
467*50dad48bSDavid Schultz	return ob0;
468*50dad48bSDavid Schultz	}
469*50dad48bSDavid Schultz#endif /*_windows_*/
470*50dad48bSDavid Schultz
471*50dad48bSDavid Schultz
472*50dad48bSDavid Schultz#ifdef IEEE_MC68k
473*50dad48bSDavid Schultz#define _0 0
474*50dad48bSDavid Schultz#define _1 1
475*50dad48bSDavid Schultz#endif
476*50dad48bSDavid Schultz#ifdef IEEE_8087
477*50dad48bSDavid Schultz#define _0 1
478*50dad48bSDavid Schultz#define _1 0
479*50dad48bSDavid Schultz#endif
480*50dad48bSDavid Schultz
481*50dad48bSDavid Schultz static void
482*50dad48bSDavid Schultzdfpbits(U *u, FPBits *b)
483*50dad48bSDavid Schultz{
484*50dad48bSDavid Schultz	ULong *bits;
485*50dad48bSDavid Schultz	int ex, i;
486*50dad48bSDavid Schultz	static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
487*50dad48bSDavid Schultz
488*50dad48bSDavid Schultz	b->fpi = &fpi0;
489*50dad48bSDavid Schultz	b->gdtoa = gdtoa;
490*50dad48bSDavid Schultz	b->sign = u->ui[_0] & 0x80000000L;
491*50dad48bSDavid Schultz	bits = b->bits;
492*50dad48bSDavid Schultz	bits[1] = u->ui[_0] & 0xfffff;
493*50dad48bSDavid Schultz	bits[0] = u->ui[_1];
494*50dad48bSDavid Schultz	if ( (ex = (u->ui[_0] & 0x7ff00000L) >> 20) !=0) {
495*50dad48bSDavid Schultz		if (ex == 0x7ff) {
496*50dad48bSDavid Schultz			/* Infinity or NaN */
497*50dad48bSDavid Schultz			i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
498*50dad48bSDavid Schultz			}
499*50dad48bSDavid Schultz		else {
500*50dad48bSDavid Schultz			i = STRTOG_Normal;
501*50dad48bSDavid Schultz			bits[1] |= 0x100000;
502*50dad48bSDavid Schultz			}
503*50dad48bSDavid Schultz		}
504*50dad48bSDavid Schultz	else if (bits[0] | bits[1]) {
505*50dad48bSDavid Schultz		i = STRTOG_Denormal;
506*50dad48bSDavid Schultz		ex = 1;
507*50dad48bSDavid Schultz		}
508*50dad48bSDavid Schultz	else
509*50dad48bSDavid Schultz		i = STRTOG_Zero;
510*50dad48bSDavid Schultz	b->kind = i;
511*50dad48bSDavid Schultz	b->ex = ex - (0x3ff + 52);
512*50dad48bSDavid Schultz	}
513*50dad48bSDavid Schultz
514*50dad48bSDavid Schultz#undef _0
515*50dad48bSDavid Schultz#undef _1
516*50dad48bSDavid Schultz
517*50dad48bSDavid Schultz#ifdef Honor_FLT_ROUNDS /*{{*/
518*50dad48bSDavid Schultz#ifdef Trust_FLT_ROUNDS /*{{*/
519*50dad48bSDavid Schultz#define RoundCheck if (Rounding == -1) Rounding = Flt_Rounds; if (Rounding != 1){\
520*50dad48bSDavid Schultz	fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
521*50dad48bSDavid Schultz#else /*}{*/
522*50dad48bSDavid Schultz#define RoundCheck if (Rounding == -1) { Rounding = 1; switch((fegetround()) {\
523*50dad48bSDavid Schultz	  case FE_TOWARDZERO:	Rounding = 0; break;\
524*50dad48bSDavid Schultz	  case FE_UPWARD:	Rounding = 2; break;\
525*50dad48bSDavid Schultz	  case FE_DOWNWARD:	Rounding = 3; }}\
526*50dad48bSDavid Schultz	if (Rounding != 1){\
527*50dad48bSDavid Schultz	fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
528*50dad48bSDavid Schultz#endif /*}}*/
529*50dad48bSDavid Schultz#else /*}{*/
530*50dad48bSDavid Schultz#define RoundCheck /*nothing*/
531*50dad48bSDavid Schultz#endif /*}}*/
532*50dad48bSDavid Schultz
533*50dad48bSDavid Schultz#ifndef NO_PRINTF_A_FMT /*{*/
534*50dad48bSDavid Schultz static int
535*50dad48bSDavid Schultzfpiprec(FPBits *b)	/* return number of hex digits minus 1, or 0 for zero */
536*50dad48bSDavid Schultz{
537*50dad48bSDavid Schultz	FPI *fpi;
538*50dad48bSDavid Schultz	ULong *bits;
539*50dad48bSDavid Schultz	int i, j, k, m;
540*50dad48bSDavid Schultz
541*50dad48bSDavid Schultz	if (b->kind == STRTOG_Zero)
542*50dad48bSDavid Schultz		return b->ex = 0;
543*50dad48bSDavid Schultz	fpi = b->fpi;
544*50dad48bSDavid Schultz	bits = b->bits;
545*50dad48bSDavid Schultz	for(k = (fpi->nbits - 1) >> 2; k > 0; --k)
546*50dad48bSDavid Schultz		if ((bits[k >> 3] >> 4*(k & 7)) & 0xf) {
547*50dad48bSDavid Schultz			m = k >> 3;
548*50dad48bSDavid Schultz			for(i = 0; i <= m; ++i)
549*50dad48bSDavid Schultz				if (bits[i]) {
550*50dad48bSDavid Schultz					if (i > 0) {
551*50dad48bSDavid Schultz						k -= 8*i;
552*50dad48bSDavid Schultz						b->ex += 32*i;
553*50dad48bSDavid Schultz						for(j = i; j <= m; ++j)
554*50dad48bSDavid Schultz							bits[j-i] = bits[j];
555*50dad48bSDavid Schultz						}
556*50dad48bSDavid Schultz					break;
557*50dad48bSDavid Schultz					}
558*50dad48bSDavid Schultz			for(i = 0; i < 28 && !((bits[0] >> i) & 0xf); i += 4);
559*50dad48bSDavid Schultz			if (i) {
560*50dad48bSDavid Schultz				b->ex += i;
561*50dad48bSDavid Schultz				m = k >> 3;
562*50dad48bSDavid Schultz				k -= (i >> 2);
563*50dad48bSDavid Schultz				for(j = 0;;++j) {
564*50dad48bSDavid Schultz					bits[j] >>= i;
565*50dad48bSDavid Schultz					if (j == m)
566*50dad48bSDavid Schultz						break;
567*50dad48bSDavid Schultz					bits[j] |= bits[j+1] << (32 - i);
568*50dad48bSDavid Schultz					}
569*50dad48bSDavid Schultz				}
570*50dad48bSDavid Schultz			break;
571*50dad48bSDavid Schultz			}
572*50dad48bSDavid Schultz	return k;
573*50dad48bSDavid Schultz	}
574*50dad48bSDavid Schultz
575*50dad48bSDavid Schultz static int
576*50dad48bSDavid Schultzbround(FPBits *b, int prec, int prec1)	/* round to prec hex digits after the "." */
577*50dad48bSDavid Schultz{					/* prec1 = incoming precision (after ".") */
578*50dad48bSDavid Schultz	FPI *fpi = b->fpi;
579*50dad48bSDavid Schultz	ULong *bits, t;
580*50dad48bSDavid Schultz	int i, inc, j, k, m, n;
581*50dad48bSDavid Schultz#ifdef Honor_FLT_ROUNDS
582*50dad48bSDavid Schultz	int rounding = fpi->rounding;
583*50dad48bSDavid Schultz
584*50dad48bSDavid Schultz	if (rounding > FPI_Round_near && b->sign)
585*50dad48bSDavid Schultz		rounding = FPI_Round_up + FPI_Round_down - rounding;
586*50dad48bSDavid Schultz	if (rounding == FPI_Round_down)
587*50dad48bSDavid Schultz		rounding = FPI_Round_zero;
588*50dad48bSDavid Schultz#endif
589*50dad48bSDavid Schultz	m = prec1 - prec;
590*50dad48bSDavid Schultz	bits = b->bits;
591*50dad48bSDavid Schultz	inc = 0;
592*50dad48bSDavid Schultz#ifdef Honor_FLT_ROUNDS
593*50dad48bSDavid Schultz	switch(rounding) {
594*50dad48bSDavid Schultz		case FPI_Round_up:
595*50dad48bSDavid Schultz			for(i = 0; i < m; i += 8)
596*50dad48bSDavid Schultz				if (bits[i>>3])
597*50dad48bSDavid Schultz					goto inc1;
598*50dad48bSDavid Schultz			if ((j = i - m) > 0 && bits[(i-8)>>3] << j*4)
599*50dad48bSDavid Schultz				goto inc1;
600*50dad48bSDavid Schultz			break;
601*50dad48bSDavid Schultz		case FPI_Round_near:
602*50dad48bSDavid Schultz#endif
603*50dad48bSDavid Schultz			k = m - 1;
604*50dad48bSDavid Schultz			if ((t = bits[k >> 3] >> (j = (k&7)*4)) & 8) {
605*50dad48bSDavid Schultz				if (t & 7)
606*50dad48bSDavid Schultz					goto inc1;
607*50dad48bSDavid Schultz				if (j && bits[k >> 3] << (32 - j))
608*50dad48bSDavid Schultz					goto inc1;
609*50dad48bSDavid Schultz				while(k >= 8) {
610*50dad48bSDavid Schultz					k -= 8;
611*50dad48bSDavid Schultz					if (bits[k>>3]) {
612*50dad48bSDavid Schultz inc1:
613*50dad48bSDavid Schultz						inc = 1;
614*50dad48bSDavid Schultz						goto haveinc;
615*50dad48bSDavid Schultz						}
616*50dad48bSDavid Schultz					}
617*50dad48bSDavid Schultz				}
618*50dad48bSDavid Schultz#ifdef Honor_FLT_ROUNDS
619*50dad48bSDavid Schultz		}
620*50dad48bSDavid Schultz#endif
621*50dad48bSDavid Schultz haveinc:
622*50dad48bSDavid Schultz	b->ex += m*4;
623*50dad48bSDavid Schultz	i = m >> 3;
624*50dad48bSDavid Schultz	k = prec1 >> 3;
625*50dad48bSDavid Schultz	j = i;
626*50dad48bSDavid Schultz	if ((n = 4*(m & 7)))
627*50dad48bSDavid Schultz		for(;; ++j) {
628*50dad48bSDavid Schultz			bits[j-i] = bits[j] >> n;
629*50dad48bSDavid Schultz			if (j == k)
630*50dad48bSDavid Schultz				break;
631*50dad48bSDavid Schultz			bits[j-i] |= bits[j+1] << (32-n);
632*50dad48bSDavid Schultz			}
633*50dad48bSDavid Schultz	else
634*50dad48bSDavid Schultz		for(;; ++j) {
635*50dad48bSDavid Schultz			bits[j-i] = bits[j];
636*50dad48bSDavid Schultz			if (j == k)
637*50dad48bSDavid Schultz				break;
638*50dad48bSDavid Schultz			}
639*50dad48bSDavid Schultz	k = prec >> 3;
640*50dad48bSDavid Schultz	if (inc) {
641*50dad48bSDavid Schultz		for(j = 0; !(++bits[j] & 0xffffffff); ++j);
642*50dad48bSDavid Schultz		if (j > k) {
643*50dad48bSDavid Schultz onebit:
644*50dad48bSDavid Schultz			bits[0] = 1;
645*50dad48bSDavid Schultz			b->ex += 4*prec;
646*50dad48bSDavid Schultz			return 1;
647*50dad48bSDavid Schultz			}
648*50dad48bSDavid Schultz		if ((j = prec & 7) < 7 && bits[k] >> (j+1)*4)
649*50dad48bSDavid Schultz			goto onebit;
650*50dad48bSDavid Schultz		}
651*50dad48bSDavid Schultz	for(i = 0; !(bits[i >> 3] & (0xf << 4*(i&7))); ++i);
652*50dad48bSDavid Schultz	if (i) {
653*50dad48bSDavid Schultz		b->ex += 4*i;
654*50dad48bSDavid Schultz		prec -= i;
655*50dad48bSDavid Schultz		j = i >> 3;
656*50dad48bSDavid Schultz		i &= 7;
657*50dad48bSDavid Schultz		i *= 4;
658*50dad48bSDavid Schultz		for(m = j; ; ++m) {
659*50dad48bSDavid Schultz			bits[m-j] = bits[m] >> i;
660*50dad48bSDavid Schultz			if (m == k)
661*50dad48bSDavid Schultz				break;
662*50dad48bSDavid Schultz			bits[m-j] |= bits[m+1] << (32 - i);
663*50dad48bSDavid Schultz			}
664*50dad48bSDavid Schultz		}
665*50dad48bSDavid Schultz	return prec;
666*50dad48bSDavid Schultz	}
667*50dad48bSDavid Schultz#endif /*}NO_PRINTF_A_FMT*/
668*50dad48bSDavid Schultz
669*50dad48bSDavid Schultz#define put(x) { *outbuf++ = x; if (outbuf == obe) outbuf = (*fput)(f,&rv); }
670*50dad48bSDavid Schultz
671*50dad48bSDavid Schultz static int
672*50dad48bSDavid Schultzx_sprintf
673*50dad48bSDavid Schultz#ifdef KR_headers
674*50dad48bSDavid Schultz	(obe, fput, f, fmt, ap)
675*50dad48bSDavid Schultz	char *obe, *fmt; Finfo *f; Putfunc fput; va_list ap;
676*50dad48bSDavid Schultz#else
677*50dad48bSDavid Schultz	(char *obe, Putfunc fput, Finfo *f, const char *fmt, va_list ap)
678*50dad48bSDavid Schultz#endif
679*50dad48bSDavid Schultz{
680*50dad48bSDavid Schultz	FPBits fpb;
681*50dad48bSDavid Schultz	Fpbits fpbits;
682*50dad48bSDavid Schultz	U u;
683*50dad48bSDavid Schultz	char *digits, *ob0, *outbuf, *s, *s0, *se;
684*50dad48bSDavid Schultz	Const char *fmt0;
685*50dad48bSDavid Schultz	char buf[32];
686*50dad48bSDavid Schultz	long i;
687*50dad48bSDavid Schultz	unsigned long j, ul;
688*50dad48bSDavid Schultz	double x;
689*50dad48bSDavid Schultz	int alt, base, c, decpt, dot, conv, i1, k, lead0, left,
690*50dad48bSDavid Schultz		len, prec, prec1, psign, rv, sign, width;
691*50dad48bSDavid Schultz	long Ltmp, *ip;
692*50dad48bSDavid Schultz	short sh;
693*50dad48bSDavid Schultz	unsigned short us;
694*50dad48bSDavid Schultz	unsigned int ui;
695*50dad48bSDavid Schultz#ifdef Honor_FLT_ROUNDS
696*50dad48bSDavid Schultz	FPI fpi1;
697*50dad48bSDavid Schultz	int Rounding = -1;
698*50dad48bSDavid Schultz#endif
699*50dad48bSDavid Schultz#ifndef NO_PRINTF_A_FMT /*{*/
700*50dad48bSDavid Schultz	int bex, bw;
701*50dad48bSDavid Schultz#endif /*} NO_PRINTF_A_FMT */
702*50dad48bSDavid Schultz	static char hex[] = "0123456789abcdefpx";
703*50dad48bSDavid Schultz	static char Hex[] = "0123456789ABCDEFPX";
704*50dad48bSDavid Schultz
705*50dad48bSDavid Schultz	ob0 = outbuf = f->ob0;
706*50dad48bSDavid Schultz	rv = 0;
707*50dad48bSDavid Schultz	for(;;) {
708*50dad48bSDavid Schultz		for(;;) {
709*50dad48bSDavid Schultz			switch(c = *fmt++) {
710*50dad48bSDavid Schultz				case 0:
711*50dad48bSDavid Schultz					goto done;
712*50dad48bSDavid Schultz				case '%':
713*50dad48bSDavid Schultz					break;
714*50dad48bSDavid Schultz				default:
715*50dad48bSDavid Schultz					put(c)
716*50dad48bSDavid Schultz					continue;
717*50dad48bSDavid Schultz				}
718*50dad48bSDavid Schultz			break;
719*50dad48bSDavid Schultz			}
720*50dad48bSDavid Schultz		alt=dot=lead0=left=len=prec=psign=sign=width=0;
721*50dad48bSDavid Schultz		fpbits = dfpbits;
722*50dad48bSDavid Schultz		fmt0 = fmt;
723*50dad48bSDavid Schultz fmtloop:
724*50dad48bSDavid Schultz		switch(conv = *fmt++) {
725*50dad48bSDavid Schultz			case ' ':
726*50dad48bSDavid Schultz			case '+':
727*50dad48bSDavid Schultz				sign = conv;
728*50dad48bSDavid Schultz				goto fmtloop;
729*50dad48bSDavid Schultz			case '-':
730*50dad48bSDavid Schultz				if (dot)
731*50dad48bSDavid Schultz					psign = 1;
732*50dad48bSDavid Schultz				else
733*50dad48bSDavid Schultz					left = 1;
734*50dad48bSDavid Schultz				goto fmtloop;
735*50dad48bSDavid Schultz			case '#':
736*50dad48bSDavid Schultz				alt = 1;
737*50dad48bSDavid Schultz				goto fmtloop;
738*50dad48bSDavid Schultz			case '0':
739*50dad48bSDavid Schultz				if (!lead0 && !dot) {
740*50dad48bSDavid Schultz					lead0 = 1;
741*50dad48bSDavid Schultz					goto fmtloop;
742*50dad48bSDavid Schultz					}
743*50dad48bSDavid Schultz			case '1':
744*50dad48bSDavid Schultz			case '2':
745*50dad48bSDavid Schultz			case '3':
746*50dad48bSDavid Schultz			case '4':
747*50dad48bSDavid Schultz			case '5':
748*50dad48bSDavid Schultz			case '6':
749*50dad48bSDavid Schultz			case '7':
750*50dad48bSDavid Schultz			case '8':
751*50dad48bSDavid Schultz			case '9':
752*50dad48bSDavid Schultz				k = conv - '0';
753*50dad48bSDavid Schultz				while((c = *fmt) >= '0' && c <= '9') {
754*50dad48bSDavid Schultz					k = 10*k + c - '0';
755*50dad48bSDavid Schultz					fmt++;
756*50dad48bSDavid Schultz					}
757*50dad48bSDavid Schultz				if (dot)
758*50dad48bSDavid Schultz					prec = psign ? -k : k;
759*50dad48bSDavid Schultz				else
760*50dad48bSDavid Schultz					width = k;
761*50dad48bSDavid Schultz				goto fmtloop;
762*50dad48bSDavid Schultz			case 'h':
763*50dad48bSDavid Schultz				len = 2;
764*50dad48bSDavid Schultz				goto fmtloop;
765*50dad48bSDavid Schultz			case 'L':
766*50dad48bSDavid Schultz#ifdef GDTOA_LD_fpbits /*{*/
767*50dad48bSDavid Schultz				fpbits = GDTOA_LD_fpbits;
768*50dad48bSDavid Schultz#ifdef GDTOA_Q_fpbits
769*50dad48bSDavid Schultz				if (*fmt == 'q') {
770*50dad48bSDavid Schultz					++fmt;
771*50dad48bSDavid Schultz					fpbits = Qfpbits;
772*50dad48bSDavid Schultz					}
773*50dad48bSDavid Schultz#endif
774*50dad48bSDavid Schultz#endif /*}*/
775*50dad48bSDavid Schultz				goto fmtloop;
776*50dad48bSDavid Schultz			case 'l':
777*50dad48bSDavid Schultz				len = 1;
778*50dad48bSDavid Schultz				goto fmtloop;
779*50dad48bSDavid Schultz			case '.':
780*50dad48bSDavid Schultz				dot = 1;
781*50dad48bSDavid Schultz				goto fmtloop;
782*50dad48bSDavid Schultz			case '*':
783*50dad48bSDavid Schultz				k = va_arg(ap, int);
784*50dad48bSDavid Schultz				if (dot)
785*50dad48bSDavid Schultz					prec = k;
786*50dad48bSDavid Schultz				else {
787*50dad48bSDavid Schultz					if (k < 0) {
788*50dad48bSDavid Schultz						sign = '-';
789*50dad48bSDavid Schultz						k = -k;
790*50dad48bSDavid Schultz						}
791*50dad48bSDavid Schultz					width = k;
792*50dad48bSDavid Schultz					}
793*50dad48bSDavid Schultz				goto fmtloop;
794*50dad48bSDavid Schultz			case 'c':
795*50dad48bSDavid Schultz				c = va_arg(ap, int);
796*50dad48bSDavid Schultz				put(c)
797*50dad48bSDavid Schultz				continue;
798*50dad48bSDavid Schultz			case '%':
799*50dad48bSDavid Schultz				put(conv)
800*50dad48bSDavid Schultz				continue;
801*50dad48bSDavid Schultz			case 'u':
802*50dad48bSDavid Schultz				switch(len) {
803*50dad48bSDavid Schultz				  case 0:
804*50dad48bSDavid Schultz					ui = va_arg(ap, int);
805*50dad48bSDavid Schultz					i = ui;
806*50dad48bSDavid Schultz					break;
807*50dad48bSDavid Schultz				  case 1:
808*50dad48bSDavid Schultz					i = va_arg(ap, long);
809*50dad48bSDavid Schultz					break;
810*50dad48bSDavid Schultz				  case 2:
811*50dad48bSDavid Schultz					us = va_arg(ap, int);
812*50dad48bSDavid Schultz					i = us;
813*50dad48bSDavid Schultz				  }
814*50dad48bSDavid Schultz				sign = 0;
815*50dad48bSDavid Schultz				goto have_i;
816*50dad48bSDavid Schultz			case 'i':
817*50dad48bSDavid Schultz			case 'd':
818*50dad48bSDavid Schultz				switch(len) {
819*50dad48bSDavid Schultz				  case 0:
820*50dad48bSDavid Schultz					k = va_arg(ap, int);
821*50dad48bSDavid Schultz					i = k;
822*50dad48bSDavid Schultz					break;
823*50dad48bSDavid Schultz				  case 1:
824*50dad48bSDavid Schultz					i = va_arg(ap, long);
825*50dad48bSDavid Schultz					break;
826*50dad48bSDavid Schultz				  case 2:
827*50dad48bSDavid Schultz					sh = va_arg(ap, int);
828*50dad48bSDavid Schultz					i = sh;
829*50dad48bSDavid Schultz				  }
830*50dad48bSDavid Schultz				if (i < 0) {
831*50dad48bSDavid Schultz					sign = '-';
832*50dad48bSDavid Schultz					i = -i;
833*50dad48bSDavid Schultz					}
834*50dad48bSDavid Schultz have_i:
835*50dad48bSDavid Schultz				base = 10;
836*50dad48bSDavid Schultz				ul = i;
837*50dad48bSDavid Schultz				digits = hex;
838*50dad48bSDavid Schultz baseloop:
839*50dad48bSDavid Schultz				if (dot)
840*50dad48bSDavid Schultz					lead0 = 0;
841*50dad48bSDavid Schultz				s = buf;
842*50dad48bSDavid Schultz				if (!ul)
843*50dad48bSDavid Schultz					alt = 0;
844*50dad48bSDavid Schultz				do {
845*50dad48bSDavid Schultz					j = ULDIV(ul, base);
846*50dad48bSDavid Schultz					*s++ = digits[ul - base*j];
847*50dad48bSDavid Schultz					}
848*50dad48bSDavid Schultz					while((ul = j));
849*50dad48bSDavid Schultz				prec -= c = s - buf;
850*50dad48bSDavid Schultz				if (alt && conv == 'o' && prec <= 0)
851*50dad48bSDavid Schultz					prec = 1;
852*50dad48bSDavid Schultz				if ((width -= c) > 0) {
853*50dad48bSDavid Schultz					if (prec > 0)
854*50dad48bSDavid Schultz						width -= prec;
855*50dad48bSDavid Schultz					if (sign)
856*50dad48bSDavid Schultz						width--;
857*50dad48bSDavid Schultz					if (alt == 2)
858*50dad48bSDavid Schultz						width--;
859*50dad48bSDavid Schultz					}
860*50dad48bSDavid Schultz				if (left) {
861*50dad48bSDavid Schultz					if (alt == 2)
862*50dad48bSDavid Schultz						put('0') /* for 0x */
863*50dad48bSDavid Schultz					if (sign)
864*50dad48bSDavid Schultz						put(sign)
865*50dad48bSDavid Schultz					while(--prec >= 0)
866*50dad48bSDavid Schultz						put('0')
867*50dad48bSDavid Schultz					do put(*--s)
868*50dad48bSDavid Schultz						while(s > buf);
869*50dad48bSDavid Schultz					while(--width >= 0)
870*50dad48bSDavid Schultz						put(' ')
871*50dad48bSDavid Schultz					continue;
872*50dad48bSDavid Schultz					}
873*50dad48bSDavid Schultz				if (width > 0) {
874*50dad48bSDavid Schultz					if (lead0) {
875*50dad48bSDavid Schultz						if (alt == 2)
876*50dad48bSDavid Schultz							put('0')
877*50dad48bSDavid Schultz						if (sign)
878*50dad48bSDavid Schultz							put(sign)
879*50dad48bSDavid Schultz						while(--width >= 0)
880*50dad48bSDavid Schultz							put('0')
881*50dad48bSDavid Schultz						goto s_loop;
882*50dad48bSDavid Schultz						}
883*50dad48bSDavid Schultz					else
884*50dad48bSDavid Schultz						while(--width >= 0)
885*50dad48bSDavid Schultz							put(' ')
886*50dad48bSDavid Schultz					}
887*50dad48bSDavid Schultz				if (alt == 2)
888*50dad48bSDavid Schultz					put('0')
889*50dad48bSDavid Schultz				if (sign)
890*50dad48bSDavid Schultz					put(sign)
891*50dad48bSDavid Schultz s_loop:
892*50dad48bSDavid Schultz				while(--prec >= 0)
893*50dad48bSDavid Schultz					put('0')
894*50dad48bSDavid Schultz				do put(*--s)
895*50dad48bSDavid Schultz					while(s > buf);
896*50dad48bSDavid Schultz				continue;
897*50dad48bSDavid Schultz			case 'n':
898*50dad48bSDavid Schultz				ip = va_arg(ap, long*);
899*50dad48bSDavid Schultz				if (!ip)
900*50dad48bSDavid Schultz					ip = &Ltmp;
901*50dad48bSDavid Schultz				c = outbuf - ob0 + rv;
902*50dad48bSDavid Schultz				switch(len) {
903*50dad48bSDavid Schultz				  case 0:
904*50dad48bSDavid Schultz					*(int*)ip = c;
905*50dad48bSDavid Schultz					break;
906*50dad48bSDavid Schultz				  case 1:
907*50dad48bSDavid Schultz					*ip = c;
908*50dad48bSDavid Schultz					break;
909*50dad48bSDavid Schultz				  case 2:
910*50dad48bSDavid Schultz					*(short*)ip = c;
911*50dad48bSDavid Schultz				  }
912*50dad48bSDavid Schultz				break;
913*50dad48bSDavid Schultz			case 'p':
914*50dad48bSDavid Schultz				len = alt = 1;
915*50dad48bSDavid Schultz				/* no break */
916*50dad48bSDavid Schultz			case 'x':
917*50dad48bSDavid Schultz				digits = hex;
918*50dad48bSDavid Schultz				goto more_x;
919*50dad48bSDavid Schultz			case 'X':
920*50dad48bSDavid Schultz				digits = Hex;
921*50dad48bSDavid Schultz more_x:
922*50dad48bSDavid Schultz				if (alt) {
923*50dad48bSDavid Schultz					alt = 2;
924*50dad48bSDavid Schultz					sign = conv;
925*50dad48bSDavid Schultz					}
926*50dad48bSDavid Schultz				else
927*50dad48bSDavid Schultz					sign = 0;
928*50dad48bSDavid Schultz				base = 16;
929*50dad48bSDavid Schultz get_u:
930*50dad48bSDavid Schultz				switch(len) {
931*50dad48bSDavid Schultz				  case 0:
932*50dad48bSDavid Schultz					ui = va_arg(ap, int);
933*50dad48bSDavid Schultz					ul = ui;
934*50dad48bSDavid Schultz					break;
935*50dad48bSDavid Schultz				  case 1:
936*50dad48bSDavid Schultz					ul = va_arg(ap, long);
937*50dad48bSDavid Schultz					break;
938*50dad48bSDavid Schultz				  case 2:
939*50dad48bSDavid Schultz					us = va_arg(ap, int);
940*50dad48bSDavid Schultz					ul = us;
941*50dad48bSDavid Schultz				  }
942*50dad48bSDavid Schultz				if (!ul)
943*50dad48bSDavid Schultz					sign = alt = 0;
944*50dad48bSDavid Schultz				goto baseloop;
945*50dad48bSDavid Schultz			case 'o':
946*50dad48bSDavid Schultz				base = 8;
947*50dad48bSDavid Schultz				digits = hex;
948*50dad48bSDavid Schultz				goto get_u;
949*50dad48bSDavid Schultz			case 's':
950*50dad48bSDavid Schultz				s0 = 0;
951*50dad48bSDavid Schultz				s = va_arg(ap, char*);
952*50dad48bSDavid Schultz				if (!s)
953*50dad48bSDavid Schultz					s = "<NULL>";
954*50dad48bSDavid Schultz				if (prec < 0)
955*50dad48bSDavid Schultz					prec = 0;
956*50dad48bSDavid Schultz have_s:
957*50dad48bSDavid Schultz				if (dot) {
958*50dad48bSDavid Schultz					for(c = 0; c < prec; c++)
959*50dad48bSDavid Schultz						if (!s[c])
960*50dad48bSDavid Schultz							break;
961*50dad48bSDavid Schultz					prec = c;
962*50dad48bSDavid Schultz					}
963*50dad48bSDavid Schultz				else
964*50dad48bSDavid Schultz					prec = strlen(s);
965*50dad48bSDavid Schultz				width -= prec;
966*50dad48bSDavid Schultz				if (!left)
967*50dad48bSDavid Schultz					while(--width >= 0)
968*50dad48bSDavid Schultz						put(' ')
969*50dad48bSDavid Schultz				while(--prec >= 0)
970*50dad48bSDavid Schultz					put(*s++)
971*50dad48bSDavid Schultz				while(--width >= 0)
972*50dad48bSDavid Schultz					put(' ')
973*50dad48bSDavid Schultz				if (s0)
974*50dad48bSDavid Schultz					freedtoa(s0);
975*50dad48bSDavid Schultz				continue;
976*50dad48bSDavid Schultz			case 'f':
977*50dad48bSDavid Schultz				if (!dot)
978*50dad48bSDavid Schultz					prec = 6;
979*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
980*50dad48bSDavid Schultz				if (fpbits == dfpbits) {
981*50dad48bSDavid Schultz#endif
982*50dad48bSDavid Schultz				x = va_arg(ap, double);
983*50dad48bSDavid Schultz				s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
984*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
985*50dad48bSDavid Schultz					}
986*50dad48bSDavid Schultz				else {
987*50dad48bSDavid Schultz#ifdef GDTOA_both
988*50dad48bSDavid Schultz					if (fpbits == GDTOA_LD_fpbits)
989*50dad48bSDavid Schultz						u.ld = va_arg(ap, long double);
990*50dad48bSDavid Schultz					else
991*50dad48bSDavid Schultz						u.Qd = va_arg(ap, GDTOA_Qtype);
992*50dad48bSDavid Schultz#else
993*50dad48bSDavid Schultz					u.ld = va_arg(ap, long double);
994*50dad48bSDavid Schultz#endif
995*50dad48bSDavid Schultz					fpbits(&u, &fpb);
996*50dad48bSDavid Schultz					RoundCheck
997*50dad48bSDavid Schultz					s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
998*50dad48bSDavid Schultz						&fpb.kind, 3, prec, &decpt, &se);
999*50dad48bSDavid Schultz					}
1000*50dad48bSDavid Schultz#endif
1001*50dad48bSDavid Schultz				if (decpt == 9999) {
1002*50dad48bSDavid Schultz fmt9999:
1003*50dad48bSDavid Schultz					dot = prec = alt = 0;
1004*50dad48bSDavid Schultz					if (*s == 'N')
1005*50dad48bSDavid Schultz						goto have_s;
1006*50dad48bSDavid Schultz					decpt = strlen(s);
1007*50dad48bSDavid Schultz					}
1008*50dad48bSDavid Schultz f_fmt:
1009*50dad48bSDavid Schultz				if (fpb.sign && (x||sign))
1010*50dad48bSDavid Schultz					sign = '-';
1011*50dad48bSDavid Schultz				if (prec > 0)
1012*50dad48bSDavid Schultz					width -= prec;
1013*50dad48bSDavid Schultz				if (width > 0) {
1014*50dad48bSDavid Schultz					if (sign)
1015*50dad48bSDavid Schultz						--width;
1016*50dad48bSDavid Schultz					if (decpt <= 0) {
1017*50dad48bSDavid Schultz						--width;
1018*50dad48bSDavid Schultz						if (prec > 0)
1019*50dad48bSDavid Schultz							--width;
1020*50dad48bSDavid Schultz						}
1021*50dad48bSDavid Schultz					else {
1022*50dad48bSDavid Schultz						if (s == se)
1023*50dad48bSDavid Schultz							decpt = 1;
1024*50dad48bSDavid Schultz						width -= decpt;
1025*50dad48bSDavid Schultz						if (prec > 0 || alt)
1026*50dad48bSDavid Schultz							--width;
1027*50dad48bSDavid Schultz						}
1028*50dad48bSDavid Schultz					}
1029*50dad48bSDavid Schultz				if (width > 0 && !left) {
1030*50dad48bSDavid Schultz					if (lead0) {
1031*50dad48bSDavid Schultz						if (sign)
1032*50dad48bSDavid Schultz							put(sign)
1033*50dad48bSDavid Schultz						sign = 0;
1034*50dad48bSDavid Schultz						do put('0')
1035*50dad48bSDavid Schultz							while(--width > 0);
1036*50dad48bSDavid Schultz						}
1037*50dad48bSDavid Schultz					else do put(' ')
1038*50dad48bSDavid Schultz						while(--width > 0);
1039*50dad48bSDavid Schultz					}
1040*50dad48bSDavid Schultz				if (sign)
1041*50dad48bSDavid Schultz					put(sign)
1042*50dad48bSDavid Schultz				if (decpt <= 0) {
1043*50dad48bSDavid Schultz					put('0')
1044*50dad48bSDavid Schultz					if (prec > 0 || alt)
1045*50dad48bSDavid Schultz						put('.')
1046*50dad48bSDavid Schultz					while(decpt < 0) {
1047*50dad48bSDavid Schultz						put('0')
1048*50dad48bSDavid Schultz						prec--;
1049*50dad48bSDavid Schultz						decpt++;
1050*50dad48bSDavid Schultz						}
1051*50dad48bSDavid Schultz					}
1052*50dad48bSDavid Schultz				else {
1053*50dad48bSDavid Schultz					do {
1054*50dad48bSDavid Schultz						if ((c = *s))
1055*50dad48bSDavid Schultz							s++;
1056*50dad48bSDavid Schultz						else
1057*50dad48bSDavid Schultz							c = '0';
1058*50dad48bSDavid Schultz						put(c)
1059*50dad48bSDavid Schultz						}
1060*50dad48bSDavid Schultz						while(--decpt > 0);
1061*50dad48bSDavid Schultz					if (prec > 0 || alt)
1062*50dad48bSDavid Schultz						put('.')
1063*50dad48bSDavid Schultz					}
1064*50dad48bSDavid Schultz				while(--prec >= 0) {
1065*50dad48bSDavid Schultz					if ((c = *s))
1066*50dad48bSDavid Schultz						s++;
1067*50dad48bSDavid Schultz					else
1068*50dad48bSDavid Schultz						c = '0';
1069*50dad48bSDavid Schultz					put(c)
1070*50dad48bSDavid Schultz					}
1071*50dad48bSDavid Schultz				while(--width >= 0)
1072*50dad48bSDavid Schultz					put(' ')
1073*50dad48bSDavid Schultz				if (s0)
1074*50dad48bSDavid Schultz					freedtoa(s0);
1075*50dad48bSDavid Schultz				continue;
1076*50dad48bSDavid Schultz			case 'G':
1077*50dad48bSDavid Schultz			case 'g':
1078*50dad48bSDavid Schultz				if (!dot)
1079*50dad48bSDavid Schultz					prec = 6;
1080*50dad48bSDavid Schultz				if (prec < 0)
1081*50dad48bSDavid Schultz					prec = 0;
1082*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
1083*50dad48bSDavid Schultz				if (fpbits == dfpbits) {
1084*50dad48bSDavid Schultz#endif
1085*50dad48bSDavid Schultz					x = va_arg(ap, double);
1086*50dad48bSDavid Schultz					s = s0 = dtoa(x, prec ? 2 : 0, prec, &decpt,
1087*50dad48bSDavid Schultz						&fpb.sign, &se);
1088*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
1089*50dad48bSDavid Schultz					}
1090*50dad48bSDavid Schultz				else {
1091*50dad48bSDavid Schultz#ifdef GDTOA_both
1092*50dad48bSDavid Schultz					if (fpbits == GDTOA_LD_fpbits)
1093*50dad48bSDavid Schultz						u.ld = va_arg(ap, long double);
1094*50dad48bSDavid Schultz					else
1095*50dad48bSDavid Schultz						u.Qd = va_arg(ap, GDTOA_Qtype);
1096*50dad48bSDavid Schultz#else
1097*50dad48bSDavid Schultz					u.ld = va_arg(ap, long double);
1098*50dad48bSDavid Schultz#endif
1099*50dad48bSDavid Schultz					fpbits(&u, &fpb);
1100*50dad48bSDavid Schultz					RoundCheck
1101*50dad48bSDavid Schultz					s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
1102*50dad48bSDavid Schultz						&fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
1103*50dad48bSDavid Schultz					}
1104*50dad48bSDavid Schultz#endif
1105*50dad48bSDavid Schultz				if (decpt == 9999)
1106*50dad48bSDavid Schultz					goto fmt9999;
1107*50dad48bSDavid Schultz				c = se - s;
1108*50dad48bSDavid Schultz				prec1 = prec;
1109*50dad48bSDavid Schultz				if (!prec) {
1110*50dad48bSDavid Schultz					prec = c;
1111*50dad48bSDavid Schultz					prec1 = c + (s[1] || alt ? 5 : 4);
1112*50dad48bSDavid Schultz					/* %.0g gives 10 rather than 1e1 */
1113*50dad48bSDavid Schultz					}
1114*50dad48bSDavid Schultz				if (decpt > -4 && decpt <= prec1) {
1115*50dad48bSDavid Schultz					if (alt)
1116*50dad48bSDavid Schultz						prec -= decpt;
1117*50dad48bSDavid Schultz					else
1118*50dad48bSDavid Schultz						prec = c - decpt;
1119*50dad48bSDavid Schultz					if (prec < 0)
1120*50dad48bSDavid Schultz						prec = 0;
1121*50dad48bSDavid Schultz					goto f_fmt;
1122*50dad48bSDavid Schultz					}
1123*50dad48bSDavid Schultz				conv -= 2;
1124*50dad48bSDavid Schultz				if (!alt && prec > c)
1125*50dad48bSDavid Schultz					prec = c;
1126*50dad48bSDavid Schultz				--prec;
1127*50dad48bSDavid Schultz				goto e_fmt;
1128*50dad48bSDavid Schultz			case 'e':
1129*50dad48bSDavid Schultz			case 'E':
1130*50dad48bSDavid Schultz				if (!dot)
1131*50dad48bSDavid Schultz					prec = 6;
1132*50dad48bSDavid Schultz				if (prec < 0)
1133*50dad48bSDavid Schultz					prec = 0;
1134*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
1135*50dad48bSDavid Schultz				if (fpbits == dfpbits) {
1136*50dad48bSDavid Schultz#endif
1137*50dad48bSDavid Schultz					x = va_arg(ap, double);
1138*50dad48bSDavid Schultz					s = s0 = dtoa(x, prec ? 2 : 0, prec+1, &decpt,
1139*50dad48bSDavid Schultz						&fpb.sign, &se);
1140*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED
1141*50dad48bSDavid Schultz					}
1142*50dad48bSDavid Schultz				else {
1143*50dad48bSDavid Schultz#ifdef GDTOA_both
1144*50dad48bSDavid Schultz					if (fpbits == GDTOA_LD_fpbits)
1145*50dad48bSDavid Schultz						u.ld = va_arg(ap, long double);
1146*50dad48bSDavid Schultz					else
1147*50dad48bSDavid Schultz						u.Qd = va_arg(ap, GDTOA_Qtype);
1148*50dad48bSDavid Schultz#else
1149*50dad48bSDavid Schultz					u.ld = va_arg(ap, long double);
1150*50dad48bSDavid Schultz#endif
1151*50dad48bSDavid Schultz					fpbits(&u, &fpb);
1152*50dad48bSDavid Schultz					RoundCheck
1153*50dad48bSDavid Schultz					s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
1154*50dad48bSDavid Schultz						&fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
1155*50dad48bSDavid Schultz					}
1156*50dad48bSDavid Schultz#endif
1157*50dad48bSDavid Schultz				if (decpt == 9999)
1158*50dad48bSDavid Schultz					goto fmt9999;
1159*50dad48bSDavid Schultz e_fmt:
1160*50dad48bSDavid Schultz				if (fpb.sign && (x||sign))
1161*50dad48bSDavid Schultz					sign = '-';
1162*50dad48bSDavid Schultz				if ((width -= prec + 5) > 0) {
1163*50dad48bSDavid Schultz					if (sign)
1164*50dad48bSDavid Schultz						--width;
1165*50dad48bSDavid Schultz					if (prec || alt)
1166*50dad48bSDavid Schultz						--width;
1167*50dad48bSDavid Schultz					}
1168*50dad48bSDavid Schultz				if ((c = --decpt) < 0)
1169*50dad48bSDavid Schultz					c = -c;
1170*50dad48bSDavid Schultz				while(c >= 100) {
1171*50dad48bSDavid Schultz					--width;
1172*50dad48bSDavid Schultz					c /= 10;
1173*50dad48bSDavid Schultz					}
1174*50dad48bSDavid Schultz				if (width > 0 && !left) {
1175*50dad48bSDavid Schultz					if (lead0) {
1176*50dad48bSDavid Schultz						if (sign)
1177*50dad48bSDavid Schultz							put(sign)
1178*50dad48bSDavid Schultz						sign = 0;
1179*50dad48bSDavid Schultz						do put('0')
1180*50dad48bSDavid Schultz							while(--width > 0);
1181*50dad48bSDavid Schultz						}
1182*50dad48bSDavid Schultz					else do put(' ')
1183*50dad48bSDavid Schultz						while(--width > 0);
1184*50dad48bSDavid Schultz					}
1185*50dad48bSDavid Schultz				if (sign)
1186*50dad48bSDavid Schultz					put(sign)
1187*50dad48bSDavid Schultz				put(*s++)
1188*50dad48bSDavid Schultz				if (prec || alt)
1189*50dad48bSDavid Schultz					put('.')
1190*50dad48bSDavid Schultz				while(--prec >= 0) {
1191*50dad48bSDavid Schultz					if ((c = *s))
1192*50dad48bSDavid Schultz						s++;
1193*50dad48bSDavid Schultz					else
1194*50dad48bSDavid Schultz						c = '0';
1195*50dad48bSDavid Schultz					put(c)
1196*50dad48bSDavid Schultz					}
1197*50dad48bSDavid Schultz				put(conv)
1198*50dad48bSDavid Schultz				if (decpt < 0) {
1199*50dad48bSDavid Schultz					put('-')
1200*50dad48bSDavid Schultz					decpt = -decpt;
1201*50dad48bSDavid Schultz					}
1202*50dad48bSDavid Schultz				else
1203*50dad48bSDavid Schultz					put('+')
1204*50dad48bSDavid Schultz				for(c = 2, k = 10; 10*k <= decpt; c++, k *= 10);
1205*50dad48bSDavid Schultz				for(;;) {
1206*50dad48bSDavid Schultz					i1 = decpt / k;
1207*50dad48bSDavid Schultz					put(i1 + '0')
1208*50dad48bSDavid Schultz					if (--c <= 0)
1209*50dad48bSDavid Schultz						break;
1210*50dad48bSDavid Schultz					decpt -= i1*k;
1211*50dad48bSDavid Schultz					decpt *= 10;
1212*50dad48bSDavid Schultz					}
1213*50dad48bSDavid Schultz				while(--width >= 0)
1214*50dad48bSDavid Schultz					put(' ')
1215*50dad48bSDavid Schultz				freedtoa(s0);
1216*50dad48bSDavid Schultz				continue;
1217*50dad48bSDavid Schultz#ifndef NO_PRINTF_A_FMT
1218*50dad48bSDavid Schultz			case 'a':
1219*50dad48bSDavid Schultz				digits = hex;
1220*50dad48bSDavid Schultz				goto more_a;
1221*50dad48bSDavid Schultz			case 'A':
1222*50dad48bSDavid Schultz				digits = Hex;
1223*50dad48bSDavid Schultz more_a:
1224*50dad48bSDavid Schultz#ifdef GDTOA_H_INCLUDED /*{{*/
1225*50dad48bSDavid Schultz				if (fpbits == dfpbits)
1226*50dad48bSDavid Schultz					u.d = va_arg(ap, double);
1227*50dad48bSDavid Schultz#ifdef GDTOA_both /*{*/
1228*50dad48bSDavid Schultz				else if (fpbits == GDTOA_LD_fpbits)
1229*50dad48bSDavid Schultz					u.ld = va_arg(ap, long double);
1230*50dad48bSDavid Schultz				else
1231*50dad48bSDavid Schultz					u.Qd = va_arg(ap, GDTOA_Qtype);
1232*50dad48bSDavid Schultz#else
1233*50dad48bSDavid Schultz				else
1234*50dad48bSDavid Schultz					u.ld = va_arg(ap, long double);
1235*50dad48bSDavid Schultz#endif /*}*/
1236*50dad48bSDavid Schultz#else /*}{*/
1237*50dad48bSDavid Schultz				u.d = va_arg(ap, double);
1238*50dad48bSDavid Schultz#endif /*}}*/
1239*50dad48bSDavid Schultz				fpbits(&u, &fpb);
1240*50dad48bSDavid Schultz				if (fpb.kind == STRTOG_Infinite) {
1241*50dad48bSDavid Schultz					s = "Infinity";
1242*50dad48bSDavid Schultz					s0 = 0;
1243*50dad48bSDavid Schultz					goto fmt9999;
1244*50dad48bSDavid Schultz					}
1245*50dad48bSDavid Schultz				if (fpb.kind == STRTOG_NaN) {
1246*50dad48bSDavid Schultz					s = "NaN";
1247*50dad48bSDavid Schultz					s0 = 0;
1248*50dad48bSDavid Schultz					goto fmt9999;
1249*50dad48bSDavid Schultz					}
1250*50dad48bSDavid Schultz				prec1 = fpiprec(&fpb);
1251*50dad48bSDavid Schultz				if (dot && prec < prec1)
1252*50dad48bSDavid Schultz					prec1 = bround(&fpb, prec, prec1);
1253*50dad48bSDavid Schultz				bw = 1;
1254*50dad48bSDavid Schultz				bex = fpb.ex + 4*prec1;
1255*50dad48bSDavid Schultz				if (bex) {
1256*50dad48bSDavid Schultz					if ((i1 = bex) < 0)
1257*50dad48bSDavid Schultz						i1 = -i1;
1258*50dad48bSDavid Schultz					while(i1 >= 10) {
1259*50dad48bSDavid Schultz						++bw;
1260*50dad48bSDavid Schultz						i1 /= 10;
1261*50dad48bSDavid Schultz						}
1262*50dad48bSDavid Schultz					}
1263*50dad48bSDavid Schultz				if (fpb.sign && (sign || fpb.kind != STRTOG_Zero))
1264*50dad48bSDavid Schultz					sign = '-';
1265*50dad48bSDavid Schultz				if ((width -= bw + 5) > 0) {
1266*50dad48bSDavid Schultz					if (sign)
1267*50dad48bSDavid Schultz						--width;
1268*50dad48bSDavid Schultz					if (prec1 || alt)
1269*50dad48bSDavid Schultz						--width;
1270*50dad48bSDavid Schultz					}
1271*50dad48bSDavid Schultz				if ((width -= prec1) > 0 && !left && !lead0) {
1272*50dad48bSDavid Schultz					do put(' ')
1273*50dad48bSDavid Schultz						while(--width > 0);
1274*50dad48bSDavid Schultz					}
1275*50dad48bSDavid Schultz				if (sign)
1276*50dad48bSDavid Schultz					put(sign)
1277*50dad48bSDavid Schultz				put('0')
1278*50dad48bSDavid Schultz				put(digits[17])
1279*50dad48bSDavid Schultz				if (lead0 && width > 0 && !left) {
1280*50dad48bSDavid Schultz					do put('0')
1281*50dad48bSDavid Schultz						while(--width > 0);
1282*50dad48bSDavid Schultz					}
1283*50dad48bSDavid Schultz				i1 = prec1 & 7;
1284*50dad48bSDavid Schultz				k = prec1 >> 3;
1285*50dad48bSDavid Schultz				put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
1286*50dad48bSDavid Schultz				if (prec1 > 0 || alt)
1287*50dad48bSDavid Schultz					put('.')
1288*50dad48bSDavid Schultz				if (prec1 > 0) {
1289*50dad48bSDavid Schultz					prec -= prec1;
1290*50dad48bSDavid Schultz					while(prec1 > 0) {
1291*50dad48bSDavid Schultz						if (--i1 < 0) {
1292*50dad48bSDavid Schultz							if (--k < 0)
1293*50dad48bSDavid Schultz								break;
1294*50dad48bSDavid Schultz							i1 = 7;
1295*50dad48bSDavid Schultz							}
1296*50dad48bSDavid Schultz						put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
1297*50dad48bSDavid Schultz						--prec1;
1298*50dad48bSDavid Schultz						}
1299*50dad48bSDavid Schultz					if (alt && prec > 0)
1300*50dad48bSDavid Schultz						do put(0)
1301*50dad48bSDavid Schultz							while(--prec > 0);
1302*50dad48bSDavid Schultz					}
1303*50dad48bSDavid Schultz				put(digits[16])
1304*50dad48bSDavid Schultz				if (bex < 0) {
1305*50dad48bSDavid Schultz					put('-')
1306*50dad48bSDavid Schultz					bex = -bex;
1307*50dad48bSDavid Schultz					}
1308*50dad48bSDavid Schultz				else
1309*50dad48bSDavid Schultz					put('+')
1310*50dad48bSDavid Schultz				for(c = 1; 10*c <= bex; c *= 10);
1311*50dad48bSDavid Schultz				for(;;) {
1312*50dad48bSDavid Schultz					i1 = bex / c;
1313*50dad48bSDavid Schultz					put('0' + i1)
1314*50dad48bSDavid Schultz					if (!--bw)
1315*50dad48bSDavid Schultz						break;
1316*50dad48bSDavid Schultz					bex -= i1 * c;
1317*50dad48bSDavid Schultz					bex *= 10;
1318*50dad48bSDavid Schultz					}
1319*50dad48bSDavid Schultz				while(--width >= 0)
1320*50dad48bSDavid Schultz					put(' ')
1321*50dad48bSDavid Schultz				continue;
1322*50dad48bSDavid Schultz#endif /* NO_PRINTF_A_FMT */
1323*50dad48bSDavid Schultz			default:
1324*50dad48bSDavid Schultz				put('%')
1325*50dad48bSDavid Schultz				while(fmt0 < fmt)
1326*50dad48bSDavid Schultz					put(*fmt0++)
1327*50dad48bSDavid Schultz				continue;
1328*50dad48bSDavid Schultz			}
1329*50dad48bSDavid Schultz		}
1330*50dad48bSDavid Schultz done:
1331*50dad48bSDavid Schultz	*outbuf = 0;
1332*50dad48bSDavid Schultz	return (f->lastlen = outbuf - ob0) + rv;
1333*50dad48bSDavid Schultz	}
1334*50dad48bSDavid Schultz
1335*50dad48bSDavid Schultz#define Bsize 256
1336*50dad48bSDavid Schultz
1337*50dad48bSDavid Schultz int
1338*50dad48bSDavid SchultzPrintf
1339*50dad48bSDavid Schultz#ifdef KR_headers
1340*50dad48bSDavid Schultz	(va_alist)
1341*50dad48bSDavid Schultz va_dcl
1342*50dad48bSDavid Schultz{
1343*50dad48bSDavid Schultz	char *fmt;
1344*50dad48bSDavid Schultz
1345*50dad48bSDavid Schultz	va_list ap;
1346*50dad48bSDavid Schultz	int rv;
1347*50dad48bSDavid Schultz	Finfo f;
1348*50dad48bSDavid Schultz	char buf[Bsize];
1349*50dad48bSDavid Schultz
1350*50dad48bSDavid Schultz	va_start(ap);
1351*50dad48bSDavid Schultz	fmt = va_arg(ap, char*);
1352*50dad48bSDavid Schultz	/*}*/
1353*50dad48bSDavid Schultz#else
1354*50dad48bSDavid Schultz	(const char *fmt, ...)
1355*50dad48bSDavid Schultz{
1356*50dad48bSDavid Schultz	va_list ap;
1357*50dad48bSDavid Schultz	int rv;
1358*50dad48bSDavid Schultz	Finfo f;
1359*50dad48bSDavid Schultz	char buf[Bsize];
1360*50dad48bSDavid Schultz
1361*50dad48bSDavid Schultz	va_start(ap, fmt);
1362*50dad48bSDavid Schultz#endif
1363*50dad48bSDavid Schultz	f.u.cf = stdout;
1364*50dad48bSDavid Schultz	f.ob0 = buf;
1365*50dad48bSDavid Schultz	f.obe1 = buf + Bsize - 1;
1366*50dad48bSDavid Schultz#ifdef _windows_
1367*50dad48bSDavid Schultz	if (fileno(stdout) == stdout_fileno_ASL) {
1368*50dad48bSDavid Schultz		rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1369*50dad48bSDavid Schultz		mwrite(buf, f.lastlen);
1370*50dad48bSDavid Schultz		}
1371*50dad48bSDavid Schultz	else
1372*50dad48bSDavid Schultz#endif
1373*50dad48bSDavid Schultz#ifdef PF_BUF
1374*50dad48bSDavid Schultz	if (stdout == stderr_ASL) {
1375*50dad48bSDavid Schultz		rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1376*50dad48bSDavid Schultz		pf_put(buf, f.lastlen);
1377*50dad48bSDavid Schultz		}
1378*50dad48bSDavid Schultz	else
1379*50dad48bSDavid Schultz#endif
1380*50dad48bSDavid Schultz		{
1381*50dad48bSDavid Schultz		rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1382*50dad48bSDavid Schultz		fputs(buf, stdout);
1383*50dad48bSDavid Schultz		}
1384*50dad48bSDavid Schultz	va_end(ap);
1385*50dad48bSDavid Schultz	return rv;
1386*50dad48bSDavid Schultz	}
1387*50dad48bSDavid Schultz
1388*50dad48bSDavid Schultz static char *
1389*50dad48bSDavid SchultzSput
1390*50dad48bSDavid Schultz#ifdef KR_headers
1391*50dad48bSDavid Schultz	(f, rvp) Finfo *f; int *rvp;
1392*50dad48bSDavid Schultz#else
1393*50dad48bSDavid Schultz	(Finfo *f, int *rvp)
1394*50dad48bSDavid Schultz#endif
1395*50dad48bSDavid Schultz{
1396*50dad48bSDavid Schultz	if (Printf("\nBUG! Sput called!\n", f, rvp))
1397*50dad48bSDavid Schultz		/* pass vp, rvp and return 0 to shut diagnostics off */
1398*50dad48bSDavid Schultz		exit(250);
1399*50dad48bSDavid Schultz	return 0;
1400*50dad48bSDavid Schultz	}
1401*50dad48bSDavid Schultz
1402*50dad48bSDavid Schultz int
1403*50dad48bSDavid SchultzSprintf
1404*50dad48bSDavid Schultz#ifdef KR_headers
1405*50dad48bSDavid Schultz	(va_alist)
1406*50dad48bSDavid Schultz va_dcl
1407*50dad48bSDavid Schultz{
1408*50dad48bSDavid Schultz	char *s, *fmt;
1409*50dad48bSDavid Schultz	va_list ap;
1410*50dad48bSDavid Schultz	int rv;
1411*50dad48bSDavid Schultz	Finfo f;
1412*50dad48bSDavid Schultz
1413*50dad48bSDavid Schultz	va_start(ap);
1414*50dad48bSDavid Schultz	s = va_arg(ap, char*);
1415*50dad48bSDavid Schultz	fmt = va_arg(ap, char*);
1416*50dad48bSDavid Schultz	/*}*/
1417*50dad48bSDavid Schultz#else
1418*50dad48bSDavid Schultz	(char *s, const char *fmt, ...)
1419*50dad48bSDavid Schultz{
1420*50dad48bSDavid Schultz	va_list ap;
1421*50dad48bSDavid Schultz	int rv;
1422*50dad48bSDavid Schultz	Finfo f;
1423*50dad48bSDavid Schultz
1424*50dad48bSDavid Schultz	va_start(ap, fmt);
1425*50dad48bSDavid Schultz#endif
1426*50dad48bSDavid Schultz	f.ob0 = s;
1427*50dad48bSDavid Schultz	rv = x_sprintf(s, Sput, &f, fmt, ap);
1428*50dad48bSDavid Schultz	va_end(ap);
1429*50dad48bSDavid Schultz	return rv;
1430*50dad48bSDavid Schultz	}
1431*50dad48bSDavid Schultz
1432*50dad48bSDavid Schultz int
1433*50dad48bSDavid SchultzFprintf
1434*50dad48bSDavid Schultz#ifdef KR_headers
1435*50dad48bSDavid Schultz	(va_alist)
1436*50dad48bSDavid Schultz va_dcl
1437*50dad48bSDavid Schultz{
1438*50dad48bSDavid Schultz	FILE *F;
1439*50dad48bSDavid Schultz	char *s, *fmt;
1440*50dad48bSDavid Schultz	va_list ap;
1441*50dad48bSDavid Schultz	int rv;
1442*50dad48bSDavid Schultz	Finfo f;
1443*50dad48bSDavid Schultz	char buf[Bsize];
1444*50dad48bSDavid Schultz
1445*50dad48bSDavid Schultz	va_start(ap);
1446*50dad48bSDavid Schultz	F = va_arg(ap, FILE*);
1447*50dad48bSDavid Schultz	fmt = va_arg(ap, char*);
1448*50dad48bSDavid Schultz	/*}*/
1449*50dad48bSDavid Schultz#else
1450*50dad48bSDavid Schultz	(FILE *F, const char *fmt, ...)
1451*50dad48bSDavid Schultz{
1452*50dad48bSDavid Schultz	va_list ap;
1453*50dad48bSDavid Schultz	int rv;
1454*50dad48bSDavid Schultz	Finfo f;
1455*50dad48bSDavid Schultz	char buf[Bsize];
1456*50dad48bSDavid Schultz
1457*50dad48bSDavid Schultz	va_start(ap, fmt);
1458*50dad48bSDavid Schultz#endif
1459*50dad48bSDavid Schultz	f.u.cf = F;
1460*50dad48bSDavid Schultz	f.ob0 = buf;
1461*50dad48bSDavid Schultz	f.obe1 = buf + Bsize - 1;
1462*50dad48bSDavid Schultz#ifdef MESS
1463*50dad48bSDavid Schultz	if (stdout_or_err(F)) {
1464*50dad48bSDavid Schultz#ifdef _windows_
1465*50dad48bSDavid Schultz		if (fileno(stdout) == stdout_fileno_ASL) {
1466*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1467*50dad48bSDavid Schultz			mwrite(buf, f.lastlen);
1468*50dad48bSDavid Schultz			}
1469*50dad48bSDavid Schultz		else
1470*50dad48bSDavid Schultz#endif
1471*50dad48bSDavid Schultz#ifdef PF_BUF
1472*50dad48bSDavid Schultz		if (F == stderr_ASL) {
1473*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1474*50dad48bSDavid Schultz			pf_put(buf, f.lastlen);
1475*50dad48bSDavid Schultz			}
1476*50dad48bSDavid Schultz		else
1477*50dad48bSDavid Schultz#endif
1478*50dad48bSDavid Schultz			{
1479*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1480*50dad48bSDavid Schultz			fputs(buf, F);
1481*50dad48bSDavid Schultz			}
1482*50dad48bSDavid Schultz		}
1483*50dad48bSDavid Schultz	else
1484*50dad48bSDavid Schultz#endif /*MESS*/
1485*50dad48bSDavid Schultz		{
1486*50dad48bSDavid Schultz#ifdef PF_BUF
1487*50dad48bSDavid Schultz		if (F == stderr_ASL) {
1488*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1489*50dad48bSDavid Schultz			pf_put(buf, f.lastlen);
1490*50dad48bSDavid Schultz			}
1491*50dad48bSDavid Schultz	else
1492*50dad48bSDavid Schultz#endif
1493*50dad48bSDavid Schultz			{
1494*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1495*50dad48bSDavid Schultz			fputs(buf, F);
1496*50dad48bSDavid Schultz			}
1497*50dad48bSDavid Schultz		}
1498*50dad48bSDavid Schultz	va_end(ap);
1499*50dad48bSDavid Schultz	return rv;
1500*50dad48bSDavid Schultz	}
1501*50dad48bSDavid Schultz
1502*50dad48bSDavid Schultz int
1503*50dad48bSDavid SchultzVsprintf
1504*50dad48bSDavid Schultz#ifdef KR_headers
1505*50dad48bSDavid Schultz	(s, fmt, ap) char *s, *fmt; va_list ap;
1506*50dad48bSDavid Schultz#else
1507*50dad48bSDavid Schultz	(char *s, const char *fmt, va_list ap)
1508*50dad48bSDavid Schultz#endif
1509*50dad48bSDavid Schultz{
1510*50dad48bSDavid Schultz	Finfo f;
1511*50dad48bSDavid Schultz	return x_sprintf(f.ob0 = s, Sput, &f, fmt, ap);
1512*50dad48bSDavid Schultz	}
1513*50dad48bSDavid Schultz
1514*50dad48bSDavid Schultz int
1515*50dad48bSDavid SchultzVfprintf
1516*50dad48bSDavid Schultz#ifdef KR_headers
1517*50dad48bSDavid Schultz	(F, fmt, ap) FILE *F; char *fmt; va_list ap;
1518*50dad48bSDavid Schultz#else
1519*50dad48bSDavid Schultz	(FILE *F, const char *fmt, va_list ap)
1520*50dad48bSDavid Schultz#endif
1521*50dad48bSDavid Schultz{
1522*50dad48bSDavid Schultz	char buf[Bsize];
1523*50dad48bSDavid Schultz	int rv;
1524*50dad48bSDavid Schultz	Finfo f;
1525*50dad48bSDavid Schultz
1526*50dad48bSDavid Schultz	f.u.cf = F;
1527*50dad48bSDavid Schultz	f.ob0 = buf;
1528*50dad48bSDavid Schultz	f.obe1 = buf + Bsize - 1;
1529*50dad48bSDavid Schultz#ifdef MESS
1530*50dad48bSDavid Schultz	if (stdout_or_err(F)) {
1531*50dad48bSDavid Schultz#ifdef _windows_
1532*50dad48bSDavid Schultz		if (fileno(stdout) == stdout_fileno_ASL) {
1533*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
1534*50dad48bSDavid Schultz			mwrite(buf, f.lastlen);
1535*50dad48bSDavid Schultz			}
1536*50dad48bSDavid Schultz		else
1537*50dad48bSDavid Schultz#endif
1538*50dad48bSDavid Schultz#ifdef PF_BUF
1539*50dad48bSDavid Schultz		if (F == stderr_ASL) {
1540*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1541*50dad48bSDavid Schultz			pf_put(buf, f.lastlen);
1542*50dad48bSDavid Schultz			}
1543*50dad48bSDavid Schultz		else
1544*50dad48bSDavid Schultz#endif
1545*50dad48bSDavid Schultz			{
1546*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1547*50dad48bSDavid Schultz			fputs(buf, F);
1548*50dad48bSDavid Schultz			}
1549*50dad48bSDavid Schultz		}
1550*50dad48bSDavid Schultz	else
1551*50dad48bSDavid Schultz#endif /*MESS*/
1552*50dad48bSDavid Schultz		{
1553*50dad48bSDavid Schultz#ifdef PF_BUF
1554*50dad48bSDavid Schultz		if (F == stderr_ASL) {
1555*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
1556*50dad48bSDavid Schultz			pf_put(buf, f.lastlen);
1557*50dad48bSDavid Schultz			}
1558*50dad48bSDavid Schultz		else
1559*50dad48bSDavid Schultz#endif
1560*50dad48bSDavid Schultz			{
1561*50dad48bSDavid Schultz			rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
1562*50dad48bSDavid Schultz			fputs(buf, F);
1563*50dad48bSDavid Schultz			}
1564*50dad48bSDavid Schultz		}
1565*50dad48bSDavid Schultz	va_end(ap);
1566*50dad48bSDavid Schultz	return rv;
1567*50dad48bSDavid Schultz	}
1568*50dad48bSDavid Schultz
1569*50dad48bSDavid Schultz void
1570*50dad48bSDavid SchultzPerror
1571*50dad48bSDavid Schultz#ifdef KR_headers
1572*50dad48bSDavid Schultz	(s) char *s;
1573*50dad48bSDavid Schultz#else
1574*50dad48bSDavid Schultz	(const char *s)
1575*50dad48bSDavid Schultz#endif
1576*50dad48bSDavid Schultz{
1577*50dad48bSDavid Schultz	if (s && *s)
1578*50dad48bSDavid Schultz		Fprintf(Stderr, "%s: ", s);
1579*50dad48bSDavid Schultz	Fprintf(Stderr, "%s\n", strerror(errno));
1580*50dad48bSDavid Schultz	}
1581*50dad48bSDavid Schultz
1582*50dad48bSDavid Schultz static char *
1583*50dad48bSDavid SchultzSnput
1584*50dad48bSDavid Schultz#ifdef KR_headers
1585*50dad48bSDavid Schultz	(f, rvp) Finfo *f; int *rvp;
1586*50dad48bSDavid Schultz#else
1587*50dad48bSDavid Schultz	(Finfo *f, int *rvp)
1588*50dad48bSDavid Schultz#endif
1589*50dad48bSDavid Schultz{
1590*50dad48bSDavid Schultz	char *s, *s0;
1591*50dad48bSDavid Schultz	size_t L;
1592*50dad48bSDavid Schultz
1593*50dad48bSDavid Schultz	*rvp += Bsize;
1594*50dad48bSDavid Schultz	s0 = f->ob0;
1595*50dad48bSDavid Schultz	s = f->u.sf;
1596*50dad48bSDavid Schultz	if ((L = f->obe1 - s) > Bsize) {
1597*50dad48bSDavid Schultz		L = Bsize;
1598*50dad48bSDavid Schultz		goto copy;
1599*50dad48bSDavid Schultz		}
1600*50dad48bSDavid Schultz	if (L > 0) {
1601*50dad48bSDavid Schultz copy:
1602*50dad48bSDavid Schultz		memcpy(s, s0, L);
1603*50dad48bSDavid Schultz		f->u.sf = s + L;
1604*50dad48bSDavid Schultz		}
1605*50dad48bSDavid Schultz	return s0;
1606*50dad48bSDavid Schultz	}
1607*50dad48bSDavid Schultz
1608*50dad48bSDavid Schultz int
1609*50dad48bSDavid SchultzVsnprintf
1610*50dad48bSDavid Schultz#ifdef KR_headers
1611*50dad48bSDavid Schultz	(s, n, fmt, ap) char *s; size_t n; char *fmt; va_list ap;
1612*50dad48bSDavid Schultz#else
1613*50dad48bSDavid Schultz	(char *s, size_t n, const char *fmt, va_list ap)
1614*50dad48bSDavid Schultz#endif
1615*50dad48bSDavid Schultz{
1616*50dad48bSDavid Schultz	Finfo f;
1617*50dad48bSDavid Schultz	char buf[Bsize];
1618*50dad48bSDavid Schultz	int L, rv;
1619*50dad48bSDavid Schultz
1620*50dad48bSDavid Schultz	if (n <= 0 || !s) {
1621*50dad48bSDavid Schultz		n = 1;
1622*50dad48bSDavid Schultz		s = buf;
1623*50dad48bSDavid Schultz		}
1624*50dad48bSDavid Schultz	f.u.sf = s;
1625*50dad48bSDavid Schultz	f.ob0 = buf;
1626*50dad48bSDavid Schultz	f.obe1 = s + n - 1;
1627*50dad48bSDavid Schultz	rv = x_sprintf(buf + Bsize, Snput, &f, fmt, ap);
1628*50dad48bSDavid Schultz	if (f.lastlen > (L = f.obe1 - f.u.sf))
1629*50dad48bSDavid Schultz		f.lastlen = L;
1630*50dad48bSDavid Schultz	if (f.lastlen > 0) {
1631*50dad48bSDavid Schultz		memcpy(f.u.sf, buf, f.lastlen);
1632*50dad48bSDavid Schultz		f.u.sf += f.lastlen;
1633*50dad48bSDavid Schultz		}
1634*50dad48bSDavid Schultz	*f.u.sf = 0;
1635*50dad48bSDavid Schultz	return rv;
1636*50dad48bSDavid Schultz	}
1637*50dad48bSDavid Schultz int
1638*50dad48bSDavid SchultzSnprintf
1639*50dad48bSDavid Schultz#ifdef KR_headers
1640*50dad48bSDavid Schultz	(va_alist)
1641*50dad48bSDavid Schultz va_dcl
1642*50dad48bSDavid Schultz{
1643*50dad48bSDavid Schultz	char *s, *fmt;
1644*50dad48bSDavid Schultz	int rv;
1645*50dad48bSDavid Schultz	size_t n;
1646*50dad48bSDavid Schultz	va_list ap;
1647*50dad48bSDavid Schultz
1648*50dad48bSDavid Schultz	va_start(ap);
1649*50dad48bSDavid Schultz	s = va_arg(ap, char*);
1650*50dad48bSDavid Schultz	n = va_arg(ap, size_t);
1651*50dad48bSDavid Schultz	fmt = va_arg(ap, char*);
1652*50dad48bSDavid Schultz	/*}*/
1653*50dad48bSDavid Schultz#else
1654*50dad48bSDavid Schultz	(char *s, size_t n, const char *fmt, ...)
1655*50dad48bSDavid Schultz{
1656*50dad48bSDavid Schultz	int rv;
1657*50dad48bSDavid Schultz	va_list ap;
1658*50dad48bSDavid Schultz
1659*50dad48bSDavid Schultz	va_start(ap, fmt);
1660*50dad48bSDavid Schultz#endif
1661*50dad48bSDavid Schultz	rv = Vsnprintf(s, n, fmt, ap);
1662*50dad48bSDavid Schultz	va_end(ap);
1663*50dad48bSDavid Schultz	return rv;
1664*50dad48bSDavid Schultz	}
1665*50dad48bSDavid Schultz
1666*50dad48bSDavid Schultz
1667*50dad48bSDavid Schultz#ifdef __cplusplus
1668*50dad48bSDavid Schultz}
1669*50dad48bSDavid Schultz#endif
1670