blob: 2b5b8918490dc99e66de5fd94d510faf59c7fae9 [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
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049varobject *
50newvarobject(tp, size)
51 typeobject *tp;
52 unsigned int size;
53{
54 varobject *op = (varobject *)
55 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
56 if (op == NULL)
Guido van Rossum05ab1111991-05-05 20:10:41 +000057 return (varobject *)err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058 NEWREF(op);
59 op->ob_type = tp;
60 op->ob_size = size;
61 return op;
62}
63
Guido van Rossum3f5da241990-12-20 15:06:42 +000064int StopPrint; /* Flag to indicate printing must be stopped */
65
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066static int prlevel;
67
68void
69printobject(op, fp, flags)
70 object *op;
71 FILE *fp;
72 int flags;
73{
74 /* Hacks to make printing a long or recursive object interruptible */
Guido van Rossum3f5da241990-12-20 15:06:42 +000075 /* XXX Interrupts should leave a more permanent error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 prlevel++;
77 if (!StopPrint && intrcheck()) {
78 fprintf(fp, "\n[print interrupted]\n");
79 StopPrint = 1;
80 }
81 if (!StopPrint) {
82 if (op == NULL) {
83 fprintf(fp, "<nil>");
84 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +000086 if (op->ob_refcnt <= 0)
87 fprintf(fp, "(refcnt %d):", op->ob_refcnt);
88 if (op->ob_type->tp_print == NULL) {
89 fprintf(fp, "<%s object at %lx>",
90 op->ob_type->tp_name, (long)op);
91 }
92 else {
93 (*op->ob_type->tp_print)(op, fp, flags);
94 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 }
96 }
97 prlevel--;
98 if (prlevel == 0)
99 StopPrint = 0;
100}
101
102object *
103reprobject(v)
104 object *v;
105{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106 object *w = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 /* Hacks to make converting a long or recursive object interruptible */
108 prlevel++;
109 if (!StopPrint && intrcheck()) {
110 StopPrint = 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 err_set(KeyboardInterrupt);
112 }
113 if (!StopPrint) {
114 if (v == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000115 w = newstringobject("<NULL>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 }
117 else if (v->ob_type->tp_repr == NULL) {
118 char buf[100];
119 sprintf(buf, "<%.80s object at %lx>",
120 v->ob_type->tp_name, (long)v);
121 w = newstringobject(buf);
122 }
123 else {
124 w = (*v->ob_type->tp_repr)(v);
125 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000126 if (StopPrint) {
127 XDECREF(w);
128 w = NULL;
129 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 }
131 prlevel--;
132 if (prlevel == 0)
133 StopPrint = 0;
134 return w;
135}
136
137int
138cmpobject(v, w)
139 object *v, *w;
140{
141 typeobject *tp;
142 if (v == w)
143 return 0;
144 if (v == NULL)
145 return -1;
146 if (w == NULL)
147 return 1;
148 if ((tp = v->ob_type) != w->ob_type)
149 return strcmp(tp->tp_name, w->ob_type->tp_name);
150 if (tp->tp_compare == NULL)
151 return (v < w) ? -1 : 1;
152 return ((*tp->tp_compare)(v, w));
153}
154
Guido van Rossum3f5da241990-12-20 15:06:42 +0000155object *
156getattr(v, name)
157 object *v;
158 char *name;
159{
160 if (v->ob_type->tp_getattr == NULL) {
161 err_setstr(TypeError, "attribute-less object");
162 return NULL;
163 }
164 else {
165 return (*v->ob_type->tp_getattr)(v, name);
166 }
167}
168
169int
170setattr(v, name, w)
171 object *v;
172 char *name;
173 object *w;
174{
175 if (v->ob_type->tp_setattr == NULL) {
176 if (v->ob_type->tp_getattr == NULL)
177 err_setstr(TypeError, "attribute-less object");
178 else
179 err_setstr(TypeError, "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000180 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000181 }
182 else {
183 return (*v->ob_type->tp_setattr)(v, name, w);
184 }
185}
186
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187
188/*
189NoObject is usable as a non-NULL undefined value, used by the macro None.
190There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000191so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192*/
193
194static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000195none_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 object *op;
197 FILE *fp;
198 int flags;
199{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000200 fprintf(fp, "None");
201}
202
203static object *
204none_repr(op)
205 object *op;
206{
207 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208}
209
210static typeobject Notype = {
211 OB_HEAD_INIT(&Typetype)
212 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 0,
215 0,
216 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000217 none_print, /*tp_print*/
218 0, /*tp_getattr*/
219 0, /*tp_setattr*/
220 0, /*tp_compare*/
221 none_repr, /*tp_repr*/
222 0, /*tp_as_number*/
223 0, /*tp_as_sequence*/
224 0, /*tp_as_mapping*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225};
226
227object NoObject = {
228 OB_HEAD_INIT(&Notype)
229};
230
231
232#ifdef TRACE_REFS
233
234static object refchain = {&refchain, &refchain};
235
236NEWREF(op)
237 object *op;
238{
239 ref_total++;
240 op->ob_refcnt = 1;
241 op->_ob_next = refchain._ob_next;
242 op->_ob_prev = &refchain;
243 refchain._ob_next->_ob_prev = op;
244 refchain._ob_next = op;
245}
246
Guido van Rossum3f5da241990-12-20 15:06:42 +0000247UNREF(op)
248 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000251 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000252 fprintf(stderr, "UNREF negative refcnt\n");
253 abort();
254 }
255 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
256 if (p == op)
257 break;
258 }
259 if (p == &refchain) { /* Not found */
260 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000261 abort();
262 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 op->_ob_next->_ob_prev = op->_ob_prev;
264 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000265}
266
267DELREF(op)
268 object *op;
269{
270 UNREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271 (*(op)->ob_type->tp_dealloc)(op);
272}
273
274printrefs(fp)
275 FILE *fp;
276{
277 object *op;
278 fprintf(fp, "Remaining objects:\n");
279 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
280 fprintf(fp, "[%d] ", op->ob_refcnt);
281 printobject(op, fp, 0);
282 putc('\n', fp);
283 }
284}
285
286#endif