diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h index 0fe27f71c57..dd36f59a849 100644 --- a/dlls/msvcrt/printf.h +++ b/dlls/msvcrt/printf.h @@ -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) diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c index e61ca5f6636..24bc401d671 100644 --- a/dlls/msvcrt/tests/printf.c +++ b/dlls/msvcrt/tests/printf.c @@ -27,6 +27,7 @@ #include #include +#include #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 )