Coverage Report

Created: 2026-10-17 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Objects/unicode_formatter.c
Line
Count
Source
1
/* implements the unicode (as opposed to string) version of the
2
   built-in formatters for string, int, float.  that is, the versions
3
   of int.__float__, etc., that take and return unicode objects */
4
5
#include "Python.h"
6
#include "pycore_fileutils.h"     // _Py_GetLocaleconvNumeric()
7
#include "pycore_long.h"          // _PyLong_FormatWriter()
8
#include "pycore_unicodeobject.h" // PyUnicode_MAX_CHAR_VALUE()
9
#include <locale.h>
10
11
12
/* _PyUnicode_InsertThousandsGrouping() helper functions */
13
14
typedef struct {
15
    const char *grouping;
16
    char previous;
17
    Py_ssize_t i; /* Where we're currently pointing in grouping. */
18
} GroupGenerator;
19
20
21
static void
22
GroupGenerator_init(GroupGenerator *self, const char *grouping)
23
11.1M
{
24
11.1M
    self->grouping = grouping;
25
11.1M
    self->i = 0;
26
11.1M
    self->previous = 0;
27
11.1M
}
28
29
30
/* Returns the next grouping, or 0 to signify end. */
31
static Py_ssize_t
32
GroupGenerator_next(GroupGenerator *self)
33
11.1M
{
34
    /* Note that we don't really do much error checking here. If a
35
       grouping string contains just CHAR_MAX, for example, then just
36
       terminate the generator. That shouldn't happen, but at least we
37
       fail gracefully. */
38
11.1M
    switch (self->grouping[self->i]) {
39
0
    case 0:
40
0
        return self->previous;
41
11.1M
    case CHAR_MAX:
42
        /* Stop the generator. */
43
11.1M
        return 0;
44
0
    default: {
45
0
        char ch = self->grouping[self->i];
46
0
        self->previous = ch;
47
0
        self->i++;
48
0
        return (Py_ssize_t)ch;
49
0
    }
50
11.1M
    }
51
11.1M
}
52
53
54
/* Fill in some digits, leading zeros, and thousands separator. All
55
   are optional, depending on when we're called. */
56
static void
57
InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos,
58
                             PyObject *digits, Py_ssize_t *digits_pos,
59
                             Py_ssize_t n_chars, Py_ssize_t n_zeros,
60
                             PyObject *thousands_sep, Py_ssize_t thousands_sep_len,
61
                             Py_UCS4 *maxchar, int forward)
62
11.1M
{
63
11.1M
    if (!writer) {
64
        /* if maxchar > 127, maxchar is already set */
65
5.59M
        if (*maxchar == 127 && thousands_sep) {
66
0
            Py_UCS4 maxchar2 = PyUnicode_MAX_CHAR_VALUE(thousands_sep);
67
0
            *maxchar = Py_MAX(*maxchar, maxchar2);
68
0
        }
69
5.59M
        return;
70
5.59M
    }
71
72
5.59M
    if (thousands_sep) {
73
0
        if (!forward) {
74
0
            *buffer_pos -= thousands_sep_len;
75
0
        }
76
        /* Copy the thousands_sep chars into the buffer. */
77
0
        _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos,
78
0
                                      thousands_sep, 0,
79
0
                                      thousands_sep_len);
80
0
        if (forward) {
81
0
            *buffer_pos += thousands_sep_len;
82
0
        }
83
0
    }
84
85
5.59M
    if (!forward) {
86
5.59M
        *buffer_pos -= n_chars;
87
5.59M
        *digits_pos -= n_chars;
88
5.59M
    }
89
5.59M
    _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos,
90
5.59M
                                  digits, *digits_pos,
91
5.59M
                                  n_chars);
92
5.59M
    if (forward) {
93
0
        *buffer_pos += n_chars;
94
0
        *digits_pos += n_chars;
95
0
    }
96
97
5.59M
    if (n_zeros) {
98
227
        if (!forward) {
99
227
            *buffer_pos -= n_zeros;
100
227
        }
101
227
        int kind = PyUnicode_KIND(writer->buffer);
102
227
        void *data = PyUnicode_DATA(writer->buffer);
103
227
        _PyUnicode_Fill(kind, data, '0', *buffer_pos, n_zeros);
104
227
        if (forward) {
105
0
            *buffer_pos += n_zeros;
106
0
        }
107
227
    }
108
5.59M
}
109
110
111
/**
112
 * InsertThousandsGrouping:
113
 * @writer: Unicode writer.
114
 * @n_buffer: Number of characters in @buffer.
115
 * @digits: Digits we're reading from. If count is non-NULL, this is unused.
116
 * @d_pos: Start of digits string.
117
 * @n_digits: The number of digits in the string, in which we want
118
 *            to put the grouping chars.
119
 * @min_width: The minimum width of the digits in the output string.
120
 *             Output will be zero-padded on the left to fill.
121
 * @grouping: see definition in localeconv().
122
 * @thousands_sep: see definition in localeconv().
123
 *
124
 * There are 2 modes: counting and filling. If @writer is NULL,
125
 *  we are in counting mode, else filling mode.
126
 * If counting, the required buffer size is returned.
127
 * If filling, we know the buffer will be large enough, so we don't
128
 *  need to pass in the buffer size.
129
 * Inserts thousand grouping characters (as defined by grouping and
130
 *  thousands_sep) into @writer.
131
 *
132
 * Return value: -1 on error, number of characters otherwise.
133
 **/
134
static Py_ssize_t
135
_PyUnicode_InsertThousandsGrouping(
136
    _PyUnicodeWriter *writer,
137
    Py_ssize_t n_buffer,
138
    PyObject *digits,
139
    Py_ssize_t d_pos,
140
    Py_ssize_t n_digits,
141
    Py_ssize_t min_width,
142
    const char *grouping,
143
    PyObject *thousands_sep,
144
    Py_UCS4 *maxchar,
145
    int forward)
146
11.1M
{
147
11.1M
    min_width = Py_MAX(0, min_width);
148
11.1M
    if (writer) {
149
5.59M
        assert(digits != NULL);
150
5.59M
        assert(maxchar == NULL);
151
5.59M
    }
152
5.59M
    else {
153
5.59M
        assert(digits == NULL);
154
5.59M
        assert(maxchar != NULL);
155
5.59M
    }
156
11.1M
    assert(0 <= d_pos);
157
11.1M
    assert(0 <= n_digits);
158
11.1M
    assert(grouping != NULL);
159
160
11.1M
    Py_ssize_t count = 0;
161
11.1M
    Py_ssize_t n_zeros;
162
11.1M
    int loop_broken = 0;
163
11.1M
    int use_separator = 0; /* First time through, don't append the
164
                              separator. They only go between
165
                              groups. */
166
11.1M
    Py_ssize_t buffer_pos;
167
11.1M
    Py_ssize_t digits_pos;
168
11.1M
    Py_ssize_t len;
169
11.1M
    Py_ssize_t n_chars;
170
11.1M
    Py_ssize_t remaining = n_digits; /* Number of chars remaining to
171
                                        be looked at */
172
    /* A generator that returns all of the grouping widths, until it
173
       returns 0. */
174
11.1M
    GroupGenerator groupgen;
175
11.1M
    GroupGenerator_init(&groupgen, grouping);
176
11.1M
    const Py_ssize_t thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep);
177
178
    /* if digits are not grouped, thousands separator
179
       should be an empty string */
180
11.1M
    assert(!(grouping[0] == CHAR_MAX && thousands_sep_len != 0));
181
182
11.1M
    digits_pos = d_pos + (forward ? 0 : n_digits);
183
11.1M
    if (writer) {
184
5.59M
        buffer_pos = writer->pos + (forward ? 0 : n_buffer);
185
5.59M
        assert(buffer_pos <= PyUnicode_GET_LENGTH(writer->buffer));
186
5.59M
        assert(digits_pos <= PyUnicode_GET_LENGTH(digits));
187
5.59M
    }
188
5.59M
    else {
189
5.59M
        buffer_pos = forward ? 0 : n_buffer;
190
5.59M
    }
191
192
11.1M
    if (!writer) {
193
5.59M
        *maxchar = 127;
194
5.59M
    }
195
196
11.1M
    while ((len = GroupGenerator_next(&groupgen)) > 0) {
197
0
        len = Py_MIN(len, Py_MAX(Py_MAX(remaining, min_width), 1));
198
0
        n_zeros = Py_MAX(0, len - remaining);
199
0
        n_chars = Py_MAX(0, Py_MIN(remaining, len));
200
201
        /* Use n_zero zero's and n_chars chars */
202
203
        /* Count only, don't do anything. */
204
0
        count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
205
206
        /* Copy into the writer. */
207
0
        InsertThousandsGrouping_fill(writer, &buffer_pos,
208
0
                                     digits, &digits_pos,
209
0
                                     n_chars, n_zeros,
210
0
                                     use_separator ? thousands_sep : NULL,
211
0
                                     thousands_sep_len, maxchar, forward);
212
213
        /* Use a separator next time. */
214
0
        use_separator = 1;
215
216
0
        remaining -= n_chars;
217
0
        min_width -= len;
218
219
0
        if (remaining <= 0 && min_width <= 0) {
220
0
            loop_broken = 1;
221
0
            break;
222
0
        }
223
0
        min_width -= thousands_sep_len;
224
0
    }
225
11.1M
    if (!loop_broken) {
226
        /* We left the loop without using a break statement. */
227
228
11.1M
        len = Py_MAX(Py_MAX(remaining, min_width), 1);
229
11.1M
        n_zeros = Py_MAX(0, len - remaining);
230
11.1M
        n_chars = Py_MAX(0, Py_MIN(remaining, len));
231
232
        /* Use n_zero zero's and n_chars chars */
233
11.1M
        count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
234
235
        /* Copy into the writer. */
236
11.1M
        InsertThousandsGrouping_fill(writer, &buffer_pos,
237
11.1M
                                     digits, &digits_pos,
238
11.1M
                                     n_chars, n_zeros,
239
11.1M
                                     use_separator ? thousands_sep : NULL,
240
11.1M
                                     thousands_sep_len, maxchar, forward);
241
11.1M
    }
