localeutil.h 2.5 KB

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