mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 09:20:30 +00:00
[CRT]
In streamout(): fix a number of formatting bugs, round floats, fix issue with large unsigned values that were treated as signed, simplify some code. svn path=/trunk/; revision=49516
This commit is contained in:
parent
2f7608101c
commit
7d0aa25a0f
1 changed files with 24 additions and 30 deletions
|
@ -145,7 +145,7 @@ format_float(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CHECKME: Windows seems to handle a max of 17 digits(?) */
|
/* CHECKME: Windows seems to handle a max of 17 digits(?) */
|
||||||
num_digits = precision <= 17 ? precision : 17;
|
num_digits = precision <= 17 ? precision: 17;
|
||||||
|
|
||||||
/* Handle sign */
|
/* Handle sign */
|
||||||
if (fpval < 0)
|
if (fpval < 0)
|
||||||
|
@ -173,20 +173,19 @@ format_float(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val64 = (__int64)fpval;
|
|
||||||
fpval -= val64;
|
|
||||||
fpval *= pow(10., precision);
|
fpval *= pow(10., precision);
|
||||||
|
val64 = (__int64)(fpval + 0.5);
|
||||||
|
|
||||||
while (num_digits--)
|
while (num_digits-- > 0)
|
||||||
{
|
{
|
||||||
*--(*string) = digits[(__int64)fpval % 10];
|
*--(*string) = digits[val64 % 10];
|
||||||
fpval /= 10;
|
val64 /= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*--(*string) = _T('.');
|
*--(*string) = _T('.');
|
||||||
|
|
||||||
/* Gather digits in reverse order */
|
/* Digits before the decimal point */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*--(*string) = digits[val64 % base];
|
*--(*string) = digits[val64 % base];
|
||||||
|
@ -286,7 +285,7 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
int base, len, prefixlen, fieldwidth, precision, padding;
|
int base, len, prefixlen, fieldwidth, precision, padding;
|
||||||
int written = 1, written_all = 0;
|
int written = 1, written_all = 0;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
__int64 val64;
|
unsigned __int64 val64;
|
||||||
|
|
||||||
buffer[BUFFER_SIZE] = '\0';
|
buffer[BUFFER_SIZE] = '\0';
|
||||||
|
|
||||||
|
@ -297,8 +296,9 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
/* Check for end of format string */
|
/* Check for end of format string */
|
||||||
if (chr == _T('\0')) break;
|
if (chr == _T('\0')) break;
|
||||||
|
|
||||||
/* Check for 'normal' character */
|
/* Check for 'normal' character or double % */
|
||||||
if (chr != _T('%'))
|
if ((chr != _T('%')) ||
|
||||||
|
(chr = *format++) == _T('%'))
|
||||||
{
|
{
|
||||||
/* Write the character to the stream */
|
/* Write the character to the stream */
|
||||||
if ((written = streamout_char(stream, chr)) == -1) return -1;
|
if ((written = streamout_char(stream, chr)) == -1) return -1;
|
||||||
|
@ -306,26 +306,17 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for escaped % character */
|
|
||||||
if (*format == _T('%'))
|
|
||||||
{
|
|
||||||
/* Write % to the stream */
|
|
||||||
if ((written = streamout_char(stream, _T('%'))) == -1) return -1;
|
|
||||||
written_all += written;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle flags */
|
/* Handle flags */
|
||||||
flags = 0;
|
flags = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
chr = *format++;
|
|
||||||
if (chr == _T('-')) flags |= FLAG_ALIGN_LEFT;
|
if (chr == _T('-')) flags |= FLAG_ALIGN_LEFT;
|
||||||
else if (chr == _T('+')) flags |= FLAG_FORCE_SIGN;
|
else if (chr == _T('+')) flags |= FLAG_FORCE_SIGN;
|
||||||
else if (chr == _T(' ')) flags |= FLAG_FORCE_SIGNSP;
|
else if (chr == _T(' ')) flags |= FLAG_FORCE_SIGNSP;
|
||||||
else if (chr == _T('0')) flags |= FLAG_PAD_ZERO;
|
else if (chr == _T('0')) flags |= FLAG_PAD_ZERO;
|
||||||
else if (chr == _T('#')) flags |= FLAG_SPECIAL;
|
else if (chr == _T('#')) flags |= FLAG_SPECIAL;
|
||||||
else break;
|
else break;
|
||||||
|
chr = *format++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle field width modifier */
|
/* Handle field width modifier */
|
||||||
|
@ -505,13 +496,14 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
/* Use external function, one for kernel one for user mode */
|
/* Use external function, one for kernel one for user mode */
|
||||||
format_float(chr, flags, precision, &string, &prefix, &argptr);
|
format_float(chr, flags, precision, &string, &prefix, &argptr);
|
||||||
len = _tcslen(string);
|
len = _tcslen(string);
|
||||||
|
precision = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _T('d'):
|
case _T('d'):
|
||||||
case _T('i'):
|
case _T('i'):
|
||||||
val64 = va_arg_f(argptr, flags);
|
val64 = (__int64)va_arg_f(argptr, flags);
|
||||||
|
|
||||||
if (val64 < 0)
|
if ((__int64)val64 < 0)
|
||||||
{
|
{
|
||||||
val64 = -val64;
|
val64 = -val64;
|
||||||
prefix = _T("-");
|
prefix = _T("-");
|
||||||
|
@ -526,12 +518,9 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
case _T('o'):
|
case _T('o'):
|
||||||
base = 8;
|
base = 8;
|
||||||
if (flags & FLAG_SPECIAL) prefix = _T("0");
|
if (flags & FLAG_SPECIAL) prefix = _T("0");
|
||||||
|
goto case_unsigned;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case _T('u'):
|
|
||||||
val64 = (unsigned __int64)va_arg_fu(argptr, flags);
|
|
||||||
goto case_number;
|
|
||||||
|
|
||||||
case _T('p'):
|
case _T('p'):
|
||||||
precision = 2 * sizeof(void*);
|
precision = 2 * sizeof(void*);
|
||||||
flags &= ~FLAG_PAD_ZERO;
|
flags &= ~FLAG_PAD_ZERO;
|
||||||
|
@ -543,27 +532,31 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case _T('x'):
|
case _T('x'):
|
||||||
val64 = (unsigned __int64)va_arg_fu(argptr, flags);
|
|
||||||
base = 16;
|
base = 16;
|
||||||
if (flags & FLAG_SPECIAL)
|
if (flags & FLAG_SPECIAL)
|
||||||
{
|
{
|
||||||
prefix = &digits[16];
|
prefix = &digits[16];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case _T('u'):
|
||||||
|
case_unsigned:
|
||||||
|
val64 = va_arg_fu(argptr, flags);
|
||||||
|
|
||||||
case_number:
|
case_number:
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
flags |= FLAG_WIDECHAR;
|
flags |= FLAG_WIDECHAR;
|
||||||
#else
|
#else
|
||||||
flags &= ~FLAG_WIDECHAR;
|
flags &= ~FLAG_WIDECHAR;
|
||||||
#endif
|
#endif
|
||||||
|
if (precision < 0) precision = 1;
|
||||||
|
|
||||||
/* Gather digits in reverse order */
|
/* Gather digits in reverse order */
|
||||||
do
|
while (val64)
|
||||||
{
|
{
|
||||||
*--string = digits[val64 % base];
|
*--string = digits[val64 % base];
|
||||||
val64 /= base;
|
val64 /= base;
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
while (val64);
|
|
||||||
|
|
||||||
len = _tcslen(string);
|
len = _tcslen(string);
|
||||||
break;
|
break;
|
||||||
|
@ -578,11 +571,12 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr)
|
||||||
prefixlen = prefix ? _tcslen(prefix) : 0;
|
prefixlen = prefix ? _tcslen(prefix) : 0;
|
||||||
if (precision < 0) precision = 0;
|
if (precision < 0) precision = 0;
|
||||||
padding = fieldwidth - len - prefixlen - precision;
|
padding = fieldwidth - len - prefixlen - precision;
|
||||||
|
if (padding < 0) padding = 0;
|
||||||
|
|
||||||
/* Optional left space padding */
|
/* Optional left space padding */
|
||||||
if ((flags & (FLAG_ALIGN_LEFT | FLAG_PAD_ZERO)) == 0)
|
if ((flags & (FLAG_ALIGN_LEFT | FLAG_PAD_ZERO)) == 0)
|
||||||
{
|
{
|
||||||
while (padding-- > 0)
|
for (; padding > 0; padding--)
|
||||||
{
|
{
|
||||||
if ((written = streamout_char(stream, _T(' '))) == -1) return -2;
|
if ((written = streamout_char(stream, _T(' '))) == -1) return -2;
|
||||||
written_all += written;
|
written_all += written;
|
||||||
|
|
Loading…
Reference in a new issue