From e73250fdc799bf1d7fcf738e4d7b6fe67166dd2f Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 28 May 2006 05:17:19 +0000 Subject: [PATCH] almost last commit for full support of %e %E %f %g %G, left todo is write the numberf function svn path=/trunk/; revision=22084 --- reactos/lib/rtl/sprintf.c | 75 ++++++++++++++++++++++++++++++++++-- reactos/lib/rtl/swprintf.c | 78 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 6 deletions(-) diff --git a/reactos/lib/rtl/sprintf.c b/reactos/lib/rtl/sprintf.c index 01740a8a368..4e33439c4ff 100644 --- a/reactos/lib/rtl/sprintf.c +++ b/reactos/lib/rtl/sprintf.c @@ -27,6 +27,42 @@ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; +} double_t; + +static +__inline +int +_isinf(double __x) +{ + union + { + double* __x; + double_t* x; + } x; + + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 )); +} + +static +__inline +int +_isnan(double __x) +{ + union + { + double* __x; + double_t* x; + } x; + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 )); +} + static __inline @@ -450,9 +486,42 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) case 'f': case 'g': case 'G': - _double = (double)va_arg(args, double); - str = number(str, end, (int)_double, base, field_width, precision, flags); - continue; + _double = (double)va_arg(args, double); + if ( _isnan(_double) ) { + s = "Nan"; + len = 3; + while ( len > 0 ) { + if (str <= end) + *str = *s++; + ++str; + len --; + } + } else if ( _isinf(_double) < 0 ) { + s = "-Inf"; + len = 4; + while ( len > 0 ) { + if (str <= end) + *str = *s++; + ++str; + len --; + } + } else if ( _isinf(_double) > 0 ) { + s = "+Inf"; + len = 4; + while ( len > 0 ) { + if (str <= end) + *str = *s++; + ++str; + len --; + } + } else { + if ( precision == -1 ) + precision = 6; + /* FIXME the float version of number */ + str = number(str, end, (int)_double, base, field_width, precision, flags); + } + + continue; /* integer number formats - set up the flags and "break" */ diff --git a/reactos/lib/rtl/swprintf.c b/reactos/lib/rtl/swprintf.c index 717ed5a122c..04fddc884d9 100644 --- a/reactos/lib/rtl/swprintf.c +++ b/reactos/lib/rtl/swprintf.c @@ -27,6 +27,42 @@ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; +} double_t; + +static +__inline +int +_isinf(double __x) +{ + union + { + double* __x; + double_t* x; + } x; + + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 )); +} + +static +__inline +int +_isnan(double __x) +{ + union + { + double* __x; + double_t* x; + } x; + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 )); +} + static __inline @@ -245,6 +281,7 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) wchar_t * str, * end; const char *s; const wchar_t *sw; + const wchar_t *ss; double _double; int flags; /* flags to number() */ @@ -446,9 +483,44 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) case 'f': case 'g': case 'G': - _double = (double)va_arg(args, double); - str = number(str, end, (int)_double, base, field_width, precision, flags); - continue; + _double = (double)va_arg(args, double); + + if ( _isnan(_double) ) { + ss = L"Nan"; + len = 3; + while ( len > 0 ) { + if (str <= end) + *str = *ss++; + ++str; + len --; + } + } else if ( _isinf(_double) < 0 ) { + ss = L"-Inf"; + len = 4; + while ( len > 0 ) { + if (str <= end) + *str = *ss++; + ++str; + len --; + } + } else if ( _isinf(_double) > 0 ) { + ss = L"+Inf"; + len = 4; + while ( len > 0 ) { + if (str <= end) + *str = *ss++; + ++str; + len --; + } + } else { + if ( precision == -1 ) + precision = 6; + /* FIXME the float version of number */ + str = number(str, end, (int)_double, base, field_width, precision, flags); + } + + continue; + /* integer number formats - set up the flags and "break" */