blob: f2b4d1f22e846e98ce7bbea65f6fa1ed74553962 [file] [log] [blame]
Guido van Rossum3f5da241990-12-20 15:06:42 +00001/* Generic object operations; and implementation of None (NoObject) */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
Guido van Rossum3f5da241990-12-20 15:06:42 +00005#ifdef REF_DEBUG
6long ref_total;
7#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008
Guido van Rossum3f5da241990-12-20 15:06:42 +00009/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
10 These are used by the individual routines for object creation.
11 Do not call them otherwise, they do not initialize the object! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012
13object *
14newobject(tp)
15 typeobject *tp;
16{
17 object *op = (object *) malloc(tp->tp_basicsize);
18 if (op == NULL)
19 return err_nomem();
20 NEWREF(op);
21 op->ob_type = tp;
22 return op;
23}
24
25#if 0 /* unused */
26
27varobject *
28newvarobject(tp, size)
29 typeobject *tp;
30 unsigned int size;
31{
32 varobject *op = (varobject *)
33 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
34 if (op == NULL)
35 return err_nomem();
36 NEWREF(op);
37 op->ob_type = tp;
38 op->ob_size = size;
39 return op;
40}
41
42#endif
43
Guido van Rossum3f5da241990-12-20 15:06:42 +000044int StopPrint; /* Flag to indicate printing must be stopped */
45
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046static int prlevel;
47
48void
49printobject(op, fp, flags)
50 object *op;
51 FILE *fp;
52 int flags;
53{
54 /* Hacks to make printing a long or recursive object interruptible */
Guido van Rossum3f5da241990-12-20 15:06:42 +000055 /* XXX Interrupts should leave a more permanent error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056 prlevel++;
57 if (!StopPrint && intrcheck()) {
58 fprintf(fp, "\n[print interrupted]\n");
59 StopPrint = 1;
60 }
61 if (!StopPrint) {
62 if (op == NULL) {
63 fprintf(fp, "<nil>");
64 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +000066 if (op->ob_refcnt <= 0)
67 fprintf(fp, "(refcnt %d):", op->ob_refcnt);
68 if (op->ob_type->tp_print == NULL) {
69 fprintf(fp, "<%s object at %lx>",
70 op->ob_type->tp_name, (long)op);
71 }
72 else {
73 (*op->ob_type->tp_print)(op, fp, flags);
74 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 }
76 }
77 prlevel--;
78 if (prlevel == 0)
79 StopPrint = 0;
80}
81
82object *
83reprobject(v)
84 object *v;
85{
Guido van Rossum3f5da241990-12-20 15:06:42 +000086 object *w = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 /* Hacks to make converting a long or recursive object interruptible */
88 prlevel++;
89 if (!StopPrint && intrcheck()) {
90 StopPrint = 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 err_set(KeyboardInterrupt);
92 }
93 if (!StopPrint) {
94 if (v == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +000095 w = newstringobject("<NULL>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 }
97 else if (v->ob_type->tp_repr == NULL) {
98 char buf[100];
99 sprintf(buf, "<%.80s object at %lx>",
100 v->ob_type->tp_name, (long)v);
101 w = newstringobject(buf);
102 }
103 else {
104 w = (*v->ob_type->tp_repr)(v);
105 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106 if (StopPrint) {
107 XDECREF(w);
108 w = NULL;
109 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 }
111 prlevel--;
112 if (prlevel == 0)
113 StopPrint = 0;
114 return w;
115}
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;
128 if ((tp = v->ob_type) != w->ob_type)
129 return strcmp(tp->tp_name, w->ob_type->tp_name);
130 if (tp->tp_compare == NULL)
131 return (v < w) ? -1 : 1;
132 return ((*tp->tp_compare)(v, w));
133}
134
Guido van Rossum3f5da241990-12-20 15:06:42 +0000135object *
136getattr(v, name)
137 object *v;
138 char *name;
139{
140 if (v->ob_type->tp_getattr == NULL) {
141 err_setstr(TypeError, "attribute-less object");
142 return NULL;
143 }
144 else {
145 return (*v->ob_type->tp_getattr)(v, name);
146 }
147}
148
149int
150setattr(v, name, w)
151 object *v;
152 char *name;
153 object *w;
154{
155 if (v->ob_type->tp_setattr == NULL) {
156 if (v->ob_type->tp_getattr == NULL)
157 err_setstr(TypeError, "attribute-less object");
158 else
159 err_setstr(TypeError, "object has read-only attributes");
160 return NULL;
161 }
162 else {
163 return (*v->ob_type->tp_setattr)(v, name, w);
164 }
165}
166
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167
168/*
169NoObject is usable as a non-NULL undefined value, used by the macro None.
170There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172*/
173
174static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175none_print(op, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 object *op;
177 FILE *fp;
178 int flags;
179{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000180 fprintf(fp, "None");
181}
182
183static object *
184none_repr(op)
185 object *op;
186{
187 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188}
189
190static typeobject Notype = {
191 OB_HEAD_INIT(&Typetype)
192 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 0,
195 0,
196 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000197 none_print, /*tp_print*/
198 0, /*tp_getattr*/
199 0, /*tp_setattr*/
200 0, /*tp_compare*/
201 none_repr, /*tp_repr*/
202 0, /*tp_as_number*/
203 0, /*tp_as_sequence*/
204 0, /*tp_as_mapping*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205};
206
207object NoObject = {
208 OB_HEAD_INIT(&Notype)
209};
210
211
212#ifdef TRACE_REFS
213
214static object refchain = {&refchain, &refchain};
215
216NEWREF(op)
217 object *op;
218{
219 ref_total++;
220 op->ob_refcnt = 1;
221 op->_ob_next = refchain._ob_next;
222 op->_ob_prev = &refchain;
223 refchain._ob_next->_ob_prev = op;
224 refchain._ob_next = op;
225}
226
Guido van Rossum3f5da241990-12-20 15:06:42 +0000227UNREF(op)
228 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000230 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000231 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232 fprintf(stderr, "UNREF negative refcnt\n");
233 abort();
234 }
235 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
236 if (p == op)
237 break;
238 }
239 if (p == &refchain) { /* Not found */
240 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000241 abort();
242 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243 op->_ob_next->_ob_prev = op->_ob_prev;
244 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000245}
246
247DELREF(op)
248 object *op;
249{
250 UNREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 (*(op)->ob_type->tp_dealloc)(op);
252}
253
254printrefs(fp)
255 FILE *fp;
256{
257 object *op;
258 fprintf(fp, "Remaining objects:\n");
259 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
260 fprintf(fp, "[%d] ", op->ob_refcnt);
261 printobject(op, fp, 0);
262 putc('\n', fp);
263 }
264}
265
266#endif