]> granicus.if.org Git - python/commitdiff
Finished removing _PyOS_double_to_string, as mentioned in issue 7117.
authorEric Smith <eric@trueblade.com>
Mon, 26 Oct 2009 17:46:17 +0000 (17:46 +0000)
committerEric Smith <eric@trueblade.com>
Mon, 26 Oct 2009 17:46:17 +0000 (17:46 +0000)
Include/pystrtod.h
Misc/NEWS
Objects/stringobject.c
Objects/unicodeobject.c
Python/pystrtod.c

index 106448bc375ac2c9eadc5dd034dd13ef77faf2cf..97578d81d609248c5de975c6588a0620f5ac19a3 100644 (file)
@@ -13,13 +13,6 @@ PyAPI_FUNC(double) PyOS_ascii_atof(const char *str);
 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,
index 2810cabec998c6948f7cb44a41a610a76fa2c561..368ed3e4af19c38caf917d92ceda9349ff11214f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
 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
index 70d90d4ee75896c4c88645bbd48b15c767825017..b5faf13fdaec5c099a6aba1c7513d743325e4793 100644 (file)
@@ -4336,7 +4336,10 @@ Py_LOCAL_INLINE(int)
 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 @@ formatfloat(char *buf, size_t buflen, int flags,
                        "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
index 6eac358b67085a971176b691ac0ec0241e75460a..65c10b1cbd9b99bc0900c8419544ef0ddc3eae29 100644 (file)
@@ -8288,18 +8288,6 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
     return len;
 }
 
-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)
 {
@@ -8323,6 +8311,8 @@ formatfloat(Py_UNICODE *buf,
             PyObject *v)
 {
     double x;
+    Py_ssize_t result;
+    char *tmp;
 
     x = PyFloat_AsDouble(v);
     if (x == -1.0 && PyErr_Occurred())
@@ -8365,8 +8355,15 @@ formatfloat(Py_UNICODE *buf,
                         "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*
index 2f34b9b6c7fd1fe65ce31270635b7a0b172cae24..64bf73daecdb61513ae9cf482cac067465341721 100644 (file)
@@ -392,25 +392,6 @@ change_decimal_from_locale_to_dot(char* buffer)
 }
 
 
-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 @@ PyOS_ascii_formatd(char       *buffer,
        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. */