mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 23:13:34 +00:00
9b29358511
Status lines for Emacs and Vim have been added to Python sources so they'll be easier to edit using Python's preferred coding style. Some DNS helper functions have been broken up into multiple files. It's nice to have one function per file whenever possible, since that way we don't need -ffunction-sections. Another reason it's good to have small source files, is because the build will be enforcing resource limits on compilation and testing soon.
90 lines
3.3 KiB
C++
90 lines
3.3 KiB
C++
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
|
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
│ Python 3 │
|
|
│ https://docs.python.org/3/license.html │
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
/* clang-format off */
|
|
|
|
/* _PyUnicode_InsertThousandsGrouping() helper functions */
|
|
|
|
typedef struct {
|
|
const char *grouping;
|
|
char previous;
|
|
Py_ssize_t i; /* Where we're currently pointing in grouping. */
|
|
} GroupGenerator;
|
|
|
|
|
|
static void
|
|
GroupGenerator_init(GroupGenerator *self, const char *grouping)
|
|
{
|
|
self->grouping = grouping;
|
|
self->i = 0;
|
|
self->previous = 0;
|
|
}
|
|
|
|
|
|
/* Returns the next grouping, or 0 to signify end. */
|
|
static Py_ssize_t
|
|
GroupGenerator_next(GroupGenerator *self)
|
|
{
|
|
/* 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* Fill in some digits, leading zeros, and thousands separator. All
|
|
are optional, depending on when we're called. */
|
|
static void
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
if (thousands_sep) {
|
|
*buffer_pos -= thousands_sep_len;
|
|
|
|
/* Copy the thousands_sep chars into the buffer. */
|
|
_PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos,
|
|
thousands_sep, 0,
|
|
thousands_sep_len);
|
|
}
|
|
|
|
*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;
|
|
enum PyUnicode_Kind kind = PyUnicode_KIND(writer->buffer);
|
|
void *data = PyUnicode_DATA(writer->buffer);
|
|
FILL(kind, data, '0', *buffer_pos, n_zeros);
|
|
}
|
|
}
|