blob: 5c7345d40fb958dc84b5a48ed051442e4c89739e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossume5372401993-03-16 12:15:04 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* String object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
29object *
30newsizedstringobject(str, size)
31 char *str;
32 int size;
33{
34 register stringobject *op = (stringobject *)
35 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000036 if (op == NULL)
37 return err_nomem();
38 NEWREF(op);
39 op->ob_type = &Stringtype;
40 op->ob_size = size;
41 if (str != NULL)
42 memcpy(op->ob_sval, str, size);
43 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044 return (object *) op;
45}
46
47object *
48newstringobject(str)
49 char *str;
50{
51 register unsigned int size = strlen(str);
52 register stringobject *op = (stringobject *)
53 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000054 if (op == NULL)
55 return err_nomem();
56 NEWREF(op);
57 op->ob_type = &Stringtype;
58 op->ob_size = size;
59 strcpy(op->ob_sval, str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060 return (object *) op;
61}
62
Guido van Rossum719f5fa1992-03-27 17:31:02 +000063void
Guido van Rossume5372401993-03-16 12:15:04 +000064string_dealloc(op)
Guido van Rossum719f5fa1992-03-27 17:31:02 +000065 object *op;
66{
67 DEL(op);
68}
69
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070unsigned int
71getstringsize(op)
72 register object *op;
73{
74 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000075 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 return -1;
77 }
78 return ((stringobject *)op) -> ob_size;
79}
80
81/*const*/ char *
82getstringvalue(op)
83 register object *op;
84{
85 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000086 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 return NULL;
88 }
89 return ((stringobject *)op) -> ob_sval;
90}
91
92/* Methods */
93
Guido van Rossumbcaa31c1991-06-07 22:58:57 +000094static int
Guido van Rossume5372401993-03-16 12:15:04 +000095string_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 stringobject *op;
97 FILE *fp;
98 int flags;
99{
100 int i;
101 char c;
Guido van Rossumbcaa31c1991-06-07 22:58:57 +0000102 /* XXX Ought to check for interrupts when writing long strings */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 if (flags & PRINT_RAW) {
104 fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
Guido van Rossumbcaa31c1991-06-07 22:58:57 +0000105 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 }
107 fprintf(fp, "'");
108 for (i = 0; i < op->ob_size; i++) {
109 c = op->ob_sval[i];
110 if (c == '\'' || c == '\\')
111 fprintf(fp, "\\%c", c);
112 else if (c < ' ' || c >= 0177)
113 fprintf(fp, "\\%03o", c&0377);
114 else
115 putc(c, fp);
116 }
117 fprintf(fp, "'");
Guido van Rossumbcaa31c1991-06-07 22:58:57 +0000118 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119}
120
121static object *
Guido van Rossume5372401993-03-16 12:15:04 +0000122string_repr(op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 register stringobject *op;
124{
125 /* XXX overflow? */
126 int newsize = 2 + 4 * op->ob_size * sizeof(char);
127 object *v = newsizedstringobject((char *)NULL, newsize);
128 if (v == NULL) {
Guido van Rossumbcaa31c1991-06-07 22:58:57 +0000129 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 }
131 else {
132 register int i;
133 register char c;
134 register char *p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 p = ((stringobject *)v)->ob_sval;
136 *p++ = '\'';
137 for (i = 0; i < op->ob_size; i++) {
138 c = op->ob_sval[i];
139 if (c == '\'' || c == '\\')
140 *p++ = '\\', *p++ = c;
141 else if (c < ' ' || c >= 0177) {
142 sprintf(p, "\\%03o", c&0377);
143 while (*p != '\0')
144 p++;
145
146 }
147 else
148 *p++ = c;
149 }
150 *p++ = '\'';
151 *p = '\0';
152 resizestring(&v, (int) (p - ((stringobject *)v)->ob_sval));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000153 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155}
156
157static int
Guido van Rossume5372401993-03-16 12:15:04 +0000158string_length(a)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 stringobject *a;
160{
161 return a->ob_size;
162}
163
164static object *
Guido van Rossume5372401993-03-16 12:15:04 +0000165string_concat(a, bb)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 register stringobject *a;
167 register object *bb;
168{
169 register unsigned int size;
170 register stringobject *op;
171 if (!is_stringobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000172 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 return NULL;
174 }
175#define b ((stringobject *)bb)
176 /* Optimize cases with empty left or right operand */
177 if (a->ob_size == 0) {
178 INCREF(bb);
179 return bb;
180 }
181 if (b->ob_size == 0) {
182 INCREF(a);
183 return (object *)a;
184 }
185 size = a->ob_size + b->ob_size;
186 op = (stringobject *)
187 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000188 if (op == NULL)
189 return err_nomem();
190 NEWREF(op);
191 op->ob_type = &Stringtype;
192 op->ob_size = size;
193 memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
194 memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
195 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 return (object *) op;
197#undef b
198}
199
200static object *
Guido van Rossume5372401993-03-16 12:15:04 +0000201string_repeat(a, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 register stringobject *a;
203 register int n;
204{
205 register int i;
206 register unsigned int size;
207 register stringobject *op;
208 if (n < 0)
209 n = 0;
210 size = a->ob_size * n;
211 if (size == a->ob_size) {
212 INCREF(a);
213 return (object *)a;
214 }
215 op = (stringobject *)
216 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000217 if (op == NULL)
218 return err_nomem();
219 NEWREF(op);
220 op->ob_type = &Stringtype;
221 op->ob_size = size;
222 for (i = 0; i < size; i += a->ob_size)
223 memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
224 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 return (object *) op;
226}
227
228/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
229
230static object *
Guido van Rossume5372401993-03-16 12:15:04 +0000231string_slice(a, i, j)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232 register stringobject *a;
233 register int i, j; /* May be negative! */
234{
235 if (i < 0)
236 i = 0;
237 if (j < 0)
238 j = 0; /* Avoid signed/unsigned bug in next line */
239 if (j > a->ob_size)
240 j = a->ob_size;
241 if (i == 0 && j == a->ob_size) { /* It's the same as a */
242 INCREF(a);
243 return (object *)a;
244 }
245 if (j < i)
246 j = i;
247 return newsizedstringobject(a->ob_sval + i, (int) (j-i));
248}
249
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000250#ifdef __STDC__
251#include <limits.h>
252#else
253#ifndef UCHAR_MAX
254#define UCHAR_MAX 255
255#endif
256#endif
257
258static object *characters[UCHAR_MAX + 1];
259
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260static object *
Guido van Rossume5372401993-03-16 12:15:04 +0000261string_item(a, i)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262 stringobject *a;
263 register int i;
264{
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000265 int c;
266 object *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000268 err_setstr(IndexError, "string index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269 return NULL;
270 }
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000271 c = a->ob_sval[i] & UCHAR_MAX;
272 v = characters[c];
273 if (v == NULL) {
274 v = newsizedstringobject((char *)NULL, 1);
275 if (v == NULL)
276 return NULL;
277 characters[c] = v;
278 ((stringobject *)v)->ob_sval[0] = c;
279 }
280 INCREF(v);
281 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282}
283
284static int
Guido van Rossume5372401993-03-16 12:15:04 +0000285string_compare(a, b)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286 stringobject *a, *b;
287{
Guido van Rossum253919f1991-02-13 23:18:39 +0000288 int len_a = a->ob_size, len_b = b->ob_size;
289 int min_len = (len_a < len_b) ? len_a : len_b;
290 int cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
291 if (cmp != 0)
292 return cmp;
293 return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294}
295
Guido van Rossum9bfef441993-03-29 10:43:31 +0000296static long
297string_hash(a)
298 stringobject *a;
299{
300 register int len = a->ob_size;
301 register unsigned char *p = (unsigned char *) a->ob_sval;
302 register long x = *p << 7;
303 while (--len >= 0)
304 x = (x + x + x) ^ *p++;
305 x ^= a->ob_size;
306 if (x == -1)
307 x = -2;
308 return x;
309}
310
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311static sequence_methods string_as_sequence = {
Guido van Rossume5372401993-03-16 12:15:04 +0000312 string_length, /*sq_length*/
313 string_concat, /*sq_concat*/
314 string_repeat, /*sq_repeat*/
315 string_item, /*sq_item*/
316 string_slice, /*sq_slice*/
Guido van Rossumf380e661991-06-04 19:36:32 +0000317 0, /*sq_ass_item*/
318 0, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319};
320
321typeobject Stringtype = {
322 OB_HEAD_INIT(&Typetype)
323 0,
324 "string",
325 sizeof(stringobject),
326 sizeof(char),
Guido van Rossume5372401993-03-16 12:15:04 +0000327 string_dealloc, /*tp_dealloc*/
328 string_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 0, /*tp_getattr*/
330 0, /*tp_setattr*/
Guido van Rossume5372401993-03-16 12:15:04 +0000331 string_compare, /*tp_compare*/
332 string_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 0, /*tp_as_number*/
334 &string_as_sequence, /*tp_as_sequence*/
335 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000336 string_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337};
338
339void
340joinstring(pv, w)
341 register object **pv;
342 register object *w;
343{
344 register object *v;
345 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
346 return;
Guido van Rossume5372401993-03-16 12:15:04 +0000347 v = string_concat((stringobject *) *pv, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348 DECREF(*pv);
349 *pv = v;
350}
351
352/* The following function breaks the notion that strings are immutable:
353 it changes the size of a string. We get away with this only if there
354 is only one module referencing the object. You can also think of it
355 as creating a new string object and destroying the old one, only
356 more efficiently. In any case, don't use this if the string may
357 already be known to some other part of the code... */
358
359int
360resizestring(pv, newsize)
361 object **pv;
362 int newsize;
363{
Guido van Rossum921842f1990-11-18 17:30:23 +0000364 register object *v;
365 register stringobject *sv;
366 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 if (!is_stringobject(v) || v->ob_refcnt != 1) {
368 *pv = 0;
369 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000370 err_badcall();
371 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000373 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000374#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000375 --ref_total;
376#endif
377 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378 *pv = (object *)
379 realloc((char *)v,
380 sizeof(stringobject) + newsize * sizeof(char));
381 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000382 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000383 err_nomem();
384 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000386 NEWREF(*pv);
387 sv = (stringobject *) *pv;
388 sv->ob_size = newsize;
389 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 return 0;
391}
Guido van Rossume5372401993-03-16 12:15:04 +0000392
393/* Helpers for formatstring */
394
395static object *
396getnextarg(args, arglen, p_argidx)
397 object *args;
398 int arglen;
399 int *p_argidx;
400{
401 int argidx = *p_argidx;
402 if (argidx < arglen) {
403 (*p_argidx)++;
404 if (arglen < 0)
405 return args;
406 else
407 return gettupleitem(args, argidx);
408 }
409 err_setstr(TypeError, "not enough arguments for format string");
410 return NULL;
411}
412
413#define F_LJUST (1<<0)
414#define F_SIGN (1<<1)
415#define F_BLANK (1<<2)
416#define F_ALT (1<<3)
417#define F_ZERO (1<<4)
418
419extern double fabs PROTO((double));
420
421static char *
422formatfloat(flags, prec, type, v)
423 int flags;
424 int prec;
425 int type;
426 object *v;
427{
428 char fmt[20];
429 static char buf[120];
430 double x;
431 if (!getargs(v, "d;float argument required", &x))
432 return NULL;
433 if (prec < 0)
434 prec = 6;
435 if (prec > 50)
436 prec = 50; /* Arbitrary limitation */
437 if (type == 'f' && fabs(x)/1e25 >= 1e25)
438 type = 'g';
439 sprintf(fmt, "%%%s.%d%c", (flags&F_ALT) ? "#" : "", prec, type);
440 sprintf(buf, fmt, x);
441 return buf;
442}
443
444static char *
445formatint(flags, prec, type, v)
446 int flags;
447 int prec;
448 int type;
449 object *v;
450{
451 char fmt[20];
452 static char buf[50];
453 long x;
454 if (!getargs(v, "l;int argument required", &x))
455 return NULL;
456 if (prec < 0)
457 prec = 1;
458 sprintf(fmt, "%%%s.%dl%c", (flags&F_ALT) ? "#" : "", prec, type);
459 sprintf(buf, fmt, x);
460 return buf;
461}
462
463static char *
464formatchar(v)
465 object *v;
466{
467 static char buf[2];
468 if (is_stringobject(v)) {
469 if (!getargs(v, "c;%c requires int or char", &buf[0]))
470 return NULL;
471 }
472 else {
473 if (!getargs(v, "b;%c requires int or char", &buf[0]))
474 return NULL;
475 }
476 buf[1] = '\0';
477 return buf;
478}
479
480/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
481
482object *
483formatstring(format, args)
484 object *format;
485 object *args;
486{
487 char *fmt, *res;
488 int fmtcnt, rescnt, reslen, arglen, argidx;
489 object *result;
490 if (format == NULL || !is_stringobject(format) || args == NULL) {
491 err_badcall();
492 return NULL;
493 }
494 reslen = rescnt = 100;
495 result = newsizedstringobject((char *)NULL, reslen);
496 if (result == NULL)
497 return NULL;
498 res = getstringvalue(result);
499 fmt = getstringvalue(format);
500 fmtcnt = getstringsize(format);
501 if (is_tupleobject(args)) {
502 arglen = gettuplesize(args);
503 argidx = 0;
504 }
505 else {
506 arglen = -1;
507 argidx = -2;
508 }
509 while (--fmtcnt >= 0) {
510 if (*fmt != '%') {
511 if (--rescnt < 0) {
512 rescnt = reslen;
513 reslen = reslen * 2; /* Maybe less when big? */
514 if (resizestring(&result, reslen) < 0)
515 return NULL;
516 res = getstringvalue(result) + rescnt;
517 rescnt = reslen - rescnt;
518 }
519 *res++ = *fmt++;
520 }
521 else {
522 /* Got a format specifier */
523 int flags = 0;
524 char *fmtstart = fmt++;
525 int width = -1;
526 int prec = -1;
527 int size = 0;
528 int c;
529 int fill;
530 object *v;
531 char *buf;
532 int sign;
533 int len;
534 while (--fmtcnt >= 0) {
535 switch (c = *fmt++) {
536 case '-': flags |= F_LJUST; continue;
537 case '+': flags |= F_SIGN; continue;
538 case ' ': flags |= F_BLANK; continue;
539 case '#': flags |= F_ALT; continue;
540 case '0': flags |= F_ZERO; continue;
541 }
542 break;
543 }
544 if (c == '*') {
545 v = getnextarg(args, arglen, &argidx);
546 if (v == NULL)
547 goto error;
548 if (!is_intobject(v)) {
549 err_setstr(TypeError, "* wants int");
550 goto error;
551 }
552 width = getintvalue(v);
553 if (width < 0)
554 width = 0;
555 if (--fmtcnt >= 0)
556 c = *fmt++;
557 }
558 else if (isdigit(c)) {
559 width = c - '0';
560 while (--fmtcnt >= 0) {
561 c = *fmt++;
562 if (!isdigit(c))
563 break;
564 if ((width*10) / 10 != width) {
565 err_setstr(ValueError,
566 "width too big");
567 goto error;
568 }
569 width = width*10 + (c - '0');
570 }
571 }
572 if (c == '.') {
573 prec = 0;
574 if (--fmtcnt >= 0)
575 c = *fmt++;
576 if (c == '*') {
577 v = getnextarg(args, arglen, &argidx);
578 if (v == NULL)
579 goto error;
580 if (!is_intobject(v)) {
581 err_setstr(TypeError,
582 "* wants int");
583 goto error;
584 }
585 prec = getintvalue(v);
586 if (prec < 0)
587 prec = 0;
588 if (--fmtcnt >= 0)
589 c = *fmt++;
590 }
591 else if (isdigit(c)) {
592 prec = c - '0';
593 while (--fmtcnt >= 0) {
594 c = *fmt++;
595 if (!isdigit(c))
596 break;
597 if ((prec*10) / 10 != prec) {
598 err_setstr(ValueError,
599 "prec too big");
600 goto error;
601 }
602 prec = prec*10 + (c - '0');
603 }
604 }
605 } /* prec */
606 if (fmtcnt >= 0) {
607 if (c == 'h' || c == 'l' || c == 'L') {
608 size = c;
609 if (--fmtcnt >= 0)
610 c = *fmt++;
611 }
612 }
613 if (fmtcnt < 0) {
614 err_setstr(ValueError, "incomplete format");
615 goto error;
616 }
617 if (c != '%') {
618 v = getnextarg(args, arglen, &argidx);
619 if (v == NULL)
620 goto error;
621 }
622 sign = 0;
623 fill = ' ';
624 switch (c) {
625 case '%':
626 buf = "%";
627 len = 1;
628 break;
629 case 's':
630 if (!is_stringobject(v)) {
631 err_setstr(TypeError,
632 "%s wants string");
633 goto error;
634 }
635 buf = getstringvalue(v);
636 len = getstringsize(v);
637 if (prec >= 0 && len > prec)
638 len = prec;
639 break;
640 case 'i':
641 case 'd':
642 case 'u':
643 case 'o':
644 case 'x':
645 case 'X':
646 if (c == 'i')
647 c = 'd';
648 buf = formatint(flags, prec, c, v);
649 if (buf == NULL)
650 goto error;
651 len = strlen(buf);
652 sign = (c == 'd');
653 if (flags&F_ZERO)
654 fill = '0';
655 break;
656 case 'e':
657 case 'E':
658 case 'f':
659 case 'g':
660 case 'G':
661 buf = formatfloat(flags, prec, c, v);
662 if (buf == NULL)
663 goto error;
664 len = strlen(buf);
665 sign = 1;
666 if (flags&F_ZERO)
667 fill = '0';
668 break;
669 case 'c':
670 buf = formatchar(v);
671 if (buf == NULL)
672 goto error;
673 len = strlen(buf);
674 break;
675 default:
676 err_setstr(ValueError,
677 "unsupported format character");
678 goto error;
679 }
680 if (sign) {
681 if (*buf == '-' || *buf == '+') {
682 sign = *buf++;
683 len--;
684 }
685 else if (flags & F_SIGN)
686 sign = '+';
687 else if (flags & F_BLANK)
688 sign = ' ';
689 else
690 sign = '\0';
691 }
692 if (width < len)
693 width = len;
694 if (rescnt < width + (sign != '\0')) {
695 rescnt = reslen;
696 reslen = reslen + width + 100;
697 if (resizestring(&result, reslen) < 0)
698 return NULL;
699 res = getstringvalue(result) + rescnt;
700 rescnt = reslen - rescnt;
701 }
702 if (sign) {
703 *res++ = sign;
704 rescnt--;
705 if (width > len)
706 width--;
707 }
708 if (width > len && !(flags&F_LJUST)) {
709 do {
710 --rescnt;
711 *res++ = fill;
712 } while (--width > len);
713 }
714 memcpy(res, buf, len);
715 res += len;
716 rescnt -= len;
717 while (--width >= len) {
718 --rescnt;
719 *res++ = ' ';
720 }
721 } /* '%' */
722 } /* until end */
723 if (argidx < arglen) {
724 err_setstr(TypeError, "not all arguments converted");
725 goto error;
726 }
727 resizestring(&result, reslen - rescnt);
728 return result;
729 error:
730 DECREF(result);
731 return NULL;
732}