blob: abb3dd69953508de121bf56a457172054b9e97e7 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* String object implementation */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
5object *
6newsizedstringobject(str, size)
7 char *str;
8 int size;
9{
10 register stringobject *op = (stringobject *)
11 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000012 if (op == NULL)
13 return err_nomem();
14 NEWREF(op);
15 op->ob_type = &Stringtype;
16 op->ob_size = size;
17 if (str != NULL)
18 memcpy(op->ob_sval, str, size);
19 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020 return (object *) op;
21}
22
23object *
24newstringobject(str)
25 char *str;
26{
27 register unsigned int size = strlen(str);
28 register stringobject *op = (stringobject *)
29 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000030 if (op == NULL)
31 return err_nomem();
32 NEWREF(op);
33 op->ob_type = &Stringtype;
34 op->ob_size = size;
35 strcpy(op->ob_sval, str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036 return (object *) op;
37}
38
39unsigned int
40getstringsize(op)
41 register object *op;
42{
43 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000044 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045 return -1;
46 }
47 return ((stringobject *)op) -> ob_size;
48}
49
50/*const*/ char *
51getstringvalue(op)
52 register object *op;
53{
54 if (!is_stringobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000055 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056 return NULL;
57 }
58 return ((stringobject *)op) -> ob_sval;
59}
60
61/* Methods */
62
63static void
64stringprint(op, fp, flags)
65 stringobject *op;
66 FILE *fp;
67 int flags;
68{
69 int i;
70 char c;
71 if (flags & PRINT_RAW) {
72 fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
73 return;
74 }
75 fprintf(fp, "'");
76 for (i = 0; i < op->ob_size; i++) {
77 c = op->ob_sval[i];
78 if (c == '\'' || c == '\\')
79 fprintf(fp, "\\%c", c);
80 else if (c < ' ' || c >= 0177)
81 fprintf(fp, "\\%03o", c&0377);
82 else
83 putc(c, fp);
84 }
85 fprintf(fp, "'");
86}
87
88static object *
89stringrepr(op)
90 register stringobject *op;
91{
92 /* XXX overflow? */
93 int newsize = 2 + 4 * op->ob_size * sizeof(char);
94 object *v = newsizedstringobject((char *)NULL, newsize);
95 if (v == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000096 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 }
98 else {
99 register int i;
100 register char c;
101 register char *p;
102 NEWREF(v);
103 v->ob_type = &Stringtype;
104 ((stringobject *)v)->ob_size = newsize;
105 p = ((stringobject *)v)->ob_sval;
106 *p++ = '\'';
107 for (i = 0; i < op->ob_size; i++) {
108 c = op->ob_sval[i];
109 if (c == '\'' || c == '\\')
110 *p++ = '\\', *p++ = c;
111 else if (c < ' ' || c >= 0177) {
112 sprintf(p, "\\%03o", c&0377);
113 while (*p != '\0')
114 p++;
115
116 }
117 else
118 *p++ = c;
119 }
120 *p++ = '\'';
121 *p = '\0';
122 resizestring(&v, (int) (p - ((stringobject *)v)->ob_sval));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000123 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125}
126
127static int
128stringlength(a)
129 stringobject *a;
130{
131 return a->ob_size;
132}
133
134static object *
135stringconcat(a, bb)
136 register stringobject *a;
137 register object *bb;
138{
139 register unsigned int size;
140 register stringobject *op;
141 if (!is_stringobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000142 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 return NULL;
144 }
145#define b ((stringobject *)bb)
146 /* Optimize cases with empty left or right operand */
147 if (a->ob_size == 0) {
148 INCREF(bb);
149 return bb;
150 }
151 if (b->ob_size == 0) {
152 INCREF(a);
153 return (object *)a;
154 }
155 size = a->ob_size + b->ob_size;
156 op = (stringobject *)
157 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000158 if (op == NULL)
159 return err_nomem();
160 NEWREF(op);
161 op->ob_type = &Stringtype;
162 op->ob_size = size;
163 memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
164 memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
165 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 return (object *) op;
167#undef b
168}
169
170static object *
171stringrepeat(a, n)
172 register stringobject *a;
173 register int n;
174{
175 register int i;
176 register unsigned int size;
177 register stringobject *op;
178 if (n < 0)
179 n = 0;
180 size = a->ob_size * n;
181 if (size == a->ob_size) {
182 INCREF(a);
183 return (object *)a;
184 }
185 op = (stringobject *)
186 malloc(sizeof(stringobject) + size * sizeof(char));
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000187 if (op == NULL)
188 return err_nomem();
189 NEWREF(op);
190 op->ob_type = &Stringtype;
191 op->ob_size = size;
192 for (i = 0; i < size; i += a->ob_size)
193 memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
194 op->ob_sval[size] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 return (object *) op;
196}
197
198/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
199
200static object *
201stringslice(a, i, j)
202 register stringobject *a;
203 register int i, j; /* May be negative! */
204{
205 if (i < 0)
206 i = 0;
207 if (j < 0)
208 j = 0; /* Avoid signed/unsigned bug in next line */
209 if (j > a->ob_size)
210 j = a->ob_size;
211 if (i == 0 && j == a->ob_size) { /* It's the same as a */
212 INCREF(a);
213 return (object *)a;
214 }
215 if (j < i)
216 j = i;
217 return newsizedstringobject(a->ob_sval + i, (int) (j-i));
218}
219
220static object *
221stringitem(a, i)
222 stringobject *a;
223 register int i;
224{
225 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000226 err_setstr(IndexError, "string index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 return NULL;
228 }
229 return stringslice(a, i, i+1);
230}
231
232static int
233stringcompare(a, b)
234 stringobject *a, *b;
235{
Guido van Rossum253919f1991-02-13 23:18:39 +0000236 int len_a = a->ob_size, len_b = b->ob_size;
237 int min_len = (len_a < len_b) ? len_a : len_b;
238 int cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
239 if (cmp != 0)
240 return cmp;
241 return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242}
243
244static sequence_methods string_as_sequence = {
245 stringlength, /*tp_length*/
246 stringconcat, /*tp_concat*/
247 stringrepeat, /*tp_repeat*/
248 stringitem, /*tp_item*/
249 stringslice, /*tp_slice*/
250 0, /*tp_ass_item*/
251 0, /*tp_ass_slice*/
252};
253
254typeobject Stringtype = {
255 OB_HEAD_INIT(&Typetype)
256 0,
257 "string",
258 sizeof(stringobject),
259 sizeof(char),
260 free, /*tp_dealloc*/
261 stringprint, /*tp_print*/
262 0, /*tp_getattr*/
263 0, /*tp_setattr*/
264 stringcompare, /*tp_compare*/
265 stringrepr, /*tp_repr*/
266 0, /*tp_as_number*/
267 &string_as_sequence, /*tp_as_sequence*/
268 0, /*tp_as_mapping*/
269};
270
271void
272joinstring(pv, w)
273 register object **pv;
274 register object *w;
275{
276 register object *v;
277 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
278 return;
279 v = stringconcat((stringobject *) *pv, w);
280 DECREF(*pv);
281 *pv = v;
282}
283
284/* The following function breaks the notion that strings are immutable:
285 it changes the size of a string. We get away with this only if there
286 is only one module referencing the object. You can also think of it
287 as creating a new string object and destroying the old one, only
288 more efficiently. In any case, don't use this if the string may
289 already be known to some other part of the code... */
290
291int
292resizestring(pv, newsize)
293 object **pv;
294 int newsize;
295{
Guido van Rossum921842f1990-11-18 17:30:23 +0000296 register object *v;
297 register stringobject *sv;
298 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 if (!is_stringobject(v) || v->ob_refcnt != 1) {
300 *pv = 0;
301 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000302 err_badcall();
303 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000305 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000306#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000307 --ref_total;
308#endif
309 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 *pv = (object *)
311 realloc((char *)v,
312 sizeof(stringobject) + newsize * sizeof(char));
313 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000314 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000315 err_nomem();
316 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000318 NEWREF(*pv);
319 sv = (stringobject *) *pv;
320 sv->ob_size = newsize;
321 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 return 0;
323}