fill_char() can now propagate an error

This commit is contained in:
Victor Stinner 2011-09-28 21:50:16 +02:00
parent 157f83fcfc
commit afbaa20fb9
1 changed files with 47 additions and 25 deletions

View File

@ -541,11 +541,12 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
/* Fill in the digit parts of a numbers's string representation, /* Fill in the digit parts of a numbers's string representation,
as determined in calc_number_widths(). as determined in calc_number_widths().
No error checking, since we know the buffer is the correct size. */ Return -1 on error, or 0 on success. */
static void static int
fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec, fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end, 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) LocaleInfo *locale, int toupper)
{ {
/* Used to keep track of digits, decimal, and remainder. */ /* Used to keep track of digits, decimal, and remainder. */
@ -589,11 +590,8 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
char *pdigits = PyUnicode_DATA(digits); char *pdigits = PyUnicode_DATA(digits);
if (PyUnicode_KIND(digits) < kind) { if (PyUnicode_KIND(digits) < kind) {
pdigits = _PyUnicode_AsKind(digits, kind); pdigits = _PyUnicode_AsKind(digits, kind);
if (pdigits == NULL) { if (pdigits == NULL)
/* XXX report exception */ return -1;
Py_FatalError("out of memory");
return;
}
} }
#ifndef NDEBUG #ifndef NDEBUG
r = r =
@ -640,6 +638,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
unicode_fill(out, pos, pos + spec->n_rpadding, fill_char); unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
pos += spec->n_rpadding; pos += spec->n_rpadding;
} }
return 0;
} }
static char no_grouping[1] = {CHAR_MAX}; static char no_grouping[1] = {CHAR_MAX};
@ -765,6 +764,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
Py_ssize_t prefix; Py_ssize_t prefix;
NumberFieldWidths spec; NumberFieldWidths spec;
long x; long x;
int err;
/* Locale settings, either from the actual locale or /* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */ from a hard-code pseudo-locale */
@ -886,10 +886,13 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
goto done; goto done;
/* Populate the memory. */ /* Populate the memory. */
fill_number(result, 0, &spec, tmp, inumeric_chars, inumeric_chars + n_digits, err = fill_number(result, 0, &spec,
tmp, inumeric_chars, inumeric_chars + n_digits,
tmp, prefix, tmp, prefix,
format->fill_char == '\0' ? ' ' : format->fill_char, format->fill_char == '\0' ? ' ' : format->fill_char,
&locale, format->type == 'X'); &locale, format->type == 'X');
if (err)
Py_CLEAR(result);
done: done:
Py_XDECREF(tmp); Py_XDECREF(tmp);
@ -929,6 +932,7 @@ format_float_internal(PyObject *value,
Py_UCS4 sign_char = '\0'; Py_UCS4 sign_char = '\0';
int float_type; /* Used to see if we have a nan, inf, or regular float. */ int float_type; /* Used to see if we have a nan, inf, or regular float. */
PyObject *unicode_tmp = NULL; PyObject *unicode_tmp = NULL;
int err;
/* Locale settings, either from the actual locale or /* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */ from a hard-code pseudo-locale */
@ -1020,10 +1024,13 @@ format_float_internal(PyObject *value,
goto done; goto done;
/* Populate the memory. */ /* Populate the memory. */
fill_number(result, 0, &spec, unicode_tmp, index, index + n_digits, err = fill_number(result, 0, &spec,
unicode_tmp, index, index + n_digits,
NULL, 0, NULL, 0,
format->fill_char == '\0' ? ' ' : format->fill_char, &locale, format->fill_char == '\0' ? ' ' : format->fill_char,
0); &locale, 0);
if (err)
Py_CLEAR(result);
done: done:
PyMem_Free(buf); PyMem_Free(buf);
@ -1077,6 +1084,7 @@ format_complex_internal(PyObject *value,
Py_ssize_t total; Py_ssize_t total;
PyObject *re_unicode_tmp = NULL; PyObject *re_unicode_tmp = NULL;
PyObject *im_unicode_tmp = NULL; PyObject *im_unicode_tmp = NULL;
int err;
/* Locale settings, either from the actual locale or /* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */ from a hard-code pseudo-locale */
@ -1225,12 +1233,26 @@ format_complex_internal(PyObject *value,
PyUnicode_WRITE(rkind, rdata, index++, '('); PyUnicode_WRITE(rkind, rdata, index++, '(');
if (!skip_re) { if (!skip_re) {
fill_number(result, index, &re_spec, re_unicode_tmp, err = fill_number(result, index, &re_spec,
i_re, i_re + n_re_digits, NULL, 0, 0, &locale, 0); 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; index += n_re_total;
} }
fill_number(result, index, &im_spec, im_unicode_tmp, err = fill_number(result, index, &im_spec,
i_im, i_im + n_im_digits, NULL, 0, 0, &locale, 0); 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; index += n_im_total;
PyUnicode_WRITE(rkind, rdata, index++, 'j'); PyUnicode_WRITE(rkind, rdata, index++, 'j');