1 /* @(#)fprint.c	1.5 17/08/03 Copyright 1985, 1989, 1995-2017 J. Schilling */
2 /*
3  *	Copyright (c) 1985, 1989, 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/unistd.h>	/* include <sys/types.h> try to get size_t */
21 #include <schily/stdlib.h>	/* Try again for size_t	*/
22 
23 #include <schily/stdio.h>
24 #include <schily/varargs.h>
25 #include <schily/standard.h>
26 #include <schily/schily.h>
27 
28 #define	BFSIZ	256
29 
30 typedef struct {
31 	short	cnt;
32 	char	*ptr;
33 	char	buf[BFSIZ];
34 	int	count;
35 	FILE	*f;
36 } *BUF, _BUF;
37 
38 LOCAL	void	_bflush	__PR((BUF));
39 LOCAL	void	_bput	__PR((char, void *));
40 EXPORT	int	fprintf	__PR((FILE *, const char *, ...)) __printflike__(2, 3);
41 EXPORT	int	printf	__PR((const char *, ...))	  __printflike__(1, 2);
42 
43 LOCAL void
_bflush(bp)44 _bflush(bp)
45 	register BUF	bp;
46 {
47 	bp->count += bp->ptr - bp->buf;
48 	if (filewrite(bp->f, bp->buf, bp->ptr - bp->buf) < 0)
49 		bp->count = EOF;
50 	bp->ptr = bp->buf;
51 	bp->cnt = BFSIZ;
52 }
53 
54 #ifdef	PROTOTYPES
55 LOCAL void
_bput(char c,void * l)56 _bput(char c, void *l)
57 #else
58 LOCAL void
59 _bput(c, l)
60 		char	c;
61 		void	*l;
62 #endif
63 {
64 	register BUF	bp = (BUF)l;
65 
66 	*bp->ptr++ = c;
67 	if (--bp->cnt <= 0)
68 		_bflush(bp);
69 }
70 
71 /* VARARGS1 */
72 #ifdef	PROTOTYPES
73 EXPORT int
printf(const char * form,...)74 printf(const char *form, ...)
75 #else
76 EXPORT int
77 printf(form, va_alist)
78 	char	*form;
79 	va_dcl
80 #endif
81 {
82 	va_list	args;
83 	_BUF	bb;
84 
85 	bb.ptr = bb.buf;
86 	bb.cnt = BFSIZ;
87 	bb.count = 0;
88 	bb.f = stdout;
89 #ifdef	PROTOTYPES
90 	va_start(args, form);
91 #else
92 	va_start(args);
93 #endif
94 	format(_bput, &bb, form, args);
95 	va_end(args);
96 	if (bb.cnt < BFSIZ)
97 		_bflush(&bb);
98 	return (bb.count);
99 }
100 
101 /* VARARGS2 */
102 #ifdef	PROTOTYPES
103 EXPORT int
fprintf(FILE * file,const char * form,...)104 fprintf(FILE *file, const char *form, ...)
105 #else
106 EXPORT int
107 fprintf(file, form, va_alist)
108 	FILE	*file;
109 	char	*form;
110 	va_dcl
111 #endif
112 {
113 	va_list	args;
114 	_BUF	bb;
115 
116 	bb.ptr = bb.buf;
117 	bb.cnt = BFSIZ;
118 	bb.count = 0;
119 	bb.f = file;
120 #ifdef	PROTOTYPES
121 	va_start(args, form);
122 #else
123 	va_start(args);
124 #endif
125 	format(_bput, &bb, form, args);
126 	va_end(args);
127 	if (bb.cnt < BFSIZ)
128 		_bflush(&bb);
129 	return (bb.count);
130 }
131 /* -------------------------------------------------------------------------- */
132 
133 EXPORT	int sprintf __PR((char *, const char *, ...));
134 
135 #ifdef	PROTOTYPES
136 static void
_cput(char c,void * ba)137 _cput(char c, void *ba)
138 #else
139 static void
140 _cput(c, ba)
141 	char	c;
142 	void	*ba;
143 #endif
144 {
145 	*(*(char **)ba)++ = c;
146 }
147 
148 /* VARARGS2 */
149 #ifdef	PROTOTYPES
150 EXPORT int
sprintf(char * buf,const char * form,...)151 sprintf(char *buf, const char *form, ...)
152 #else
153 EXPORT int
154 sprintf(buf, form, va_alist)
155 	char	*buf;
156 	char	*form;
157 	va_dcl
158 #endif
159 {
160 	va_list	args;
161 	int	cnt;
162 	char	*bp = buf;
163 
164 #ifdef	PROTOTYPES
165 	va_start(args, form);
166 #else
167 	va_start(args);
168 #endif
169 	cnt = format(_cput, &bp, form,  args);
170 	va_end(args);
171 	*bp = '\0';
172 
173 	return (cnt);
174 }
175 
176 EXPORT	int snprintf __PR((char *, size_t maxcnt, const char *, ...));
177 
178 typedef struct {
179 	char	*ptr;
180 	int	count;
181 } *SBUF, _SBUF;
182 
183 #ifdef	PROTOTYPES
184 static void
_scput(char c,void * l)185 _scput(char c, void *l)
186 #else
187 static void
188 _scput(c, l)
189 	char	c;
190 	void	*l;
191 #endif
192 {
193 	register SBUF	bp = (SBUF)l;
194 
195 	if (--bp->count > 0) {
196 		*bp->ptr++ = c;
197 	} else {
198 		/*
199 		 * Make sure that there will never be a negative overflow.
200 		 */
201 		bp->count++;
202 	}
203 }
204 
205 /* VARARGS2 */
206 #ifdef	PROTOTYPES
207 EXPORT int
snprintf(char * buf,size_t maxcnt,const char * form,...)208 snprintf(char *buf, size_t maxcnt, const char *form, ...)
209 #else
210 EXPORT int
211 snprintf(buf, maxcnt, form, va_alist)
212 	char	*buf;
213 	unsigned maxcnt;
214 	char	*form;
215 	va_dcl
216 #endif
217 {
218 	va_list	args;
219 	int	cnt;
220 	_SBUF	bb;
221 
222 	bb.ptr = buf;
223 	bb.count = maxcnt;
224 
225 #ifdef	PROTOTYPES
226 	va_start(args, form);
227 #else
228 	va_start(args);
229 #endif
230 	cnt = format(_scput, &bb, form,  args);
231 	va_end(args);
232 	if (maxcnt > 0)
233 		*(bb.ptr) = '\0';
234 	if (bb.count < 0)
235 		return (-1);
236 
237 	return (cnt);
238 }
239