Christian Heimes added the comment:

Update:

I've added a platform independent implementation of stricmp and strnicmp
(case insensitive compare). It could be useful for other parts of the
code as well.

Added file: http://bugs.python.org/file8962/trunk_float_inf_nan2.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1635>
__________________________________
Index: Python/pystrcmp.c
===================================================================
--- Python/pystrcmp.c	(Revision 0)
+++ Python/pystrcmp.c	(Revision 0)
@@ -0,0 +1,26 @@
+/* Cross platform case insenstive string compare functions
+ */
+
+#include "Python.h"
+
+int
+PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size)
+{
+	if (size == 0)
+		return 0;
+	while ((--size > 0) && (tolower(*s1) == tolower(*s2))) {
+		if (!*s1++ || !*s2++)
+			break;
+	}
+	return tolower(*s1) - tolower(*s2);
+}
+
+int
+PyOS_mystricmp(const char *s1, const char *s2)
+{
+	while (*s1 && (tolower(*s1++) == tolower(*s2++))) {
+		;
+	}
+	return (tolower(*s1) - tolower(*s2));
+}
+

Eigenschaftsänderungen: Python/pystrcmp.c
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: PCbuild/pythoncore.vcproj
===================================================================
--- PCbuild/pythoncore.vcproj	(Revision 59511)
+++ PCbuild/pythoncore.vcproj	(Arbeitskopie)
@@ -701,6 +701,10 @@
 			RelativePath="..\Python\pystate.c">
 		</File>
 		<File
+			RelativePath="..\Python\pystrcmp.c"
+			>
+		</File>
+		<File
 			RelativePath="..\Python\pystrtod.c">
 		</File>
 		<File
Index: Include/pyport.h
===================================================================
--- Include/pyport.h	(Revision 59511)
+++ Include/pyport.h	(Arbeitskopie)
@@ -393,6 +393,15 @@
 #define Py_HUGE_VAL HUGE_VAL
 #endif
 
+/* Py_NAN
+ * Some value that evaluates to a NaN. On IEEE 754 platforms INF*0 or
+ * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform
+ * doesn't support NaNs.
+ */
+#if !defined(Py_NAN) && !defined(Py_NO_NAN)
+#define Py_NAN Py_HUGE_VAL * 0
+#endif
+
 /* Py_OVERFLOWED(X)
  * Return 1 iff a libm function overflowed.  Set errno to 0 before calling
  * a libm function, and invoke this macro after, passing the function
Index: Include/pystrcmp.h
===================================================================
--- Include/pystrcmp.h	(Revision 0)
+++ Include/pystrcmp.h	(Revision 0)
@@ -0,0 +1,23 @@
+#ifndef Py_STRCMP_H
+#define Py_STRCMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(int) PyOS_mystrnicmp(const char *, const char *, Py_ssize_t);
+PyAPI_FUNC(int) PyOS_mystricmp(const char *, const char *);
+
+#ifdef MS_WINDOWS
+#define PyOS_strnicmp strnicmp
+#define PyOS_stricmp stricmp
+#else
+#define PyOS_strnicmp PyOS_mystrnicmp
+#define PyOS_stricmp PyOS_mystricmp
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_STRCMP_H */

Eigenschaftsänderungen: Include/pystrcmp.h
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: Include/Python.h
===================================================================
--- Include/Python.h	(Revision 59511)
+++ Include/Python.h	(Arbeitskopie)
@@ -129,6 +129,7 @@
 #include "eval.h"
 
 #include "pystrtod.h"
+#include "pystrcmp.h"
 
 /* _Py_Mangle is defined in compile.c */
 PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
Index: Objects/floatobject.c
===================================================================
--- Objects/floatobject.c	(Revision 59511)
+++ Objects/floatobject.c	(Arbeitskopie)
@@ -128,7 +128,7 @@
 PyObject *
 PyFloat_FromString(PyObject *v, char **pend)
 {
-	const char *s, *last, *end;
+	const char *s, *last, *end, *sp;
 	double x;
 	char buffer[256]; /* for errors */
 #ifdef Py_USING_UNICODE
@@ -171,6 +171,7 @@
 		PyErr_SetString(PyExc_ValueError, "empty string for float()");
 		return NULL;
 	}