242
11.1M
    return count;
243
11.1M
}
244
245
246
/* Raises an exception about an unknown presentation type for this
247
 * type. */
248
249
static void
250
unknown_presentation_type(Py_UCS4 presentation_type,
251
                          const char* type_name)
252
0
{
253
    /* %c might be out-of-range, hence the two cases. */
254
0
    if (presentation_type > 32 && presentation_type < 128)
255
0
        PyErr_Format(PyExc_ValueError,
256
0
                     "Unknown format code '%c' "
257
0
                     "for object of type '%.200s'",
258
0
                     (char)presentation_type,
259
0
                     type_name);
260
0
    else
261
0
        PyErr_Format(PyExc_ValueError,
262
0
                     "Unknown format code '\\x%x' "
263
0
                     "for object of type '%.200s'",
264
0
                     (unsigned int)presentation_type,
265
0
                     type_name);
266
0
}
267
268
static void
269
invalid_thousands_separator_type(char specifier, Py_UCS4 presentation_type)
270
0
{
271
0
    assert(specifier == ',' || specifier == '_');
272
0
    if (presentation_type > 32 && presentation_type < 128)
273
0
        PyErr_Format(PyExc_ValueError,
274
0
                     "Cannot specify '%c' with '%c'.",
275
0
                     specifier, (char)presentation_type);
276
0
    else
277
0
        PyErr_Format(PyExc_ValueError,
278
0
                     "Cannot specify '%c' with '\\x%x'.",
279
0
                     specifier, (unsigned int)presentation_type);
280
0
}
281
282
static void
283
invalid_comma_and_underscore(void)
284
0
{
285
0
    PyErr_Format(PyExc_ValueError, "Cannot specify both ',' and '_'.");
286
0
}
287
288
/*
289
    get_integer consumes 0 or more decimal digit characters from an
290
    input string, updates *result with the corresponding positive
291
    integer, and returns the number of digits consumed.
292
293
    returns -1 on error.
294
*/
295
static int
296
get_integer(PyObject *str, Py_ssize_t *ppos, Py_ssize_t end,
297
                  Py_ssize_t *result)
298
5.59M
{
299
5.59M
    Py_ssize_t accumulator, digitval, pos = *ppos;
300
5.59M
    int numdigits;
301
5.59M
    int kind = PyUnicode_KIND(str);
302
5.59M
    const void *data = PyUnicode_DATA(str);
303
304
5.59M
    accumulator = numdigits = 0;
305
11.1M
    for (; pos < end; pos++, numdigits++) {
306
11.1M
        digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(kind, data, pos));
307
11.1M
        if (digitval < 0)
308
5.59M
            break;
309
        /*
310
           Detect possible overflow before it happens:
311
312
              accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
313
              accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
314
        */
315
5.59M
        if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
316
0
            PyErr_Format(PyExc_ValueError,
317
0
                         "Too many decimal digits in format string");
318
0
            *ppos = pos;
319
0
            return -1;
320
0
        }
321
5.59M
        accumulator = accumulator * 10 + digitval;
322
5.59M
    }
323
5.59M
    *ppos = pos;
324
5.59M
    *result = accumulator;
325
5.59M
    return numdigits;
326
5.59M
}
327
328
/************************************************************************/
329
/*********** standard format specifier parsing **************************/
330
/************************************************************************/
331
332
/* returns true if this character is a specifier alignment token */
333
Py_LOCAL_INLINE(int)
334
is_alignment_token(Py_UCS4 c)
335
11.1M
{
336
11.1M
    switch (c) {
337
0
    case '<': case '>': case '=': case '^':
338
0
        return 1;
339
11.1M
    default:
340
11.1M
        return 0;
341
11.1M
    }
342
11.1M
}
343
344
/* returns true if this character is a sign element */
345
Py_LOCAL_INLINE(int)
346
is_sign_element(Py_UCS4 c)
347
5.59M
{
348
5.59M
    switch (c) {
349
0
    case ' ': case '+': case '-':
350
0
        return 1;
351
5.59M
    default:
352
5.59M
        return 0;
353
5.59M
    }
354
5.59M
}
355
356
/* Locale type codes. LT_NO_LOCALE must be zero. */
357
enum LocaleType {
358
    LT_NO_LOCALE = 0,
359
    LT_DEFAULT_LOCALE = ',',
360
    LT_UNDERSCORE_LOCALE = '_',
361
    LT_UNDER_FOUR_LOCALE,
362
    LT_CURRENT_LOCALE
363
};
364
365
typedef struct {
366
    Py_UCS4 fill_char;
367
    Py_UCS4 align;
368
    int alternate;
369
    int no_neg_0;
370
    Py_UCS4 sign;
371
    Py_ssize_t width;
372
    enum LocaleType thousands_separators;
373
    Py_ssize_t precision;
374
    enum LocaleType frac_thousands_separator;
375
    Py_UCS4 type;
376
} InternalFormatSpec;
377
378
379
/*
380
  ptr points to the start of the format_spec, end points just past its end.
381
  fills in format with the parsed information.
382
  returns 1 on success, 0 on failure.
383
  if failure, sets the exception
384
*/
385
static int
386
parse_internal_render_format_spec(PyObject *obj,
387
                                  PyObject *format_spec,
388
                                  Py_ssize_t start, Py_ssize_t end,
389
                                  InternalFormatSpec *format,
390
                                  char default_type,
391
                                  char default_align)
392
5.59M
{
393
5.59M
    Py_ssize_t pos = start;
394
5.59M
    int kind = PyUnicode_KIND(format_spec);
395
5.59M
    const void *data = PyUnicode_DATA(format_spec);
396
    /* end-pos is used throughout this code to specify the length of
397
       the input string */
398
61.5M
#define READ_spec(index) PyUnicode_READ(kind, data, index)
399
400
5.59M
    Py_ssize_t consumed;
401
5.59M
    int align_specified = 0;
402
5.59M
    int fill_char_specified = 0;
403
404
5.59M
    format->fill_char = ' ';
405
5.59M
    format->align = default_align;
406
5.59M
    format->alternate = 0;
407
5.59M
    format->no_neg_0 = 0;
408
5.59M
    format->sign = '\0';
409
5.59M
    format->width = -1;
410
5.59M
    format->thousands_separators = LT_NO_LOCALE;
411
5.59M
    format->frac_thousands_separator = LT_NO_LOCALE;
412
5.59M
    format->precision = -1;
413
5.59M
    format->type = default_type;
414
415
    /* If the second char is an alignment token,
416
       then parse the fill char */
417
5.59M
    if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) {
418
0
        format->align = READ_spec(pos+1);
419
0
        format->fill_char = READ_spec(pos);
420
0
        fill_char_specified = 1;
421
0
        align_specified = 1;
422
0
        pos += 2;
423
0
    }
424
5.59M
    else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) {
425
0
        format->align = READ_spec(pos);
426
0
        align_specified = 1;
427
0
        ++pos;
428
0
    }
429
430
    /* Parse the various sign options */
431
5.59M
    if (end-pos >= 1 && is_sign_element(READ_spec(pos))) {
432
0
        format->sign = READ_spec(pos);
433
0
        ++pos;
434
0
    }
435
436
    /* If the next character is z, request coercion of negative 0.
437
       Applies only to floats. */
438
5.59M
    if (end-pos >= 1 && READ_spec(pos) == 'z') {
439
0
        format->no_neg_0 = 1;
440
0
        ++pos;
441
0
    }
442
443
    /* If the next character is #, we're in alternate mode.  This only
444
       applies to integers. */
445
5.59M
    if (end-pos >= 1 && READ_spec(pos) == '#') {
446
0
        format->alternate = 1;
447
0
        ++pos;
448
0
    }
449
450
    /* The special case for 0-padding (backwards compat) */
451
5.59M
    if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') {
452
312
        format->fill_char = '0';
453
312
        if (!align_specified && default_align == '>') {
454
312
            format->align = '=';
455
312
        }
456
312
        ++pos;
457
312
    }
458
459
5.59M
    consumed = get_integer(format_spec, &pos, end, &format->width);
460
5.59M
    if (consumed == -1)
461
        /* Overflow error. Exception already set. */
462
0
        return 0;
463
464
    /* If consumed is 0, we didn't consume any characters for the
465
       width. In that case, reset the width to -1, because
466
       get_integer() will have set it to zero. -1 is how we record
467
       that the width wasn't specified. */
468
5.59M
    if (consumed == 0)
469
427
        format->width = -1;
470
471
    /* Comma signifies add thousands separators */
472
5.59M
    if (end-pos && READ_spec(pos) == ',') {
473
0
        format->thousands_separators = LT_DEFAULT_LOCALE;
474
0
        ++pos;
475
0
    }
476
    /* Underscore signifies add thousands separators */
477
5.59M
    if (end-pos && READ_spec(pos) == '_') {
478
0
        if (format->thousands_separators != LT_NO_LOCALE) {
479
0
            invalid_comma_and_underscore();
480
0
            return 0;
481
0
        }
482
0
        format->thousands_separators = LT_UNDERSCORE_LOCALE;
483
0
        ++pos;
484
0
    }
485
5.59M
    if (end-pos && READ_spec(pos) == ',') {
486
0
        if (format->thousands_separators == LT_UNDERSCORE_LOCALE) {
487
0
            invalid_comma_and_underscore();
488
0
            return 0;
489
0
        }
490
0
    }
491
492
    /* Parse field precision */
