1 | /*-␊ |
2 | * Copyright (c) 1990, 1993␊ |
3 | *␉The Regents of the University of California. All rights reserved.␊ |
4 | *␊ |
5 | * This code is derived from software contributed to Berkeley by␊ |
6 | * Chris Torek.␊ |
7 | *␊ |
8 | * Redistribution and use in source and binary forms, with or without␊ |
9 | * modification, are permitted provided that the following conditions␊ |
10 | * are met:␊ |
11 | * 1. Redistributions of source code must retain the above copyright␊ |
12 | * notice, this list of conditions and the following disclaimer.␊ |
13 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
14 | * notice, this list of conditions and the following disclaimer in the␊ |
15 | * documentation and/or other materials provided with the distribution.␊ |
16 | * 3. All advertising materials mentioning features or use of this software␊ |
17 | * must display the following acknowledgement:␊ |
18 | *␉This product includes software developed by the University of␊ |
19 | *␉California, Berkeley and its contributors.␊ |
20 | * 4. Neither the name of the University nor the names of its contributors␊ |
21 | * may be used to endorse or promote products derived from this software␊ |
22 | * without specific prior written permission.␊ |
23 | *␊ |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
34 | * SUCH DAMAGE.␊ |
35 | */␊ |
36 | ␊ |
37 | #if defined(LIBC_SCCS) && !defined(lint)␊ |
38 | #if 0␊ |
39 | static char sccsid[] = "@(#)vfprintf.c␉8.1 (Berkeley) 6/4/93";␊ |
40 | #endif␊ |
41 | static const char rcsid[] =␊ |
42 | "$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.22.2.6 2012/11/17 07:23:37 svnexp Exp $";␊ |
43 | #endif /* LIBC_SCCS and not lint */␊ |
44 | ␊ |
45 | /*␊ |
46 | * Actual printf innards.␊ |
47 | *␊ |
48 | * This code is large and complicated...␊ |
49 | */␊ |
50 | ␊ |
51 | #include "namespace.h"␊ |
52 | #include <sys/types.h>␊ |
53 | ␊ |
54 | #include <ctype.h>␊ |
55 | #include <limits.h>␊ |
56 | #include <locale.h>␊ |
57 | #include <stddef.h>␊ |
58 | #include <stdint.h>␊ |
59 | #include <stdio.h>␊ |
60 | #include <stdlib.h>␊ |
61 | #include <string.h>␊ |
62 | #if __STDC__␊ |
63 | #include <stdarg.h>␊ |
64 | #else␊ |
65 | #include <varargs.h>␊ |
66 | #endif␊ |
67 | #include <errno.h>␊ |
68 | #include "un-namespace.h"␊ |
69 | #include "local.h"␊ |
70 | #include "fvwrite.h"␊ |
71 | #include "printflocal.h"␊ |
72 | ␊ |
73 | static int␉__sprint __P((FILE *, struct __suio *));␊ |
74 | static int␉__sbprintf __P((FILE *, const char *, va_list));␊ |
75 | static char *␉__ultoa __P((u_long, char *, int, int, char *));␊ |
76 | static char *␉__uqtoa __P((u_quad_t, char *, int, int, char *));␊ |
77 | ␊ |
78 | /*␊ |
79 | * Flush out all the vectors defined by the given uio,␊ |
80 | * then reset it so that it can be reused.␊ |
81 | */␊ |
82 | static int␊ |
83 | __sprint(FILE *fp, struct __suio *uio)␊ |
84 | {␊ |
85 | ␉int err;␊ |
86 | ␊ |
87 | ␉if (uio->uio_resid == 0) {␊ |
88 | ␉␉uio->uio_iovcnt = 0;␊ |
89 | ␉␉return (0);␊ |
90 | ␉}␊ |
91 | ␉err = __sfvwrite(fp, uio);␊ |
92 | ␉uio->uio_resid = 0;␊ |
93 | ␉uio->uio_iovcnt = 0;␊ |
94 | ␉return (err);␊ |
95 | }␊ |
96 | ␊ |
97 | /*␊ |
98 | * Helper function for `fprintf to unbuffered unix file': creates a␊ |
99 | * temporary buffer. We only work on write-only files; this avoids␊ |
100 | * worries about ungetc buffers and so forth.␊ |
101 | */␊ |
102 | static int␊ |
103 | __sbprintf(FILE *fp, const char *fmt, va_list ap)␊ |
104 | {␊ |
105 | ␉int ret;␊ |
106 | ␉FILE fake;␊ |
107 | ␉unsigned char buf[BUFSIZ];␊ |
108 | ␊ |
109 | ␉/* copy the important variables */␊ |
110 | ␉fake._flags = fp->_flags & ~__SNBF;␊ |
111 | ␉fake._file = fp->_file;␊ |
112 | ␉fake._cookie = fp->_cookie;␊ |
113 | ␉fake._write = fp->_write;␊ |
114 | ␊ |
115 | ␉/* set up the buffer */␊ |
116 | ␉fake._bf._base = fake._p = buf;␊ |
117 | ␉fake._bf._size = fake._w = sizeof(buf);␊ |
118 | ␉fake._lbfsize = 0;␉/* not actually used, but Just In Case */␊ |
119 | ␊ |
120 | ␉/* do the work, then copy any error status */␊ |
121 | ␉ret = vfprintf(&fake, fmt, ap);␊ |
122 | ␉if (ret >= 0 && fflush(&fake))␊ |
123 | ␉␉ret = EOF;␊ |
124 | ␉if (fake._flags & __SERR)␊ |
125 | ␉␉fp->_flags |= __SERR;␊ |
126 | ␉return (ret);␊ |
127 | }␊ |
128 | ␊ |
129 | /*␊ |
130 | * Macros for converting digits to letters and vice versa␊ |
131 | */␊ |
132 | #define␉to_digit(c)␉((c) - '0')␊ |
133 | #define is_digit(c)␉((unsigned)to_digit(c) <= 9)␊ |
134 | #define␉to_char(n)␉((n) + '0')␊ |
135 | ␊ |
136 | /*␊ |
137 | * Convert an unsigned long to ASCII for printf purposes, returning␊ |
138 | * a pointer to the first character of the string representation.␊ |
139 | * Octal numbers can be forced to have a leading zero; hex numbers␊ |
140 | * use the given digits.␊ |
141 | */␊ |
142 | static char *␊ |
143 | __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)␊ |
144 | {␊ |
145 | ␉register char *cp = endp;␊ |
146 | ␉register long sval;␊ |
147 | ␊ |
148 | ␉/*␊ |
149 | ␉ * Handle the three cases separately, in the hope of getting␊ |
150 | ␉ * better/faster code.␊ |
151 | ␉ */␊ |
152 | ␉switch (base) {␊ |
153 | case 10:␊ |
154 | if (val < 10) {␉/* many numbers are 1 digit */␊ |
155 | *--cp = to_char(val);␊ |
156 | return (cp);␊ |
157 | }␊ |
158 | /*␊ |
159 | * On many machines, unsigned arithmetic is harder than␊ |
160 | * signed arithmetic, so we do at most one unsigned mod and␊ |
161 | * divide; this is sufficient to reduce the range of␊ |
162 | * the incoming value to where signed arithmetic works.␊ |
163 | */␊ |
164 | if (val > LONG_MAX) {␊ |
165 | *--cp = to_char(val % 10);␊ |
166 | sval = val / 10;␊ |
167 | } else␊ |
168 | sval = val;␊ |
169 | do {␊ |
170 | *--cp = to_char(sval % 10);␊ |
171 | sval /= 10;␊ |
172 | } while (sval != 0);␊ |
173 | break;␊ |
174 | ␊ |
175 | case 8:␊ |
176 | do {␊ |
177 | *--cp = to_char(val & 7);␊ |
178 | val >>= 3;␊ |
179 | } while (val);␊ |
180 | if (octzero && *cp != '0')␊ |
181 | *--cp = '0';␊ |
182 | break;␊ |
183 | ␊ |
184 | case 16:␊ |
185 | do {␊ |
186 | *--cp = xdigs[val & 15];␊ |
187 | val >>= 4;␊ |
188 | } while (val);␊ |
189 | break;␊ |
190 | ␊ |
191 | default:␉␉␉/* oops */␊ |
192 | abort();␊ |
193 | ␉}␊ |
194 | ␉return (cp);␊ |
195 | }␊ |
196 | ␊ |
197 | /* Identical to __ultoa, but for quads. */␊ |
198 | static char *␊ |
199 | __uqtoa(u_quad_t val, char *endp, int base, int octzero, char *xdigs)␊ |
200 | {␊ |
201 | ␉char *cp = endp;␊ |
202 | ␉quad_t sval;␊ |
203 | ␊ |
204 | ␉/* quick test for small values; __ultoa is typically much faster */␊ |
205 | ␉/* (perhaps instead we should run until small, then call __ultoa?) */␊ |
206 | ␉if (val <= ULONG_MAX)␊ |
207 | ␉␉return (__ultoa((u_long)val, endp, base, octzero, xdigs));␊ |
208 | ␉switch (base) {␊ |
209 | case 10:␊ |
210 | if (val < 10) {␊ |
211 | *--cp = to_char(val % 10);␊ |
212 | return (cp);␊ |
213 | }␊ |
214 | if (val > QUAD_MAX) {␊ |
215 | *--cp = to_char(val % 10);␊ |
216 | sval = val / 10;␊ |
217 | } else␊ |
218 | sval = val;␊ |
219 | do {␊ |
220 | *--cp = to_char(sval % 10);␊ |
221 | sval /= 10;␊ |
222 | } while (sval != 0);␊ |
223 | break;␊ |
224 | ␊ |
225 | case 8:␊ |
226 | do {␊ |
227 | *--cp = to_char(val & 7);␊ |
228 | val >>= 3;␊ |
229 | } while (val);␊ |
230 | if (octzero && *cp != '0')␊ |
231 | *--cp = '0';␊ |
232 | break;␊ |
233 | ␊ |
234 | case 16:␊ |
235 | do {␊ |
236 | *--cp = xdigs[val & 15];␊ |
237 | val >>= 4;␊ |
238 | } while (val);␊ |
239 | break;␊ |
240 | ␊ |
241 | default:␊ |
242 | abort();␊ |
243 | ␉}␊ |
244 | ␉return (cp);␊ |
245 | }␊ |
246 | ␊ |
247 | #ifndef NO_FLOATING_POINT␊ |
248 | ␊ |
249 | ␊ |
250 | #else /* no FLOATING_POINT */␊ |
251 | ␊ |
252 | #define␉BUF␉␉68␊ |
253 | ␊ |
254 | #endif /* FLOATING_POINT */␊ |
255 | ␊ |
256 | #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */␊ |
257 | ␊ |
258 | /*␊ |
259 | * Flags used during conversion.␊ |
260 | */␊ |
261 | #define␉ALT␉␉0x001␉␉/* alternate form */␊ |
262 | #define␉HEXPREFIX␉0x002␉␉/* add 0x or 0X prefix */␊ |
263 | #define␉LADJUST␉␉0x004␉␉/* left adjustment */␊ |
264 | #define␉LONGDBL␉␉0x008␉␉/* long double */␊ |
265 | #define␉LONGINT␉␉0x010␉␉/* long integer */␊ |
266 | #define␉QUADINT␉␉0x020␉␉/* quad integer */␊ |
267 | #define␉SHORTINT␉0x040␉␉/* short integer */␊ |
268 | #define␉ZEROPAD␉␉0x080␉␉/* zero (as opposed to blank) pad */␊ |
269 | #define FPT␉␉0x100␉␉/* Floating point number */␊ |
270 | int␊ |
271 | vfprintf(FILE *fp, const char *fmt0, va_list ap)␊ |
272 | {␊ |
273 | ␉char *fmt;␉␉/* format string */␊ |
274 | ␉int ch;␉␉␉/* character from fmt */␊ |
275 | ␉int n, n2;␉␉/* handy integer (short term usage) */␊ |
276 | ␉char *cp;␉␉/* handy char pointer (short term usage) */␊ |
277 | ␉struct __siov *iovp;␉/* for PRINT macro */␊ |
278 | ␉int flags;␉␉/* flags as above */␊ |
279 | ␉int ret;␉␉/* return value accumulator */␊ |
280 | ␉int width;␉␉/* width from format (%8d), or 0 */␊ |
281 | ␉int prec;␉␉/* precision from format (%.3d), or -1 */␊ |
282 | ␉char sign;␉␉/* sign prefix (' ', '+', '-', or \0) */␊ |
283 | #ifndef NO_FLOATING_POINT␊ |
284 | ␉char *decimal_point = localeconv()->decimal_point;␊ |
285 | ␉char softsign;␉␉/* temporary negative sign for floats */␊ |
286 | ␉double _double;␉␉/* double precision arguments %[eEfgG] */␊ |
287 | ␉int expt;␉␉/* integer value of exponent */␊ |
288 | ␉int expsize;␉␉/* character count for expstr */␊ |
289 | ␉int ndig;␉␉/* actual number of digits returned by cvt */␊ |
290 | ␉char expstr[7];␉␉/* buffer for exponent string */␊ |
291 | ␉char *dtoaresult;␉/* buffer allocated by dtoa */␊ |
292 | #endif␊ |
293 | ␉u_long␉ulval = 0;␉␉/* integer arguments %[diouxX] */␊ |
294 | ␉u_quad_t uqval = 0;␉␉/* %q integers */␊ |
295 | ␉int base;␉␉/* base for [diouxX] conversion */␊ |
296 | ␉int dprec;␉␉/* a copy of prec if [diouxX], 0 otherwise */␊ |
297 | ␉int realsz;␉␉/* field size expanded by dprec, sign, etc */␊ |
298 | ␉int size;␉␉/* size of converted field or string */␊ |
299 | ␉int prsize; /* max size of printed field */␊ |
300 | ␉char *xdigs = NULL;␉␉/* digits for [xX] conversion */␊ |
301 | #define NIOV 8␊ |
302 | ␉struct __suio uio;␉/* output information: summary */␊ |
303 | ␉struct __siov iov[NIOV];/* ... and individual io vectors */␊ |
304 | ␉char buf[BUF];␉␉/* space for %c, %[diouxX], %[eEfgG] */␊ |
305 | ␉char ox[2];␉␉/* space for 0x hex-prefix */␊ |
306 | union arg *argtable; /* args, built due to positional arg */␊ |
307 | ␉union arg statargtable [STATIC_ARG_TBL_SIZE];␊ |
308 | int nextarg; /* 1-based argument index */␊ |
309 | va_list orgap; /* original argument pointer */␊ |
310 | ␊ |
311 | ␉/*␊ |
312 | ␉ * Choose PADSIZE to trade efficiency vs. size. If larger printf␊ |
313 | ␉ * fields occur frequently, increase PADSIZE and make the initialisers␊ |
314 | ␉ * below longer.␊ |
315 | ␉ */␊ |
316 | #define␉PADSIZE␉16␉␉/* pad chunk size */␊ |
317 | ␉static char blanks[PADSIZE] =␊ |
318 | {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};␊ |
319 | ␉static char zeroes[PADSIZE] =␊ |
320 | {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};␊ |
321 | ␊ |
322 | ␉/*␊ |
323 | ␉ * BEWARE, these `goto error' on error, and PAD uses `n'.␊ |
324 | ␉ */␊ |
325 | #define␉PRINT(ptr, len) { \␊ |
326 | iovp->iov_base = (ptr); \␊ |
327 | iovp->iov_len = (len); \␊ |
328 | uio.uio_resid += (len); \␊ |
329 | iovp++; \␊ |
330 | if (++uio.uio_iovcnt >= NIOV) { \␊ |
331 | if (__sprint(fp, &uio)) \␊ |
332 | goto error; \␊ |
333 | iovp = iov; \␊ |
334 | } \␊ |
335 | }␊ |
336 | #define␉PAD(howmany, with) { \␊ |
337 | if ((n = (howmany)) > 0) { \␊ |
338 | while (n > PADSIZE) { \␊ |
339 | PRINT(with, PADSIZE); \␊ |
340 | n -= PADSIZE; \␊ |
341 | } \␊ |
342 | PRINT(with, n); \␊ |
343 | } \␊ |
344 | }␊ |
345 | #define␉FLUSH() { \␊ |
346 | if (uio.uio_resid && __sprint(fp, &uio)) \␊ |
347 | goto error; \␊ |
348 | uio.uio_iovcnt = 0; \␊ |
349 | iovp = iov; \␊ |
350 | }␊ |
351 | ␊ |
352 | ␉/*␊ |
353 | ␉ * Get the argument indexed by nextarg. If the argument table is␊ |
354 | ␉ * built, use it to get the argument. If its not, get the next␊ |
355 | ␉ * argument (and arguments must be gotten sequentially).␊ |
356 | ␉ */␊ |
357 | #define GETARG(type) \␊ |
358 | ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \␊ |
359 | (nextarg++, va_arg(ap, type)))␊ |
360 | ␊ |
361 | ␉/*␊ |
362 | ␉ * To extend shorts properly, we need both signed and unsigned␊ |
363 | ␉ * argument extraction methods.␊ |
364 | ␉ */␊ |
365 | #define␉SARG() \␊ |
366 | (flags&LONGINT ? GETARG(long) : \␊ |
367 | flags&SHORTINT ? (long)(short)GETARG(int) : \␊ |
368 | flags&CHARINT ? (long)(signed char)GETARG(int) : \␊ |
369 | (long)GETARG(int))␊ |
370 | #define␉UARG() \␊ |
371 | (flags&LONGINT ? GETARG(u_long) : \␊ |
372 | flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \␊ |
373 | flags&CHARINT ? (u_long)(u_char)GETARG(int) : \␊ |
374 | (u_long)GETARG(u_int))␊ |
375 | #define␉INTMAX_SIZE␉(INTMAXT|SIZET|PTRDIFFT|LLONGINT)␊ |
376 | #define SJARG() \␊ |
377 | (flags&INTMAXT ? GETARG(intmax_t) : \␊ |
378 | flags&SIZET ? (intmax_t)GETARG(ssize_t) : \␊ |
379 | flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \␊ |
380 | (intmax_t)GETARG(long long))␊ |
381 | #define␉UJARG() \␊ |
382 | (flags&INTMAXT ? GETARG(uintmax_t) : \␊ |
383 | flags&SIZET ? (uintmax_t)GETARG(size_t) : \␊ |
384 | flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \␊ |
385 | (uintmax_t)GETARG(unsigned long long))␊ |
386 | ␊ |
387 | ␉/*␊ |
388 | ␉ * Get * arguments, including the form *nn$. Preserve the nextarg␊ |
389 | ␉ * that the argument can be gotten once the type is determined.␊ |
390 | ␉ */␊ |
391 | #define GETASTER(val) \␊ |
392 | n2 = 0; \␊ |
393 | cp = fmt; \␊ |
394 | while (is_digit(*cp)) { \␊ |
395 | n2 = 10 * n2 + to_digit(*cp); \␊ |
396 | cp++; \␊ |
397 | } \␊ |
398 | if (*cp == '$') { \␊ |
399 | int hold = nextarg; \␊ |
400 | if (argtable == NULL) { \␊ |
401 | argtable = statargtable; \␊ |
402 | if (__find_arguments (fmt0, orgap, &argtable)) { \␊ |
403 | ret = EOF; \␊ |
404 | goto error; \␊ |
405 | } \␊ |
406 | } \␊ |
407 | nextarg = n2; \␊ |
408 | val = GETARG (int); \␊ |
409 | nextarg = hold; \␊ |
410 | fmt = ++cp; \␊ |
411 | } else { \␊ |
412 | val = GETARG (int); \␊ |
413 | }␊ |
414 | ␊ |
415 | ␊ |
416 | #ifndef NO_FLOATING_POINT␊ |
417 | ␉dtoaresult = NULL;␊ |
418 | #endif␊ |
419 | ␉/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */␊ |
420 | ␉if (prepwrite(fp) != 0)␊ |
421 | ␉␉return (EOF);␊ |
422 | ␊ |
423 | ␉/* optimise fprintf(stderr) (and other unbuffered Unix files) */␊ |
424 | ␉if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&␊ |
425 | ␉ fp->_file >= 0) {␊ |
426 | ␉␉return (__sbprintf(fp, fmt0, ap));␊ |
427 | ␉}␊ |
428 | ␊ |
429 | ␉fmt = (char *)fmt0;␊ |
430 | argtable = NULL;␊ |
431 | nextarg = 1;␊ |
432 | orgap = ap;␊ |
433 | ␉uio.uio_iov = iovp = iov;␊ |
434 | ␉uio.uio_resid = 0;␊ |
435 | ␉uio.uio_iovcnt = 0;␊ |
436 | ␉ret = 0;␊ |
437 | ␊ |
438 | ␉/*␊ |
439 | ␉ * Scan the format for conversions (`%' character).␊ |
440 | ␉ */␊ |
441 | ␉for (;;) {␊ |
442 | ␉␉for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)␊ |
443 | /* void */;␊ |
444 | ␉␉if ((n = fmt - cp) != 0) {␊ |
445 | ␉␉␉if ((unsigned)ret + n > INT_MAX) {␊ |
446 | ␉␉␉␉ret = EOF;␊ |
447 | ␉␉␉␉goto error;␊ |
448 | ␉␉␉}␊ |
449 | ␉␉␉PRINT(cp, n);␊ |
450 | ␉␉␉ret += n;␊ |
451 | ␉␉}␊ |
452 | ␉␉if (ch == '\0')␊ |
453 | ␉␉␉goto done;␊ |
454 | ␉␉fmt++;␉␉/* skip over '%' */␊ |
455 | ␊ |
456 | ␉␉flags = 0;␊ |
457 | ␉␉dprec = 0;␊ |
458 | ␉␉width = 0;␊ |
459 | ␉␉prec = -1;␊ |
460 | ␉␉sign = '\0';␊ |
461 | ␊ |
462 | rflag:␉␉ch = *fmt++;␊ |
463 | reswitch:␉switch (ch) {␊ |
464 | ␉␉case ' ':␊ |
465 | ␉␉␉/*␊ |
466 | ␉␉␉ * ``If the space and + flags both appear, the space␊ |
467 | ␉␉␉ * flag will be ignored.''␊ |
468 | ␉␉␉ *␉-- ANSI X3J11␊ |
469 | ␉␉␉ */␊ |
470 | ␉␉␉if (!sign)␊ |
471 | ␉␉␉␉sign = ' ';␊ |
472 | ␉␉␉goto rflag;␊ |
473 | ␉␉case '#':␊ |
474 | ␉␉␉flags |= ALT;␊ |
475 | ␉␉␉goto rflag;␊ |
476 | ␉␉case '*':␊ |
477 | ␉␉␉/*␊ |
478 | ␉␉␉ * ``A negative field width argument is taken as a␊ |
479 | ␉␉␉ * - flag followed by a positive field width.''␊ |
480 | ␉␉␉ *␉-- ANSI X3J11␊ |
481 | ␉␉␉ * They don't exclude field widths read from args.␊ |
482 | ␉␉␉ */␊ |
483 | ␉␉␉GETASTER (width);␊ |
484 | ␉␉␉if (width >= 0)␊ |
485 | ␉␉␉␉goto rflag;␊ |
486 | ␉␉␉width = -width;␊ |
487 | ␉␉␉/* FALLTHROUGH */␊ |
488 | ␉␉case '-':␊ |
489 | ␉␉␉flags |= LADJUST;␊ |
490 | ␉␉␉goto rflag;␊ |
491 | ␉␉case '+':␊ |
492 | ␉␉␉sign = '+';␊ |
493 | ␉␉␉goto rflag;␊ |
494 | ␉␉case '.':␊ |
495 | ␉␉␉if ((ch = *fmt++) == '*') {␊ |
496 | ␉␉␉␉GETASTER (n);␊ |
497 | ␉␉␉␉prec = n < 0 ? -1 : n;␊ |
498 | ␉␉␉␉goto rflag;␊ |
499 | ␉␉␉}␊ |
500 | ␉␉␉n = 0;␊ |
501 | ␉␉␉while (is_digit(ch)) {␊ |
502 | ␉␉␉␉n = 10 * n + to_digit(ch);␊ |
503 | ␉␉␉␉ch = *fmt++;␊ |
504 | ␉␉␉}␊ |
505 | ␉␉␉prec = n < 0 ? -1 : n;␊ |
506 | ␉␉␉goto reswitch;␊ |
507 | ␉␉case '0':␊ |
508 | ␉␉␉/*␊ |
509 | ␉␉␉ * ``Note that 0 is taken as a flag, not as the␊ |
510 | ␉␉␉ * beginning of a field width.''␊ |
511 | ␉␉␉ *␉-- ANSI X3J11␊ |
512 | ␉␉␉ */␊ |
513 | ␉␉␉flags |= ZEROPAD;␊ |
514 | ␉␉␉goto rflag;␊ |
515 | ␉␉case '1': case '2': case '3': case '4':␊ |
516 | ␉␉case '5': case '6': case '7': case '8': case '9':␊ |
517 | ␉␉␉n = 0;␊ |
518 | ␉␉␉do {␊ |
519 | ␉␉␉␉n = 10 * n + to_digit(ch);␊ |
520 | ␉␉␉␉ch = *fmt++;␊ |
521 | ␉␉␉} while (is_digit(ch));␊ |
522 | ␉␉␉if (ch == '$') {␊ |
523 | ␉␉␉␉nextarg = n;␊ |
524 | if (argtable == NULL) {␊ |
525 | argtable = statargtable;␊ |
526 | __find_arguments (fmt0, orgap,␊ |
527 | &argtable);␊ |
528 | ␉␉␉␉}␊ |
529 | ␉␉␉␉goto rflag;␊ |
530 | }␊ |
531 | ␉␉␉width = n;␊ |
532 | ␉␉␉goto reswitch;␊ |
533 | #ifndef NO_FLOATING_POINT␊ |
534 | ␉␉case 'L':␊ |
535 | ␉␉␉flags |= LONGDBL;␊ |
536 | ␉␉␉goto rflag;␊ |
537 | #endif␊ |
538 | ␉␉case 'h':␊ |
539 | ␉␉␉flags |= SHORTINT;␊ |
540 | ␉␉␉goto rflag;␊ |
541 | ␉␉case 'l':␊ |
542 | ␉␉␉if (flags & LONGINT)␊ |
543 | ␉␉␉␉flags |= QUADINT;␊ |
544 | ␉␉␉else␊ |
545 | ␉␉␉␉flags |= LONGINT;␊ |
546 | ␉␉␉goto rflag;␊ |
547 | ␉␉case 'q':␊ |
548 | ␉␉␉flags |= QUADINT;␊ |
549 | ␉␉␉goto rflag;␊ |
550 | ␉␉case 'c':␊ |
551 | ␉␉␉*(cp = buf) = GETARG(int);␊ |
552 | ␉␉␉size = 1;␊ |
553 | ␉␉␉sign = '\0';␊ |
554 | ␉␉␉break;␊ |
555 | ␉␉case 'D':␊ |
556 | ␉␉␉flags |= LONGINT;␊ |
557 | ␉␉␉/*FALLTHROUGH*/␊ |
558 | ␉␉case 'd':␊ |
559 | ␉␉case 'i':␊ |
560 | ␉␉␉if (flags & QUADINT) {␊ |
561 | ␉␉␉␉uqval = GETARG(quad_t);␊ |
562 | ␉␉␉␉if ((quad_t)uqval < 0) {␊ |
563 | ␉␉␉␉␉uqval = -uqval;␊ |
564 | ␉␉␉␉␉sign = '-';␊ |
565 | ␉␉␉␉}␊ |
566 | ␉␉␉} else {␊ |
567 | ␉␉␉␉ulval = SARG();␊ |
568 | ␉␉␉␉if ((long)ulval < 0) {␊ |
569 | ␉␉␉␉␉ulval = -ulval;␊ |
570 | ␉␉␉␉␉sign = '-';␊ |
571 | ␉␉␉␉}␊ |
572 | ␉␉␉}␊ |
573 | ␉␉␉base = 10;␊ |
574 | ␉␉␉goto number;␊ |
575 | #ifndef NO_FLOATING_POINT␊ |
576 | ␉␉case 'e':␊ |
577 | ␉␉case 'E':␊ |
578 | ␉␉case 'f':␊ |
579 | ␉␉␉goto fp_begin;␊ |
580 | ␉␉case 'g':␊ |
581 | ␉␉case 'G':␊ |
582 | ␉␉␉if (prec == 0)␊ |
583 | ␉␉␉␉prec = 1;␊ |
584 | fp_begin:␉␉if (prec == -1)␊ |
585 | prec = DEFPREC;␊ |
586 | ␉␉␉if (flags & LONGDBL)␊ |
587 | /* XXX this loses precision. */␊ |
588 | ␉␉␉␉_double = (double)GETARG(long double);␊ |
589 | ␉␉␉else␊ |
590 | ␉␉␉␉_double = GETARG(double);␊ |
591 | ␉␉␉/* do this before tricky precision changes */␊ |
592 | ␉␉␉if (isinf(_double)) {␊ |
593 | ␉␉␉␉if (_double < 0)␊ |
594 | ␉␉␉␉␉sign = '-';␊ |
595 | ␉␉␉␉cp = "Inf";␊ |
596 | ␉␉␉␉size = 3;␊ |
597 | ␉␉␉␉break;␊ |
598 | ␉␉␉}␊ |
599 | ␉␉␉if (isnan(_double)) {␊ |
600 | ␉␉␉␉cp = "NaN";␊ |
601 | ␉␉␉␉size = 3;␊ |
602 | ␉␉␉␉break;␊ |
603 | ␉␉␉}␊ |
604 | ␉␉␉flags |= FPT;␊ |
605 | ␉␉␉if (dtoaresult != NULL) {␊ |
606 | ␉␉␉␉free(dtoaresult);␊ |
607 | ␉␉␉␉dtoaresult = NULL;␊ |
608 | ␉␉␉}␊ |
609 | ␉␉␉cp = cvt(_double, prec, flags, &softsign,␊ |
610 | &expt, ch, &ndig, &dtoaresult);␊ |
611 | ␉␉␉if (ch == 'g' || ch == 'G') {␊ |
612 | ␉␉␉␉if (expt <= -4 || expt > prec)␊ |
613 | ␉␉␉␉␉ch = (ch == 'g') ? 'e' : 'E';␊ |
614 | ␉␉␉␉else␊ |
615 | ␉␉␉␉␉ch = 'g';␊ |
616 | ␉␉␉}␊ |
617 | ␉␉␉if (ch <= 'e') {␉/* 'e' or 'E' fmt */␊ |
618 | ␉␉␉␉--expt;␊ |
619 | ␉␉␉␉expsize = exponent(expstr, expt, ch);␊ |
620 | ␉␉␉␉size = expsize + ndig;␊ |
621 | ␉␉␉␉if (ndig > 1 || flags & ALT)␊ |
622 | ␉␉␉␉␉++size;␊ |
623 | ␉␉␉} else if (ch == 'f') {␉␉/* f fmt */␊ |
624 | ␉␉␉␉if (expt > 0) {␊ |
625 | ␉␉␉␉␉size = expt;␊ |
626 | ␉␉␉␉␉if (prec || flags & ALT)␊ |
627 | ␉␉␉␉␉␉size += prec + 1;␊ |
628 | ␉␉␉␉} else␉/* "0.X" */␊ |
629 | ␉␉␉␉␉size = prec + 2;␊ |
630 | ␉␉␉} else if (expt >= ndig) {␉/* fixed g fmt */␊ |
631 | ␉␉␉␉size = expt;␊ |
632 | ␉␉␉␉if (flags & ALT)␊ |
633 | ␉␉␉␉␉++size;␊ |
634 | ␉␉␉} else␊ |
635 | ␉␉␉␉size = ndig + (expt > 0 ?␊ |
636 | 1 : 2 - expt);␊ |
637 | ␊ |
638 | ␉␉␉if (softsign)␊ |
639 | ␉␉␉␉sign = '-';␊ |
640 | ␉␉␉break;␊ |
641 | #endif /* FLOATING_POINT */␊ |
642 | ␉␉case 'n':␊ |
643 | ␉␉␉if (flags & QUADINT)␊ |
644 | ␉␉␉␉*GETARG(quad_t *) = ret;␊ |
645 | ␉␉␉else if (flags & LONGINT)␊ |
646 | ␉␉␉␉*GETARG(long *) = ret;␊ |
647 | ␉␉␉else if (flags & SHORTINT)␊ |
648 | ␉␉␉␉*GETARG(short *) = ret;␊ |
649 | ␉␉␉else␊ |
650 | ␉␉␉␉*GETARG(int *) = ret;␊ |
651 | ␉␉␉continue;␉/* no output */␊ |
652 | ␉␉case 'O':␊ |
653 | ␉␉␉flags |= LONGINT;␊ |
654 | ␉␉␉/*FALLTHROUGH*/␊ |
655 | ␉␉case 'o':␊ |
656 | ␉␉␉if (flags & QUADINT)␊ |
657 | ␉␉␉␉uqval = GETARG(u_quad_t);␊ |
658 | ␉␉␉else␊ |
659 | ␉␉␉␉ulval = UARG();␊ |
660 | ␉␉␉base = 8;␊ |
661 | ␉␉␉goto nosign;␊ |
662 | ␉␉case 'p':␊ |
663 | ␉␉␉/*␊ |
664 | ␉␉␉ * ``The argument shall be a pointer to void. The␊ |
665 | ␉␉␉ * value of the pointer is converted to a sequence␊ |
666 | ␉␉␉ * of printable characters, in an implementation-␊ |
667 | ␉␉␉ * defined manner.''␊ |
668 | ␉␉␉ *␉-- ANSI X3J11␊ |
669 | ␉␉␉ */␊ |
670 | ␉␉␉ulval = (u_long)GETARG(void *);␊ |
671 | ␉␉␉base = 16;␊ |
672 | ␉␉␉xdigs = "0123456789abcdef";␊ |
673 | ␉␉␉flags = (flags & ~QUADINT) | HEXPREFIX;␊ |
674 | ␉␉␉ch = 'x';␊ |
675 | ␉␉␉goto nosign;␊ |
676 | ␉␉case 's':␊ |
677 | ␉␉␉if ((cp = GETARG(char *)) == NULL)␊ |
678 | ␉␉␉␉cp = "(null)";␊ |
679 | ␉␉␉if (prec >= 0) {␊ |
680 | ␉␉␉␉/*␊ |
681 | ␉␉␉␉ * can't use strlen; can only look for the␊ |
682 | ␉␉␉␉ * NUL in the first `prec' characters, and␊ |
683 | ␉␉␉␉ * strlen() will go further.␊ |
684 | ␉␉␉␉ */␊ |
685 | ␉␉␉␉char *p = memchr(cp, 0, (size_t)prec);␊ |
686 | ␊ |
687 | ␉␉␉␉if (p != NULL) {␊ |
688 | ␉␉␉␉␉size = p - cp;␊ |
689 | ␉␉␉␉␉if (size > prec)␊ |
690 | ␉␉␉␉␉␉size = prec;␊ |
691 | ␉␉␉␉} else␊ |
692 | ␉␉␉␉␉size = prec;␊ |
693 | ␉␉␉} else␊ |
694 | ␉␉␉␉size = strlen(cp);␊ |
695 | ␉␉␉sign = '\0';␊ |
696 | ␉␉␉break;␊ |
697 | ␉␉case 'U':␊ |
698 | ␉␉␉flags |= LONGINT;␊ |
699 | ␉␉␉/*FALLTHROUGH*/␊ |
700 | ␉␉case 'u':␊ |
701 | ␉␉␉if (flags & QUADINT)␊ |
702 | ␉␉␉␉uqval = GETARG(u_quad_t);␊ |
703 | ␉␉␉else␊ |
704 | ␉␉␉␉ulval = UARG();␊ |
705 | ␉␉␉base = 10;␊ |
706 | ␉␉␉goto nosign;␊ |
707 | ␉␉case 'X':␊ |
708 | ␉␉␉xdigs = "0123456789ABCDEF";␊ |
709 | ␉␉␉goto hex;␊ |
710 | ␉␉case 'x':␊ |
711 | ␉␉␉xdigs = "0123456789abcdef";␊ |
712 | hex:␉␉␉if (flags & QUADINT)␊ |
713 | uqval = GETARG(u_quad_t);␊ |
714 | else␊ |
715 | ulval = UARG();␊ |
716 | ␉␉␉base = 16;␊ |
717 | ␉␉␉/* leading 0x/X only if non-zero */␊ |
718 | ␉␉␉if (flags & ALT &&␊ |
719 | ␉␉␉ (flags & QUADINT ? uqval != 0 : ulval != 0))␊ |
720 | ␉␉␉␉flags |= HEXPREFIX;␊ |
721 | ␊ |
722 | ␉␉␉/* unsigned conversions */␊ |
723 | nosign:␉␉␉sign = '\0';␊ |
724 | ␉␉␉/*␊ |
725 | ␉␉␉ * ``... diouXx conversions ... if a precision is␊ |
726 | ␉␉␉ * specified, the 0 flag will be ignored.''␊ |
727 | ␉␉␉ *␉-- ANSI X3J11␊ |
728 | ␉␉␉ */␊ |
729 | number:␉␉␉if ((dprec = prec) >= 0)␊ |
730 | flags &= ~ZEROPAD;␊ |
731 | ␊ |
732 | ␉␉␉/*␊ |
733 | ␉␉␉ * ``The result of converting a zero value with an␊ |
734 | ␉␉␉ * explicit precision of zero is no characters.''␊ |
735 | ␉␉␉ *␉-- ANSI X3J11␊ |
736 | ␉␉␉ */␊ |
737 | ␉␉␉cp = buf + BUF;␊ |
738 | ␉␉␉if (flags & QUADINT) {␊ |
739 | ␉␉␉␉if (uqval != 0 || prec != 0)␊ |
740 | ␉␉␉␉␉cp = __uqtoa(uqval, cp, base,␊ |
741 | flags & ALT, xdigs);␊ |
742 | ␉␉␉} else {␊ |
743 | ␉␉␉␉if (ulval != 0 || prec != 0)␊ |
744 | ␉␉␉␉␉cp = __ultoa(ulval, cp, base,␊ |
745 | flags & ALT, xdigs);␊ |
746 | ␉␉␉}␊ |
747 | ␉␉␉size = buf + BUF - cp;␊ |
748 | ␉␉␉break;␊ |
749 | ␉␉default:␉/* "%?" prints ?, unless ? is NUL */␊ |
750 | ␉␉␉if (ch == '\0')␊ |
751 | ␉␉␉␉goto done;␊ |
752 | ␉␉␉/* pretend it was %c with argument ch */␊ |
753 | ␉␉␉cp = buf;␊ |
754 | ␉␉␉*cp = ch;␊ |
755 | ␉␉␉size = 1;␊ |
756 | ␉␉␉sign = '\0';␊ |
757 | ␉␉␉break;␊ |
758 | }␊ |
759 | ␊ |
760 | ␉␉/*␊ |
761 | ␉␉ * All reasonable formats wind up here. At this point, `cp'␊ |
762 | ␉␉ * points to a string which (if not flags&LADJUST) should be␊ |
763 | ␉␉ * padded out to `width' places. If flags&ZEROPAD, it should␊ |
764 | ␉␉ * first be prefixed by any sign or other prefix; otherwise,␊ |
765 | ␉␉ * it should be blank padded before the prefix is emitted.␊ |
766 | ␉␉ * After any left-hand padding and prefixing, emit zeroes␊ |
767 | ␉␉ * required by a decimal [diouxX] precision, then print the␊ |
768 | ␉␉ * string proper, then emit zeroes required by any leftover␊ |
769 | ␉␉ * floating precision; finally, if LADJUST, pad with blanks.␊ |
770 | ␉␉ *␊ |
771 | ␉␉ * Compute actual size, so we know how much to pad.␊ |
772 | ␉␉ * size excludes decimal prec; realsz includes it.␊ |
773 | ␉␉ */␊ |
774 | ␉␉realsz = dprec > size ? dprec : size;␊ |
775 | ␉␉if (sign)␊ |
776 | ␉␉␉realsz++;␊ |
777 | ␉␉else if (flags & HEXPREFIX)␊ |
778 | ␉␉␉realsz += 2;␊ |
779 | ␊ |
780 | ␉␉prsize = width > realsz ? width : realsz;␊ |
781 | ␉␉if ((unsigned)ret + prsize > INT_MAX) {␊ |
782 | ␉␉␉ret = EOF;␊ |
783 | ␉␉␉goto error;␊ |
784 | ␉␉}␊ |
785 | ␊ |
786 | ␉␉/* right-adjusting blank padding */␊ |
787 | ␉␉if ((flags & (LADJUST|ZEROPAD)) == 0)␊ |
788 | ␉␉␉PAD(width - realsz, blanks);␊ |
789 | ␊ |
790 | ␉␉/* prefix */␊ |
791 | ␉␉if (sign) {␊ |
792 | ␉␉␉PRINT(&sign, 1);␊ |
793 | ␉␉} else if (flags & HEXPREFIX) {␊ |
794 | ␉␉␉ox[0] = '0';␊ |
795 | ␉␉␉ox[1] = ch;␊ |
796 | ␉␉␉PRINT(ox, 2);␊ |
797 | ␉␉}␊ |
798 | ␊ |
799 | ␉␉/* right-adjusting zero padding */␊ |
800 | ␉␉if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)␊ |
801 | ␉␉␉PAD(width - realsz, zeroes);␊ |
802 | ␊ |
803 | ␉␉/* leading zeroes from decimal precision */␊ |
804 | ␉␉PAD(dprec - size, zeroes);␊ |
805 | ␊ |
806 | ␉␉/* the string or number proper */␊ |
807 | #ifndef NO_FLOATING_POINT␊ |
808 | ␉␉if ((flags & FPT) == 0) {␊ |
809 | ␉␉␉PRINT(cp, size);␊ |
810 | ␉␉} else {␉/* glue together f_p fragments */␊ |
811 | ␉␉␉if (ch >= 'f') {␉/* 'f' or 'g' */␊ |
812 | ␉␉␉␉if (_double == 0) {␊ |
813 | ␉␉␉␉␉/* kludge for __dtoa irregularity */␊ |
814 | ␉␉␉␉␉PRINT("0", 1);␊ |
815 | ␉␉␉␉␉if (expt < ndig || (flags & ALT) != 0) {␊ |
816 | ␉␉␉␉␉␉PRINT(decimal_point, 1);␊ |
817 | ␉␉␉␉␉␉PAD(ndig - 1, zeroes);␊ |
818 | ␉␉␉␉␉}␊ |
819 | ␉␉␉␉} else if (expt <= 0) {␊ |
820 | ␉␉␉␉␉PRINT("0", 1);␊ |
821 | ␉␉␉␉␉PRINT(decimal_point, 1);␊ |
822 | ␉␉␉␉␉PAD(-expt, zeroes);␊ |
823 | ␉␉␉␉␉PRINT(cp, ndig);␊ |
824 | ␉␉␉␉} else if (expt >= ndig) {␊ |
825 | ␉␉␉␉␉PRINT(cp, ndig);␊ |
826 | ␉␉␉␉␉PAD(expt - ndig, zeroes);␊ |
827 | ␉␉␉␉␉if (flags & ALT)␊ |
828 | ␉␉␉␉␉␉PRINT(decimal_point, 1);␊ |
829 | ␉␉␉␉} else {␊ |
830 | ␉␉␉␉␉PRINT(cp, expt);␊ |
831 | ␉␉␉␉␉cp += expt;␊ |
832 | ␉␉␉␉␉PRINT(decimal_point, 1);␊ |
833 | ␉␉␉␉␉PRINT(cp, ndig-expt);␊ |
834 | ␉␉␉␉}␊ |
835 | ␉␉␉} else {␉/* 'e' or 'E' */␊ |
836 | ␉␉␉␉if (ndig > 1 || flags & ALT) {␊ |
837 | ␉␉␉␉␉ox[0] = *cp++;␊ |
838 | ␉␉␉␉␉ox[1] = *decimal_point;␊ |
839 | ␉␉␉␉␉PRINT(ox, 2);␊ |
840 | ␉␉␉␉␉if (_double) {␊ |
841 | ␉␉␉␉␉␉PRINT(cp, ndig-1);␊ |
842 | ␉␉␉␉␉} else␉/* 0.[0..] */␊ |
843 | /* __dtoa irregularity */␊ |
844 | ␉␉␉␉␉␉PAD(ndig - 1, zeroes);␊ |
845 | ␉␉␉␉} else␉/* XeYYY */␊ |
846 | ␉␉␉␉␉PRINT(cp, 1);␊ |
847 | ␉␉␉␉PRINT(expstr, expsize);␊ |
848 | ␉␉␉}␊ |
849 | ␉␉}␊ |
850 | #else␊ |
851 | ␉␉PRINT(cp, size);␊ |
852 | #endif␊ |
853 | ␉␉/* left-adjusting padding (always blank) */␊ |
854 | ␉␉if (flags & LADJUST)␊ |
855 | ␉␉␉PAD(width - realsz, blanks);␊ |
856 | ␊ |
857 | ␉␉/* finally, adjust ret */␊ |
858 | ␉␉ret += prsize;␊ |
859 | ␊ |
860 | ␉␉FLUSH();␉/* copy out the I/O vectors */␊ |
861 | ␉}␊ |
862 | done:␊ |
863 | ␉FLUSH();␊ |
864 | error:␊ |
865 | #ifndef NO_FLOATING_POINT␊ |
866 | ␉if (dtoaresult != NULL)␊ |
867 | ␉␉free(dtoaresult);␊ |
868 | #endif␊ |
869 | ␉if (__sferror(fp))␊ |
870 | ␉␉ret = EOF;␊ |
871 | if ((argtable != NULL) && (argtable != statargtable))␊ |
872 | free (argtable);␊ |
873 | ␉return (ret);␊ |
874 | ␉/* NOTREACHED */␊ |
875 | }␊ |
876 | |