1
0
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:
David Schultz 2008-06-29 21:01:27 +00:00
parent ce3cb38836
commit e5abb5e698
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=180102
2 changed files with 306 additions and 188 deletions

View File

@ -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;
}

View File

@ -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;
}