| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | /* _PyUnicode_InsertThousandsGrouping() helper functions */ | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     const char *grouping; | 
					
						
							|  |  |  |     char previous; | 
					
						
							|  |  |  |     Py_ssize_t i; /* Where we're currently pointing in grouping. */ | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | } GroupGenerator; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | GroupGenerator_init(GroupGenerator *self, const char *grouping) | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     self->grouping = grouping; | 
					
						
							|  |  |  |     self->i = 0; | 
					
						
							|  |  |  |     self->previous = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | /* Returns the next grouping, or 0 to signify end. */ | 
					
						
							|  |  |  | static Py_ssize_t | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | GroupGenerator_next(GroupGenerator *self) | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     /* Note that we don't really do much error checking here. If a
 | 
					
						
							|  |  |  |        grouping string contains just CHAR_MAX, for example, then just | 
					
						
							|  |  |  |        terminate the generator. That shouldn't happen, but at least we | 
					
						
							|  |  |  |        fail gracefully. */ | 
					
						
							|  |  |  |     switch (self->grouping[self->i]) { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |         return self->previous; | 
					
						
							|  |  |  |     case CHAR_MAX: | 
					
						
							|  |  |  |         /* Stop the generator. */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |         char ch = self->grouping[self->i]; | 
					
						
							|  |  |  |         self->previous = ch; | 
					
						
							|  |  |  |         self->i++; | 
					
						
							|  |  |  |         return (Py_ssize_t)ch; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | /* Fill in some digits, leading zeros, and thousands separator. All
 | 
					
						
							|  |  |  |    are optional, depending on when we're called. */ | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  | InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, | 
					
						
							|  |  |  |                              PyObject *digits, Py_ssize_t *digits_pos, | 
					
						
							|  |  |  |                              Py_ssize_t n_chars, Py_ssize_t n_zeros, | 
					
						
							|  |  |  |                              PyObject *thousands_sep, Py_ssize_t thousands_sep_len, | 
					
						
							|  |  |  |                              Py_UCS4 *maxchar) | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  |     if (!writer) { | 
					
						
							|  |  |  |         /* if maxchar > 127, maxchar is already set */ | 
					
						
							|  |  |  |         if (*maxchar == 127 && thousands_sep) { | 
					
						
							|  |  |  |             Py_UCS4 maxchar2 = PyUnicode_MAX_CHAR_VALUE(thousands_sep); | 
					
						
							|  |  |  |             *maxchar = Py_MAX(*maxchar, maxchar2); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (thousands_sep) { | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  |         *buffer_pos -= thousands_sep_len; | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* Copy the thousands_sep chars into the buffer. */ | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  |         _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, | 
					
						
							|  |  |  |                                       thousands_sep, 0, | 
					
						
							|  |  |  |                                       thousands_sep_len); | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  |     *buffer_pos -= n_chars; | 
					
						
							|  |  |  |     *digits_pos -= n_chars; | 
					
						
							|  |  |  |     _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, | 
					
						
							|  |  |  |                                   digits, *digits_pos, | 
					
						
							|  |  |  |                                   n_chars); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (n_zeros) { | 
					
						
							|  |  |  |         *buffer_pos -= n_zeros; | 
					
						
							| 
									
										
										
										
											2022-05-13 12:41:05 +02:00
										 |  |  |         int kind = PyUnicode_KIND(writer->buffer); | 
					
						
							| 
									
										
										
										
											2018-11-26 13:40:01 +01:00
										 |  |  |         void *data = PyUnicode_DATA(writer->buffer); | 
					
						
							|  |  |  |         unicode_fill(kind, data, '0', *buffer_pos, n_zeros); | 
					
						
							| 
									
										
										
										
											2009-04-16 20:16:10 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-03 14:45:06 +00:00
										 |  |  | } |