493
5.59M
    if (end-pos && READ_spec(pos) == '.') {
494
0
        ++pos;
495
496
0
        consumed = get_integer(format_spec, &pos, end, &format->precision);
497
0
        if (consumed == -1)
498
            /* Overflow error. Exception already set. */
499
0
            return 0;
500
501
0
        if (end-pos && READ_spec(pos) == ',') {
502
0
            if (consumed == 0) {
503
0
                format->precision = -1;
504
0
            }
505
0
            format->frac_thousands_separator = LT_DEFAULT_LOCALE;
506
0
            ++pos;
507
0
            ++consumed;
508
0
        }
509
0
        if (end-pos && READ_spec(pos) == '_') {
510
0
            if (format->frac_thousands_separator != LT_NO_LOCALE) {
511
0
                invalid_comma_and_underscore();
512
0
                return 0;
513
0
            }
514
0
            if (consumed == 0) {
515
0
                format->precision = -1;
516
0
            }
517
0
            format->frac_thousands_separator = LT_UNDERSCORE_LOCALE;
518
0
            ++pos;
519
0
            ++consumed;
520
0
        }
521
0
        if (end-pos && READ_spec(pos) == ',') {
522
0
            if (format->frac_thousands_separator == LT_UNDERSCORE_LOCALE) {
523
0
                invalid_comma_and_underscore();
524
0
                return 0;
525
0
            }
526
0
        }
527
528
        /* Not having a precision or underscore/comma after a dot
529
           is an error. */
530
0
        if (consumed == 0) {
531
0
            PyErr_Format(PyExc_ValueError,
532
0
                         "Format specifier missing precision");
533
0
            return 0;
534
0
        }
535
536
0
    }
537
538
    /* Finally, parse the type field. */
539
540
5.59M
    if (end-pos > 1) {
541
        /* More than one char remains, so this is an invalid format
542
           specifier. */
543
        /* Create a temporary object that contains the format spec we're
544
           operating on.  It's format_spec[start:end] (in Python syntax). */
545
0
        PyObject* actual_format_spec = PyUnicode_FromKindAndData(kind,
546
0
                                         (char*)data + kind*start,
547
0
                                         end-start);
548
0
        if (actual_format_spec != NULL) {
549
0
            PyErr_Format(PyExc_ValueError,
550
0
                "Invalid format specifier '%U' for object of type '%.200s'",
551
0
                actual_format_spec, Py_TYPE(obj)->tp_name);
552
0
            Py_DECREF(actual_format_spec);
553
0
        }
554
0
        return 0;
555
0
    }
556
557
5.59M
    if (end-pos == 1) {
558
5.59M
        format->type = READ_spec(pos);
559
5.59M
        ++pos;
560
5.59M
    }
561
562
    /* Do as much validating as we can, just by looking at the format
563
       specifier.  Do not take into account what type of formatting
564
       we're doing (int, float, string). */
565
566
5.59M
    if (format->thousands_separators) {
567
0
        switch (format->type) {
568
0
        case 'd':
569
0
        case 'e':
570
0
        case 'f':
571
0
        case 'g':
572
0
        case 'E':
573
0
        case 'G':
574
0
        case '%':
575
0
        case 'F':
576
0
        case '\0':
577
            /* These are allowed. See PEP 378.*/
578
0
            break;
579
0
        case 'b':
580
0
        case 'o':
581
0
        case 'x':
582
0
        case 'X':
583
            /* Underscores are allowed in bin/oct/hex. See PEP 515. */
584
0
            if (format->thousands_separators == LT_UNDERSCORE_LOCALE) {
585
                /* Every four digits, not every three, in bin/oct/hex. */
586
0
                format->thousands_separators = LT_UNDER_FOUR_LOCALE;
587
0
                break;
588
0
            }
589
0
            _Py_FALLTHROUGH;
590
0
        default:
591
0
            invalid_thousands_separator_type(format->thousands_separators, format->type);
592
0
            return 0;
593
0
        }
594
0
    }
595
596
5.59M
    if (format->type == 'n'
597
0
        && format->frac_thousands_separator != LT_NO_LOCALE)
598
0
    {
599
0
        invalid_thousands_separator_type(format->frac_thousands_separator,
600
0
                                         format->type);
601
0
        return 0;
602
0
    }
603
604
5.59M
    assert (format->align <= 127);
605
5.59M
    assert (format->sign <= 127);
606
5.59M
    return 1;
607
5.59M
}
608
609
/* Calculate the padding needed. */
610
static void
611
calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align,
612
             Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
613
             Py_ssize_t *n_total)
614
0
{
615
0
    if (width >= 0) {
616
0
        if (nchars > width)
617
0
            *n_total = nchars;
618
0
        else
619
0
            *n_total = width;
620
0
    }
621
0
    else {
622
        /* not specified, use all of the chars and no more */
623
0
        *n_total = nchars;
624
0
    }
625
626
    /* Figure out how much leading space we need, based on the
627
       aligning */
628
0
    if (align == '>')
629
0
        *n_lpadding = *n_total - nchars;
630
0
    else if (align == '^')
631
0
        *n_lpadding = (*n_total - nchars) / 2;
632
0
    else if (align == '<' || align == '=')
633
0
        *n_lpadding = 0;
634
0
    else {
635
        /* We should never have an unspecified alignment. */
636
0
        Py_UNREACHABLE();
637
0
    }
638
639
0
    *n_rpadding = *n_total - nchars - *n_lpadding;
640
0
}
641
642
/* Do the padding, and return a pointer to where the caller-supplied
643
   content goes. */
644
static int
645
fill_padding(_PyUnicodeWriter *writer,
646
             Py_ssize_t nchars,
647
             Py_UCS4 fill_char, Py_ssize_t n_lpadding,
648
             Py_ssize_t n_rpadding)
649
0
{
650
0
    Py_ssize_t pos;
651
652
    /* Pad on left. */
653
0
    if (n_lpadding) {
654
0
        pos = writer->pos;
655
0
        _PyUnicode_FastFill(writer->buffer, pos, n_lpadding, fill_char);
656
0
    }
657
658
    /* Pad on right. */
659
0
    if (n_rpadding) {
660
0
        pos = writer->pos + nchars + n_lpadding;
661
0
        _PyUnicode_FastFill(writer->buffer, pos, n_rpadding, fill_char);
662
0
    }
663
664
    /* Pointer to the user content. */
665
0
    writer->pos += n_lpadding;
666
0
    return 0;
667
0
}
668
669
/************************************************************************/
670
/*********** common routines for numeric formatting *********************/
671
/************************************************************************/
672
673
/* Locale info needed for formatting integers and the part of floats
674
   before and including the decimal. Note that locales only support
675
   8-bit chars, not unicode. */
676
typedef struct {
677
    PyObject *decimal_point;
678
    PyObject *thousands_sep;
679
    PyObject *frac_thousands_sep;
680
    const char *grouping;
681
    char *grouping_buffer;
682
} LocaleInfo;
683
684
5.59M
#define LocaleInfo_STATIC_INIT {0, 0, 0, 0}
685
686
/* describes the layout for an integer, see the comment in
687
   calc_number_widths() for details */
688
typedef struct {
689
    Py_ssize_t n_lpadding;
690
    Py_ssize_t n_prefix;
691
    Py_ssize_t n_spadding;
692
    Py_ssize_t n_rpadding;
693
    char sign;
694
    Py_ssize_t n_sign;      /* number of digits needed for sign (0/1) */
695
    Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
696
                                    any grouping chars. */
697
    Py_ssize_t n_decimal;   /* 0 if only an integer */
698
    Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
699
                               excluding the decimal itself, if
700
                               present. */
701
    Py_ssize_t n_frac;
702
    Py_ssize_t n_grouped_frac_digits;
703
704
    /* These 2 are not the widths of fields, but are needed by
705
       STRINGLIB_GROUPING. */
706
    Py_ssize_t n_digits;    /* The number of digits before a decimal
707
                               or exponent. */
708
    Py_ssize_t n_min_width; /* The min_width we used when we computed
709
                               the n_grouped_digits width. */
710
} NumberFieldWidths;
711
712
713
/* Given a number of the form:
714
   digits[remainder]
715
   where ptr points to the start and end points to the end, find where
716
    the integer part ends. This could be a decimal, an exponent, both,
717
    or neither.
718
   If a decimal point is present, set *has_decimal and increment
719
    remainder beyond it.
720
   Results are undefined (but shouldn't crash) for improperly
721
    formatted strings.
722
*/
723
static void
724
parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end,
725
             Py_ssize_t *n_remainder, Py_ssize_t *n_frac, int *has_decimal)
726
0
{
727
0
    Py_ssize_t frac;
728
0
    int kind = PyUnicode_KIND(s);
729
0
    const void *data = PyUnicode_DATA(s);
730
731
0
    while (pos<end && Py_ISDIGIT(PyUnicode_READ(kind, data, pos))) {
732
0
        ++pos;
733
0
    }
734
0
    frac = pos;
735
736
    /* Does remainder start with a decimal point? */
737
0
    *has_decimal = pos<end && PyUnicode_READ(kind, data, frac) == '.';
738
739
    /* Skip the decimal point. */
740
0
    if (*has_decimal) {
741
0
        frac++;
742
0
        pos++;
743
0
    }
744
745
0
    while (pos<end && Py_ISDIGIT(PyUnicode_READ(kind, data, pos))) {
746
0
        ++pos;
747
0
    }
748
749
0
    *n_frac = pos - frac;
750
0
    *n_remainder = end - pos;
751
0
}
752
753
/* not all fields of format are used.  for example, precision is
754
   unused.  should this take discrete params in order to be more clear
755
   about what it does?  or is passing a single format parameter easier
756
   and more efficient enough to justify a little obfuscation?
757
   Return -1 on error. */
