blob: 68f5c3a7927c193fa04a464d7ae6df23be1e8547 [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
63unsigned int
64getstringsize(op)
65 register object *op;
66{
67 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000068 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 return -1;
70 }
71 return ((stringobject *)op) -> ob_size;
72}
73
74/*const*/ char *
75getstringvalue(op)
76 register object *op;
77{
78 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000079 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 return NULL;
81 }
82 return ((stringobject *)op) -> ob_sval;
83}
84
85/* Methods */
86
87static void
88stringprint(op, fp, flags)
89 stringobject *op;
90 FILE *fp;
91 int flags;
92{
93 int i;
94 char c;
95 if (flags & PRINT_RAW) {
96 fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
97 return;
98 }
99 fprintf(fp, "'");
100 for (i = 0; i < op->ob_size; i++) {
101 c = op->ob_sval[i];
102 if (c == '\'' || c == '\\')
103 fprintf(fp, "\\%c", c);
104 else if (c < ' ' || c >= 0177)
105 fprintf(fp, "\\%03o", c&0377);
106 else
107 putc(c, fp);
108 }
109 fprintf(fp, "'");
110}
111
112static object *
113stringrepr(op)
114 register stringobject *op;
115{
116 /* XXX overflow? */
117 int newsize = 2 + 4 * op->ob_size * sizeof(char);
118 object *v = newsizedstringobject((char *)NULL, newsize);
119 if (v == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000120 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 }
122 else {
123 register int i;
124 register char c;
125 register char *p;
126 NEWREF(v);
127 v->ob_type = &Stringtype;
128 ((stringobject *)v)->ob_size = newsize;
129 p = ((stringobject *)v)->ob_sval;
130 *p++ = '\'';
131 for (i = 0; i < op->ob_size; i++) {
132 c = op->ob_sval[i];
133 if (c == '\'' || c == '\\')
134 *p++ = '\\', *p++ = c;
135 else if (c < ' ' || c >= 0177) {
136 sprintf(p, "\\%03o", c&0377);
137 while (*p != '\0')
138 p++;
139
140 }
141 else
142 *p++ = c;
143 }
144 *p++ = '\'';
145 *p = '\0';
146 resizestring(&v, (int) (p - ((stringobject *)v)->ob_sval));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000147 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149}
150
151static int
152stringlength(a)
153 stringobject *a;
154{
155 return a->ob_size;
156}
157
158static object *
159stringconcat(a, bb)
160 register stringobject *a;
161 register object *bb;
162{
163 register unsigned int size;
164 register stringobject *op;
165 if (!is_stringobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000166 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 return NULL;
168 }
169#define b ((stringobject *)bb)
170 /* Optimize cases with empty left or right operand */
171 if (a->ob_size == 0) {
172 INCREF(bb);
173 return bb;
174 }
175 if (b->ob_size == 0) {
176 INCREF(a);
177 return (object *)a;
178 }
179 size = a->ob_size + b->ob_size;
180 op = (stringobject *)
181 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000182 if (op == NULL)
183 return err_nomem();
184 NEWREF(op);
185 op->ob_type = &Stringtype;
186 op->ob_size = size;
187 memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
188 memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
189 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190 return (object *) op;
191#undef b
192}
193
194static object *
195stringrepeat(a, n)
196 register stringobject *a;
197 register int n;
198{
199 register int i;
200 register unsigned int size;
201 register stringobject *op;
202 if (n < 0)
203 n = 0;
204 size = a->ob_size * n;
205 if (size == a->ob_size) {
206 INCREF(a);
207 return (object *)a;
208 }
209 op = (stringobject *)
210 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000211 if (op == NULL)
212 return err_nomem();
213 NEWREF(op);
214 op->ob_type = &Stringtype;
215 op->ob_size = size;
216 for (i = 0; i < size; i += a->ob_size)
217 memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
218 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219 return (object *) op;
220}
221
222/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
223
224static object *
225stringslice(a, i, j)
226 register stringobject *a;
227 register int i, j; /* May be negative! */
228{
229 if (i < 0)
230 i = 0;
231 if (j < 0)
232 j = 0; /* Avoid signed/unsigned bug in next line */
233 if (j > a->ob_size)
234 j = a->ob_size;
235 if (i == 0 && j == a->ob_size) { /* It's the same as a */
236 INCREF(a);
237 return (object *)a;
238 }
239 if (j < i)
240 j = i;
241 return newsizedstringobject(a->ob_sval + i, (int) (j-i));
242}
243
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000244#ifdef __STDC__
245#include <limits.h>
246#else
247#ifndef UCHAR_MAX
248#define UCHAR_MAX 255
249#endif
250#endif
251
252static object *characters[UCHAR_MAX + 1];
253
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254static object *
255stringitem(a, i)
256 stringobject *a;
257 register int i;
258{
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000259 int c;
260 object *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000262 err_setstr(IndexError, "string index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 return NULL;
264 }
Guido van Rossumdaa8bb31991-04-04 10:48:33 +0000265 c = a->ob_sval[i] & UCHAR_MAX;
266 v = characters[c];
267 if (v == NULL) {
268 v = newsizedstringobject((char *)NULL, 1);
269 if (v == NULL)
270 return NULL;
271 characters[c] = v;
272 ((stringobject *)v)->ob_sval[0] = c;
273 }
274 INCREF(v);
275 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276}
277
278static int
279stringcompare(a, b)
280 stringobject *a, *b;
281{
Guido van Rossum253919f1991-02-13 23:18:39 +0000282 int len_a = a->ob_size, len_b = b->ob_size;
283 int min_len = (len_a < len_b) ? len_a : len_b;
284 int cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
285 if (cmp != 0)
286 return cmp;
287 return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288}
289
290static sequence_methods string_as_sequence = {
291 stringlength, /*tp_length*/
292 stringconcat, /*tp_concat*/
293 stringrepeat, /*tp_repeat*/
294 stringitem, /*tp_item*/
295 stringslice, /*tp_slice*/
296 0, /*tp_ass_item*/
297 0, /*tp_ass_slice*/
298};
299
300typeobject Stringtype = {
301 OB_HEAD_INIT(&Typetype)
302 0,
303 "string",
304 sizeof(stringobject),
305 sizeof(char),
306 free, /*tp_dealloc*/
307 stringprint, /*tp_print*/
308 0, /*tp_getattr*/
309 0, /*tp_setattr*/
310 stringcompare, /*tp_compare*/
311 stringrepr, /*tp_repr*/
312 0, /*tp_as_number*/
313 &string_as_sequence, /*tp_as_sequence*/
314 0, /*tp_as_mapping*/
315};
316
317void
318joinstring(pv, w)
319 register object **pv;
320 register object *w;
321{
322 register object *v;
323 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
324 return;
325 v = stringconcat((stringobject *) *pv, w);
326 DECREF(*pv);
327 *pv = v;
328}
329
330/* The following function breaks the notion that strings are immutable:
331 it changes the size of a string. We get away with this only if there
332 is only one module referencing the object. You can also think of it
333 as creating a new string object and destroying the old one, only
334 more efficiently. In any case, don't use this if the string may
335 already be known to some other part of the code... */
336
337int
338resizestring(pv, newsize)
339 object **pv;
340 int newsize;
341{
Guido van Rossum921842f1990-11-18 17:30:23 +0000342 register object *v;
343 register stringobject *sv;
344 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 if (!is_stringobject(v) || v->ob_refcnt != 1) {
346 *pv = 0;
347 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000348 err_badcall();
349 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000351 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000352#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000353 --ref_total;
354#endif
355 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 *pv = (object *)
357 realloc((char *)v,
358 sizeof(stringobject) + newsize * sizeof(char));
359 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000360 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000361 err_nomem();
362 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000364 NEWREF(*pv);
365 sv = (stringobject *) *pv;
366 sv->ob_size = newsize;
367 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000368 return 0;
369}