It then seems to enter this function, which is just huge ! and complex ! and ugly ! and insane ! it's like oh my god ?! How can anybody program this shhhhiiittt ?!?
Now this truely makes me wonder if "unicode" was only invented to introduce exploitable system bugs for the chinese hackers ! YIKES !
int __cdecl _output_s_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
#endif /* _UNICODE */
#endif /* CPRFLAG */
const _TCHAR *format,
#ifndef _SAFECRT_IMPL
_locale_t plocinfo,
#endif /* _SAFECRT_IMPL */
va_list argptr
)
{
int hexadd=0; /* offset to add to number to get 'a'..'f' */
TCHAR ch; /* character just read */
int flags=0; /* flag word -- see #defines above for flag values */
enum STATE state; /* current state */
enum CHARTYPE chclass; /* class of current character */
int radix; /* current conversion radix */
int charsout; /* characters currently written so far, -1 = IO error */
int fldwidth = 0; /* selected field width -- 0 means default */
int precision = 0; /* selected precision -- -1 means default */
TCHAR prefix[2]; /* numeric prefix -- up to two characters */
int prefixlen=0; /* length of prefix -- 0 means no prefix */
int capexp; /* non-zero = 'E' exponent signifient, zero = 'e' */
int no_output=0; /* non-zero = prodcue no output for this specifier */
union {
char *sz; /* pointer text to be printed, not zero terminated */
wchar_t *wz;
} text;
int textlen; /* length of the text in bytes/wchars to be printed.
textlen is in multibyte or wide chars if _UNICODE */
union {
char sz[BUFFERSIZE];
#ifdef _UNICODE
wchar_t wz[BUFFERSIZE];
#endif /* _UNICODE */
} buffer;
wchar_t wchar; /* temp wchar_t */
int buffersize; /* size of text.sz (used only for the call to _cfltcvt) */
int bufferiswide=0; /* non-zero = buffer contains wide chars already */
#ifndef _SAFECRT_IMPL
_LocaleUpdate _loc_update(plocinfo);
#endif /* _SAFECRT_IMPL */
#ifdef POSITIONAL_PARAMETERS
/* Used for parsing the format */
const _TCHAR * saved_format = NULL;
_TCHAR * end_pos = NULL;
/* This is the structure which stores the values corresponding to
each positional param */
struct positional_param pos_value[_ARGMAX];
int pass = 0; /* Ctr for scanning the format string in diff passes */
int noofpasses = 0; /* Set to 2 for positional formats, otherwise 1 */
int max_pos = -1; /* Keeping track of the current max positional arg */
int type_pos = -1; /* position of an arg denoting a type */
int width_pos = -1; /* position of an arg denoting width */
int precis_pos = -1; /* position of an arg denoting precision */
int format_type = FMT_TYPE_NOTSET; /* type of format string */
#endif /* POSITIONAL_PARAMETERS */
char *heapbuf = NULL; /* non-zero = test.sz using heap buffer to be freed */
#ifndef CPRFLAG
_VALIDATE_RETURN( (stream != NULL), EINVAL, -1);
#ifndef _UNICODE
_VALIDATE_STREAM_ANSI_RETURN(stream, EINVAL, EOF);
#endif /* _UNICODE */
#endif /* CPRFLAG */
_VALIDATE_RETURN( (format != NULL), EINVAL, -1);
charsout = 0; /* no characters written yet */
#ifdef POSITIONAL_PARAMETERS
saved_format = format;
for(pass = 0 ; pass < 2; ++pass)
{
if((pass == FORMAT_OUTPUT_PASS) && (format_type == FMT_TYPE_NONPOSITIONAL))
{
/* If in pass2, we still have format_type isn't positional, it means
that we do not need a 2nd pass */
break;
}
#endif /* POSITIONAL_PARAMETERS */
textlen = 0; /* no text yet */
state = ST_NORMAL; /* starting state */
heapbuf = NULL; /* not using heap-allocated buffer */
buffersize = 0;
#ifdef POSITIONAL_PARAMETERS
max_pos = -1;
fldwidth = 0;
precision = 0;
format = saved_format;
type_pos = -1;
width_pos = -1;
precis_pos = -1;
/* All chars before the first format specifier get output in the first
pass itself. Hence we have to reset format_type to FMT_TYPE_NOTSET to ensure
that they do not get output again in the 2nd pass */
format_type = FMT_TYPE_NOTSET;
#endif /* POSITIONAL_PARAMETERS */
/* main loop -- loop while format character exist and no I/O errors */
while ((ch = *format++) != _T('\0') && charsout >= 0) {
#ifndef FORMAT_VALIDATIONS
chclass = FIND_CHAR_CLASS(__lookuptable, ch); /* find character class */
state = FIND_NEXT_STATE(__lookuptable, chclass, state); /* find next state */
#else /* FORMAT_VALIDATIONS */
chclass = FIND_CHAR_CLASS(__lookuptable_s, ch); /* find character class */
state = FIND_NEXT_STATE(__lookuptable_s, chclass, state); /* find next state */
#ifdef POSITIONAL_PARAMETERS
if((state == ST_PERCENT) && (*format != _T('%')))
{
if(format_type == FMT_TYPE_NOTSET)
{
/* We set the value of format_type when we hit the first type specifier */
if(_tcstol(format, &end_pos, 10) > 0 && (*end_pos == POSITION_CHAR))
{
if(pass == FORMAT_POSSCAN_PASS)
{
memset(pos_value,0,sizeof(pos_value));
}
format_type = FMT_TYPE_POSITIONAL;
}
else
{
format_type = FMT_TYPE_NONPOSITIONAL;
}
}
if(format_type == FMT_TYPE_POSITIONAL)
{
type_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
/* We don't redo the validations in the 2nd pass */
_VALIDATE_RETURN(((type_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = type_pos > max_pos ? type_pos : max_pos;
}
}
}
else
{
/* If state is ST_INVALID, that means an invalid format specifier */
if (state == ST_INVALID)
_VALIDATE_RETURN(("Incorrect format specifier", 0), EINVAL, -1);
}
#else /* POSITIONAL_PARAMETERS */
if (state == ST_INVALID)
_VALIDATE_RETURN(("Incorrect format specifier", 0), EINVAL, -1);
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
/* execute code for each state */
switch (state) {
case ST_NORMAL:
#ifdef POSITIONAL_PARAMETERS
if(((pass == FORMAT_POSSCAN_PASS) && (format_type == FMT_TYPE_POSITIONAL))
|| ((pass == FORMAT_OUTPUT_PASS) && (format_type == FMT_TYPE_NOTSET)))
{
/* Do not output in the 1st pass, if we have already come across
a positional format specifier. All chars before the first format
specifier get output in the first pass itself. Hence we need to
check the format_type to make sure that they don't get output
again in the 2nd pass */
break;
}
#endif /* POSITIONAL_PARAMETERS */
NORMAL_STATE:
/* normal state -- just write character */
#ifdef _UNICODE
bufferiswide = 1;
#else /* _UNICODE */
bufferiswide = 0;
#ifdef _SAFECRT_IMPL
if (isleadbyte((unsigned char)ch)) {
#else /* _SAFECRT_IMPL */
if (_isleadbyte_l((unsigned char)ch, _loc_update.GetLocaleT())) {
#endif /* _SAFECRT_IMPL */
WRITE_CHAR(ch, &charsout);
ch = *format++;
/* don't fall off format string */
_VALIDATE_RETURN( (ch != _T('\0')), EINVAL, -1);
}
#endif /* _UNICODE */
WRITE_CHAR(ch, &charsout);
break;
case ST_PERCENT:
/* set default value of conversion parameters */
prefixlen = fldwidth = no_output = capexp = 0;
flags = 0;
precision = -1;
bufferiswide = 0; /* default */
break;
case ST_FLAG:
/* set flag based on which flag character */
switch (ch) {
case _T('-'):
flags |= FL_LEFT; /* '-' => left justify */
break;
case _T('+'):
flags |= FL_SIGN; /* '+' => force sign indicator */
break;
case _T(' '):
flags |= FL_SIGNSP; /* ' ' => force sign or space */
break;
case _T('#'):
flags |= FL_ALTERNATE; /* '#' => alternate form */
break;
case _T('0'):
flags |= FL_LEADZERO; /* '0' => pad with leading zeros */
break;
}
break;
case ST_WIDTH:
/* update width value */
if (ch == _T('*')) {
/* get width from arg list */
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
fldwidth = get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
width_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
_VALIDATE_RETURN(((width_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = width_pos > max_pos ? width_pos : max_pos;
STORE_ARGPTR(pos_value, e_int_arg, width_pos, ch, flags)
break;
}
else
{
/* get width from arg list */
GET_ARG(get_int_arg,pos_value[width_pos].arg_ptr, fldwidth, )
}
}
#endif /* POSITIONAL_PARAMETERS */
if (fldwidth < 0) {
/* ANSI says neg fld width means '-' flag and pos width */
flags |= FL_LEFT;
fldwidth = -fldwidth;
}
}
else {
/* add digit to current field width */
fldwidth = fldwidth * 10 + (ch - _T('0'));
}
break;
case ST_DOT:
/* zero the precision, since dot with no number means 0
not default, according to ANSI */
precision = 0;
break;
case ST_PRECIS:
/* update precison value */
if (ch == _T('*')) {
/* get precision from arg list */
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
precision = get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
precis_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
_VALIDATE_RETURN(((precis_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = precis_pos > max_pos ? precis_pos : max_pos;
STORE_ARGPTR(pos_value, e_int_arg, precis_pos, ch, flags)
break;
}
else
{
/* get width from arg list */
GET_ARG(get_int_arg,pos_value[precis_pos].arg_ptr, precision, )
}
}
#endif /* POSITIONAL_PARAMETERS */
if (precision < 0)
precision = -1; /* neg precision means default */
}
else {
/* add digit to current precision */
precision = precision * 10 + (ch - _T('0'));
}
break;
case ST_SIZE:
/* just read a size specifier, set the flags based on it */
switch (ch) {
case _T('l'):
/*
* In order to handle the ll case, we depart from the
* simple deterministic state machine.
*/
if (*format == _T('l'))
{
++format;
flags |= FL_LONGLONG; /* 'll' => long long */
}
else
{
flags |= FL_LONG; /* 'l' => long int or wchar_t */
}
break;
case _T('I'):
/*
* In order to handle the I, I32, and I64 size modifiers, we
* depart from the simple deterministic state machine. The
* code below scans for characters following the 'I',
* and defaults to 64 bit on WIN64 and 32 bit on WIN32
*/
#if PTR_IS_INT64
flags |= FL_I64; /* 'I' => __int64 on WIN64 systems */
#endif /* PTR_IS_INT64 */
if ( (*format == _T('6')) && (*(format + 1) == _T('4')) )
{
format += 2;
flags |= FL_I64; /* I64 => __int64 */
}
else if ( (*format == _T('3')) && (*(format + 1) == _T('2')) )
{
format += 2;
flags &= ~FL_I64; /* I32 => __int32 */
}
else if ( (*format == _T('d')) ||
(*format == _T('i')) ||
(*format == _T('o')) ||
(*format == _T('u')) ||
(*format == _T('x')) ||
(*format == _T('X')) )
{
#ifdef POSITIONAL_PARAMETERS
/* %I without 32/64 is platform dependent. We set FL_PTRSIZE to indicate
this - this is used in the positional parameter reuse validation */
flags |= FL_PTRSIZE;
#else /* POSITIONAL_PARAMETERS */
/*
* Nothing further needed. %Id (et al) is
* handled just like %d, except that it defaults to 64 bits
* on WIN64. Fall through to the next iteration.
*/
#endif /* POSITIONAL_PARAMETERS */
}
else {
state = ST_NORMAL;
goto NORMAL_STATE;
}
break;
case _T('h'):
flags |= FL_SHORT; /* 'h' => short int or char */
break;
case _T('w'):
flags |= FL_WIDECHAR; /* 'w' => wide character */
break;
}
break;
case ST_TYPE:
/* we have finally read the actual type character, so we */
/* now format and "print" the output. We use a big switch */
/* statement that sets 'text' to point to the text that should */
/* be printed, and 'textlen' to the length of this text. */
/* Common code later on takes care of justifying it and */
/* other miscellaneous chores. Note that cases share code, */
/* in particular, all integer formatting is done in one place. */
/* Look at those funky goto statements! */
switch (ch) {
case _T('C'): /* ISO wide character */
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
#ifdef _UNICODE
flags |= FL_SHORT;
#else /* _UNICODE */
flags |= FL_WIDECHAR; /* ISO std. */
#endif /* _UNICODE */
/* fall into 'c' case */
case _T('c'): {
/* print a single character specified by int argument */
#ifdef _UNICODE
bufferiswide = 1;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
wchar = (wchar_t) get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_int_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_int_arg,pos_value[type_pos].arg_ptr, wchar, (wchar_t))
}
}
#endif /* POSITIONAL_PARAMETERS */
if (flags & FL_SHORT) {
/* format multibyte character */
/* this is an extension of ANSI */
char tempchar[2];
{
tempchar[0] = (char)(wchar & 0x00ff);
tempchar[1] = '\0';
}
#ifdef _SAFECRT_IMPL
if (_MBTOWC(buffer.wz,tempchar, MB_CUR_MAX) < 0)
#else /* _SAFECRT_IMPL */
if (_mbtowc_l(buffer.wz,
tempchar,
_loc_update.GetLocaleT()->locinfo->mb_cur_max,
_loc_update.GetLocaleT()) < 0)
#endif /* _SAFECRT_IMPL */
{
/* ignore if conversion was unsuccessful */
no_output = 1;
}
} else {
buffer.wz[0] = wchar;
}
text.wz = buffer.wz;
textlen = 1; /* print just a single character */
#else /* _UNICODE */
if (flags & (FL_LONG|FL_WIDECHAR)) {
errno_t e = 0;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
wchar = (wchar_t) get_short_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_short_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_short_arg,pos_value[type_pos].arg_ptr, wchar, (wchar_t))
}
}
#endif /* POSITIONAL_PARAMETERS */
/* convert to multibyte character */
e = _WCTOMB_S(&textlen, buffer.sz, _countof(buffer.sz), wchar);
/* check that conversion was successful */
if (e != 0)
no_output = 1;
} else {
/* format multibyte character */
/* this is an extension of ANSI */
unsigned short temp;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
temp = (unsigned short) get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_int_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_int_arg,pos_value[type_pos].arg_ptr, temp, (unsigned short))
}
}
#endif /* POSITIONAL_PARAMETERS */
{
buffer.sz[0] = (char) temp;
textlen = 1;
}
}
text.sz = buffer.sz;
#endif /* _UNICODE */
}
break;
case _T('Z'): {
/* print a Counted String
int i;
char *p; /* temps */
struct _count_string {
short Length;
short MaximumLength;
char *Buffer;
} *pstr;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
pstr = (struct _count_string *)get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr, pstr, (struct _count_string *) )
}
}
#endif /* POSITIONAL_PARAMETERS */
if (pstr == NULL || pstr->Buffer == NULL) {
/* null ptr passed, use special string */
text.sz = __nullstring;
textlen = (int)strlen(text.sz);
} else {
if (flags & FL_WIDECHAR) {
text.wz = (wchar_t *)pstr->Buffer;
textlen = pstr->Length / (int)sizeof(wchar_t);
bufferiswide = 1;
} else {
bufferiswide = 0;
text.sz = pstr->Buffer;
textlen = pstr->Length;
}
}
}
break;
case _T('S'): /* ISO wide character string */
#ifndef _UNICODE
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
flags |= FL_WIDECHAR;
#else /* _UNICODE */
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
flags |= FL_SHORT;
#endif /* _UNICODE */
case _T('s'): {
/* print a string -- */
/* ANSI rules on how much of string to print: */
/* all if precision is default, */
/* min(precision, length) if precision given. */
/* prints '(null)' if a null string is passed */
int i;
char *p; /* temps */
wchar_t *pwch;
/* At this point it is tempting to use strlen(), but */
/* if a precision is specified, we're not allowed to */
/* scan past there, because there might be no null */
/* at all. Thus, we must do our own scan. */
i = (precision == -1) ? INT_MAX : precision;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
text.sz = (char *)get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr, text.sz,(char *))
}
}
#endif /* POSITIONAL_PARAMETERS */
/* scan for null upto i characters */
#ifdef _UNICODE
if (flags & FL_SHORT) {
if (text.sz == NULL) /* NULL passed, use special string */
text.sz = __nullstring;
p = text.sz;
for (textlen=0; textlen
#ifdef _SAFECRT_IMPL
if (isleadbyte((unsigned char)(*p)))
#else /* _SAFECRT_IMPL */
if (_isleadbyte_l((unsigned char)(*p), _loc_update.GetLocaleT()))
#endif /* _SAFECRT_IMPL */
++p;
++p;
}
/* textlen now contains length in multibyte chars */
} else {
if (text.wz == NULL) /* NULL passed, use special string */
text.wz = __wnullstring;
bufferiswide = 1;
pwch = text.wz;
while (i-- && *pwch)
++pwch;
textlen = (int)(pwch - text.wz); /* in wchar_ts */
/* textlen now contains length in wide chars */
}
#else /* _UNICODE */
if (flags & (FL_LONG|FL_WIDECHAR)) {
if (text.wz == NULL) /* NULL passed, use special string */
text.wz = __wnullstring;
bufferiswide = 1;
pwch = text.wz;
while ( i-- && *pwch )
++pwch;
textlen = (int)(pwch - text.wz);
/* textlen now contains length in wide chars */
} else {
if (text.sz == NULL) /* NULL passed, use special string */
text.sz = __nullstring;
p = text.sz;
while (i-- && *p)
++p;
textlen = (int)(p - text.sz); /* length of the string */
}
#endif /* _UNICODE */
}
break;
case _T('n'): {
/* write count of characters seen so far into */
/* short/int/long thru ptr read from args */
void *p; /* temp */
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
p = get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
if (pass == FORMAT_POSSCAN_PASS)
{
STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr,p,)
}
}
#endif /* POSITIONAL_PARAMETERS */
/* if %n is disabled, we skip an arg and print 'n' */
if ( !_get_printf_count_output() )
{
_VALIDATE_RETURN(("'n' format specifier disabled", 0), EINVAL, -1);
break;
}
/* store chars out into short/long/int depending on flags */
#if !LONG_IS_INT
if (flags & FL_LONG)
*(long *)p = charsout;
else
#endif /* !LONG_IS_INT */
#if !SHORT_IS_INT
if (flags & FL_SHORT)
*(short *)p = (short) charsout;
else
#endif /* !SHORT_IS_INT */
*(int *)p = charsout;
no_output = 1; /* force no output */
}
break;
case _T('E'):
case _T('G'):
case _T('A'):
capexp = 1; /* capitalize exponent */
ch += _T('a') - _T('A'); /* convert format char to lower */
/* DROP THROUGH */
case _T('e'):
case _T('f'):
case _T('g'):
case _T('a'): {
/* floating point conversion -- we call cfltcvt routines */
/* to do the work for us. */
flags |= FL_SIGNED; /* floating point is signed conversion */
#ifdef POSITIONAL_PARAMETERS
if((format_type == FMT_TYPE_POSITIONAL) && (pass == FORMAT_POSSCAN_PASS))
{
_VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);
#if !LONGDOUBLE_IS_DOUBLE
if (flags & FL_LONGDOUBLE)
{
STORE_ARGPTR(pos_value, e_longdouble_arg, type_pos, ch, flags)
}
else
#endif /* !LONGDOUBLE_IS_DOUBLE */
{
STORE_ARGPTR(pos_value, e_double_arg, type_pos, ch, flags)
}
break;
}
#endif /* POSITIONAL_PARAMETERS */
text.sz = buffer.sz; /* put result in buffer */
buffersize = BUFFERSIZE;
/* compute the precision value */
if (precision < 0)
precision = 6; /* default precision: 6 */
else if (precision == 0 && ch == _T('g'))
precision = 1; /* ANSI specified */
else if (precision > MAXPRECISION)
precision = MAXPRECISION;
if (precision > BUFFERSIZE - _CVTBUFSIZE) {
/* conversion will potentially overflow local buffer */
/* so we need to use a heap-allocated buffer. */
heapbuf = (char *)_malloc_crt(_CVTBUFSIZE + precision);
if (heapbuf != NULL)
{
text.sz = heapbuf;
buffersize = _CVTBUFSIZE + precision;
}
else
/* malloc failed, cap precision further */
precision = BUFFERSIZE - _CVTBUFSIZE;
}
#ifdef _SAFECRT_IMPL
/* for safecrt, we pass along the FL_ALTERNATE flag to _safecrt_cfltcvt */
if (flags & FL_ALTERNATE)
{
capexp |= FL_ALTERNATE;
}
#endif /* _SAFECRT_IMPL */
#if !LONGDOUBLE_IS_DOUBLE
/* do the conversion */
if (flags & FL_LONGDOUBLE) {
_LONGDOUBLE tmp;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
tmp=va_arg(argptr, _LONGDOUBLE);
#ifdef POSITIONAL_PARAMETERS
}
else
{
/* Will get here only for pass == FORMAT_OUTPUT_PASS because
pass == FORMAT_POSSCAN_PASS has a break Above */
va_list tmp_arg;
_ASSERTE(pass == FORMAT_OUTPUT_PASS);
&nb