Branch data 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 : 949468 : GroupGenerator_init(GroupGenerator *self, const char *grouping) 12 : : { 13 : 949468 : self->grouping = grouping; 14 : 949468 : self->i = 0; 15 : 949468 : self->previous = 0; 16 : 949468 : } 17 : : 18 : : 19 : : /* Returns the next grouping, or 0 to signify end. */ 20 : : static Py_ssize_t 21 : 950300 : 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 [ + + + ]: 950300 : switch (self->grouping[self->i]) { 28 : 710 : case 0: 29 : 710 : return self->previous; 30 : 948964 : case CHAR_MAX: 31 : : /* Stop the generator. */ 32 : 948964 : return 0; 33 : 626 : default: { 34 : 626 : char ch = self->grouping[self->i]; 35 : 626 : self->previous = ch; 36 : 626 : self->i++; 37 : 626 : 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 : 950300 : 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 [ + + ]: 950300 : if (!writer) { 53 : : /* if maxchar > 127, maxchar is already set */ 54 [ + - + + ]: 475153 : if (*maxchar == 127 && thousands_sep) { 55 : 416 : Py_UCS4 maxchar2 = PyUnicode_MAX_CHAR_VALUE(thousands_sep); 56 : 416 : *maxchar = Py_MAX(*maxchar, maxchar2); 57 : : } 58 : 475153 : return; 59 : : } 60 : : 61 [ + + ]: 475147 : if (thousands_sep) { 62 : 416 : *buffer_pos -= thousands_sep_len; 63 : : 64 : : /* Copy the thousands_sep chars into the buffer. */ 65 : 416 : _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, 66 : : thousands_sep, 0, 67 : : thousands_sep_len); 68 : : } 69 : : 70 : 475147 : *buffer_pos -= n_chars; 71 : 475147 : *digits_pos -= n_chars; 72 : 475147 : _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, 73 : : digits, *digits_pos, 74 : : n_chars); 75 : : 76 [ + + ]: 475147 : if (n_zeros) { 77 : 173028 : *buffer_pos -= n_zeros; 78 : 173028 : int kind = PyUnicode_KIND(writer->buffer); 79 : 173028 : void *data = PyUnicode_DATA(writer->buffer); 80 : 173028 : unicode_fill(kind, data, '0', *buffer_pos, n_zeros); 81 : : } 82 : : }