iscprint.c revision 1.2.2.2 1 1.2.2.2 pgoyette /* $NetBSD: iscprint.c,v 1.2.2.2 2018/04/16 01:59:48 pgoyette Exp $ */
2 1.2.2.2 pgoyette
3 1.2.2.2 pgoyette /*
4 1.2.2.2 pgoyette * Copyright (C) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
5 1.2.2.2 pgoyette * Copyright (C) 1999-2003 Internet Software Consortium.
6 1.2.2.2 pgoyette *
7 1.2.2.2 pgoyette * This Source Code Form is subject to the terms of the Mozilla Public
8 1.2.2.2 pgoyette * License, v. 2.0. If a copy of the MPL was not distributed with this
9 1.2.2.2 pgoyette * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 1.2.2.2 pgoyette *
11 1.2.2.2 pgoyette * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 1.2.2.2 pgoyette * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 1.2.2.2 pgoyette * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 1.2.2.2 pgoyette * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 1.2.2.2 pgoyette * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 1.2.2.2 pgoyette * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 1.2.2.2 pgoyette * PERFORMANCE OF THIS SOFTWARE.
18 1.2.2.2 pgoyette */
19 1.2.2.2 pgoyette
20 1.2.2.2 pgoyette #include <sys/cdefs.h>
21 1.2.2.2 pgoyette __RCSID("$NetBSD: iscprint.c,v 1.2.2.2 2018/04/16 01:59:48 pgoyette Exp $");
22 1.2.2.2 pgoyette
23 1.2.2.2 pgoyette
24 1.2.2.2 pgoyette /* Id: iscprint.c,v 1.2 2005/03/17 20:30:41 dhankins Exp */
25 1.2.2.2 pgoyette
26 1.2.2.2 pgoyette #include "dhcpd.h"
27 1.2.2.2 pgoyette
28 1.2.2.2 pgoyette #ifdef NO_SNPRINTF
29 1.2.2.2 pgoyette
30 1.2.2.2 pgoyette #ifndef LINT
31 1.2.2.2 pgoyette static char copyright[] =
32 1.2.2.2 pgoyette "Id: iscprint.c,v 1.2 2005/03/17 20:30:41 dhankins Exp Copyright (c) 2004 Internet Systems Consortium, Inc. All rights reserved.";
33 1.2.2.2 pgoyette #endif
34 1.2.2.2 pgoyette
35 1.2.2.2 pgoyette #define INSIST(cond) REQUIRE(cond)
36 1.2.2.2 pgoyette #define REQUIRE(cond) if (!(cond)) { return 0; }
37 1.2.2.2 pgoyette
38 1.2.2.2 pgoyette /*
39 1.2.2.2 pgoyette * Return length of string that would have been written if not truncated.
40 1.2.2.2 pgoyette */
41 1.2.2.2 pgoyette
42 1.2.2.2 pgoyette int
43 1.2.2.2 pgoyette isc_print_snprintf(char *str, size_t size, const char *format, ...) {
44 1.2.2.2 pgoyette va_list ap;
45 1.2.2.2 pgoyette int ret;
46 1.2.2.2 pgoyette
47 1.2.2.2 pgoyette va_start(ap, format);
48 1.2.2.2 pgoyette ret = vsnprintf(str, size, format, ap);
49 1.2.2.2 pgoyette va_end(ap);
50 1.2.2.2 pgoyette return (ret);
51 1.2.2.2 pgoyette }
52 1.2.2.2 pgoyette
53 1.2.2.2 pgoyette /*
54 1.2.2.2 pgoyette * Return length of string that would have been written if not truncated.
55 1.2.2.2 pgoyette */
56 1.2.2.2 pgoyette
57 1.2.2.2 pgoyette int
58 1.2.2.2 pgoyette isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
59 1.2.2.2 pgoyette int h;
60 1.2.2.2 pgoyette int l;
61 1.2.2.2 pgoyette int q;
62 1.2.2.2 pgoyette int alt;
63 1.2.2.2 pgoyette int zero;
64 1.2.2.2 pgoyette int left;
65 1.2.2.2 pgoyette int plus;
66 1.2.2.2 pgoyette int space;
67 1.2.2.2 pgoyette int neg;
68 1.2.2.2 pgoyette isc_int64_t tmpi;
69 1.2.2.2 pgoyette isc_uint64_t tmpui;
70 1.2.2.2 pgoyette unsigned long width;
71 1.2.2.2 pgoyette unsigned long precision;
72 1.2.2.2 pgoyette unsigned int length;
73 1.2.2.2 pgoyette char buf[1024];
74 1.2.2.2 pgoyette char c;
75 1.2.2.2 pgoyette void *v;
76 1.2.2.2 pgoyette char *save = str;
77 1.2.2.2 pgoyette const char *cp;
78 1.2.2.2 pgoyette const char *head;
79 1.2.2.2 pgoyette int count = 0;
80 1.2.2.2 pgoyette int pad;
81 1.2.2.2 pgoyette int zeropad;
82 1.2.2.2 pgoyette int dot;
83 1.2.2.2 pgoyette double dbl;
84 1.2.2.2 pgoyette #ifdef HAVE_LONG_DOUBLE
85 1.2.2.2 pgoyette long double ldbl;
86 1.2.2.2 pgoyette #endif
87 1.2.2.2 pgoyette char fmt[32];
88 1.2.2.2 pgoyette
89 1.2.2.2 pgoyette INSIST(str != NULL);
90 1.2.2.2 pgoyette INSIST(format != NULL);
91 1.2.2.2 pgoyette
92 1.2.2.2 pgoyette while (*format != '\0') {
93 1.2.2.2 pgoyette if (*format != '%') {
94 1.2.2.2 pgoyette if (size > 1) {
95 1.2.2.2 pgoyette *str++ = *format;
96 1.2.2.2 pgoyette size--;
97 1.2.2.2 pgoyette }
98 1.2.2.2 pgoyette count++;
99 1.2.2.2 pgoyette format++;
100 1.2.2.2 pgoyette continue;
101 1.2.2.2 pgoyette }
102 1.2.2.2 pgoyette format++;
103 1.2.2.2 pgoyette
104 1.2.2.2 pgoyette /*
105 1.2.2.2 pgoyette * Reset flags.
106 1.2.2.2 pgoyette */
107 1.2.2.2 pgoyette dot = neg = space = plus = left = zero = alt = h = l = q = 0;
108 1.2.2.2 pgoyette width = precision = 0;
109 1.2.2.2 pgoyette head = "";
110 1.2.2.2 pgoyette length = pad = zeropad = 0;
111 1.2.2.2 pgoyette
112 1.2.2.2 pgoyette do {
113 1.2.2.2 pgoyette if (*format == '#') {
114 1.2.2.2 pgoyette alt = 1;
115 1.2.2.2 pgoyette format++;
116 1.2.2.2 pgoyette } else if (*format == '-') {
117 1.2.2.2 pgoyette left = 1;
118 1.2.2.2 pgoyette zero = 0;
119 1.2.2.2 pgoyette format++;
120 1.2.2.2 pgoyette } else if (*format == ' ') {
121 1.2.2.2 pgoyette if (!plus)
122 1.2.2.2 pgoyette space = 1;
123 1.2.2.2 pgoyette format++;
124 1.2.2.2 pgoyette } else if (*format == '+') {
125 1.2.2.2 pgoyette plus = 1;
126 1.2.2.2 pgoyette space = 0;
127 1.2.2.2 pgoyette format++;
128 1.2.2.2 pgoyette } else if (*format == '0') {
129 1.2.2.2 pgoyette if (!left)
130 1.2.2.2 pgoyette zero = 1;
131 1.2.2.2 pgoyette format++;
132 1.2.2.2 pgoyette } else
133 1.2.2.2 pgoyette break;
134 1.2.2.2 pgoyette } while (1);
135 1.2.2.2 pgoyette
136 1.2.2.2 pgoyette /*
137 1.2.2.2 pgoyette * Width.
138 1.2.2.2 pgoyette */
139 1.2.2.2 pgoyette if (*format == '*') {
140 1.2.2.2 pgoyette width = va_arg(ap, int);
141 1.2.2.2 pgoyette format++;
142 1.2.2.2 pgoyette } else if (isdigit((unsigned char)*format)) {
143 1.2.2.2 pgoyette char *e;
144 1.2.2.2 pgoyette width = strtoul(format, &e, 10);
145 1.2.2.2 pgoyette format = e;
146 1.2.2.2 pgoyette }
147 1.2.2.2 pgoyette
148 1.2.2.2 pgoyette /*
149 1.2.2.2 pgoyette * Precision.
150 1.2.2.2 pgoyette */
151 1.2.2.2 pgoyette if (*format == '.') {
152 1.2.2.2 pgoyette format++;
153 1.2.2.2 pgoyette dot = 1;
154 1.2.2.2 pgoyette if (*format == '*') {
155 1.2.2.2 pgoyette precision = va_arg(ap, int);
156 1.2.2.2 pgoyette format++;
157 1.2.2.2 pgoyette } else if (isdigit((unsigned char)*format)) {
158 1.2.2.2 pgoyette char *e;
159 1.2.2.2 pgoyette precision = strtoul(format, &e, 10);
160 1.2.2.2 pgoyette format = e;
161 1.2.2.2 pgoyette }
162 1.2.2.2 pgoyette }
163 1.2.2.2 pgoyette
164 1.2.2.2 pgoyette switch (*format) {
165 1.2.2.2 pgoyette case '\0':
166 1.2.2.2 pgoyette continue;
167 1.2.2.2 pgoyette case '%':
168 1.2.2.2 pgoyette if (size > 1) {
169 1.2.2.2 pgoyette *str++ = *format;
170 1.2.2.2 pgoyette size--;
171 1.2.2.2 pgoyette }
172 1.2.2.2 pgoyette count++;
173 1.2.2.2 pgoyette break;
174 1.2.2.2 pgoyette case 'q':
175 1.2.2.2 pgoyette q = 1;
176 1.2.2.2 pgoyette format++;
177 1.2.2.2 pgoyette goto doint;
178 1.2.2.2 pgoyette case 'h':
179 1.2.2.2 pgoyette h = 1;
180 1.2.2.2 pgoyette format++;
181 1.2.2.2 pgoyette goto doint;
182 1.2.2.2 pgoyette case 'l':
183 1.2.2.2 pgoyette l = 1;
184 1.2.2.2 pgoyette format++;
185 1.2.2.2 pgoyette if (*format == 'l') {
186 1.2.2.2 pgoyette q = 1;
187 1.2.2.2 pgoyette format++;
188 1.2.2.2 pgoyette }
189 1.2.2.2 pgoyette goto doint;
190 1.2.2.2 pgoyette case 'n':
191 1.2.2.2 pgoyette case 'i':
192 1.2.2.2 pgoyette case 'd':
193 1.2.2.2 pgoyette case 'o':
194 1.2.2.2 pgoyette case 'u':
195 1.2.2.2 pgoyette case 'x':
196 1.2.2.2 pgoyette case 'X':
197 1.2.2.2 pgoyette doint:
198 1.2.2.2 pgoyette if (precision != 0)
199 1.2.2.2 pgoyette zero = 0;
200 1.2.2.2 pgoyette switch (*format) {
201 1.2.2.2 pgoyette case 'n':
202 1.2.2.2 pgoyette if (h) {
203 1.2.2.2 pgoyette short int *p;
204 1.2.2.2 pgoyette p = va_arg(ap, short *);
205 1.2.2.2 pgoyette REQUIRE(p != NULL);
206 1.2.2.2 pgoyette *p = str - save;
207 1.2.2.2 pgoyette } else if (l) {
208 1.2.2.2 pgoyette long int *p;
209 1.2.2.2 pgoyette p = va_arg(ap, long *);
210 1.2.2.2 pgoyette REQUIRE(p != NULL);
211 1.2.2.2 pgoyette *p = str - save;
212 1.2.2.2 pgoyette } else {
213 1.2.2.2 pgoyette int *p;
214 1.2.2.2 pgoyette p = va_arg(ap, int *);
215 1.2.2.2 pgoyette REQUIRE(p != NULL);
216 1.2.2.2 pgoyette *p = str - save;
217 1.2.2.2 pgoyette }
218 1.2.2.2 pgoyette break;
219 1.2.2.2 pgoyette case 'i':
220 1.2.2.2 pgoyette case 'd':
221 1.2.2.2 pgoyette if (q)
222 1.2.2.2 pgoyette tmpi = va_arg(ap, isc_int64_t);
223 1.2.2.2 pgoyette else if (l)
224 1.2.2.2 pgoyette tmpi = va_arg(ap, long int);
225 1.2.2.2 pgoyette else
226 1.2.2.2 pgoyette tmpi = va_arg(ap, int);
227 1.2.2.2 pgoyette if (tmpi < 0) {
228 1.2.2.2 pgoyette head = "-";
229 1.2.2.2 pgoyette tmpui = -tmpi;
230 1.2.2.2 pgoyette } else {
231 1.2.2.2 pgoyette if (plus)
232 1.2.2.2 pgoyette head = "+";
233 1.2.2.2 pgoyette else if (space)
234 1.2.2.2 pgoyette head = " ";
235 1.2.2.2 pgoyette else
236 1.2.2.2 pgoyette head = "";
237 1.2.2.2 pgoyette tmpui = tmpi;
238 1.2.2.2 pgoyette }
239 1.2.2.2 pgoyette sprintf(buf, "%u", tmpui);
240 1.2.2.2 pgoyette goto printint;
241 1.2.2.2 pgoyette case 'o':
242 1.2.2.2 pgoyette if (q)
243 1.2.2.2 pgoyette tmpui = va_arg(ap, isc_uint64_t);
244 1.2.2.2 pgoyette else if (l)
245 1.2.2.2 pgoyette tmpui = va_arg(ap, long int);
246 1.2.2.2 pgoyette else
247 1.2.2.2 pgoyette tmpui = va_arg(ap, int);
248 1.2.2.2 pgoyette sprintf(buf, alt ? "%#o"
249 1.2.2.2 pgoyette : "%o", tmpui);
250 1.2.2.2 pgoyette goto printint;
251 1.2.2.2 pgoyette case 'u':
252 1.2.2.2 pgoyette if (q)
253 1.2.2.2 pgoyette tmpui = va_arg(ap, isc_uint64_t);
254 1.2.2.2 pgoyette else if (l)
255 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned long int);
256 1.2.2.2 pgoyette else
257 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned int);
258 1.2.2.2 pgoyette sprintf(buf, "%u", tmpui);
259 1.2.2.2 pgoyette goto printint;
260 1.2.2.2 pgoyette case 'x':
261 1.2.2.2 pgoyette if (q)
262 1.2.2.2 pgoyette tmpui = va_arg(ap, isc_uint64_t);
263 1.2.2.2 pgoyette else if (l)
264 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned long int);
265 1.2.2.2 pgoyette else
266 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned int);
267 1.2.2.2 pgoyette if (alt) {
268 1.2.2.2 pgoyette head = "0x";
269 1.2.2.2 pgoyette if (precision > 2)
270 1.2.2.2 pgoyette precision -= 2;
271 1.2.2.2 pgoyette }
272 1.2.2.2 pgoyette sprintf(buf, "%x", tmpui);
273 1.2.2.2 pgoyette goto printint;
274 1.2.2.2 pgoyette case 'X':
275 1.2.2.2 pgoyette if (q)
276 1.2.2.2 pgoyette tmpui = va_arg(ap, isc_uint64_t);
277 1.2.2.2 pgoyette else if (l)
278 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned long int);
279 1.2.2.2 pgoyette else
280 1.2.2.2 pgoyette tmpui = va_arg(ap, unsigned int);
281 1.2.2.2 pgoyette if (alt) {
282 1.2.2.2 pgoyette head = "0X";
283 1.2.2.2 pgoyette if (precision > 2)
284 1.2.2.2 pgoyette precision -= 2;
285 1.2.2.2 pgoyette }
286 1.2.2.2 pgoyette sprintf(buf, "%X", tmpui);
287 1.2.2.2 pgoyette goto printint;
288 1.2.2.2 pgoyette printint:
289 1.2.2.2 pgoyette if (precision != 0 || width != 0) {
290 1.2.2.2 pgoyette length = strlen(buf);
291 1.2.2.2 pgoyette if (length < precision)
292 1.2.2.2 pgoyette zeropad = precision - length;
293 1.2.2.2 pgoyette else if (length < width && zero)
294 1.2.2.2 pgoyette zeropad = width - length;
295 1.2.2.2 pgoyette if (width != 0) {
296 1.2.2.2 pgoyette pad = width - length -
297 1.2.2.2 pgoyette zeropad - strlen(head);
298 1.2.2.2 pgoyette if (pad < 0)
299 1.2.2.2 pgoyette pad = 0;
300 1.2.2.2 pgoyette }
301 1.2.2.2 pgoyette }
302 1.2.2.2 pgoyette count += strlen(head) + strlen(buf) + pad +
303 1.2.2.2 pgoyette zeropad;
304 1.2.2.2 pgoyette if (!left) {
305 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
306 1.2.2.2 pgoyette *str++ = ' ';
307 1.2.2.2 pgoyette size--;
308 1.2.2.2 pgoyette pad--;
309 1.2.2.2 pgoyette }
310 1.2.2.2 pgoyette }
311 1.2.2.2 pgoyette cp = head;
312 1.2.2.2 pgoyette while (*cp != '\0' && size > 1) {
313 1.2.2.2 pgoyette *str++ = *cp++;
314 1.2.2.2 pgoyette size--;
315 1.2.2.2 pgoyette }
316 1.2.2.2 pgoyette while (zeropad > 0 && size > 1) {
317 1.2.2.2 pgoyette *str++ = '0';
318 1.2.2.2 pgoyette size--;
319 1.2.2.2 pgoyette zeropad--;
320 1.2.2.2 pgoyette }
321 1.2.2.2 pgoyette cp = buf;
322 1.2.2.2 pgoyette while (*cp != '\0' && size > 1) {
323 1.2.2.2 pgoyette *str++ = *cp++;
324 1.2.2.2 pgoyette size--;
325 1.2.2.2 pgoyette }
326 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
327 1.2.2.2 pgoyette *str++ = ' ';
328 1.2.2.2 pgoyette size--;
329 1.2.2.2 pgoyette pad--;
330 1.2.2.2 pgoyette }
331 1.2.2.2 pgoyette break;
332 1.2.2.2 pgoyette default:
333 1.2.2.2 pgoyette break;
334 1.2.2.2 pgoyette }
335 1.2.2.2 pgoyette break;
336 1.2.2.2 pgoyette case 's':
337 1.2.2.2 pgoyette cp = va_arg(ap, char *);
338 1.2.2.2 pgoyette REQUIRE(cp != NULL);
339 1.2.2.2 pgoyette
340 1.2.2.2 pgoyette if (precision != 0) {
341 1.2.2.2 pgoyette /*
342 1.2.2.2 pgoyette * cp need not be NULL terminated.
343 1.2.2.2 pgoyette */
344 1.2.2.2 pgoyette const char *tp;
345 1.2.2.2 pgoyette unsigned long n;
346 1.2.2.2 pgoyette
347 1.2.2.2 pgoyette n = precision;
348 1.2.2.2 pgoyette tp = cp;
349 1.2.2.2 pgoyette while (n != 0 && *tp != '\0')
350 1.2.2.2 pgoyette n--, tp++;
351 1.2.2.2 pgoyette length = precision - n;
352 1.2.2.2 pgoyette } else {
353 1.2.2.2 pgoyette length = strlen(cp);
354 1.2.2.2 pgoyette }
355 1.2.2.2 pgoyette if (width != 0) {
356 1.2.2.2 pgoyette pad = width - length;
357 1.2.2.2 pgoyette if (pad < 0)
358 1.2.2.2 pgoyette pad = 0;
359 1.2.2.2 pgoyette }
360 1.2.2.2 pgoyette count += pad + length;
361 1.2.2.2 pgoyette if (!left)
362 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
363 1.2.2.2 pgoyette *str++ = ' ';
364 1.2.2.2 pgoyette size--;
365 1.2.2.2 pgoyette pad--;
366 1.2.2.2 pgoyette }
367 1.2.2.2 pgoyette if (precision != 0)
368 1.2.2.2 pgoyette while (precision > 0 && *cp != '\0' &&
369 1.2.2.2 pgoyette size > 1) {
370 1.2.2.2 pgoyette *str++ = *cp++;
371 1.2.2.2 pgoyette size--;
372 1.2.2.2 pgoyette precision--;
373 1.2.2.2 pgoyette }
374 1.2.2.2 pgoyette else
375 1.2.2.2 pgoyette while (*cp != '\0' && size > 1) {
376 1.2.2.2 pgoyette *str++ = *cp++;
377 1.2.2.2 pgoyette size--;
378 1.2.2.2 pgoyette }
379 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
380 1.2.2.2 pgoyette *str++ = ' ';
381 1.2.2.2 pgoyette size--;
382 1.2.2.2 pgoyette pad--;
383 1.2.2.2 pgoyette }
384 1.2.2.2 pgoyette break;
385 1.2.2.2 pgoyette case 'c':
386 1.2.2.2 pgoyette c = va_arg(ap, int);
387 1.2.2.2 pgoyette if (width > 0) {
388 1.2.2.2 pgoyette count += width;
389 1.2.2.2 pgoyette width--;
390 1.2.2.2 pgoyette if (left) {
391 1.2.2.2 pgoyette *str++ = c;
392 1.2.2.2 pgoyette size--;
393 1.2.2.2 pgoyette }
394 1.2.2.2 pgoyette while (width-- > 0 && size > 1) {
395 1.2.2.2 pgoyette *str++ = ' ';
396 1.2.2.2 pgoyette size--;
397 1.2.2.2 pgoyette }
398 1.2.2.2 pgoyette if (!left && size > 1) {
399 1.2.2.2 pgoyette *str++ = c;
400 1.2.2.2 pgoyette size--;
401 1.2.2.2 pgoyette }
402 1.2.2.2 pgoyette } else {
403 1.2.2.2 pgoyette count++;
404 1.2.2.2 pgoyette if (size > 1) {
405 1.2.2.2 pgoyette *str++ = c;
406 1.2.2.2 pgoyette size--;
407 1.2.2.2 pgoyette }
408 1.2.2.2 pgoyette }
409 1.2.2.2 pgoyette break;
410 1.2.2.2 pgoyette case 'p':
411 1.2.2.2 pgoyette v = va_arg(ap, void *);
412 1.2.2.2 pgoyette sprintf(buf, "%p", v);
413 1.2.2.2 pgoyette length = strlen(buf);
414 1.2.2.2 pgoyette if (precision > length)
415 1.2.2.2 pgoyette zeropad = precision - length;
416 1.2.2.2 pgoyette if (width > 0) {
417 1.2.2.2 pgoyette pad = width - length - zeropad;
418 1.2.2.2 pgoyette if (pad < 0)
419 1.2.2.2 pgoyette pad = 0;
420 1.2.2.2 pgoyette }
421 1.2.2.2 pgoyette count += length + pad + zeropad;
422 1.2.2.2 pgoyette if (!left)
423 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
424 1.2.2.2 pgoyette *str++ = ' ';
425 1.2.2.2 pgoyette size--;
426 1.2.2.2 pgoyette pad--;
427 1.2.2.2 pgoyette }
428 1.2.2.2 pgoyette cp = buf;
429 1.2.2.2 pgoyette if (zeropad > 0 && buf[0] == '0' &&
430 1.2.2.2 pgoyette (buf[1] == 'x' || buf[1] == 'X')) {
431 1.2.2.2 pgoyette if (size > 1) {
432 1.2.2.2 pgoyette *str++ = *cp++;
433 1.2.2.2 pgoyette size--;
434 1.2.2.2 pgoyette }
435 1.2.2.2 pgoyette if (size > 1) {
436 1.2.2.2 pgoyette *str++ = *cp++;
437 1.2.2.2 pgoyette size--;
438 1.2.2.2 pgoyette }
439 1.2.2.2 pgoyette while (zeropad > 0 && size > 1) {
440 1.2.2.2 pgoyette *str++ = '0';
441 1.2.2.2 pgoyette size--;
442 1.2.2.2 pgoyette zeropad--;
443 1.2.2.2 pgoyette }
444 1.2.2.2 pgoyette }
445 1.2.2.2 pgoyette while (*cp != '\0' && size > 1) {
446 1.2.2.2 pgoyette *str++ = *cp++;
447 1.2.2.2 pgoyette size--;
448 1.2.2.2 pgoyette }
449 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
450 1.2.2.2 pgoyette *str++ = ' ';
451 1.2.2.2 pgoyette size--;
452 1.2.2.2 pgoyette pad--;
453 1.2.2.2 pgoyette }
454 1.2.2.2 pgoyette break;
455 1.2.2.2 pgoyette case 'D': /*deprecated*/
456 1.2.2.2 pgoyette INSIST("use %ld instead of %D" == NULL);
457 1.2.2.2 pgoyette case 'O': /*deprecated*/
458 1.2.2.2 pgoyette INSIST("use %lo instead of %O" == NULL);
459 1.2.2.2 pgoyette case 'U': /*deprecated*/
460 1.2.2.2 pgoyette INSIST("use %lu instead of %U" == NULL);
461 1.2.2.2 pgoyette
462 1.2.2.2 pgoyette case 'L':
463 1.2.2.2 pgoyette #ifdef HAVE_LONG_DOUBLE
464 1.2.2.2 pgoyette l = 1;
465 1.2.2.2 pgoyette #else
466 1.2.2.2 pgoyette INSIST("long doubles are not supported" == NULL);
467 1.2.2.2 pgoyette #endif
468 1.2.2.2 pgoyette /*FALLTHROUGH*/
469 1.2.2.2 pgoyette case 'e':
470 1.2.2.2 pgoyette case 'E':
471 1.2.2.2 pgoyette case 'f':
472 1.2.2.2 pgoyette case 'g':
473 1.2.2.2 pgoyette case 'G':
474 1.2.2.2 pgoyette if (!dot)
475 1.2.2.2 pgoyette precision = 6;
476 1.2.2.2 pgoyette /*
477 1.2.2.2 pgoyette * IEEE floating point.
478 1.2.2.2 pgoyette * MIN 2.2250738585072014E-308
479 1.2.2.2 pgoyette * MAX 1.7976931348623157E+308
480 1.2.2.2 pgoyette * VAX floating point has a smaller range than IEEE.
481 1.2.2.2 pgoyette *
482 1.2.2.2 pgoyette * precisions > 324 don't make much sense.
483 1.2.2.2 pgoyette * if we cap the precision at 512 we will not
484 1.2.2.2 pgoyette * overflow buf.
485 1.2.2.2 pgoyette */
486 1.2.2.2 pgoyette if (precision > 512)
487 1.2.2.2 pgoyette precision = 512;
488 1.2.2.2 pgoyette sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "",
489 1.2.2.2 pgoyette plus ? "+" : space ? " " : "",
490 1.2.2.2 pgoyette precision, l ? "L" : "", *format);
491 1.2.2.2 pgoyette switch (*format) {
492 1.2.2.2 pgoyette case 'e':
493 1.2.2.2 pgoyette case 'E':
494 1.2.2.2 pgoyette case 'f':
495 1.2.2.2 pgoyette case 'g':
496 1.2.2.2 pgoyette case 'G':
497 1.2.2.2 pgoyette #ifdef HAVE_LONG_DOUBLE
498 1.2.2.2 pgoyette if (l) {
499 1.2.2.2 pgoyette ldbl = va_arg(ap, long double);
500 1.2.2.2 pgoyette sprintf(buf, fmt, ldbl);
501 1.2.2.2 pgoyette } else
502 1.2.2.2 pgoyette #endif
503 1.2.2.2 pgoyette {
504 1.2.2.2 pgoyette dbl = va_arg(ap, double);
505 1.2.2.2 pgoyette sprintf(buf, fmt, dbl);
506 1.2.2.2 pgoyette }
507 1.2.2.2 pgoyette length = strlen(buf);
508 1.2.2.2 pgoyette if (width > 0) {
509 1.2.2.2 pgoyette pad = width - length;
510 1.2.2.2 pgoyette if (pad < 0)
511 1.2.2.2 pgoyette pad = 0;
512 1.2.2.2 pgoyette }
513 1.2.2.2 pgoyette count += length + pad;
514 1.2.2.2 pgoyette if (!left)
515 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
516 1.2.2.2 pgoyette *str++ = ' ';
517 1.2.2.2 pgoyette size--;
518 1.2.2.2 pgoyette pad--;
519 1.2.2.2 pgoyette }
520 1.2.2.2 pgoyette cp = buf;
521 1.2.2.2 pgoyette while (*cp != ' ' && size > 1) {
522 1.2.2.2 pgoyette *str++ = *cp++;
523 1.2.2.2 pgoyette size--;
524 1.2.2.2 pgoyette }
525 1.2.2.2 pgoyette while (pad > 0 && size > 1) {
526 1.2.2.2 pgoyette *str++ = ' ';
527 1.2.2.2 pgoyette size--;
528 1.2.2.2 pgoyette pad--;
529 1.2.2.2 pgoyette }
530 1.2.2.2 pgoyette break;
531 1.2.2.2 pgoyette default:
532 1.2.2.2 pgoyette continue;
533 1.2.2.2 pgoyette }
534 1.2.2.2 pgoyette break;
535 1.2.2.2 pgoyette default:
536 1.2.2.2 pgoyette continue;
537 1.2.2.2 pgoyette }
538 1.2.2.2 pgoyette format++;
539 1.2.2.2 pgoyette }
540 1.2.2.2 pgoyette if (size > 0)
541 1.2.2.2 pgoyette *str = '\0';
542 1.2.2.2 pgoyette return (count);
543 1.2.2.2 pgoyette }
544 1.2.2.2 pgoyette
545 1.2.2.2 pgoyette #endif
546