blob: 33fe48502f6fa7763e2df097b8657c6a36947da5 [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 }
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000494 fmt = getstringvalue(format);
495 fmtcnt = getstringsize(format);
496 reslen = rescnt = fmtcnt + 100;
Guido van Rossume5372401993-03-16 12:15:04 +0000497 result = newsizedstringobject((char *)NULL, reslen);
498 if (result == NULL)
499 return NULL;
500 res = getstringvalue(result);
Guido van Rossume5372401993-03-16 12:15:04 +0000501 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) {
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000512 rescnt = fmtcnt + 100;
513 reslen += rescnt;
Guido van Rossume5372401993-03-16 12:15:04 +0000514 if (resizestring(&result, reslen) < 0)
515 return NULL;
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000516 res = getstringvalue(result) + reslen - rescnt;
Guido van Rossume5372401993-03-16 12:15:04 +0000517 }
518 *res++ = *fmt++;
519 }
520 else {
521 /* Got a format specifier */
522 int flags = 0;
523 char *fmtstart = fmt++;
524 int width = -1;
525 int prec = -1;
526 int size = 0;
527 int c;
528 int fill;
529 object *v;
530 char *buf;
531 int sign;
532 int len;
533 while (--fmtcnt >= 0) {
534 switch (c = *fmt++) {
535 case '-': flags |= F_LJUST; continue;
536 case '+': flags |= F_SIGN; continue;
537 case ' ': flags |= F_BLANK; continue;
538 case '#': flags |= F_ALT; continue;
539 case '0': flags |= F_ZERO; continue;
540 }
541 break;
542 }
543 if (c == '*') {
544 v = getnextarg(args, arglen, &argidx);
545 if (v == NULL)
546 goto error;
547 if (!is_intobject(v)) {
548 err_setstr(TypeError, "* wants int");
549 goto error;
550 }
551 width = getintvalue(v);
552 if (width < 0)
553 width = 0;
554 if (--fmtcnt >= 0)
555 c = *fmt++;
556 }
557 else if (isdigit(c)) {
558 width = c - '0';
559 while (--fmtcnt >= 0) {
560 c = *fmt++;
561 if (!isdigit(c))
562 break;
563 if ((width*10) / 10 != width) {
564 err_setstr(ValueError,
565 "width too big");
566 goto error;
567 }
568 width = width*10 + (c - '0');
569 }
570 }
571 if (c == '.') {
572 prec = 0;
573 if (--fmtcnt >= 0)
574 c = *fmt++;
575 if (c == '*') {
576 v = getnextarg(args, arglen, &argidx);
577 if (v == NULL)
578 goto error;
579 if (!is_intobject(v)) {
580 err_setstr(TypeError,
581 "* wants int");
582 goto error;
583 }
584 prec = getintvalue(v);
585 if (prec < 0)
586 prec = 0;
587 if (--fmtcnt >= 0)
588 c = *fmt++;
589 }
590 else if (isdigit(c)) {
591 prec = c - '0';
592 while (--fmtcnt >= 0) {
593 c = *fmt++;
594 if (!isdigit(c))
595 break;
596 if ((prec*10) / 10 != prec) {
597 err_setstr(ValueError,
598 "prec too big");
599 goto error;
600 }
601 prec = prec*10 + (c - '0');
602 }
603 }
604 } /* prec */
605 if (fmtcnt >= 0) {
606 if (c == 'h' || c == 'l' || c == 'L') {
607 size = c;
608 if (--fmtcnt >= 0)
609 c = *fmt++;
610 }
611 }
612 if (fmtcnt < 0) {
613 err_setstr(ValueError, "incomplete format");
614 goto error;
615 }
616 if (c != '%') {
617 v = getnextarg(args, arglen, &argidx);
618 if (v == NULL)
619 goto error;
620 }
621 sign = 0;
622 fill = ' ';
623 switch (c) {
624 case '%':
625 buf = "%";
626 len = 1;
627 break;
628 case 's':
629 if (!is_stringobject(v)) {
630 err_setstr(TypeError,
631 "%s wants string");
632 goto error;
633 }
634 buf = getstringvalue(v);
635 len = getstringsize(v);
636 if (prec >= 0 && len > prec)
637 len = prec;
638 break;
639 case 'i':
640 case 'd':
641 case 'u':
642 case 'o':
643 case 'x':
644 case 'X':
645 if (c == 'i')
646 c = 'd';
647 buf = formatint(flags, prec, c, v);
648 if (buf == NULL)
649 goto error;
650 len = strlen(buf);
651 sign = (c == 'd');
652 if (flags&F_ZERO)
653 fill = '0';
654 break;
655 case 'e':
656 case 'E':
657 case 'f':
658 case 'g':
659 case 'G':
660 buf = formatfloat(flags, prec, c, v);
661 if (buf == NULL)
662 goto error;
663 len = strlen(buf);
664 sign = 1;
665 if (flags&F_ZERO)
666 fill = '0';
667 break;
668 case 'c':
669 buf = formatchar(v);
670 if (buf == NULL)
671 goto error;
672 len = strlen(buf);
673 break;
674 default:
675 err_setstr(ValueError,
676 "unsupported format character");
677 goto error;
678 }
679 if (sign) {
680 if (*buf == '-' || *buf == '+') {
681 sign = *buf++;
682 len--;
683 }
684 else if (flags & F_SIGN)
685 sign = '+';
686 else if (flags & F_BLANK)
687 sign = ' ';
688 else
689 sign = '\0';
690 }
691 if (width < len)
692 width = len;
693 if (rescnt < width + (sign != '\0')) {
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000694 reslen -= rescnt;
695 rescnt = width + fmtcnt + 100;
696 reslen += rescnt;
Guido van Rossume5372401993-03-16 12:15:04 +0000697 if (resizestring(&result, reslen) < 0)
698 return NULL;
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000699 res = getstringvalue(result) + reslen - rescnt;
Guido van Rossume5372401993-03-16 12:15:04 +0000700 }
701 if (sign) {
702 *res++ = sign;
703 rescnt--;
704 if (width > len)
705 width--;
706 }
707 if (width > len && !(flags&F_LJUST)) {
708 do {
709 --rescnt;
710 *res++ = fill;
711 } while (--width > len);
712 }
713 memcpy(res, buf, len);
714 res += len;
715 rescnt -= len;
716 while (--width >= len) {
717 --rescnt;
718 *res++ = ' ';
719 }
720 } /* '%' */
721 } /* until end */
722 if (argidx < arglen) {
723 err_setstr(TypeError, "not all arguments converted");
724 goto error;
725 }
726 resizestring(&result, reslen - rescnt);
727 return result;
728 error:
729 DECREF(result);
730 return NULL;
731}