blob: 3b0b7d340c2f3299a92864547a92aa6a190cff7f [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 Rossum90933611991-06-07 16:10:43 +000064int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065printobject(op, fp, flags)
66 object *op;
67 FILE *fp;
68 int flags;
69{
Guido van Rossum278ef591991-07-27 21:40:24 +000070 int ret = 0;
Guido van Rossum90933611991-06-07 16:10:43 +000071 if (intrcheck()) {
72 err_set(KeyboardInterrupt);
73 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 }
Guido van Rossum90933611991-06-07 16:10:43 +000075 if (op == NULL) {
76 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077 }
Guido van Rossum90933611991-06-07 16:10:43 +000078 else {
79 if (op->ob_refcnt <= 0)
Guido van Rossum0c182a11992-03-27 17:26:13 +000080 fprintf(fp, "(refcnt %u):", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +000081 if (op->ob_type->tp_print == NULL)
82 fprintf(fp, "<%s object at %lx>",
83 op->ob_type->tp_name, (long)op);
84 else
Guido van Rossum278ef591991-07-27 21:40:24 +000085 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +000086 }
Guido van Rossum278ef591991-07-27 21:40:24 +000087 if (ret == 0) {
88 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +000089 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +000090 clearerr(fp);
91 ret = -1;
92 }
93 }
94 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095}
96
97object *
98reprobject(v)
99 object *v;
100{
Guido van Rossum90933611991-06-07 16:10:43 +0000101 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000103 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 }
Guido van Rossum90933611991-06-07 16:10:43 +0000105 if (v == NULL)
106 return newstringobject("<NULL>");
107 else if (v->ob_type->tp_repr == NULL) {
108 char buf[120];
109 sprintf(buf, "<%.80s object at %lx>",
110 v->ob_type->tp_name, (long)v);
111 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 }
Guido van Rossum90933611991-06-07 16:10:43 +0000113 else
114 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115}
116
117int
118cmpobject(v, w)
119 object *v, *w;
120{
121 typeobject *tp;
122 if (v == w)
123 return 0;
124 if (v == NULL)
125 return -1;
126 if (w == NULL)
127 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000128 if ((tp = v->ob_type) != w->ob_type) {
129 if (tp->tp_as_number != NULL &&
130 w->ob_type->tp_as_number != NULL) {
131 if (coerce(&v, &w) != 0) {
132 err_clear();
133 /* XXX Should report the error,
134 XXX but the interface isn't there... */
135 }
136 else {
137 int cmp = (*v->ob_type->tp_compare)(v, w);
138 DECREF(v);
139 DECREF(w);
140 return cmp;
141 }
142 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000144 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 if (tp->tp_compare == NULL)
146 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000147 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148}
149
Guido van Rossum3f5da241990-12-20 15:06:42 +0000150object *
151getattr(v, name)
152 object *v;
153 char *name;
154{
155 if (v->ob_type->tp_getattr == NULL) {
156 err_setstr(TypeError, "attribute-less object");
157 return NULL;
158 }
159 else {
160 return (*v->ob_type->tp_getattr)(v, name);
161 }
162}
163
164int
165setattr(v, name, w)
166 object *v;
167 char *name;
168 object *w;
169{
170 if (v->ob_type->tp_setattr == NULL) {
171 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000172 err_setstr(TypeError,
173 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000174 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000175 err_setstr(TypeError,
176 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000177 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000178 }
179 else {
180 return (*v->ob_type->tp_setattr)(v, name, w);
181 }
182}
183
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184
185/*
186NoObject is usable as a non-NULL undefined value, used by the macro None.
187There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000188so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189*/
190
Guido van Rossum0c182a11992-03-27 17:26:13 +0000191/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000192static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193none_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 object *op;
195 FILE *fp;
196 int flags;
197{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000198 fprintf(fp, "None");
Guido van Rossum90933611991-06-07 16:10:43 +0000199 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000200}
201
Guido van Rossum0c182a11992-03-27 17:26:13 +0000202/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000203static 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);
Guido van Rossum90933611991-06-07 16:10:43 +0000281 if (printobject(op, fp, 0) != 0)
282 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 putc('\n', fp);
284 }
285}
286
287#endif