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.
This commit is contained in:
Eric Smith 2008-05-11 19:52:48 +00:00
parent 30ece44f2e
commit cf537ff39e
9 changed files with 184 additions and 52 deletions

View file

@ -343,14 +343,9 @@ ensure_decimal_point(char* buffer, size_t buf_size)
Py_LOCAL_INLINE(int)
add_thousands_grouping(char* buffer, size_t buf_size)
{
Py_ssize_t len = strlen(buffer);
struct lconv *locale_data = localeconv();
const char *grouping = locale_data->grouping;
const char *thousands_sep = locale_data->thousands_sep;
size_t thousands_sep_len = strlen(thousands_sep);
const char *decimal_point = locale_data->decimal_point;
char *pend = buffer + strlen(buffer); /* current end of buffer */
char *pmax = buffer + buf_size; /* max of buffer */
char current_grouping;
/* Find the decimal point, if any. We're only concerned
about the characters to the left of the decimal when
@ -364,49 +359,13 @@ add_thousands_grouping(char* buffer, size_t buf_size)
if (!p)
/* No exponent and no decimal. Use the entire
string. */
p = pend;
p = buffer + len;
}
/* At this point, p points just past the right-most character we
want to format. We need to add the grouping string for the
characters between buffer and p. */
/* Starting at p and working right-to-left, keep track of
what grouping needs to be added and insert that. */
current_grouping = *grouping++;
/* If the first character is 0, perform no grouping at all. */
if (current_grouping == 0)
return 1;
while (p - buffer > current_grouping) {
/* Always leave buffer and pend valid at the end of this
loop, since we might leave with a return statement. */
/* Is there room to insert thousands_sep_len chars?. */
if (pmax - pend <= thousands_sep_len)
/* No room. */
return 0;
/* Move the rest of the string down. */
p -= current_grouping;
memmove(p + thousands_sep_len,
p,
pend - p + 1);
/* Adjust end pointer. */
pend += thousands_sep_len;
/* Copy the thousands_sep chars into the buffer. */
memcpy(p, thousands_sep, thousands_sep_len);
/* Move to the next grouping character, unless we're
repeating (which is designated by a grouping of 0). */
if (*grouping != 0) {
current_grouping = *grouping++;
if (current_grouping == CHAR_MAX)
/* We're done. */
return 1;
}
}
return 1;
return _PyString_InsertThousandsGrouping(buffer, len, p,
buf_size, NULL, 1);
}
/* see FORMATBUFLEN in unicodeobject.c */