fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (c) 1990
0f2dc02ed2763dadc70bec1db8dd407e16db8e49ek * The Regents of the University of California. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This code is derived from software contributed to Berkeley by
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Chris Torek.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * By using this file, you agree to the terms and conditions set
fa9e4066f08beec538e775443c5be79dd423fcabahrens * forth in the LICENSE file which can be found at the top level of
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the sendmail distribution.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrensSM_IDSTR(id, "@(#)$Id: vfprintf.c,v 1.54 2005/05/16 03:52:00 ca Exp $")
60030f278c9b10a64cb18b6443f7e8d97d6e45e4Mark Shellenbaum** Actual printing innards.
fa9e4066f08beec538e775443c5be79dd423fcabahrens** This code is large and complicated...
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int sm_bprintf __P((SM_FILE_T *, const char *, va_list));
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void sm_find_arguments __P((const char *, va_list , va_list **));
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void sm_grow_type_table_x __P((unsigned char **, int *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int sm_print __P((SM_FILE_T *, int, struct sm_uio *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens** SM_PRINT -- print/flush to the file
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Flush out all the vectors defined by the given uio,
fa9e4066f08beec538e775443c5be79dd423fcabahrens** then reset it so that it can be reused.
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Parameters:
fa9e4066f08beec538e775443c5be79dd423fcabahrens** fp -- file pointer
fa9e4066f08beec538e775443c5be79dd423fcabahrens** timeout -- time to complete operation (milliseconds)
fa9e4066f08beec538e775443c5be79dd423fcabahrens** uio -- vector list of memory locations of data for printing
f18faf3f3e5def85fdfff681617d227703ace2adek** Results:
f18faf3f3e5def85fdfff681617d227703ace2adek** Success: 0 (zero)
f18faf3f3e5def85fdfff681617d227703ace2adek** Failure:
6d1e0b89f3e34478a022854df6b0cfab82ccce66marks** SM_BPRINTF -- allow formating to an unbuffered file.
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** Helper function for `fprintf to unbuffered unix file': creates a
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** temporary buffer (via a "fake" file pointer).
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** We only work on write-only files; this avoids
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** worries about ungetc buffers and so forth.
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** Parameters:
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** fp -- the file to send the o/p to
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** fmt -- format instructions for the o/p
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** ap -- vectors of data units used for formating
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** Results:
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck** Failure: SM_IO_EOF and errno set
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Success: number of data units used in the formating
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Side effects:
fa9e4066f08beec538e775443c5be79dd423fcabahrens** formatted o/p can be SM_IO_BUFSIZ length maximum
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *fmt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens extern const char SmFileMagic[];
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* copy the important variables */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* set up the buffer */
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck fake.f_lbfsize = 0; /* not actually used, but Just In Case */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* do the work, then copy any error status */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright/* Macros for converting digits to letters and vice versa */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* Flags used during conversion. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
fa9e4066f08beec538e775443c5be79dd423fcabahrens** SM_IO_VPRINTF -- performs actual formating for o/p
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Parameters:
fa9e4066f08beec538e775443c5be79dd423fcabahrens** fp -- file pointer for o/p
fa9e4066f08beec538e775443c5be79dd423fcabahrens** timeout -- time to complete the print
fa9e4066f08beec538e775443c5be79dd423fcabahrens** fmt0 -- formating directives
fa9e4066f08beec538e775443c5be79dd423fcabahrens** ap -- vectors with data units for formating
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Success: number of data units used for formatting
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Failure: SM_IO_EOF and sets errno
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright const char *fmt0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register int n, m, n2; /* handy integers (short term usage) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens register char *cp; /* handy char pointer (short term usage) */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright register struct sm_iov *iovp;/* for PRINT macro */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright char sign; /* sign prefix (' ', '+', '-', or \0) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ULONGLONG_T _uquad; /* integer arguments %[diouxX] */
fa9e4066f08beec538e775443c5be79dd423fcabahrens enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
fa9e4066f08beec538e775443c5be79dd423fcabahrens int dprec; /* a copy of prec if [diouxX], 0 otherwise */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright char *xdigs="0123456789abcdef"; /* digits for [xX] conversion */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright struct sm_uio uio; /* output information: summary */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright struct sm_iov iov[NIOV];/* ... and individual io vectors */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright va_list *argtable; /* args, built due to positional arg */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** Choose PADSIZE to trade efficiency vs. size. If larger printf
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** fields occur frequently, increase PADSIZE and make the initialisers
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** below longer.
fa9e4066f08beec538e775443c5be79dd423fcabahrens {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
fa9e4066f08beec538e775443c5be79dd423fcabahrens {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** BEWARE, these `goto error' on error, and PAD uses `n'.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((n = (howmany)) > 0) \
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (n > PADSIZE) { \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** To extend shorts properly, we need both signed and unsigned
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** argument extraction methods.
fa9e4066f08beec538e775443c5be79dd423fcabahrens (long) GETARG(int))
fa9e4066f08beec538e775443c5be79dd423fcabahrens flags&SHORTINT ? (unsigned long) (unsigned short) GETARG(int) : \
fa9e4066f08beec538e775443c5be79dd423fcabahrens (unsigned long) GETARG(unsigned int))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** Get * arguments, including the form *nn$. Preserve the nextarg
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ** that the argument can be gotten once the type is determined.
60030f278c9b10a64cb18b6443f7e8d97d6e45e4Mark Shellenbaum** Get the argument indexed by nextarg. If the argument table is
60030f278c9b10a64cb18b6443f7e8d97d6e45e4Mark Shellenbaum** built, use it to get the argument. If its not, get the next
60030f278c9b10a64cb18b6443f7e8d97d6e45e4Mark Shellenbaum** argument (and arguments must be gotten sequentially).
fa9e4066f08beec538e775443c5be79dd423fcabahrens (((argtable != NULL) ? (void) (ap = argtable[nextarg]) : (void) 0), \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else /* SM_VA_STD */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((argtable != NULL) ? (*((type*)(argtable[nextarg++]))) : \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* SM_VA_STD */
a32fded1a905061abae92da5bcbab429cb6146f1ek /* sorry, fprintf(read_only_file, "") returns SM_IO_EOF, not 0 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* optimise fprintf(stderr) (and other unbuffered Unix files) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((fp->f_flags & (SMNBF|SMWR|SMRW)) == (SMNBF|SMWR) &&
a32fded1a905061abae92da5bcbab429cb6146f1ek /* Scan the format for conversions (`%' character). */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (n <= 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** ``If the space and + flags both appear, the space
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** flag will be ignored.''
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright ** -- ANSI X3J11
9e1320c015cea6985d2122bc1d654b79fa479f7aMark Shellenbaum ** ``A negative field width argument is taken as a
9e1320c015cea6985d2122bc1d654b79fa479f7aMark Shellenbaum ** - flag followed by a positive field width.''
9e1320c015cea6985d2122bc1d654b79fa479f7aMark Shellenbaum ** -- ANSI X3J11
9e1320c015cea6985d2122bc1d654b79fa479f7aMark Shellenbaum ** They don't exclude field widths read from args.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /* FALLTHROUGH */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** ``Note that 0 is taken as a flag, not as the
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** beginning of a field width.''
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** -- ANSI X3J11
aa59c4cb15a6ac5d4e585dadf7a055b580abf579rsb /*FALLTHROUGH*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** This code implements floating point output
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** in the most portable manner possible,
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck ** relying only on 'sprintf' as defined by
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck ** the 1989 ANSI C standard.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** We silently cap width and precision
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck ** at 120, to avoid buffer overflow.
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '%';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '#';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '-';
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee *p++ = '0';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '*';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '.';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p++ = '*';
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck *p = '\0';
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else /* HASSNPRINTF */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* HASSNPRINTF */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else /* HASSNPRINTF */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* HASSNPRINTF */
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue; /* no output */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*FALLTHROUGH*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** ``The argument shall be a pointer to void. The
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** value of the pointer is converted to a sequence
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** of printable characters, in an implementation-
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** defined manner.''
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** -- ANSI X3J11
0b69c2f001a429251e2d38f25aca860396551214ahrens /* NOSTRICT */
fa9e4066f08beec538e775443c5be79dd423fcabahrens unsigned long l;
fa9e4066f08beec538e775443c5be79dd423fcabahrens unsigned i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw u.p = GETARG(void *);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (sizeof(void *) == sizeof(ULONGLONG_T))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else if (sizeof(void *) == sizeof(long))
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** can't use strlen; can only look for the
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** NUL in the first `prec' characters, and
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** strlen() will go further.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*FALLTHROUGH*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* leading 0x/X only if non-zero */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* unsigned conversions */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** ``... diouXx conversions ... if a precision is
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** specified, the 0 flag will be ignored.''
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** -- ANSI X3J11
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck ** ``The result of converting a zero value with an
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** explicit precision of zero is no characters.''
fa9e4066f08beec538e775443c5be79dd423fcabahrens ** -- ANSI X3J11
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** Unsigned mod is hard, and unsigned mod
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** by a constant is easier than that by
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh ** a variable; hence this switch.
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh /* handle octal leading 0 */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks /* many numbers are 1 digit */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks default: /* "%?" prints ?, unless ? is NUL */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks /* pretend it was %c with argument ch */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** All reasonable formats wind up here. At this point, `cp'
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** points to a string which (if not flags&LADJUST) should be
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** padded out to `width' places. If flags&ZEROPAD, it should
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** first be prefixed by any sign or other prefix; otherwise,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** it should be blank padded before the prefix is emitted.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** After any left-hand padding and prefixing, emit zeroes
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** required by a decimal [diouxX] precision, then print the
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** string proper, then emit zeroes required by any leftover
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** floating precision; finally, if LADJUST, pad with blanks.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** Compute actual size, so we know how much to pad.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ** size excludes decimal prec; realsz includes it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* right-adjusting blank padding */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* prefix */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* right-adjusting zero padding */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* leading zeroes from decimal precision */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* the string or number proper */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* left-adjusting padding (always blank) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* finally, adjust ret */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((argtable != NULL) && (argtable != statargtable))
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* NOTREACHED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* Type ids for argument type table. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens** SM_FIND_ARGUMENTS -- find all args when a positional parameter is found.
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Find all arguments when a positional parameter is encountered. Returns a
fa9e4066f08beec538e775443c5be79dd423fcabahrens** table, indexed by argument number, of pointers to each arguments. The
fa9e4066f08beec538e775443c5be79dd423fcabahrens** initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee** It will be replaced with a malloc-ed one if it overflows.
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee** Parameters:
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee** fmt0 -- formating directives
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee** ap -- vector list of data unit for formating consumption
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee** argtable -- an indexable table (returned) of 'ap'
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bckstatic void
8bf40bf00a7564d0ccb4a33906734188cb2d1e9bck const char *fmt0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register int n, n2; /* handy integer (short term usage) */
bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77dbmaybee register char *cp; /* handy char pointer (short term usage) */
5422900b426b0077b9c2720a47bf829be8225830maybee /* Add an argument type to the table, expanding if necessary. */
2283022c7c1b8c8d3595e7fcb96a4e4bacc6141amarks (sm_grow_type_table_x(&typetable, &tablesize), 0) : 0, \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((flags & SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((flags & SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Add * arguments to the type array. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
95c9592adb96db1ca55dd488cb18abe5e5c261f4maybee /* Scan the format for conversions (`%' character). */
f18faf3f3e5def85fdfff681617d227703ace2adek /* void */;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright case '5': case '6': case '7': case '8': case '9':
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*FALLTHROUGH*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue; /* no output */
b38f097029665f4ece801ca129913d36f757b49cck /*FALLTHROUGH*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*FALLTHROUGH*/
9e1320c015cea6985d2122bc1d654b79fa479f7aMark Shellenbaum default: /* "%?" prints ?, unless ? is NUL */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /* Build the argument table. */
f18faf3f3e5def85fdfff681617d227703ace2adek switch (typetable [n])
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if ((typetable != NULL) && (typetable != stattypetable))
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright** SM_GROW_TYPE_TABLE -- Increase the size of the type table.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright** Parameters:
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright** tabletype -- type of table to grow
fa9e4066f08beec538e775443c5be79dd423fcabahrens** tablesize -- requested new table size
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw** Results:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw** Raises an exception if can't allocate memory.
fa9e4066f08beec538e775443c5be79dd423fcabahrens unsigned char **typetable;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *typetable = (unsigned char *) sm_malloc_x(sizeof(unsigned char)
bb963f1cfd0c29d3203584c421c00a566367047cmaybee *typetable = (unsigned char *) sm_realloc_x(typetable,
bb963f1cfd0c29d3203584c421c00a566367047cmaybee sizeof(unsigned char) * newsize);