LCOV - code coverage report
Current view: top level - lib/talloc - pytalloc.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 75 99 75.8 %
Date: 2021-09-23 10:06:22 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Python Talloc Module
       4             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010-2011
       5             : 
       6             :      ** NOTE! The following LGPL license applies to the talloc
       7             :      ** library. This does NOT imply that all of Samba is released
       8             :      ** under the LGPL
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Lesser General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public
      21             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include <Python.h>
      25             : #include <talloc.h>
      26             : #include <pytalloc.h>
      27             : #include "pytalloc_private.h"
      28             : 
      29             : static PyTypeObject TallocObject_Type;
      30             : 
      31             : /* print a talloc tree report for a talloc python object */
      32           1 : static PyObject *pytalloc_report_full(PyObject *self, PyObject *args)
      33             : {
      34           1 :         PyObject *py_obj = Py_None;
      35             : 
      36           1 :         if (!PyArg_ParseTuple(args, "|O", &py_obj))
      37           0 :                 return NULL;
      38             : 
      39           1 :         if (py_obj == Py_None) {
      40           0 :                 talloc_report_full(NULL, stdout);
      41             :         } else {
      42           1 :                 talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout);
      43             :         }
      44           1 :         Py_RETURN_NONE;
      45             : }
      46             : 
      47             : /* enable null tracking */
      48          11 : static PyObject *pytalloc_enable_null_tracking(PyObject *self,
      49             :                 PyObject *Py_UNUSED(ignored))
      50             : {
      51          11 :         talloc_enable_null_tracking();
      52          11 :         Py_RETURN_NONE;
      53             : }
      54             : 
      55             : /* return the number of talloc blocks */
      56          30 : static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args)
      57             : {
      58          30 :         PyObject *py_obj = Py_None;
      59             : 
      60          30 :         if (!PyArg_ParseTuple(args, "|O", &py_obj))
      61           0 :                 return NULL;
      62             : 
      63          30 :         if (py_obj == Py_None) {
      64          25 :                 return PyLong_FromLong(talloc_total_blocks(NULL));
      65             :         }
      66             : 
      67           5 :         return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj)));
      68             : }
      69             : 
      70             : static PyMethodDef talloc_methods[] = {
      71             :         { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS,
      72             :                 "show a talloc tree for an object"},
      73             :         { "enable_null_tracking", (PyCFunction)pytalloc_enable_null_tracking, METH_NOARGS,
      74             :                 "enable tracking of the NULL object"},
      75             :         { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS,
      76             :                 "return talloc block count"},
      77             :         {0}
      78             : };
      79             : 
      80             : /**
      81             :  * Default (but only slightly more useful than the default) implementation of Repr().
      82             :  */
      83           3 : static PyObject *pytalloc_default_repr(PyObject *obj)
      84             : {
      85           3 :         pytalloc_Object *talloc_obj = (pytalloc_Object *)obj;
      86           3 :         PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
      87             : 
      88           3 :         return PyUnicode_FromFormat("<%s talloc object at %p>",
      89             :                                 type->tp_name, talloc_obj->ptr);
      90             : }
      91             : 
      92             : /**
      93             :  * Simple dealloc for talloc-wrapping PyObjects
      94             :  */
      95           9 : static void pytalloc_dealloc(PyObject* self)
      96             : {
      97           9 :         pytalloc_Object *obj = (pytalloc_Object *)self;
      98           9 :         assert(talloc_unlink(NULL, obj->talloc_ctx) != -1);
      99           9 :         obj->talloc_ctx = NULL;
     100           9 :         self->ob_type->tp_free(self);
     101           9 : }
     102             : 
     103             : /**
     104             :  * Default (but only slightly more useful than the default) implementation of cmp.
     105             :  */
     106             : #if PY_MAJOR_VERSION >= 3
     107          13 : static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
     108             : {
     109             :         void *ptr1;
     110             :         void *ptr2;
     111          13 :         if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
     112             :                 /* When types match, compare pointers */
     113          13 :                 ptr1 = pytalloc_get_ptr(obj1);
     114          13 :                 ptr2 = pytalloc_get_ptr(obj2);
     115           0 :         } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
     116             :                 /* Otherwise, compare types */
     117           0 :                 ptr1 = Py_TYPE(obj1);
     118           0 :                 ptr2 = Py_TYPE(obj2);
     119             :         } else {
     120           0 :                 Py_INCREF(Py_NotImplemented);
     121           0 :                 return Py_NotImplemented;
     122             :         }
     123          13 :         switch (op) {
     124           2 :                 case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
     125           2 :                 case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
     126           3 :                 case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
     127           2 :                 case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
     128           2 :                 case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
     129           2 :                 case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
     130             :         }
     131           0 :         Py_INCREF(Py_NotImplemented);
     132           0 :         return Py_NotImplemented;
     133             : }
     134             : #else
     135             : static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
     136             : {
     137             :         pytalloc_Object *obj1 = (pytalloc_Object *)_obj1,
     138             :                                          *obj2 = (pytalloc_Object *)_obj2;
     139             :         if (obj1->ob_type != obj2->ob_type)
     140             :                 return ((char *)obj1->ob_type - (char *)obj2->ob_type);
     141             : 
     142             :         return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
     143             : }
     144             : #endif
     145             : 
     146             : static PyTypeObject TallocObject_Type = {
     147             :         .tp_name = "talloc.Object",
     148             :         .tp_doc = "Python wrapper for a talloc-maintained object.",
     149             :         .tp_basicsize = sizeof(pytalloc_Object),
     150             :         .tp_dealloc = (destructor)pytalloc_dealloc,
     151             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     152             :         .tp_repr = pytalloc_default_repr,
     153             : #if PY_MAJOR_VERSION >= 3
     154             :         .tp_richcompare = pytalloc_default_richcmp,
     155             : #else
     156             :         .tp_compare = pytalloc_default_cmp,
     157             : #endif
     158             : };
     159             : 
     160             : /**
     161             :  * Default (but only slightly more useful than the default) implementation of Repr().
     162             :  */
     163           3 : static PyObject *pytalloc_base_default_repr(PyObject *obj)
     164             : {
     165           3 :         pytalloc_BaseObject *talloc_obj = (pytalloc_BaseObject *)obj;
     166           3 :         PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
     167             : 
     168           3 :         return PyUnicode_FromFormat("<%s talloc based object at %p>",
     169             :                                 type->tp_name, talloc_obj->ptr);
     170             : }
     171             : 
     172             : /**
     173             :  * Simple dealloc for talloc-wrapping PyObjects
     174             :  */
     175    64839321 : static void pytalloc_base_dealloc(PyObject* self)
     176             : {
     177    64839321 :         pytalloc_BaseObject *obj = (pytalloc_BaseObject *)self;
     178    64839321 :         assert(talloc_unlink(NULL, obj->talloc_ctx) != -1);
     179    64839321 :         obj->talloc_ctx = NULL;
     180    64839321 :         self->ob_type->tp_free(self);
     181    64839321 : }
     182             : 
     183             : /**
     184             :  * Default (but only slightly more useful than the default) implementation of cmp.
     185             :  */
     186             : #if PY_MAJOR_VERSION >= 3
     187         135 : static PyObject *pytalloc_base_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
     188             : {
     189             :         void *ptr1;
     190             :         void *ptr2;
     191         135 :         if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
     192             :                 /* When types match, compare pointers */
     193         126 :                 ptr1 = pytalloc_get_ptr(obj1);
     194         126 :                 ptr2 = pytalloc_get_ptr(obj2);
     195           9 :         } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
     196             :                 /* Otherwise, compare types */
     197           0 :                 ptr1 = Py_TYPE(obj1);
     198           0 :                 ptr2 = Py_TYPE(obj2);
     199             :         } else {
     200           9 :                 Py_INCREF(Py_NotImplemented);
     201           9 :                 return Py_NotImplemented;
     202             :         }
     203         126 :         switch (op) {
     204         115 :                 case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
     205           2 :                 case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
     206           3 :                 case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
     207           2 :                 case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
     208           2 :                 case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
     209           2 :                 case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
     210             :         }
     211           0 :         Py_INCREF(Py_NotImplemented);
     212           0 :         return Py_NotImplemented;
     213             : }
     214             : #else
     215             : static int pytalloc_base_default_cmp(PyObject *_obj1, PyObject *_obj2)
     216             : {
     217             :         pytalloc_BaseObject *obj1 = (pytalloc_BaseObject *)_obj1,
     218             :                                          *obj2 = (pytalloc_BaseObject *)_obj2;
     219             :         if (obj1->ob_type != obj2->ob_type)
     220             :                 return ((char *)obj1->ob_type - (char *)obj2->ob_type);
     221             : 
     222             :         return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
     223             : }
     224             : #endif
     225             : 
     226             : static PyTypeObject TallocBaseObject_Type = {
     227             :         .tp_name = "talloc.BaseObject",
     228             :         .tp_doc = "Python wrapper for a talloc-maintained object.",
     229             :         .tp_basicsize = sizeof(pytalloc_BaseObject),
     230             :         .tp_dealloc = (destructor)pytalloc_base_dealloc,
     231             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     232             :         .tp_repr = pytalloc_base_default_repr,
     233             : #if PY_MAJOR_VERSION >= 3
     234             :         .tp_richcompare = pytalloc_base_default_richcmp,
     235             : #else
     236             :         .tp_compare = pytalloc_base_default_cmp,
     237             : #endif
     238             : };
     239             : 
     240             : static PyTypeObject TallocGenericObject_Type = {
     241             :         .tp_name = "talloc.GenericObject",
     242             :         .tp_doc = "Python wrapper for a talloc-maintained object.",
     243             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     244             :         .tp_base = &TallocBaseObject_Type,
     245             :         .tp_basicsize = sizeof(pytalloc_BaseObject),
     246             : };
     247             : 
     248             : #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
     249             : 
     250             : #if PY_MAJOR_VERSION >= 3
     251             : static struct PyModuleDef moduledef = {
     252             :     PyModuleDef_HEAD_INIT,
     253             :     .m_name = "talloc",
     254             :     .m_doc = MODULE_DOC,
     255             :     .m_size = -1,
     256             :     .m_methods = talloc_methods,
     257             : };
     258             : #endif
     259             : 
     260             : static PyObject *module_init(void);
     261       11825 : static PyObject *module_init(void)
     262             : {
     263             :         PyObject *m;
     264             : 
     265       11825 :         if (PyType_Ready(&TallocObject_Type) < 0)
     266           0 :                 return NULL;
     267             : 
     268       11825 :         if (PyType_Ready(&TallocBaseObject_Type) < 0)
     269           0 :                 return NULL;
     270             : 
     271       11825 :         if (PyType_Ready(&TallocGenericObject_Type) < 0)
     272           0 :                 return NULL;
     273             : 
     274             : #if PY_MAJOR_VERSION >= 3
     275       11825 :         m = PyModule_Create(&moduledef);
     276             : #else
     277             :         m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC);
     278             : #endif
     279       11825 :         if (m == NULL)
     280           0 :                 return NULL;
     281             : 
     282       11825 :         Py_INCREF(&TallocObject_Type);
     283       11825 :         if (PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type)) {
     284           0 :                 goto err;
     285             :         }
     286       11825 :         Py_INCREF(&TallocBaseObject_Type);
     287       11825 :         if (PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type)) {
     288           0 :                 goto err;
     289             :         }
     290       11825 :         Py_INCREF(&TallocGenericObject_Type);
     291       11825 :         if (PyModule_AddObject(m, "GenericObject", (PyObject *)&TallocGenericObject_Type)) {
     292           0 :                 goto err;
     293             :         }
     294       11340 :         return m;
     295             : 
     296           0 : err:
     297           0 :         Py_DECREF(m);
     298           0 :         return NULL;
     299             : }
     300             : 
     301             : #if PY_MAJOR_VERSION >= 3
     302             : PyMODINIT_FUNC PyInit_talloc(void);
     303       11825 : PyMODINIT_FUNC PyInit_talloc(void)
     304             : {
     305       11825 :         return module_init();
     306             : }
     307             : #else
     308             : void inittalloc(void);
     309             : void inittalloc(void)
     310             : {
     311             :         module_init();
     312             : }
     313             : #endif

Generated by: LCOV version 1.13