blob: ca7bac6dcac7cd2a2b24c2c0ab82cdcde51ef89e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
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
64stringdealloc(op)
65 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 Rossum85a5fbb1990-10-14 12:07:46 +000095stringprint(op, fp, flags)
96 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 *
122stringrepr(op)
123 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;
135 NEWREF(v);
136 v->ob_type = &Stringtype;
137 ((stringobject *)v)->ob_size = newsize;
138 p = ((stringobject *)v)->ob_sval;
139 *p++ = '\'';
140 for (i = 0; i < op->ob_size; i++) {
141 c = op->ob_sval[i];
142 if (c == '\'' || c == '\\')
143 *p++ = '\\', *p++ = c;
144 else if (c < ' ' || c >= 0177) {
145 sprintf(p, "\\%03o", c&0377);
146 while (*p != '\0')
147 p++;
148
149 }
150 else
151 *p++ = c;
152 }
153 *p++ = '\'';
154 *p = '\0';
155 resizestring(&v, (int) (p - ((stringobject *)v)->ob_sval));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000156 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158}
159
160static int
161stringlength(a)
162 stringobject *a;
163{
164 return a->ob_size;
165}
166
167static object *
168stringconcat(a, bb)
169 register stringobject *a;
170 register object *bb;
171{
172 register unsigned int size;
173 register stringobject *op;
174 if (!is_stringobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000175 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return NULL;
177 }
178#define b ((stringobject *)bb)
179 /* Optimize cases with empty left or right operand */
180 if (a->ob_size == 0) {
181 INCREF(bb);
182 return bb;
183 }
184 if (b->ob_size == 0) {
185 INCREF(a);
186 return (object *)a;
187 }
188 size = a->ob_size + b->ob_size;
189 op = (stringobject *)
190 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000191 if (op == NULL)
192 return err_nomem();
193 NEWREF(op);
194 op->ob_type = &Stringtype;
195 op->ob_size = size;
196 memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
197 memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
198 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 return (object *) op;
200#undef b
201}
202
203static object *
204stringrepeat(a, n)
205 register stringobject *a;
206 register int n;
207{
208 register int i;
209 register unsigned int size;
210 register stringobject *op;
211 if (n < 0)
212 n = 0;
213 size = a->ob_size * n;
214 if (size == a->ob_size) {
215 INCREF(a);
216 return (object *)a;
217 }
218 op = (stringobject *)
219 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000220 if (op == NULL)
221 return err_nomem();
222 NEWREF(op);
223 op->ob_type = &Stringtype;
224 op->ob_size = size;
225 for (i = 0; i < size; i += a->ob_size)
226 memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
227 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 return (object *) op;
229}
230
231/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
232
233static object *
234stringslice(a, i, j)
235 register stringobject *a;
236 register int i, j; /* May be negative! */
237{
238 if (i < 0)
239 i = 0;
240 if (j < 0)
241 j = 0; /* Avoid signed/unsigned bug in next line */
242 if (j > a->ob_size)
243 j = a->ob_size;
244 if (i == 0 && j == a->ob_size) { /* It's the same as a */
245 INCREF(a);
246 return (object *)a;
247 }
248 if (j < i)
249 j = i;
250 return newsizedstringobject(a->ob_sval + i, (int) (j-i));
251}
252
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000253#ifdef __STDC__
254#include <limits.h>
255#else
256#ifndef UCHAR_MAX
257#define UCHAR_MAX 255
258#endif
259#endif
260
261static object *characters[UCHAR_MAX + 1];
262
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263static object *
264stringitem(a, i)
265 stringobject *a;
266 register int i;
267{
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000268 int c;
269 object *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000271 err_setstr(IndexError, "string index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272 return NULL;
273 }
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000274 c = a->ob_sval[i] & UCHAR_MAX;
275 v = characters[c];
276 if (v == NULL) {
277 v = newsizedstringobject((char *)NULL, 1);
278 if (v == NULL)
279 return NULL;
280 characters[c] = v;
281 ((stringobject *)v)->ob_sval[0] = c;
282 }
283 INCREF(v);
284 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285}
286
287static int
288stringcompare(a, b)
289 stringobject *a, *b;
290{
Guido van Rossum253919f1991-02-13 23:18:39 +0000291 int len_a = a->ob_size, len_b = b->ob_size;
292 int min_len = (len_a < len_b) ? len_a : len_b;
293 int cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
294 if (cmp != 0)
295 return cmp;
296 return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297}
298
299static sequence_methods string_as_sequence = {
Guido van Rossumf380e661991-06-04 19:36:32 +0000300 stringlength, /*sq_length*/
301 stringconcat, /*sq_concat*/
302 stringrepeat, /*sq_repeat*/
303 stringitem, /*sq_item*/
304 stringslice, /*sq_slice*/
305 0, /*sq_ass_item*/
306 0, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307};
308
309typeobject Stringtype = {
310 OB_HEAD_INIT(&Typetype)
311 0,
312 "string",
313 sizeof(stringobject),
314 sizeof(char),
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000315 stringdealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316 stringprint, /*tp_print*/
317 0, /*tp_getattr*/
318 0, /*tp_setattr*/
319 stringcompare, /*tp_compare*/
320 stringrepr, /*tp_repr*/
321 0, /*tp_as_number*/
322 &string_as_sequence, /*tp_as_sequence*/
323 0, /*tp_as_mapping*/
324};
325
326void
327joinstring(pv, w)
328 register object **pv;
329 register object *w;
330{
331 register object *v;
332 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
333 return;
334 v = stringconcat((stringobject *) *pv, w);
335 DECREF(*pv);
336 *pv = v;
337}
338
339/* The following function breaks the notion that strings are immutable:
340 it changes the size of a string. We get away with this only if there
341 is only one module referencing the object. You can also think of it
342 as creating a new string object and destroying the old one, only
343 more efficiently. In any case, don't use this if the string may
344 already be known to some other part of the code... */
345
346int
347resizestring(pv, newsize)
348 object **pv;
349 int newsize;
350{
Guido van Rossum921842f1990-11-18 17:30:23 +0000351 register object *v;
352 register stringobject *sv;
353 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 if (!is_stringobject(v) || v->ob_refcnt != 1) {
355 *pv = 0;
356 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000357 err_badcall();
358 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000360 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000361#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000362 --ref_total;
363#endif
364 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 *pv = (object *)
366 realloc((char *)v,
367 sizeof(stringobject) + newsize * sizeof(char));
368 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000369 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000370 err_nomem();
371 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000373 NEWREF(*pv);
374 sv = (stringobject *) *pv;
375 sv->ob_size = newsize;
376 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 return 0;
378}