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

#include "Python.h"

PyObject *
PyCell_New(PyObject *obj)
{
8
    PyCellObject *op;
Jeremy Hylton's avatar
Jeremy Hylton committed
9

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

16 17
    _PyObject_GC_TRACK(op);
    return (PyObject *)op;
Jeremy Hylton's avatar
Jeremy Hylton committed
18 19 20 21 22
}

PyObject *
PyCell_Get(PyObject *op)
{
23 24 25 26 27 28
    if (!PyCell_Check(op)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    Py_XINCREF(((PyCellObject*)op)->ob_ref);
    return PyCell_GET(op);
Jeremy Hylton's avatar
Jeremy Hylton committed
29 30 31 32 33
}

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

static void
cell_dealloc(PyCellObject *op)
{
49 50 51
    _PyObject_GC_UNTRACK(op);
    Py_XDECREF(op->ob_ref);
    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 58 59 60 61 62 63 64 65 66 67 68 69
    /* Py3K warning for comparisons  */
    if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
                       1) < 0) {
        return -2;
    }

    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);
Jeremy Hylton's avatar
Jeremy Hylton committed
70 71 72 73 74
}

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

78 79 80
    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
81 82 83 84 85
}

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

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

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

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

Jeremy Hylton's avatar
Jeremy Hylton committed
114
PyTypeObject PyCell_Type = {
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "cell",
    sizeof(PyCellObject),
    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 */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    0,                                          /* tp_doc */
    (traverseproc)cell_traverse,                /* tp_traverse */
    (inquiry)cell_clear,                        /* tp_clear */
    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
};