blob: 1881bdf6f95d64eededfea2717460c1da611e272 [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{
236 /* XXX should use memcmp on shortest size, then compare lengths */
237 return strcmp(a->ob_sval, b->ob_sval);
238}
239
240static sequence_methods string_as_sequence = {
241 stringlength, /*tp_length*/
242 stringconcat, /*tp_concat*/
243 stringrepeat, /*tp_repeat*/
244 stringitem, /*tp_item*/
245 stringslice, /*tp_slice*/
246 0, /*tp_ass_item*/
247 0, /*tp_ass_slice*/
248};
249
250typeobject Stringtype = {
251 OB_HEAD_INIT(&Typetype)
252 0,
253 "string",
254 sizeof(stringobject),
255 sizeof(char),
256 free, /*tp_dealloc*/
257 stringprint, /*tp_print*/
258 0, /*tp_getattr*/
259 0, /*tp_setattr*/
260 stringcompare, /*tp_compare*/
261 stringrepr, /*tp_repr*/
262 0, /*tp_as_number*/
263 &string_as_sequence, /*tp_as_sequence*/
264 0, /*tp_as_mapping*/
265};
266
267void
268joinstring(pv, w)
269 register object **pv;
270 register object *w;
271{
272 register object *v;
273 if (*pv == NULL || w == NULL || !is_stringobject(*pv))
274 return;
275 v = stringconcat((stringobject *) *pv, w);
276 DECREF(*pv);
277 *pv = v;
278}
279
280/* The following function breaks the notion that strings are immutable:
281 it changes the size of a string. We get away with this only if there
282 is only one module referencing the object. You can also think of it
283 as creating a new string object and destroying the old one, only
284 more efficiently. In any case, don't use this if the string may
285 already be known to some other part of the code... */
286
287int
288resizestring(pv, newsize)
289 object **pv;
290 int newsize;
291{
Guido van Rossum921842f1990-11-18 17:30:23 +0000292 register object *v;
293 register stringobject *sv;
294 v = *pv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 if (!is_stringobject(v) || v->ob_refcnt != 1) {
296 *pv = 0;
297 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000298 err_badcall();
299 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000301 /* XXX UNREF/NEWREF interface should be more symmetrical */
Guido van Rossum392ab321990-11-18 17:41:19 +0000302#ifdef REF_DEBUG
Guido van Rossum921842f1990-11-18 17:30:23 +0000303 --ref_total;
304#endif
305 UNREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 *pv = (object *)
307 realloc((char *)v,
308 sizeof(stringobject) + newsize * sizeof(char));
309 if (*pv == NULL) {
Guido van Rossum921842f1990-11-18 17:30:23 +0000310 DEL(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000311 err_nomem();
312 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 }
Guido van Rossum921842f1990-11-18 17:30:23 +0000314 NEWREF(*pv);
315 sv = (stringobject *) *pv;
316 sv->ob_size = newsize;
317 sv->ob_sval[newsize] = '\0';
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 return 0;
319}