blob: 9f8de920b243c8ee1c8d8981a4d3e290f9bcf929 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
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;
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
158stringlength(a)
159 stringobject *a;
160{
161 return a->ob_size;
162}
163
164static object *
165stringconcat(a, bb)
166 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 *
201stringrepeat(a, n)
202 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 *
231stringslice(a, i, j)
232 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 *
261stringitem(a, i)
262 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
285stringcompare(a, b)
286 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
296static sequence_methods string_as_sequence = {
Guido van Rossumf380e661991-06-04 19:36:32 +0000297 stringlength, /*sq_length*/
298 stringconcat, /*sq_concat*/
299 stringrepeat, /*sq_repeat*/
300 stringitem, /*sq_item*/
301 stringslice, /*sq_slice*/
302 0, /*sq_ass_item*/
303 0, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304};
305
306typeobject Stringtype = {
307 OB_HEAD_INIT(&Typetype)
308 0,
309 "string",
310 sizeof(stringobject),
311 sizeof(char),
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000312 stringdealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 stringprint, /*tp_print*/
314 0, /*tp_getattr*/
315 0, /*tp_setattr*/
316 stringcompare, /*tp_compare*/
317 stringrepr, /*tp_repr*/
318 0, /*tp_as_number*/
319 &string_as_sequence, /*tp_as_sequence*/
320 0, /*tp_as_mapping*/
321};
322
323void
324joinstring(pv, w)
325 register object **pv;
326 register object *w;
327{
328 register object *v;
329 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
330 return;
331 v = stringconcat((stringobject *) *pv, w);
332 DECREF(*pv);
333 *pv = v;
334}
335
336/* The following function breaks the notion that strings are immutable:
337 it changes the size of a string. We get away with this only if there
338 is only one module referencing the object. You can also think of it
339 as creating a new string object and destroying the old one, only
340 more efficiently. In any case, don't use this if the string may
341 already be known to some other part of the code... */
342
343int
344resizestring(pv, newsize)
345 object **pv;
346 int newsize;
347{
Guido van Rossum921842f1990-11-18 17:30:23 +0000348 register object *v;
349 register stringobject *sv;
350 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 if (!is_stringobject(v) || v->ob_refcnt != 1) {
352 *pv = 0;
353 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000354 err_badcall();
355 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000357 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000358#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000359 --ref_total;
360#endif
361 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362 *pv = (object *)
363 realloc((char *)v,
364 sizeof(stringobject) + newsize * sizeof(char));
365 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000366 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000367 err_nomem();
368 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000370 NEWREF(*pv);
371 sv = (stringobject *) *pv;
372 sv->ob_size = newsize;
373 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000374 return 0;
375}