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