blob: 79c12f2b9065870ad24b4221ddf2d19501fb797e [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 Rossum90933611991-06-07 16:10:43 +000070 if (intrcheck()) {
71 err_set(KeyboardInterrupt);
72 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 }
Guido van Rossum90933611991-06-07 16:10:43 +000074 if (op == NULL) {
75 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 }
Guido van Rossum90933611991-06-07 16:10:43 +000077 else {
78 if (op->ob_refcnt <= 0)
79 fprintf(fp, "(refcnt %d):", op->ob_refcnt);
80 if (op->ob_type->tp_print == NULL)
81 fprintf(fp, "<%s object at %lx>",
82 op->ob_type->tp_name, (long)op);
83 else
84 return (*op->ob_type->tp_print)(op, fp, flags);
85 }
86 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087}
88
89object *
90reprobject(v)
91 object *v;
92{
Guido van Rossum90933611991-06-07 16:10:43 +000093 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +000095 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 }
Guido van Rossum90933611991-06-07 16:10:43 +000097 if (v == NULL)
98 return newstringobject("<NULL>");
99 else if (v->ob_type->tp_repr == NULL) {
100 char buf[120];
101 sprintf(buf, "<%.80s object at %lx>",
102 v->ob_type->tp_name, (long)v);
103 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 }
Guido van Rossum90933611991-06-07 16:10:43 +0000105 else
106 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107}
108
109int
110cmpobject(v, w)
111 object *v, *w;
112{
113 typeobject *tp;
114 if (v == w)
115 return 0;
116 if (v == NULL)
117 return -1;
118 if (w == NULL)
119 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000120 if ((tp = v->ob_type) != w->ob_type) {
121 if (tp->tp_as_number != NULL &&
122 w->ob_type->tp_as_number != NULL) {
123 if (coerce(&v, &w) != 0) {
124 err_clear();
125 /* XXX Should report the error,
126 XXX but the interface isn't there... */
127 }
128 else {
129 int cmp = (*v->ob_type->tp_compare)(v, w);
130 DECREF(v);
131 DECREF(w);
132 return cmp;
133 }
134 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000136 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 if (tp->tp_compare == NULL)
138 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000139 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140}
141
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142object *
143getattr(v, name)
144 object *v;
145 char *name;
146{
147 if (v->ob_type->tp_getattr == NULL) {
148 err_setstr(TypeError, "attribute-less object");
149 return NULL;
150 }
151 else {
152 return (*v->ob_type->tp_getattr)(v, name);
153 }
154}
155
156int
157setattr(v, name, w)
158 object *v;
159 char *name;
160 object *w;
161{
162 if (v->ob_type->tp_setattr == NULL) {
163 if (v->ob_type->tp_getattr == NULL)
164 err_setstr(TypeError, "attribute-less object");
165 else
166 err_setstr(TypeError, "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000167 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000168 }
169 else {
170 return (*v->ob_type->tp_setattr)(v, name, w);
171 }
172}
173
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
175/*
176NoObject is usable as a non-NULL undefined value, used by the macro None.
177There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000178so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179*/
180
Guido van Rossum90933611991-06-07 16:10:43 +0000181static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182none_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 object *op;
184 FILE *fp;
185 int flags;
186{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000187 fprintf(fp, "None");
Guido van Rossum90933611991-06-07 16:10:43 +0000188 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000189}
190
191static object *
192none_repr(op)
193 object *op;
194{
195 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196}
197
198static typeobject Notype = {
199 OB_HEAD_INIT(&Typetype)
200 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000201 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 0,
203 0,
204 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000205 none_print, /*tp_print*/
206 0, /*tp_getattr*/
207 0, /*tp_setattr*/
208 0, /*tp_compare*/
209 none_repr, /*tp_repr*/
210 0, /*tp_as_number*/
211 0, /*tp_as_sequence*/
212 0, /*tp_as_mapping*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213};
214
215object NoObject = {
216 OB_HEAD_INIT(&Notype)
217};
218
219
220#ifdef TRACE_REFS
221
222static object refchain = {&refchain, &refchain};
223
224NEWREF(op)
225 object *op;
226{
227 ref_total++;
228 op->ob_refcnt = 1;
229 op->_ob_next = refchain._ob_next;
230 op->_ob_prev = &refchain;
231 refchain._ob_next->_ob_prev = op;
232 refchain._ob_next = op;
233}
234
Guido van Rossum3f5da241990-12-20 15:06:42 +0000235UNREF(op)
236 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000238 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000239 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240 fprintf(stderr, "UNREF negative refcnt\n");
241 abort();
242 }
243 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
244 if (p == op)
245 break;
246 }
247 if (p == &refchain) { /* Not found */
248 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000249 abort();
250 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 op->_ob_next->_ob_prev = op->_ob_prev;
252 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000253}
254
255DELREF(op)
256 object *op;
257{
258 UNREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 (*(op)->ob_type->tp_dealloc)(op);
260}
261
262printrefs(fp)
263 FILE *fp;
264{
265 object *op;
266 fprintf(fp, "Remaining objects:\n");
267 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
268 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000269 if (printobject(op, fp, 0) != 0)
270 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271 putc('\n', fp);
272 }
273}
274
275#endif