xref: /freebsd/contrib/tcsh/tc.printf.c (revision 2930157267fc56387bb43acf5bb441a84ff6e765)
129301572SMark Peek /* $Header: /src/pub/tcsh/tc.printf.c,v 3.23 2002/03/08 17:36:47 christos Exp $ */
2c80476e4SDavid E. O'Brien /*
3c80476e4SDavid E. O'Brien  * tc.printf.c: A public-domain, minimal printf/sprintf routine that prints
4c80476e4SDavid E. O'Brien  *	       through the putchar() routine.  Feel free to use for
5c80476e4SDavid E. O'Brien  *	       anything...  -- 7/17/87 Paul Placeway
6c80476e4SDavid E. O'Brien  */
7c80476e4SDavid E. O'Brien /*-
8c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
9c80476e4SDavid E. O'Brien  * All rights reserved.
10c80476e4SDavid E. O'Brien  *
11c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
12c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
13c80476e4SDavid E. O'Brien  * are met:
14c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
15c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
16c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
17c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
18c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1929301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
20c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
21c80476e4SDavid E. O'Brien  *    without specific prior written permission.
22c80476e4SDavid E. O'Brien  *
23c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
34c80476e4SDavid E. O'Brien  */
35c80476e4SDavid E. O'Brien #include "sh.h"
36c80476e4SDavid E. O'Brien 
3729301572SMark Peek RCSID("$Id: tc.printf.c,v 3.23 2002/03/08 17:36:47 christos Exp $")
38c80476e4SDavid E. O'Brien 
39c80476e4SDavid E. O'Brien #ifdef lint
40c80476e4SDavid E. O'Brien #undef va_arg
41c80476e4SDavid E. O'Brien #define va_arg(a, b) (a ? (b) 0 : (b) 0)
42c80476e4SDavid E. O'Brien #endif
43c80476e4SDavid E. O'Brien 
44c80476e4SDavid E. O'Brien #define INF	32766		/* should be bigger than any field to print */
45c80476e4SDavid E. O'Brien 
46c80476e4SDavid E. O'Brien static char buf[128];
47c80476e4SDavid E. O'Brien 
48c80476e4SDavid E. O'Brien static	void	xaddchar	__P((int));
49c80476e4SDavid E. O'Brien static	void	doprnt		__P((void (*) __P((int)), const char *, va_list));
50c80476e4SDavid E. O'Brien 
51c80476e4SDavid E. O'Brien static void
52c80476e4SDavid E. O'Brien doprnt(addchar, sfmt, ap)
53c80476e4SDavid E. O'Brien     void    (*addchar) __P((int));
54c80476e4SDavid E. O'Brien     const char   *sfmt;
55c80476e4SDavid E. O'Brien     va_list ap;
56c80476e4SDavid E. O'Brien {
5729301572SMark Peek     char *bp;
5829301572SMark Peek     const char *f;
59c80476e4SDavid E. O'Brien #ifdef SHORT_STRINGS
6029301572SMark Peek     Char *Bp;
61c80476e4SDavid E. O'Brien #endif /* SHORT_STRINGS */
6229301572SMark Peek #ifdef HAVE_QUAD
6329301572SMark Peek     long long l;
6429301572SMark Peek     unsigned long long u;
6529301572SMark Peek #else
6629301572SMark Peek     long l;
6729301572SMark Peek     unsigned long u;
6829301572SMark Peek #endif
6929301572SMark Peek     int i;
7029301572SMark Peek     int fmt;
7129301572SMark Peek     unsigned char pad = ' ';
72c80476e4SDavid E. O'Brien     int     flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
73c80476e4SDavid E. O'Brien     int     sign = 0;
74c80476e4SDavid E. O'Brien     int     attributes = 0;
75c80476e4SDavid E. O'Brien 
76c80476e4SDavid E. O'Brien 
77c80476e4SDavid E. O'Brien     f = sfmt;
78c80476e4SDavid E. O'Brien     for (; *f; f++) {
79c80476e4SDavid E. O'Brien 	if (*f != '%') {	/* then just out the char */
80c80476e4SDavid E. O'Brien 	    (*addchar) ((int) (((unsigned char)*f) | attributes));
81c80476e4SDavid E. O'Brien 	}
82c80476e4SDavid E. O'Brien 	else {
83c80476e4SDavid E. O'Brien 	    f++;		/* skip the % */
84c80476e4SDavid E. O'Brien 
85c80476e4SDavid E. O'Brien 	    if (*f == '-') {	/* minus: flush left */
86c80476e4SDavid E. O'Brien 		flush_left = 1;
87c80476e4SDavid E. O'Brien 		f++;
88c80476e4SDavid E. O'Brien 	    }
89c80476e4SDavid E. O'Brien 
90c80476e4SDavid E. O'Brien 	    if (*f == '0' || *f == '.') {
91c80476e4SDavid E. O'Brien 		/* padding with 0 rather than blank */
92c80476e4SDavid E. O'Brien 		pad = '0';
93c80476e4SDavid E. O'Brien 		f++;
94c80476e4SDavid E. O'Brien 	    }
95c80476e4SDavid E. O'Brien 	    if (*f == '*') {	/* field width */
96c80476e4SDavid E. O'Brien 		f_width = va_arg(ap, int);
97c80476e4SDavid E. O'Brien 		f++;
98c80476e4SDavid E. O'Brien 	    }
99c80476e4SDavid E. O'Brien 	    else if (Isdigit((unsigned char) *f)) {
100c80476e4SDavid E. O'Brien 		f_width = atoi(f);
101c80476e4SDavid E. O'Brien 		while (Isdigit((unsigned char) *f))
102c80476e4SDavid E. O'Brien 		    f++;	/* skip the digits */
103c80476e4SDavid E. O'Brien 	    }
104c80476e4SDavid E. O'Brien 
105c80476e4SDavid E. O'Brien 	    if (*f == '.') {	/* precision */
106c80476e4SDavid E. O'Brien 		f++;
107c80476e4SDavid E. O'Brien 		if (*f == '*') {
108c80476e4SDavid E. O'Brien 		    prec = va_arg(ap, int);
109c80476e4SDavid E. O'Brien 		    f++;
110c80476e4SDavid E. O'Brien 		}
111c80476e4SDavid E. O'Brien 		else if (Isdigit((unsigned char) *f)) {
112c80476e4SDavid E. O'Brien 		    prec = atoi((char *) f);
113c80476e4SDavid E. O'Brien 		    while (Isdigit((unsigned char) *f))
114c80476e4SDavid E. O'Brien 			f++;	/* skip the digits */
115c80476e4SDavid E. O'Brien 		}
116c80476e4SDavid E. O'Brien 	    }
117c80476e4SDavid E. O'Brien 
118c80476e4SDavid E. O'Brien 	    if (*f == '#') {	/* alternate form */
119c80476e4SDavid E. O'Brien 		hash = 1;
120c80476e4SDavid E. O'Brien 		f++;
121c80476e4SDavid E. O'Brien 	    }
122c80476e4SDavid E. O'Brien 
123c80476e4SDavid E. O'Brien 	    if (*f == 'l') {	/* long format */
12429301572SMark Peek 		do_long++;
125c80476e4SDavid E. O'Brien 		f++;
12629301572SMark Peek 		if (*f == 'l') {
12729301572SMark Peek 		    do_long++;
12829301572SMark Peek 		    f++;
12929301572SMark Peek 		}
130c80476e4SDavid E. O'Brien 	    }
131c80476e4SDavid E. O'Brien 
132c80476e4SDavid E. O'Brien 	    fmt = (unsigned char) *f;
133c80476e4SDavid E. O'Brien 	    if (fmt != 'S' && fmt != 'Q' && Isupper(fmt)) {
134c80476e4SDavid E. O'Brien 		do_long = 1;
135c80476e4SDavid E. O'Brien 		fmt = Tolower(fmt);
136c80476e4SDavid E. O'Brien 	    }
137c80476e4SDavid E. O'Brien 	    bp = buf;
138c80476e4SDavid E. O'Brien 	    switch (fmt) {	/* do the format */
139c80476e4SDavid E. O'Brien 	    case 'd':
14029301572SMark Peek 		switch (do_long) {
14129301572SMark Peek 		case 0:
142c80476e4SDavid E. O'Brien 		    l = (long) (va_arg(ap, int));
14329301572SMark Peek 		    break;
14429301572SMark Peek 		case 1:
14529301572SMark Peek #ifndef HAVE_QUAD
14629301572SMark Peek 		default:
14729301572SMark Peek #endif
14829301572SMark Peek 		    l = va_arg(ap, long);
14929301572SMark Peek 		    break;
15029301572SMark Peek #ifdef HAVE_QUAD
15129301572SMark Peek 		default:
15229301572SMark Peek 		    l = va_arg(ap, long long);
15329301572SMark Peek 		    break;
15429301572SMark Peek #endif
15529301572SMark Peek 		}
15629301572SMark Peek 
157c80476e4SDavid E. O'Brien 		if (l < 0) {
158c80476e4SDavid E. O'Brien 		    sign = 1;
159c80476e4SDavid E. O'Brien 		    l = -l;
160c80476e4SDavid E. O'Brien 		}
161c80476e4SDavid E. O'Brien 		do {
162c80476e4SDavid E. O'Brien 		    *bp++ = (char) (l % 10) + '0';
163c80476e4SDavid E. O'Brien 		} while ((l /= 10) > 0);
164c80476e4SDavid E. O'Brien 		if (sign)
165c80476e4SDavid E. O'Brien 		    *bp++ = '-';
166c80476e4SDavid E. O'Brien 		f_width = f_width - (int) (bp - buf);
167c80476e4SDavid E. O'Brien 		if (!flush_left)
168c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
169c80476e4SDavid E. O'Brien 			(*addchar) ((int) (pad | attributes));
170c80476e4SDavid E. O'Brien 		for (bp--; bp >= buf; bp--)
171c80476e4SDavid E. O'Brien 		    (*addchar) ((int) (((unsigned char) *bp) | attributes));
172c80476e4SDavid E. O'Brien 		if (flush_left)
173c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
174c80476e4SDavid E. O'Brien 			(*addchar) ((int) (' ' | attributes));
175c80476e4SDavid E. O'Brien 		break;
176c80476e4SDavid E. O'Brien 
177c80476e4SDavid E. O'Brien 	    case 'o':
178c80476e4SDavid E. O'Brien 	    case 'x':
179c80476e4SDavid E. O'Brien 	    case 'u':
18029301572SMark Peek 		switch (do_long) {
18129301572SMark Peek 		case 0:
182c80476e4SDavid E. O'Brien 		    u = (unsigned long) (va_arg(ap, unsigned int));
18329301572SMark Peek 		    break;
18429301572SMark Peek 		case 1:
18529301572SMark Peek #ifndef HAVE_QUAD
18629301572SMark Peek 		default:
18729301572SMark Peek #endif
18829301572SMark Peek 		    u = va_arg(ap, unsigned long);
18929301572SMark Peek 		    break;
19029301572SMark Peek #ifdef HAVE_QUAD
19129301572SMark Peek 		default:
19229301572SMark Peek 		    u = va_arg(ap, unsigned long long);
19329301572SMark Peek 		    break;
19429301572SMark Peek #endif
19529301572SMark Peek 		}
196c80476e4SDavid E. O'Brien 		if (fmt == 'u') {	/* unsigned decimal */
197c80476e4SDavid E. O'Brien 		    do {
198c80476e4SDavid E. O'Brien 			*bp++ = (char) (u % 10) + '0';
199c80476e4SDavid E. O'Brien 		    } while ((u /= 10) > 0);
200c80476e4SDavid E. O'Brien 		}
201c80476e4SDavid E. O'Brien 		else if (fmt == 'o') {	/* octal */
202c80476e4SDavid E. O'Brien 		    do {
203c80476e4SDavid E. O'Brien 			*bp++ = (char) (u % 8) + '0';
204c80476e4SDavid E. O'Brien 		    } while ((u /= 8) > 0);
205c80476e4SDavid E. O'Brien 		    if (hash)
206c80476e4SDavid E. O'Brien 			*bp++ = '0';
207c80476e4SDavid E. O'Brien 		}
208c80476e4SDavid E. O'Brien 		else if (fmt == 'x') {	/* hex */
209c80476e4SDavid E. O'Brien 		    do {
210c80476e4SDavid E. O'Brien 			i = (int) (u % 16);
211c80476e4SDavid E. O'Brien 			if (i < 10)
212c80476e4SDavid E. O'Brien 			    *bp++ = i + '0';
213c80476e4SDavid E. O'Brien 			else
214c80476e4SDavid E. O'Brien 			    *bp++ = i - 10 + 'a';
215c80476e4SDavid E. O'Brien 		    } while ((u /= 16) > 0);
216c80476e4SDavid E. O'Brien 		    if (hash) {
217c80476e4SDavid E. O'Brien 			*bp++ = 'x';
218c80476e4SDavid E. O'Brien 			*bp++ = '0';
219c80476e4SDavid E. O'Brien 		    }
220c80476e4SDavid E. O'Brien 		}
221c80476e4SDavid E. O'Brien 		i = f_width - (int) (bp - buf);
222c80476e4SDavid E. O'Brien 		if (!flush_left)
223c80476e4SDavid E. O'Brien 		    while (i-- > 0)
224c80476e4SDavid E. O'Brien 			(*addchar) ((int) (pad | attributes));
225c80476e4SDavid E. O'Brien 		for (bp--; bp >= buf; bp--)
226c80476e4SDavid E. O'Brien 		    (*addchar) ((int) (((unsigned char) *bp) | attributes));
227c80476e4SDavid E. O'Brien 		if (flush_left)
228c80476e4SDavid E. O'Brien 		    while (i-- > 0)
229c80476e4SDavid E. O'Brien 			(*addchar) ((int) (' ' | attributes));
230c80476e4SDavid E. O'Brien 		break;
231c80476e4SDavid E. O'Brien 
232c80476e4SDavid E. O'Brien 
233c80476e4SDavid E. O'Brien 	    case 'c':
234c80476e4SDavid E. O'Brien 		i = va_arg(ap, int);
235c80476e4SDavid E. O'Brien 		(*addchar) ((int) (i | attributes));
236c80476e4SDavid E. O'Brien 		break;
237c80476e4SDavid E. O'Brien 
238c80476e4SDavid E. O'Brien 	    case 'S':
239c80476e4SDavid E. O'Brien 	    case 'Q':
2406767bd61SMark Peek #ifdef SHORT_STRINGS
241c80476e4SDavid E. O'Brien 		Bp = va_arg(ap, Char *);
242c80476e4SDavid E. O'Brien 		if (!Bp) {
243c80476e4SDavid E. O'Brien 		    bp = NULL;
244c80476e4SDavid E. O'Brien 		    goto lcase_s;
245c80476e4SDavid E. O'Brien 	        }
246c80476e4SDavid E. O'Brien 		f_width = f_width - Strlen(Bp);
247c80476e4SDavid E. O'Brien 		if (!flush_left)
248c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
249c80476e4SDavid E. O'Brien 			(*addchar) ((int) (pad | attributes));
250c80476e4SDavid E. O'Brien 		for (i = 0; *Bp && i < prec; i++) {
251c80476e4SDavid E. O'Brien 		    if (fmt == 'Q' && *Bp & QUOTE)
252c80476e4SDavid E. O'Brien 			(*addchar) ((int) ('\\' | attributes));
253c80476e4SDavid E. O'Brien 		    (*addchar) ((int) ((*Bp & TRIM) | attributes));
254c80476e4SDavid E. O'Brien 		    Bp++;
255c80476e4SDavid E. O'Brien 		}
256c80476e4SDavid E. O'Brien 		if (flush_left)
257c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
258c80476e4SDavid E. O'Brien 			(*addchar) ((int) (' ' | attributes));
259c80476e4SDavid E. O'Brien 		break;
2606767bd61SMark Peek #endif /* SHORT_STRINGS */
261c80476e4SDavid E. O'Brien 
262c80476e4SDavid E. O'Brien 	    case 's':
263c80476e4SDavid E. O'Brien 	    case 'q':
264c80476e4SDavid E. O'Brien 		bp = va_arg(ap, char *);
265c80476e4SDavid E. O'Brien lcase_s:
266c80476e4SDavid E. O'Brien 		if (!bp)
267c80476e4SDavid E. O'Brien 		    bp = "(nil)";
268c80476e4SDavid E. O'Brien 		f_width = f_width - strlen((char *) bp);
269c80476e4SDavid E. O'Brien 		if (!flush_left)
270c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
271c80476e4SDavid E. O'Brien 			(*addchar) ((int) (pad | attributes));
272c80476e4SDavid E. O'Brien 		for (i = 0; *bp && i < prec; i++) {
273c80476e4SDavid E. O'Brien 		    if (fmt == 'q' && *bp & QUOTE)
274c80476e4SDavid E. O'Brien 			(*addchar) ((int) ('\\' | attributes));
275c80476e4SDavid E. O'Brien 		    (*addchar) ((int) (((unsigned char) *bp & TRIM) |
276c80476e4SDavid E. O'Brien 				   	attributes));
277c80476e4SDavid E. O'Brien 		    bp++;
278c80476e4SDavid E. O'Brien 		}
279c80476e4SDavid E. O'Brien 		if (flush_left)
280c80476e4SDavid E. O'Brien 		    while (f_width-- > 0)
281c80476e4SDavid E. O'Brien 			(*addchar) ((int) (' ' | attributes));
282c80476e4SDavid E. O'Brien 		break;
283c80476e4SDavid E. O'Brien 
284c80476e4SDavid E. O'Brien 	    case 'a':
285c80476e4SDavid E. O'Brien 		attributes = va_arg(ap, int);
286c80476e4SDavid E. O'Brien 		break;
287c80476e4SDavid E. O'Brien 
288c80476e4SDavid E. O'Brien 	    case '%':
289c80476e4SDavid E. O'Brien 		(*addchar) ((int) ('%' | attributes));
290c80476e4SDavid E. O'Brien 		break;
291c80476e4SDavid E. O'Brien 
292c80476e4SDavid E. O'Brien 	    default:
293c80476e4SDavid E. O'Brien 		break;
294c80476e4SDavid E. O'Brien 	    }
295c80476e4SDavid E. O'Brien 	    flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
296c80476e4SDavid E. O'Brien 	    sign = 0;
297c80476e4SDavid E. O'Brien 	    pad = ' ';
298c80476e4SDavid E. O'Brien 	}
299c80476e4SDavid E. O'Brien     }
300c80476e4SDavid E. O'Brien }
301c80476e4SDavid E. O'Brien 
302c80476e4SDavid E. O'Brien 
303c80476e4SDavid E. O'Brien static char *xstring, *xestring;
304c80476e4SDavid E. O'Brien static void
305c80476e4SDavid E. O'Brien xaddchar(c)
306c80476e4SDavid E. O'Brien     int     c;
307c80476e4SDavid E. O'Brien {
308c80476e4SDavid E. O'Brien     if (xestring == xstring)
309c80476e4SDavid E. O'Brien 	*xstring = '\0';
310c80476e4SDavid E. O'Brien     else
311c80476e4SDavid E. O'Brien 	*xstring++ = (char) c;
312c80476e4SDavid E. O'Brien }
313c80476e4SDavid E. O'Brien 
314c80476e4SDavid E. O'Brien 
315c80476e4SDavid E. O'Brien pret_t
316c80476e4SDavid E. O'Brien /*VARARGS*/
317c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
318c80476e4SDavid E. O'Brien xsnprintf(char *str, size_t size, const char *fmt, ...)
319c80476e4SDavid E. O'Brien #else
320c80476e4SDavid E. O'Brien xsnprintf(va_alist)
321c80476e4SDavid E. O'Brien     va_dcl
322c80476e4SDavid E. O'Brien #endif
323c80476e4SDavid E. O'Brien {
324c80476e4SDavid E. O'Brien     va_list va;
325c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
326c80476e4SDavid E. O'Brien     va_start(va, fmt);
327c80476e4SDavid E. O'Brien #else
328c80476e4SDavid E. O'Brien     char *str, *fmt;
329c80476e4SDavid E. O'Brien     size_t size;
330c80476e4SDavid E. O'Brien 
331c80476e4SDavid E. O'Brien     va_start(va);
332c80476e4SDavid E. O'Brien     str = va_arg(va, char *);
333c80476e4SDavid E. O'Brien     size = va_arg(va, size_t);
334c80476e4SDavid E. O'Brien     fmt = va_arg(va, char *);
335c80476e4SDavid E. O'Brien #endif
336c80476e4SDavid E. O'Brien 
337c80476e4SDavid E. O'Brien     xstring = str;
338c80476e4SDavid E. O'Brien     xestring = str + size - 1;
339c80476e4SDavid E. O'Brien     doprnt(xaddchar, fmt, va);
340c80476e4SDavid E. O'Brien     va_end(va);
341c80476e4SDavid E. O'Brien     *xstring++ = '\0';
342c80476e4SDavid E. O'Brien #ifdef PURIFY
343c80476e4SDavid E. O'Brien     return 1;
344c80476e4SDavid E. O'Brien #endif
345c80476e4SDavid E. O'Brien }
346c80476e4SDavid E. O'Brien 
347c80476e4SDavid E. O'Brien pret_t
348c80476e4SDavid E. O'Brien /*VARARGS*/
349c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
350c80476e4SDavid E. O'Brien xprintf(const char *fmt, ...)
351c80476e4SDavid E. O'Brien #else
352c80476e4SDavid E. O'Brien xprintf(va_alist)
353c80476e4SDavid E. O'Brien     va_dcl
354c80476e4SDavid E. O'Brien #endif
355c80476e4SDavid E. O'Brien {
356c80476e4SDavid E. O'Brien     va_list va;
357c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
358c80476e4SDavid E. O'Brien     va_start(va, fmt);
359c80476e4SDavid E. O'Brien #else
360c80476e4SDavid E. O'Brien     char   *fmt;
361c80476e4SDavid E. O'Brien 
362c80476e4SDavid E. O'Brien     va_start(va);
363c80476e4SDavid E. O'Brien     fmt = va_arg(va, char *);
364c80476e4SDavid E. O'Brien #endif
365c80476e4SDavid E. O'Brien     doprnt(xputchar, fmt, va);
366c80476e4SDavid E. O'Brien     va_end(va);
367c80476e4SDavid E. O'Brien #ifdef PURIFY
368c80476e4SDavid E. O'Brien     return 1;
369c80476e4SDavid E. O'Brien #endif
370c80476e4SDavid E. O'Brien }
371c80476e4SDavid E. O'Brien 
372c80476e4SDavid E. O'Brien 
373c80476e4SDavid E. O'Brien pret_t
374c80476e4SDavid E. O'Brien xvprintf(fmt, va)
375c80476e4SDavid E. O'Brien     const char   *fmt;
376c80476e4SDavid E. O'Brien     va_list va;
377c80476e4SDavid E. O'Brien {
378c80476e4SDavid E. O'Brien     doprnt(xputchar, fmt, va);
379c80476e4SDavid E. O'Brien #ifdef PURIFY
380c80476e4SDavid E. O'Brien     return 1;
381c80476e4SDavid E. O'Brien #endif
382c80476e4SDavid E. O'Brien }
383c80476e4SDavid E. O'Brien 
384c80476e4SDavid E. O'Brien pret_t
385c80476e4SDavid E. O'Brien xvsnprintf(str, size, fmt, va)
386c80476e4SDavid E. O'Brien     char   *str;
387c80476e4SDavid E. O'Brien     size_t size;
388c80476e4SDavid E. O'Brien     const char   *fmt;
389c80476e4SDavid E. O'Brien     va_list va;
390c80476e4SDavid E. O'Brien {
391c80476e4SDavid E. O'Brien     xstring = str;
392c80476e4SDavid E. O'Brien     xestring = str + size - 1;
393c80476e4SDavid E. O'Brien     doprnt(xaddchar, fmt, va);
394c80476e4SDavid E. O'Brien     *xstring++ = '\0';
395c80476e4SDavid E. O'Brien #ifdef PURIFY
396c80476e4SDavid E. O'Brien     return 1;
397c80476e4SDavid E. O'Brien #endif
398c80476e4SDavid E. O'Brien }
399c80476e4SDavid E. O'Brien 
400c80476e4SDavid E. O'Brien 
401c80476e4SDavid E. O'Brien 
402c80476e4SDavid E. O'Brien #ifdef PURIFY
403c80476e4SDavid E. O'Brien /* Purify uses (some of..) the following functions to output memory-use
404c80476e4SDavid E. O'Brien  * debugging info.  Given all the messing with file descriptors that
405c80476e4SDavid E. O'Brien  * tcsh does, the easiest way I could think of to get it (Purify) to
406c80476e4SDavid E. O'Brien  * print anything was by replacing some standard functions with
407c80476e4SDavid E. O'Brien  * ones that do tcsh output directly - see dumb hook in doreaddirs()
408c80476e4SDavid E. O'Brien  * (sh.dir.c) -sg
409c80476e4SDavid E. O'Brien  */
410c80476e4SDavid E. O'Brien #ifndef FILE
411c80476e4SDavid E. O'Brien #define FILE int
412c80476e4SDavid E. O'Brien #endif
413c80476e4SDavid E. O'Brien int
414c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
415c80476e4SDavid E. O'Brien fprintf(FILE *fp, const char* fmt, ...)
416c80476e4SDavid E. O'Brien #else
417c80476e4SDavid E. O'Brien fprintf(va_alist)
418c80476e4SDavid E. O'Brien     va_dcl
419c80476e4SDavid E. O'Brien #endif
420c80476e4SDavid E. O'Brien {
421c80476e4SDavid E. O'Brien     va_list va;
422c80476e4SDavid E. O'Brien #ifdef FUNCPROTO
423c80476e4SDavid E. O'Brien     va_start(va, fmt);
424c80476e4SDavid E. O'Brien #else
425c80476e4SDavid E. O'Brien     FILE *fp;
426c80476e4SDavid E. O'Brien     const char   *fmt;
427c80476e4SDavid E. O'Brien 
428c80476e4SDavid E. O'Brien     va_start(va);
429c80476e4SDavid E. O'Brien     fp = va_arg(va, FILE *);
430c80476e4SDavid E. O'Brien     fmt = va_arg(va, const char *);
431c80476e4SDavid E. O'Brien #endif
432c80476e4SDavid E. O'Brien     doprnt(xputchar, fmt, va);
433c80476e4SDavid E. O'Brien     va_end(va);
434c80476e4SDavid E. O'Brien     return 1;
435c80476e4SDavid E. O'Brien }
436c80476e4SDavid E. O'Brien 
437c80476e4SDavid E. O'Brien int
438c80476e4SDavid E. O'Brien vfprintf(fp, fmt, va)
439c80476e4SDavid E. O'Brien     FILE *fp;
440c80476e4SDavid E. O'Brien     const char   *fmt;
441c80476e4SDavid E. O'Brien     va_list va;
442c80476e4SDavid E. O'Brien {
443c80476e4SDavid E. O'Brien     doprnt(xputchar, fmt, va);
444c80476e4SDavid E. O'Brien     return 1;
445c80476e4SDavid E. O'Brien }
446c80476e4SDavid E. O'Brien 
447c80476e4SDavid E. O'Brien #endif	/* PURIFY */
448