#include <float.h>
#ifdef _UNICODE
-#define streamout wstreamout
-#define format_float format_floatw
+# define streamout wstreamout
+# define format_float format_floatw
#endif
#define MB_CUR_MAX 10
(flags & FLAG_LONGDOUBLE) ? va_arg(argptr, long double) : \
va_arg(argptr, double)
-#ifdef _LIBCNT_
-# define _flsbuf(chr, stream) 0
-#endif
-
#define get_exp(f) floor(f == 0 ? 0 : (f >= 0 ? log10(f) : log10(-f)))
+#define round(x) floor((x) + 0.5)
+
+#ifndef _USER32_WSPRINTF
void
#ifdef _LIBCNT
exponent = get_exp(fpval);
sign = fpval < 0 ? -1 : 1;
- /* Shift the decimal point and round */
- fpval2 = round(sign * fpval * pow(10., precision - exponent));
- if (fpval2 >= (unsigned __int64)pow(10., precision + 1))
- {
- exponent++;
- fpval2 = round(sign * fpval * pow(10., precision - exponent));
- }
-
switch (chr)
{
case _T('G'):
if (precision > 0) precision--;
if (exponent < -4 || exponent >= precision) goto case_e;
+ /* Shift the decimal point and round */
+ fpval2 = round(sign * fpval * pow(10., precision));
+
/* Skip trailing zeroes */
while (precision && (unsigned __int64)fpval2 % 10 == 0)
{
digits = digits_u;
case _T('e'):
case_e:
+ /* Shift the decimal point and round */
+ fpval2 = round(sign * fpval * pow(10., precision - exponent));
+
+ /* Compensate for changed exponent through rounding */
+ if (fpval2 >= (unsigned __int64)pow(10., precision + 1))
+ {
+ exponent++;
+ fpval2 = round(sign * fpval * pow(10., precision - exponent));
+ }
+
val32 = exponent >= 0 ? exponent : -exponent;
// FIXME: handle length of exponent field:
// FIXME: TODO
case _T('f'):
+ default:
+ /* Shift the decimal point and round */
+ fpval2 = round(sign * fpval * pow(10., precision));
break;
}
while ((unsigned __int64)fpval2);
}
+#endif
static
int
streamout_char(FILE *stream, int chr)
{
+#if defined(_USER32_WSPRINTF) || defined(_LIBCNT_)
/* Check if the buffer is full */
if (stream->_cnt < sizeof(TCHAR))
- {
- /* Strings are done now */
- if (stream->_flag & _IOSTRG) return _TEOF;
-
- /* Flush buffer for files */
- return _flsbuf(chr, stream) != _TEOF;
- }
+ return 0;
*(TCHAR*)stream->_ptr = chr;
stream->_ptr += sizeof(TCHAR);
stream->_cnt -= sizeof(TCHAR);
return 1;
+#else
+ return _fputtc((TCHAR)chr, stream) != _TEOF;
+#endif
}
static
#define streamout_string streamout_astring
#endif
+#ifdef _USER32_WSPRINTF
+# define USE_MULTISIZE 0
+#else
+# define USE_MULTISIZE 1
+#endif
int
_cdecl
else precision = -1;
/* Handle argument size prefix */
- while (1)
+ do
{
if (chr == _T('h')) flags |= FLAG_SHORT;
else if (chr == _T('w')) flags |= FLAG_WIDECHAR;
else if (chr == _T('F')) flags |= 0; // FIXME: what is that?
else if (chr == _T('l'))
{
- flags |= FLAG_LONG;
-#if SUPPORT_LL
- if (format[0] == _T('l'))
- {
- format++;
- flags |= FLAG_INT64;
- }
-#endif
+ /* Check if this is the 2nd 'l' in a row */
+ if (format[-2] == 'l') flags |= FLAG_INT64;
+ else flags |= FLAG_LONG;
}
else if (chr == _T('I'))
{
else break;
chr = *format++;
}
+ while (USE_MULTISIZE);
/* Handle the format specifier */
digits = digits_l;
precision = 0;
break;
+#ifndef _USER32_WSPRINTF
case _T('G'):
case _T('E'):
case _T('A'):
len = _tcslen(string);
precision = 0;
break;
+#endif
case _T('d'):
case _T('i'):
if (flags & FLAG_SPECIAL)
{
prefix = &digits[16];
+#ifdef _USER32_WSPRINTF
+ fieldwidth += 2;
+#endif
}
case _T('u'):