758
static Py_ssize_t
759
calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
760
                   Py_UCS4 sign_char, Py_ssize_t n_start,
761
                   Py_ssize_t n_end, Py_ssize_t n_remainder, Py_ssize_t n_frac,
762
                   int has_decimal, const LocaleInfo *locale,
763
                   const InternalFormatSpec *format, Py_UCS4 *maxchar)
764
5.59M
{
765
5.59M
    Py_ssize_t n_non_digit_non_padding;
766
5.59M
    Py_ssize_t n_padding;
767
768
5.59M
    spec->n_digits = n_end - n_start - n_frac - n_remainder - (has_decimal?1:0);
769
5.59M
    spec->n_lpadding = 0;
770
5.59M
    spec->n_prefix = n_prefix;
771
5.59M
    spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0;
772
5.59M
    spec->n_remainder = n_remainder;
773
5.59M
    spec->n_frac = n_frac;
774
5.59M
    spec->n_spadding = 0;
775
5.59M
    spec->n_rpadding = 0;
776
5.59M
    spec->sign = '\0';
777
5.59M
    spec->n_sign = 0;
778
779
    /* the output will look like:
780
       |                                                                                         |
781
       | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
782
       |                                                                                         |
783
784
       sign is computed from format->sign and the actual
785
       sign of the number
786
787
       prefix is given (it's for the '0x' prefix)
788
789
       digits is already known
790
791
       the total width is either given, or computed from the
792
       actual digits
793
794
       only one of lpadding, spadding, and rpadding can be non-zero,
795
       and it's calculated from the width and other fields
796
    */
797
798
    /* compute the various parts we're going to write */
799
5.59M
    switch (format->sign) {
800
0
    case '+':
801
        /* always put a + or - */
802
0
        spec->n_sign = 1;
803
0
        spec->sign = (sign_char == '-' ? '-' : '+');
804
0
        break;
805
0
    case ' ':
806
0
        spec->n_sign = 1;
807
0
        spec->sign = (sign_char == '-' ? '-' : ' ');
808
0
        break;
809
5.59M
    default:
810
        /* Not specified, or the default (-) */
811
5.59M
        if (sign_char == '-') {
812
0
            spec->n_sign = 1;
813
0
            spec->sign = '-';
814
0
        }
815
5.59M
    }
816
817
5.59M
    if (spec->n_frac == 0) {
818
5.59M
        spec->n_grouped_frac_digits = 0;
819
5.59M
    }
820
0
    else {
821
0
        Py_UCS4 grouping_maxchar;
822
0
        spec->n_grouped_frac_digits = _PyUnicode_InsertThousandsGrouping(
823
0
            NULL, 0,
824
0
            NULL, 0, spec->n_frac,
825
0
            spec->n_frac,
826
0
            locale->grouping, locale->frac_thousands_sep, &grouping_maxchar, 1);
827
0
        if (spec->n_grouped_frac_digits == -1) {
828
0
            return -1;
829
0
        }
830
0
        *maxchar = Py_MAX(*maxchar, grouping_maxchar);
831
0
    }
832
833
    /* The number of chars used for non-digits and non-padding. */
834
5.59M
    n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
835
5.59M
        + spec->n_frac + spec->n_remainder;
836
837
    /* min_width can go negative, that's okay. format->width == -1 means
838
       we don't care. */
839
5.59M
    if (format->fill_char == '0' && format->align == '=')
840
312
        spec->n_min_width = (format->width - n_non_digit_non_padding
841
312
                             + spec->n_frac - spec->n_grouped_frac_digits);
842
5.59M
    else
843
5.59M
        spec->n_min_width = 0;
844
845
5.59M
    if (spec->n_digits == 0)
846
        /* This case only occurs when using 'c' formatting, we need
847
           to special case it because the grouping code always wants
848
           to have at least one character. */
849
0
        spec->n_grouped_digits = 0;
850
5.59M
    else {
851
5.59M
        Py_UCS4 grouping_maxchar;
852
5.59M
        spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
853
5.59M
            NULL, 0,
854
5.59M
            NULL, 0, spec->n_digits,
855
5.59M
            spec->n_min_width,
856
5.59M
            locale->grouping, locale->thousands_sep, &grouping_maxchar, 0);
857
5.59M
        if (spec->n_grouped_digits == -1) {
858
0
            return -1;
859
0
        }
860
5.59M
        *maxchar = Py_MAX(*maxchar, grouping_maxchar);
861
5.59M
    }
862
863
    /* Given the desired width and the total of digit and non-digit
864
       space we consume, see if we need any padding. format->width can
865
       be negative (meaning no padding), but this code still works in
866
       that case. */
867
5.59M
    n_padding = format->width -
868
5.59M
                        (n_non_digit_non_padding + spec->n_grouped_digits
869
5.59M
                         + spec->n_grouped_frac_digits - spec->n_frac);
870
5.59M
    if (n_padding > 0) {
871
        /* Some padding is needed. Determine if it's left, space, or right. */
872
14.5k
        switch (format->align) {
873
0
        case '<':
874
0
            spec->n_rpadding = n_padding;
875
0
            break;
876
0
        case '^':
877
0
            spec->n_lpadding = n_padding / 2;
878
0
            spec->n_rpadding = n_padding - spec->n_lpadding;
879
0
            break;
880
0
        case '=':
881
0
            spec->n_spadding = n_padding;
882
0
            break;
883
14.5k
        case '>':
884
14.5k
            spec->n_lpadding = n_padding;
885
14.5k
            break;
886
0
        default:
887
            /* Shouldn't get here */
888
0
            Py_UNREACHABLE();
889
14.5k
        }
890
14.5k
    }
891
892
5.59M
    if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
893
14.5k
        *maxchar = Py_MAX(*maxchar, format->fill_char);
894
895
5.59M
    if (spec->n_decimal) {
896
0
        Py_UCS4 point_maxchar = PyUnicode_MAX_CHAR_VALUE(locale->decimal_point);
897
0
        *maxchar = Py_MAX(*maxchar, point_maxchar);
898
0
    }
899
900
5.59M
    return spec->n_lpadding + spec->n_sign + spec->n_prefix +
901
5.59M
        spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
902
5.59M
        spec->n_grouped_frac_digits + spec->n_remainder + spec->n_rpadding;
903
5.59M
}
904
905
/* Fill in the digit parts of a number's string representation,
906
   as determined in calc_number_widths().
907
   Return -1 on error, or 0 on success. */
908
static int
909
fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec,
910
            PyObject *digits, Py_ssize_t d_start,
911
            PyObject *prefix, Py_ssize_t p_start,
912
            Py_UCS4 fill_char,
913
            LocaleInfo *locale, int toupper)
914
5.59M
{
915
    /* Used to keep track of digits, decimal, and remainder. */
916
5.59M
    Py_ssize_t d_pos = d_start;
917
5.59M
    const int kind = writer->kind;
918
5.59M
    const void *data = writer->data;
919
5.59M
    Py_ssize_t r;
920
921
5.59M
    if (spec->n_lpadding) {
922
14.5k
        _PyUnicode_FastFill(writer->buffer,
923
14.5k
                            writer->pos, spec->n_lpadding, fill_char);
924
14.5k
        writer->pos += spec->n_lpadding;
925
14.5k
    }
926
5.59M
    if (spec->n_sign == 1) {
927
0
        PyUnicode_WRITE(kind, data, writer->pos, spec->sign);
928
0
        writer->pos++;
929
0
    }
930
5.59M
    if (spec->n_prefix) {
931
0
        _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
932
0
                                      prefix, p_start,
933
0
                                      spec->n_prefix);
934
0
        if (toupper) {
935
0
            Py_ssize_t t;
936
0
            for (t = 0; t < spec->n_prefix; t++) {
937
0
                Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t);
938
0
                c = Py_TOUPPER(c);
939
0
                assert (c <= 127);
940
0
                PyUnicode_WRITE(kind, data, writer->pos + t, c);
941
0
            }
942
0
        }
943
0
        writer->pos += spec->n_prefix;
944
0
    }
945
5.59M
    if (spec->n_spadding) {
946
0
        _PyUnicode_FastFill(writer->buffer,
947
0
                            writer->pos, spec->n_spadding, fill_char);
948
0
        writer->pos += spec->n_spadding;
949
0
    }
950
951
    /* Only for type 'c' special case, it has no digits. */
952
5.59M
    if (spec->n_digits != 0) {
953
        /* Fill the digits with InsertThousandsGrouping. */
954
5.59M
        r = _PyUnicode_InsertThousandsGrouping(
955
5.59M
                writer, spec->n_grouped_digits,
956
5.59M
                digits, d_pos, spec->n_digits,
957
5.59M
                spec->n_min_width,
958
5.59M
                locale->grouping, locale->thousands_sep, NULL, 0);
959
5.59M
        if (r == -1)
960
0
            return -1;
961
5.59M
        assert(r == spec->n_grouped_digits);
962
5.59M
        d_pos += spec->n_digits;
963
5.59M
    }
964
5.59M
    if (toupper) {
965
0
        Py_ssize_t t;
966
0
        for (t = 0; t < spec->n_grouped_digits; t++) {
967
0
            Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t);
968
0
            c = Py_TOUPPER(c);
969
0
            if (c > 127) {
970
0
                PyErr_SetString(PyExc_SystemError, "non-ascii grouped digit");
971
0
                return -1;
972
0
            }
973
0
            PyUnicode_WRITE(kind, data, writer->pos + t, c);
974
0
        }
975
0
    }
976
5.59M
    writer->pos += spec->n_grouped_digits;
977
978
5.59M
    if (spec->n_decimal) {
979
0
        _PyUnicode_FastCopyCharacters(
980
0
            writer->buffer, writer->pos,
981
0
            locale->decimal_point, 0, spec->n_decimal);
982
0
        writer->pos += spec->n_decimal;
983
0
        d_pos += 1;
984
0
    }
