diff options
author | Eric Smith <eric@trueblade.com> | 2008-05-11 21:00:57 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-05-11 21:00:57 (GMT) |
commit | 5807c415c5b16b9119895cdc80c4608f37c8c30b (patch) | |
tree | 2cf4895e2be7e15641c70d92e47272e09b42d826 /Objects/stringlib/formatter.h | |
parent | aa5b411b41978f3835c49850dd567fc284d9aad5 (diff) | |
download | cpython-5807c415c5b16b9119895cdc80c4608f37c8c30b.zip cpython-5807c415c5b16b9119895cdc80c4608f37c8c30b.tar.gz cpython-5807c415c5b16b9119895cdc80c4608f37c8c30b.tar.bz2 |
Merged revisions 63078 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
When forward porting this, I added _PyUnicode_InsertThousandsGrouping.
........
r63078 | eric.smith | 2008-05-11 15:52:48 -0400 (Sun, 11 May 2008) | 14 lines
Addresses issue 2802: 'n' formatting for integers.
Adds 'n' as a format specifier for integers, to mirror the same
specifier which is already available for floats. 'n' is the same as
'd', but inserts the current locale-specific thousands grouping.
I added this as a stringlib function, but it's only used by str type,
not unicode. This is because of an implementation detail in
unicode.format(), which does its own str->unicode conversion. But the
unicode version will be needed in 3.0, and it may be needed by other
code eventually in 2.6 (maybe decimal?), so I left it as a stringlib
implementation. As long as the unicode version isn't instantiated,
there's no overhead for this.
........
Diffstat (limited to 'Objects/stringlib/formatter.h')
-rw-r--r-- | Objects/stringlib/formatter.h | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 531bc22..22dd292 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -453,6 +453,9 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, Py_ssize_t n_digits; /* count of digits need from the computed string */ Py_ssize_t n_leading_chars; + Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to + allocate, used for 'n' + formatting. */ NumberFieldWidths spec; long x; @@ -523,6 +526,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, break; default: /* shouldn't be needed, but stops a compiler warning */ case 'd': + case 'n': base = 10; leading_chars_to_skip = 0; break; @@ -555,8 +559,15 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, /* Calculate the widths of the various leading and trailing parts */ calc_number_widths(&spec, sign, n_digits, format); + if (format->type == 'n') + /* Compute how many additional chars we need to allocate + to hold the thousands grouping. */ + STRINGLIB_GROUPING(pnumeric_chars, n_digits, + pnumeric_chars+n_digits, + 0, &n_grouping_chars, 0); + /* Allocate a new string to hold the result */ - result = STRINGLIB_NEW(NULL, spec.n_total); + result = STRINGLIB_NEW(NULL, spec.n_total + n_grouping_chars); if (!result) goto done; p = STRINGLIB_STR(result); @@ -567,13 +578,26 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, pnumeric_chars, n_digits * sizeof(STRINGLIB_CHAR)); - /* if X, convert to uppercase */ + /* If type is 'X', convert to uppercase */ if (format->type == 'X') { Py_ssize_t t; for (t = 0; t < n_digits; ++t) p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); } + /* Insert the grouping, if any, after the uppercasing of 'X', so we can + ensure that grouping chars won't be affeted. */ + if (n_grouping_chars && format->type == 'n') { + /* We know this can't fail, since we've already + reserved enough space. */ + STRINGLIB_CHAR *pstart = p + n_leading_chars; + int r = STRINGLIB_GROUPING(pstart, n_digits, + pstart + n_digits, + spec.n_total+n_grouping_chars-n_leading_chars, + NULL, 0); + assert(r); + } + /* Fill in the non-digit parts */ fill_number(p, &spec, n_digits, format->fill_char == '\0' ? ' ' : format->fill_char); @@ -841,6 +865,7 @@ format_int_or_long(PyObject* value, PyObject* args, IntOrLongToString tostring) case 'o': case 'x': case 'X': + case 'n': /* no type conversion needed, already an int (or long). do the formatting */ result = format_int_or_long_internal(value, &format, tostring); @@ -852,7 +877,6 @@ format_int_or_long(PyObject* value, PyObject* args, IntOrLongToString tostring) case 'F': case 'g': case 'G': - case 'n': case '%': /* convert to float */ tmp = PyNumber_Float(value); |