mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Begin de-spaghettifying the code that handles positional arguments.
In particular, encapsulate the state of the type table in a struct, and add inline functions to initialize, free, and manipulate that state. This replaces some ugly macros that made proper error handling impossible. While here, remove an unneeded test for NULL and a variable that is initialized (many times!) but never used. The compiler didn't catch these because of rampant use of the same variable to mean different things in different places. This commit should not cause any changes in functionality.
This commit is contained in:
parent
ce3cb38836
commit
e5abb5e698
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=180102
@ -103,6 +103,17 @@ enum typeid {
|
||||
T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
|
||||
};
|
||||
|
||||
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
|
||||
|
||||
/* An expandable array of types. */
|
||||
struct typetable {
|
||||
enum typeid *table; /* table of types */
|
||||
enum typeid stattable[STATIC_ARG_TBL_SIZE];
|
||||
int tablesize; /* current size of type table */
|
||||
int tablemax; /* largest used index in table */
|
||||
int nextarg; /* 1-based argument index */
|
||||
};
|
||||
|
||||
static int __sprint(FILE *, struct __suio *);
|
||||
static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
|
||||
static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
|
||||
@ -111,7 +122,7 @@ static char *__ultoa(u_long, char *, int, int, const char *, int, char,
|
||||
const char *);
|
||||
static char *__wcsconv(wchar_t *, int);
|
||||
static void __find_arguments(const char *, va_list, union arg **);
|
||||
static void __grow_type_table(int, enum typeid **, int *);
|
||||
static void __grow_type_table(struct typetable *);
|
||||
|
||||
/*
|
||||
* Flush out all the vectors defined by the given uio,
|
||||
@ -426,8 +437,6 @@ static int exponent(char *, int, int);
|
||||
*/
|
||||
#define BUF 100
|
||||
|
||||
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
|
||||
|
||||
/*
|
||||
* Flags used during conversion.
|
||||
*/
|
||||
@ -1255,6 +1264,109 @@ number: if ((dprec = prec) >= 0)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a struct typetable.
|
||||
*/
|
||||
static inline void
|
||||
inittypes(struct typetable *types)
|
||||
{
|
||||
int n;
|
||||
|
||||
types->table = types->stattable;
|
||||
types->tablesize = STATIC_ARG_TBL_SIZE;
|
||||
types->tablemax = 0;
|
||||
types->nextarg = 1;
|
||||
for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
|
||||
types->table[n] = T_UNUSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct typetable destructor.
|
||||
*/
|
||||
static inline void
|
||||
freetypes(struct typetable *types)
|
||||
{
|
||||
|
||||
if (types->table != types->stattable)
|
||||
free (types->table);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an argument type to the table, expanding if necessary.
|
||||
*/
|
||||
static inline void
|
||||
addtype(struct typetable *types, enum typeid type)
|
||||
{
|
||||
|
||||
if (types->nextarg >= types->tablesize)
|
||||
__grow_type_table(types);
|
||||
if (types->nextarg > types->tablemax)
|
||||
types->tablemax = types->nextarg;
|
||||
types->table[types->nextarg++] = type;
|
||||
}
|
||||
|
||||
static inline void
|
||||
addsarg(struct typetable *types, int flags)
|
||||
{
|
||||
|
||||
if (flags & INTMAXT)
|
||||
addtype(types, T_INTMAXT);
|
||||
else if (flags & SIZET)
|
||||
addtype(types, T_SIZET);
|
||||
else if (flags & PTRDIFFT)
|
||||
addtype(types, T_PTRDIFFT);
|
||||
else if (flags & LLONGINT)
|
||||
addtype(types, T_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
addtype(types, T_LONG);
|
||||
else
|
||||
addtype(types, T_INT);
|
||||
}
|
||||
|
||||
static inline void
|
||||
adduarg(struct typetable *types, int flags)
|
||||
{
|
||||
|
||||
if (flags & INTMAXT)
|
||||
addtype(types, T_UINTMAXT);
|
||||
else if (flags & SIZET)
|
||||
addtype(types, T_SIZET);
|
||||
else if (flags & PTRDIFFT)
|
||||
addtype(types, T_PTRDIFFT);
|
||||
else if (flags & LLONGINT)
|
||||
addtype(types, T_U_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
addtype(types, T_U_LONG);
|
||||
else
|
||||
addtype(types, T_U_INT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add * arguments to the type array.
|
||||
*/
|
||||
static inline void
|
||||
addaster(struct typetable *types, char **fmtp)
|
||||
{
|
||||
char *cp;
|
||||
int n2;
|
||||
|
||||
n2 = 0;
|
||||
cp = *fmtp;
|
||||
while (is_digit(*cp)) {
|
||||
n2 = 10 * n2 + to_digit(*cp);
|
||||
cp++;
|
||||
}
|
||||
if (*cp == '$') {
|
||||
int hold = types->nextarg;
|
||||
types->nextarg = n2;
|
||||
addtype(types, T_INT);
|
||||
types->nextarg = hold;
|
||||
*fmtp = ++cp;
|
||||
} else {
|
||||
addtype(types, T_INT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find all arguments when a positional parameter is encountered. Returns a
|
||||
* table, indexed by argument number, of pointers to each arguments. The
|
||||
@ -1266,72 +1378,20 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
|
||||
{
|
||||
char *fmt; /* format string */
|
||||
int ch; /* character from fmt */
|
||||
int n, n2; /* handy integer (short term usage) */
|
||||
char *cp; /* handy char pointer (short term usage) */
|
||||
int n; /* handy integer (short term usage) */
|
||||
int flags; /* flags as above */
|
||||
int width; /* width from format (%8d), or 0 */
|
||||
enum typeid *typetable; /* table of types */
|
||||
enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
|
||||
int tablesize; /* current size of type table */
|
||||
int tablemax; /* largest used index in table */
|
||||
int nextarg; /* 1-based argument index */
|
||||
struct typetable types; /* table of types */
|
||||
|
||||
/*
|
||||
* Add an argument type to the table, expanding if necessary.
|
||||
*/
|
||||
#define ADDTYPE(type) \
|
||||
((nextarg >= tablesize) ? \
|
||||
__grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \
|
||||
(nextarg > tablemax) ? tablemax = nextarg : 0, \
|
||||
typetable[nextarg++] = type)
|
||||
|
||||
#define ADDSARG() \
|
||||
((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
|
||||
((flags&SIZET) ? ADDTYPE(T_SIZET) : \
|
||||
((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
|
||||
((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
|
||||
((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
|
||||
|
||||
#define ADDUARG() \
|
||||
((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
|
||||
((flags&SIZET) ? ADDTYPE(T_SIZET) : \
|
||||
((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
|
||||
((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
|
||||
((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
|
||||
|
||||
/*
|
||||
* Add * arguments to the type array.
|
||||
*/
|
||||
#define ADDASTER() \
|
||||
n2 = 0; \
|
||||
cp = fmt; \
|
||||
while (is_digit(*cp)) { \
|
||||
n2 = 10 * n2 + to_digit(*cp); \
|
||||
cp++; \
|
||||
} \
|
||||
if (*cp == '$') { \
|
||||
int hold = nextarg; \
|
||||
nextarg = n2; \
|
||||
ADDTYPE (T_INT); \
|
||||
nextarg = hold; \
|
||||
fmt = ++cp; \
|
||||
} else { \
|
||||
ADDTYPE (T_INT); \
|
||||
}
|
||||
fmt = (char *)fmt0;
|
||||
typetable = stattypetable;
|
||||
tablesize = STATIC_ARG_TBL_SIZE;
|
||||
tablemax = 0;
|
||||
nextarg = 1;
|
||||
for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
|
||||
typetable[n] = T_UNUSED;
|
||||
inittypes(&types);
|
||||
|
||||
/*
|
||||
* Scan the format for conversions (`%' character).
|
||||
*/
|
||||
for (;;) {
|
||||
for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
|
||||
/* void */;
|
||||
while ((ch = *fmt) != '\0' && ch != '%')
|
||||
fmt++;
|
||||
if (ch == '\0')
|
||||
goto done;
|
||||
fmt++; /* skip over '%' */
|
||||
@ -1345,7 +1405,7 @@ reswitch: switch (ch) {
|
||||
case '#':
|
||||
goto rflag;
|
||||
case '*':
|
||||
ADDASTER ();
|
||||
addaster(&types, &fmt);
|
||||
goto rflag;
|
||||
case '-':
|
||||
case '+':
|
||||
@ -1353,7 +1413,7 @@ reswitch: switch (ch) {
|
||||
goto rflag;
|
||||
case '.':
|
||||
if ((ch = *fmt++) == '*') {
|
||||
ADDASTER ();
|
||||
addaster(&types, &fmt);
|
||||
goto rflag;
|
||||
}
|
||||
while (is_digit(ch)) {
|
||||
@ -1370,7 +1430,7 @@ reswitch: switch (ch) {
|
||||
ch = *fmt++;
|
||||
} while (is_digit(ch));
|
||||
if (ch == '$') {
|
||||
nextarg = n;
|
||||
types.nextarg = n;
|
||||
goto rflag;
|
||||
}
|
||||
width = n;
|
||||
@ -1411,16 +1471,16 @@ reswitch: switch (ch) {
|
||||
/*FALLTHROUGH*/
|
||||
case 'c':
|
||||
if (flags & LONGINT)
|
||||
ADDTYPE(T_WINT);
|
||||
addtype(&types, T_WINT);
|
||||
else
|
||||
ADDTYPE(T_INT);
|
||||
addtype(&types, T_INT);
|
||||
break;
|
||||
case 'D':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'd':
|
||||
case 'i':
|
||||
ADDSARG();
|
||||
addsarg(&types, flags);
|
||||
break;
|
||||
#ifndef NO_FLOATING_POINT
|
||||
case 'a':
|
||||
@ -1431,46 +1491,46 @@ reswitch: switch (ch) {
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (flags & LONGDBL)
|
||||
ADDTYPE(T_LONG_DOUBLE);
|
||||
addtype(&types, T_LONG_DOUBLE);
|
||||
else
|
||||
ADDTYPE(T_DOUBLE);
|
||||
addtype(&types, T_DOUBLE);
|
||||
break;
|
||||
#endif /* !NO_FLOATING_POINT */
|
||||
case 'n':
|
||||
if (flags & INTMAXT)
|
||||
ADDTYPE(TP_INTMAXT);
|
||||
addtype(&types, TP_INTMAXT);
|
||||
else if (flags & PTRDIFFT)
|
||||
ADDTYPE(TP_PTRDIFFT);
|
||||
addtype(&types, TP_PTRDIFFT);
|
||||
else if (flags & SIZET)
|
||||
ADDTYPE(TP_SIZET);
|
||||
addtype(&types, TP_SIZET);
|
||||
else if (flags & LLONGINT)
|
||||
ADDTYPE(TP_LLONG);
|
||||
addtype(&types, TP_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
ADDTYPE(TP_LONG);
|
||||
addtype(&types, TP_LONG);
|
||||
else if (flags & SHORTINT)
|
||||
ADDTYPE(TP_SHORT);
|
||||
addtype(&types, TP_SHORT);
|
||||
else if (flags & CHARINT)
|
||||
ADDTYPE(TP_SCHAR);
|
||||
addtype(&types, TP_SCHAR);
|
||||
else
|
||||
ADDTYPE(TP_INT);
|
||||
addtype(&types, TP_INT);
|
||||
continue; /* no output */
|
||||
case 'O':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'o':
|
||||
ADDUARG();
|
||||
adduarg(&types, flags);
|
||||
break;
|
||||
case 'p':
|
||||
ADDTYPE(TP_VOID);
|
||||
addtype(&types, TP_VOID);
|
||||
break;
|
||||
case 'S':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 's':
|
||||
if (flags & LONGINT)
|
||||
ADDTYPE(TP_WCHAR);
|
||||
addtype(&types, TP_WCHAR);
|
||||
else
|
||||
ADDTYPE(TP_CHAR);
|
||||
addtype(&types, TP_CHAR);
|
||||
break;
|
||||
case 'U':
|
||||
flags |= LONGINT;
|
||||
@ -1478,7 +1538,7 @@ reswitch: switch (ch) {
|
||||
case 'u':
|
||||
case 'X':
|
||||
case 'x':
|
||||
ADDUARG();
|
||||
adduarg(&types, flags);
|
||||
break;
|
||||
default: /* "%?" prints ?, unless ? is NUL */
|
||||
if (ch == '\0')
|
||||
@ -1490,14 +1550,14 @@ reswitch: switch (ch) {
|
||||
/*
|
||||
* Build the argument table.
|
||||
*/
|
||||
if (tablemax >= STATIC_ARG_TBL_SIZE) {
|
||||
if (types.tablemax >= STATIC_ARG_TBL_SIZE) {
|
||||
*argtable = (union arg *)
|
||||
malloc (sizeof (union arg) * (tablemax + 1));
|
||||
malloc (sizeof (union arg) * (types.tablemax + 1));
|
||||
}
|
||||
|
||||
(*argtable) [0].intarg = 0;
|
||||
for (n = 1; n <= tablemax; n++) {
|
||||
switch (typetable [n]) {
|
||||
for (n = 1; n <= types.tablemax; n++) {
|
||||
switch (types.table[n]) {
|
||||
case T_UNUSED: /* whoops! */
|
||||
(*argtable) [n].intarg = va_arg (ap, int);
|
||||
break;
|
||||
@ -1580,23 +1640,22 @@ reswitch: switch (ch) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((typetable != NULL) && (typetable != stattypetable))
|
||||
free (typetable);
|
||||
freetypes(&types);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase the size of the type table.
|
||||
*/
|
||||
static void
|
||||
__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
|
||||
__grow_type_table(struct typetable *types)
|
||||
{
|
||||
enum typeid *const oldtable = *typetable;
|
||||
const int oldsize = *tablesize;
|
||||
enum typeid *const oldtable = types->table;
|
||||
const int oldsize = types->tablesize;
|
||||
enum typeid *newtable;
|
||||
int n, newsize = oldsize * 2;
|
||||
|
||||
if (newsize < nextarg + 1)
|
||||
newsize = nextarg + 1;
|
||||
if (newsize < types->nextarg + 1)
|
||||
newsize = types->nextarg + 1;
|
||||
if (oldsize == STATIC_ARG_TBL_SIZE) {
|
||||
if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
|
||||
abort(); /* XXX handle better */
|
||||
@ -1609,8 +1668,8 @@ __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
|
||||
for (n = oldsize; n < newsize; n++)
|
||||
newtable[n] = T_UNUSED;
|
||||
|
||||
*typetable = newtable;
|
||||
*tablesize = newsize;
|
||||
types->table = newtable;
|
||||
types->tablesize = newsize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,6 +105,17 @@ enum typeid {
|
||||
T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
|
||||
};
|
||||
|
||||
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
|
||||
|
||||
/* An expandable array of types. */
|
||||
struct typetable {
|
||||
enum typeid *table; /* table of types */
|
||||
enum typeid stattable[STATIC_ARG_TBL_SIZE];
|
||||
int tablesize; /* current size of type table */
|
||||
int tablemax; /* largest used index in table */
|
||||
int nextarg; /* 1-based argument index */
|
||||
};
|
||||
|
||||
static int __sbprintf(FILE *, const wchar_t *, va_list);
|
||||
static wint_t __xfputwc(wchar_t, FILE *);
|
||||
static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
|
||||
@ -113,7 +124,7 @@ static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int,
|
||||
char, const char *);
|
||||
static wchar_t *__mbsconv(char *, int);
|
||||
static void __find_arguments(const wchar_t *, va_list, union arg **);
|
||||
static void __grow_type_table(int, enum typeid **, int *);
|
||||
static void __grow_type_table(struct typetable *);
|
||||
|
||||
/*
|
||||
* Helper function for `fprintf to unbuffered unix file': creates a
|
||||
@ -452,8 +463,6 @@ static int exponent(wchar_t *, int, wchar_t);
|
||||
*/
|
||||
#define BUF 100
|
||||
|
||||
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
|
||||
|
||||
/*
|
||||
* Flags used during conversion.
|
||||
*/
|
||||
@ -1247,6 +1256,109 @@ number: if ((dprec = prec) >= 0)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a struct typetable.
|
||||
*/
|
||||
static inline void
|
||||
inittypes(struct typetable *types)
|
||||
{
|
||||
int n;
|
||||
|
||||
types->table = types->stattable;
|
||||
types->tablesize = STATIC_ARG_TBL_SIZE;
|
||||
types->tablemax = 0;
|
||||
types->nextarg = 1;
|
||||
for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
|
||||
types->table[n] = T_UNUSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct typetable destructor.
|
||||
*/
|
||||
static inline void
|
||||
freetypes(struct typetable *types)
|
||||
{
|
||||
|
||||
if (types->table != types->stattable)
|
||||
free(types->table);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an argument type to the table, expanding if necessary.
|
||||
*/
|
||||
static inline void
|
||||
addtype(struct typetable *types, enum typeid type)
|
||||
{
|
||||
|
||||
if (types->nextarg >= types->tablesize)
|
||||
__grow_type_table(types);
|
||||
if (types->nextarg > types->tablemax)
|
||||
types->tablemax = types->nextarg;
|
||||
types->table[types->nextarg++] = type;
|
||||
}
|
||||
|
||||
static inline void
|
||||
addsarg(struct typetable *types, int flags)
|
||||
{
|
||||
|
||||
if (flags & INTMAXT)
|
||||
addtype(types, T_INTMAXT);
|
||||
else if (flags & SIZET)
|
||||
addtype(types, T_SIZET);
|
||||
else if (flags & PTRDIFFT)
|
||||
addtype(types, T_PTRDIFFT);
|
||||
else if (flags & LLONGINT)
|
||||
addtype(types, T_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
addtype(types, T_LONG);
|
||||
else
|
||||
addtype(types, T_INT);
|
||||
}
|
||||
|
||||
static inline void
|
||||
adduarg(struct typetable *types, int flags)
|
||||
{
|
||||
|
||||
if (flags & INTMAXT)
|
||||
addtype(types, T_UINTMAXT);
|
||||
else if (flags & SIZET)
|
||||
addtype(types, T_SIZET);
|
||||
else if (flags & PTRDIFFT)
|
||||
addtype(types, T_PTRDIFFT);
|
||||
else if (flags & LLONGINT)
|
||||
addtype(types, T_U_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
addtype(types, T_U_LONG);
|
||||
else
|
||||
addtype(types, T_U_INT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add * arguments to the type array.
|
||||
*/
|
||||
static inline void
|
||||
addaster(struct typetable *types, wchar_t **fmtp)
|
||||
{
|
||||
wchar_t *cp;
|
||||
int n2;
|
||||
|
||||
n2 = 0;
|
||||
cp = *fmtp;
|
||||
while (is_digit(*cp)) {
|
||||
n2 = 10 * n2 + to_digit(*cp);
|
||||
cp++;
|
||||
}
|
||||
if (*cp == '$') {
|
||||
int hold = types->nextarg;
|
||||
types->nextarg = n2;
|
||||
addtype(types, T_INT);
|
||||
types->nextarg = hold;
|
||||
*fmtp = ++cp;
|
||||
} else {
|
||||
addtype(types, T_INT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find all arguments when a positional parameter is encountered. Returns a
|
||||
* table, indexed by argument number, of pointers to each arguments. The
|
||||
@ -1258,72 +1370,20 @@ __find_arguments (const wchar_t *fmt0, va_list ap, union arg **argtable)
|
||||
{
|
||||
wchar_t *fmt; /* format string */
|
||||
wchar_t ch; /* character from fmt */
|
||||
int n, n2; /* handy integer (short term usage) */
|
||||
wchar_t *cp; /* handy char pointer (short term usage) */
|
||||
int n; /* handy integer (short term usage) */
|
||||
int flags; /* flags as above */
|
||||
int width; /* width from format (%8d), or 0 */
|
||||
enum typeid *typetable; /* table of types */
|
||||
enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
|
||||
int tablesize; /* current size of type table */
|
||||
int tablemax; /* largest used index in table */
|
||||
int nextarg; /* 1-based argument index */
|
||||
struct typetable types; /* table of types */
|
||||
|
||||
/*
|
||||
* Add an argument type to the table, expanding if necessary.
|
||||
*/
|
||||
#define ADDTYPE(type) \
|
||||
((nextarg >= tablesize) ? \
|
||||
__grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \
|
||||
(nextarg > tablemax) ? tablemax = nextarg : 0, \
|
||||
typetable[nextarg++] = type)
|
||||
|
||||
#define ADDSARG() \
|
||||
((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
|
||||
((flags&SIZET) ? ADDTYPE(T_SIZET) : \
|
||||
((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
|
||||
((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
|
||||
((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
|
||||
|
||||
#define ADDUARG() \
|
||||
((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
|
||||
((flags&SIZET) ? ADDTYPE(T_SIZET) : \
|
||||
((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
|
||||
((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
|
||||
((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
|
||||
|
||||
/*
|
||||
* Add * arguments to the type array.
|
||||
*/
|
||||
#define ADDASTER() \
|
||||
n2 = 0; \
|
||||
cp = fmt; \
|
||||
while (is_digit(*cp)) { \
|
||||
n2 = 10 * n2 + to_digit(*cp); \
|
||||
cp++; \
|
||||
} \
|
||||
if (*cp == '$') { \
|
||||
int hold = nextarg; \
|
||||
nextarg = n2; \
|
||||
ADDTYPE (T_INT); \
|
||||
nextarg = hold; \
|
||||
fmt = ++cp; \
|
||||
} else { \
|
||||
ADDTYPE (T_INT); \
|
||||
}
|
||||
fmt = (wchar_t *)fmt0;
|
||||
typetable = stattypetable;
|
||||
tablesize = STATIC_ARG_TBL_SIZE;
|
||||
tablemax = 0;
|
||||
nextarg = 1;
|
||||
for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
|
||||
typetable[n] = T_UNUSED;
|
||||
inittypes(&types);
|
||||
|
||||
/*
|
||||
* Scan the format for conversions (`%' character).
|
||||
*/
|
||||
for (;;) {
|
||||
for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
|
||||
/* void */;
|
||||
while ((ch = *fmt) != '\0' && ch != '%')
|
||||
fmt++;
|
||||
if (ch == '\0')
|
||||
goto done;
|
||||
fmt++; /* skip over '%' */
|
||||
@ -1337,7 +1397,7 @@ reswitch: switch (ch) {
|
||||
case '#':
|
||||
goto rflag;
|
||||
case '*':
|
||||
ADDASTER ();
|
||||
addaster(&types, &fmt);
|
||||
goto rflag;
|
||||
case '-':
|
||||
case '+':
|
||||
@ -1345,7 +1405,7 @@ reswitch: switch (ch) {
|
||||
goto rflag;
|
||||
case '.':
|
||||
if ((ch = *fmt++) == '*') {
|
||||
ADDASTER ();
|
||||
addaster(&types, &fmt);
|
||||
goto rflag;
|
||||
}
|
||||
while (is_digit(ch)) {
|
||||
@ -1362,7 +1422,7 @@ reswitch: switch (ch) {
|
||||
ch = *fmt++;
|
||||
} while (is_digit(ch));
|
||||
if (ch == '$') {
|
||||
nextarg = n;
|
||||
types.nextarg = n;
|
||||
goto rflag;
|
||||
}
|
||||
width = n;
|
||||
@ -1403,16 +1463,16 @@ reswitch: switch (ch) {
|
||||
/*FALLTHROUGH*/
|
||||
case 'c':
|
||||
if (flags & LONGINT)
|
||||
ADDTYPE(T_WINT);
|
||||
addtype(&types, T_WINT);
|
||||
else
|
||||
ADDTYPE(T_INT);
|
||||
addtype(&types, T_INT);
|
||||
break;
|
||||
case 'D':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'd':
|
||||
case 'i':
|
||||
ADDSARG();
|
||||
addsarg(&types, flags);
|
||||
break;
|
||||
#ifndef NO_FLOATING_POINT
|
||||
case 'a':
|
||||
@ -1423,46 +1483,46 @@ reswitch: switch (ch) {
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (flags & LONGDBL)
|
||||
ADDTYPE(T_LONG_DOUBLE);
|
||||
addtype(&types, T_LONG_DOUBLE);
|
||||
else
|
||||
ADDTYPE(T_DOUBLE);
|
||||
addtype(&types, T_DOUBLE);
|
||||
break;
|
||||
#endif /* !NO_FLOATING_POINT */
|
||||
case 'n':
|
||||
if (flags & INTMAXT)
|
||||
ADDTYPE(TP_INTMAXT);
|
||||
addtype(&types, TP_INTMAXT);
|
||||
else if (flags & PTRDIFFT)
|
||||
ADDTYPE(TP_PTRDIFFT);
|
||||
addtype(&types, TP_PTRDIFFT);
|
||||
else if (flags & SIZET)
|
||||
ADDTYPE(TP_SIZET);
|
||||
addtype(&types, TP_SIZET);
|
||||
else if (flags & LLONGINT)
|
||||
ADDTYPE(TP_LLONG);
|
||||
addtype(&types, TP_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
ADDTYPE(TP_LONG);
|
||||
addtype(&types, TP_LONG);
|
||||
else if (flags & SHORTINT)
|
||||
ADDTYPE(TP_SHORT);
|
||||
addtype(&types, TP_SHORT);
|
||||
else if (flags & CHARINT)
|
||||
ADDTYPE(TP_SCHAR);
|
||||
addtype(&types, TP_SCHAR);
|
||||
else
|
||||
ADDTYPE(TP_INT);
|
||||
addtype(&types, TP_INT);
|
||||
continue; /* no output */
|
||||
case 'O':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'o':
|
||||
ADDUARG();
|
||||
adduarg(&types, flags);
|
||||
break;
|
||||
case 'p':
|
||||
ADDTYPE(TP_VOID);
|
||||
addtype(&types, TP_VOID);
|
||||
break;
|
||||
case 'S':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 's':
|
||||
if (flags & LONGINT)
|
||||
ADDTYPE(TP_WCHAR);
|
||||
addtype(&types, TP_WCHAR);
|
||||
else
|
||||
ADDTYPE(TP_CHAR);
|
||||
addtype(&types, TP_CHAR);
|
||||
break;
|
||||
case 'U':
|
||||
flags |= LONGINT;
|
||||
@ -1470,7 +1530,7 @@ reswitch: switch (ch) {
|
||||
case 'u':
|
||||
case 'X':
|
||||
case 'x':
|
||||
ADDUARG();
|
||||
adduarg(&types, flags);
|
||||
break;
|
||||
default: /* "%?" prints ?, unless ? is NUL */
|
||||
if (ch == '\0')
|
||||
@ -1482,14 +1542,14 @@ reswitch: switch (ch) {
|
||||
/*
|
||||
* Build the argument table.
|
||||
*/
|
||||
if (tablemax >= STATIC_ARG_TBL_SIZE) {
|
||||
if (types.tablemax >= STATIC_ARG_TBL_SIZE) {
|
||||
*argtable = (union arg *)
|
||||
malloc (sizeof (union arg) * (tablemax + 1));
|
||||
malloc (sizeof (union arg) * (types.tablemax + 1));
|
||||
}
|
||||
|
||||
(*argtable) [0].intarg = 0;
|
||||
for (n = 1; n <= tablemax; n++) {
|
||||
switch (typetable [n]) {
|
||||
for (n = 1; n <= types.tablemax; n++) {
|
||||
switch (types.table[n]) {
|
||||
case T_UNUSED: /* whoops! */
|
||||
(*argtable) [n].intarg = va_arg (ap, int);
|
||||
break;
|
||||
@ -1572,23 +1632,22 @@ reswitch: switch (ch) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((typetable != NULL) && (typetable != stattypetable))
|
||||
free (typetable);
|
||||
freetypes(&types);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase the size of the type table.
|
||||
*/
|
||||
static void
|
||||
__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
|
||||
__grow_type_table(struct typetable *types)
|
||||
{
|
||||
enum typeid *const oldtable = *typetable;
|
||||
const int oldsize = *tablesize;
|
||||
enum typeid *const oldtable = types->table;
|
||||
const int oldsize = types->tablesize;
|
||||
enum typeid *newtable;
|
||||
int n, newsize = oldsize * 2;
|
||||
|
||||
if (newsize < nextarg + 1)
|
||||
newsize = nextarg + 1;
|
||||
if (newsize < types->nextarg + 1)
|
||||
newsize = types->nextarg + 1;
|
||||
if (oldsize == STATIC_ARG_TBL_SIZE) {
|
||||
if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
|
||||
abort(); /* XXX handle better */
|
||||
@ -1601,8 +1660,8 @@ __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
|
||||
for (n = oldsize; n < newsize; n++)
|
||||
newtable[n] = T_UNUSED;
|
||||
|
||||
*typetable = newtable;
|
||||
*tablesize = newsize;
|
||||
types->table = newtable;
|
||||
types->tablesize = newsize;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user