blob: ebeb0f8cf64de009a73aeeb401277fe014860ecd [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Object implementation; and 'noobject' implementation */
2
3#include <stdio.h>
4
5#include "PROTO.h"
6#include "object.h"
7#include "stringobject.h"
8#include "objimpl.h"
9#include "errors.h"
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011int StopPrint; /* Flag to indicate printing must be stopped */
12
13/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros */
14
15object *
16newobject(tp)
17 typeobject *tp;
18{
19 object *op = (object *) malloc(tp->tp_basicsize);
20 if (op == NULL)
21 return err_nomem();
22 NEWREF(op);
23 op->ob_type = tp;
24 return op;
25}
26
27#if 0 /* unused */
28
29varobject *
30newvarobject(tp, size)
31 typeobject *tp;
32 unsigned int size;
33{
34 varobject *op = (varobject *)
35 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
36 if (op == NULL)
37 return err_nomem();
38 NEWREF(op);
39 op->ob_type = tp;
40 op->ob_size = size;
41 return op;
42}
43
44#endif
45
46static 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 */
55 prlevel++;
56 if (!StopPrint && intrcheck()) {
57 fprintf(fp, "\n[print interrupted]\n");
58 StopPrint = 1;
59 }
60 if (!StopPrint) {
61 if (op == NULL) {
62 fprintf(fp, "<nil>");
63 }
64 else if (op->ob_type->tp_print == NULL) {
65 fprintf(fp, "<%s object at %lx>",
66 op->ob_type->tp_name, (long)op);
67 }
68 else {
69 (*op->ob_type->tp_print)(op, fp, flags);
70 }
71 }
72 prlevel--;
73 if (prlevel == 0)
74 StopPrint = 0;
75}
76
77object *
78reprobject(v)
79 object *v;
80{
81 object *w;
82 /* Hacks to make converting a long or recursive object interruptible */
83 prlevel++;
84 if (!StopPrint && intrcheck()) {
85 StopPrint = 1;
86 w = NULL;
87 err_set(KeyboardInterrupt);
88 }
89 if (!StopPrint) {
90 if (v == NULL) {
91 w = newstringobject("<nil>");
92 }
93 else if (v->ob_type->tp_repr == NULL) {
94 char buf[100];
95 sprintf(buf, "<%.80s object at %lx>",
96 v->ob_type->tp_name, (long)v);
97 w = newstringobject(buf);
98 }
99 else {
100 w = (*v->ob_type->tp_repr)(v);
101 }
102 }
103 prlevel--;
104 if (prlevel == 0)
105 StopPrint = 0;
106 return w;
107}
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;
120 if ((tp = v->ob_type) != w->ob_type)
121 return strcmp(tp->tp_name, w->ob_type->tp_name);
122 if (tp->tp_compare == NULL)
123 return (v < w) ? -1 : 1;
124 return ((*tp->tp_compare)(v, w));
125}
126
127
128/*
129NoObject is usable as a non-NULL undefined value, used by the macro None.
130There is (and should be!) no way to create other objects of this type,
131so there is exactly one.
132*/
133
134static void
135noprint(op, fp, flags)
136 object *op;
137 FILE *fp;
138 int flags;
139{
140 fprintf(fp, "<no value>");
141}
142
143static typeobject Notype = {
144 OB_HEAD_INIT(&Typetype)
145 0,
146 "novalue",
147 0,
148 0,
149 0, /*tp_dealloc*/ /*never called*/
150 noprint, /*tp_print*/
151};
152
153object NoObject = {
154 OB_HEAD_INIT(&Notype)
155};
156
157
158#ifdef TRACE_REFS
159
160static object refchain = {&refchain, &refchain};
161
162NEWREF(op)
163 object *op;
164{
165 ref_total++;
166 op->ob_refcnt = 1;
167 op->_ob_next = refchain._ob_next;
168 op->_ob_prev = &refchain;
169 refchain._ob_next->_ob_prev = op;
170 refchain._ob_next = op;
171}
172
173DELREF(op)
174 object *op;
175{
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000176 if (op->ob_refcnt < 0) {
177 fprintf(stderr, "negative refcnt\n");
178 abort();
179 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 op->_ob_next->_ob_prev = op->_ob_prev;
181 op->_ob_prev->_ob_next = op->_ob_next;
182 (*(op)->ob_type->tp_dealloc)(op);
183}
184
185printrefs(fp)
186 FILE *fp;
187{
188 object *op;
189 fprintf(fp, "Remaining objects:\n");
190 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
191 fprintf(fp, "[%d] ", op->ob_refcnt);
192 printobject(op, fp, 0);
193 putc('\n', fp);
194 }
195}
196
197#endif