blob: c206684dab14e445d100eabf94598c7a37dd665f [file] [log] [blame]
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00001/* Cell object implementation */
2
3#include "Python.h"
4
5PyObject *
6PyCell_New(PyObject *obj)
7{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008 PyCellObject *op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00009
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010 op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
11 if (op == NULL)
12 return NULL;
13 op->ob_ref = obj;
14 Py_XINCREF(obj);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000015
Antoine Pitrouc83ea132010-05-09 14:46:46 +000016 _PyObject_GC_TRACK(op);
17 return (PyObject *)op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000018}
19
20PyObject *
21PyCell_Get(PyObject *op)
22{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000023 if (!PyCell_Check(op)) {
24 PyErr_BadInternalCall();
25 return NULL;
26 }
27 Py_XINCREF(((PyCellObject*)op)->ob_ref);
28 return PyCell_GET(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000029}
30
31int
32PyCell_Set(PyObject *op, PyObject *obj)
33{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000034 PyObject* oldobj;
35 if (!PyCell_Check(op)) {
36 PyErr_BadInternalCall();
37 return -1;
38 }
39 oldobj = PyCell_GET(op);
40 Py_XINCREF(obj);
41 PyCell_SET(op, obj);
42 Py_XDECREF(oldobj);
43 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000044}
45
46static void
47cell_dealloc(PyCellObject *op)
48{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000049 _PyObject_GC_UNTRACK(op);
50 Py_XDECREF(op->ob_ref);
51 PyObject_GC_Del(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000052}
53
54static int
55cell_compare(PyCellObject *a, PyCellObject *b)
56{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000057 /* Py3K warning for comparisons */
58 if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
59 1) < 0) {
60 return -2;
61 }
Steven Bethardae42f332008-03-18 17:26:10 +000062
Antoine Pitrouc83ea132010-05-09 14:46:46 +000063 if (a->ob_ref == NULL) {
64 if (b->ob_ref == NULL)
65 return 0;
66 return -1;
67 } else if (b->ob_ref == NULL)
68 return 1;
69 return PyObject_Compare(a->ob_ref, b->ob_ref);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000070}
71
72static PyObject *
73cell_repr(PyCellObject *op)
74{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000075 if (op->ob_ref == NULL)
76 return PyString_FromFormat("<cell at %p: empty>", op);
Barry Warsaw7ce36942001-08-24 18:34:26 +000077
Antoine Pitrouc83ea132010-05-09 14:46:46 +000078 return PyString_FromFormat("<cell at %p: %.80s object at %p>",
79 op, op->ob_ref->ob_type->tp_name,
80 op->ob_ref);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000081}
82
83static int
84cell_traverse(PyCellObject *op, visitproc visit, void *arg)
85{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000086 Py_VISIT(op->ob_ref);
87 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000088}
89
90static int
91cell_clear(PyCellObject *op)
92{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 Py_CLEAR(op->ob_ref);
94 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000095}
96
Georg Brandlabd1ff82006-03-18 07:59:59 +000097static PyObject *
98cell_get_contents(PyCellObject *op, void *closure)
99{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000100 if (op->ob_ref == NULL)
101 {
102 PyErr_SetString(PyExc_ValueError, "Cell is empty");
103 return NULL;
104 }
105 Py_INCREF(op->ob_ref);
106 return op->ob_ref;
Georg Brandlabd1ff82006-03-18 07:59:59 +0000107}
108
109static PyGetSetDef cell_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000110 {"cell_contents", (getter)cell_get_contents, NULL},
111 {NULL} /* sentinel */
Georg Brandlabd1ff82006-03-18 07:59:59 +0000112};
113
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000114PyTypeObject PyCell_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 PyVarObject_HEAD_INIT(&PyType_Type, 0)
116 "cell",
117 sizeof(PyCellObject),
118 0,
Benjamin Peterson413a8e12016-05-12 23:12:21 -0700119 (destructor)cell_dealloc, /* tp_dealloc */
120 0, /* tp_print */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 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 */
Benjamin Peterson413a8e12016-05-12 23:12:21 -0700134 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000135 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 */
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000145};