summaryrefslogtreecommitdiffstats
path: root/Objects/stringlib/localeutil.h
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/stringlib/localeutil.h')
-rw-r--r--Objects/stringlib/localeutil.h100
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 */