Deleted Added
full compact
vfprintf.c (180102) vfprintf.c (180104)
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

--- 20 unchanged lines hidden (view full) ---

29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
35#endif /* LIBC_SCCS and not lint */
36#include <sys/cdefs.h>
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

--- 20 unchanged lines hidden (view full) ---

29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
35#endif /* LIBC_SCCS and not lint */
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/lib/libc/stdio/vfprintf.c 180102 2008-06-29 21:01:27Z das $");
37__FBSDID("$FreeBSD: head/lib/libc/stdio/vfprintf.c 180104 2008-06-29 21:52:40Z das $");
38
39/*
40 * Actual printf innards.
41 *
42 * This code is large and complicated...
43 */
44
45#include "namespace.h"

--- 11 unchanged lines hidden (view full) ---

57#include <printf.h>
58
59#include <stdarg.h>
60#include "un-namespace.h"
61
62#include "libc_private.h"
63#include "local.h"
64#include "fvwrite.h"
38
39/*
40 * Actual printf innards.
41 *
42 * This code is large and complicated...
43 */
44
45#include "namespace.h"

--- 11 unchanged lines hidden (view full) ---

57#include <printf.h>
58
59#include <stdarg.h>
60#include "un-namespace.h"
61
62#include "libc_private.h"
63#include "local.h"
64#include "fvwrite.h"
65#include "printflocal.h"
65
66
66union arg {
67 int intarg;
68 u_int uintarg;
69 long longarg;
70 u_long ulongarg;
71 long long longlongarg;
72 unsigned long long ulonglongarg;
73 ptrdiff_t ptrdiffarg;
74 size_t sizearg;
75 intmax_t intmaxarg;
76 uintmax_t uintmaxarg;
77 void *pvoidarg;
78 char *pchararg;
79 signed char *pschararg;
80 short *pshortarg;
81 int *pintarg;
82 long *plongarg;
83 long long *plonglongarg;
84 ptrdiff_t *pptrdiffarg;
85 size_t *psizearg;
86 intmax_t *pintmaxarg;
87#ifndef NO_FLOATING_POINT
88 double doublearg;
89 long double longdoublearg;
90#endif
91 wint_t wintarg;
92 wchar_t *pwchararg;
93};
94
95/*
96 * Type ids for argument type table.
97 */
98enum typeid {
99 T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
100 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
101 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
102 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
103 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
104};
105
106#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
107
108/* An expandable array of types. */
109struct typetable {
110 enum typeid *table; /* table of types */
111 enum typeid stattable[STATIC_ARG_TBL_SIZE];
112 int tablesize; /* current size of type table */
113 int tablemax; /* largest used index in table */
114 int nextarg; /* 1-based argument index */
115};
116
117static int __sprint(FILE *, struct __suio *);
118static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
119static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
120 const char *);
121static char *__ultoa(u_long, char *, int, int, const char *, int, char,
122 const char *);
123static char *__wcsconv(wchar_t *, int);
67static int __sprint(FILE *, struct __suio *);
68static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
69static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
70 const char *);
71static char *__ultoa(u_long, char *, int, int, const char *, int, char,
72 const char *);
73static char *__wcsconv(wchar_t *, int);
124static void __find_arguments(const char *, va_list, union arg **);
125static void __grow_type_table(struct typetable *);
126
127/*
128 * Flush out all the vectors defined by the given uio,
129 * then reset it so that it can be reused.
130 */
131static int
132__sprint(FILE *fp, struct __suio *uio)
133{

--- 39 unchanged lines hidden (view full) ---

173 if (ret >= 0 && __fflush(&fake))
174 ret = EOF;
175 if (fake._flags & __SERR)
176 fp->_flags |= __SERR;
177 return (ret);
178}
179
180/*
74
75/*
76 * Flush out all the vectors defined by the given uio,
77 * then reset it so that it can be reused.
78 */
79static int
80__sprint(FILE *fp, struct __suio *uio)
81{

--- 39 unchanged lines hidden (view full) ---

121 if (ret >= 0 && __fflush(&fake))
122 ret = EOF;
123 if (fake._flags & __SERR)
124 fp->_flags |= __SERR;
125 return (ret);
126}
127
128/*
181 * Macros for converting digits to letters and vice versa
182 */
183#define to_digit(c) ((c) - '0')
184#define is_digit(c) ((unsigned)to_digit(c) <= 9)
185#define to_char(n) ((n) + '0')
186
187/*
188 * Convert an unsigned long to ASCII for printf purposes, returning
189 * a pointer to the first character of the string representation.
190 * Octal numbers can be forced to have a leading zero; hex numbers
191 * use the given digits.
192 */
193static char *
194__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
195 int needgrp, char thousep, const char *grp)

