msvcrt: Fix Inf and NaN handling in printf function.

This commit is contained in:
Piotr Caban 2013-09-16 15:05:16 +02:00 committed by Alexandre Julliard
parent 57ed5bf32e
commit 6594212dd6
2 changed files with 75 additions and 2 deletions

View File

@ -537,6 +537,27 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
int len = flags.Precision + 10;
double val = pf_args(args_ctx, pos, VT_R8, valist).get_double;
int r;
BOOL inf = FALSE, nan = FALSE;
if(isinf(val))
inf = TRUE;
else if(isnan(val))
nan = TRUE; /* FIXME: NaN value may be displayed as #IND or #QNAN */
if(inf || nan) {
if(nan || val<0)
flags.Sign = '-';
if(flags.Format=='g' || flags.Format=='G')
val = 1.1234; /* fraction will be overwritten with #INF or #IND string */
else
val = 1;
if(flags.Format=='a') {
if(flags.Precision==-1)
flags.Precision = 6; /* strlen("#INF00") */
}
}
if(flags.Format=='f') {
if(val>-10.0 && val<10.0)
@ -566,9 +587,25 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
FUNC_NAME(pf_fixup_exponent)(tmp);
decimal_point = strchr(tmp, '.');
if(decimal_point)
if(decimal_point) {
*decimal_point = *locinfo->lconv->decimal_point;
if(inf || nan) {
static const char inf_str[] = "#INF";
static const char ind_str[] = "#IND";
for(i=1; i<=sizeof(inf ? inf_str : ind_str); i++) {
if(decimal_point[i]<'0' || decimal_point[i]>'9')
break;
decimal_point[i] = inf ? inf_str[i-1] : ind_str[i-1];
}
if(i!=sizeof(inf_str) && i!=1)
decimal_point[i-1]++;
}
}
len = strlen(tmp);
i = FUNC_NAME(pf_fill)(pf_puts, puts_ctx, len, &flags, TRUE);
if(i < 0)

View File

@ -27,6 +27,7 @@
#include <stdio.h>
#include <errno.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
@ -81,7 +82,7 @@ static void test_sprintf( void )
{
char buffer[100];
const char *format;
double pnumber=789456123;
double pnumber=789456123, inf, nan;
int x, r;
WCHAR wide[] = { 'w','i','d','e',0};
@ -639,6 +640,41 @@ static void test_sprintf( void )
ok(!strcmp(buffer,"123"), "failed: \"%s\"\n", buffer);
r = sprintf(buffer, format, 0x12345);
ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer);
nan = 0.0;
inf = 1.0/nan;
nan = sqrt(-1);
format = "%lf";
r = sprintf(buffer, format, nan);
ok(r==9, "r = %d\n", r);
ok(!strcmp(buffer, "-1.#IND00"), "failed: \"%s\"\n", buffer);
r = sprintf(buffer, format, inf);
ok(r==8, "r = %d\n", r);
ok(!strcmp(buffer, "1.#INF00"), "failed: \"%s\"\n", buffer);
format = "%le";
r = sprintf(buffer, format, nan);
ok(r==14, "r = %d\n", r);
ok(!strcmp(buffer, "-1.#IND00e+000"), "failed: \"%s\"\n", buffer);
r = sprintf(buffer, format, inf);
ok(r==13, "r = %d\n", r);
ok(!strcmp(buffer, "1.#INF00e+000"), "failed: \"%s\"\n", buffer);
format = "%lg";
r = sprintf(buffer, format, nan);
ok(r==7, "r = %d\n", r);
ok(!strcmp(buffer, "-1.#IND"), "failed: \"%s\"\n", buffer);
r = sprintf(buffer, format, inf);
ok(r==6, "r = %d\n", r);
ok(!strcmp(buffer, "1.#INF"), "failed: \"%s\"\n", buffer);
format = "%010.2lf";
r = sprintf(buffer, format, nan);
ok(r==10, "r = %d\n", r);
ok(!strcmp(buffer, "-000001.#J"), "failed: \"%s\"\n", buffer);
r = sprintf(buffer, format, inf);
ok(r==10, "r = %d\n", r);
ok(!strcmp(buffer, "0000001.#J"), "failed: \"%s\"\n", buffer);
}
static void test_swprintf( void )