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