cellobject.c 2.92 KB
Newer Older
Jeremy Hylton's avatar
Jeremy Hylton committed
1 2 3 4 5 6 7 8 9
/* Cell object implementation */

#include "Python.h"

PyObject *
PyCell_New(PyObject *obj)
{
	PyCellObject *op;

Neil Schemenauer's avatar
Neil Schemenauer committed
10
	op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
11 12
	if (op == NULL)
		return NULL;
Jeremy Hylton's avatar
Jeremy Hylton committed
13 14 15
	op->ob_ref = obj;
	Py_XINCREF(obj);

Neil Schemenauer's avatar
Neil Schemenauer committed
16
	_PyObject_GC_TRACK(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
	return (PyObject *)op;
}

PyObject *
PyCell_Get(PyObject *op)
{
	if (!PyCell_Check(op)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	Py_XINCREF(((PyCellObject*)op)->ob_ref);
	return PyCell_GET(op);
}

int
PyCell_Set(PyObject *op, PyObject *obj)
{
34
	PyObject* oldobj;
Jeremy Hylton's avatar
Jeremy Hylton committed
35 36 37 38
	if (!PyCell_Check(op)) {
		PyErr_BadInternalCall();
		return -1;
	}
39
	oldobj = PyCell_GET(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
40 41
	Py_XINCREF(obj);
	PyCell_SET(op, obj);
42
	Py_XDECREF(oldobj);
Jeremy Hylton's avatar
Jeremy Hylton committed
43 44 45 46 47 48
	return 0;
}

static void
cell_dealloc(PyCellObject *op)
{
Neil Schemenauer's avatar
Neil Schemenauer committed
49
	_PyObject_GC_UNTRACK(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
50
	Py_XDECREF(op->ob_ref);
Neil Schemenauer's avatar
Neil Schemenauer committed
51
	PyObject_GC_Del(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
52 53 54 55 56
}

static int
cell_compare(PyCellObject *a, PyCellObject *b)
{
57
	/* Py3K warning for comparisons  */
58
	if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
59
			   1) < 0) {
60
		return -2;
61 62
	}

Jeremy Hylton's avatar
Jeremy Hylton committed
63 64 65 66 67 68 69 70 71 72 73 74 75
	if (a->ob_ref == NULL) {
		if (b->ob_ref == NULL)
			return 0;
		return -1;
	} else if (b->ob_ref == NULL)
		return 1;
	return PyObject_Compare(a->ob_ref, b->ob_ref);
}

static PyObject *
cell_repr(PyCellObject *op)
{
	if (op->ob_ref == NULL)
76
		return PyString_FromFormat("<cell at %p: empty>", op);
77

78
	return PyString_FromFormat("<cell at %p: %.80s object at %p>",
79 80
				   op, op->ob_ref->ob_type->tp_name,
				   op->ob_ref);
Jeremy Hylton's avatar
Jeremy Hylton committed
81 82 83 84 85
}

static int
cell_traverse(PyCellObject *op, visitproc visit, void *arg)
{
86
	Py_VISIT(op->ob_ref);
Jeremy Hylton's avatar
Jeremy Hylton committed
87 88 89 90 91 92
	return 0;
}

static int
cell_clear(PyCellObject *op)
{
93
	Py_CLEAR(op->ob_ref);
Jeremy Hylton's avatar
Jeremy Hylton committed
94 95 96
	return 0;
}

97 98 99
static PyObject *
cell_get_contents(PyCellObject *op, void *closure)
{
100 101 102 103 104 105
	if (op->ob_ref == NULL)
	{
		PyErr_SetString(PyExc_ValueError, "Cell is empty");
		return NULL;
	}
	Py_INCREF(op->ob_ref);
106 107 108 109 110 111 112 113
	return op->ob_ref;
}

static PyGetSetDef cell_getsetlist[] = {
	{"cell_contents", (getter)cell_get_contents, NULL},
	{NULL} /* sentinel */
};

Jeremy Hylton's avatar
Jeremy Hylton committed
114
PyTypeObject PyCell_Type = {
115
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
Jeremy Hylton's avatar
Jeremy Hylton committed
116
	"cell",
Neil Schemenauer's avatar
Neil Schemenauer committed
117
	sizeof(PyCellObject),
Jeremy Hylton's avatar
Jeremy Hylton committed
118 119 120 121 122 123 124 125 126 127 128 129 130
	0,
	(destructor)cell_dealloc,               /* tp_dealloc */
	0,                                      /* tp_print */
	0,	                                /* tp_getattr */
	0,					/* tp_setattr */
	(cmpfunc)cell_compare,			/* tp_compare */
	(reprfunc)cell_repr,			/* tp_repr */
	0,					/* tp_as_number */
	0,			                /* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
131
	PyObject_GenericGetAttr,		/* tp_getattro */
Jeremy Hylton's avatar
Jeremy Hylton committed
132 133
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
Neil Schemenauer's avatar
Neil Schemenauer committed
134
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
Jeremy Hylton's avatar
Jeremy Hylton committed
135 136 137
 	0,					/* tp_doc */
 	(traverseproc)cell_traverse,		/* tp_traverse */
 	(inquiry)cell_clear,			/* tp_clear */
138 139 140 141 142 143 144
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0, 					/* tp_iter */
	0,					/* tp_iternext */
	0,					/* tp_methods */
	0,					/* tp_members */
	cell_getsetlist,			/* tp_getset */
Jeremy Hylton's avatar
Jeremy Hylton committed
145
};