[Python-checkins] cpython: fill_char() can now propagate an error

victor.stinner python-checkins at python.org
Wed Sep 28 22:08:38 CEST 2011


http://hg.python.org/cpython/rev/cf3557b65ae1
changeset:   72495:cf3557b65ae1
user:        Victor Stinner <victor.stinner at haypocalc.com>
date:        Wed Sep 28 21:50:16 2011 +0200
summary:
  fill_char() can now propagate an error

files:
  Python/formatter_unicode.c |  72 ++++++++++++++++---------
  1 files changed, 47 insertions(+), 25 deletions(-)


diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -341,7 +341,7 @@
 
     /* Pad on right. */
     if (n_rpadding)
-        unicode_fill(s, start + nchars + n_lpadding, 
+        unicode_fill(s, start + nchars + n_lpadding,
                      start + nchars + n_lpadding + n_rpadding, fill_char);
 
     /* Pointer to the user content. */
@@ -501,7 +501,7 @@
         spec->n_grouped_digits = 0;
     else
         spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
-            PyUnicode_1BYTE_KIND, NULL, 0, NULL, 
+            PyUnicode_1BYTE_KIND, NULL, 0, NULL,
             spec->n_digits, spec->n_min_width,
             locale->grouping, locale->thousands_sep);
 
@@ -541,11 +541,12 @@
 
 /* Fill in the digit parts of a numbers's string representation,
    as determined in calc_number_widths().
-   No error checking, since we know the buffer is the correct size. */
-static void
+   Return -1 on error, or 0 on success. */
+static int
 fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
             PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end,
-            PyObject *prefix, Py_ssize_t p_start, Py_UCS4 fill_char,
+            PyObject *prefix, Py_ssize_t p_start,
+            Py_UCS4 fill_char,
             LocaleInfo *locale, int toupper)
 {
     /* Used to keep track of digits, decimal, and remainder. */
@@ -589,11 +590,8 @@
         char *pdigits = PyUnicode_DATA(digits);
         if (PyUnicode_KIND(digits) < kind) {
             pdigits = _PyUnicode_AsKind(digits, kind);
-            if (pdigits == NULL) {
-                /* XXX report exception */
-                Py_FatalError("out of memory");
-                return;
-            }
+            if (pdigits == NULL)
+                return -1;
         }
 #ifndef NDEBUG
         r =
@@ -640,6 +638,7 @@
         unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
         pos += spec->n_rpadding;
     }
+    return 0;
 }
 
 static char no_grouping[1] = {CHAR_MAX};
@@ -765,6 +764,7 @@
     Py_ssize_t prefix;
     NumberFieldWidths spec;
     long x;
+    int err;
 
     /* Locale settings, either from the actual locale or
        from a hard-code pseudo-locale */
@@ -886,10 +886,13 @@
         goto done;
 
     /* Populate the memory. */
-    fill_number(result, 0, &spec, tmp, inumeric_chars, inumeric_chars + n_digits,
-                tmp, prefix,
-                format->fill_char == '\0' ? ' ' : format->fill_char,
-                &locale, format->type == 'X');
+    err = fill_number(result, 0, &spec,
+                      tmp, inumeric_chars, inumeric_chars + n_digits,
+                      tmp, prefix,
+                      format->fill_char == '\0' ? ' ' : format->fill_char,
+                      &locale, format->type == 'X');
+    if (err)
+        Py_CLEAR(result);
 
 done:
     Py_XDECREF(tmp);
@@ -929,6 +932,7 @@
     Py_UCS4 sign_char = '\0';
     int float_type; /* Used to see if we have a nan, inf, or regular float. */
     PyObject *unicode_tmp = NULL;
+    int err;
 
     /* Locale settings, either from the actual locale or
        from a hard-code pseudo-locale */
@@ -1010,7 +1014,7 @@
                     &locale);
 
     /* Calculate how much memory we'll need. */
-    n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index, 
+    n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
                                  index + n_digits, n_remainder, has_decimal,
                                  &locale, format);
 
@@ -1020,10 +1024,13 @@
         goto done;
 
     /* Populate the memory. */
-    fill_number(result, 0, &spec, unicode_tmp, index, index + n_digits,
-                NULL, 0,
-                format->fill_char == '\0' ? ' ' : format->fill_char, &locale,
-                0);
+    err = fill_number(result, 0, &spec,
+                      unicode_tmp, index, index + n_digits,
+                      NULL, 0,
+                      format->fill_char == '\0' ? ' ' : format->fill_char,
+                      &locale, 0);
+    if (err)
+        Py_CLEAR(result);
 
 done:
     PyMem_Free(buf);
@@ -1077,6 +1084,7 @@
     Py_ssize_t total;
     PyObject *re_unicode_tmp = NULL;
     PyObject *im_unicode_tmp = NULL;
+    int err;
 
     /* Locale settings, either from the actual locale or
        from a hard-code pseudo-locale */
@@ -1170,9 +1178,9 @@
 
     /* Determine if we have any "remainder" (after the digits, might include
        decimal or exponent or both (or neither)) */
-    parse_number(re_unicode_tmp, i_re, i_re + n_re_digits, 
+    parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
                  &n_re_remainder, &re_has_decimal);
-    parse_number(im_unicode_tmp, i_im, i_im + n_im_digits, 
+    parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
                  &n_im_remainder, &im_has_decimal);
 
     /* Determine the grouping, separator, and decimal point, if any. */
@@ -1225,12 +1233,26 @@
         PyUnicode_WRITE(rkind, rdata, index++, '(');
 
     if (!skip_re) {
-        fill_number(result, index, &re_spec, re_unicode_tmp, 
-                    i_re, i_re + n_re_digits, NULL, 0, 0, &locale, 0);
+        err = fill_number(result, index, &re_spec,
+                          re_unicode_tmp, i_re, i_re + n_re_digits,
+                          NULL, 0,
+                          0,
+                          &locale, 0);
+        if (err) {
+            Py_CLEAR(result);
+            goto done;
+        }
         index += n_re_total;
     }
-    fill_number(result, index, &im_spec, im_unicode_tmp,
-                i_im, i_im + n_im_digits, NULL, 0, 0, &locale, 0);
+    err = fill_number(result, index, &im_spec,
+                      im_unicode_tmp, i_im, i_im + n_im_digits,
+                      NULL, 0,
+                      0,
+                      &locale, 0);
+    if (err) {
+        Py_CLEAR(result);
+        goto done;
+    }
     index += n_im_total;
     PyUnicode_WRITE(rkind, rdata, index++, 'j');
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list