blob: c54bf5c951389bf90d9099e05d508bca6f8bbc8e [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 Rossum3f5da241990-12-20 15:06:42 +000025/* Generic object operations; and implementation of None (NoObject) */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000026
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum3f5da241990-12-20 15:06:42 +000029#ifdef REF_DEBUG
30long ref_total;
31#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032
Guido van Rossum3f5da241990-12-20 15:06:42 +000033/* 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! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
37object *
38newobject(tp)
39 typeobject *tp;
40{
41 object *op = (object *) malloc(tp->tp_basicsize);
42 if (op == NULL)
43 return err_nomem();
44 NEWREF(op);
45 op->ob_type = tp;
46 return op;
47}
48
49#if 0 /* unused */
50
51varobject *
52newvarobject(tp, size)
53 typeobject *tp;
54 unsigned int size;
55{
56 varobject *op = (varobject *)
57 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
58 if (op == NULL)
59 return err_nomem();
60 NEWREF(op);
61 op->ob_type = tp;
62 op->ob_size = size;
63 return op;
64}
65
66#endif
67
Guido van Rossum3f5da241990-12-20 15:06:42 +000068int StopPrint; /* Flag to indicate printing must be stopped */
69
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070static int prlevel;
71
72void
73printobject(op, fp, flags)
74 object *op;
75 FILE *fp;
76 int flags;
77{
78 /* Hacks to make printing a long or recursive object interruptible */
Guido van Rossum3f5da241990-12-20 15:06:42 +000079 /* XXX Interrupts should leave a more permanent error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 prlevel++;
81 if (!StopPrint && intrcheck()) {
82 fprintf(fp, "\n[print interrupted]\n");
83 StopPrint = 1;
84 }
85 if (!StopPrint) {
86 if (op == NULL) {
87 fprintf(fp, "<nil>");
88 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +000090 if (op->ob_refcnt <= 0)
91 fprintf(fp, "(refcnt %d):", op->ob_refcnt);
92 if (op->ob_type->tp_print == NULL) {
93 fprintf(fp, "<%s object at %lx>",
94 op->ob_type->tp_name, (long)op);
95 }
96 else {
97 (*op->ob_type->tp_print)(op, fp, flags);
98 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 }
100 }
101 prlevel--;
102 if (prlevel == 0)
103 StopPrint = 0;
104}
105
106object *
107reprobject(v)
108 object *v;
109{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000110 object *w = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 /* Hacks to make converting a long or recursive object interruptible */
112 prlevel++;
113 if (!StopPrint && intrcheck()) {
114 StopPrint = 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 err_set(KeyboardInterrupt);
116 }
117 if (!StopPrint) {
118 if (v == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119 w = newstringobject("<NULL>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 }
121 else if (v->ob_type->tp_repr == NULL) {
122 char buf[100];
123 sprintf(buf, "<%.80s object at %lx>",
124 v->ob_type->tp_name, (long)v);
125 w = newstringobject(buf);
126 }
127 else {
128 w = (*v->ob_type->tp_repr)(v);
129 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130 if (StopPrint) {
131 XDECREF(w);
132 w = NULL;
133 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 }
135 prlevel--;
136 if (prlevel == 0)
137 StopPrint = 0;
138 return w;
139}
140
141int
142cmpobject(v, w)
143 object *v, *w;
144{
145 typeobject *tp;
146 if (v == w)
147 return 0;
148 if (v == NULL)
149 return -1;
150 if (w == NULL)
151 return 1;
152 if ((tp = v->ob_type) != w->ob_type)
153 return strcmp(tp->tp_name, w->ob_type->tp_name);
154 if (tp->tp_compare == NULL)
155 return (v < w) ? -1 : 1;
156 return ((*tp->tp_compare)(v, w));
157}
158
Guido van Rossum3f5da241990-12-20 15:06:42 +0000159object *
160getattr(v, name)
161 object *v;
162 char *name;
163{
164 if (v->ob_type->tp_getattr == NULL) {
165 err_setstr(TypeError, "attribute-less object");
166 return NULL;
167 }
168 else {
169 return (*v->ob_type->tp_getattr)(v, name);
170 }
171}
172
173int
174setattr(v, name, w)
175 object *v;
176 char *name;
177 object *w;
178{
179 if (v->ob_type->tp_setattr == NULL) {
180 if (v->ob_type->tp_getattr == NULL)
181 err_setstr(TypeError, "attribute-less object");
182 else
183 err_setstr(TypeError, "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000184 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000185 }
186 else {
187 return (*v->ob_type->tp_setattr)(v, name, w);
188 }
189}
190
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191
192/*
193NoObject is usable as a non-NULL undefined value, used by the macro None.
194There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000195so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196*/
197
198static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000199none_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 object *op;
201 FILE *fp;
202 int flags;
203{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204 fprintf(fp, "None");
205}
206
207static object *
208none_repr(op)
209 object *op;
210{
211 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212}
213
214static typeobject Notype = {
215 OB_HEAD_INIT(&Typetype)
216 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000217 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 0,
219 0,
220 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221 none_print, /*tp_print*/
222 0, /*tp_getattr*/
223 0, /*tp_setattr*/
224 0, /*tp_compare*/
225 none_repr, /*tp_repr*/
226 0, /*tp_as_number*/
227 0, /*tp_as_sequence*/
228 0, /*tp_as_mapping*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229};
230
231object NoObject = {
232 OB_HEAD_INIT(&Notype)
233};
234
235
236#ifdef TRACE_REFS
237
238static object refchain = {&refchain, &refchain};
239
240NEWREF(op)
241 object *op;
242{
243 ref_total++;
244 op->ob_refcnt = 1;
245 op->_ob_next = refchain._ob_next;
246 op->_ob_prev = &refchain;
247 refchain._ob_next->_ob_prev = op;
248 refchain._ob_next = op;
249}
250
Guido van Rossum3f5da241990-12-20 15:06:42 +0000251UNREF(op)
252 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000255 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000256 fprintf(stderr, "UNREF negative refcnt\n");
257 abort();
258 }
259 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
260 if (p == op)
261 break;
262 }
263 if (p == &refchain) { /* Not found */
264 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000265 abort();
266 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 op->_ob_next->_ob_prev = op->_ob_prev;
268 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000269}
270
271DELREF(op)
272 object *op;
273{
274 UNREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275 (*(op)->ob_type->tp_dealloc)(op);
276}
277
278printrefs(fp)
279 FILE *fp;
280{
281 object *op;
282 fprintf(fp, "Remaining objects:\n");
283 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
284 fprintf(fp, "[%d] ", op->ob_refcnt);
285 printobject(op, fp, 0);
286 putc('\n', fp);
287 }
288}
289
290#endif