cellobject.c 2.26 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);
Jeremy Hylton's avatar
Jeremy Hylton committed
11 12 13
	op->ob_ref = obj;
	Py_XINCREF(obj);

Neil Schemenauer's avatar
Neil Schemenauer committed
14
	_PyObject_GC_TRACK(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	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)
{
	if (!PyCell_Check(op)) {
		PyErr_BadInternalCall();
		return -1;
	}
	Py_XDECREF(((PyCellObject*)op)->ob_ref);
	Py_XINCREF(obj);
	PyCell_SET(op, obj);
	return 0;
}

static void
cell_dealloc(PyCellObject *op)
{
Neil Schemenauer's avatar
Neil Schemenauer committed
45
	_PyObject_GC_UNTRACK(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
46
	Py_XDECREF(op->ob_ref);
Neil Schemenauer's avatar
Neil Schemenauer committed
47
	PyObject_GC_Del(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
}

static int
cell_compare(PyCellObject *a, PyCellObject *b)
{
	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)
66 67 68 69 70
		return PyString_FromFormat("<cell at %p: empty>", op);

	return PyString_FromFormat("<cell at %p: %.80s object at %p>",
				   op, op->ob_ref->ob_type->tp_name,
				   op->ob_ref);
Jeremy Hylton's avatar
Jeremy Hylton committed
71 72 73 74 75 76 77 78 79 80 81 82 83
}

static int
cell_traverse(PyCellObject *op, visitproc visit, void *arg)
{
	if (op->ob_ref)
		return visit(op->ob_ref, arg);
	return 0;
}

static int
cell_clear(PyCellObject *op)
{
84
	Py_XDECREF(op->ob_ref);
Jeremy Hylton's avatar
Jeremy Hylton committed
85 86 87 88 89 90 91 92
	op->ob_ref = NULL;
	return 0;
}

PyTypeObject PyCell_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"cell",
Neil Schemenauer's avatar
Neil Schemenauer committed
93
	sizeof(PyCellObject),
Jeremy Hylton's avatar
Jeremy Hylton committed
94 95 96 97 98 99 100 101 102 103 104 105 106
	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 */
107
	PyObject_GenericGetAttr,		/* tp_getattro */
Jeremy Hylton's avatar
Jeremy Hylton committed
108 109
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
Neil Schemenauer's avatar
Neil Schemenauer committed
110
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
Jeremy Hylton's avatar
Jeremy Hylton committed
111 112 113 114
 	0,					/* tp_doc */
 	(traverseproc)cell_traverse,		/* tp_traverse */
 	(inquiry)cell_clear,			/* tp_clear */
};