Piotr Caban : msvcrt: Fix Inf and NaN handling in printf function.
Alexandre Julliard
julliard at winehq.org
Mon Sep 16 16:57:23 CDT 2013
Module: wine
Branch: master
Commit: 6594212dd6bbf93d17cedb82eacc6a81bd066fe3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6594212dd6bbf93d17cedb82eacc6a81bd066fe3
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Sep 16 15:05:16 2013 +0200
msvcrt: Fix Inf and NaN handling in printf function.
---
dlls/msvcrt/printf.h | 39 ++++++++++++++++++++++++++++++++++++++-
dlls/msvcrt/tests/printf.c | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h
index 0fe27f7..dd36f59 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 e61ca5f..24bc401 100644
--- a/dlls/msvcrt/tests/printf.c
+++ b/dlls/msvcrt/tests/printf.c
@@ -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 )
More information about the wine-cvs
mailing list