17db96d56Sopenharmony_ci/* Cell object implementation */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci#include "Python.h"
47db96d56Sopenharmony_ci#include "pycore_object.h"
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciPyObject *
77db96d56Sopenharmony_ciPyCell_New(PyObject *obj)
87db96d56Sopenharmony_ci{
97db96d56Sopenharmony_ci    PyCellObject *op;
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci    op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
127db96d56Sopenharmony_ci    if (op == NULL)
137db96d56Sopenharmony_ci        return NULL;
147db96d56Sopenharmony_ci    op->ob_ref = obj;
157db96d56Sopenharmony_ci    Py_XINCREF(obj);
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci    _PyObject_GC_TRACK(op);
187db96d56Sopenharmony_ci    return (PyObject *)op;
197db96d56Sopenharmony_ci}
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ciPyDoc_STRVAR(cell_new_doc,
227db96d56Sopenharmony_ci"cell([contents])\n"
237db96d56Sopenharmony_ci"--\n"
247db96d56Sopenharmony_ci"\n"
257db96d56Sopenharmony_ci"Create a new cell object.\n"
267db96d56Sopenharmony_ci"\n"
277db96d56Sopenharmony_ci"  contents\n"
287db96d56Sopenharmony_ci"    the contents of the cell. If not specified, the cell will be empty,\n"
297db96d56Sopenharmony_ci"    and \n further attempts to access its cell_contents attribute will\n"
307db96d56Sopenharmony_ci"    raise a ValueError.");
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_cistatic PyObject *
347db96d56Sopenharmony_cicell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
357db96d56Sopenharmony_ci{
367db96d56Sopenharmony_ci    PyObject *return_value = NULL;
377db96d56Sopenharmony_ci    PyObject *obj = NULL;
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    if (!_PyArg_NoKeywords("cell", kwargs)) {
407db96d56Sopenharmony_ci        goto exit;
417db96d56Sopenharmony_ci    }
427db96d56Sopenharmony_ci    /* min = 0: we allow the cell to be empty */
437db96d56Sopenharmony_ci    if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) {
447db96d56Sopenharmony_ci        goto exit;
457db96d56Sopenharmony_ci    }
467db96d56Sopenharmony_ci    return_value = PyCell_New(obj);
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ciexit:
497db96d56Sopenharmony_ci    return return_value;
507db96d56Sopenharmony_ci}
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ciPyObject *
537db96d56Sopenharmony_ciPyCell_Get(PyObject *op)
547db96d56Sopenharmony_ci{
557db96d56Sopenharmony_ci    if (!PyCell_Check(op)) {
567db96d56Sopenharmony_ci        PyErr_BadInternalCall();
577db96d56Sopenharmony_ci        return NULL;
587db96d56Sopenharmony_ci    }
597db96d56Sopenharmony_ci    Py_XINCREF(((PyCellObject*)op)->ob_ref);
607db96d56Sopenharmony_ci    return PyCell_GET(op);
617db96d56Sopenharmony_ci}
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ciint
647db96d56Sopenharmony_ciPyCell_Set(PyObject *op, PyObject *obj)
657db96d56Sopenharmony_ci{
667db96d56Sopenharmony_ci    PyObject* oldobj;
677db96d56Sopenharmony_ci    if (!PyCell_Check(op)) {
687db96d56Sopenharmony_ci        PyErr_BadInternalCall();
697db96d56Sopenharmony_ci        return -1;
707db96d56Sopenharmony_ci    }
717db96d56Sopenharmony_ci    oldobj = PyCell_GET(op);
727db96d56Sopenharmony_ci    Py_XINCREF(obj);
737db96d56Sopenharmony_ci    PyCell_SET(op, obj);
747db96d56Sopenharmony_ci    Py_XDECREF(oldobj);
757db96d56Sopenharmony_ci    return 0;
767db96d56Sopenharmony_ci}
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_cistatic void
797db96d56Sopenharmony_cicell_dealloc(PyCellObject *op)
807db96d56Sopenharmony_ci{
817db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(op);
827db96d56Sopenharmony_ci    Py_XDECREF(op->ob_ref);
837db96d56Sopenharmony_ci    PyObject_GC_Del(op);
847db96d56Sopenharmony_ci}
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_cistatic PyObject *
877db96d56Sopenharmony_cicell_richcompare(PyObject *a, PyObject *b, int op)
887db96d56Sopenharmony_ci{
897db96d56Sopenharmony_ci    /* neither argument should be NULL, unless something's gone wrong */
907db96d56Sopenharmony_ci    assert(a != NULL && b != NULL);
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci    /* both arguments should be instances of PyCellObject */
937db96d56Sopenharmony_ci    if (!PyCell_Check(a) || !PyCell_Check(b)) {
947db96d56Sopenharmony_ci        Py_RETURN_NOTIMPLEMENTED;
957db96d56Sopenharmony_ci    }
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci    /* compare cells by contents; empty cells come before anything else */
987db96d56Sopenharmony_ci    a = ((PyCellObject *)a)->ob_ref;
997db96d56Sopenharmony_ci    b = ((PyCellObject *)b)->ob_ref;
1007db96d56Sopenharmony_ci    if (a != NULL && b != NULL)
1017db96d56Sopenharmony_ci        return PyObject_RichCompare(a, b, op);
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci    Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op);
1047db96d56Sopenharmony_ci}
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_cistatic PyObject *
1077db96d56Sopenharmony_cicell_repr(PyCellObject *op)
1087db96d56Sopenharmony_ci{
1097db96d56Sopenharmony_ci    if (op->ob_ref == NULL)
1107db96d56Sopenharmony_ci        return PyUnicode_FromFormat("<cell at %p: empty>", op);
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>",
1137db96d56Sopenharmony_ci                               op, Py_TYPE(op->ob_ref)->tp_name,
1147db96d56Sopenharmony_ci                               op->ob_ref);
1157db96d56Sopenharmony_ci}
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_cistatic int
1187db96d56Sopenharmony_cicell_traverse(PyCellObject *op, visitproc visit, void *arg)
1197db96d56Sopenharmony_ci{
1207db96d56Sopenharmony_ci    Py_VISIT(op->ob_ref);
1217db96d56Sopenharmony_ci    return 0;
1227db96d56Sopenharmony_ci}
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_cistatic int
1257db96d56Sopenharmony_cicell_clear(PyCellObject *op)
1267db96d56Sopenharmony_ci{
1277db96d56Sopenharmony_ci    Py_CLEAR(op->ob_ref);
1287db96d56Sopenharmony_ci    return 0;
1297db96d56Sopenharmony_ci}
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_cistatic PyObject *
1327db96d56Sopenharmony_cicell_get_contents(PyCellObject *op, void *closure)
1337db96d56Sopenharmony_ci{
1347db96d56Sopenharmony_ci    if (op->ob_ref == NULL)
1357db96d56Sopenharmony_ci    {
1367db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "Cell is empty");
1377db96d56Sopenharmony_ci        return NULL;
1387db96d56Sopenharmony_ci    }
1397db96d56Sopenharmony_ci    Py_INCREF(op->ob_ref);
1407db96d56Sopenharmony_ci    return op->ob_ref;
1417db96d56Sopenharmony_ci}
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_cistatic int
1447db96d56Sopenharmony_cicell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored))
1457db96d56Sopenharmony_ci{
1467db96d56Sopenharmony_ci    Py_XINCREF(obj);
1477db96d56Sopenharmony_ci    Py_XSETREF(op->ob_ref, obj);
1487db96d56Sopenharmony_ci    return 0;
1497db96d56Sopenharmony_ci}
1507db96d56Sopenharmony_ci
1517db96d56Sopenharmony_cistatic PyGetSetDef cell_getsetlist[] = {
1527db96d56Sopenharmony_ci    {"cell_contents", (getter)cell_get_contents,
1537db96d56Sopenharmony_ci                      (setter)cell_set_contents, NULL},
1547db96d56Sopenharmony_ci    {NULL} /* sentinel */
1557db96d56Sopenharmony_ci};
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ciPyTypeObject PyCell_Type = {
1587db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
1597db96d56Sopenharmony_ci    "cell",
1607db96d56Sopenharmony_ci    sizeof(PyCellObject),
1617db96d56Sopenharmony_ci    0,
1627db96d56Sopenharmony_ci    (destructor)cell_dealloc,                   /* tp_dealloc */
1637db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
1647db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
1657db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
1667db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
1677db96d56Sopenharmony_ci    (reprfunc)cell_repr,                        /* tp_repr */
1687db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
1697db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
1707db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
1717db96d56Sopenharmony_ci    0,                                          /* tp_hash */
1727db96d56Sopenharmony_ci    0,                                          /* tp_call */
1737db96d56Sopenharmony_ci    0,                                          /* tp_str */
1747db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
1757db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
1767db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
1777db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
1787db96d56Sopenharmony_ci    cell_new_doc,                               /* tp_doc */
1797db96d56Sopenharmony_ci    (traverseproc)cell_traverse,                /* tp_traverse */
1807db96d56Sopenharmony_ci    (inquiry)cell_clear,                        /* tp_clear */
1817db96d56Sopenharmony_ci    cell_richcompare,                           /* tp_richcompare */
1827db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
1837db96d56Sopenharmony_ci    0,                                          /* tp_iter */
1847db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
1857db96d56Sopenharmony_ci    0,                                          /* tp_methods */
1867db96d56Sopenharmony_ci    0,                                          /* tp_members */
1877db96d56Sopenharmony_ci    cell_getsetlist,                            /* tp_getset */
1887db96d56Sopenharmony_ci    0,                                          /* tp_base */
1897db96d56Sopenharmony_ci    0,                                          /* tp_dict */
1907db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
1917db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
1927db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
1937db96d56Sopenharmony_ci    0,                                          /* tp_init */
1947db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
1957db96d56Sopenharmony_ci    (newfunc)cell_new,                          /* tp_new */
1967db96d56Sopenharmony_ci    0,                                          /* tp_free */
1977db96d56Sopenharmony_ci};
198