This commit was manufactured by cvs2svn to create tag 'release101'.
[python/dscho.git] / Objects / object.c
blob09328be914e37051b3f10b30b3cf04c4c238fd0d
1 /***********************************************************
2 Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Generic object operations; and implementation of None (NoObject) */
27 #include "allobjects.h"
29 #ifdef REF_DEBUG
30 long ref_total;
31 #endif
33 /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
34 These are used by the individual routines for object creation.
35 Do not call them otherwise, they do not initialize the object! */
37 #ifdef COUNT_ALLOCS
38 static typeobject *type_list;
39 extern int tuple_zero_allocs, fast_tuple_allocs;
40 extern int quick_int_allocs, quick_neg_int_allocs;
41 extern int null_strings, one_strings;
42 void
43 dump_counts()
45 typeobject *tp;
47 for (tp = type_list; tp; tp = tp->tp_next)
48 fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
49 tp->tp_name, tp->tp_alloc, tp->tp_free,
50 tp->tp_maxalloc);
51 fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
52 fast_tuple_allocs, tuple_zero_allocs);
53 fprintf(stderr, "fast int allocs: pos: %d, neg: %d\n",
54 quick_int_allocs, quick_neg_int_allocs);
55 fprintf(stderr, "null strings: %d, 1-strings: %d\n",
56 null_strings, one_strings);
59 void
60 inc_count(tp)
61 typeobject *tp;
63 if (tp->tp_alloc == 0) {
64 /* first time; hang in linked list */
65 if (tp->tp_next != NULL) /* sanity check */
66 abort();
67 tp->tp_next = type_list;
68 type_list = tp;
70 tp->tp_alloc++;
71 if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
72 tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
74 #endif
76 object *
77 newobject(tp)
78 typeobject *tp;
80 object *op = (object *) malloc(tp->tp_basicsize);
81 if (op == NULL)
82 return err_nomem();
83 op->ob_type = tp;
84 NEWREF(op);
85 return op;
88 varobject *
89 newvarobject(tp, size)
90 typeobject *tp;
91 unsigned int size;
93 varobject *op = (varobject *)
94 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
95 if (op == NULL)
96 return (varobject *)err_nomem();
97 op->ob_type = tp;
98 op->ob_size = size;
99 NEWREF(op);
100 return op;
104 printobject(op, fp, flags)
105 object *op;
106 FILE *fp;
107 int flags;
109 int ret = 0;
110 if (intrcheck()) {
111 err_set(KeyboardInterrupt);
112 return -1;
114 if (op == NULL) {
115 fprintf(fp, "<nil>");
117 else {
118 if (op->ob_refcnt <= 0)
119 fprintf(fp, "<refcnt %u at %lx>",
120 op->ob_refcnt, (long)op);
121 else if (op->ob_type->tp_print == NULL) {
122 if (op->ob_type->tp_repr == NULL) {
123 fprintf(fp, "<%s object at %lx>",
124 op->ob_type->tp_name, (long)op);
126 else {
127 object *s;
128 if (flags & PRINT_RAW)
129 s = strobject(op);
130 else
131 s = reprobject(op);
132 if (s == NULL)
133 ret = -1;
134 else if (!is_stringobject(s)) {
135 err_setstr(TypeError,
136 "repr not string");
137 ret = -1;
139 else {
140 fprintf(fp, "%s", getstringvalue(s));
142 XDECREF(s);
145 else
146 ret = (*op->ob_type->tp_print)(op, fp, flags);
148 if (ret == 0) {
149 if (ferror(fp)) {
150 err_errno(IOError);
151 clearerr(fp);
152 ret = -1;
155 return ret;
158 object *
159 reprobject(v)
160 object *v;
162 if (intrcheck()) {
163 err_set(KeyboardInterrupt);
164 return NULL;
166 if (v == NULL)
167 return newstringobject("<NULL>");
168 else if (v->ob_type->tp_repr == NULL) {
169 char buf[120];
170 sprintf(buf, "<%.80s object at %lx>",
171 v->ob_type->tp_name, (long)v);
172 return newstringobject(buf);
174 else
175 return (*v->ob_type->tp_repr)(v);
178 object *
179 strobject(v)
180 object *v;
182 if (v == NULL)
183 return newstringobject("<NULL>");
184 if (is_stringobject(v)) {
185 INCREF(v);
186 return v;
188 else {
189 object *func = getattr(v, "__str__");
190 object *args;
191 object *res;
192 if (func == NULL) {
193 err_clear();
194 return reprobject(v);
196 args = newtupleobject(0);
197 if (args == NULL)
198 res = NULL;
199 else {
200 res = call_object(func, args);
201 DECREF(args);
203 DECREF(func);
204 return res;
209 cmpobject(v, w)
210 object *v, *w;
212 typeobject *tp;
213 if (v == w)
214 return 0;
215 if (v == NULL)
216 return -1;
217 if (w == NULL)
218 return 1;
219 if ((tp = v->ob_type) != w->ob_type) {
220 if (tp->tp_as_number != NULL &&
221 w->ob_type->tp_as_number != NULL) {
222 if (coerce(&v, &w) != 0) {
223 err_clear();
224 /* XXX Should report the error,
225 XXX but the interface isn't there... */
227 else {
228 int cmp = (*v->ob_type->tp_compare)(v, w);
229 DECREF(v);
230 DECREF(w);
231 return cmp;
234 return strcmp(tp->tp_name, w->ob_type->tp_name);
236 if (tp->tp_compare == NULL)
237 return (v < w) ? -1 : 1;
238 return (*tp->tp_compare)(v, w);
241 long
242 hashobject(v)
243 object *v;
245 typeobject *tp = v->ob_type;
246 if (tp->tp_hash != NULL)
247 return (*tp->tp_hash)(v);
248 if (tp->tp_compare == NULL)
249 return (long) v; /* Use address as hash value */
250 /* If there's a cmp but no hash defined, the object can't be hashed */
251 err_setstr(TypeError, "unhashable type");
252 return -1;
255 object *
256 getattr(v, name)
257 object *v;
258 char *name;
260 if (v->ob_type->tp_getattr == NULL) {
261 err_setstr(TypeError, "attribute-less object");
262 return NULL;
264 else {
265 return (*v->ob_type->tp_getattr)(v, name);
270 hasattr(v, name)
271 object *v;
272 char *name;
274 object *res = getattr(v, name);
275 if (res != NULL) {
276 DECREF(res);
277 return 1;
279 err_clear();
280 return 0;
284 setattr(v, name, w)
285 object *v;
286 char *name;
287 object *w;
289 if (v->ob_type->tp_setattr == NULL) {
290 if (v->ob_type->tp_getattr == NULL)
291 err_setstr(TypeError,
292 "attribute-less object (assign or del)");
293 else
294 err_setstr(TypeError,
295 "object has read-only attributes");
296 return -1;
298 else {
299 return (*v->ob_type->tp_setattr)(v, name, w);
303 /* Test a value used as condition, e.g., in a for or if statement.
304 Return -1 if an error occurred */
307 testbool(v)
308 object *v;
310 int res;
311 if (v == None)
312 res = 0;
313 else if (v->ob_type->tp_as_number != NULL)
314 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
315 else if (v->ob_type->tp_as_mapping != NULL)
316 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
317 else if (v->ob_type->tp_as_sequence != NULL)
318 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
319 else
320 res = 1;
321 if (res > 0)
322 res = 1;
323 return res;
328 NoObject is usable as a non-NULL undefined value, used by the macro None.
329 There is (and should be!) no way to create other objects of this type,
330 so there is exactly one (which is indestructible, by the way).
333 /* ARGSUSED */
334 static object *
335 none_repr(op)
336 object *op;
338 return newstringobject("None");
341 static typeobject Notype = {
342 OB_HEAD_INIT(&Typetype)
344 "None",
347 0, /*tp_dealloc*/ /*never called*/
348 0, /*tp_print*/
349 0, /*tp_getattr*/
350 0, /*tp_setattr*/
351 0, /*tp_compare*/
352 (reprfunc)none_repr, /*tp_repr*/
353 0, /*tp_as_number*/
354 0, /*tp_as_sequence*/
355 0, /*tp_as_mapping*/
356 0, /*tp_hash */
359 object NoObject = {
360 OB_HEAD_INIT(&Notype)
364 #ifdef TRACE_REFS
366 static object refchain = {&refchain, &refchain};
368 NEWREF(op)
369 object *op;
371 ref_total++;
372 op->ob_refcnt = 1;
373 op->_ob_next = refchain._ob_next;
374 op->_ob_prev = &refchain;
375 refchain._ob_next->_ob_prev = op;
376 refchain._ob_next = op;
377 #ifdef COUNT_ALLOCS
378 inc_count(op->ob_type);
379 #endif
382 UNREF(op)
383 register object *op;
385 register object *p;
386 if (op->ob_refcnt < 0) {
387 fprintf(stderr, "UNREF negative refcnt\n");
388 abort();
390 if (op == &refchain ||
391 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
392 fprintf(stderr, "UNREF invalid object\n");
393 abort();
395 #ifdef SLOW_UNREF_CHECK
396 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
397 if (p == op)
398 break;
400 if (p == &refchain) { /* Not found */
401 fprintf(stderr, "UNREF unknown object\n");
402 abort();
404 #endif
405 op->_ob_next->_ob_prev = op->_ob_prev;
406 op->_ob_prev->_ob_next = op->_ob_next;
407 op->_ob_next = op->_ob_prev = NULL;
410 DELREF(op)
411 object *op;
413 UNREF(op);
414 #ifdef COUNT_ALLOCS
415 op->ob_type->tp_free++;
416 #endif
417 (*(op)->ob_type->tp_dealloc)(op);
418 op->ob_type = NULL;
421 printrefs(fp)
422 FILE *fp;
424 object *op;
425 fprintf(fp, "Remaining objects (except strings referenced once):\n");
426 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
427 if (op->ob_refcnt == 1 && is_stringobject(op))
428 continue; /* Will be printed elsewhere */
429 fprintf(fp, "[%d] ", op->ob_refcnt);
430 if (printobject(op, fp, 0) != 0)
431 err_clear();
432 putc('\n', fp);
436 #endif