Implement several of the c99 updates to printf(3):
- New length modifiers: hh, j, t, z. - New flag: '. Note that %'f is not yet implemented. - Use "inf"/"nan" for efg formats, "INF"/"NAN" for EFG formats. - Implemented %q in terms of %ll; if "quad_t" is not "long long" %q will break. Still to do: - %C, %S, %lc, %ls (wide character support) - %'f (thousands in integer portion of %f) - %a/%A (exact hex representation of floating-point numbers) Garrett Wollman wrote the first version of the vfprintf.c update; Mike Barcroft wrote the first version of the printf.3 changes.
This commit is contained in:
parent
58cbb07307
commit
7735bb0f64
@ -36,7 +36,7 @@
|
||||
.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dd November 8, 2001
|
||||
.Dt PRINTF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -191,12 +191,9 @@ If unaccessed arguments in the format string are interspersed with ones that
|
||||
are accessed the results will be indeterminate.
|
||||
.It
|
||||
Zero or more of the following flags:
|
||||
.Bl -hyphen
|
||||
.It
|
||||
A
|
||||
.Cm #
|
||||
character
|
||||
specifying that the value should be converted to an
|
||||
.Bl -tag -width ".So \&\ \& Sc (space)" -compact -offset indent
|
||||
.It Sq Cm #
|
||||
The value should be converted to an
|
||||
.Dq alternate form .
|
||||
For
|
||||
.Cm c , d , i , n , p , s ,
|
||||
@ -220,7 +217,7 @@ for
|
||||
.Cm X
|
||||
conversions) prepended to it.
|
||||
For
|
||||
.Cm e , E , f , g ,
|
||||
.Cm a , A , e , E , f , F , g ,
|
||||
and
|
||||
.Cm G
|
||||
conversions, the result will always contain a decimal point, even if no
|
||||
@ -232,11 +229,8 @@ and
|
||||
.Cm G
|
||||
conversions, trailing zeros are not removed from the result as they
|
||||
would otherwise be.
|
||||
.It
|
||||
A
|
||||
.Cm 0
|
||||
(zero)
|
||||
character specifying zero padding.
|
||||
.It So Cm 0 Sc (zero)
|
||||
Zero padding.
|
||||
For all conversions except
|
||||
.Cm n ,
|
||||
the converted value is padded on the left with zeros rather than blanks.
|
||||
@ -247,10 +241,9 @@ and
|
||||
the
|
||||
.Cm 0
|
||||
flag is ignored.
|
||||
.It
|
||||
A negative field width flag
|
||||
.Cm \-
|
||||
indicates the converted value is to be left adjusted on the field boundary.
|
||||
.It Sq Cm \&\-
|
||||
A negative field width flag;
|
||||
the converted value is to be left adjusted on the field boundary.
|
||||
Except for
|
||||
.Cm n
|
||||
conversions, the converted value is padded on the right with blanks,
|
||||
@ -260,20 +253,30 @@ A
|
||||
overrides a
|
||||
.Cm 0
|
||||
if both are given.
|
||||
.It
|
||||
A space, specifying that a blank should be left before a positive number
|
||||
.It So \&\ \& Sc (space)
|
||||
A blank should be left before a positive number
|
||||
produced by a signed conversion
|
||||
.Cm ( d , e , E , f , g , G ,
|
||||
.Cm ( a , A , d , e , E , f , F , g , G ,
|
||||
or
|
||||
.Cm i ) .
|
||||
.It
|
||||
A
|
||||
.Cm +
|
||||
character specifying that a sign always be placed before a
|
||||
.It Sq Cm +
|
||||
A sign must always be placed before a
|
||||
number produced by a signed conversion.
|
||||
A
|
||||
.Cm +
|
||||
overrides a space if both are used.
|
||||
.It Sq Cm '
|
||||
Decimal conversions
|
||||
.Cm ( d , u ,
|
||||
or
|
||||
.Cm i )
|
||||
or the integral portion of a floating point conversion
|
||||
.Cm ( f
|
||||
or
|
||||
.Cm F )
|
||||
should be grouped and separated by thousands using
|
||||
the non-monetary seperator returned by
|
||||
.Xr localeconv 3 .
|
||||
.El
|
||||
.It
|
||||
An optional decimal digit string specifying a minimum field width.
|
||||
@ -292,9 +295,9 @@ This gives the minimum number of digits to appear for
|
||||
and
|
||||
.Cm X
|
||||
conversions, the number of digits to appear after the decimal-point for
|
||||
.Cm e , E ,
|
||||
.Cm a , A , e , E , f ,
|
||||
and
|
||||
.Cm f
|
||||
.Cm F
|
||||
conversions, the maximum number of significant digits for
|
||||
.Cm g
|
||||
and
|
||||
@ -304,79 +307,69 @@ string for
|
||||
.Cm s
|
||||
conversions.
|
||||
.It
|
||||
The optional character
|
||||
.Cm h ,
|
||||
specifying that a following
|
||||
.Cm d , i , o , u , x ,
|
||||
An optional length modifier, that specifies the size of the argument.
|
||||
The following length modifiers are valid for the
|
||||
.Cm d , i , n , o , u , x ,
|
||||
or
|
||||
.Cm X
|
||||
conversion corresponds to a
|
||||
.Vt short int
|
||||
or
|
||||
.Vt unsigned short int
|
||||
argument, or that a following
|
||||
.Cm n
|
||||
conversion corresponds to a pointer to a
|
||||
.Vt short int
|
||||
argument.
|
||||
.It
|
||||
The optional character
|
||||
.Cm l
|
||||
(ell) specifying that a following
|
||||
.Cm d , i , o , u , x ,
|
||||
conversion:
|
||||
.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt unsigned long long *"
|
||||
.It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n
|
||||
.It Cm hh Ta Vt signed char Ta Vt unsigned char Ta Vt signed char *
|
||||
.It Cm h Ta Vt short Ta Vt unsigned short Ta Vt short *
|
||||
.It Cm l No (ell) Ta Vt long Ta Vt unsigned long Ta Vt long *
|
||||
.It Cm ll No (ell ell) Ta Vt long long Ta Vt unsigned long long Ta Vt long long *
|
||||
.It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt intmax_t *
|
||||
.It Cm t Ta Vt ptrdiff_t Ta Sy * Ta Vt ptrdiff_t *
|
||||
.It Cm z Ta Sy * Ta Vt size_t Ta Sy *
|
||||
.It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt quad_t *
|
||||
.El
|
||||
.Pp
|
||||
.Bl -tag -width ".Cm * No -"
|
||||
.It Cm * No -
|
||||
The
|
||||
.Cm t
|
||||
modifier, when applied to a
|
||||
.Cm o , u , x ,
|
||||
or
|
||||
.Cm X
|
||||
conversion applies to a pointer to a
|
||||
.Vt long int
|
||||
or
|
||||
.Vt unsigned long int
|
||||
argument, or that a following
|
||||
conversion, indicates that the argument is of an unsigned type
|
||||
equivalent in size to a
|
||||
.Vt ptrdiff_t .
|
||||
The
|
||||
.Cm z
|
||||
modifier, when applied to a
|
||||
.Cm d or
|
||||
.Cm i
|
||||
conversion, indicates that the argument is of a signed type equivalent in
|
||||
size to a
|
||||
.Vt size_t .
|
||||
Similarly, when applied to an
|
||||
.Cm n
|
||||
conversion corresponds to a pointer to a
|
||||
.Vt long int
|
||||
argument.
|
||||
.It
|
||||
The optional characters
|
||||
.Cm ll
|
||||
(ell ell) specifying that a following
|
||||
.Cm d , i , o , u , x ,
|
||||
or
|
||||
.Cm X
|
||||
conversion applies to a pointer to a
|
||||
.Vt long long int
|
||||
or
|
||||
.Vt unsigned long long int
|
||||
argument, or that a following
|
||||
.Cm n
|
||||
conversion corresponds to a pointer to a
|
||||
.Vt long long int
|
||||
argument.
|
||||
.It
|
||||
The optional character
|
||||
.Cm q ,
|
||||
specifying that a following
|
||||
.Cm d , i , o , u , x ,
|
||||
or
|
||||
.Cm X
|
||||
conversion corresponds to a
|
||||
.Vt quad int
|
||||
or
|
||||
.Vt unsigned quad int
|
||||
argument, or that a following
|
||||
.Cm n
|
||||
conversion corresponds to a pointer to a
|
||||
.Vt quad int
|
||||
argument.
|
||||
.It
|
||||
The character
|
||||
.Cm L
|
||||
specifying that a following
|
||||
.Cm e , E , f , g ,
|
||||
conversion, it indicates that the argument is a pointer to a signed type
|
||||
equivalent in size to a
|
||||
.Vt size_t .
|
||||
.El
|
||||
.Pp
|
||||
The following length modifier is valid for the
|
||||
.Cm a , A , e , E , f , F , g ,
|
||||
or
|
||||
.Cm G
|
||||
conversion corresponds to a
|
||||
.Vt long double
|
||||
argument.
|
||||
conversion:
|
||||
.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G"
|
||||
.It Sy Modifier Ta Cm a , A , e , E , f , F , g , G
|
||||
.It Cm L Ta Vt long double
|
||||
.El
|
||||
.Pp
|
||||
The following length modifier is valid for the
|
||||
.Cm c
|
||||
or
|
||||
.Cm s
|
||||
conversion:
|
||||
.Bl -column ".Sy Modifier" ".Vt wint_t" ".Vt wchar_t *"
|
||||
.It Sy Modifier Ta Cm c Ta Cm s
|
||||
.It Cm l No (ell) Ta Vt wint_t Ta Vt wchar_t *
|
||||
.El
|
||||
.It
|
||||
A character that specifies the type of conversion to be applied.
|
||||
.El
|
||||
@ -457,7 +450,26 @@ conversion uses the letter
|
||||
to introduce the exponent.
|
||||
The exponent always contains at least two digits; if the value is zero,
|
||||
the exponent is 00.
|
||||
.It Cm f
|
||||
.Pp
|
||||
For
|
||||
.Cm a , A , e , E , f , F , g ,
|
||||
and
|
||||
.Cm G
|
||||
conversions, positive and negative infinity are represented as
|
||||
.Li inf
|
||||
and
|
||||
.Li -inf
|
||||
respectively when using the lowercase conversion character, and
|
||||
.Li INF
|
||||
and
|
||||
.Li -INF
|
||||
respectively when using the uppercase conversion character.
|
||||
Similarly, NaN is represented as
|
||||
.Li nan
|
||||
when using the lowercase conversion, and
|
||||
.Li NAN
|
||||
when using the uppercase conversion.
|
||||
.It Cm fF
|
||||
The
|
||||
.Vt double
|
||||
argument is rounded and converted to decimal notation in the style
|
||||
@ -475,6 +487,8 @@ argument is converted in style
|
||||
or
|
||||
.Cm e
|
||||
(or
|
||||
.Cm F
|
||||
or
|
||||
.Cm E
|
||||
for
|
||||
.Cm G
|
||||
@ -488,12 +502,74 @@ is used if the exponent from its conversion is less than -4 or greater than
|
||||
or equal to the precision.
|
||||
Trailing zeros are removed from the fractional part of the result; a
|
||||
decimal point appears only if it is followed by at least one digit.
|
||||
.It Cm aA
|
||||
The
|
||||
.Vt double
|
||||
argument is converted to hexadecimal notation in the style
|
||||
.Oo \- Oc Ns 0xh Ns Cm \&. Ns hhhp Ns Oo +- Oc Ns d ,
|
||||
where the number of digits after the hexadecimal-point character
|
||||
is equal to the precision specification.
|
||||
If the precision is missing, it is taken as enough to exactly
|
||||
represent the floating-point number; if the precision is
|
||||
explicitly zero, no hexadecimal-point character appears.
|
||||
This is an exact coversion of the mantissa+exponent internal
|
||||
floating point representation; the
|
||||
.Oo \- Oc Ns 0xh Ns Cm \&. Ns hhh
|
||||
portion represents exactly the mantissa; only denormalized
|
||||
mantissas have a zero value to the left of the hexadecimal
|
||||
point.
|
||||
The
|
||||
.Cm p
|
||||
is a literal character
|
||||
.Qq p ;
|
||||
the exponent is preceded by a positive or negative sign
|
||||
and is represented in decimal, using only enough characters
|
||||
to represent the exponent.
|
||||
The
|
||||
.Cm A
|
||||
conversion uses the prefix
|
||||
.Cm 0X
|
||||
(rather than
|
||||
.Cm 0x ) ,
|
||||
the letters
|
||||
.Cm ABCDEF
|
||||
(rather than
|
||||
.Cm abcdef )
|
||||
to represent the hex digits, and the letter
|
||||
.Cm P
|
||||
(rather than
|
||||
.Cm p )
|
||||
to seperate the mantissa and exponent.
|
||||
|
||||
.It Cm C
|
||||
Treated as
|
||||
.Cm c
|
||||
with the
|
||||
.Cm l
|
||||
(ell) modifier.
|
||||
.It Cm c
|
||||
The
|
||||
.Vt int
|
||||
argument is converted to an
|
||||
.Vt unsigned char ,
|
||||
and the resulting character is written.
|
||||
.Pp
|
||||
If the
|
||||
.Cm l
|
||||
(ell) modifier is used, the
|
||||
.Vt wint_t
|
||||
argument shall be converted to a
|
||||
.Vt wchar_t ,
|
||||
and the (potentially multi-byte) sequence representing the
|
||||
single wide character is written, including any shift sequences.
|
||||
If a shift sequence is used, the shift state is also restored
|
||||
to the original state after the character.
|
||||
.It Cm S
|
||||
Treated as
|
||||
.Cm s
|
||||
with the
|
||||
.Cm l
|
||||
(ell) modifier.
|
||||
.It Cm s
|
||||
The
|
||||
.Vt char *
|
||||
@ -510,6 +586,30 @@ need be present; if the precision is not specified, or is greater than
|
||||
the size of the array, the array must contain a terminating
|
||||
.Dv NUL
|
||||
character.
|
||||
.Pp
|
||||
If the
|
||||
.Cm l
|
||||
(ell) modifier is used, the
|
||||
.Vt wchar_t *
|
||||
argument is expected to be a pointer to an array of wide characters
|
||||
(pointer to a wide string).
|
||||
For each wide character in the string, the (potentially multi-byte)
|
||||
sequence representing the
|
||||
wide character is written, including any shift sequences.
|
||||
If any shift sequence is used, the shift state is also restored
|
||||
to the original state after the string.
|
||||
Wide characters from the array are written up to (but not including)
|
||||
a terminating wide
|
||||
.Dv NUL
|
||||
character;
|
||||
if a precision is specified, no more than the number of bytes specified are
|
||||
written (including shift sequences). Partial characters are never written.
|
||||
If a precision is given, no null character
|
||||
need be present; if the precision is not specified, or is greater than
|
||||
the number of bytes required to render the multibyte representation of
|
||||
the string, the array must contain a terminating wide
|
||||
.Dv NUL
|
||||
character.
|
||||
.It Cm p
|
||||
The
|
||||
.Vt void *
|
||||
@ -538,7 +638,8 @@ character is defined in the program's locale (category
|
||||
.Dv LC_NUMERIC ) .
|
||||
.Pp
|
||||
In no case does a non-existent or small field width cause truncation of
|
||||
a field; if the result of a conversion is wider than the field width, the
|
||||
a numeric field; if the result of a conversion is wider than the field
|
||||
width, the
|
||||
field is expanded to contain the conversion result.
|
||||
.Sh EXAMPLES
|
||||
To print a date and time in the form
|
||||
@ -581,7 +682,8 @@ char *newfmt(const char *fmt, ...)
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr printf 1 ,
|
||||
.Xr scanf 3
|
||||
.Xr scanf 3 ,
|
||||
.Xr setlocale 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn fprintf ,
|
||||
@ -675,4 +777,31 @@ for later interpolation by
|
||||
.Pp
|
||||
Always use the proper secure idiom:
|
||||
.Pp
|
||||
.Dl snprintf(buffer, sizeof(buffer), "%s", string);
|
||||
.Dl snprintf(buffer, sizeof(buffer), \*q%s\*q, string);
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
family of functions currently lack the ability to use the
|
||||
.Qq '
|
||||
flag in conjunction with the
|
||||
.Qq f
|
||||
conversion specifier. The
|
||||
.Qq a
|
||||
and
|
||||
.Qq A
|
||||
conversion specifiers have not yet been implemented.
|
||||
The
|
||||
.Qq l
|
||||
(ell) modifier for the
|
||||
.Qq c
|
||||
and
|
||||
.Qq s
|
||||
conversion specifiers, for wide characters and strings, have not yet
|
||||
been implemented.
|
||||
The
|
||||
.Qq L
|
||||
modifier for floating point formats simply round the
|
||||
.Vt long double
|
||||
argument to
|
||||
.Vt double ,
|
||||
providing no additional precision.
|
||||
|
@ -51,7 +51,10 @@ static const char rcsid[] =
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -75,26 +78,45 @@ union arg {
|
||||
u_int uintarg;
|
||||
long longarg;
|
||||
u_long ulongarg;
|
||||
quad_t quadarg;
|
||||
u_quad_t uquadarg;
|
||||
long long longlongarg;
|
||||
unsigned long long ulonglongarg;
|
||||
ptrdiff_t ptrdiffarg;
|
||||
size_t sizearg;
|
||||
intmax_t intmaxarg;
|
||||
uintmax_t uintmaxarg;
|
||||
void *pvoidarg;
|
||||
char *pchararg;
|
||||
signed char *pschararg;
|
||||
short *pshortarg;
|
||||
int *pintarg;
|
||||
long *plongarg;
|
||||
quad_t *pquadarg;
|
||||
long long *plonglongarg;
|
||||
ptrdiff_t *pptrdiffarg;
|
||||
size_t *psizearg;
|
||||
intmax_t *pintmaxarg;
|
||||
#ifdef FLOATING_POINT
|
||||
double doublearg;
|
||||
long double longdoublearg;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Type ids for argument type table.
|
||||
*/
|
||||
enum typeid {
|
||||
T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
|
||||
T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
|
||||
T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
|
||||
T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
|
||||
T_DOUBLE, T_LONG_DOUBLE
|
||||
};
|
||||
|
||||
static int __sprint __P((FILE *, struct __suio *));
|
||||
static int __sbprintf __P((FILE *, const char *, va_list)) __printflike(2, 0);
|
||||
static char * __ultoa __P((u_long, char *, int, int, char *));
|
||||
static char * __uqtoa __P((u_quad_t, char *, int, int, char *));
|
||||
static char * __ujtoa __P((uintmax_t, char *, int, int, char *, const char *));
|
||||
static char * __ultoa __P((u_long, char *, int, int, char *, const char *));
|
||||
static void __find_arguments __P((const char *, va_list, union arg **));
|
||||
static void __grow_type_table __P((int, unsigned char **, int *));
|
||||
static void __grow_type_table __P((int, enum typeid **, int *));
|
||||
|
||||
/*
|
||||
* Flush out all the vectors defined by the given uio,
|
||||
@ -161,10 +183,12 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
|
||||
* use the given digits.
|
||||
*/
|
||||
static char *
|
||||
__ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)
|
||||
__ultoa(u_long val, char *endp, int base, int octzero, char *xdigs,
|
||||
const char *thousep)
|
||||
{
|
||||
register char *cp = endp;
|
||||
register long sval;
|
||||
int ndig;
|
||||
|
||||
/*
|
||||
* Handle the three cases separately, in the hope of getting
|
||||
@ -176,6 +200,7 @@ __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)
|
||||
*--cp = to_char(val);
|
||||
return (cp);
|
||||
}
|
||||
ndig = 0;
|
||||
/*
|
||||
* On many machines, unsigned arithmetic is harder than
|
||||
* signed arithmetic, so we do at most one unsigned mod and
|
||||
@ -184,11 +209,16 @@ __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)
|
||||
*/
|
||||
if (val > LONG_MAX) {
|
||||
*--cp = to_char(val % 10);
|
||||
ndig++;
|
||||
sval = val / 10;
|
||||
} else
|
||||
sval = val;
|
||||
do {
|
||||
*--cp = to_char(sval % 10);
|
||||
if (++ndig == 3 && thousep && *thousep != '\0') {
|
||||
*--cp = *thousep;
|
||||
ndig = 0;
|
||||
}
|
||||
sval /= 10;
|
||||
} while (sval != 0);
|
||||
break;
|
||||
@ -215,30 +245,39 @@ __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/* Identical to __ultoa, but for quads. */
|
||||
/* Identical to __ultoa, but for intmax_t. */
|
||||
static char *
|
||||
__uqtoa(u_quad_t val, char *endp, int base, int octzero, char *xdigs)
|
||||
__ujtoa(uintmax_t val, char *endp, int base, int octzero, char *xdigs,
|
||||
const char *thousep)
|
||||
{
|
||||
char *cp = endp;
|
||||
quad_t sval;
|
||||
intmax_t sval;
|
||||
int ndig;
|
||||
|
||||
/* quick test for small values; __ultoa is typically much faster */
|
||||
/* (perhaps instead we should run until small, then call __ultoa?) */
|
||||
if (val <= ULONG_MAX)
|
||||
return (__ultoa((u_long)val, endp, base, octzero, xdigs));
|
||||
return (__ultoa((u_long)val, endp, base, octzero, xdigs,
|
||||
thousep));
|
||||
switch (base) {
|
||||
case 10:
|
||||
if (val < 10) {
|
||||
*--cp = to_char(val % 10);
|
||||
return (cp);
|
||||
}
|
||||
if (val > QUAD_MAX) {
|
||||
ndig = 0;
|
||||
if (val > INTMAX_MAX) {
|
||||
*--cp = to_char(val % 10);
|
||||
ndig++;
|
||||
sval = val / 10;
|
||||
} else
|
||||
sval = val;
|
||||
do {
|
||||
*--cp = to_char(sval % 10);
|
||||
if (++ndig == 3 && thousep && *thousep != '\0') {
|
||||
*--cp = *thousep;
|
||||
ndig = 0;
|
||||
}
|
||||
sval /= 10;
|
||||
} while (sval != 0);
|
||||
break;
|
||||
@ -284,7 +323,7 @@ vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
#include <math.h>
|
||||
#include "floatio.h"
|
||||
|
||||
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
|
||||
#define BUF ((MAXEXP*4/3)+MAXFRACT+1) /* + decimal point */
|
||||
#define DEFPREC 6
|
||||
|
||||
static char *cvt __P((double, int, int, char *, int *, int, int *, char **));
|
||||
@ -292,7 +331,7 @@ static int exponent __P((char *, int, int));
|
||||
|
||||
#else /* no FLOATING_POINT */
|
||||
|
||||
#define BUF 68
|
||||
#define BUF 90
|
||||
|
||||
#endif /* FLOATING_POINT */
|
||||
|
||||
@ -306,10 +345,16 @@ static int exponent __P((char *, int, int));
|
||||
#define LADJUST 0x004 /* left adjustment */
|
||||
#define LONGDBL 0x008 /* long double */
|
||||
#define LONGINT 0x010 /* long integer */
|
||||
#define QUADINT 0x020 /* quad integer */
|
||||
#define LLONGINT 0x020 /* long long integer */
|
||||
#define SHORTINT 0x040 /* short integer */
|
||||
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
|
||||
#define FPT 0x100 /* Floating point number */
|
||||
/* C99 additional size modifiers: */
|
||||
#define SIZET 0x200 /* size_t */
|
||||
#define PTRDIFFT 0x400 /* ptrdiff_t */
|
||||
#define INTMAXT 0x800 /* intmax_t */
|
||||
#define CHARINT 0x1000 /* print char using int format */
|
||||
|
||||
/*
|
||||
* Non-MT-safe version
|
||||
*/
|
||||
@ -326,8 +371,9 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
int width; /* width from format (%8d), or 0 */
|
||||
int prec; /* precision from format (%.3d), or -1 */
|
||||
char sign; /* sign prefix (' ', '+', '-', or \0) */
|
||||
const char *thousands_sep;
|
||||
#ifdef FLOATING_POINT
|
||||
char *decimal_point = localeconv()->decimal_point;
|
||||
char *decimal_point;
|
||||
char softsign; /* temporary negative sign for floats */
|
||||
double _double; /* double precision arguments %[eEfgG] */
|
||||
int expt; /* integer value of exponent */
|
||||
@ -337,7 +383,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
char *dtoaresult; /* buffer allocated by dtoa */
|
||||
#endif
|
||||
u_long ulval; /* integer arguments %[diouxX] */
|
||||
u_quad_t uqval; /* %q integers */
|
||||
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
|
||||
int base; /* base for [diouxX] conversion */
|
||||
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
|
||||
int realsz; /* field size expanded by dprec, sign, etc */
|
||||
@ -347,9 +393,9 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
#define NIOV 8
|
||||
struct __suio uio; /* output information: summary */
|
||||
struct __siov iov[NIOV];/* ... and individual io vectors */
|
||||
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
|
||||
char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */
|
||||
char ox[2]; /* space for 0x hex-prefix */
|
||||
union arg *argtable; /* args, built due to positional arg */
|
||||
union arg *argtable; /* args, built due to positional arg */
|
||||
union arg statargtable [STATIC_ARG_TBL_SIZE];
|
||||
int nextarg; /* 1-based argument index */
|
||||
va_list orgap; /* original argument pointer */
|
||||
@ -411,11 +457,24 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
#define SARG() \
|
||||
(flags&LONGINT ? GETARG(long) : \
|
||||
flags&SHORTINT ? (long)(short)GETARG(int) : \
|
||||
flags&CHARINT ? (long)(signed char)GETARG(int) : \
|
||||
(long)GETARG(int))
|
||||
#define UARG() \
|
||||
(flags&LONGINT ? GETARG(u_long) : \
|
||||
flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
|
||||
flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
|
||||
(u_long)GETARG(u_int))
|
||||
#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
|
||||
#define SJARG() \
|
||||
(flags&INTMAXT ? GETARG(intmax_t) : \
|
||||
flags&SIZET ? (intmax_t)GETARG(size_t) : \
|
||||
flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
|
||||
(intmax_t)GETARG(long long))
|
||||
#define UJARG() \
|
||||
(flags&INTMAXT ? GETARG(uintmax_t) : \
|
||||
flags&SIZET ? (uintmax_t)GETARG(size_t) : \
|
||||
flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
|
||||
(uintmax_t)GETARG(unsigned long long))
|
||||
|
||||
/*
|
||||
* Get * arguments, including the form *nn$. Preserve the nextarg
|
||||
@ -443,8 +502,10 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
|
||||
}
|
||||
|
||||
|
||||
thousands_sep = NULL;
|
||||
#ifdef FLOATING_POINT
|
||||
dtoaresult = NULL;
|
||||
decimal_point = localeconv()->decimal_point;
|
||||
#endif
|
||||
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
|
||||
if (cantwrite(fp))
|
||||
@ -520,6 +581,9 @@ reswitch: switch (ch) {
|
||||
case '+':
|
||||
sign = '+';
|
||||
goto rflag;
|
||||
case '\'':
|
||||
thousands_sep = localeconv()->thousands_sep;
|
||||
goto rflag;
|
||||
case '.':
|
||||
if ((ch = *fmt++) == '*') {
|
||||
GETASTER (n);
|
||||
@ -565,16 +629,30 @@ reswitch: switch (ch) {
|
||||
goto rflag;
|
||||
#endif
|
||||
case 'h':
|
||||
flags |= SHORTINT;
|
||||
if (flags & SHORTINT) {
|
||||
flags &= ~SHORTINT;
|
||||
flags |= CHARINT;
|
||||
} else
|
||||
flags |= SHORTINT;
|
||||
goto rflag;
|
||||
case 'j':
|
||||
flags |= INTMAXT;
|
||||
goto rflag;
|
||||
case 'l':
|
||||
if (flags & LONGINT)
|
||||
flags |= QUADINT;
|
||||
else
|
||||
if (flags & LONGINT) {
|
||||
flags &= ~LONGINT;
|
||||
flags |= LLONGINT;
|
||||
} else
|
||||
flags |= LONGINT;
|
||||
goto rflag;
|
||||
case 'q':
|
||||
flags |= QUADINT;
|
||||
flags |= LLONGINT; /* not necessarily */
|
||||
goto rflag;
|
||||
case 't':
|
||||
flags |= PTRDIFFT;
|
||||
goto rflag;
|
||||
case 'z':
|
||||
flags |= SIZET;
|
||||
goto rflag;
|
||||
case 'c':
|
||||
*(cp = buf) = GETARG(int);
|
||||
@ -586,10 +664,10 @@ reswitch: switch (ch) {
|
||||
/*FALLTHROUGH*/
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (flags & QUADINT) {
|
||||
uqval = GETARG(quad_t);
|
||||
if ((quad_t)uqval < 0) {
|
||||
uqval = -uqval;
|
||||
if (flags & INTMAX_SIZE) {
|
||||
ujval = SJARG();
|
||||
if ((intmax_t)ujval < 0) {
|
||||
ujval = -ujval;
|
||||
sign = '-';
|
||||
}
|
||||
} else {
|
||||
@ -602,9 +680,14 @@ reswitch: switch (ch) {
|
||||
base = 10;
|
||||
goto number;
|
||||
#ifdef FLOATING_POINT
|
||||
#ifdef HEXFLOAT
|
||||
case 'a':
|
||||
case 'A':
|
||||
#endif
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
goto fp_begin;
|
||||
case 'g':
|
||||
case 'G':
|
||||
@ -621,12 +704,18 @@ fp_begin: if (prec == -1)
|
||||
if (isinf(_double)) {
|
||||
if (_double < 0)
|
||||
sign = '-';
|
||||
cp = "Inf";
|
||||
if (isupper(ch))
|
||||
cp = "INF";
|
||||
else
|
||||
cp = "inf";
|
||||
size = 3;
|
||||
break;
|
||||
}
|
||||
if (isnan(_double)) {
|
||||
cp = "NaN";
|
||||
if (isupper(ch))
|
||||
cp = "NAN";
|
||||
else
|
||||
cp = "nan";
|
||||
size = 3;
|
||||
break;
|
||||
}
|
||||
@ -643,13 +732,13 @@ fp_begin: if (prec == -1)
|
||||
else
|
||||
ch = 'g';
|
||||
}
|
||||
if (ch <= 'e') { /* 'e' or 'E' fmt */
|
||||
if (ch == 'e' || ch == 'E') {
|
||||
--expt;
|
||||
expsize = exponent(expstr, expt, ch);
|
||||
size = expsize + ndig;
|
||||
if (ndig > 1 || flags & ALT)
|
||||
++size;
|
||||
} else if (ch == 'f') { /* f fmt */
|
||||
} else if (ch == 'f' || ch == 'F') {
|
||||
if (expt > 0) {
|
||||
size = expt;
|
||||
if (prec || flags & ALT)
|
||||
@ -669,12 +758,25 @@ fp_begin: if (prec == -1)
|
||||
break;
|
||||
#endif /* FLOATING_POINT */
|
||||
case 'n':
|
||||
if (flags & QUADINT)
|
||||
*GETARG(quad_t *) = ret;
|
||||
/*
|
||||
* Assignment-like behavior is specified if the
|
||||
* value overflows or is otherwise unrepresentable.
|
||||
* C99 says to use `signed char' for %hhn conversions.
|
||||
*/
|
||||
if (flags & LLONGINT)
|
||||
*GETARG(long long *) = ret;
|
||||
else if (flags & SIZET)
|
||||
*GETARG(ssize_t *) = (ssize_t)ret;
|
||||
else if (flags & PTRDIFFT)
|
||||
*GETARG(ptrdiff_t *) = ret;
|
||||
else if (flags & INTMAXT)
|
||||
*GETARG(intmax_t *) = ret;
|
||||
else if (flags & LONGINT)
|
||||
*GETARG(long *) = ret;
|
||||
else if (flags & SHORTINT)
|
||||
*GETARG(short *) = ret;
|
||||
else if (flags & CHARINT)
|
||||
*GETARG(signed char *) = ret;
|
||||
else
|
||||
*GETARG(int *) = ret;
|
||||
continue; /* no output */
|
||||
@ -682,8 +784,8 @@ fp_begin: if (prec == -1)
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'o':
|
||||
if (flags & QUADINT)
|
||||
uqval = GETARG(u_quad_t);
|
||||
if (flags & INTMAX_SIZE)
|
||||
ujval = UJARG();
|
||||
else
|
||||
ulval = UARG();
|
||||
base = 8;
|
||||
@ -696,10 +798,10 @@ fp_begin: if (prec == -1)
|
||||
* defined manner.''
|
||||
* -- ANSI X3J11
|
||||
*/
|
||||
ulval = (u_long)GETARG(void *);
|
||||
ujval = (uintmax_t)(uintptr_t)GETARG(void *);
|
||||
base = 16;
|
||||
xdigs = "0123456789abcdef";
|
||||
flags = (flags & ~QUADINT) | HEXPREFIX;
|
||||
flags = flags | INTMAXT | HEXPREFIX;
|
||||
ch = 'x';
|
||||
goto nosign;
|
||||
case 's':
|
||||
@ -727,8 +829,8 @@ fp_begin: if (prec == -1)
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'u':
|
||||
if (flags & QUADINT)
|
||||
uqval = GETARG(u_quad_t);
|
||||
if (flags & INTMAX_SIZE)
|
||||
ujval = UJARG();
|
||||
else
|
||||
ulval = UARG();
|
||||
base = 10;
|
||||
@ -738,14 +840,15 @@ fp_begin: if (prec == -1)
|
||||
goto hex;
|
||||
case 'x':
|
||||
xdigs = "0123456789abcdef";
|
||||
hex: if (flags & QUADINT)
|
||||
uqval = GETARG(u_quad_t);
|
||||
hex:
|
||||
if (flags & INTMAX_SIZE)
|
||||
ujval = UJARG();
|
||||
else
|
||||
ulval = UARG();
|
||||
base = 16;
|
||||
/* leading 0x/X only if non-zero */
|
||||
if (flags & ALT &&
|
||||
(flags & QUADINT ? uqval != 0 : ulval != 0))
|
||||
(flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
|
||||
flags |= HEXPREFIX;
|
||||
|
||||
/* unsigned conversions */
|
||||
@ -764,14 +867,14 @@ number: if ((dprec = prec) >= 0)
|
||||
* -- ANSI X3J11
|
||||
*/
|
||||
cp = buf + BUF;
|
||||
if (flags & QUADINT) {
|
||||
if (uqval != 0 || prec != 0)
|
||||
cp = __uqtoa(uqval, cp, base,
|
||||
flags & ALT, xdigs);
|
||||
if (flags & INTMAX_SIZE) {
|
||||
if (ujval != 0 || prec != 0)
|
||||
cp = __ujtoa(ujval, cp, base,
|
||||
flags & ALT, xdigs, thousands_sep);
|
||||
} else {
|
||||
if (ulval != 0 || prec != 0)
|
||||
cp = __ultoa(ulval, cp, base,
|
||||
flags & ALT, xdigs);
|
||||
flags & ALT, xdigs, thousands_sep);
|
||||
}
|
||||
size = buf + BUF - cp;
|
||||
break;
|
||||
@ -903,27 +1006,6 @@ error:
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Type ids for argument type table.
|
||||
*/
|
||||
#define T_UNUSED 0
|
||||
#define T_SHORT 1
|
||||
#define T_U_SHORT 2
|
||||
#define TP_SHORT 3
|
||||
#define T_INT 4
|
||||
#define T_U_INT 5
|
||||
#define TP_INT 6
|
||||
#define T_LONG 7
|
||||
#define T_U_LONG 8
|
||||
#define TP_LONG 9
|
||||
#define T_QUAD 10
|
||||
#define T_U_QUAD 11
|
||||
#define TP_QUAD 12
|
||||
#define T_DOUBLE 13
|
||||
#define T_LONG_DOUBLE 14
|
||||
#define TP_CHAR 15
|
||||
#define TP_VOID 16
|
||||
|
||||
/*
|
||||
* Find all arguments when a positional parameter is encountered. Returns a
|
||||
* table, indexed by argument number, of pointers to each arguments. The
|
||||
@ -939,8 +1021,8 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
|
||||
char *cp; /* handy char pointer (short term usage) */
|
||||
int flags; /* flags as above */
|
||||
int width; /* width from format (%8d), or 0 */
|
||||
unsigned char *typetable; /* table of types */
|
||||
unsigned char stattypetable [STATIC_ARG_TBL_SIZE];
|
||||
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 */
|
||||
@ -955,12 +1037,18 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
|
||||
typetable[nextarg++] = type)
|
||||
|
||||
#define ADDSARG() \
|
||||
((flags&LONGINT) ? ADDTYPE(T_LONG) : \
|
||||
((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT)))
|
||||
((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&LONGINT) ? ADDTYPE(T_U_LONG) : \
|
||||
((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT)))
|
||||
((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.
|
||||
@ -1011,6 +1099,7 @@ reswitch: switch (ch) {
|
||||
goto rflag;
|
||||
case '-':
|
||||
case '+':
|
||||
case '\'':
|
||||
goto rflag;
|
||||
case '.':
|
||||
if ((ch = *fmt++) == '*') {
|
||||
@ -1042,16 +1131,30 @@ reswitch: switch (ch) {
|
||||
goto rflag;
|
||||
#endif
|
||||
case 'h':
|
||||
flags |= SHORTINT;
|
||||
if (flags & SHORTINT) {
|
||||
flags &= ~SHORTINT;
|
||||
flags |= CHARINT;
|
||||
} else
|
||||
flags |= SHORTINT;
|
||||
goto rflag;
|
||||
case 'j':
|
||||
flags |= INTMAXT;
|
||||
goto rflag;
|
||||
case 'l':
|
||||
if (flags & LONGINT)
|
||||
flags |= QUADINT;
|
||||
else
|
||||
if (flags & LONGINT) {
|
||||
flags &= ~LONGINT;
|
||||
flags |= LLONGINT;
|
||||
} else
|
||||
flags |= LONGINT;
|
||||
goto rflag;
|
||||
case 'q':
|
||||
flags |= QUADINT;
|
||||
flags |= LLONGINT; /* not necessarily */
|
||||
goto rflag;
|
||||
case 't':
|
||||
flags |= PTRDIFFT;
|
||||
goto rflag;
|
||||
case 'z':
|
||||
flags |= SIZET;
|
||||
goto rflag;
|
||||
case 'c':
|
||||
ADDTYPE(T_INT);
|
||||
@ -1061,13 +1164,13 @@ reswitch: switch (ch) {
|
||||
/*FALLTHROUGH*/
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (flags & QUADINT) {
|
||||
ADDTYPE(T_QUAD);
|
||||
} else {
|
||||
ADDSARG();
|
||||
}
|
||||
ADDSARG();
|
||||
break;
|
||||
#ifdef FLOATING_POINT
|
||||
#ifdef HEXFLOAT
|
||||
case 'a':
|
||||
case 'A':
|
||||
#endif
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
@ -1080,12 +1183,20 @@ reswitch: switch (ch) {
|
||||
break;
|
||||
#endif /* FLOATING_POINT */
|
||||
case 'n':
|
||||
if (flags & QUADINT)
|
||||
ADDTYPE(TP_QUAD);
|
||||
if (flags & INTMAXT)
|
||||
ADDTYPE(TP_INTMAXT);
|
||||
else if (flags & PTRDIFFT)
|
||||
ADDTYPE(TP_PTRDIFFT);
|
||||
else if (flags & SIZET)
|
||||
ADDTYPE(TP_SIZET);
|
||||
else if (flags & LLONGINT)
|
||||
ADDTYPE(TP_LLONG);
|
||||
else if (flags & LONGINT)
|
||||
ADDTYPE(TP_LONG);
|
||||
else if (flags & SHORTINT)
|
||||
ADDTYPE(TP_SHORT);
|
||||
else if (flags & CHARINT)
|
||||
ADDTYPE(TP_SCHAR);
|
||||
else
|
||||
ADDTYPE(TP_INT);
|
||||
continue; /* no output */
|
||||
@ -1093,10 +1204,7 @@ reswitch: switch (ch) {
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'o':
|
||||
if (flags & QUADINT)
|
||||
ADDTYPE(T_U_QUAD);
|
||||
else
|
||||
ADDUARG();
|
||||
ADDUARG();
|
||||
break;
|
||||
case 'p':
|
||||
ADDTYPE(TP_VOID);
|
||||
@ -1108,17 +1216,9 @@ reswitch: switch (ch) {
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'u':
|
||||
if (flags & QUADINT)
|
||||
ADDTYPE(T_U_QUAD);
|
||||
else
|
||||
ADDUARG();
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
if (flags & QUADINT)
|
||||
ADDTYPE(T_U_QUAD);
|
||||
else
|
||||
ADDUARG();
|
||||
ADDUARG();
|
||||
break;
|
||||
default: /* "%?" prints ?, unless ? is NUL */
|
||||
if (ch == '\0')
|
||||
@ -1138,14 +1238,11 @@ done:
|
||||
(*argtable) [0].intarg = 0;
|
||||
for (n = 1; n <= tablemax; n++) {
|
||||
switch (typetable [n]) {
|
||||
case T_UNUSED:
|
||||
case T_UNUSED: /* whoops! */
|
||||
(*argtable) [n].intarg = va_arg (ap, int);
|
||||
break;
|
||||
case T_SHORT:
|
||||
(*argtable) [n].intarg = va_arg (ap, int);
|
||||
break;
|
||||
case T_U_SHORT:
|
||||
(*argtable) [n].intarg = va_arg (ap, int);
|
||||
case TP_SCHAR:
|
||||
(*argtable) [n].pschararg = va_arg (ap, signed char *);
|
||||
break;
|
||||
case TP_SHORT:
|
||||
(*argtable) [n].pshortarg = va_arg (ap, short *);
|
||||
@ -1168,14 +1265,35 @@ done:
|
||||
case TP_LONG:
|
||||
(*argtable) [n].plongarg = va_arg (ap, long *);
|
||||
break;
|
||||
case T_QUAD:
|
||||
(*argtable) [n].quadarg = va_arg (ap, quad_t);
|
||||
case T_LLONG:
|
||||
(*argtable) [n].longlongarg = va_arg (ap, long long);
|
||||
break;
|
||||
case T_U_QUAD:
|
||||
(*argtable) [n].uquadarg = va_arg (ap, u_quad_t);
|
||||
case T_U_LLONG:
|
||||
(*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
|
||||
break;
|
||||
case TP_QUAD:
|
||||
(*argtable) [n].pquadarg = va_arg (ap, quad_t *);
|
||||
case TP_LLONG:
|
||||
(*argtable) [n].plonglongarg = va_arg (ap, long long *);
|
||||
break;
|
||||
case T_PTRDIFFT:
|
||||
(*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
|
||||
break;
|
||||
case TP_PTRDIFFT:
|
||||
(*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
|
||||
break;
|
||||
case T_SIZET:
|
||||
(*argtable) [n].sizearg = va_arg (ap, size_t);
|
||||
break;
|
||||
case TP_SIZET:
|
||||
(*argtable) [n].psizearg = va_arg (ap, ssize_t *);
|
||||
break;
|
||||
case T_INTMAXT:
|
||||
(*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
|
||||
break;
|
||||
case T_UINTMAXT:
|
||||
(*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
|
||||
break;
|
||||
case TP_INTMAXT:
|
||||
(*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
|
||||
break;
|
||||
#ifdef FLOATING_POINT
|
||||
case T_DOUBLE:
|
||||
@ -1202,11 +1320,11 @@ done:
|
||||
* Increase the size of the type table.
|
||||
*/
|
||||
static void
|
||||
__grow_type_table (int nextarg, unsigned char **typetable, int *tablesize)
|
||||
__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
|
||||
{
|
||||
unsigned char *const oldtable = *typetable;
|
||||
enum typeid *const oldtable = *typetable;
|
||||
const int oldsize = *tablesize;
|
||||
unsigned char *newtable;
|
||||
enum typeid *newtable;
|
||||
int newsize = oldsize * 2;
|
||||
|
||||
if (newsize < nextarg + 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user