You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.0 KiB

  1. /* Cell object implementation */
  2. #include "Python.h"
  3. PyObject *
  4. PyCell_New(PyObject *obj)
  5. {
  6. PyCellObject *op;
  7. op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
  8. if (op == NULL)
  9. return NULL;
  10. op->ob_ref = obj;
  11. Py_XINCREF(obj);
  12. _PyObject_GC_TRACK(op);
  13. return (PyObject *)op;
  14. }
  15. PyObject *
  16. PyCell_Get(PyObject *op)
  17. {
  18. if (!PyCell_Check(op)) {
  19. PyErr_BadInternalCall();
  20. return NULL;
  21. }
  22. Py_XINCREF(((PyCellObject*)op)->ob_ref);
  23. return PyCell_GET(op);
  24. }
  25. int
  26. PyCell_Set(PyObject *op, PyObject *obj)
  27. {
  28. PyObject* oldobj;
  29. if (!PyCell_Check(op)) {
  30. PyErr_BadInternalCall();
  31. return -1;
  32. }
  33. oldobj = PyCell_GET(op);
  34. Py_XINCREF(obj);
  35. PyCell_SET(op, obj);
  36. Py_XDECREF(oldobj);
  37. return 0;
  38. }
  39. static void
  40. cell_dealloc(PyCellObject *op)
  41. {
  42. _PyObject_GC_UNTRACK(op);
  43. Py_XDECREF(op->ob_ref);
  44. PyObject_GC_Del(op);
  45. }
  46. static int
  47. cell_compare(PyCellObject *a, PyCellObject *b)
  48. {
  49. /* Py3K warning for comparisons */
  50. if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
  51. 1) < 0) {
  52. return -2;
  53. }
  54. if (a->ob_ref == NULL) {
  55. if (b->ob_ref == NULL)
  56. return 0;
  57. return -1;
  58. } else if (b->ob_ref == NULL)
  59. return 1;
  60. return PyObject_Compare(a->ob_ref, b->ob_ref);
  61. }
  62. static PyObject *
  63. cell_repr(PyCellObject *op)
  64. {
  65. if (op->ob_ref == NULL)
  66. return PyString_FromFormat("<cell at %p: empty>", op);
  67. return PyString_FromFormat("<cell at %p: %.80s object at %p>",
  68. op, op->ob_ref->ob_type->tp_name,
  69. op->ob_ref);
  70. }
  71. static int
  72. cell_traverse(PyCellObject *op, visitproc visit, void *arg)
  73. {
  74. Py_VISIT(op->ob_ref);
  75. return 0;
  76. }
  77. static int
  78. cell_clear(PyCellObject *op)
  79. {
  80. Py_CLEAR(op->ob_ref);
  81. return 0;
  82. }
  83. static PyObject *
  84. cell_get_contents(PyCellObject *op, void *closure)
  85. {
  86. if (op->ob_ref == NULL)
  87. {
  88. PyErr_SetString(PyExc_ValueError, "Cell is empty");
  89. return NULL;
  90. }
  91. Py_INCREF(op->ob_ref);
  92. return op->ob_ref;
  93. }
  94. static PyGetSetDef cell_getsetlist[] = {
  95. {"cell_contents", (getter)cell_get_contents, NULL},
  96. {NULL} /* sentinel */
  97. };
  98. PyTypeObject PyCell_Type = {
  99. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  100. "cell",
  101. sizeof(PyCellObject),
  102. 0,
  103. (destructor)cell_dealloc, /* tp_dealloc */
  104. 0, /* tp_print */
  105. 0, /* tp_getattr */
  106. 0, /* tp_setattr */
  107. (cmpfunc)cell_compare, /* tp_compare */
  108. (reprfunc)cell_repr, /* tp_repr */
  109. 0, /* tp_as_number */
  110. 0, /* tp_as_sequence */
  111. 0, /* tp_as_mapping */
  112. 0, /* tp_hash */
  113. 0, /* tp_call */
  114. 0, /* tp_str */
  115. PyObject_GenericGetAttr, /* tp_getattro */
  116. 0, /* tp_setattro */
  117. 0, /* tp_as_buffer */
  118. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
  119. 0, /* tp_doc */
  120. (traverseproc)cell_traverse, /* tp_traverse */
  121. (inquiry)cell_clear, /* tp_clear */
  122. 0, /* tp_richcompare */
  123. 0, /* tp_weaklistoffset */
  124. 0, /* tp_iter */
  125. 0, /* tp_iternext */
  126. 0, /* tp_methods */
  127. 0, /* tp_members */
  128. cell_getsetlist, /* tp_getset */
  129. };