[geos-commits] r4037 - trunk/src/io

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Nov 26 07:33:49 PST 2014


Author: mloskot
Date: 2014-11-26 07:33:49 -0800 (Wed, 26 Nov 2014)
New Revision: 4037

Modified:
   trunk/src/io/StringTokenizer.cpp
Log:
Fix MSVC handling of strtod (Thanks to Paul Kohut for the patch submitted as part of https://github.com/libgeos/libgeos/pull/31/)
Apparently, it solves the long running INF/NAN parsing issues on Windows and enables GEOSisValidDetail test pass again.
It should also solve problems reported as part of ticket #509.

Modified: trunk/src/io/StringTokenizer.cpp
===================================================================
--- trunk/src/io/StringTokenizer.cpp	2014-11-26 14:58:35 UTC (rev 4036)
+++ trunk/src/io/StringTokenizer.cpp	2014-11-26 15:33:49 UTC (rev 4037)
@@ -37,6 +37,41 @@
 	iter=str.begin();
 }
 
+double strtod_with_vc_fix(const char * str, char ** str_end)
+{
+	double dbl = strtod(str, str_end);
+#if _MSC_VER && !__INTEL_COMPILER
+	// Special handling of NAN and INF in MSVC, where strtod returns 0.0
+	// for NAN and INF.		
+	// This fixes failing test GEOSisValidDetail::test<3>, maybe others
+	// as well.
+	// Note: this hack is not robust, Boost lexical_cast or
+	// std::stod (C++11) would be better.
+	if (*str_end[0] != '\0')
+	{
+		char sign = 0;
+		const char *pos = str;
+		if (*pos == '+' || *pos == '-')
+			sign = *pos++;
+
+		if (stricmp(pos, "inf") == 0)
+		{
+			if (!sign || sign == '+')
+				dbl = std::numeric_limits<double>::infinity();
+			else
+				dbl = -(std::numeric_limits<double>::infinity)();
+			*str_end[0] = '\0';
+		}
+		else if (stricmp(pos, "nan") == 0)
+		{
+			dbl = std::numeric_limits<double>::quiet_NaN();
+			*str_end[0] = '\0';
+		}
+	}
+#endif
+	return dbl;
+}
+
 /*public*/
 int
 StringTokenizer::nextToken()
@@ -76,7 +111,7 @@
 		iter=str.begin()+pos;
 	}
 	char *stopstring;
-	double dbl=strtod(tok.c_str(),&stopstring);
+	double dbl=strtod_with_vc_fix(tok.c_str(),&stopstring);
 	if (*stopstring=='\0') {
 		ntok=dbl;
 		stok="";
@@ -124,7 +159,7 @@
 	}
 
 	char *stopstring;
-	double dbl=strtod(tok.c_str(),&stopstring);
+	double dbl = strtod_with_vc_fix(tok.c_str(), &stopstring);
 	if (*stopstring=='\0') {
 		ntok=dbl;
 		stok="";



More information about the geos-commits mailing list