Line data Source code
1 : /* Cell object implementation */
2 :
3 : #include "Python.h"
4 :
5 : PyObject *
6 12 : PyCell_New(PyObject *obj)
7 : {
8 : PyCellObject *op;
9 :
10 12 : op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
11 12 : if (op == NULL)
12 0 : return NULL;
13 12 : op->ob_ref = obj;
14 12 : Py_XINCREF(obj);
15 :
16 12 : _PyObject_GC_TRACK(op);
17 12 : return (PyObject *)op;
18 : }
19 :
20 : PyObject *
21 261 : PyCell_Get(PyObject *op)
22 : {
23 261 : if (!PyCell_Check(op)) {
24 0 : PyErr_BadInternalCall();
25 0 : return NULL;
26 : }
27 261 : Py_XINCREF(((PyCellObject*)op)->ob_ref);
28 261 : return PyCell_GET(op);
29 : }
30 :
31 : int
32 81 : PyCell_Set(PyObject *op, PyObject *obj)
33 : {
34 : PyObject* oldobj;
35 81 : if (!PyCell_Check(op)) {
36 0 : PyErr_BadInternalCall();
37 0 : return -1;
38 : }
39 81 : oldobj = PyCell_GET(op);
40 81 : Py_XINCREF(obj);
41 81 : PyCell_SET(op, obj);
42 81 : Py_XDECREF(oldobj);
43 81 : return 0;
44 : }
45 :
46 : static void
47 12 : cell_dealloc(PyCellObject *op)
48 : {
49 12 : _PyObject_GC_UNTRACK(op);
50 12 : Py_XDECREF(op->ob_ref);
51 12 : PyObject_GC_Del(op);
52 12 : }
53 :
54 : static int
55 0 : cell_compare(PyCellObject *a, PyCellObject *b)
56 : {
57 : /* Py3K warning for comparisons */
58 0 : if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
59 0 : 1) < 0) {
60 0 : return -2;
61 : }
62 :
63 0 : if (a->ob_ref == NULL) {
64 0 : if (b->ob_ref == NULL)
65 0 : return 0;
66 0 : return -1;
67 0 : } else if (b->ob_ref == NULL)
68 0 : return 1;
69 0 : return PyObject_Compare(a->ob_ref, b->ob_ref);
70 : }
71 :
72 : static PyObject *
73 0 : cell_repr(PyCellObject *op)
74 : {
75 0 : if (op->ob_ref == NULL)
76 0 : return PyString_FromFormat("<cell at %p: empty>", op);
77 :
78 0 : return PyString_FromFormat("<cell at %p: %.80s object at %p>",
79 0 : op, op->ob_ref->ob_type->tp_name,
80 : op->ob_ref);
81 : }
82 :
83 : static int
84 0 : cell_traverse(PyCellObject *op, visitproc visit, void *arg)
85 : {
86 0 : Py_VISIT(op->ob_ref);
87 0 : return 0;
88 : }
89 :
90 : static int
91 0 : cell_clear(PyCellObject *op)
92 : {
93 0 : Py_CLEAR(op->ob_ref);
94 0 : return 0;
95 : }
96 :
97 : static PyObject *
98 0 : cell_get_contents(PyCellObject *op, void *closure)
99 : {
100 0 : if (op->ob_ref == NULL)
101 : {
102 0 : PyErr_SetString(PyExc_ValueError, "Cell is empty");
103 0 : return NULL;
104 : }
105 0 : Py_INCREF(op->ob_ref);
106 0 : return op->ob_ref;
107 : }
108 :
109 : static PyGetSetDef cell_getsetlist[] = {
110 : {"cell_contents", (getter)cell_get_contents, NULL},
111 : {NULL} /* sentinel */
112 : };
113 :
114 : PyTypeObject PyCell_Type = {
115 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
116 : "cell",
117 : sizeof(PyCellObject),
118 : 0,
119 : (destructor)cell_dealloc, /* tp_dealloc */
120 : 0, /* tp_print */
121 : 0, /* tp_getattr */
122 : 0, /* tp_setattr */
123 : (cmpfunc)cell_compare, /* tp_compare */
124 : (reprfunc)cell_repr, /* tp_repr */
125 : 0, /* tp_as_number */
126 : 0, /* tp_as_sequence */
127 : 0, /* tp_as_mapping */
128 : 0, /* tp_hash */
129 : 0, /* tp_call */
130 : 0, /* tp_str */
131 : PyObject_GenericGetAttr, /* tp_getattro */
132 : 0, /* tp_setattro */
133 : 0, /* tp_as_buffer */
134 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
135 : 0, /* tp_doc */
136 : (traverseproc)cell_traverse, /* tp_traverse */
137 : (inquiry)cell_clear, /* tp_clear */
138 : 0, /* tp_richcompare */
139 : 0, /* tp_weaklistoffset */
140 : 0, /* tp_iter */
141 : 0, /* tp_iternext */
142 : 0, /* tp_methods */
143 : 0, /* tp_members */
144 : cell_getsetlist, /* tp_getset */
145 : };
|