985
986
5.59M
    if (spec->n_frac) {
987
0
        r = _PyUnicode_InsertThousandsGrouping(
988
0
                writer, spec->n_grouped_frac_digits,
989
0
                digits, d_pos, spec->n_frac, spec->n_frac,
990
0
                locale->grouping, locale->frac_thousands_sep, NULL, 1);
991
0
        if (r == -1) {
992
0
            return -1;
993
0
        }
994
0
        assert(r == spec->n_grouped_frac_digits);
995
0
        d_pos += spec->n_frac;
996
0
        writer->pos += spec->n_grouped_frac_digits;
997
0
    }
998
999
5.59M
    if (spec->n_remainder) {
1000
0
        _PyUnicode_FastCopyCharacters(
1001
0
            writer->buffer, writer->pos,
1002
0
            digits, d_pos, spec->n_remainder);
1003
0
        writer->pos += spec->n_remainder;
1004
        /* d_pos += spec->n_remainder; */
1005
0
    }
1006
1007
5.59M
    if (spec->n_rpadding) {
1008
0
        _PyUnicode_FastFill(writer->buffer,
1009
0
                            writer->pos, spec->n_rpadding,
1010
0
                            fill_char);
1011
0
        writer->pos += spec->n_rpadding;
1012
0
    }
1013
5.59M
    return 0;
1014
5.59M
}
1015
1016
static const char no_grouping[1] = {CHAR_MAX};
1017
1018
/* Find the decimal point character(s?), thousands_separator(s?), and
1019
   grouping description, either for the current locale if type is
1020
   LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE or
1021
   LT_UNDERSCORE_LOCALE/LT_UNDER_FOUR_LOCALE, or none if LT_NO_LOCALE. */
1022
static int
1023
get_locale_info(enum LocaleType type, enum LocaleType frac_type,
1024
                LocaleInfo *locale_info)
1025
5.59M
{
1026
5.59M
    switch (type) {
1027
0
    case LT_CURRENT_LOCALE: {
1028
0
        struct lconv *lc = localeconv();
1029
0
        if (_Py_GetLocaleconvNumeric(lc,
1030
0
                                     &locale_info->decimal_point,
1031
0
                                     &locale_info->thousands_sep) < 0) {
1032
0
            return -1;
1033
0
        }
1034
1035
        /* localeconv() grouping can become a dangling pointer or point
1036
           to a different string if another thread calls localeconv() during
1037
           the string formatting. Copy the string to avoid this risk. */
1038
0
        locale_info->grouping_buffer = _PyMem_Strdup(lc->grouping);
1039
0
        if (locale_info->grouping_buffer == NULL) {
1040
0
            PyErr_NoMemory();
1041
0
            return -1;
1042
0
        }
1043
0
        locale_info->grouping = locale_info->grouping_buffer;
1044
0
        break;
1045
0
    }
1046
0
    case LT_DEFAULT_LOCALE:
1047
0
    case LT_UNDERSCORE_LOCALE:
1048
0
    case LT_UNDER_FOUR_LOCALE:
1049
0
        locale_info->decimal_point = PyUnicode_FromOrdinal('.');
1050
0
        locale_info->thousands_sep = PyUnicode_FromOrdinal(
1051
0
            type == LT_DEFAULT_LOCALE ? ',' : '_');
1052
0
        if (!locale_info->decimal_point || !locale_info->thousands_sep)
1053
0
            return -1;
1054
0
        if (type != LT_UNDER_FOUR_LOCALE)
1055
0
            locale_info->grouping = "\3"; /* Group every 3 characters.  The
1056
                                         (implicit) trailing 0 means repeat
1057
                                         infinitely. */
1058
0
        else
1059
0
            locale_info->grouping = "\4"; /* Bin/oct/hex group every four. */
1060
0
        break;
1061
5.59M
    case LT_NO_LOCALE:
1062
5.59M
        locale_info->decimal_point = PyUnicode_FromOrdinal('.');
1063
5.59M
        locale_info->thousands_sep = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
1064
5.59M
        if (!locale_info->decimal_point || !locale_info->thousands_sep)
1065
0
            return -1;
1066
5.59M
        locale_info->grouping = no_grouping;
1067
5.59M
        break;
1068
5.59M
    }
1069
5.59M
    if (frac_type != LT_NO_LOCALE) {
1070
0
        locale_info->frac_thousands_sep = PyUnicode_FromOrdinal(
1071
0
            frac_type == LT_DEFAULT_LOCALE ? ',' : '_');
1072
0
        if (!locale_info->frac_thousands_sep) {
1073
0
            return -1;
1074
0
        }
1075
0
        if (locale_info->grouping == no_grouping) {
1076
0
            locale_info->grouping = "\3";
1077
0
        }
1078
0
    }
1079
5.59M
    else {
1080
5.59M
        locale_info->frac_thousands_sep = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
1081
5.59M
    }
1082
5.59M
    return 0;
1083
5.59M
}
1084
1085
static void
1086
free_locale_info(LocaleInfo *locale_info)
1087
5.59M
{
1088
5.59M
    Py_XDECREF(locale_info->decimal_point);
1089
5.59M
    Py_XDECREF(locale_info->thousands_sep);
1090
5.59M
    Py_XDECREF(locale_info->frac_thousands_sep);
1091
5.59M
    PyMem_Free(locale_info->grouping_buffer);
1092
5.59M
}
1093
1094
/************************************************************************/
1095
/*********** string formatting ******************************************/
1096
/************************************************************************/
1097
1098
static int
1099
format_string_internal(PyObject *value, const InternalFormatSpec *format,
1100
                       _PyUnicodeWriter *writer)
1101
0
{
1102
0
    Py_ssize_t lpad;
1103
0
    Py_ssize_t rpad;
1104
0
    Py_ssize_t total;
1105
0
    Py_ssize_t len;
1106
0
    int result = -1;
1107
0
    Py_UCS4 maxchar;
1108
1109
0
    len = PyUnicode_GET_LENGTH(value);
1110
1111
    /* sign is not allowed on strings */
1112
0
    if (format->sign != '\0') {
1113
0
        if (format->sign == ' ') {
1114
0
            PyErr_SetString(PyExc_ValueError,
1115
0
                "Space not allowed in string format specifier");
1116
0
        }
1117
0
        else {
1118
0
            PyErr_SetString(PyExc_ValueError,
1119
0
                "Sign not allowed in string format specifier");
1120
0
        }
1121
0
        goto done;
1122
0
    }
1123
1124
    /* negative 0 coercion is not allowed on strings */
1125
0
    if (format->no_neg_0) {
1126
0
        PyErr_SetString(PyExc_ValueError,
1127
0
                        "Negative zero coercion (z) not allowed in string format "
1128
0
                        "specifier");
1129
0
        goto done;
1130
0
    }
1131
1132
    /* alternate is not allowed on strings */
1133
0
    if (format->alternate) {
1134
0
        PyErr_SetString(PyExc_ValueError,
1135
0
                        "Alternate form (#) not allowed in string format "
1136
0
                        "specifier");
1137
0
        goto done;
1138
0
    }
1139
1140
    /* '=' alignment not allowed on strings */
1141
0
    if (format->align == '=') {
1142
0
        PyErr_SetString(PyExc_ValueError,
1143
0
                        "'=' alignment not allowed "
1144
0
                        "in string format specifier");
1145
0
        goto done;
1146
0
    }
1147
1148
0
    if ((format->width == -1 || format->width <= len)
1149
0
        && (format->precision == -1 || format->precision >= len)) {
1150
        /* Fast path */
1151
0
        return _PyUnicodeWriter_WriteStr(writer, value);
1152
0
    }
1153
1154
    /* if precision is specified, output no more that format.precision
1155
       characters */
1156
0
    if (format->precision >= 0 && len >= format->precision) {
1157
0
        len = format->precision;
1158
0
    }
1159
1160
0
    calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
1161
1162
0
    maxchar = writer->maxchar;
1163
0
    if (lpad != 0 || rpad != 0)
1164
0
        maxchar = Py_MAX(maxchar, format->fill_char);
1165
0
    if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) {
1166
0
        Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len);
1167
0
        maxchar = Py_MAX(maxchar, valmaxchar);
1168
0
    }
1169
1170
    /* allocate the resulting string */
1171
0
    if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1)
1172
0
        goto done;
1173
1174
    /* Write into that space. First the padding. */
1175
0
    result = fill_padding(writer, len, format->fill_char, lpad, rpad);
1176
0
    if (result == -1)
1177
0
        goto done;
1178
1179
    /* Then the source string. */
1180
0
    if (len) {
1181
0
        _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
1182
0
                                      value, 0, len);
1183
0
    }
1184
0
    writer->pos += (len + rpad);
1185
0
    result = 0;
1186
1187
0
done:
1188
0
    return result;
1189
0
}
1190
1191
1192
/************************************************************************/
1193
/*********** long formatting ********************************************/
1194
/************************************************************************/
1195
1196
static int
1197
format_long_internal(PyObject *value, const InternalFormatSpec *format,
1198
                     _PyUnicodeWriter *writer)
