blob: 52ccafa8d085021310a25524c88fc52c17a0f62d [file] [log] [blame]
Eric Smith8c663262007-08-25 02:26:07 +00001/* 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"
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02006#include <locale.h>
7
8/* Raises an exception about an unknown presentation type for this
9 * type. */
10
11static void
12unknown_presentation_type(Py_UCS4 presentation_type,
13 const char* type_name)
14{
15 /* %c might be out-of-range, hence the two cases. */
16 if (presentation_type > 32 && presentation_type < 128)
17 PyErr_Format(PyExc_ValueError,
18 "Unknown format code '%c' "
19 "for object of type '%.200s'",
20 (char)presentation_type,
21 type_name);
22 else
23 PyErr_Format(PyExc_ValueError,
24 "Unknown format code '\\x%x' "
25 "for object of type '%.200s'",
26 (unsigned int)presentation_type,
27 type_name);
28}
29
30static void
31invalid_comma_type(Py_UCS4 presentation_type)
32{
33 if (presentation_type > 32 && presentation_type < 128)
34 PyErr_Format(PyExc_ValueError,
35 "Cannot specify ',' with '%c'.",
36 (char)presentation_type);
37 else
38 PyErr_Format(PyExc_ValueError,
39 "Cannot specify ',' with '\\x%x'.",
40 (unsigned int)presentation_type);
41}
42
43/*
44 get_integer consumes 0 or more decimal digit characters from an
45 input string, updates *result with the corresponding positive
46 integer, and returns the number of digits consumed.
47
48 returns -1 on error.
49*/
50static int
51get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end,
52 Py_ssize_t *result)
53{
54 Py_ssize_t accumulator, digitval, oldaccumulator;
55 int numdigits;
56 accumulator = numdigits = 0;
57 for (;;(*pos)++, numdigits++) {
58 if (*pos >= end)
59 break;
60 digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str, *pos));
61 if (digitval < 0)
62 break;
63 /*
64 This trick was copied from old Unicode format code. It's cute,
65 but would really suck on an old machine with a slow divide
66 implementation. Fortunately, in the normal case we do not
67 expect too many digits.
68 */
69 oldaccumulator = accumulator;
70 accumulator *= 10;
71 if ((accumulator+10)/10 != oldaccumulator+1) {
72 PyErr_Format(PyExc_ValueError,
73 "Too many decimal digits in format string");
74 return -1;
75 }
76 accumulator += digitval;
77 }
78 *result = accumulator;
79 return numdigits;
80}
81
82/************************************************************************/
83/*********** standard format specifier parsing **************************/
84/************************************************************************/
85
86/* returns true if this character is a specifier alignment token */
87Py_LOCAL_INLINE(int)
88is_alignment_token(Py_UCS4 c)
89{
90 switch (c) {
91 case '<': case '>': case '=': case '^':
92 return 1;
93 default:
94 return 0;
95 }
96}
97
98/* returns true if this character is a sign element */
99Py_LOCAL_INLINE(int)
100is_sign_element(Py_UCS4 c)
101{
102 switch (c) {
103 case ' ': case '+': case '-':
104 return 1;
105 default:
106 return 0;
107 }
108}
Eric Smith8c663262007-08-25 02:26:07 +0000109
Eric Smith4a7d76d2008-05-30 18:10:19 +0000110
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200111typedef struct {
112 Py_UCS4 fill_char;
113 Py_UCS4 align;
114 int alternate;
115 Py_UCS4 sign;
116 Py_ssize_t width;
117 int thousands_separators;
118 Py_ssize_t precision;
119 Py_UCS4 type;
120} InternalFormatSpec;
Eric Smith4a7d76d2008-05-30 18:10:19 +0000121
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200122#if 0
123/* Occassionally useful for debugging. Should normally be commented out. */
124static void
125DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
126{
127 printf("internal format spec: fill_char %d\n", format->fill_char);
128 printf("internal format spec: align %d\n", format->align);
129 printf("internal format spec: alternate %d\n", format->alternate);
130 printf("internal format spec: sign %d\n", format->sign);
131 printf("internal format spec: width %zd\n", format->width);
132 printf("internal format spec: thousands_separators %d\n",
133 format->thousands_separators);
134 printf("internal format spec: precision %zd\n", format->precision);
135 printf("internal format spec: type %c\n", format->type);
136 printf("\n");
137}
138#endif
139
140
141/*
142 ptr points to the start of the format_spec, end points just past its end.
143 fills in format with the parsed information.
144 returns 1 on success, 0 on failure.
145 if failure, sets the exception
146*/
147static int
148parse_internal_render_format_spec(PyObject *format_spec,
149 Py_ssize_t start, Py_ssize_t end,
150 InternalFormatSpec *format,
151 char default_type,
152 char default_align)
153{
154 Py_ssize_t pos = start;
155 /* end-pos is used throughout this code to specify the length of
156 the input string */
157#define READ_spec(index) PyUnicode_READ_CHAR(format_spec, index)
158
159 Py_ssize_t consumed;
160 int align_specified = 0;
161
162 format->fill_char = '\0';
163 format->align = default_align;
164 format->alternate = 0;
165 format->sign = '\0';
166 format->width = -1;
167 format->thousands_separators = 0;
168 format->precision = -1;
169 format->type = default_type;
170
171 /* If the second char is an alignment token,
172 then parse the fill char */
173 if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) {
174 format->align = READ_spec(pos+1);
175 format->fill_char = READ_spec(pos);
176 align_specified = 1;
177 pos += 2;
178 }
179 else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) {
180 format->align = READ_spec(pos);
181 align_specified = 1;
182 ++pos;
183 }
184
185 /* Parse the various sign options */
186 if (end-pos >= 1 && is_sign_element(READ_spec(pos))) {
187 format->sign = READ_spec(pos);
188 ++pos;
189 }
190
191 /* If the next character is #, we're in alternate mode. This only
192 applies to integers. */
193 if (end-pos >= 1 && READ_spec(pos) == '#') {
194 format->alternate = 1;
195 ++pos;
196 }
197
198 /* The special case for 0-padding (backwards compat) */
199 if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') {
200 format->fill_char = '0';
201 if (!align_specified) {
202 format->align = '=';
203 }
204 ++pos;
205 }
206
207 consumed = get_integer(format_spec, &pos, end, &format->width);
208 if (consumed == -1)
209 /* Overflow error. Exception already set. */
210 return 0;
211
212 /* If consumed is 0, we didn't consume any characters for the
213 width. In that case, reset the width to -1, because
214 get_integer() will have set it to zero. -1 is how we record
215 that the width wasn't specified. */
216 if (consumed == 0)
217 format->width = -1;
218
219 /* Comma signifies add thousands separators */
220 if (end-pos && READ_spec(pos) == ',') {
221 format->thousands_separators = 1;
222 ++pos;
223 }
224
225 /* Parse field precision */
226 if (end-pos && READ_spec(pos) == '.') {
227 ++pos;
228
229 consumed = get_integer(format_spec, &pos, end, &format->precision);
230 if (consumed == -1)
231 /* Overflow error. Exception already set. */
232 return 0;
233
234 /* Not having a precision after a dot is an error. */
235 if (consumed == 0) {
236 PyErr_Format(PyExc_ValueError,
237 "Format specifier missing precision");
238 return 0;
239 }
240
241 }
242
243 /* Finally, parse the type field. */
244
245 if (end-pos > 1) {
246 /* More than one char remain, invalid conversion spec. */
247 PyErr_Format(PyExc_ValueError, "Invalid conversion specification");
248 return 0;
249 }
250
251 if (end-pos == 1) {
252 format->type = READ_spec(pos);
253 ++pos;
254 }
255
256 /* Do as much validating as we can, just by looking at the format
257 specifier. Do not take into account what type of formatting
258 we're doing (int, float, string). */
259
260 if (format->thousands_separators) {
261 switch (format->type) {
262 case 'd':
263 case 'e':
264 case 'f':
265 case 'g':
266 case 'E':
267 case 'G':
268 case '%':
269 case 'F':
270 case '\0':
271 /* These are allowed. See PEP 378.*/
272 break;
273 default:
274 invalid_comma_type(format->type);
275 return 0;
276 }
277 }
278
279 if (format->fill_char > 127 || format->align > 127 ||
280 format->sign > 127) {
281 PyErr_SetString(PyExc_ValueError, "fill character too large");
282 return 0;
283 }
284
285 return 1;
286}
287
288/* Calculate the padding needed. */
289static void
290calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align,
291 Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
292 Py_ssize_t *n_total)
293{
294 if (width >= 0) {
295 if (nchars > width)
296 *n_total = nchars;
297 else
298 *n_total = width;
299 }
300 else {
301 /* not specified, use all of the chars and no more */
302 *n_total = nchars;
303 }
304
305 /* Figure out how much leading space we need, based on the
306 aligning */
307 if (align == '>')
308 *n_lpadding = *n_total - nchars;
309 else if (align == '^')
310 *n_lpadding = (*n_total - nchars) / 2;
311 else if (align == '<' || align == '=')
312 *n_lpadding = 0;
313 else {
314 /* We should never have an unspecified alignment. */
315 *n_lpadding = 0;
316 assert(0);
317 }
318
319 *n_rpadding = *n_total - nchars - *n_lpadding;
320}
321
322static void
323unicode_fill(PyObject *str, Py_ssize_t start, Py_ssize_t end, Py_UCS4 ch)
324{
325 int kind = PyUnicode_KIND(str);
326 void *data = PyUnicode_DATA(str);
327 while (start < end)
328 PyUnicode_WRITE(kind, data, start++, ch);
329}
330
331/* Do the padding, and return a pointer to where the caller-supplied
332 content goes. */
333static Py_ssize_t
334fill_padding(PyObject *s, Py_ssize_t start, Py_ssize_t nchars,
335 Py_UCS4 fill_char, Py_ssize_t n_lpadding,
336 Py_ssize_t n_rpadding)
337{
338 /* Pad on left. */
339 if (n_lpadding)
340 unicode_fill(s, start, start + n_lpadding, fill_char);
341
342 /* Pad on right. */
343 if (n_rpadding)
Victor Stinnerafbaa202011-09-28 21:50:16 +0200344 unicode_fill(s, start + nchars + n_lpadding,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200345 start + nchars + n_lpadding + n_rpadding, fill_char);
346
347 /* Pointer to the user content. */
348 return start + n_lpadding;
349}
350
351/************************************************************************/
352/*********** common routines for numeric formatting *********************/
353/************************************************************************/
354
355/* Locale type codes. */
356#define LT_CURRENT_LOCALE 0
357#define LT_DEFAULT_LOCALE 1
358#define LT_NO_LOCALE 2
359
360/* Locale info needed for formatting integers and the part of floats
361 before and including the decimal. Note that locales only support
362 8-bit chars, not unicode. */
363typedef struct {
364 char *decimal_point;
365 char *thousands_sep;
366 char *grouping;
367} LocaleInfo;
368
369/* describes the layout for an integer, see the comment in
370 calc_number_widths() for details */
371typedef struct {
372 Py_ssize_t n_lpadding;
373 Py_ssize_t n_prefix;
374 Py_ssize_t n_spadding;
375 Py_ssize_t n_rpadding;
376 char sign;
377 Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */
378 Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
379 any grouping chars. */
380 Py_ssize_t n_decimal; /* 0 if only an integer */
381 Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
382 excluding the decimal itself, if
383 present. */
384
385 /* These 2 are not the widths of fields, but are needed by
386 STRINGLIB_GROUPING. */
387 Py_ssize_t n_digits; /* The number of digits before a decimal
388 or exponent. */
389 Py_ssize_t n_min_width; /* The min_width we used when we computed
390 the n_grouped_digits width. */
391} NumberFieldWidths;
392
393
394/* Given a number of the form:
395 digits[remainder]
396 where ptr points to the start and end points to the end, find where
397 the integer part ends. This could be a decimal, an exponent, both,
398 or neither.
399 If a decimal point is present, set *has_decimal and increment
400 remainder beyond it.
401 Results are undefined (but shouldn't crash) for improperly
402 formatted strings.
403*/
404static void
405parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end,
406 Py_ssize_t *n_remainder, int *has_decimal)
407{
408 Py_ssize_t remainder;
409
410 while (pos<end && isdigit(PyUnicode_READ_CHAR(s, pos)))
411 ++pos;
412 remainder = pos;
413
414 /* Does remainder start with a decimal point? */
415 *has_decimal = pos<end && PyUnicode_READ_CHAR(s, remainder) == '.';
416
417 /* Skip the decimal point. */
418 if (*has_decimal)
419 remainder++;
420
421 *n_remainder = end - remainder;
422}
423
424/* not all fields of format are used. for example, precision is
425 unused. should this take discrete params in order to be more clear
426 about what it does? or is passing a single format parameter easier
427 and more efficient enough to justify a little obfuscation? */
428static Py_ssize_t
429calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
430 Py_UCS4 sign_char, PyObject *number, Py_ssize_t n_start,
431 Py_ssize_t n_end, Py_ssize_t n_remainder,
432 int has_decimal, const LocaleInfo *locale,
433 const InternalFormatSpec *format)
434{
435 Py_ssize_t n_non_digit_non_padding;
436 Py_ssize_t n_padding;
437
438 spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0);
439 spec->n_lpadding = 0;
440 spec->n_prefix = n_prefix;
441 spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0;
442 spec->n_remainder = n_remainder;
443 spec->n_spadding = 0;
444 spec->n_rpadding = 0;
445 spec->sign = '\0';
446 spec->n_sign = 0;
447
448 /* the output will look like:
449 | |
450 | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
451 | |
452
453 sign is computed from format->sign and the actual
454 sign of the number
455
456 prefix is given (it's for the '0x' prefix)
457
458 digits is already known
459
460 the total width is either given, or computed from the
461 actual digits
462
463 only one of lpadding, spadding, and rpadding can be non-zero,
464 and it's calculated from the width and other fields
465 */
466
467 /* compute the various parts we're going to write */
468 switch (format->sign) {
469 case '+':
470 /* always put a + or - */
471 spec->n_sign = 1;
472 spec->sign = (sign_char == '-' ? '-' : '+');
473 break;
474 case ' ':
475 spec->n_sign = 1;
476 spec->sign = (sign_char == '-' ? '-' : ' ');
477 break;
478 default:
479 /* Not specified, or the default (-) */
480 if (sign_char == '-') {
481 spec->n_sign = 1;
482 spec->sign = '-';
483 }
484 }
485
486 /* The number of chars used for non-digits and non-padding. */
487 n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
488 spec->n_remainder;
489
490 /* min_width can go negative, that's okay. format->width == -1 means
491 we don't care. */
492 if (format->fill_char == '0' && format->align == '=')
493 spec->n_min_width = format->width - n_non_digit_non_padding;
494 else
495 spec->n_min_width = 0;
496
497 if (spec->n_digits == 0)
498 /* This case only occurs when using 'c' formatting, we need
499 to special case it because the grouping code always wants
500 to have at least one character. */
501 spec->n_grouped_digits = 0;
502 else
503 spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
Victor Stinnerafbaa202011-09-28 21:50:16 +0200504 PyUnicode_1BYTE_KIND, NULL, 0, NULL,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200505 spec->n_digits, spec->n_min_width,
506 locale->grouping, locale->thousands_sep);
507
508 /* Given the desired width and the total of digit and non-digit
509 space we consume, see if we need any padding. format->width can
510 be negative (meaning no padding), but this code still works in
511 that case. */
512 n_padding = format->width -
513 (n_non_digit_non_padding + spec->n_grouped_digits);
514 if (n_padding > 0) {
515 /* Some padding is needed. Determine if it's left, space, or right. */
516 switch (format->align) {
517 case '<':
518 spec->n_rpadding = n_padding;
519 break;
520 case '^':
521 spec->n_lpadding = n_padding / 2;
522 spec->n_rpadding = n_padding - spec->n_lpadding;
523 break;
524 case '=':
525 spec->n_spadding = n_padding;
526 break;
527 case '>':
528 spec->n_lpadding = n_padding;
529 break;
530 default:
531 /* Shouldn't get here, but treat it as '>' */
532 spec->n_lpadding = n_padding;
533 assert(0);
534 break;
535 }
536 }
537 return spec->n_lpadding + spec->n_sign + spec->n_prefix +
538 spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
539 spec->n_remainder + spec->n_rpadding;
540}
541
542/* Fill in the digit parts of a numbers's string representation,
543 as determined in calc_number_widths().
Victor Stinnerafbaa202011-09-28 21:50:16 +0200544 Return -1 on error, or 0 on success. */
545static int
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200546fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
547 PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end,
Victor Stinnerafbaa202011-09-28 21:50:16 +0200548 PyObject *prefix, Py_ssize_t p_start,
549 Py_UCS4 fill_char,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200550 LocaleInfo *locale, int toupper)
551{
552 /* Used to keep track of digits, decimal, and remainder. */
553 Py_ssize_t d_pos = d_start;
554 unsigned int kind = PyUnicode_KIND(out);
555 void *data = PyUnicode_DATA(out);
556
557#ifndef NDEBUG
558 Py_ssize_t r;
559#endif
560
561 if (spec->n_lpadding) {
562 unicode_fill(out, pos, pos + spec->n_lpadding, fill_char);
563 pos += spec->n_lpadding;
564 }
565 if (spec->n_sign == 1) {
566 PyUnicode_WRITE(kind, data, pos++, spec->sign);
567 }
568 if (spec->n_prefix) {
569 PyUnicode_CopyCharacters(out, pos, prefix, p_start, spec->n_prefix);
570 if (toupper) {
571 Py_ssize_t t;
572 /* XXX if the upper-case prefix is wider than the target
573 buffer, the caller should have allocated a wider string,
574 but currently doesn't. */
575 for (t = 0; t < spec->n_prefix; ++t)
576 PyUnicode_WRITE(kind, data, pos + t,
577 Py_UNICODE_TOUPPER(
578 PyUnicode_READ(kind, data, pos + t)));
579 }
580 pos += spec->n_prefix;
581 }
582 if (spec->n_spadding) {
583 unicode_fill(out, pos, pos + spec->n_spadding, fill_char);
584 pos += spec->n_spadding;
585 }
586
587 /* Only for type 'c' special case, it has no digits. */
588 if (spec->n_digits != 0) {
589 /* Fill the digits with InsertThousandsGrouping. */
Victor Stinnerdba2dee2011-09-28 21:50:42 +0200590 char *pdigits;
591 if (PyUnicode_READY(digits))
592 return -1;
593 pdigits = PyUnicode_DATA(digits);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200594 if (PyUnicode_KIND(digits) < kind) {
595 pdigits = _PyUnicode_AsKind(digits, kind);
Victor Stinnerafbaa202011-09-28 21:50:16 +0200596 if (pdigits == NULL)
597 return -1;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200598 }
599#ifndef NDEBUG
600 r =
601#endif
602 _PyUnicode_InsertThousandsGrouping(
603 kind,
604 (char*)data + PyUnicode_KIND_SIZE(kind, pos),
605 spec->n_grouped_digits,
606 pdigits + PyUnicode_KIND_SIZE(kind, d_pos),
607 spec->n_digits, spec->n_min_width,
608 locale->grouping, locale->thousands_sep);
609#ifndef NDEBUG
610 assert(r == spec->n_grouped_digits);
611#endif
612 if (PyUnicode_KIND(digits) < kind)
613 PyMem_Free(pdigits);
614 d_pos += spec->n_digits;
615 }
616 if (toupper) {
617 Py_ssize_t t;
618 for (t = 0; t < spec->n_grouped_digits; ++t)
619 PyUnicode_WRITE(kind, data, pos + t,
620 Py_UNICODE_TOUPPER(
621 PyUnicode_READ(kind, data, pos + t)));
622 }
623 pos += spec->n_grouped_digits;
624
625 if (spec->n_decimal) {
626 Py_ssize_t t;
627 for (t = 0; t < spec->n_decimal; ++t)
628 PyUnicode_WRITE(kind, data, pos + t,
629 locale->decimal_point[t]);
630 pos += spec->n_decimal;
631 d_pos += 1;
632 }
633
634 if (spec->n_remainder) {
635 PyUnicode_CopyCharacters(out, pos, digits, d_pos, spec->n_remainder);
636 pos += spec->n_remainder;
637 d_pos += spec->n_remainder;
638 }
639
640 if (spec->n_rpadding) {
641 unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
642 pos += spec->n_rpadding;
643 }
Victor Stinnerafbaa202011-09-28 21:50:16 +0200644 return 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200645}
646
647static char no_grouping[1] = {CHAR_MAX};
648
649/* Find the decimal point character(s?), thousands_separator(s?), and
650 grouping description, either for the current locale if type is
651 LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
652 none if LT_NO_LOCALE. */
653static void
654get_locale_info(int type, LocaleInfo *locale_info)
655{
656 switch (type) {
657 case LT_CURRENT_LOCALE: {
658 struct lconv *locale_data = localeconv();
659 locale_info->decimal_point = locale_data->decimal_point;
660 locale_info->thousands_sep = locale_data->thousands_sep;
661 locale_info->grouping = locale_data->grouping;
662 break;
663 }
664 case LT_DEFAULT_LOCALE:
665 locale_info->decimal_point = ".";
666 locale_info->thousands_sep = ",";
667 locale_info->grouping = "\3"; /* Group every 3 characters. The
668 (implicit) trailing 0 means repeat
669 infinitely. */
670 break;
671 case LT_NO_LOCALE:
672 locale_info->decimal_point = ".";
673 locale_info->thousands_sep = "";
674 locale_info->grouping = no_grouping;
675 break;
676 default:
677 assert(0);
678 }
679}
680
681/************************************************************************/
682/*********** string formatting ******************************************/
683/************************************************************************/
684
685static PyObject *
686format_string_internal(PyObject *value, const InternalFormatSpec *format)
687{
688 Py_ssize_t lpad;
689 Py_ssize_t rpad;
690 Py_ssize_t total;
691 Py_ssize_t pos;
692 Py_ssize_t len = PyUnicode_GET_SIZE(value);
693 PyObject *result = NULL;
694 int maxchar = 127;
695
696 /* sign is not allowed on strings */
697 if (format->sign != '\0') {
698 PyErr_SetString(PyExc_ValueError,
699 "Sign not allowed in string format specifier");
700 goto done;
701 }
702
703 /* alternate is not allowed on strings */
704 if (format->alternate) {
705 PyErr_SetString(PyExc_ValueError,
706 "Alternate form (#) not allowed in string format "
707 "specifier");
708 goto done;
709 }
710
711 /* '=' alignment not allowed on strings */
712 if (format->align == '=') {
713 PyErr_SetString(PyExc_ValueError,
714 "'=' alignment not allowed "
715 "in string format specifier");
716 goto done;
717 }
718
719 /* if precision is specified, output no more that format.precision
720 characters */
721 if (format->precision >= 0 && len >= format->precision) {
722 len = format->precision;
723 }
724
725 calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
726
727 /* allocate the resulting string */
728 result = PyUnicode_New(total, maxchar);
729 if (result == NULL)
730 goto done;
731
732 /* Write into that space. First the padding. */
733 pos = fill_padding(result, 0, len,
734 format->fill_char=='\0'?' ':format->fill_char,
735 lpad, rpad);
736
737 /* Then the source string. */
738 PyUnicode_CopyCharacters(result, pos, value, 0, len);
739
740done:
741 return result;
742}
743
744
745/************************************************************************/
746/*********** long formatting ********************************************/
747/************************************************************************/
748
749typedef PyObject*
750(*IntOrLongToString)(PyObject *value, int base);
751
752static PyObject *
753format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
754 IntOrLongToString tostring)
755{
756 PyObject *result = NULL;
757 int maxchar = 127;
758 PyObject *tmp = NULL;
759 Py_ssize_t inumeric_chars;
760 Py_UCS4 sign_char = '\0';
761 Py_ssize_t n_digits; /* count of digits need from the computed
762 string */
763 Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
764 produces non-digits */
765 Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
766 Py_ssize_t n_total;
767 Py_ssize_t prefix;
768 NumberFieldWidths spec;
769 long x;
Victor Stinnerafbaa202011-09-28 21:50:16 +0200770 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200771
772 /* Locale settings, either from the actual locale or
773 from a hard-code pseudo-locale */
774 LocaleInfo locale;
775
776 /* no precision allowed on integers */
777 if (format->precision != -1) {
778 PyErr_SetString(PyExc_ValueError,
779 "Precision not allowed in integer format specifier");
780 goto done;
781 }
782
783 /* special case for character formatting */
784 if (format->type == 'c') {
785 /* error to specify a sign */
786 if (format->sign != '\0') {
787 PyErr_SetString(PyExc_ValueError,
788 "Sign not allowed with integer"
789 " format specifier 'c'");
790 goto done;
791 }
792
793 /* taken from unicodeobject.c formatchar() */
794 /* Integer input truncated to a character */
795/* XXX: won't work for int */
796 x = PyLong_AsLong(value);
797 if (x == -1 && PyErr_Occurred())
798 goto done;
799 if (x < 0 || x > 0x10ffff) {
800 PyErr_SetString(PyExc_OverflowError,
801 "%c arg not in range(0x110000) "
802 "(wide Python build)");
803 goto done;
804 }
805 tmp = PyUnicode_FromOrdinal(x);
806 inumeric_chars = 0;
807 n_digits = 1;
808 if (x > maxchar)
809 maxchar = x;
810
811 /* As a sort-of hack, we tell calc_number_widths that we only
812 have "remainder" characters. calc_number_widths thinks
813 these are characters that don't get formatted, only copied
814 into the output string. We do this for 'c' formatting,
815 because the characters are likely to be non-digits. */
816 n_remainder = 1;
817 }
818 else {
819 int base;
820 int leading_chars_to_skip = 0; /* Number of characters added by
821 PyNumber_ToBase that we want to
822 skip over. */
823
824 /* Compute the base and how many characters will be added by
825 PyNumber_ToBase */
826 switch (format->type) {
827 case 'b':
828 base = 2;
829 leading_chars_to_skip = 2; /* 0b */
830 break;
831 case 'o':
832 base = 8;
833 leading_chars_to_skip = 2; /* 0o */
834 break;
835 case 'x':
836 case 'X':
837 base = 16;
838 leading_chars_to_skip = 2; /* 0x */
839 break;
840 default: /* shouldn't be needed, but stops a compiler warning */
841 case 'd':
842 case 'n':
843 base = 10;
844 break;
845 }
846
847 /* The number of prefix chars is the same as the leading
848 chars to skip */
849 if (format->alternate)
850 n_prefix = leading_chars_to_skip;
851
852 /* Do the hard part, converting to a string in a given base */
853 tmp = tostring(value, base);
854 if (tmp == NULL || PyUnicode_READY(tmp) == -1)
855 goto done;
856
857 inumeric_chars = 0;
858 n_digits = PyUnicode_GET_LENGTH(tmp);
859
860 prefix = inumeric_chars;
861
862 /* Is a sign character present in the output? If so, remember it
863 and skip it */
864 if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') {
865 sign_char = '-';
866 ++prefix;
867 ++leading_chars_to_skip;
868 }
869
870 /* Skip over the leading chars (0x, 0b, etc.) */
871 n_digits -= leading_chars_to_skip;
872 inumeric_chars += leading_chars_to_skip;
873 }
874
875 /* Determine the grouping, separator, and decimal point, if any. */
876 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
877 (format->thousands_separators ?
878 LT_DEFAULT_LOCALE :
879 LT_NO_LOCALE),
880 &locale);
881
882 /* Calculate how much memory we'll need. */
883 n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars,
884 inumeric_chars + n_digits, n_remainder, 0, &locale, format);
885
886 /* Allocate the memory. */
887 result = PyUnicode_New(n_total, maxchar);
888 if (!result)
889 goto done;
890
891 /* Populate the memory. */
Victor Stinnerafbaa202011-09-28 21:50:16 +0200892 err = fill_number(result, 0, &spec,
893 tmp, inumeric_chars, inumeric_chars + n_digits,
894 tmp, prefix,
895 format->fill_char == '\0' ? ' ' : format->fill_char,
896 &locale, format->type == 'X');
897 if (err)
898 Py_CLEAR(result);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200899
900done:
901 Py_XDECREF(tmp);
902 return result;
903}
904
905/************************************************************************/
906/*********** float formatting *******************************************/
907/************************************************************************/
908
909static PyObject*
910strtounicode(char *charbuffer, Py_ssize_t len)
911{
912 return PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, charbuffer, len);
913}
914
915/* much of this is taken from unicodeobject.c */
916static PyObject *
917format_float_internal(PyObject *value,
918 const InternalFormatSpec *format)
919{
920 char *buf = NULL; /* buffer returned from PyOS_double_to_string */
921 Py_ssize_t n_digits;
922 Py_ssize_t n_remainder;
923 Py_ssize_t n_total;
924 int has_decimal;
925 double val;
926 Py_ssize_t precision = format->precision;
927 Py_ssize_t default_precision = 6;
928 Py_UCS4 type = format->type;
929 int add_pct = 0;
930 Py_ssize_t index;
931 NumberFieldWidths spec;
932 int flags = 0;
933 PyObject *result = NULL;
934 int maxchar = 127;
935 Py_UCS4 sign_char = '\0';
936 int float_type; /* Used to see if we have a nan, inf, or regular float. */
937 PyObject *unicode_tmp = NULL;
Victor Stinnerafbaa202011-09-28 21:50:16 +0200938 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200939
940 /* Locale settings, either from the actual locale or
941 from a hard-code pseudo-locale */
942 LocaleInfo locale;
943
944 if (format->alternate)
945 flags |= Py_DTSF_ALT;
946
947 if (type == '\0') {
948 /* Omitted type specifier. Behaves in the same way as repr(x)
949 and str(x) if no precision is given, else like 'g', but with
950 at least one digit after the decimal point. */
951 flags |= Py_DTSF_ADD_DOT_0;
952 type = 'r';
953 default_precision = 0;
954 }
955
956 if (type == 'n')
957 /* 'n' is the same as 'g', except for the locale used to
958 format the result. We take care of that later. */
959 type = 'g';
960
961 val = PyFloat_AsDouble(value);
962 if (val == -1.0 && PyErr_Occurred())
963 goto done;
964
965 if (type == '%') {
966 type = 'f';
967 val *= 100;
968 add_pct = 1;
969 }
970
971 if (precision < 0)
972 precision = default_precision;
973 else if (type == 'r')
974 type = 'g';
975
976 /* Cast "type", because if we're in unicode we need to pass a
977 8-bit char. This is safe, because we've restricted what "type"
978 can be. */
979 buf = PyOS_double_to_string(val, (char)type, precision, flags,
980 &float_type);
981 if (buf == NULL)
982 goto done;
983 n_digits = strlen(buf);
984
985 if (add_pct) {
986 /* We know that buf has a trailing zero (since we just called
987 strlen() on it), and we don't use that fact any more. So we
988 can just write over the trailing zero. */
989 buf[n_digits] = '%';
990 n_digits += 1;
991 }
992
993 /* Since there is no unicode version of PyOS_double_to_string,
994 just use the 8 bit version and then convert to unicode. */
995 unicode_tmp = strtounicode(buf, n_digits);
996 if (unicode_tmp == NULL)
997 goto done;
998 index = 0;
999
1000 /* Is a sign character present in the output? If so, remember it
1001 and skip it */
1002 if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') {
1003 sign_char = '-';
1004 ++index;
1005 --n_digits;
1006 }
1007
1008 /* Determine if we have any "remainder" (after the digits, might include
1009 decimal or exponent or both (or neither)) */
1010 parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal);
1011
1012 /* Determine the grouping, separator, and decimal point, if any. */
1013 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1014 (format->thousands_separators ?
1015 LT_DEFAULT_LOCALE :
1016 LT_NO_LOCALE),
1017 &locale);
1018
1019 /* Calculate how much memory we'll need. */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001020 n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001021 index + n_digits, n_remainder, has_decimal,
1022 &locale, format);
1023
1024 /* Allocate the memory. */
1025 result = PyUnicode_New(n_total, maxchar);
1026 if (result == NULL)
1027 goto done;
1028
1029 /* Populate the memory. */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001030 err = fill_number(result, 0, &spec,
1031 unicode_tmp, index, index + n_digits,
1032 NULL, 0,
1033 format->fill_char == '\0' ? ' ' : format->fill_char,
1034 &locale, 0);
1035 if (err)
1036 Py_CLEAR(result);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001037
1038done:
1039 PyMem_Free(buf);
1040 Py_DECREF(unicode_tmp);
1041 return result;
1042}
1043
1044/************************************************************************/
1045/*********** complex formatting *****************************************/
1046/************************************************************************/
1047
1048static PyObject *
1049format_complex_internal(PyObject *value,
1050 const InternalFormatSpec *format)
1051{
1052 double re;
1053 double im;
1054 char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */
1055 char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */
1056
1057 InternalFormatSpec tmp_format = *format;
1058 Py_ssize_t n_re_digits;
1059 Py_ssize_t n_im_digits;
1060 Py_ssize_t n_re_remainder;
1061 Py_ssize_t n_im_remainder;
1062 Py_ssize_t n_re_total;
1063 Py_ssize_t n_im_total;
1064 int re_has_decimal;
1065 int im_has_decimal;
1066 Py_ssize_t precision = format->precision;
1067 Py_ssize_t default_precision = 6;
1068 Py_UCS4 type = format->type;
1069 Py_ssize_t i_re;
1070 Py_ssize_t i_im;
1071 NumberFieldWidths re_spec;
1072 NumberFieldWidths im_spec;
1073 int flags = 0;
1074 PyObject *result = NULL;
1075 int maxchar = 127;
1076 int rkind;
1077 void *rdata;
1078 Py_ssize_t index;
1079 Py_UCS4 re_sign_char = '\0';
1080 Py_UCS4 im_sign_char = '\0';
1081 int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
1082 int im_float_type;
1083 int add_parens = 0;
1084 int skip_re = 0;
1085 Py_ssize_t lpad;
1086 Py_ssize_t rpad;
1087 Py_ssize_t total;
1088 PyObject *re_unicode_tmp = NULL;
1089 PyObject *im_unicode_tmp = NULL;
Victor Stinnerafbaa202011-09-28 21:50:16 +02001090 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001091
1092 /* Locale settings, either from the actual locale or
1093 from a hard-code pseudo-locale */
1094 LocaleInfo locale;
1095
1096 /* Zero padding is not allowed. */
1097 if (format->fill_char == '0') {
1098 PyErr_SetString(PyExc_ValueError,
1099 "Zero padding is not allowed in complex format "
1100 "specifier");
1101 goto done;
1102 }
1103
1104 /* Neither is '=' alignment . */
1105 if (format->align == '=') {
1106 PyErr_SetString(PyExc_ValueError,
1107 "'=' alignment flag is not allowed in complex format "
1108 "specifier");
1109 goto done;
1110 }
1111
1112 re = PyComplex_RealAsDouble(value);
1113 if (re == -1.0 && PyErr_Occurred())
1114 goto done;
1115 im = PyComplex_ImagAsDouble(value);
1116 if (im == -1.0 && PyErr_Occurred())
1117 goto done;
1118
1119 if (format->alternate)
1120 flags |= Py_DTSF_ALT;
1121
1122 if (type == '\0') {
1123 /* Omitted type specifier. Should be like str(self). */
1124 type = 'r';
1125 default_precision = 0;
1126 if (re == 0.0 && copysign(1.0, re) == 1.0)
1127 skip_re = 1;
1128 else
1129 add_parens = 1;
1130 }
1131
1132 if (type == 'n')
1133 /* 'n' is the same as 'g', except for the locale used to
1134 format the result. We take care of that later. */
1135 type = 'g';
1136
1137 if (precision < 0)
1138 precision = default_precision;
1139 else if (type == 'r')
1140 type = 'g';
1141
1142 /* Cast "type", because if we're in unicode we need to pass a
1143 8-bit char. This is safe, because we've restricted what "type"
1144 can be. */
1145 re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
1146 &re_float_type);
1147 if (re_buf == NULL)
1148 goto done;
1149 im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
1150 &im_float_type);
1151 if (im_buf == NULL)
1152 goto done;
1153
1154 n_re_digits = strlen(re_buf);
1155 n_im_digits = strlen(im_buf);
1156
1157 /* Since there is no unicode version of PyOS_double_to_string,
1158 just use the 8 bit version and then convert to unicode. */
1159 re_unicode_tmp = strtounicode(re_buf, n_re_digits);
1160 if (re_unicode_tmp == NULL)
1161 goto done;
1162 i_re = 0;
1163
1164 im_unicode_tmp = strtounicode(im_buf, n_im_digits);
1165 if (im_unicode_tmp == NULL)
1166 goto done;
1167 i_im = 0;
1168
1169 /* Is a sign character present in the output? If so, remember it
1170 and skip it */
1171 if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') {
1172 re_sign_char = '-';
1173 ++i_re;
1174 --n_re_digits;
1175 }
1176 if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') {
1177 im_sign_char = '-';
1178 ++i_im;
1179 --n_im_digits;
1180 }
1181
1182 /* Determine if we have any "remainder" (after the digits, might include
1183 decimal or exponent or both (or neither)) */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001184 parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001185 &n_re_remainder, &re_has_decimal);
Victor Stinnerafbaa202011-09-28 21:50:16 +02001186 parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001187 &n_im_remainder, &im_has_decimal);
1188
1189 /* Determine the grouping, separator, and decimal point, if any. */
1190 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1191 (format->thousands_separators ?
1192 LT_DEFAULT_LOCALE :
1193 LT_NO_LOCALE),
1194 &locale);
1195
1196 /* Turn off any padding. We'll do it later after we've composed
1197 the numbers without padding. */
1198 tmp_format.fill_char = '\0';
1199 tmp_format.align = '<';
1200 tmp_format.width = -1;
1201
1202 /* Calculate how much memory we'll need. */
1203 n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp,
1204 i_re, i_re + n_re_digits, n_re_remainder,
1205 re_has_decimal, &locale, &tmp_format);
1206
1207 /* Same formatting, but always include a sign, unless the real part is
1208 * going to be omitted, in which case we use whatever sign convention was
1209 * requested by the original format. */
1210 if (!skip_re)
1211 tmp_format.sign = '+';
1212 n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp,
1213 i_im, i_im + n_im_digits, n_im_remainder,
1214 im_has_decimal, &locale, &tmp_format);
1215
1216 if (skip_re)
1217 n_re_total = 0;
1218
1219 /* Add 1 for the 'j', and optionally 2 for parens. */
1220 calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
1221 format->width, format->align, &lpad, &rpad, &total);
1222
1223 result = PyUnicode_New(total, maxchar);
1224 if (result == NULL)
1225 goto done;
1226 rkind = PyUnicode_KIND(result);
1227 rdata = PyUnicode_DATA(result);
1228
1229 /* Populate the memory. First, the padding. */
1230 index = fill_padding(result, 0,
1231 n_re_total + n_im_total + 1 + add_parens * 2,
1232 format->fill_char=='\0' ? ' ' : format->fill_char,
1233 lpad, rpad);
1234
1235 if (add_parens)
1236 PyUnicode_WRITE(rkind, rdata, index++, '(');
1237
1238 if (!skip_re) {
Victor Stinnerafbaa202011-09-28 21:50:16 +02001239 err = fill_number(result, index, &re_spec,
1240 re_unicode_tmp, i_re, i_re + n_re_digits,
1241 NULL, 0,
1242 0,
1243 &locale, 0);
1244 if (err) {
1245 Py_CLEAR(result);
1246 goto done;
1247 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001248 index += n_re_total;
1249 }
Victor Stinnerafbaa202011-09-28 21:50:16 +02001250 err = fill_number(result, index, &im_spec,
1251 im_unicode_tmp, i_im, i_im + n_im_digits,
1252 NULL, 0,
1253 0,
1254 &locale, 0);
1255 if (err) {
1256 Py_CLEAR(result);
1257 goto done;
1258 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001259 index += n_im_total;
1260 PyUnicode_WRITE(rkind, rdata, index++, 'j');
1261
1262 if (add_parens)
1263 PyUnicode_WRITE(rkind, rdata, index++, ')');
1264
1265done:
1266 PyMem_Free(re_buf);
1267 PyMem_Free(im_buf);
1268 Py_XDECREF(re_unicode_tmp);
1269 Py_XDECREF(im_unicode_tmp);
1270 return result;
1271}
1272
1273/************************************************************************/
1274/*********** built in formatters ****************************************/
1275/************************************************************************/
1276PyObject *
1277_PyUnicode_FormatAdvanced(PyObject *obj,
1278 PyObject *format_spec,
1279 Py_ssize_t start, Py_ssize_t end)
1280{
1281 InternalFormatSpec format;
1282 PyObject *result = NULL;
1283
1284 /* check for the special case of zero length format spec, make
1285 it equivalent to str(obj) */
1286 if (start == end) {
1287 result = PyObject_Str(obj);
1288 goto done;
1289 }
1290
1291 /* parse the format_spec */
1292 if (!parse_internal_render_format_spec(format_spec, start, end,
1293 &format, 's', '<'))
1294 goto done;
1295
1296 /* type conversion? */
1297 switch (format.type) {
1298 case 's':
1299 /* no type conversion needed, already a string. do the formatting */
1300 result = format_string_internal(obj, &format);
1301 break;
1302 default:
1303 /* unknown */
1304 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1305 goto done;
1306 }
1307
1308done:
1309 return result;
1310}
1311
1312static PyObject*
1313format_int_or_long(PyObject* obj, PyObject* format_spec,
1314 Py_ssize_t start, Py_ssize_t end,
1315 IntOrLongToString tostring)
1316{
1317 PyObject *result = NULL;
1318 PyObject *tmp = NULL;
1319 InternalFormatSpec format;
1320
1321 /* check for the special case of zero length format spec, make
1322 it equivalent to str(obj) */
1323 if (start == end) {
1324 result = PyObject_Str(obj);
1325 goto done;
1326 }
1327
1328 /* parse the format_spec */
1329 if (!parse_internal_render_format_spec(format_spec, start, end,
1330 &format, 'd', '>'))
1331 goto done;
1332
1333 /* type conversion? */
1334 switch (format.type) {
1335 case 'b':
1336 case 'c':
1337 case 'd':
1338 case 'o':
1339 case 'x':
1340 case 'X':
1341 case 'n':
1342 /* no type conversion needed, already an int (or long). do
1343 the formatting */
1344 result = format_int_or_long_internal(obj, &format, tostring);
1345 break;
1346
1347 case 'e':
1348 case 'E':
1349 case 'f':
1350 case 'F':
1351 case 'g':
1352 case 'G':
1353 case '%':
1354 /* convert to float */
1355 tmp = PyNumber_Float(obj);
1356 if (tmp == NULL)
1357 goto done;
1358 result = format_float_internal(tmp, &format);
1359 break;
1360
1361 default:
1362 /* unknown */
1363 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1364 goto done;
1365 }
1366
1367done:
1368 Py_XDECREF(tmp);
1369 return result;
1370}
1371
1372/* Need to define long_format as a function that will convert a long
1373 to a string. In 3.0, _PyLong_Format has the correct signature. */
1374#define long_format _PyLong_Format
1375
1376PyObject *
1377_PyLong_FormatAdvanced(PyObject *obj,
1378 PyObject *format_spec,
1379 Py_ssize_t start, Py_ssize_t end)
1380{
1381 return format_int_or_long(obj, format_spec, start, end,
1382 long_format);
1383}
1384
1385PyObject *
1386_PyFloat_FormatAdvanced(PyObject *obj,
1387 PyObject *format_spec,
1388 Py_ssize_t start, Py_ssize_t end)
1389{
1390 PyObject *result = NULL;
1391 InternalFormatSpec format;
1392
1393 /* check for the special case of zero length format spec, make
1394 it equivalent to str(obj) */
1395 if (start == end) {
1396 result = PyObject_Str(obj);
1397 goto done;
1398 }
1399
1400 /* parse the format_spec */
1401 if (!parse_internal_render_format_spec(format_spec, start, end,
1402 &format, '\0', '>'))
1403 goto done;
1404
1405 /* type conversion? */
1406 switch (format.type) {
1407 case '\0': /* No format code: like 'g', but with at least one decimal. */
1408 case 'e':
1409 case 'E':
1410 case 'f':
1411 case 'F':
1412 case 'g':
1413 case 'G':
1414 case 'n':
1415 case '%':
1416 /* no conversion, already a float. do the formatting */
1417 result = format_float_internal(obj, &format);
1418 break;
1419
1420 default:
1421 /* unknown */
1422 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1423 goto done;
1424 }
1425
1426done:
1427 return result;
1428}
1429
1430PyObject *
1431_PyComplex_FormatAdvanced(PyObject *obj,
1432 PyObject *format_spec,
1433 Py_ssize_t start, Py_ssize_t end)
1434{
1435 PyObject *result = NULL;
1436 InternalFormatSpec format;
1437
1438 /* check for the special case of zero length format spec, make
1439 it equivalent to str(obj) */
1440 if (start == end) {
1441 result = PyObject_Str(obj);
1442 goto done;
1443 }
1444
1445 /* parse the format_spec */
1446 if (!parse_internal_render_format_spec(format_spec, start, end,
1447 &format, '\0', '>'))
1448 goto done;
1449
1450 /* type conversion? */
1451 switch (format.type) {
1452 case '\0': /* No format code: like 'g', but with at least one decimal. */
1453 case 'e':
1454 case 'E':
1455 case 'f':
1456 case 'F':
1457 case 'g':
1458 case 'G':
1459 case 'n':
1460 /* no conversion, already a complex. do the formatting */
1461 result = format_complex_internal(obj, &format);
1462 break;
1463
1464 default:
1465 /* unknown */
1466 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1467 goto done;
1468 }
1469
1470done:
1471 return result;
1472}