--- 237 unchanged lines hidden (view full) ---

433 * conversions, among other things. Technically, we would need the
434 * most space for base 10 conversions with thousands' grouping
435 * characters between each pair of digits. 100 bytes is a
436 * conservative overestimate even for a 128-bit uintmax_t.
437 */
438#define BUF 100
439
440/*
129 * Convert an unsigned long to ASCII for printf purposes, returning
130 * a pointer to the first character of the string representation.
131 * Octal numbers can be forced to have a leading zero; hex numbers
132 * use the given digits.
133 */
134static char *
135__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
136 int needgrp, char thousep, const char *grp)

--- 237 unchanged lines hidden (view full) ---

374 * conversions, among other things. Technically, we would need the
375 * most space for base 10 conversions with thousands' grouping
376 * characters between each pair of digits. 100 bytes is a
377 * conservative overestimate even for a 128-bit uintmax_t.
378 */
379#define BUF 100
380
381/*
441 * Flags used during conversion.
442 */
443#define ALT 0x001 /* alternate form */
444#define LADJUST 0x004 /* left adjustment */
445#define LONGDBL 0x008 /* long double */
446#define LONGINT 0x010 /* long integer */
447#define LLONGINT 0x020 /* long long integer */
448#define SHORTINT 0x040 /* short integer */
449#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
450#define FPT 0x100 /* Floating point number */
451#define GROUPING 0x200 /* use grouping ("'" flag) */
452 /* C99 additional size modifiers: */
453#define SIZET 0x400 /* size_t */
454#define PTRDIFFT 0x800 /* ptrdiff_t */
455#define INTMAXT 0x1000 /* intmax_t */
456#define CHARINT 0x2000 /* print char using int format */
457
458/*
459 * Non-MT-safe version
460 */
461int
462__vfprintf(FILE *fp, const char *fmt0, va_list ap)
463{
464 char *fmt; /* format string */
465 int ch; /* character from fmt */
466 int n, n2; /* handy integer (short term usage) */

--- 792 unchanged lines hidden (view full) ---

1259 if (__sferror(fp))
1260 ret = EOF;
1261 if ((argtable != NULL) && (argtable != statargtable))
1262 free (argtable);
1263 return (ret);
1264 /* NOTREACHED */
1265}
1266
382 * Non-MT-safe version
383 */
384int
385__vfprintf(FILE *fp, const char *fmt0, va_list ap)
386{
387 char *fmt; /* format string */
388 int ch; /* character from fmt */
389 int n, n2; /* handy integer (short term usage) */

--- 792 unchanged lines hidden (view full) ---

1182 if (__sferror(fp))
1183 ret = EOF;
1184 if ((argtable != NULL) && (argtable != statargtable))
1185 free (argtable);
1186 return (ret);
1187 /* NOTREACHED */
1188}
1189
1267/*
1268 * Initialize a struct typetable.
1269 */
1270static inline void
1271inittypes(struct typetable *types)
1272{
1273 int n;
1274
1190
1275 types->table = types->stattable;
1276 types->tablesize = STATIC_ARG_TBL_SIZE;
1277 types->tablemax = 0;
1278 types->nextarg = 1;
1279 for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
1280 types->table[n] = T_UNUSED;
1281}
1282
1283/*
1284 * struct typetable destructor.
1285 */
1286static inline void
1287freetypes(struct typetable *types)
1288{
1289
1290 if (types->table != types->stattable)
1291 free (types->table);
1292}
1293
1294/*
1295 * Add an argument type to the table, expanding if necessary.
1296 */
1297static inline void
1298addtype(struct typetable *types, enum typeid type)
1299{
1300
1301 if (types->nextarg >= types->tablesize)
1302 __grow_type_table(types);
1303 if (types->nextarg > types->tablemax)
1304 types->tablemax = types->nextarg;
1305 types->table[types->nextarg++] = type;
1306}
1307
1308static inline void
1309addsarg(struct typetable *types, int flags)
1310{
1311
1312 if (flags & INTMAXT)
1313 addtype(types, T_INTMAXT);
1314 else if (flags & SIZET)
1315 addtype(types, T_SIZET);
1316 else if (flags & PTRDIFFT)
1317 addtype(types, T_PTRDIFFT);
1318 else if (flags & LLONGINT)
1319 addtype(types, T_LLONG);
1320 else if (flags & LONGINT)
1321 addtype(types, T_LONG);
1322 else
1323 addtype(types, T_INT);
1324}
1325
1326static inline void
1327adduarg(struct typetable *types, int flags)
1328{
1329
1330 if (flags & INTMAXT)
1331 addtype(types, T_UINTMAXT);
1332 else if (flags & SIZET)
1333 addtype(types, T_SIZET);
1334 else if (flags & PTRDIFFT)
1335 addtype(types, T_PTRDIFFT);
1336 else if (flags & LLONGINT)
1337 addtype(types, T_U_LLONG);
1338 else if (flags & LONGINT)
1339 addtype(types, T_U_LONG);
1340 else
1341 addtype(types, T_U_INT);
1342}
1343
1344/*
1345 * Add * arguments to the type array.
1346 */
1347static inline void
1348addaster(struct typetable *types, char **fmtp)
1349{
1350 char *cp;
1351 int n2;
1352
1353 n2 = 0;
1354 cp = *fmtp;
1355 while (is_digit(*cp)) {
1356 n2 = 10 * n2 + to_digit(*cp);
1357 cp++;
1358 }
1359 if (*cp == '$') {
1360 int hold = types->nextarg;
1361 types->nextarg = n2;
1362 addtype(types, T_INT);
1363 types->nextarg = hold;
1364 *fmtp = ++cp;
1365 } else {
1366 addtype(types, T_INT);
1367 }
1368}
1369
1370/*
1371 * Find all arguments when a positional parameter is encountered. Returns a
1372 * table, indexed by argument number, of pointers to each arguments. The
1373 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1374 * It will be replaces with a malloc-ed one if it overflows.
1375 */
1376static void
1377__find_arguments (const char *fmt0, va_list ap, union arg **argtable)
1378{
1379 char *fmt; /* format string */
1380 int ch; /* character from fmt */
1381 int n; /* handy integer (short term usage) */
1382 int flags; /* flags as above */
1383 int width; /* width from format (%8d), or 0 */
1384 struct typetable types; /* table of types */
1385
1386 fmt = (char *)fmt0;
1387 inittypes(&types);
1388
1389 /*
1390 * Scan the format for conversions (`%' character).
1391 */
1392 for (;;) {
1393 while ((ch = *fmt) != '\0' && ch != '%')
1394 fmt++;
1395 if (ch == '\0')
1396 goto done;
1397 fmt++; /* skip over '%' */
1398
1399 flags = 0;
1400 width = 0;
1401
1402rflag: ch = *fmt++;
1403reswitch: switch (ch) {
1404 case ' ':
1405 case '#':
1406 goto rflag;
1407 case '*':
1408 addaster(&types, &fmt);
1409 goto rflag;
1410 case '-':
1411 case '+':
1412 case '\'':
1413 goto rflag;
1414 case '.':
1415 if ((ch = *fmt++) == '*') {
1416 addaster(&types, &fmt);
1417 goto rflag;
1418 }
1419 while (is_digit(ch)) {
1420 ch = *fmt++;
1421 }
1422 goto reswitch;
1423 case '0':
1424 goto rflag;
1425 case '1': case '2': case '3': case '4':
1426 case '5': case '6': case '7': case '8': case '9':
1427 n = 0;
1428 do {
1429 n = 10 * n + to_digit(ch);
1430 ch = *fmt++;
1431 } while (is_digit(ch));
1432 if (ch == '$') {
1433 types.nextarg = n;
1434 goto rflag;
1435 }
1436 width = n;
1437 goto reswitch;
1438#ifndef NO_FLOATING_POINT
1191#ifndef NO_FLOATING_POINT
1439 case 'L':
1440 flags |= LONGDBL;
1441 goto rflag;
1442#endif
1443 case 'h':
1444 if (flags & SHORTINT) {
1445 flags &= ~SHORTINT;
1446 flags |= CHARINT;
1447 } else
1448 flags |= SHORTINT;
1449 goto rflag;
1450 case 'j':
1451 flags |= INTMAXT;
1452 goto rflag;
1453 case 'l':
1454 if (flags & LONGINT) {
1455 flags &= ~LONGINT;
1456 flags |= LLONGINT;
1457 } else
1458 flags |= LONGINT;
1459 goto rflag;
1460 case 'q':
1461 flags |= LLONGINT; /* not necessarily */
1462 goto rflag;
1463 case 't':
1464 flags |= PTRDIFFT;
1465 goto rflag;
1466 case 'z':
1467 flags |= SIZET;
1468 goto rflag;
1469 case 'C':
1470 flags |= LONGINT;
1471 /*FALLTHROUGH*/
1472 case 'c':
1473 if (flags & LONGINT)
1474 addtype(&types, T_WINT);
1475 else
1476 addtype(&types, T_INT);
1477 break;
1478 case 'D':
1479 flags |= LONGINT;
1480 /*FALLTHROUGH*/
1481 case 'd':
1482 case 'i':
1483 addsarg(&types, flags);
1484 break;
1485#ifndef NO_FLOATING_POINT
1486 case 'a':
1487 case 'A':
1488 case 'e':
1489 case 'E':
1490 case 'f':
1491 case 'g':
1492 case 'G':
1493 if (flags & LONGDBL)
1494 addtype(&types, T_LONG_DOUBLE);
1495 else
1496 addtype(&types, T_DOUBLE);
1497 break;
1498#endif /* !NO_FLOATING_POINT */
1499 case 'n':
1500 if (flags & INTMAXT)
1501 addtype(&types, TP_INTMAXT);
1502 else if (flags & PTRDIFFT)
1503 addtype(&types, TP_PTRDIFFT);
1504 else if (flags & SIZET)
1505 addtype(&types, TP_SIZET);
1506 else if (flags & LLONGINT)
1507 addtype(&types, TP_LLONG);
1508 else if (flags & LONGINT)
1509 addtype(&types, TP_LONG);
1510 else if (flags & SHORTINT)
1511 addtype(&types, TP_SHORT);
1512 else if (flags & CHARINT)
1513 addtype(&types, TP_SCHAR);
1514 else
1515 addtype(&types, TP_INT);
1516 continue; /* no output */
1517 case 'O':
1518 flags |= LONGINT;
1519 /*FALLTHROUGH*/
1520 case 'o':
1521 adduarg(&types, flags);
1522 break;
1523 case 'p':
1524 addtype(&types, TP_VOID);
1525 break;
1526 case 'S':
1527 flags |= LONGINT;
1528 /*FALLTHROUGH*/
1529 case 's':
1530 if (flags & LONGINT)
1531 addtype(&types, TP_WCHAR);
1532 else
1533 addtype(&types, TP_CHAR);
1534 break;
1535 case 'U':
1536 flags |= LONGINT;
1537 /*FALLTHROUGH*/
1538 case 'u':
1539 case 'X':
1540 case 'x':
1541 adduarg(&types, flags);
1542 break;
1543 default: /* "%?" prints ?, unless ? is NUL */
1544 if (ch == '\0')
1545 goto done;
1546 break;
1547 }
1548 }
1549done:
1550 /*
1551 * Build the argument table.
1552 */
1553 if (types.tablemax >= STATIC_ARG_TBL_SIZE) {
1554 *argtable = (union arg *)
1555 malloc (sizeof (union arg) * (types.tablemax + 1));
1556 }
1557
1192
1558 (*argtable) [0].intarg = 0;
1559 for (n = 1; n <= types.tablemax; n++) {
1560 switch (types.table[n]) {
1561 case T_UNUSED: /* whoops! */
1562 (*argtable) [n].intarg = va_arg (ap, int);
1563 break;
1564 case TP_SCHAR:
1565 (*argtable) [n].pschararg = va_arg (ap, signed char *);
1566 break;
1567 case TP_SHORT:
1568 (*argtable) [n].pshortarg = va_arg (ap, short *);
1569 break;
1570 case T_INT:
1571 (*argtable) [n].intarg = va_arg (ap, int);
1572 break;
1573 case T_U_INT:
1574 (*argtable) [n].uintarg = va_arg (ap, unsigned int);
1575 break;
1576 case TP_INT:
1577 (*argtable) [n].pintarg = va_arg (ap, int *);
1578 break;
1579 case T_LONG:
1580 (*argtable) [n].longarg = va_arg (ap, long);
1581 break;
1582 case T_U_LONG:
1583 (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
1584 break;
1585 case TP_LONG:
1586 (*argtable) [n].plongarg = va_arg (ap, long *);
1587 break;
1588 case T_LLONG:
1589 (*argtable) [n].longlongarg = va_arg (ap, long long);
1590 break;
1591 case T_U_LLONG:
1592 (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
1593 break;
1594 case TP_LLONG:
1595 (*argtable) [n].plonglongarg = va_arg (ap, long long *);
1596 break;
1597 case T_PTRDIFFT:
1598 (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
1599 break;
1600 case TP_PTRDIFFT:
1601 (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
1602 break;
1603 case T_SIZET:
1604 (*argtable) [n].sizearg = va_arg (ap, size_t);
1605 break;
1606 case TP_SIZET:
1607 (*argtable) [n].psizearg = va_arg (ap, size_t *);
1608 break;
1609 case T_INTMAXT:
1610 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
1611 break;
1612 case T_UINTMAXT:
1613 (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
1614 break;
1615 case TP_INTMAXT:
1616 (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
1617 break;
1618 case T_DOUBLE:
1619#ifndef NO_FLOATING_POINT
1620 (*argtable) [n].doublearg = va_arg (ap, double);
1621#endif
1622 break;
1623 case T_LONG_DOUBLE:
1624#ifndef NO_FLOATING_POINT
1625 (*argtable) [n].longdoublearg = va_arg (ap, long double);
1626#endif
1627 break;
1628 case TP_CHAR:
1629 (*argtable) [n].pchararg = va_arg (ap, char *);
1630 break;
1631 case TP_VOID:
1632 (*argtable) [n].pvoidarg = va_arg (ap, void *);
1633 break;
1634 case T_WINT:
1635 (*argtable) [n].wintarg = va_arg (ap, wint_t);
1636 break;
1637 case TP_WCHAR:
1638 (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
1639 break;
1640 }
1641 }
1642
1643 freetypes(&types);
1644}
1645
1646/*
1647 * Increase the size of the type table.
1648 */
1649static void
1650__grow_type_table(struct typetable *types)
1651{
1652 enum typeid *const oldtable = types->table;
1653 const int oldsize = types->tablesize;
1654 enum typeid *newtable;
1655 int n, newsize = oldsize * 2;
1656
1657 if (newsize < types->nextarg + 1)
1658 newsize = types->nextarg + 1;
1659 if (oldsize == STATIC_ARG_TBL_SIZE) {
1660 if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
1661 abort(); /* XXX handle better */
1662 bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
1663 } else {
1664 newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
1665 if (newtable == NULL)
1666 abort(); /* XXX handle better */
1667 }
1668 for (n = oldsize; n < newsize; n++)
1669 newtable[n] = T_UNUSED;
1670
1671 types->table = newtable;
1672 types->tablesize = newsize;
1673}
1674
1675
1676#ifndef NO_FLOATING_POINT
1677
1678static int
1679exponent(char *p0, int exp, int fmtch)
1680{
1681 char *p, *t;
1682 char expbuf[MAXEXPDIG];
1683
1684 p = p0;
1685 *p++ = fmtch;

--- 28 unchanged lines hidden ---
1193static int
1194exponent(char *p0, int exp, int fmtch)
1195{
1196 char *p, *t;
1197 char expbuf[MAXEXPDIG];
1198
1199 p = p0;
1200 *p++ = fmtch;

--- 28 unchanged lines hidden ---