1199
5.59M
{
1200
5.59M
    int result = -1;
1201
5.59M
    Py_UCS4 maxchar = 127;
1202
5.59M
    PyObject *tmp = NULL;
1203
5.59M
    Py_ssize_t inumeric_chars;
1204
5.59M
    Py_UCS4 sign_char = '\0';
1205
5.59M
    Py_ssize_t n_digits;       /* count of digits need from the computed
1206
                                  string */
1207
5.59M
    Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
1208
                                   produces non-digits */
1209
5.59M
    Py_ssize_t n_prefix = 0;   /* Count of prefix chars, (e.g., '0x') */
1210
5.59M
    Py_ssize_t n_total;
1211
5.59M
    Py_ssize_t prefix = 0;
1212
5.59M
    NumberFieldWidths spec;
1213
5.59M
    long x;
1214
1215
    /* Locale settings, either from the actual locale or
1216
       from a hard-code pseudo-locale */
1217
5.59M
    LocaleInfo locale = LocaleInfo_STATIC_INIT;
1218
1219
    /* no precision allowed on integers */
1220
5.59M
    if (format->precision != -1) {
1221
0
        PyErr_SetString(PyExc_ValueError,
1222
0
                        "Precision not allowed in integer format specifier");
1223
0
        goto done;
1224
0
    }
1225
    /* no negative zero coercion on integers */
1226
5.59M
    if (format->no_neg_0) {
1227
0
        PyErr_SetString(PyExc_ValueError,
1228
0
                        "Negative zero coercion (z) not allowed in integer"
1229
0
                        " format specifier");
1230
0
        goto done;
1231
0
    }
1232
1233
    /* special case for character formatting */
1234
5.59M
    if (format->type == 'c') {
1235
        /* error to specify a sign */
1236
0
        if (format->sign != '\0') {
1237
0
            PyErr_SetString(PyExc_ValueError,
1238
0
                            "Sign not allowed with integer"
1239
0
                            " format specifier 'c'");
1240
0
            goto done;
1241
0
        }
1242
        /* error to request alternate format */
1243
0
        if (format->alternate) {
1244
0
            PyErr_SetString(PyExc_ValueError,
1245
0
                            "Alternate form (#) not allowed with integer"
1246
0
                            " format specifier 'c'");
1247
0
            goto done;
1248
0
        }
1249
1250
        /* taken from unicodeobject.c formatchar() */
1251
        /* Integer input truncated to a character */
1252
0
        x = PyLong_AsLong(value);
1253
0
        if (x == -1 && PyErr_Occurred())
1254
0
            goto done;
1255
0
        if (x < 0 || x > 0x10ffff) {
1256
0
            PyErr_SetString(PyExc_OverflowError,
1257
0
                            "%c arg not in range(0x110000)");
1258
0
            goto done;
1259
0
        }
1260
0
        tmp = PyUnicode_FromOrdinal(x);
1261
0
        inumeric_chars = 0;
1262
0
        n_digits = 1;
1263
0
        maxchar = Py_MAX(maxchar, (Py_UCS4)x);
1264
1265
        /* As a sort-of hack, we tell calc_number_widths that we only
1266
           have "remainder" characters. calc_number_widths thinks
1267
           these are characters that don't get formatted, only copied
1268
           into the output string. We do this for 'c' formatting,
1269
           because the characters are likely to be non-digits. */
1270
0
        n_remainder = 1;
1271
0
    }
1272
5.59M
    else {
1273
5.59M
        int base;
1274
5.59M
        int leading_chars_to_skip = 0;  /* Number of characters added by
1275
                                           PyNumber_ToBase that we want to
1276
                                           skip over. */
1277
1278
        /* Compute the base and how many characters will be added by
1279
           PyNumber_ToBase */
1280
5.59M
        switch (format->type) {
1281
0
        case 'b':
1282
0
            base = 2;
1283
0
            leading_chars_to_skip = 2; /* 0b */
1284
0
            break;
1285
0
        case 'o':
1286
0
            base = 8;
1287
0
            leading_chars_to_skip = 2; /* 0o */
1288
0
            break;
1289
739
        case 'x':
1290
739
        case 'X':
1291
739
            base = 16;
1292
739
            leading_chars_to_skip = 2; /* 0x */
1293
739
            break;
1294
0
        default:  /* shouldn't be needed, but stops a compiler warning */
1295
5.59M
        case 'd':
1296
5.59M
        case 'n':
1297
5.59M
            base = 10;
1298
5.59M
            break;
1299
5.59M
        }
1300
1301
5.59M
        if (format->sign != '+' && format->sign != ' '
1302
5.59M
            && format->width == -1
1303
427
            && format->type != 'X' && format->type != 'n'
1304
427
            && !format->thousands_separators
1305
427
            && PyLong_CheckExact(value))
1306
427
        {
1307
            /* Fast path */
1308
427
            return _PyLong_FormatWriter(writer, value, base, format->alternate);
1309
427
        }
1310
1311
        /* The number of prefix chars is the same as the leading
1312
           chars to skip */
1313
5.59M
        if (format->alternate)
1314
0
            n_prefix = leading_chars_to_skip;
1315
1316
        /* Do the hard part, converting to a string in a given base */
1317
5.59M
        tmp = _PyLong_Format(value, base);
1318
5.59M
        if (tmp == NULL)
1319
0
            goto done;
1320
1321
5.59M
        inumeric_chars = 0;
1322
5.59M
        n_digits = PyUnicode_GET_LENGTH(tmp);
1323
1324
5.59M
        prefix = inumeric_chars;
1325
1326
        /* Is a sign character present in the output?  If so, remember it
1327
           and skip it */
1328
5.59M
        if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') {
1329
0
            sign_char = '-';
1330
0
            ++prefix;
1331
0
            ++leading_chars_to_skip;
1332
0
        }
1333
1334
        /* Skip over the leading chars (0x, 0b, etc.) */
1335
5.59M
        n_digits -= leading_chars_to_skip;
1336
5.59M
        inumeric_chars += leading_chars_to_skip;
1337
5.59M
    }
1338
1339
    /* Determine the grouping, separator, and decimal point, if any. */
1340
5.59M
    if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1341
5.59M
                        format->thousands_separators, 0,
1342
5.59M
                        &locale) == -1)
1343
0
        goto done;
1344
1345
    /* Calculate how much memory we'll need. */
1346
5.59M
    n_total = calc_number_widths(&spec, n_prefix, sign_char, inumeric_chars,
1347
5.59M
                                 inumeric_chars + n_digits, n_remainder, 0, 0,
1348
5.59M
                                 &locale, format, &maxchar);
1349
5.59M
    if (n_total == -1) {
1350
0
        goto done;
1351
0
    }
1352
5.59M
    assert(n_total >= 1);
1353
1354
    /* Allocate the memory. */
1355
5.59M
    if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1)
1356
0
        goto done;
1357
1358
    /* Populate the memory. */
1359
5.59M
    result = fill_number(writer, &spec,
1360
5.59M
                         tmp, inumeric_chars,
1361
5.59M
                         tmp, prefix, format->fill_char,
1362
5.59M
                         &locale, format->type == 'X');
1363
1364
5.59M
done:
1365
5.59M
    Py_XDECREF(tmp);
1366
5.59M
    free_locale_info(&locale);
1367
5.59M
    return result;
1368
5.59M
}
1369
1370
/************************************************************************/
1371
/*********** float formatting *******************************************/
1372
/************************************************************************/
1373
1374
/* much of this is taken from unicodeobject.c */
1375
static int
1376
format_float_internal(PyObject *value,
1377
                      const InternalFormatSpec *format,
1378
                      _PyUnicodeWriter *writer)
1379
0
{
1380
0
    char *buf = NULL;       /* buffer returned from PyOS_double_to_string */
1381
0
    Py_ssize_t n_digits;
1382
0
    Py_ssize_t n_remainder;
1383
0
    Py_ssize_t n_frac;
1384
0
    Py_ssize_t n_total;
1385
0
    int has_decimal;
1386
0
    double val;
1387
0
    int precision, default_precision = 6;
1388
0
    Py_UCS4 type = format->type;
1389
0
    int add_pct = 0;
1390
0
    Py_ssize_t index;
1391
0
    NumberFieldWidths spec;
1392
0
    int flags = 0;
1393
0
    int result = -1;
1394
0
    Py_UCS4 maxchar = 127;
1395
0
    Py_UCS4 sign_char = '\0';
1396
0
    int float_type; /* Used to see if we have a nan, inf, or regular float. */
1397
0
    PyObject *unicode_tmp = NULL;
1398
1399
    /* Locale settings, either from the actual locale or
1400
       from a hard-code pseudo-locale */
1401
0
    LocaleInfo locale = LocaleInfo_STATIC_INIT;
1402
1403
0
    if (format->precision > INT_MAX) {
1404
0
        PyErr_SetString(PyExc_ValueError, "precision too big");
1405
0
        goto done;
1406
0
    }
1407
0
    precision = (int)format->precision;
1408
1409
0
    if (format->alternate)
1410
0
        flags |= Py_DTSF_ALT;
1411
0
    if (format->no_neg_0)
1412
0
        flags |= Py_DTSF_NO_NEG_0;
1413
1414
0
    if (type == '\0') {
1415
        /* Omitted type specifier.  Behaves in the same way as repr(x)
1416
           and str(x) if no precision is given, else like 'g', but with
1417
           at least one digit after the decimal point. */
1418
0
        flags |= Py_DTSF_ADD_DOT_0;
1419
0
        type = 'r';
1420
0
        default_precision = 0;
1421
0
    }
1422
1423
0
    if (type == 'n')
1424
        /* 'n' is the same as 'g', except for the locale used to
1425
           format the result. We take care of that later. */
1426
0
        type = 'g';
1427
1428
0
    val = PyFloat_AsDouble(value);
1429
0
    if (val == -1.0 && PyErr_Occurred())
1430
0
        goto done;
1431
1432
0
    if (type == '%') {
1433
0
        type = 'f';
1434
0
        val *= 100;
1435
0
        add_pct = 1;
1436
0
    }
1437
1438
0
    if (precision < 0)
1439
0
        precision = default_precision;
1440
0
    else if (type == 'r')
1441
0
        type = 'g';
1442
1443
    /* Cast "type", because if we're in unicode we need to pass an
1444
       8-bit char. This is safe, because we've restricted what "type"
1445
       can be. */
1446
0
    buf = PyOS_double_to_string(val, (char)type, precision, flags,
1447
0
                                &float_type);
1448
0
    if (buf == NULL)
1449
0
        goto done;
1450
0
    n_digits = strlen(buf);
1451
1452
0
    if (add_pct) {
1453
        /* We know that buf has a trailing zero (since we just called
1454
           strlen() on it), and we don't use that fact any more. So we
1455
           can just write over the trailing zero. */
1456
0
        buf[n_digits] = '%';
1457
0
        n_digits += 1;
1458
0
    }
1459
1460
0
    if (format->sign != '+' && format->sign != ' '
1461
0
        && format->width == -1
1462
0
        && format->type != 'n'
1463
0
        && !format->thousands_separators
1464
0
        && !format->frac_thousands_separator)
1465
0
    {
1466
        /* Fast path */
1467
0
        result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits);
1468
0
        PyMem_Free(buf);
1469
0
        return result;
1470
0
    }