+	sp = s;
 	/* We don't care about overflow or underflow.  If the platform supports
 	 * them, infinities and signed zeroes (on underflow) are fine.
 	 * However, strtod can return 0 for denormalized numbers, where atof
@@ -186,7 +187,26 @@
 	   byte at the end of the string, when the input is inf(inity). */
 	if (end > last)
 		end = last;
+	/* Check for inf and nan. This is done late because it rarely happens. */
 	if (end == s) {
+		char *p = sp;
+		int sign = 1;
+
+		if (*p == '-') {
+			sign = -1;
+			p++;
+		}
+		if (*p == '+') {
+			p++;
+		}
+		if (PyOS_strnicmp(p, "inf", 4) == 0) {
+			return PyFloat_FromDouble(sign * HUGE_VAL);
+		}
+#ifdef Py_NAN
+		if(PyOS_strnicmp(p, "nan", 4) == 0) {
+			return PyFloat_FromDouble(Py_NAN);
+		}
+#endif
 		PyOS_snprintf(buffer, sizeof(buffer),
 			      "invalid literal for float(): %.200s", s);
 		PyErr_SetString(PyExc_ValueError, buffer);
@@ -271,6 +291,8 @@
 {
 	register char *cp;
 	char format[32];
+	int i;
+
 	/* Subroutine for float_repr and float_print.
 	   We want float numbers to be recognizable as such,
 	   i.e., they should contain a decimal point or an exponent.
@@ -293,7 +315,39 @@
 		*cp++ = '.';
 		*cp++ = '0';
 		*cp++ = '\0';
+		return;
 	}
+	/* checking the next three items should be more than enough to 
+	 * detect inf or nan, even on Windows. We check for inf or nan
+	 * at last because they are rare cases.
+	 */
+	for (i=0; *cp != '\0' && i<3; cp++, i++) {
+		if (isdigit(Py_CHARMASK(*cp)) || *cp == '.')
+			continue;
+		/* found something that is neither a digit nor point
+		 * it might be a NaN or INF
+		 */
+#ifdef Py_NAN
+		if (Py_IS_NAN(v->ob_fval)) {
+			cp = buf;
+			*cp++ = 'n';
+			*cp++ = 'a';
+			*cp++ = 'n';
+			*cp++ = '\0';
+		}
+#endif
+		if (Py_IS_INFINITY(v->ob_fval)) {
+			cp = buf;
+			if (*cp == '-')
+				cp++;
+			*cp++ = 'i';
+			*cp++ = 'n';
+			*cp++ = 'f';
+			*cp++ = '\0';
+		}
+		break;
+	}
+
 }
 
 /* XXX PyFloat_AsStringEx should not be a public API function (for one
Index: Lib/test/test_float.py
===================================================================
--- Lib/test/test_float.py	(Revision 59511)
+++ Lib/test/test_float.py	(Arbeitskopie)
@@ -3,6 +3,12 @@
 import os
 from test import test_support
 
+def isinf(x):
+    return x * 0.5 == x
+    
+def isnan(x):
+    return x != x
+
 class FormatFunctionsTestCase(unittest.TestCase):
 
     def setUp(self):
@@ -128,13 +134,78 @@
             self.assertEqual(v, eval(repr(v)))
         floats_file.close()
 
+# Beginning with Python 2.6 float has cross platform compatible
+# ways to create and representate inf and nan
+class InfNanTest(unittest.TestCase):
+    def test_inf_from_str(self):
+        self.assert_(isinf(float("inf")))
+        self.assert_(isinf(float("+inf")))
+        self.assert_(isinf(float("-inf")))
 
+        self.assertEqual(repr(float("inf")), "inf")
+        self.assertEqual(repr(float("+inf")), "inf")
+        self.assertEqual(repr(float("-inf")), "-inf")
+
+        self.assertEqual(repr(float("INF")), "inf")
+        self.assertEqual(repr(float("+Inf")), "inf")
+        self.assertEqual(repr(float("-iNF")), "-inf")
+        
+        self.assertEqual(str(float("inf")), "inf")
+        self.assertEqual(str(float("+inf")), "inf")
+        self.assertEqual(str(float("-inf")), "-inf")
+
+        self.assertRaises(ValueError, float, "info")
+        self.assertRaises(ValueError, float, "+info")
+        self.assertRaises(ValueError, float, "-info")
+        self.assertRaises(ValueError, float, "in")
+        self.assertRaises(ValueError, float, "+in")
+        self.assertRaises(ValueError, float, "-in")
+        
+    def test_inf_as_str(self):
+        self.assertEqual(repr(1e300 * 1e300), "inf")
+        self.assertEqual(repr(-1e300 * 1e300), "-inf")
+        
+        self.assertEqual(str(1e300 * 1e300), "inf")
+        self.assertEqual(str(-1e300 * 1e300), "-inf")
+
+    def test_nan_from_str(self):
+        self.assert_(isnan(float("nan")))
+        self.assert_(isnan(float("+nan")))
+        self.assert_(isnan(float("-nan")))
+
+        self.assertEqual(repr(float("nan")), "nan")
+        self.assertEqual(repr(float("+nan")), "nan")
+        self.assertEqual(repr(float("-nan")), "nan")
+
+        self.assertEqual(repr(float("NAN")), "nan")
+        self.assertEqual(repr(float("+NAn")), "nan")
+        self.assertEqual(repr(float("-NaN")), "nan")
+        
+        self.assertEqual(str(float("nan")), "nan")
+        self.assertEqual(str(float("+nan")), "nan")
+        self.assertEqual(str(float("-nan")), "nan")
+
+        self.assertRaises(ValueError, float, "nana")
+        self.assertRaises(ValueError, float, "+nana")
+        self.assertRaises(ValueError, float, "-nana")
+        self.assertRaises(ValueError, float, "na")
+        self.assertRaises(ValueError, float, "+na")
+        self.assertRaises(ValueError, float, "-na")
+
+    def test_nan_as_str(self):
+        self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
+        self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
+        
+        self.assertEqual(str(1e300 * 1e300 * 0), "nan")
+        self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
+
 def test_main():
     test_support.run_unittest(
         FormatFunctionsTestCase,
         UnknownFormatTestCase,
         IEEEFormatTestCase,
-        #ReprTestCase
+        ReprTestCase,
+        InfNanTest,
         )
 
 if __name__ == '__main__':
Index: Makefile.pre.in
===================================================================
--- Makefile.pre.in	(Revision 59511)
+++ Makefile.pre.in	(Arbeitskopie)
@@ -275,6 +275,7 @@
 		Python/sysmodule.o \
 		Python/traceback.o \
 		Python/getopt.o \
+		Python/pystrcmp.o \
 		Python/pystrtod.o \
 		Python/$(DYNLOADFILE) \
 		$(LIBOBJS) \
@@ -554,6 +555,8 @@
 		Include/pymem.h \
 		Include/pyport.h \
 		Include/pystate.h \
+		Include/pystrtod.h \
+		Include/pystrcmp.h \
 		Include/pythonrun.h \
 		Include/rangeobject.h \
                 Include/setobject.h \
Index: PCbuild8/pythoncore/pythoncore.vcproj
===================================================================
--- PCbuild8/pythoncore/pythoncore.vcproj	(Revision 59511)
+++ PCbuild8/pythoncore/pythoncore.vcproj	(Arbeitskopie)
@@ -736,6 +736,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Python\pystrcmp.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Python\pystrtod.c"
 				>
 			</File>
@@ -1194,6 +1198,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Include\pystrcmp.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Include\pystrtod.h"
 				>
 			</File>
Index: PCbuild9/pythoncore.vcproj
===================================================================
--- PCbuild9/pythoncore.vcproj	(Revision 59511)
+++ PCbuild9/pythoncore.vcproj	(Arbeitskopie)
@@ -875,6 +875,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Include\pystrcmp.h"
+				>
+			</File>
+			<File
 				RelativePath="..\Include\pystrtod.h"
 				>
 			</File>
@@ -1715,6 +1719,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Python\pystrcmp.c"
+				>
+			</File>
+			<File
 				RelativePath="..\Python\pystrtod.c"
 				>
 			</File>
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to