Deleted Added
sdiff udiff text old ( 178287 ) new ( 180102 )
full compact
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 178287 2008-04-17 22:17:54Z jhb $");
38
39/*
40 * Actual printf innards.
41 *
42 * This code is large and complicated...
43 */
44
45#include "namespace.h"

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

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
106static int __sprint(FILE *, struct __suio *);
107static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
108static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
109 const char *);
110static char *__ultoa(u_long, char *, int, int, const char *, int, char,
111 const char *);
112static char *__wcsconv(wchar_t *, int);
113static void __find_arguments(const char *, va_list, union arg **);
114static void __grow_type_table(int, enum typeid **, int *);
115
116/*
117 * Flush out all the vectors defined by the given uio,
118 * then reset it so that it can be reused.
119 */
120static int
121__sprint(FILE *fp, struct __suio *uio)
122{

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

421 * The size of the buffer we use as scratch space for integer
422 * conversions, among other things. Technically, we would need the
423 * most space for base 10 conversions with thousands' grouping
424 * characters between each pair of digits. 100 bytes is a
425 * conservative overestimate even for a 128-bit uintmax_t.
426 */
427#define BUF 100
428
429#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
430
431/*
432 * Flags used during conversion.
433 */
434#define ALT 0x001 /* alternate form */
435#define LADJUST 0x004 /* left adjustment */
436#define LONGDBL 0x008 /* long double */
437#define LONGINT 0x010 /* long integer */
438#define LLONGINT 0x020 /* long long integer */

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

1251 ret = EOF;
1252 if ((argtable != NULL) && (argtable != statargtable))
1253 free (argtable);
1254 return (ret);
1255 /* NOTREACHED */
1256}
1257
1258/*
1259 * Find all arguments when a positional parameter is encountered. Returns a
1260 * table, indexed by argument number, of pointers to each arguments. The
1261 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1262 * It will be replaces with a malloc-ed one if it overflows.
1263 */
1264static void
1265__find_arguments (const char *fmt0, va_list ap, union arg **argtable)
1266{
1267 char *fmt; /* format string */
1268 int ch; /* character from fmt */
1269 int n, n2; /* handy integer (short term usage) */
1270 char *cp; /* handy char pointer (short term usage) */
1271 int flags; /* flags as above */
1272 int width; /* width from format (%8d), or 0 */
1273 enum typeid *typetable; /* table of types */
1274 enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
1275 int tablesize; /* current size of type table */
1276 int tablemax; /* largest used index in table */
1277 int nextarg; /* 1-based argument index */
1278
1279 /*
1280 * Add an argument type to the table, expanding if necessary.
1281 */
1282#define ADDTYPE(type) \
1283 ((nextarg >= tablesize) ? \
1284 __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \
1285 (nextarg > tablemax) ? tablemax = nextarg : 0, \
1286 typetable[nextarg++] = type)
1287
1288#define ADDSARG() \
1289 ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
1290 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1291 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1292 ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
1293 ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
1294
1295#define ADDUARG() \
1296 ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
1297 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1298 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1299 ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
1300 ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
1301
1302 /*
1303 * Add * arguments to the type array.
1304 */
1305#define ADDASTER() \
1306 n2 = 0; \
1307 cp = fmt; \
1308 while (is_digit(*cp)) { \
1309 n2 = 10 * n2 + to_digit(*cp); \
1310 cp++; \
1311 } \
1312 if (*cp == '$') { \
1313 int hold = nextarg; \
1314 nextarg = n2; \
1315 ADDTYPE (T_INT); \
1316 nextarg = hold; \
1317 fmt = ++cp; \
1318 } else { \
1319 ADDTYPE (T_INT); \
1320 }
1321 fmt = (char *)fmt0;
1322 typetable = stattypetable;
1323 tablesize = STATIC_ARG_TBL_SIZE;
1324 tablemax = 0;
1325 nextarg = 1;
1326 for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
1327 typetable[n] = T_UNUSED;
1328
1329 /*
1330 * Scan the format for conversions (`%' character).
1331 */
1332 for (;;) {
1333 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
1334 /* void */;
1335 if (ch == '\0')
1336 goto done;
1337 fmt++; /* skip over '%' */
1338
1339 flags = 0;
1340 width = 0;
1341
1342rflag: ch = *fmt++;
1343reswitch: switch (ch) {
1344 case ' ':
1345 case '#':
1346 goto rflag;
1347 case '*':
1348 ADDASTER ();
1349 goto rflag;
1350 case '-':
1351 case '+':
1352 case '\'':
1353 goto rflag;
1354 case '.':
1355 if ((ch = *fmt++) == '*') {
1356 ADDASTER ();
1357 goto rflag;
1358 }
1359 while (is_digit(ch)) {
1360 ch = *fmt++;
1361 }
1362 goto reswitch;
1363 case '0':
1364 goto rflag;
1365 case '1': case '2': case '3': case '4':
1366 case '5': case '6': case '7': case '8': case '9':
1367 n = 0;
1368 do {
1369 n = 10 * n + to_digit(ch);
1370 ch = *fmt++;
1371 } while (is_digit(ch));
1372 if (ch == '$') {
1373 nextarg = n;
1374 goto rflag;
1375 }
1376 width = n;
1377 goto reswitch;
1378#ifndef NO_FLOATING_POINT
1379 case 'L':
1380 flags |= LONGDBL;
1381 goto rflag;

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

1406 case 'z':
1407 flags |= SIZET;
1408 goto rflag;
1409 case 'C':
1410 flags |= LONGINT;
1411 /*FALLTHROUGH*/
1412 case 'c':
1413 if (flags & LONGINT)
1414 ADDTYPE(T_WINT);
1415 else
1416 ADDTYPE(T_INT);
1417 break;
1418 case 'D':
1419 flags |= LONGINT;
1420 /*FALLTHROUGH*/
1421 case 'd':
1422 case 'i':
1423 ADDSARG();
1424 break;
1425#ifndef NO_FLOATING_POINT
1426 case 'a':
1427 case 'A':
1428 case 'e':
1429 case 'E':
1430 case 'f':
1431 case 'g':
1432 case 'G':
1433 if (flags & LONGDBL)
1434 ADDTYPE(T_LONG_DOUBLE);
1435 else
1436 ADDTYPE(T_DOUBLE);
1437 break;
1438#endif /* !NO_FLOATING_POINT */
1439 case 'n':
1440 if (flags & INTMAXT)
1441 ADDTYPE(TP_INTMAXT);
1442 else if (flags & PTRDIFFT)
1443 ADDTYPE(TP_PTRDIFFT);
1444 else if (flags & SIZET)
1445 ADDTYPE(TP_SIZET);
1446 else if (flags & LLONGINT)
1447 ADDTYPE(TP_LLONG);
1448 else if (flags & LONGINT)
1449 ADDTYPE(TP_LONG);
1450 else if (flags & SHORTINT)
1451 ADDTYPE(TP_SHORT);
1452 else if (flags & CHARINT)
1453 ADDTYPE(TP_SCHAR);
1454 else
1455 ADDTYPE(TP_INT);
1456 continue; /* no output */
1457 case 'O':
1458 flags |= LONGINT;
1459 /*FALLTHROUGH*/
1460 case 'o':
1461 ADDUARG();
1462 break;
1463 case 'p':
1464 ADDTYPE(TP_VOID);
1465 break;
1466 case 'S':
1467 flags |= LONGINT;
1468 /*FALLTHROUGH*/
1469 case 's':
1470 if (flags & LONGINT)
1471 ADDTYPE(TP_WCHAR);
1472 else
1473 ADDTYPE(TP_CHAR);
1474 break;
1475 case 'U':
1476 flags |= LONGINT;
1477 /*FALLTHROUGH*/
1478 case 'u':
1479 case 'X':
1480 case 'x':
1481 ADDUARG();
1482 break;
1483 default: /* "%?" prints ?, unless ? is NUL */
1484 if (ch == '\0')
1485 goto done;
1486 break;
1487 }
1488 }
1489done:
1490 /*
1491 * Build the argument table.
1492 */
1493 if (tablemax >= STATIC_ARG_TBL_SIZE) {
1494 *argtable = (union arg *)
1495 malloc (sizeof (union arg) * (tablemax + 1));
1496 }
1497
1498 (*argtable) [0].intarg = 0;
1499 for (n = 1; n <= tablemax; n++) {
1500 switch (typetable [n]) {
1501 case T_UNUSED: /* whoops! */
1502 (*argtable) [n].intarg = va_arg (ap, int);
1503 break;
1504 case TP_SCHAR:
1505 (*argtable) [n].pschararg = va_arg (ap, signed char *);
1506 break;
1507 case TP_SHORT:
1508 (*argtable) [n].pshortarg = va_arg (ap, short *);

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

1575 (*argtable) [n].wintarg = va_arg (ap, wint_t);
1576 break;
1577 case TP_WCHAR:
1578 (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
1579 break;
1580 }
1581 }
1582
1583 if ((typetable != NULL) && (typetable != stattypetable))
1584 free (typetable);
1585}
1586
1587/*
1588 * Increase the size of the type table.
1589 */
1590static void
1591__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
1592{
1593 enum typeid *const oldtable = *typetable;
1594 const int oldsize = *tablesize;
1595 enum typeid *newtable;
1596 int n, newsize = oldsize * 2;
1597
1598 if (newsize < nextarg + 1)
1599 newsize = nextarg + 1;
1600 if (oldsize == STATIC_ARG_TBL_SIZE) {
1601 if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
1602 abort(); /* XXX handle better */
1603 bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
1604 } else {
1605 newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
1606 if (newtable == NULL)
1607 abort(); /* XXX handle better */
1608 }
1609 for (n = oldsize; n < newsize; n++)
1610 newtable[n] = T_UNUSED;
1611
1612 *typetable = newtable;
1613 *tablesize = newsize;
1614}
1615
1616
1617#ifndef NO_FLOATING_POINT
1618
1619static int
1620exponent(char *p0, int exp, int fmtch)
1621{

--- 33 unchanged lines hidden ---