1471
1472
    /* Since there is no unicode version of PyOS_double_to_string,
1473
       just use the 8 bit version and then convert to unicode. */
1474
0
    unicode_tmp = _PyUnicode_FromASCII(buf, n_digits);
1475
0
    PyMem_Free(buf);
1476
0
    if (unicode_tmp == NULL)
1477
0
        goto done;
1478
1479
    /* Is a sign character present in the output?  If so, remember it
1480
       and skip it */
1481
0
    index = 0;
1482
0
    if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') {
1483
0
        sign_char = '-';
1484
0
        ++index;
1485
0
        --n_digits;
1486
0
    }
1487
1488
    /* Determine if we have any "remainder" (after the digits, might include
1489
       decimal or exponent or both (or neither)) */
1490
0
    parse_number(unicode_tmp, index, index + n_digits,
1491
0
                 &n_remainder, &n_frac, &has_decimal);
1492
1493
    /* Determine the grouping, separator, and decimal point, if any. */
1494
0
    if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1495
0
                        format->thousands_separators,
1496
0
                        format->frac_thousands_separator,
1497
0
                        &locale) == -1)
1498
0
        goto done;
1499
1500
    /* Calculate how much memory we'll need. */
1501
0
    n_total = calc_number_widths(&spec, 0, sign_char, index,
1502
0
                                 index + n_digits, n_remainder, n_frac,
1503
0
                                 has_decimal, &locale, format, &maxchar);
1504
0
    if (n_total == -1) {
1505
0
        goto done;
1506
0
    }
1507
0
    assert(n_total >= 1);
1508
1509
    /* Allocate the memory. */
1510
0
    if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1)
1511
0
        goto done;
1512
1513
    /* Populate the memory. */
1514
0
    result = fill_number(writer, &spec,
1515
0
                         unicode_tmp, index,
1516
0
                         NULL, 0, format->fill_char,
1517
0
                         &locale, 0);
1518
1519
0
done:
1520
0
    Py_XDECREF(unicode_tmp);
1521
0
    free_locale_info(&locale);
1522
0
    return result;
1523
0
}
1524
1525
/************************************************************************/
1526
/*********** complex formatting *****************************************/
1527
/************************************************************************/
1528
1529
static int
1530
format_complex_internal(PyObject *value,
1531
                        const InternalFormatSpec *format,
1532
                        _PyUnicodeWriter *writer)
1533
0
{
1534
0
    double re;
1535
0
    double im;
1536
0
    char *re_buf = NULL;       /* buffer returned from PyOS_double_to_string */
1537
0
    char *im_buf = NULL;       /* buffer returned from PyOS_double_to_string */
1538
1539
0
    InternalFormatSpec tmp_format = *format;
1540
0
    Py_ssize_t n_re_digits;
1541
0
    Py_ssize_t n_im_digits;
1542
0
    Py_ssize_t n_re_remainder;
1543
0
    Py_ssize_t n_im_remainder;
1544
0
    Py_ssize_t n_re_frac;
1545
0
    Py_ssize_t n_im_frac;
1546
0
    Py_ssize_t n_re_total;
1547
0
    Py_ssize_t n_im_total;
1548
0
    int re_has_decimal;
1549
0
    int im_has_decimal;
1550
0
    int precision, default_precision = 6;
1551
0
    Py_UCS4 type = format->type;
1552
0
    Py_ssize_t i_re;
1553
0
    Py_ssize_t i_im;
1554
0
    NumberFieldWidths re_spec;
1555
0
    NumberFieldWidths im_spec;
1556
0
    int flags = 0;
1557
0
    int result = -1;
1558
0
    Py_UCS4 maxchar = 127;
1559
0
    int rkind;
1560
0
    void *rdata;
1561
0
    Py_UCS4 re_sign_char = '\0';
1562
0
    Py_UCS4 im_sign_char = '\0';
1563
0
    int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
1564
0
    int im_float_type;
1565
0
    int add_parens = 0;
1566
0
    int skip_re = 0;
1567
0
    Py_ssize_t lpad;
1568
0
    Py_ssize_t rpad;
1569
0
    Py_ssize_t total;
1570
0
    PyObject *re_unicode_tmp = NULL;
1571
0
    PyObject *im_unicode_tmp = NULL;
1572
1573
    /* Locale settings, either from the actual locale or
1574
       from a hard-code pseudo-locale */
1575
0
    LocaleInfo locale = LocaleInfo_STATIC_INIT;
1576
1577
0
    if (format->precision > INT_MAX) {
1578
0
        PyErr_SetString(PyExc_ValueError, "precision too big");
1579
0
        goto done;
1580
0
    }
1581
0
    precision = (int)format->precision;
1582
1583
    /* Zero padding is not allowed. */
1584
0
    if (format->fill_char == '0') {
1585
0
        PyErr_SetString(PyExc_ValueError,
1586
0
                        "Zero padding is not allowed in complex format "
1587
0
                        "specifier");
1588
0
        goto done;
1589
0
    }
1590
1591
    /* Neither is '=' alignment . */
1592
0
    if (format->align == '=') {
1593
0
        PyErr_SetString(PyExc_ValueError,
1594
0
                        "'=' alignment flag is not allowed in complex format "
1595
0
                        "specifier");
1596
0
        goto done;
1597
0
    }
1598
1599
0
    re = PyComplex_RealAsDouble(value);
1600
0
    if (re == -1.0 && PyErr_Occurred())
1601
0
        goto done;
1602
0
    im = PyComplex_ImagAsDouble(value);
1603
0
    if (im == -1.0 && PyErr_Occurred())
1604
0
        goto done;
1605
1606
0
    if (format->alternate)
1607
0
        flags |= Py_DTSF_ALT;
1608
0
    if (format->no_neg_0)
1609
0
        flags |= Py_DTSF_NO_NEG_0;
1610
1611
0
    if (type == '\0') {
1612
        /* Omitted type specifier. Should be like str(self). */
1613
0
        type = 'r';
1614
0
        default_precision = 0;
1615
0
        if (re == 0.0 && copysign(1.0, re) == 1.0)
1616
0
            skip_re = 1;
1617
0
        else
1618
0
            add_parens = 1;
1619
0
    }
1620
1621
0
    if (type == 'n')
1622
        /* 'n' is the same as 'g', except for the locale used to
1623
           format the result. We take care of that later. */
1624
0
        type = 'g';
1625
1626
0
    if (precision < 0)
1627
0
        precision = default_precision;
1628
0
    else if (type == 'r')
1629
0
        type = 'g';
1630
1631
    /* Cast "type", because if we're in unicode we need to pass an
1632
       8-bit char. This is safe, because we've restricted what "type"
1633
       can be. */
1634
0
    re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
1635
0
                                   &re_float_type);
1636
0
    if (re_buf == NULL)
1637
0
        goto done;
1638
0
    im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
1639
0
                                   &im_float_type);
1640
0
    if (im_buf == NULL)
1641
0
        goto done;
1642
1643
0
    n_re_digits = strlen(re_buf);
1644
0
    n_im_digits = strlen(im_buf);
1645
1646
    /* Since there is no unicode version of PyOS_double_to_string,
1647
       just use the 8 bit version and then convert to unicode. */
1648
0
    re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits);
1649
0
    if (re_unicode_tmp == NULL)
1650
0
        goto done;
1651
0
    i_re = 0;
1652
1653
0
    im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits);
1654
0
    if (im_unicode_tmp == NULL)
1655
0
        goto done;
1656
0
    i_im = 0;
1657
1658
    /* Is a sign character present in the output?  If so, remember it
1659
       and skip it */
1660
0
    if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') {
1661
0
        re_sign_char = '-';
1662
0
        ++i_re;
1663
0
        --n_re_digits;
1664
0
    }
1665
0
    if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') {
1666
0
        im_sign_char = '-';
1667
0
        ++i_im;
1668
0
        --n_im_digits;
1669
0
    }
1670
1671
    /* Determine if we have any "remainder" (after the digits, might include
1672
       decimal or exponent or both (or neither)) */
1673
0
    parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
1674
0
                 &n_re_remainder, &n_re_frac, &re_has_decimal);
1675
0
    parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
1676
0
                 &n_im_remainder, &n_im_frac, &im_has_decimal);
1677
1678
    /* Determine the grouping, separator, and decimal point, if any. */
1679
0
    if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1680
0
                        format->thousands_separators,
1681
0
                        format->frac_thousands_separator,
1682
0
                        &locale) == -1)
1683
0
        goto done;
1684
1685
    /* Turn off any padding. We'll do it later after we've composed
1686
       the numbers without padding. */
1687
0
    tmp_format.fill_char = '\0';
1688
0
    tmp_format.align = '<';
1689
0
    tmp_format.width = -1;
1690
1691
    /* Calculate how much memory we'll need. */
1692
0
    n_re_total = calc_number_widths(&re_spec, 0, re_sign_char,
1693
0
                                    i_re, i_re + n_re_digits, n_re_remainder,
1694
0
                                    n_re_frac, re_has_decimal, &locale,
1695
0
                                    &tmp_format, &maxchar);
