blob: 8e2b8ef0957e851038d7c8ae9527863e39bcc46d [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 */
472 x = PyInt_AsLong(value);
473 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
771 if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
772 goto done;
773 if (!STRINGLIB_CHECK(format_spec)) {
774 PyErr_SetString(PyExc_TypeError, STRINGLIB_TYPE_NAME " object required");
775 goto done;
776 }
777
778 /* check for the special case of zero length format spec, make
779 it equivalent to str(value) */
780 if (STRINGLIB_LEN(format_spec) == 0) {
781 result = STRINGLIB_TOSTR(value);
782 goto done;
783 }
784
785 /* parse the format_spec */
786 if (!parse_internal_render_format_spec(format_spec, &format, 's'))
787 goto done;
788
789 /* type conversion? */
790 switch (format.type) {
791 case 's':
792 /* no type conversion needed, already a string. do the formatting */
793 result = format_string_internal(value, &format);
794 break;
795#if 0
796 case 'b':
797 case 'c':
798 case 'd':
799 case 'o':
800 case 'x':
801 case 'X':
802 /* convert to integer */
803 /* XXX: make a stringlib function to do this when backporting,
804 since FromUnicode differs from FromString */
805 tmp = PyLong_FromUnicode(STRINGLIB_STR(value), STRINGLIB_LEN(value), 0);
806 if (tmp == NULL)
807 goto done;
808 result = format_long_internal(tmp, &format);
809 break;
810
811 case 'e':
812 case 'E':
813 case 'f':
814 case 'F':
815 case 'g':
816 case 'G':
817 case 'n':
818 case '%':
819 /* convert to float */
820 tmp = PyFloat_FromString(value);
821 if (tmp == NULL)
822 goto done;
823 result = format_float_internal(tmp, &format);
824 break;
825#endif
826 default:
827 /* unknown */
828 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
829 format.type);
830 goto done;
831 }
832
833done:
834 Py_XDECREF(tmp);
835 return result;
836}
837
838PyObject *
839FORMAT_LONG(PyObject* value, PyObject* args)
840{
841 PyObject *format_spec;
842 PyObject *result = NULL;
843 PyObject *tmp = NULL;
844 InternalFormatSpec format;
845
846 if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
847 goto done;
848 if (!STRINGLIB_CHECK(format_spec)) {
849 PyErr_SetString(PyExc_TypeError, STRINGLIB_TYPE_NAME " object required");
850 goto done;
851 }
852
853 /* check for the special case of zero length format spec, make
854 it equivalent to str(value) */
855 if (STRINGLIB_LEN(format_spec) == 0) {
856 result = STRINGLIB_TOSTR(value);
857 goto done;
858 }
859
860 /* parse the format_spec */
861 if (!parse_internal_render_format_spec(format_spec, &format, 'd'))
862 goto done;
863
864 /* type conversion? */
865 switch (format.type) {
866#if 0
867 case 's':
868 /* convert to string/unicode */
869 tmp = STRINGLIB_TOSTR(value);
870 if (tmp == NULL)
871 goto done;
872 result = format_string_internal(tmp, &format);
873 break;
874#endif
875 case 'b':
876 case 'c':
877 case 'd':
878 case 'o':
879 case 'x':
880 case 'X':
881 /* no type conversion needed, already an int. do the formatting */
882 result = format_long_internal(value, &format);
883 break;
884
885 case 'e':
886 case 'E':
887 case 'f':
888 case 'F':
889 case 'g':
890 case 'G':
891 case 'n':
892 case '%':
893 /* convert to float */
894 tmp = PyNumber_Float(value);
895 if (tmp == NULL)
896 goto done;
897 result = format_float_internal(value, &format);
898 break;
899
900 default:
901 /* unknown */
902 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
903 format.type);
904 goto done;
905 }
906
907done:
908 Py_XDECREF(tmp);
909 return result;
910}
911
912PyObject *
913FORMAT_FLOAT(PyObject *value, PyObject *args)
914{
915 PyObject *format_spec;
916 PyObject *result = NULL;
917 PyObject *tmp = NULL;
918 InternalFormatSpec format;
919
920 if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
921 goto done;
922 if (!STRINGLIB_CHECK(format_spec)) {
923 PyErr_SetString(PyExc_TypeError, STRINGLIB_TYPE_NAME " object required");
924 goto done;
925 }
926
927 /* check for the special case of zero length format spec, make
928 it equivalent to str(value) */
929 if (STRINGLIB_LEN(format_spec) == 0) {
930 result = STRINGLIB_TOSTR(value);
931 goto done;
932 }
933
934 /* parse the format_spec */
935 if (!parse_internal_render_format_spec(format_spec, &format, 'g'))
936 goto done;
937
938 /* type conversion? */
939 switch (format.type) {
940#if 0
941 case 's':
942 /* convert to string/unicode */
943 tmp = STRINGLIB_TOSTR(value);
944 if (tmp == NULL)
945 goto done;
946 result = format_string_internal(tmp, &format);
947 break;
948#endif
949 case 'b':
950 case 'c':
951 case 'd':
952 case 'o':
953 case 'x':
954 case 'X':
955 /* convert to integer */
956 tmp = PyNumber_Long(value);
957 if (tmp == NULL)
958 goto done;
959 result = format_long_internal(tmp, &format);
960 break;
961
962 case 'e':
963 case 'E':
964 case 'f':
965 case 'F':
966 case 'g':
967 case 'G':
968 case 'n':
969 case '%':
970 /* no conversion, already a float. do the formatting */
971 result = format_float_internal(value, &format);
972 break;
973
974 default:
975 /* unknown */
976 PyErr_Format(PyExc_ValueError, "Unknown conversion type %c",
977 format.type);
978 goto done;
979 }
980
981done:
982 Py_XDECREF(tmp);
983 return result;
984}