1 /* @(#)jsprintf.c	1.20 17/08/03 Copyright 1985, 1995-2017 J. Schilling */
2 /*
3  *	Copyright (c) 1985, 1995-2017 J. Schilling
4  */
5 /*
6  * The contents of this file are subject to the terms of the
7  * Common Development and Distribution License, Version 1.0 only
8  * (the "License").  You may not use this file except in compliance
9  * with the License.
10  *
11  * See the file CDDL.Schily.txt in this distribution for details.
12  * A copy of the CDDL is also available via the Internet at
13  * http://www.opensource.org/licenses/cddl1.txt
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file CDDL.Schily.txt from this distribution.
17  */
18 
19 #include <schily/mconfig.h>
20 #include <schily/stdio.h>
21 #include <schily/types.h>
22 #include <schily/varargs.h>
23 #include <schily/standard.h>
24 #include <schily/schily.h>
25 
26 #ifdef	NO_FPRFORMAT
27 #undef	USE_FPRFORMAT
28 #else
29 #define	USE_FPRFORMAT
30 #endif
31 
32 #ifdef	USE_FPRFORMAT
33 /*
34  * This is the speed-optimized version that currently only has been tested
35  * on Solaris.
36  * It is based on fprformat() instead of format() and is faster than the
37  * the format() based standard implementation, in case that putc() or
38  * putc_unlocked() is a macro.
39  */
40 
41 /* VARARGS1 */
42 #ifdef	PROTOTYPES
43 EXPORT int
js_printf(const char * form,...)44 js_printf(const char *form, ...)
45 #else
46 EXPORT int
47 js_printf(form, va_alist)
48 	char	*form;
49 	va_dcl
50 #endif
51 {
52 	va_list	args;
53 	int	ret;
54 
55 #ifdef	PROTOTYPES
56 	va_start(args, form);
57 #else
58 	va_start(args);
59 #endif
60 	ret = fprformat(stdout, form, args);
61 	va_end(args);
62 	return (ret);
63 }
64 
65 /* VARARGS2 */
66 #ifdef	PROTOTYPES
67 EXPORT int
js_fprintf(FILE * file,const char * form,...)68 js_fprintf(FILE *file, const char *form, ...)
69 #else
70 EXPORT int
71 js_fprintf(file, form, va_alist)
72 	FILE	*file;
73 	char	*form;
74 	va_dcl
75 #endif
76 {
77 	va_list	args;
78 	int	ret;
79 
80 #ifdef	PROTOTYPES
81 	va_start(args, form);
82 #else
83 	va_start(args);
84 #endif
85 	ret = fprformat(file, form, args);
86 	va_end(args);
87 	return (ret);
88 }
89 
90 #else	/* !USE_FPRFORMAT */
91 /*
92  * This is the portable standard implementation that works anywhere.
93  */
94 
95 #define	BFSIZ	256
96 
97 typedef struct {
98 	short	cnt;
99 	char	*ptr;
100 	char	buf[BFSIZ];
101 	int	count;
102 	FILE	*f;
103 } *BUF, _BUF;
104 
105 LOCAL	void	_bflush		__PR((BUF));
106 LOCAL	void	_bput		__PR((char, void *));
107 EXPORT	int	js_fprintf	__PR((FILE *, const char *, ...));
108 EXPORT	int	js_printf	__PR((const char *, ...));
109 
110 LOCAL void
_bflush(bp)111 _bflush(bp)
112 	register BUF	bp;
113 {
114 	bp->count += bp->ptr - bp->buf;
115 	if (filewrite(bp->f, bp->buf, bp->ptr - bp->buf) < 0)
116 		bp->count = EOF;
117 	bp->ptr = bp->buf;
118 	bp->cnt = BFSIZ;
119 }
120 
121 #ifdef	PROTOTYPES
122 LOCAL void
_bput(char c,void * l)123 _bput(char c, void *l)
124 #else
125 LOCAL void
126 _bput(c, l)
127 		char	c;
128 		void	*l;
129 #endif
130 {
131 	register BUF	bp = (BUF)l;
132 
133 	*bp->ptr++ = c;
134 	if (--bp->cnt <= 0)
135 		_bflush(bp);
136 }
137 
138 /* VARARGS1 */
139 #ifdef	PROTOTYPES
140 EXPORT int
js_printf(const char * form,...)141 js_printf(const char *form, ...)
142 #else
143 EXPORT int
144 js_printf(form, va_alist)
145 	char	*form;
146 	va_dcl
147 #endif
148 {
149 	va_list	args;
150 	_BUF	bb;
151 
152 	bb.ptr = bb.buf;
153 	bb.cnt = BFSIZ;
154 	bb.count = 0;
155 	bb.f = stdout;
156 #ifdef	PROTOTYPES
157 	va_start(args, form);
158 #else
159 	va_start(args);
160 #endif
161 	format(_bput, &bb, form, args);
162 	va_end(args);
163 	if (bb.cnt < BFSIZ)
164 		_bflush(&bb);
165 	return (bb.count);
166 }
167 
168 /* VARARGS2 */
169 #ifdef	PROTOTYPES
170 EXPORT int
js_fprintf(FILE * file,const char * form,...)171 js_fprintf(FILE *file, const char *form, ...)
172 #else
173 EXPORT int
174 js_fprintf(file, form, va_alist)
175 	FILE	*file;
176 	char	*form;
177 	va_dcl
178 #endif
179 {
180 	va_list	args;
181 	_BUF	bb;
182 
183 	bb.ptr = bb.buf;
184 	bb.cnt = BFSIZ;
185 	bb.count = 0;
186 	bb.f = file;
187 #ifdef	PROTOTYPES
188 	va_start(args, form);
189 #else
190 	va_start(args);
191 #endif
192 	format(_bput, &bb, form, args);
193 	va_end(args);
194 	if (bb.cnt < BFSIZ)
195 		_bflush(&bb);
196 	return (bb.count);
197 }
198 #endif
199