diff options
Diffstat (limited to 'Objects/stringlib/localeutil.h')
-rw-r--r-- | Objects/stringlib/localeutil.h | 100 |
1 files changed, 34 insertions, 66 deletions
diff --git a/Objects/stringlib/localeutil.h b/Objects/stringlib/localeutil.h index f548133..6e2f073 100644 --- a/Objects/stringlib/localeutil.h +++ b/Objects/stringlib/localeutil.h @@ -1,21 +1,19 @@ /* stringlib: locale related helpers implementation */ -#ifndef STRINGLIB_LOCALEUTIL_H -#define STRINGLIB_LOCALEUTIL_H - #include <locale.h> -#define MAX(x, y) ((x) < (y) ? (y) : (x)) -#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#ifndef STRINGLIB_IS_UNICODE +# error "localeutil is specific to Unicode" +#endif typedef struct { const char *grouping; char previous; Py_ssize_t i; /* Where we're currently pointing in grouping. */ -} GroupGenerator; +} STRINGLIB(GroupGenerator); static void -_GroupGenerator_init(GroupGenerator *self, const char *grouping) +STRINGLIB(GroupGenerator_init)(STRINGLIB(GroupGenerator) *self, const char *grouping) { self->grouping = grouping; self->i = 0; @@ -24,7 +22,7 @@ _GroupGenerator_init(GroupGenerator *self, const char *grouping) /* Returns the next grouping, or 0 to signify end. */ static Py_ssize_t -_GroupGenerator_next(GroupGenerator *self) +STRINGLIB(GroupGenerator_next)(STRINGLIB(GroupGenerator) *self) { /* Note that we don't really do much error checking here. If a grouping string contains just CHAR_MAX, for example, then just @@ -48,27 +46,18 @@ _GroupGenerator_next(GroupGenerator *self) /* Fill in some digits, leading zeros, and thousands separator. All are optional, depending on when we're called. */ static void -fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, - Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep, +STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, + Py_ssize_t n_chars, Py_ssize_t n_zeros, STRINGLIB_CHAR* thousands_sep, Py_ssize_t thousands_sep_len) { -#if STRINGLIB_IS_UNICODE Py_ssize_t i; -#endif if (thousands_sep) { *buffer_end -= thousands_sep_len; /* Copy the thousands_sep chars into the buffer. */ -#if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - for (i = 0; i < thousands_sep_len; ++i) - (*buffer_end)[i] = thousands_sep[i]; -#else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(*buffer_end, thousands_sep, thousands_sep_len); -#endif + memcpy(*buffer_end, thousands_sep, + thousands_sep_len * STRINGLIB_SIZEOF_CHAR); } *buffer_end -= n_chars; @@ -76,11 +65,12 @@ fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR)); *buffer_end -= n_zeros; - STRINGLIB_FILL(*buffer_end, '0', n_zeros); + for (i = 0; i < n_zeros; i++) + (*buffer_end)[i] = '0'; } /** - * _Py_InsertThousandsGrouping: + * InsertThousandsGrouping: * @buffer: A pointer to the start of a string. * @n_buffer: Number of characters in @buffer. * @digits: A pointer to the digits we're reading from. If count @@ -109,14 +99,16 @@ fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, * As closely as possible, this code mimics the logic in decimal.py's _insert_thousands_sep(). **/ -Py_ssize_t -_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, - Py_ssize_t n_buffer, - STRINGLIB_CHAR *digits, - Py_ssize_t n_digits, - Py_ssize_t min_width, - const char *grouping, - const char *thousands_sep) +static Py_ssize_t +STRINGLIB(InsertThousandsGrouping)( + STRINGLIB_CHAR *buffer, + Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + STRINGLIB_CHAR *thousands_sep, + Py_ssize_t thousands_sep_len) { Py_ssize_t count = 0; Py_ssize_t n_zeros; @@ -128,23 +120,22 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, STRINGLIB_CHAR *digits_end = NULL; Py_ssize_t l; Py_ssize_t n_chars; - Py_ssize_t thousands_sep_len = strlen(thousands_sep); Py_ssize_t remaining = n_digits; /* Number of chars remaining to be looked at */ /* A generator that returns all of the grouping widths, until it returns 0. */ - GroupGenerator groupgen; - _GroupGenerator_init(&groupgen, grouping); + STRINGLIB(GroupGenerator) groupgen; + STRINGLIB(GroupGenerator_init)(&groupgen, grouping); if (buffer) { buffer_end = buffer + n_buffer; digits_end = digits + n_digits; } - while ((l = _GroupGenerator_next(&groupgen)) > 0) { - l = MIN(l, MAX(MAX(remaining, min_width), 1)); - n_zeros = MAX(0, l - remaining); - n_chars = MAX(0, MIN(remaining, l)); + while ((l = STRINGLIB(GroupGenerator_next)(&groupgen)) > 0) { + l = Py_MIN(l, Py_MAX(Py_MAX(remaining, min_width), 1)); + n_zeros = Py_MAX(0, l - remaining); + n_chars = Py_MAX(0, Py_MIN(remaining, l)); /* Use n_zero zero's and n_chars chars */ @@ -153,7 +144,7 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, if (buffer) { /* Copy into the output buffer. */ - fill(&digits_end, &buffer_end, n_chars, n_zeros, + STRINGLIB(fill)(&digits_end, &buffer_end, n_chars, n_zeros, use_separator ? thousands_sep : NULL, thousands_sep_len); } @@ -172,41 +163,18 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, if (!loop_broken) { /* We left the loop without using a break statement. */ - l = MAX(MAX(remaining, min_width), 1); - n_zeros = MAX(0, l - remaining); - n_chars = MAX(0, MIN(remaining, l)); + l = Py_MAX(Py_MAX(remaining, min_width), 1); + n_zeros = Py_MAX(0, l - remaining); + n_chars = Py_MAX(0, Py_MIN(remaining, l)); /* Use n_zero zero's and n_chars chars */ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; if (buffer) { /* Copy into the output buffer. */ - fill(&digits_end, &buffer_end, n_chars, n_zeros, + STRINGLIB(fill)(&digits_end, &buffer_end, n_chars, n_zeros, use_separator ? thousands_sep : NULL, thousands_sep_len); } } return count; } -/** - * _Py_InsertThousandsGroupingLocale: - * @buffer: A pointer to the start of a string. - * @n_digits: The number of digits in the string, in which we want - * to put the grouping chars. - * - * Reads thee current locale and calls _Py_InsertThousandsGrouping(). - **/ -Py_ssize_t -_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, - Py_ssize_t n_buffer, - STRINGLIB_CHAR *digits, - Py_ssize_t n_digits, - Py_ssize_t min_width) -{ - struct lconv *locale_data = localeconv(); - const char *grouping = locale_data->grouping; - const char *thousands_sep = locale_data->thousands_sep; - - return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, - min_width, grouping, thousands_sep); -} -#endif /* STRINGLIB_LOCALEUTIL_H */ |