}
}
- #define LT_NO_LOCALE 0
- #define LT_DEFAULT_LOCALE 1
- #define LT_UNDERSCORE_LOCALE 2
- #define LT_UNDER_FOUR_LOCALE 3
- #define LT_CURRENT_LOCALE 4
+/* Locale type codes. LT_NO_LOCALE must be zero. */
++enum LocaleType {
++ LT_NO_LOCALE = 0,
++ LT_DEFAULT_LOCALE,
++ LT_UNDERSCORE_LOCALE,
++ LT_UNDER_FOUR_LOCALE,
++ LT_CURRENT_LOCALE
++};
typedef struct {
Py_UCS4 fill_char;
int alternate;
Py_UCS4 sign;
Py_ssize_t width;
-- int thousands_separators;
++ enum LocaleType thousands_separators;
Py_ssize_t precision;
Py_UCS4 type;
} InternalFormatSpec;
format->alternate = 0;
format->sign = '\0';
format->width = -1;
-- format->thousands_separators = 0;
++ format->thousands_separators = LT_NO_LOCALE;
format->precision = -1;
format->type = default_type;
/* Comma signifies add thousands separators */
if (end-pos && READ_spec(pos) == ',') {
- format->thousands_separators = 1;
+ format->thousands_separators = LT_DEFAULT_LOCALE;
+ ++pos;
+ }
+ /* Underscore signifies add thousands separators */
+ if (end-pos && READ_spec(pos) == '_') {
- if (format->thousands_separators != 0) {
++ if (format->thousands_separators != LT_NO_LOCALE) {
+ invalid_comma_and_underscore();
+ return 0;
+ }
+ format->thousands_separators = LT_UNDERSCORE_LOCALE;
++pos;
}
+ if (end-pos && READ_spec(pos) == ',') {
+ invalid_comma_and_underscore();
+ return 0;
+ }
/* Parse field precision */
if (end-pos && READ_spec(pos) == '.') {
/* Find the decimal point character(s?), thousands_separator(s?), and
grouping description, either for the current locale if type is
- LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
- none if LT_NO_LOCALE. */
+ LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE or
+ LT_UNDERSCORE_LOCALE/LT_UNDER_FOUR_LOCALE, or none if LT_NO_LOCALE. */
static int
- get_locale_info(int type, LocaleInfo *locale_info)
+ get_locale_info(enum LocaleType type, LocaleInfo *locale_info)
{
switch (type) {
case LT_CURRENT_LOCALE: {
break;
}
case LT_DEFAULT_LOCALE:
+ case LT_UNDERSCORE_LOCALE:
+ case LT_UNDER_FOUR_LOCALE:
locale_info->decimal_point = PyUnicode_FromOrdinal('.');
- locale_info->thousands_sep = PyUnicode_FromOrdinal(',');
+ locale_info->thousands_sep = PyUnicode_FromOrdinal(
+ type == LT_DEFAULT_LOCALE ? ',' : '_');
- if (!locale_info->decimal_point || !locale_info->thousands_sep) {
- Py_XDECREF(locale_info->decimal_point);
- Py_XDECREF(locale_info->thousands_sep);
+ if (!locale_info->decimal_point || !locale_info->thousands_sep)
return -1;
- }
- locale_info->grouping = "\3"; /* Group every 3 characters. The
+ if (type != LT_UNDER_FOUR_LOCALE)
+ locale_info->grouping = "\3"; /* Group every 3 characters. The
(implicit) trailing 0 means repeat
infinitely. */
+ else
+ locale_info->grouping = "\4"; /* Bin/oct/hex group every four. */
break;
case LT_NO_LOCALE:
locale_info->decimal_point = PyUnicode_FromOrdinal('.');