1696
0
    if (n_re_total == -1) {
1697
0
        goto done;
1698
0
    }
1699
1700
    /* Same formatting, but always include a sign, unless the real part is
1701
     * going to be omitted, in which case we use whatever sign convention was
1702
     * requested by the original format. */
1703
0
    if (!skip_re)
1704
0
        tmp_format.sign = '+';
1705
0
    n_im_total = calc_number_widths(&im_spec, 0, im_sign_char,
1706
0
                                    i_im, i_im + n_im_digits, n_im_remainder,
1707
0
                                    n_im_frac, im_has_decimal, &locale,
1708
0
                                    &tmp_format, &maxchar);
1709
0
    if (n_im_total == -1) {
1710
0
        goto done;
1711
0
    }
1712
1713
0
    if (skip_re)
1714
0
        n_re_total = 0;
1715
1716
    /* Add 1 for the 'j', and optionally 2 for parens. */
1717
0
    calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
1718
0
                 format->width, format->align, &lpad, &rpad, &total);
1719
0
    assert(total >= 1);
1720
1721
0
    if (lpad || rpad)
1722
0
        maxchar = Py_MAX(maxchar, format->fill_char);
1723
1724
0
    if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1)
1725
0
        goto done;
1726
0
    rkind = writer->kind;
1727
0
    rdata = writer->data;
1728
1729
    /* Populate the memory. First, the padding. */
1730
0
    result = fill_padding(writer,
1731
0
                          n_re_total + n_im_total + 1 + add_parens * 2,
1732
0
                          format->fill_char, lpad, rpad);
1733
0
    if (result == -1)
1734
0
        goto done;
1735
1736
0
    if (add_parens) {
1737
0
        PyUnicode_WRITE(rkind, rdata, writer->pos, '(');
1738
0
        writer->pos++;
1739
0
    }
1740
1741
0
    if (!skip_re) {
1742
0
        result = fill_number(writer, &re_spec,
1743
0
                             re_unicode_tmp, i_re,
1744
0
                             NULL, 0,
1745
0
                             0,
1746
0
                             &locale, 0);
1747
0
        if (result == -1)
1748
0
            goto done;
1749
0
    }
1750
0
    result = fill_number(writer, &im_spec,
1751
0
                         im_unicode_tmp, i_im,
1752
0
                         NULL, 0,
1753
0
                         0,
1754
0
                         &locale, 0);
1755
0
    if (result == -1)
1756
0
        goto done;
1757
0
    PyUnicode_WRITE(rkind, rdata, writer->pos, 'j');
1758
0
    writer->pos++;
1759
1760
0
    if (add_parens) {
1761
0
        PyUnicode_WRITE(rkind, rdata, writer->pos, ')');
1762
0
        writer->pos++;
1763
0
    }
1764
1765
0
    writer->pos += rpad;
1766
1767
0
done:
1768
0
    PyMem_Free(re_buf);
1769
0
    PyMem_Free(im_buf);
1770
0
    Py_XDECREF(re_unicode_tmp);
1771
0
    Py_XDECREF(im_unicode_tmp);
1772
0
    free_locale_info(&locale);
1773
0
    return result;
1774
0
}
1775
1776
/************************************************************************/
1777
/*********** built in formatters ****************************************/
1778
/************************************************************************/
1779
static int
1780
format_obj(PyObject *obj, _PyUnicodeWriter *writer)
1781
0
{
1782
0
    PyObject *str;
1783
0
    int err;
1784
1785
0
    str = PyObject_Str(obj);
1786
0
    if (str == NULL)
1787
0
        return -1;
1788
0
    err = _PyUnicodeWriter_WriteStr(writer, str);
1789
0
    Py_DECREF(str);
1790
0
    return err;
1791
0
}
1792
1793
int
1794
_PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer,
1795
                                PyObject *obj,
1796
                                PyObject *format_spec,
1797
                                Py_ssize_t start, Py_ssize_t end)
1798
16.8M
{
1799
16.8M
    InternalFormatSpec format;
1800
1801
16.8M
    assert(PyUnicode_Check(obj));
1802
1803
    /* check for the special case of zero length format spec, make
1804
       it equivalent to str(obj) */
1805
16.8M
    if (start == end) {
1806
16.8M
        if (PyUnicode_CheckExact(obj))
1807
16.8M
            return _PyUnicodeWriter_WriteStr(writer, obj);
1808
0
        else
1809
0
            return format_obj(obj, writer);
1810
16.8M
    }
1811
1812
    /* parse the format_spec */
1813
0
    if (!parse_internal_render_format_spec(obj, format_spec, start, end,
1814
0
                                           &format, 's', '<'))
1815
0
        return -1;
1816
1817
    /* type conversion? */
1818
0
    switch (format.type) {
1819
0
    case 's':
1820
        /* no type conversion needed, already a string.  do the formatting */
1821
0
        return format_string_internal(obj, &format, writer);
1822
0
    default:
1823
        /* unknown */
1824
0
        unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
1825
0
        return -1;
1826
0
    }
1827
0
}
1828
1829
int
1830
_PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer,
1831
                             PyObject *obj,
1832
                             PyObject *format_spec,
1833
                             Py_ssize_t start, Py_ssize_t end)
1834
5.64M
{
1835
5.64M
    PyObject *tmp = NULL;
1836
5.64M
    InternalFormatSpec format;
1837
5.64M
    int result = -1;
1838
1839
    /* check for the special case of zero length format spec, make
1840
       it equivalent to str(obj) */
1841
5.64M
    if (start == end) {
1842
54.4k
        if (PyLong_CheckExact(obj))
1843
54.4k
            return _PyLong_FormatWriter(writer, obj, 10, 0);
1844
0
        else
1845
0
            return format_obj(obj, writer);
1846
54.4k
    }
1847
1848
    /* parse the format_spec */
1849
5.59M
    if (!parse_internal_render_format_spec(obj, format_spec, start, end,
1850
5.59M
                                           &format, 'd', '>'))
1851
0
        goto done;
1852
1853
    /* type conversion? */
1854
5.59M
    switch (format.type) {
1855
0
    case 'b':
1856
0
    case 'c':
1857
5.59M
    case 'd':
1858
5.59M
    case 'o':
1859
5.59M
    case 'x':
1860
5.59M
    case 'X':
1861
5.59M
    case 'n':
1862
        /* no type conversion needed, already an int.  do the formatting */
1863
5.59M
        result = format_long_internal(obj, &format, writer);
1864
5.59M
        break;
1865
1866
0
    case 'e':
1867
0
    case 'E':
1868
0
    case 'f':
1869
0
    case 'F':
1870
0
    case 'g':
1871
0
    case 'G':
1872
0
    case '%':
1873
        /* convert to float */
1874
0
        tmp = PyNumber_Float(obj);
1875
0
        if (tmp == NULL)
1876
0
            goto done;
1877
0
        result = format_float_internal(tmp, &format, writer);
1878
0
        break;
1879
1880
0
    default:
1881
        /* unknown */
1882
0
        unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
1883
0
        goto done;
1884
5.59M
    }
1885
1886
5.59M
done:
1887
5.59M
    Py_XDECREF(tmp);
1888
5.59M
    return result;
1889
5.59M
}
1890
1891
int
1892
_PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer,
1893
                              PyObject *obj,
1894
                              PyObject *format_spec,
1895
                              Py_ssize_t start, Py_ssize_t end)
1896
0
{
1897
0
    InternalFormatSpec format;
1898
1899
    /* check for the special case of zero length format spec, make
1900
       it equivalent to str(obj) */
1901
0
    if (start == end)
1902
0
        return format_obj(obj, writer);
1903
1904
    /* parse the format_spec */
1905
0
    if (!parse_internal_render_format_spec(obj, format_spec, start, end,
1906
0
                                           &format, '\0', '>'))
1907
0
        return -1;
1908
1909
    /* type conversion? */
1910
0
    switch (format.type) {
1911
0
    case '\0': /* No format code: like 'g', but with at least one decimal. */
1912
0
    case 'e':
1913
0
    case 'E':
1914
0
    case 'f':
1915
0
    case 'F':
1916
0
    case 'g':
1917
0
    case 'G':
1918
0
    case 'n':
1919
0
    case '%':
1920
        /* no conversion, already a float.  do the formatting */
1921
0
        return format_float_internal(obj, &format, writer);
1922
1923
0
    default:
1924
        /* unknown */
1925
0
        unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
1926
0
        return -1;
1927
0
    }
1928
0
}
1929
1930
int
1931
_PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer,
1932
                                PyObject *obj,
1933
                                PyObject *format_spec,
1934
                                Py_ssize_t start, Py_ssize_t end)
1935
0
{
1936
0
    InternalFormatSpec format;
1937
1938
    /* check for the special case of zero length format spec, make
1939
       it equivalent to str(obj) */
1940
0
    if (start == end)
1941
0
        return format_obj(obj, writer);
1942
1943
    /* parse the format_spec */
1944
0
    if (!parse_internal_render_format_spec(obj, format_spec, start, end,
1945
0
                                           &format, '\0', '>'))
1946
0
        return -1;
1947
1948
    /* type conversion? */
1949
0
    switch (format.type) {
1950
0
    case '\0': /* No format code: like 'g', but with at least one decimal. */
1951
0
    case 'e':
1952
0
    case 'E':
1953
0
    case 'f':
1954
0
    case 'F':
1955
0
    case 'g':
1956
0
    case 'G':
1957
0
    case 'n':
1958
        /* no conversion, already a complex.  do the formatting */
1959
0
        return format_complex_internal(obj, &format, writer);
1960
1961
0
    default:
1962
        /* unknown */
1963
0
        unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
1964
0
        return -1;
1965
0
    }
1966
0
}