Line data Source code
1 : /* _PyUnicode_InsertThousandsGrouping() helper functions */ 2 : 3 : typedef struct { 4 : const char *grouping; 5 : char previous; 6 : Py_ssize_t i; /* Where we're currently pointing in grouping. */ 7 : } GroupGenerator; 8 : 9 : 10 : static void 11 949228 : GroupGenerator_init(GroupGenerator *self, const char *grouping) 12 : { 13 949228 : self->grouping = grouping; 14 949228 : self->i = 0; 15 949228 : self->previous = 0; 16 949228 : } 17 : 18 : 19 : /* Returns the next grouping, or 0 to signify end. */ 20 : static Py_ssize_t 21 950054 : GroupGenerator_next(GroupGenerator *self) 22 : { 23 : /* Note that we don't really do much error checking here. If a 24 : grouping string contains just CHAR_MAX, for example, then just 25 : terminate the generator. That shouldn't happen, but at least we 26 : fail gracefully. */ 27 950054 : switch (self->grouping[self->i]) { 28 712 : case 0: 29 712 : return self->previous; 30 948724 : case CHAR_MAX: 31 : /* Stop the generator. */ 32 948724 : return 0; 33 618 : default: { 34 618 : char ch = self->grouping[self->i]; 35 618 : self->previous = ch; 36 618 : self->i++; 37 618 : return (Py_ssize_t)ch; 38 : } 39 : } 40 : } 41 : 42 : 43 : /* Fill in some digits, leading zeros, and thousands separator. All 44 : are optional, depending on when we're called. */ 45 : static void 46 950054 : InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, 47 : PyObject *digits, Py_ssize_t *digits_pos, 48 : Py_ssize_t n_chars, Py_ssize_t n_zeros, 49 : PyObject *thousands_sep, Py_ssize_t thousands_sep_len, 50 : Py_UCS4 *maxchar) 51 : { 52 950054 : if (!writer) { 53 : /* if maxchar > 127, maxchar is already set */ 54 475030 : if (*maxchar == 127 && thousands_sep) { 55 413 : Py_UCS4 maxchar2 = PyUnicode_MAX_CHAR_VALUE(thousands_sep); 56 413 : *maxchar = Py_MAX(*maxchar, maxchar2); 57 : } 58 475030 : return; 59 : } 60 : 61 475024 : if (thousands_sep) { 62 413 : *buffer_pos -= thousands_sep_len; 63 : 64 : /* Copy the thousands_sep chars into the buffer. */ 65 413 : _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, 66 : thousands_sep, 0, 67 : thousands_sep_len); 68 : } 69 : 70 475024 : *buffer_pos -= n_chars; 71 475024 : *digits_pos -= n_chars; 72 475024 : _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, 73 : digits, *digits_pos, 74 : n_chars); 75 : 76 475024 : if (n_zeros) { 77 173049 : *buffer_pos -= n_zeros; 78 173049 : int kind = PyUnicode_KIND(writer->buffer); 79 173049 : void *data = PyUnicode_DATA(writer->buffer); 80 173049 : unicode_fill(kind, data, '0', *buffer_pos, n_zeros); 81 : } 82 : }