[Python-checkins] r75722 - in python/trunk: Include/pystrtod.h Misc/NEWS Objects/stringobject.c Objects/unicodeobject.c Python/pystrtod.c

eric.smith python-checkins at python.org
Mon Oct 26 18:46:18 CET 2009


Author: eric.smith
Date: Mon Oct 26 18:46:17 2009
New Revision: 75722

Log:
Finished removing _PyOS_double_to_string, as mentioned in issue 7117.

Modified:
   python/trunk/Include/pystrtod.h
   python/trunk/Misc/NEWS
   python/trunk/Objects/stringobject.c
   python/trunk/Objects/unicodeobject.c
   python/trunk/Python/pystrtod.c

Modified: python/trunk/Include/pystrtod.h
==============================================================================
--- python/trunk/Include/pystrtod.h	(original)
+++ python/trunk/Include/pystrtod.h	Mon Oct 26 18:46:17 2009
@@ -13,13 +13,6 @@
 PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len,
                                       const char *format, double d);
 
-/* Use PyOS_double_to_string instead. It's the same, except it allocates
-   the appropriately sized buffer and returns it. This function will go
-   away in Python 2.8 and 3.2. */
-PyAPI_FUNC(void) _PyOS_double_to_string(char *buf, size_t buf_len, double val,
-                                        char format_code, int precision,
-                                        int flags, int* type);
-
 /* The caller is responsible for calling PyMem_Free to free the buffer
    that's is returned. */
 PyAPI_FUNC(char *) PyOS_double_to_string(double val,

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Mon Oct 26 18:46:17 2009
@@ -12,6 +12,10 @@
 Core and Builtins
 -----------------
 
+- Removed _PyOS_double_to_string. Use PyOS_double_to_string
+  instead. This is in preparation for (but not strictly related to)
+  issue #7117, short float repr.
+
 - Issue #1087418: Boost performance of bitwise operations for longs.
 
 - Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which

Modified: python/trunk/Objects/stringobject.c
==============================================================================
--- python/trunk/Objects/stringobject.c	(original)
+++ python/trunk/Objects/stringobject.c	Mon Oct 26 18:46:17 2009
@@ -4336,7 +4336,10 @@
 formatfloat(char *buf, size_t buflen, int flags,
             int prec, int type, PyObject *v)
 {
+	char *tmp;
 	double x;
+	Py_ssize_t len;
+
 	x = PyFloat_AsDouble(v);
 	if (x == -1.0 && PyErr_Occurred()) {
 		PyErr_Format(PyExc_TypeError, "float argument required, "
@@ -4381,9 +4384,20 @@
 			"formatted float is too long (precision too large?)");
 		return -1;
 	}
-	_PyOS_double_to_string(buf, buflen, x, type, prec,
-                            (flags&F_ALT)?Py_DTSF_ALT:0, NULL);
-	return (int)strlen(buf);
+	tmp = PyOS_double_to_string(x, type, prec,
+				    (flags&F_ALT)?Py_DTSF_ALT:0, NULL);
+	if (!tmp)
+		return -1;
+	len = strlen(tmp);
+	if (len >= buflen) {
+		PyErr_SetString(PyExc_OverflowError,
+			"formatted float is too long (precision too large?)");
+		PyMem_Free(tmp);
+		return -1;
+	}
+	strcpy(buf, tmp);
+	PyMem_Free(tmp);
+	return (int)len;
 }
 
 /* _PyString_FormatLong emulates the format codes d, u, o, x and X, and

Modified: python/trunk/Objects/unicodeobject.c
==============================================================================
--- python/trunk/Objects/unicodeobject.c	(original)
+++ python/trunk/Objects/unicodeobject.c	Mon Oct 26 18:46:17 2009
@@ -8289,18 +8289,6 @@
 }
 
 static int
-doubletounicode(Py_UNICODE *buffer, size_t len, int format_code,
-                int precision, int flags, double x)
-{
-    Py_ssize_t result;
-
-    _PyOS_double_to_string((char *)buffer, len, x, format_code, precision,
-                           flags, NULL);
-    result = strtounicode(buffer, (char *)buffer);
-    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
-}
-
-static int
 longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
 {
     Py_ssize_t result;
@@ -8323,6 +8311,8 @@
             PyObject *v)
 {
     double x;
+    Py_ssize_t result;
+    char *tmp;
 
     x = PyFloat_AsDouble(v);
     if (x == -1.0 && PyErr_Occurred())
@@ -8365,8 +8355,15 @@
                         "formatted float is too long (precision too large?)");
         return -1;
     }
-    return doubletounicode(buf, buflen, type, prec,
-                           (flags&F_ALT)?Py_DTSF_ALT:0, x);
+
+    tmp = PyOS_double_to_string(x, type, prec,
+                                (flags&F_ALT)?Py_DTSF_ALT:0, NULL);
+    if (!tmp)
+        return -1;
+
+    result = strtounicode(buf, tmp);
+    PyMem_Free(tmp);
+    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
 }
 
 static PyObject*

Modified: python/trunk/Python/pystrtod.c
==============================================================================
--- python/trunk/Python/pystrtod.c	(original)
+++ python/trunk/Python/pystrtod.c	Mon Oct 26 18:46:17 2009
@@ -392,25 +392,6 @@
 }
 
 
-Py_LOCAL_INLINE(void)
-ensure_sign(char* buffer, size_t buf_size)
-{
-	size_t len;
-
-	if (buffer[0] == '-')
-		/* Already have a sign. */
-		return;
-
-	/* Include the trailing 0 byte. */
-	len = strlen(buffer)+1;
-	if (len >= buf_size+1)
-		/* No room for the sign, don't do anything. */
-		return;
-
-	memmove(buffer+1, buffer, len);
-	buffer[0] = '+';
-}
-
 /* From the C99 standard, section 7.19.6:
 The exponent always contains at least two digits, and only as many more digits
 as necessary to represent the exponent.
@@ -739,122 +720,6 @@
 	return _PyOS_ascii_formatd(buffer, buf_size, format, d, -1);
 }
 
-PyAPI_FUNC(void)
-_PyOS_double_to_string(char *buf, size_t buf_len, double val,
-		    char format_code, int precision,
-		    int flags, int *ptype)
-{
-	char format[32];
-	int t;
-	int upper = 0;
-
-	if (buf_len < 1) {
-		assert(0);
-		/* There's no way to signal this error. Just return. */
-		return;
-	}
-	buf[0] = 0;
-
-	/* Validate format_code, and map upper and lower case */
-	switch (format_code) {
-	case 'e':          /* exponent */
-	case 'f':          /* fixed */
-	case 'g':          /* general */
-		break;
-	case 'E':
-		upper = 1;
-		format_code = 'e';
-		break;
-	case 'F':
-		upper = 1;
-		format_code = 'f';
-		break;
-	case 'G':
-		upper = 1;
-		format_code = 'g';
-		break;
-	case 'r':          /* repr format */
-		/* Supplied precision is unused, must be 0. */
-		if (precision != 0)
-			return;
-		/* The repr() precision (17 significant decimal digits) is the
-		   minimal number that is guaranteed to have enough precision
-		   so that if the number is read back in the exact same binary
-		   value is recreated.  This is true for IEEE floating point
-		   by design, and also happens to work for all other modern
-		   hardware. */
-		precision = 17;
-		format_code = 'g';
-		break;
-	default:
-		assert(0);
-		return;
-	}
-
-	/* Check for buf too small to fit "-inf". Other buffer too small
-	   conditions are dealt with when converting or formatting finite
-	   numbers. */
-	if (buf_len < 5) {
-		assert(0);
-		return;
-	}
-
-	/* Handle nan and inf. */
-	if (Py_IS_NAN(val)) {
-		strcpy(buf, "nan");
-		t = Py_DTST_NAN;
-	} else if (Py_IS_INFINITY(val)) {
-		if (copysign(1., val) == 1.)
-			strcpy(buf, "inf");
-		else
-			strcpy(buf, "-inf");
-		t = Py_DTST_INFINITE;
-	} else {
-		t = Py_DTST_FINITE;
-
-		/* Build the format string. */
-		PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
-			      (flags & Py_DTSF_ALT ? "#" : ""), precision,
-			      format_code);
-
-		/* Have PyOS_snprintf do the hard work. */
-		PyOS_snprintf(buf, buf_len, format, val);
-
-		/* Do various fixups on the return string */
-
-		/* Get the current locale, and find the decimal point string.
-		   Convert that string back to a dot. */
-		change_decimal_from_locale_to_dot(buf);
-
-		/* If an exponent exists, ensure that the exponent is at least
-		   MIN_EXPONENT_DIGITS digits, providing the buffer is large
-		   enough for the extra zeros.  Also, if there are more than
-		   MIN_EXPONENT_DIGITS, remove as many zeros as possible until
-		   we get back to MIN_EXPONENT_DIGITS */
-		ensure_minimum_exponent_length(buf, buf_len);
-
-		/* Possibly make sure we have at least one character after the
-		   decimal point (and make sure we have a decimal point). */
-		if (flags & Py_DTSF_ADD_DOT_0)
-			buf = ensure_decimal_point(buf, buf_len, precision);
-	}
-
-	/* Add the sign if asked and the result isn't negative. */
-	if (flags & Py_DTSF_SIGN && buf[0] != '-')
-		ensure_sign(buf, buf_len);
-
-	if (upper) {
-		/* Convert to upper case. */
-		char *p;
-		for (p = buf; *p; p++)
-			*p = Py_TOUPPER(*p);
-	}
-
-	if (ptype)
-		*ptype = t;
-}
-
-
 #ifdef PY_NO_SHORT_FLOAT_REPR
 
 /* The fallback code to use if _Py_dg_dtoa is not available. */


More information about the Python-checkins mailing list