blob: b4f6e3c018986215fa5de55ab6bc5975ec4b64df [file] [log] [blame]
Eric Smith8c663262007-08-25 02:26:07 +00001/* implements the string, long, and float formatters. that is,
2 string.__format__, etc. */
3
4/* Before including this, you must include either:
5 stringlib/unicodedefs.h
6 stringlib/stringdefs.h
7
8 Also, you should define the names:
9 FORMAT_STRING
10 FORMAT_LONG
11 FORMAT_FLOAT
12 to be whatever you want the public names of these functions to
13 be. These are the only non-static functions defined here.
14*/
15
Eric Smithb7f5ba12007-08-29 12:38:45 +000016#define ALLOW_PARENS_FOR_SIGN 0
17
Eric Smith8c663262007-08-25 02:26:07 +000018/*
19 get_integer consumes 0 or more decimal digit characters from an
20 input string, updates *result with the corresponding positive
21 integer, and returns the number of digits consumed.
22
23 returns -1 on error.
24*/
25static int
26get_integer(STRINGLIB_CHAR **ptr, STRINGLIB_CHAR *end,
27 Py_ssize_t *result)
28{
29 Py_ssize_t accumulator, digitval, oldaccumulator;
30 int numdigits;
31 accumulator = numdigits = 0;
32 for (;;(*ptr)++, numdigits++) {
33 if (*ptr >= end)
34 break;
35 digitval = STRINGLIB_TODECIMAL(**ptr);
36 if (digitval < 0)
37 break;
38 /*
39 This trick was copied from old Unicode format code. It's cute,
40 but would really suck on an old machine with a slow divide
41 implementation. Fortunately, in the normal case we do not
42 expect too many digits.
43 */
44 oldaccumulator = accumulator;
45 accumulator *= 10;
46 if ((accumulator+10)/10 != oldaccumulator+1) {
47 PyErr_Format(PyExc_ValueError,
48 "Too many decimal digits in format string");
49 return -1;
50 }
51 accumulator += digitval;
52 }
53 *result = accumulator;
54 return numdigits;
55}
56
57/************************************************************************/
58/*********** standard format specifier parsing **************************/
59/************************************************************************/
60
61/* returns true if this character is a specifier alignment token */
62Py_LOCAL_INLINE(int)
63is_alignment_token(STRINGLIB_CHAR c)
64{
65 switch (c) {
66 case '<': case '>': case '=': case '^':
67 return 1;
68 default:
69 return 0;
70 }
71}
72
73/* returns true if this character is a sign element */
74Py_LOCAL_INLINE(int)
75is_sign_element(STRINGLIB_CHAR c)
76{
77 switch (c) {
Eric Smithb7f5ba12007-08-29 12:38:45 +000078 case ' ': case '+': case '-':
Eric Smith44300952007-08-29 12:43:12 +000079#if ALLOW_PARENS_FOR_SIGN
Eric Smithb7f5ba12007-08-29 12:38:45 +000080 case '(':
Eric Smith44300952007-08-29 12:43:12 +000081#endif
Eric Smith8c663262007-08-25 02:26:07 +000082 return 1;
83 default:
84 return 0;
85 }
86}
87
88
89typedef struct {
90 STRINGLIB_CHAR fill_char;
91 STRINGLIB_CHAR align;
92 STRINGLIB_CHAR sign;
93 Py_ssize_t width;
94 Py_ssize_t precision;
95 STRINGLIB_CHAR type;
96} InternalFormatSpec;
97
98/*
99 ptr points to the start of the format_spec, end points just past its end.
100 fills in format with the parsed information.
101 returns 1 on success, 0 on failure.
102 if failure, sets the exception
103*/
104static int
105parse_internal_render_format_spec(PyObject *format_spec,
106 InternalFormatSpec *format,
107 char default_type)
108{
109 STRINGLIB_CHAR *ptr = STRINGLIB_STR(format_spec);
110 STRINGLIB_CHAR *end = ptr + STRINGLIB_LEN(format_spec);
111
112 /* end-ptr is used throughout this code to specify the length of
113 the input string */
114
115 Py_ssize_t specified_width;
116
117 format->fill_char = '\0';
118 format->align = '\0';
119 format->sign = '\0';
120 format->width = -1;
121 format->precision = -1;
122 format->type = default_type;
123
124 /* If the second char is an alignment token,
125 then parse the fill char */
126 if (end-ptr >= 2 && is_alignment_token(ptr[1])) {
127 format->align = ptr[1];
128 format->fill_char = ptr[0];
129 ptr += 2;
Eric Smith0cb431c2007-08-28 01:07:27 +0000130 }
131 else if (end-ptr >= 1 && is_alignment_token(ptr[0])) {
Eric Smith8c663262007-08-25 02:26:07 +0000132 format->align = ptr[0];
133 ptr++;
134 }
135
136 /* Parse the various sign options */
137 if (end-ptr >= 1 && is_sign_element(ptr[0])) {
138 format->sign = ptr[0];
139 ptr++;
Eric Smithb7f5ba12007-08-29 12:38:45 +0000140#if ALLOW_PARENS_FOR_SIGN
Eric Smith8c663262007-08-25 02:26:07 +0000141 if (end-ptr >= 1 && ptr[0] == ')') {
142 ptr++;
143 }
Eric Smithb7f5ba12007-08-29 12:38:45 +0000144#endif
Eric Smith8c663262007-08-25 02:26:07 +0000145 }
146
147 /* The special case for 0-padding (backwards compat) */
Eric Smith185e30c2007-08-30 22:23:08 +0000148 if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') {
Eric Smith8c663262007-08-25 02:26:07 +0000149 format->fill_char = '0';
150 if (format->align == '\0') {
151 format->align = '=';
152 }
153 ptr++;
154 }
155
156 /* XXX add error checking */
157 specified_width = get_integer(&ptr, end, &format->width);
158
159 /* if specified_width is 0, we didn't consume any characters for
160 the width. in that case, reset the width to -1, because
161 get_integer() will have set it to zero */
162 if (specified_width == 0) {
163 format->width = -1;
164 }
165
166 /* Parse field precision */
167 if (end-ptr && ptr[0] == '.') {
168 ptr++;
169
170 /* XXX add error checking */
171 specified_width = get_integer(&ptr, end, &format->precision);
172
173 /* not having a precision after a dot is an error */
174 if (specified_width == 0) {
175 PyErr_Format(PyExc_ValueError,
176 "Format specifier missing precision");
177 return 0;
178 }
179
180 }
181
182 /* Finally, parse the type field */
183
184 if (end-ptr > 1) {
185 /* invalid conversion spec */
186 PyErr_Format(PyExc_ValueError, "Invalid conversion specification");
187 return 0;
188 }
189
190 if (end-ptr == 1) {
191 format->type = ptr[0];
192 ptr++;
193 }
194
195 return 1;
196}
197
198
199/************************************************************************/
200/*********** common routines for numeric formatting *********************/
201/************************************************************************/
202
203/* describes the layout for an integer, see the comment in
204 _calc_integer_widths() for details */
205typedef struct {
206 Py_ssize_t n_lpadding;
207 Py_ssize_t n_spadding;
208 Py_ssize_t n_rpadding;
209 char lsign;
210 Py_ssize_t n_lsign;
211 char rsign;
212 Py_ssize_t n_rsign;
213 Py_ssize_t n_total; /* just a convenience, it's derivable from the
214 other fields */
215} NumberFieldWidths;
216
217/* not all fields of format are used. for example, precision is
218 unused. should this take discrete params in order to be more clear
219 about what it does? or is passing a single format parameter easier
220 and more efficient enough to justify a little obfuscation? */
221static void
222calc_number_widths(NumberFieldWidths *r, STRINGLIB_CHAR actual_sign,
223 Py_ssize_t n_digits, const InternalFormatSpec *format)
224{
225 r->n_lpadding = 0;
226 r->n_spadding = 0;
227 r->n_rpadding = 0;
228 r->lsign = '\0';
229 r->n_lsign = 0;
230 r->rsign = '\0';
231 r->n_rsign = 0;
232
233 /* the output will look like:
234 | |
235 | <lpadding> <lsign> <spadding> <digits> <rsign> <rpadding> |
236 | |
237
238 lsign and rsign are computed from format->sign and the actual
239 sign of the number
240
241 digits is already known
242
243 the total width is either given, or computed from the
244 actual digits
245
246 only one of lpadding, spadding, and rpadding can be non-zero,
247 and it's calculated from the width and other fields
248 */
249
250 /* compute the various parts we're going to write */
251 if (format->sign == '+') {
252 /* always put a + or - */
253 r->n_lsign = 1;
254 r->lsign = (actual_sign == '-' ? '-' : '+');
Eric Smith0cb431c2007-08-28 01:07:27 +0000255 }
Eric Smithb7f5ba12007-08-29 12:38:45 +0000256#if ALLOW_PARENS_FOR_SIGN
Eric Smith0cb431c2007-08-28 01:07:27 +0000257 else if (format->sign == '(') {
Eric Smith8c663262007-08-25 02:26:07 +0000258 if (actual_sign == '-') {
259 r->n_lsign = 1;
260 r->lsign = '(';
261 r->n_rsign = 1;
262 r->rsign = ')';
263 }
Eric Smith0cb431c2007-08-28 01:07:27 +0000264 }
Eric Smithb7f5ba12007-08-29 12:38:45 +0000265#endif
Eric Smith0cb431c2007-08-28 01:07:27 +0000266 else if (format->sign == ' ') {
Eric Smith8c663262007-08-25 02:26:07 +0000267 r->n_lsign = 1;
268 r->lsign = (actual_sign == '-' ? '-' : ' ');
Eric Smith0cb431c2007-08-28 01:07:27 +0000269 }
270 else {
Eric Smith8c663262007-08-25 02:26:07 +0000271 /* non specified, or the default (-) */
272 if (actual_sign == '-') {
273 r->n_lsign = 1;
274 r->lsign = '-';
275 }
276 }
277
278 /* now the number of padding characters */
279 if (format->width == -1) {
280 /* no padding at all, nothing to do */
Eric Smith0cb431c2007-08-28 01:07:27 +0000281 }
282 else {
Eric Smith8c663262007-08-25 02:26:07 +0000283 /* see if any padding is needed */
284 if (r->n_lsign + n_digits + r->n_rsign >= format->width) {
285 /* no padding needed, we're already bigger than the
286 requested width */
Eric Smith0cb431c2007-08-28 01:07:27 +0000287 }
288 else {
Eric Smith8c663262007-08-25 02:26:07 +0000289 /* determine which of left, space, or right padding is
290 needed */
291 Py_ssize_t padding = format->width - (r->n_lsign + n_digits + r->n_rsign);
292 if (format->align == '<')
293 r->n_rpadding = padding;
294 else if (format->align == '>')
295 r->n_lpadding = padding;
296 else if (format->align == '^') {
297 r->n_lpadding = padding / 2;
298 r->n_rpadding = padding - r->n_lpadding;
Eric Smith0cb431c2007-08-28 01:07:27 +0000299 }
Eric Smith185e30c2007-08-30 22:23:08 +0000300 else if (format->align == '=')
Eric Smith8c663262007-08-25 02:26:07 +0000301 r->n_spadding = padding;
Eric Smith185e30c2007-08-30 22:23:08 +0000302 else
303 r->n_lpadding = padding;
Eric Smith8c663262007-08-25 02:26:07 +0000304 }
305 }
306 r->n_total = r->n_lpadding + r->n_lsign + r->n_spadding +
307 n_digits + r->n_rsign + r->n_rpadding;
308}
309
310/* fill in the non-digit parts of a numbers's string representation,
311 as determined in _calc_integer_widths(). returns the pointer to
312 where the digits go. */
313static STRINGLIB_CHAR *
314fill_number(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec,
315 Py_ssize_t n_digits, STRINGLIB_CHAR fill_char)
316{
317 STRINGLIB_CHAR* p_digits;
318
319 if (spec->n_lpadding) {
320 STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding);
321 p_buf += spec->n_lpadding;
322 }
323 if (spec->n_lsign == 1) {
324 *p_buf++ = spec->lsign;
325 }
326 if (spec->n_spadding) {
327 STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding);
328 p_buf += spec->n_spadding;
329 }
330 p_digits = p_buf;
331 p_buf += n_digits;
332 if (spec->n_rsign == 1) {
333 *p_buf++ = spec->rsign;
334 }
335 if (spec->n_rpadding) {
336 STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding);
337 p_buf += spec->n_rpadding;
338 }
339 return p_digits;
340}
341
342/************************************************************************/
343/*********** string formatting ******************************************/
344/************************************************************************/
345
346static PyObject *
347format_string_internal(PyObject *value, const InternalFormatSpec *format)
348{
349 Py_ssize_t width; /* total field width */
350 Py_ssize_t lpad;
351 STRINGLIB_CHAR *dst;
352 STRINGLIB_CHAR *src = STRINGLIB_STR(value);
353 Py_ssize_t len = STRINGLIB_LEN(value);
354 PyObject *result = NULL;
355
356 /* sign is not allowed on strings */
357 if (format->sign != '\0') {
358 PyErr_SetString(PyExc_ValueError,
359 "Sign not allowed in string format specifier");
360 goto done;
361 }
362
363 /* '=' alignment not allowed on strings */
364 if (format->align == '=') {
365 PyErr_SetString(PyExc_ValueError,
366 "'=' alignment not allowed "
367 "in string format specifier");
368 goto done;
369 }
370
371 /* if precision is specified, output no more that format.precision
372 characters */
373 if (format->precision >= 0 && len >= format->precision) {
374 len = format->precision;
375 }
376
377 if (format->width >= 0) {
378 width = format->width;
379
380 /* but use at least len characters */
381 if (len > width) {
382 width = len;
383 }
Eric Smith0cb431c2007-08-28 01:07:27 +0000384 }
385 else {
Eric Smith8c663262007-08-25 02:26:07 +0000386 /* not specified, use all of the chars and no more */
387 width = len;
388 }
389
390 /* allocate the resulting string */
391 result = STRINGLIB_NEW(NULL, width);
392 if (result == NULL)
393 goto done;
394
395 /* now write into that space */
396 dst = STRINGLIB_STR(result);
397
398 /* figure out how much leading space we need, based on the
399 aligning */
400 if (format->align == '>')
401 lpad = width - len;
402 else if (format->align == '^')
403 lpad = (width - len) / 2;
404 else
405 lpad = 0;
406
407 /* if right aligning, increment the destination allow space on the
408 left */
409 memcpy(dst + lpad, src, len * sizeof(STRINGLIB_CHAR));
410
411 /* do any padding */
412 if (width > len) {
413 STRINGLIB_CHAR fill_char = format->fill_char;
414 if (fill_char == '\0') {
415 /* use the default, if not specified */
416 fill_char = ' ';
417 }
418
419 /* pad on left */
420 if (lpad)
421 STRINGLIB_FILL(dst, fill_char, lpad);
422
423 /* pad on right */
424 if (width - len - lpad)
425 STRINGLIB_FILL(dst + len + lpad, fill_char, width - len - lpad);
426 }
427
428done:
429 return result;
430}
431
432
433/************************************************************************/
434/*********** long formatting ********************************************/
435/************************************************************************/
436
437static PyObject *
438format_long_internal(PyObject *value, const InternalFormatSpec *format)
439{
440 PyObject *result = NULL;
441 int total_leading_chars_to_skip = 0; /* also includes sign, if
442 present */
443 STRINGLIB_CHAR sign = '\0';
444 STRINGLIB_CHAR *p;
445 Py_ssize_t n_digits; /* count of digits need from the computed
446 string */
447 Py_ssize_t len;
448 Py_ssize_t tmp;
449 NumberFieldWidths spec;
450 long x;
451
452 /* no precision allowed on integers */
453 if (format->precision != -1) {
454 PyErr_SetString(PyExc_ValueError,
455 "Precision not allowed in integer format specifier");
456 goto done;
457 }
458
459
460 /* special case for character formatting */
461 if (format->type == 'c') {
462 /* error to specify a sign */
463 if (format->sign != '\0') {
464 PyErr_SetString(PyExc_ValueError,
465 "Sign not allowed with integer"
466 " format specifier 'c'");
467 goto done;
468 }
469
470 /* taken from unicodeobject.c formatchar() */
471 /* Integer input truncated to a character */
Christian Heimes217cfd12007-12-02 14:31:20 +0000472 x = PyLong_AsLong(value);
Eric Smith8c663262007-08-25 02:26:07 +0000473 if (x == -1 && PyErr_Occurred())
474 goto done;
475#ifdef Py_UNICODE_WIDE
476 if (x < 0 || x > 0x10ffff) {
477 PyErr_SetString(PyExc_OverflowError,
478 "%c arg not in range(0x110000) "
479 "(wide Python build)");
480 goto done;
481 }
482#else
483 if (x < 0 || x > 0xffff) {
484 PyErr_SetString(PyExc_OverflowError,
485 "%c arg not in range(0x10000) "
486 "(narrow Python build)");
487 goto done;
488 }
489#endif
490 result = STRINGLIB_NEW(NULL, 1);
491 if (result == NULL)
492 goto done;
493 p = STRINGLIB_STR(result);
494 p[0] = (Py_UNICODE) x;
495 n_digits = len = 1;
Eric Smith0cb431c2007-08-28 01:07:27 +0000496 }
497 else {
Eric Smith8c663262007-08-25 02:26:07 +0000498 int base;
499 int format_leading_chars_to_skip; /* characters added by
500 PyNumber_ToBase that we
501 want to skip over.
502 instead of using them,
503 we'll compute our
504 own. */
505 /* compute the base and how many characters will be added by
506 PyNumber_ToBase */
507 switch (format->type) {
508 case 'b':
509 base = 2;
510 format_leading_chars_to_skip = 2; /* 0b */
511 break;
512 case 'o':
513 base = 8;
514 format_leading_chars_to_skip = 2; /* 0o */
515 break;
516 case 'x':
517 case 'X':
518 base = 16;
519 format_leading_chars_to_skip = 2; /* 0x */
520 break;
521 default: /* shouldn't be needed, but stops a compiler warning */
522 case 'd':
523 base = 10;
524 format_leading_chars_to_skip = 0;
525 break;
526 }
527
528 /* do the hard part, converting to a string in a given base */
529 result = PyNumber_ToBase(value, base);
530 if (result == NULL)
531 goto done;
532
533 n_digits = STRINGLIB_LEN(result);
534 len = n_digits;
535 p = STRINGLIB_STR(result);
536
537 /* if X, convert to uppercase */
538 if (format->type == 'X')
539 for (tmp = 0; tmp < len; tmp++)
540 p[tmp] = STRINGLIB_TOUPPER(p[tmp]);
541
542 /* is a sign character present in the output? if so, remember it
543 and skip it */
544 sign = p[0];
545 if (sign == '-') {
546 total_leading_chars_to_skip += 1;
547 n_digits--;
548 }
549
550 /* skip over the leading digits (0x, 0b, etc.) */
551 assert(n_digits >= format_leading_chars_to_skip + 1);
552 n_digits -= format_leading_chars_to_skip;
553 total_leading_chars_to_skip += format_leading_chars_to_skip;
554 }
555
556 calc_number_widths(&spec, sign, n_digits, format);
557
558 /* if the buffer is getting bigger, realloc it. if it's getting
559 smaller, don't realloc because we need to move the results
560 around first. realloc after we've done that */
561
562 if (spec.n_total > len) {
563 if (STRINGLIB_RESIZE(&result, spec.n_total) < 0)
564 goto done;
565 /* recalc, because string might have moved */
566 p = STRINGLIB_STR(result);
567 }
568
569 /* copy the characters into position first, since we're going to
570 overwrite some of that space */
571 /* we need to move if the number of left padding in the output is
572 different from the number of characters we need to skip */
573 if ((spec.n_lpadding + spec.n_lsign + spec.n_spadding) !=
574 total_leading_chars_to_skip) {
575 memmove(p + (spec.n_lpadding + spec.n_lsign + spec.n_spadding),
576 p + total_leading_chars_to_skip,
577 n_digits * sizeof(STRINGLIB_CHAR));
578 }
579
580 /* now fill in the non-digit parts */
581 fill_number(p, &spec, n_digits,
582 format->fill_char == '\0' ? ' ' : format->fill_char);
583
584 /* if we're getting smaller, realloc now */
585 if (spec.n_total < len) {
586 if (STRINGLIB_RESIZE(&result, spec.n_total) < 0)
587 goto done;
588 }
589
590done:
591 return result;
592}
593
594
595/************************************************************************/
596/*********** float formatting *******************************************/
597/************************************************************************/
598
599/* taken from unicodeobject.c */
600static Py_ssize_t
601strtounicode(Py_UNICODE *buffer, const char *charbuffer)
602{
603 register Py_ssize_t i;
604 Py_ssize_t len = strlen(charbuffer);
605 for (i = len - 1; i >= 0; i--)
Eric Smith185e30c2007-08-30 22:23:08 +0000606 buffer[i] = (Py_UNICODE) charbuffer[i];
Eric Smith8c663262007-08-25 02:26:07 +0000607
608 return len;
609}
610
611/* the callback function to call to do the actual float formatting.
612 it matches the definition of PyOS_ascii_formatd */
613typedef char*
614(*DoubleSnprintfFunction)(char *buffer, size_t buf_len,
615 const char *format, double d);
616
617/* just a wrapper to make PyOS_snprintf look like DoubleSnprintfFunction */
618static char*
619snprintf_double(char *buffer, size_t buf_len, const char *format, double d)
620{
621 PyOS_snprintf(buffer, buf_len, format, d);
622 return NULL;
623}
624
625/* see FORMATBUFLEN in unicodeobject.c */
626#define FLOAT_FORMATBUFLEN 120
627
628/* much of this is taken from unicodeobject.c */
629/* use type instead of format->type, so that it can be overridden by
630 format_number() */
631static PyObject *
632_format_float(STRINGLIB_CHAR type, PyObject *value,
633 const InternalFormatSpec *format,
634 DoubleSnprintfFunction snprintf)
635{
636 /* fmt = '%.' + `prec` + `type` + '%%'
637 worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/
638 char fmt[20];
639
640 /* taken from unicodeobject.c */
641 /* Worst case length calc to ensure no buffer overrun:
642
643 'g' formats:
Eric Smith185e30c2007-08-30 22:23:08 +0000644 fmt = %#.<prec>g
645 buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
646 for any double rep.)
647 len = 1 + prec + 1 + 2 + 5 = 9 + prec
Eric Smith8c663262007-08-25 02:26:07 +0000648
649 'f' formats:
Eric Smith185e30c2007-08-30 22:23:08 +0000650 buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
651 len = 1 + 50 + 1 + prec = 52 + prec
Eric Smith8c663262007-08-25 02:26:07 +0000652
653 If prec=0 the effective precision is 1 (the leading digit is
654 always given), therefore increase the length by one.
655
656 */
657 char charbuf[FLOAT_FORMATBUFLEN];
658 Py_ssize_t n_digits;
659 double x;
660 Py_ssize_t precision = format->precision;
661 PyObject *result = NULL;
662 STRINGLIB_CHAR sign;
663 char* trailing = "";
664 STRINGLIB_CHAR *p;
665 NumberFieldWidths spec;
666
667#if STRINGLIB_IS_UNICODE
668 Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN];
669#endif
670
671 /* first, do the conversion as 8-bit chars, using the platform's
672 snprintf. then, if needed, convert to unicode. */
673
674 /* 'F' is the same as 'f', per the PEP */
675 if (type == 'F')
676 type = 'f';
677
678 x = PyFloat_AsDouble(value);
679
680 if (x == -1.0 && PyErr_Occurred())
Eric Smith185e30c2007-08-30 22:23:08 +0000681 goto done;
Eric Smith8c663262007-08-25 02:26:07 +0000682
683 if (type == '%') {
684 type = 'f';
685 x *= 100;
686 trailing = "%";
687 }
688
689 if (precision < 0)
Eric Smith185e30c2007-08-30 22:23:08 +0000690 precision = 6;
Eric Smith8c663262007-08-25 02:26:07 +0000691 if (type == 'f' && (fabs(x) / 1e25) >= 1e25)
Eric Smith185e30c2007-08-30 22:23:08 +0000692 type = 'g';
Eric Smith8c663262007-08-25 02:26:07 +0000693
694 /* cast "type", because if we're in unicode we need to pass a
695 8-bit char. this is safe, because we've restricted what "type"
696 can be */
Guido van Rossum39342f42007-08-29 18:42:15 +0000697 PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, (char)type);
Eric Smith8c663262007-08-25 02:26:07 +0000698
699 /* call the passed in function to do the actual formatting */
700 snprintf(charbuf, sizeof(charbuf), fmt, x);
701
702 /* adding trailing to fmt with PyOS_snprintf doesn't work, not
703 sure why. we'll just concatentate it here, no harm done. we
704 know we can't have a buffer overflow from the fmt size
705 analysis */
706 strcat(charbuf, trailing);
707
708 /* rather than duplicate the code for snprintf for both unicode
709 and 8 bit strings, we just use the 8 bit version and then
710 convert to unicode in a separate code path. that's probably
711 the lesser of 2 evils. */
712#if STRINGLIB_IS_UNICODE
713 n_digits = strtounicode(unicodebuf, charbuf);
714 p = unicodebuf;
715#else
716 /* compute the length. I believe this is done because the return
717 value from snprintf above is unreliable */
718 n_digits = strlen(charbuf);
719 p = charbuf;
720#endif
721
722 /* is a sign character present in the output? if so, remember it
723 and skip it */
724 sign = p[0];
725 if (sign == '-') {
726 p++;
727 n_digits--;
728 }
729
730 calc_number_widths(&spec, sign, n_digits, format);
731
732 /* allocate a string with enough space */
733 result = STRINGLIB_NEW(NULL, spec.n_total);
734 if (result == NULL)
735 goto done;
736
737 /* fill in the non-digit parts */
738 fill_number(STRINGLIB_STR(result), &spec, n_digits,
739 format->fill_char == '\0' ? ' ' : format->fill_char);
740
741 /* fill in the digit parts */
742 memmove(STRINGLIB_STR(result) + (spec.n_lpadding + spec.n_lsign + spec.n_spadding),
743 p,
744 n_digits * sizeof(STRINGLIB_CHAR));
745
746done:
747 return result;
748}
749
750static PyObject *
751format_float_internal(PyObject *value, const InternalFormatSpec *format)
752{
753 if (format->type == 'n')
754 return _format_float('f', value, format, snprintf_double);
755 else
756 return _format_float(format->type, value, format, PyOS_ascii_formatd);
757}
758
759/************************************************************************/
760/*********** built in formatters ****************************************/
761/************************************************************************/
762
763PyObject *
764FORMAT_STRING(PyObject* value, PyObject* args)
765{
766 PyObject *format_spec;
767 PyObject *tmp = NULL;
768 PyObject *result = NULL;
769 InternalFormatSpec format;
770
Eric Smith37f10382007-09-01 10:56:01 +0000771 if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", &format_spec))
Eric Smith8c663262007-08-25 02:26:07 +0000772 goto done;
Eric Smith8c663262007-08-25 02:26:07 +0000773
774 /* check for the special case of zero length format spec, make
775 it equivalent to str(value) */
776 if (STRINGLIB_LEN(format_spec) == 0) {
777 result = STRINGLIB_TOSTR(value);
778 goto done;
779 }
780
781 /* parse the format_spec */
782 if (!parse_internal_render_format_spec(format_spec, &format, 's'))
783 goto done;
784
785 /* type conversion? */
786 switch (format.type) {
787 case 's':
788 /* no type conversion needed, already a string. do the formatting */
789 result = format_string_internal(value, &format);
790 break;
791#if 0
792 case 'b':
793 case 'c':
794 case 'd':
795 case 'o':
796 case 'x':
797 case 'X':
798 /* convert to integer */
799 /* XXX: make a stringlib function to do this when backporting,
800 since FromUnicode differs from FromString */
801 tmp = PyLong_FromUnicode(STRINGLIB_STR(value), STRINGLIB_LEN(value), 0);
802 if (tmp == NULL)
803 goto done;
804 result = format_long_internal(tmp, &format);
805 break;
806
807 case 'e':
808 case 'E':
809 case 'f':
810 case 'F':
811 case 'g':
812 case 'G':
813 case 'n':
814 case '%':
815 /* convert to float */
816 tmp = PyFloat_FromString(value);
817 if (tmp == NULL)
818 goto done;
819 result = format_float_internal(tmp, &format);
820 break;
821#endif
822 default:
823 /* unknown */
824 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
825 format.type);
826 goto done;
827 }
828
829done:
830 Py_XDECREF(tmp);
831 return result;
832}
833
834PyObject *
835FORMAT_LONG(PyObject* value, PyObject* args)
836{
837 PyObject *format_spec;
838 PyObject *result = NULL;
839 PyObject *tmp = NULL;
840 InternalFormatSpec format;
841
Eric Smith37f10382007-09-01 10:56:01 +0000842 if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", &format_spec))
Eric Smith8c663262007-08-25 02:26:07 +0000843 goto done;
Eric Smith8c663262007-08-25 02:26:07 +0000844
845 /* check for the special case of zero length format spec, make
846 it equivalent to str(value) */
847 if (STRINGLIB_LEN(format_spec) == 0) {
848 result = STRINGLIB_TOSTR(value);
849 goto done;
850 }
851
852 /* parse the format_spec */
853 if (!parse_internal_render_format_spec(format_spec, &format, 'd'))
854 goto done;
855
856 /* type conversion? */
857 switch (format.type) {
858#if 0
859 case 's':
860 /* convert to string/unicode */
861 tmp = STRINGLIB_TOSTR(value);
862 if (tmp == NULL)
863 goto done;
864 result = format_string_internal(tmp, &format);
865 break;
866#endif
867 case 'b':
868 case 'c':
869 case 'd':
870 case 'o':
871 case 'x':
872 case 'X':
873 /* no type conversion needed, already an int. do the formatting */
874 result = format_long_internal(value, &format);
875 break;
876
877 case 'e':
878 case 'E':
879 case 'f':
880 case 'F':
881 case 'g':
882 case 'G':
883 case 'n':
884 case '%':
885 /* convert to float */
886 tmp = PyNumber_Float(value);
887 if (tmp == NULL)
888 goto done;
889 result = format_float_internal(value, &format);
890 break;
891
892 default:
893 /* unknown */
894 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
895 format.type);
896 goto done;
897 }
898
899done:
900 Py_XDECREF(tmp);
901 return result;
902}
903
904PyObject *
905FORMAT_FLOAT(PyObject *value, PyObject *args)
906{
907 PyObject *format_spec;
908 PyObject *result = NULL;
909 PyObject *tmp = NULL;
910 InternalFormatSpec format;
911
Eric Smith37f10382007-09-01 10:56:01 +0000912 if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", &format_spec))
Eric Smith8c663262007-08-25 02:26:07 +0000913 goto done;
Eric Smith8c663262007-08-25 02:26:07 +0000914
915 /* check for the special case of zero length format spec, make
916 it equivalent to str(value) */
917 if (STRINGLIB_LEN(format_spec) == 0) {
918 result = STRINGLIB_TOSTR(value);
919 goto done;
920 }
921
922 /* parse the format_spec */
923 if (!parse_internal_render_format_spec(format_spec, &format, 'g'))
924 goto done;
925
926 /* type conversion? */
927 switch (format.type) {
928#if 0
929 case 's':
930 /* convert to string/unicode */
931 tmp = STRINGLIB_TOSTR(value);
932 if (tmp == NULL)
933 goto done;
934 result = format_string_internal(tmp, &format);
935 break;
936#endif
937 case 'b':
938 case 'c':
939 case 'd':
940 case 'o':
941 case 'x':
942 case 'X':
943 /* convert to integer */
944 tmp = PyNumber_Long(value);
945 if (tmp == NULL)
946 goto done;
947 result = format_long_internal(tmp, &format);
948 break;
949
950 case 'e':
951 case 'E':
952 case 'f':
953 case 'F':
954 case 'g':
955 case 'G':
956 case 'n':
957 case '%':
958 /* no conversion, already a float. do the formatting */
959 result = format_float_internal(value, &format);
960 break;
961
962 default:
963 /* unknown */
964 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
965 format.type);
966 goto done;
967 }
968
969done:
970 Py_XDECREF(tmp);
971 return result;
972}