blob: 86385f6f7fc6eb2a73481f149a0e3565734e7569 [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. */
590 char *pdigits = PyUnicode_DATA(digits);
591 if (PyUnicode_KIND(digits) < kind) {
592 pdigits = _PyUnicode_AsKind(digits, kind);
Victor Stinnerafbaa202011-09-28 21:50:16 +0200593 if (pdigits == NULL)
594 return -1;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200595 }
596#ifndef NDEBUG
597 r =
598#endif
599 _PyUnicode_InsertThousandsGrouping(
600 kind,
601 (char*)data + PyUnicode_KIND_SIZE(kind, pos),
602 spec->n_grouped_digits,
603 pdigits + PyUnicode_KIND_SIZE(kind, d_pos),
604 spec->n_digits, spec->n_min_width,
605 locale->grouping, locale->thousands_sep);
606#ifndef NDEBUG
607 assert(r == spec->n_grouped_digits);
608#endif
609 if (PyUnicode_KIND(digits) < kind)
610 PyMem_Free(pdigits);
611 d_pos += spec->n_digits;
612 }
613 if (toupper) {
614 Py_ssize_t t;
615 for (t = 0; t < spec->n_grouped_digits; ++t)
616 PyUnicode_WRITE(kind, data, pos + t,
617 Py_UNICODE_TOUPPER(
618 PyUnicode_READ(kind, data, pos + t)));
619 }
620 pos += spec->n_grouped_digits;
621
622 if (spec->n_decimal) {
623 Py_ssize_t t;
624 for (t = 0; t < spec->n_decimal; ++t)
625 PyUnicode_WRITE(kind, data, pos + t,
626 locale->decimal_point[t]);
627 pos += spec->n_decimal;
628 d_pos += 1;
629 }
630
631 if (spec->n_remainder) {
632 PyUnicode_CopyCharacters(out, pos, digits, d_pos, spec->n_remainder);
633 pos += spec->n_remainder;
634 d_pos += spec->n_remainder;
635 }
636
637 if (spec->n_rpadding) {
638 unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
639 pos += spec->n_rpadding;
640 }
Victor Stinnerafbaa202011-09-28 21:50:16 +0200641 return 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200642}
643
644static char no_grouping[1] = {CHAR_MAX};
645
646/* Find the decimal point character(s?), thousands_separator(s?), and
647 grouping description, either for the current locale if type is
648 LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
649 none if LT_NO_LOCALE. */
650static void
651get_locale_info(int type, LocaleInfo *locale_info)
652{
653 switch (type) {
654 case LT_CURRENT_LOCALE: {
655 struct lconv *locale_data = localeconv();
656 locale_info->decimal_point = locale_data->decimal_point;
657 locale_info->thousands_sep = locale_data->thousands_sep;
658 locale_info->grouping = locale_data->grouping;
659 break;
660 }
661 case LT_DEFAULT_LOCALE:
662 locale_info->decimal_point = ".";
663 locale_info->thousands_sep = ",";
664 locale_info->grouping = "\3"; /* Group every 3 characters. The
665 (implicit) trailing 0 means repeat
666 infinitely. */
667 break;
668 case LT_NO_LOCALE:
669 locale_info->decimal_point = ".";
670 locale_info->thousands_sep = "";
671 locale_info->grouping = no_grouping;
672 break;
673 default:
674 assert(0);
675 }
676}
677
678/************************************************************************/
679/*********** string formatting ******************************************/
680/************************************************************************/
681
682static PyObject *
683format_string_internal(PyObject *value, const InternalFormatSpec *format)
684{
685 Py_ssize_t lpad;
686 Py_ssize_t rpad;
687 Py_ssize_t total;
688 Py_ssize_t pos;
689 Py_ssize_t len = PyUnicode_GET_SIZE(value);
690 PyObject *result = NULL;
691 int maxchar = 127;
692
693 /* sign is not allowed on strings */
694 if (format->sign != '\0') {
695 PyErr_SetString(PyExc_ValueError,
696 "Sign not allowed in string format specifier");
697 goto done;
698 }
699
700 /* alternate is not allowed on strings */
701 if (format->alternate) {
702 PyErr_SetString(PyExc_ValueError,
703 "Alternate form (#) not allowed in string format "
704 "specifier");
705 goto done;
706 }
707
708 /* '=' alignment not allowed on strings */
709 if (format->align == '=') {
710 PyErr_SetString(PyExc_ValueError,
711 "'=' alignment not allowed "
712 "in string format specifier");
713 goto done;
714 }
715
716 /* if precision is specified, output no more that format.precision
717 characters */
718 if (format->precision >= 0 && len >= format->precision) {
719 len = format->precision;
720 }
721
722 calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
723
724 /* allocate the resulting string */
725 result = PyUnicode_New(total, maxchar);
726 if (result == NULL)
727 goto done;
728
729 /* Write into that space. First the padding. */
730 pos = fill_padding(result, 0, len,
731 format->fill_char=='\0'?' ':format->fill_char,
732 lpad, rpad);
733
734 /* Then the source string. */
735 PyUnicode_CopyCharacters(result, pos, value, 0, len);
736
737done:
738 return result;
739}
740
741
742/************************************************************************/
743/*********** long formatting ********************************************/
744/************************************************************************/
745
746typedef PyObject*
747(*IntOrLongToString)(PyObject *value, int base);
748
749static PyObject *
750format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
751 IntOrLongToString tostring)
752{
753 PyObject *result = NULL;
754 int maxchar = 127;
755 PyObject *tmp = NULL;
756 Py_ssize_t inumeric_chars;
757 Py_UCS4 sign_char = '\0';
758 Py_ssize_t n_digits; /* count of digits need from the computed
759 string */
760 Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
761 produces non-digits */
762 Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
763 Py_ssize_t n_total;
764 Py_ssize_t prefix;
765 NumberFieldWidths spec;
766 long x;
Victor Stinnerafbaa202011-09-28 21:50:16 +0200767 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200768
769 /* Locale settings, either from the actual locale or
770 from a hard-code pseudo-locale */
771 LocaleInfo locale;
772
773 /* no precision allowed on integers */
774 if (format->precision != -1) {
775 PyErr_SetString(PyExc_ValueError,
776 "Precision not allowed in integer format specifier");
777 goto done;
778 }
779
780 /* special case for character formatting */
781 if (format->type == 'c') {
782 /* error to specify a sign */
783 if (format->sign != '\0') {
784 PyErr_SetString(PyExc_ValueError,
785 "Sign not allowed with integer"
786 " format specifier 'c'");
787 goto done;
788 }
789
790 /* taken from unicodeobject.c formatchar() */
791 /* Integer input truncated to a character */
792/* XXX: won't work for int */
793 x = PyLong_AsLong(value);
794 if (x == -1 && PyErr_Occurred())
795 goto done;
796 if (x < 0 || x > 0x10ffff) {
797 PyErr_SetString(PyExc_OverflowError,
798 "%c arg not in range(0x110000) "
799 "(wide Python build)");
800 goto done;
801 }
802 tmp = PyUnicode_FromOrdinal(x);
803 inumeric_chars = 0;
804 n_digits = 1;
805 if (x > maxchar)
806 maxchar = x;
807
808 /* As a sort-of hack, we tell calc_number_widths that we only
809 have "remainder" characters. calc_number_widths thinks
810 these are characters that don't get formatted, only copied
811 into the output string. We do this for 'c' formatting,
812 because the characters are likely to be non-digits. */
813 n_remainder = 1;
814 }
815 else {
816 int base;
817 int leading_chars_to_skip = 0; /* Number of characters added by
818 PyNumber_ToBase that we want to
819 skip over. */
820
821 /* Compute the base and how many characters will be added by
822 PyNumber_ToBase */
823 switch (format->type) {
824 case 'b':
825 base = 2;
826 leading_chars_to_skip = 2; /* 0b */
827 break;
828 case 'o':
829 base = 8;
830 leading_chars_to_skip = 2; /* 0o */
831 break;
832 case 'x':
833 case 'X':
834 base = 16;
835 leading_chars_to_skip = 2; /* 0x */
836 break;
837 default: /* shouldn't be needed, but stops a compiler warning */
838 case 'd':
839 case 'n':
840 base = 10;
841 break;
842 }
843
844 /* The number of prefix chars is the same as the leading
845 chars to skip */
846 if (format->alternate)
847 n_prefix = leading_chars_to_skip;
848
849 /* Do the hard part, converting to a string in a given base */
850 tmp = tostring(value, base);
851 if (tmp == NULL || PyUnicode_READY(tmp) == -1)
852 goto done;
853
854 inumeric_chars = 0;
855 n_digits = PyUnicode_GET_LENGTH(tmp);
856
857 prefix = inumeric_chars;
858
859 /* Is a sign character present in the output? If so, remember it
860 and skip it */
861 if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') {
862 sign_char = '-';
863 ++prefix;
864 ++leading_chars_to_skip;
865 }
866
867 /* Skip over the leading chars (0x, 0b, etc.) */
868 n_digits -= leading_chars_to_skip;
869 inumeric_chars += leading_chars_to_skip;
870 }
871
872 /* Determine the grouping, separator, and decimal point, if any. */
873 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
874 (format->thousands_separators ?
875 LT_DEFAULT_LOCALE :
876 LT_NO_LOCALE),
877 &locale);
878
879 /* Calculate how much memory we'll need. */
880 n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars,
881 inumeric_chars + n_digits, n_remainder, 0, &locale, format);
882
883 /* Allocate the memory. */
884 result = PyUnicode_New(n_total, maxchar);
885 if (!result)
886 goto done;
887
888 /* Populate the memory. */
Victor Stinnerafbaa202011-09-28 21:50:16 +0200889 err = fill_number(result, 0, &spec,
890 tmp, inumeric_chars, inumeric_chars + n_digits,
891 tmp, prefix,
892 format->fill_char == '\0' ? ' ' : format->fill_char,
893 &locale, format->type == 'X');
894 if (err)
895 Py_CLEAR(result);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200896
897done:
898 Py_XDECREF(tmp);
899 return result;
900}
901
902/************************************************************************/
903/*********** float formatting *******************************************/
904/************************************************************************/
905
906static PyObject*
907strtounicode(char *charbuffer, Py_ssize_t len)
908{
909 return PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, charbuffer, len);
910}
911
912/* much of this is taken from unicodeobject.c */
913static PyObject *
914format_float_internal(PyObject *value,
915 const InternalFormatSpec *format)
916{
917 char *buf = NULL; /* buffer returned from PyOS_double_to_string */
918 Py_ssize_t n_digits;
919 Py_ssize_t n_remainder;
920 Py_ssize_t n_total;
921 int has_decimal;
922 double val;
923 Py_ssize_t precision = format->precision;
924 Py_ssize_t default_precision = 6;
925 Py_UCS4 type = format->type;
926 int add_pct = 0;
927 Py_ssize_t index;
928 NumberFieldWidths spec;
929 int flags = 0;
930 PyObject *result = NULL;
931 int maxchar = 127;
932 Py_UCS4 sign_char = '\0';
933 int float_type; /* Used to see if we have a nan, inf, or regular float. */
934 PyObject *unicode_tmp = NULL;
Victor Stinnerafbaa202011-09-28 21:50:16 +0200935 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200936
937 /* Locale settings, either from the actual locale or
938 from a hard-code pseudo-locale */
939 LocaleInfo locale;
940
941 if (format->alternate)
942 flags |= Py_DTSF_ALT;
943
944 if (type == '\0') {
945 /* Omitted type specifier. Behaves in the same way as repr(x)
946 and str(x) if no precision is given, else like 'g', but with
947 at least one digit after the decimal point. */
948 flags |= Py_DTSF_ADD_DOT_0;
949 type = 'r';
950 default_precision = 0;
951 }
952
953 if (type == 'n')
954 /* 'n' is the same as 'g', except for the locale used to
955 format the result. We take care of that later. */
956 type = 'g';
957
958 val = PyFloat_AsDouble(value);
959 if (val == -1.0 && PyErr_Occurred())
960 goto done;
961
962 if (type == '%') {
963 type = 'f';
964 val *= 100;
965 add_pct = 1;
966 }
967
968 if (precision < 0)
969 precision = default_precision;
970 else if (type == 'r')
971 type = 'g';
972
973 /* Cast "type", because if we're in unicode we need to pass a
974 8-bit char. This is safe, because we've restricted what "type"
975 can be. */
976 buf = PyOS_double_to_string(val, (char)type, precision, flags,
977 &float_type);
978 if (buf == NULL)
979 goto done;
980 n_digits = strlen(buf);
981
982 if (add_pct) {
983 /* We know that buf has a trailing zero (since we just called
984 strlen() on it), and we don't use that fact any more. So we
985 can just write over the trailing zero. */
986 buf[n_digits] = '%';
987 n_digits += 1;
988 }
989
990 /* Since there is no unicode version of PyOS_double_to_string,
991 just use the 8 bit version and then convert to unicode. */
992 unicode_tmp = strtounicode(buf, n_digits);
993 if (unicode_tmp == NULL)
994 goto done;
995 index = 0;
996
997 /* Is a sign character present in the output? If so, remember it
998 and skip it */
999 if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') {
1000 sign_char = '-';
1001 ++index;
1002 --n_digits;
1003 }
1004
1005 /* Determine if we have any "remainder" (after the digits, might include
1006 decimal or exponent or both (or neither)) */
1007 parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal);
1008
1009 /* Determine the grouping, separator, and decimal point, if any. */
1010 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1011 (format->thousands_separators ?
1012 LT_DEFAULT_LOCALE :
1013 LT_NO_LOCALE),
1014 &locale);
1015
1016 /* Calculate how much memory we'll need. */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001017 n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001018 index + n_digits, n_remainder, has_decimal,
1019 &locale, format);
1020
1021 /* Allocate the memory. */
1022 result = PyUnicode_New(n_total, maxchar);
1023 if (result == NULL)
1024 goto done;
1025
1026 /* Populate the memory. */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001027 err = fill_number(result, 0, &spec,
1028 unicode_tmp, index, index + n_digits,
1029 NULL, 0,
1030 format->fill_char == '\0' ? ' ' : format->fill_char,
1031 &locale, 0);
1032 if (err)
1033 Py_CLEAR(result);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001034
1035done:
1036 PyMem_Free(buf);
1037 Py_DECREF(unicode_tmp);
1038 return result;
1039}
1040
1041/************************************************************************/
1042/*********** complex formatting *****************************************/
1043/************************************************************************/
1044
1045static PyObject *
1046format_complex_internal(PyObject *value,
1047 const InternalFormatSpec *format)
1048{
1049 double re;
1050 double im;
1051 char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */
1052 char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */
1053
1054 InternalFormatSpec tmp_format = *format;
1055 Py_ssize_t n_re_digits;
1056 Py_ssize_t n_im_digits;
1057 Py_ssize_t n_re_remainder;
1058 Py_ssize_t n_im_remainder;
1059 Py_ssize_t n_re_total;
1060 Py_ssize_t n_im_total;
1061 int re_has_decimal;
1062 int im_has_decimal;
1063 Py_ssize_t precision = format->precision;
1064 Py_ssize_t default_precision = 6;
1065 Py_UCS4 type = format->type;
1066 Py_ssize_t i_re;
1067 Py_ssize_t i_im;
1068 NumberFieldWidths re_spec;
1069 NumberFieldWidths im_spec;
1070 int flags = 0;
1071 PyObject *result = NULL;
1072 int maxchar = 127;
1073 int rkind;
1074 void *rdata;
1075 Py_ssize_t index;
1076 Py_UCS4 re_sign_char = '\0';
1077 Py_UCS4 im_sign_char = '\0';
1078 int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
1079 int im_float_type;
1080 int add_parens = 0;
1081 int skip_re = 0;
1082 Py_ssize_t lpad;
1083 Py_ssize_t rpad;
1084 Py_ssize_t total;
1085 PyObject *re_unicode_tmp = NULL;
1086 PyObject *im_unicode_tmp = NULL;
Victor Stinnerafbaa202011-09-28 21:50:16 +02001087 int err;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001088
1089 /* Locale settings, either from the actual locale or
1090 from a hard-code pseudo-locale */
1091 LocaleInfo locale;
1092
1093 /* Zero padding is not allowed. */
1094 if (format->fill_char == '0') {
1095 PyErr_SetString(PyExc_ValueError,
1096 "Zero padding is not allowed in complex format "
1097 "specifier");
1098 goto done;
1099 }
1100
1101 /* Neither is '=' alignment . */
1102 if (format->align == '=') {
1103 PyErr_SetString(PyExc_ValueError,
1104 "'=' alignment flag is not allowed in complex format "
1105 "specifier");
1106 goto done;
1107 }
1108
1109 re = PyComplex_RealAsDouble(value);
1110 if (re == -1.0 && PyErr_Occurred())
1111 goto done;
1112 im = PyComplex_ImagAsDouble(value);
1113 if (im == -1.0 && PyErr_Occurred())
1114 goto done;
1115
1116 if (format->alternate)
1117 flags |= Py_DTSF_ALT;
1118
1119 if (type == '\0') {
1120 /* Omitted type specifier. Should be like str(self). */
1121 type = 'r';
1122 default_precision = 0;
1123 if (re == 0.0 && copysign(1.0, re) == 1.0)
1124 skip_re = 1;
1125 else
1126 add_parens = 1;
1127 }
1128
1129 if (type == 'n')
1130 /* 'n' is the same as 'g', except for the locale used to
1131 format the result. We take care of that later. */
1132 type = 'g';
1133
1134 if (precision < 0)
1135 precision = default_precision;
1136 else if (type == 'r')
1137 type = 'g';
1138
1139 /* Cast "type", because if we're in unicode we need to pass a
1140 8-bit char. This is safe, because we've restricted what "type"
1141 can be. */
1142 re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
1143 &re_float_type);
1144 if (re_buf == NULL)
1145 goto done;
1146 im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
1147 &im_float_type);
1148 if (im_buf == NULL)
1149 goto done;
1150
1151 n_re_digits = strlen(re_buf);
1152 n_im_digits = strlen(im_buf);
1153
1154 /* Since there is no unicode version of PyOS_double_to_string,
1155 just use the 8 bit version and then convert to unicode. */
1156 re_unicode_tmp = strtounicode(re_buf, n_re_digits);
1157 if (re_unicode_tmp == NULL)
1158 goto done;
1159 i_re = 0;
1160
1161 im_unicode_tmp = strtounicode(im_buf, n_im_digits);
1162 if (im_unicode_tmp == NULL)
1163 goto done;
1164 i_im = 0;
1165
1166 /* Is a sign character present in the output? If so, remember it
1167 and skip it */
1168 if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') {
1169 re_sign_char = '-';
1170 ++i_re;
1171 --n_re_digits;
1172 }
1173 if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') {
1174 im_sign_char = '-';
1175 ++i_im;
1176 --n_im_digits;
1177 }
1178
1179 /* Determine if we have any "remainder" (after the digits, might include
1180 decimal or exponent or both (or neither)) */
Victor Stinnerafbaa202011-09-28 21:50:16 +02001181 parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001182 &n_re_remainder, &re_has_decimal);
Victor Stinnerafbaa202011-09-28 21:50:16 +02001183 parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001184 &n_im_remainder, &im_has_decimal);
1185
1186 /* Determine the grouping, separator, and decimal point, if any. */
1187 get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
1188 (format->thousands_separators ?
1189 LT_DEFAULT_LOCALE :
1190 LT_NO_LOCALE),
1191 &locale);
1192
1193 /* Turn off any padding. We'll do it later after we've composed
1194 the numbers without padding. */
1195 tmp_format.fill_char = '\0';
1196 tmp_format.align = '<';
1197 tmp_format.width = -1;
1198
1199 /* Calculate how much memory we'll need. */
1200 n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp,
1201 i_re, i_re + n_re_digits, n_re_remainder,
1202 re_has_decimal, &locale, &tmp_format);
1203
1204 /* Same formatting, but always include a sign, unless the real part is
1205 * going to be omitted, in which case we use whatever sign convention was
1206 * requested by the original format. */
1207 if (!skip_re)
1208 tmp_format.sign = '+';
1209 n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp,
1210 i_im, i_im + n_im_digits, n_im_remainder,
1211 im_has_decimal, &locale, &tmp_format);
1212
1213 if (skip_re)
1214 n_re_total = 0;
1215
1216 /* Add 1 for the 'j', and optionally 2 for parens. */
1217 calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
1218 format->width, format->align, &lpad, &rpad, &total);
1219
1220 result = PyUnicode_New(total, maxchar);
1221 if (result == NULL)
1222 goto done;
1223 rkind = PyUnicode_KIND(result);
1224 rdata = PyUnicode_DATA(result);
1225
1226 /* Populate the memory. First, the padding. */
1227 index = fill_padding(result, 0,
1228 n_re_total + n_im_total + 1 + add_parens * 2,
1229 format->fill_char=='\0' ? ' ' : format->fill_char,
1230 lpad, rpad);
1231
1232 if (add_parens)
1233 PyUnicode_WRITE(rkind, rdata, index++, '(');
1234
1235 if (!skip_re) {
Victor Stinnerafbaa202011-09-28 21:50:16 +02001236 err = fill_number(result, index, &re_spec,
1237 re_unicode_tmp, i_re, i_re + n_re_digits,
1238 NULL, 0,
1239 0,
1240 &locale, 0);
1241 if (err) {
1242 Py_CLEAR(result);
1243 goto done;
1244 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001245 index += n_re_total;
1246 }
Victor Stinnerafbaa202011-09-28 21:50:16 +02001247 err = fill_number(result, index, &im_spec,
1248 im_unicode_tmp, i_im, i_im + n_im_digits,
1249 NULL, 0,
1250 0,
1251 &locale, 0);
1252 if (err) {
1253 Py_CLEAR(result);
1254 goto done;
1255 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001256 index += n_im_total;
1257 PyUnicode_WRITE(rkind, rdata, index++, 'j');
1258
1259 if (add_parens)
1260 PyUnicode_WRITE(rkind, rdata, index++, ')');
1261
1262done:
1263 PyMem_Free(re_buf);
1264 PyMem_Free(im_buf);
1265 Py_XDECREF(re_unicode_tmp);
1266 Py_XDECREF(im_unicode_tmp);
1267 return result;
1268}
1269
1270/************************************************************************/
1271/*********** built in formatters ****************************************/
1272/************************************************************************/
1273PyObject *
1274_PyUnicode_FormatAdvanced(PyObject *obj,
1275 PyObject *format_spec,
1276 Py_ssize_t start, Py_ssize_t end)
1277{
1278 InternalFormatSpec format;
1279 PyObject *result = NULL;
1280
1281 /* check for the special case of zero length format spec, make
1282 it equivalent to str(obj) */
1283 if (start == end) {
1284 result = PyObject_Str(obj);
1285 goto done;
1286 }
1287
1288 /* parse the format_spec */
1289 if (!parse_internal_render_format_spec(format_spec, start, end,
1290 &format, 's', '<'))
1291 goto done;
1292
1293 /* type conversion? */
1294 switch (format.type) {
1295 case 's':
1296 /* no type conversion needed, already a string. do the formatting */
1297 result = format_string_internal(obj, &format);
1298 break;
1299 default:
1300 /* unknown */
1301 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1302 goto done;
1303 }
1304
1305done:
1306 return result;
1307}
1308
1309static PyObject*
1310format_int_or_long(PyObject* obj, PyObject* format_spec,
1311 Py_ssize_t start, Py_ssize_t end,
1312 IntOrLongToString tostring)
1313{
1314 PyObject *result = NULL;
1315 PyObject *tmp = NULL;
1316 InternalFormatSpec format;
1317
1318 /* check for the special case of zero length format spec, make
1319 it equivalent to str(obj) */
1320 if (start == end) {
1321 result = PyObject_Str(obj);
1322 goto done;
1323 }
1324
1325 /* parse the format_spec */
1326 if (!parse_internal_render_format_spec(format_spec, start, end,
1327 &format, 'd', '>'))
1328 goto done;
1329
1330 /* type conversion? */
1331 switch (format.type) {
1332 case 'b':
1333 case 'c':
1334 case 'd':
1335 case 'o':
1336 case 'x':
1337 case 'X':
1338 case 'n':
1339 /* no type conversion needed, already an int (or long). do
1340 the formatting */
1341 result = format_int_or_long_internal(obj, &format, tostring);
1342 break;
1343
1344 case 'e':
1345 case 'E':
1346 case 'f':
1347 case 'F':
1348 case 'g':
1349 case 'G':
1350 case '%':
1351 /* convert to float */
1352 tmp = PyNumber_Float(obj);
1353 if (tmp == NULL)
1354 goto done;
1355 result = format_float_internal(tmp, &format);
1356 break;
1357
1358 default:
1359 /* unknown */
1360 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1361 goto done;
1362 }
1363
1364done:
1365 Py_XDECREF(tmp);
1366 return result;
1367}
1368
1369/* Need to define long_format as a function that will convert a long
1370 to a string. In 3.0, _PyLong_Format has the correct signature. */
1371#define long_format _PyLong_Format
1372
1373PyObject *
1374_PyLong_FormatAdvanced(PyObject *obj,
1375 PyObject *format_spec,
1376 Py_ssize_t start, Py_ssize_t end)
1377{
1378 return format_int_or_long(obj, format_spec, start, end,
1379 long_format);
1380}
1381
1382PyObject *
1383_PyFloat_FormatAdvanced(PyObject *obj,
1384 PyObject *format_spec,
1385 Py_ssize_t start, Py_ssize_t end)
1386{
1387 PyObject *result = NULL;
1388 InternalFormatSpec format;
1389
1390 /* check for the special case of zero length format spec, make
1391 it equivalent to str(obj) */
1392 if (start == end) {
1393 result = PyObject_Str(obj);
1394 goto done;
1395 }
1396
1397 /* parse the format_spec */
1398 if (!parse_internal_render_format_spec(format_spec, start, end,
1399 &format, '\0', '>'))
1400 goto done;
1401
1402 /* type conversion? */
1403 switch (format.type) {
1404 case '\0': /* No format code: like 'g', but with at least one decimal. */
1405 case 'e':
1406 case 'E':
1407 case 'f':
1408 case 'F':
1409 case 'g':
1410 case 'G':
1411 case 'n':
1412 case '%':
1413 /* no conversion, already a float. do the formatting */
1414 result = format_float_internal(obj, &format);
1415 break;
1416
1417 default:
1418 /* unknown */
1419 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1420 goto done;
1421 }
1422
1423done:
1424 return result;
1425}
1426
1427PyObject *
1428_PyComplex_FormatAdvanced(PyObject *obj,
1429 PyObject *format_spec,
1430 Py_ssize_t start, Py_ssize_t end)
1431{
1432 PyObject *result = NULL;
1433 InternalFormatSpec format;
1434
1435 /* check for the special case of zero length format spec, make
1436 it equivalent to str(obj) */
1437 if (start == end) {
1438 result = PyObject_Str(obj);
1439 goto done;
1440 }
1441
1442 /* parse the format_spec */
1443 if (!parse_internal_render_format_spec(format_spec, start, end,
1444 &format, '\0', '>'))
1445 goto done;
1446
1447 /* type conversion? */
1448 switch (format.type) {
1449 case '\0': /* No format code: like 'g', but with at least one decimal. */
1450 case 'e':
1451 case 'E':
1452 case 'f':
1453 case 'F':
1454 case 'g':
1455 case 'G':
1456 case 'n':
1457 /* no conversion, already a complex. do the formatting */
1458 result = format_complex_internal(obj, &format);
1459 break;
1460
1461 default:
1462 /* unknown */
1463 unknown_presentation_type(format.type, obj->ob_type->tp_name);
1464 goto done;
1465 }
1466
1467done:
1468 return result;
1469}