2010-11-05 05:00:45 +03:00
/*
Unix SMB / CIFS implementation .
Python Talloc Module
2011-08-10 17:15:18 +04:00
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2010 - 2011
2010-11-05 05:00:45 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <Python.h>
# include <talloc.h>
# include <pytalloc.h>
2016-02-22 04:02:28 +03:00
# include "pytalloc_private.h"
2010-11-05 05:00:45 +03:00
2015-01-15 16:07:09 +03:00
static PyTypeObject TallocObject_Type ;
2010-11-05 05:00:45 +03:00
/* print a talloc tree report for a talloc python object */
2011-08-10 17:15:18 +04:00
static PyObject * pytalloc_report_full ( PyObject * self , PyObject * args )
2010-11-05 05:00:45 +03:00
{
2010-11-05 15:48:34 +03:00
PyObject * py_obj = Py_None ;
2010-11-05 05:00:45 +03:00
2010-11-05 15:48:34 +03:00
if ( ! PyArg_ParseTuple ( args , " |O " , & py_obj ) )
2010-11-05 05:00:45 +03:00
return NULL ;
if ( py_obj = = Py_None ) {
talloc_report_full ( NULL , stdout ) ;
} else {
2011-08-10 17:15:18 +04:00
talloc_report_full ( pytalloc_get_mem_ctx ( py_obj ) , stdout ) ;
2010-11-05 05:00:45 +03:00
}
return Py_None ;
}
/* enable null tracking */
2019-05-02 21:49:27 +03:00
static PyObject * pytalloc_enable_null_tracking ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-11-05 05:00:45 +03:00
{
talloc_enable_null_tracking ( ) ;
return Py_None ;
}
/* return the number of talloc blocks */
2011-08-10 17:15:18 +04:00
static PyObject * pytalloc_total_blocks ( PyObject * self , PyObject * args )
2010-11-05 05:00:45 +03:00
{
2010-11-05 15:48:34 +03:00
PyObject * py_obj = Py_None ;
2010-11-05 05:00:45 +03:00
2010-11-05 15:48:34 +03:00
if ( ! PyArg_ParseTuple ( args , " |O " , & py_obj ) )
2010-11-05 05:00:45 +03:00
return NULL ;
if ( py_obj = = Py_None ) {
return PyLong_FromLong ( talloc_total_blocks ( NULL ) ) ;
}
2011-08-10 17:15:18 +04:00
return PyLong_FromLong ( talloc_total_blocks ( pytalloc_get_mem_ctx ( py_obj ) ) ) ;
2010-11-05 05:00:45 +03:00
}
static PyMethodDef talloc_methods [ ] = {
2011-08-10 17:15:18 +04:00
{ " report_full " , ( PyCFunction ) pytalloc_report_full , METH_VARARGS ,
2010-11-05 05:00:45 +03:00
" show a talloc tree for an object " } ,
2011-08-10 17:15:18 +04:00
{ " enable_null_tracking " , ( PyCFunction ) pytalloc_enable_null_tracking , METH_NOARGS ,
2010-11-05 05:00:45 +03:00
" enable tracking of the NULL object " } ,
2011-08-10 17:15:18 +04:00
{ " total_blocks " , ( PyCFunction ) pytalloc_total_blocks , METH_VARARGS ,
2010-11-05 05:00:45 +03:00
" return talloc block count " } ,
{ NULL }
} ;
2010-12-01 02:07:11 +03:00
/**
* Default ( but only slightly more useful than the default ) implementation of Repr ( ) .
*/
2011-08-10 17:15:18 +04:00
static PyObject * pytalloc_default_repr ( PyObject * obj )
2010-12-01 02:07:11 +03:00
{
2011-08-10 17:15:18 +04:00
pytalloc_Object * talloc_obj = ( pytalloc_Object * ) obj ;
2010-12-01 02:07:11 +03:00
PyTypeObject * type = ( PyTypeObject * ) PyObject_Type ( obj ) ;
2019-06-07 12:08:55 +03:00
return PyUnicode_FromFormat ( " <%s talloc object at %p> " ,
2015-01-15 16:07:09 +03:00
type - > tp_name , talloc_obj - > ptr ) ;
2010-12-01 02:07:11 +03:00
}
2010-12-01 02:14:27 +03:00
/**
* Simple dealloc for talloc - wrapping PyObjects
*/
2011-08-10 17:15:18 +04:00
static void pytalloc_dealloc ( PyObject * self )
2010-12-01 02:14:27 +03:00
{
2011-08-10 17:15:18 +04:00
pytalloc_Object * obj = ( pytalloc_Object * ) self ;
2010-12-01 02:14:27 +03:00
assert ( talloc_unlink ( NULL , obj - > talloc_ctx ) ! = - 1 ) ;
obj - > talloc_ctx = NULL ;
2011-01-01 08:55:54 +03:00
self - > ob_type - > tp_free ( self ) ;
2010-12-01 02:14:27 +03:00
}
2010-12-01 02:19:37 +03:00
/**
* Default ( but only slightly more useful than the default ) implementation of cmp .
*/
2015-01-15 16:07:09 +03:00
# if PY_MAJOR_VERSION >= 3
static PyObject * pytalloc_default_richcmp ( PyObject * obj1 , PyObject * obj2 , int op )
{
void * ptr1 ;
void * ptr2 ;
if ( Py_TYPE ( obj1 ) = = Py_TYPE ( obj2 ) ) {
/* When types match, compare pointers */
ptr1 = pytalloc_get_ptr ( obj1 ) ;
ptr2 = pytalloc_get_ptr ( obj2 ) ;
} else if ( PyObject_TypeCheck ( obj2 , & TallocObject_Type ) ) {
/* Otherwise, compare types */
ptr1 = Py_TYPE ( obj1 ) ;
ptr2 = Py_TYPE ( obj2 ) ;
} else {
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
switch ( op ) {
case Py_EQ : return PyBool_FromLong ( ptr1 = = ptr2 ) ;
case Py_NE : return PyBool_FromLong ( ptr1 ! = ptr2 ) ;
case Py_LT : return PyBool_FromLong ( ptr1 < ptr2 ) ;
case Py_GT : return PyBool_FromLong ( ptr1 > ptr2 ) ;
case Py_LE : return PyBool_FromLong ( ptr1 < = ptr2 ) ;
case Py_GE : return PyBool_FromLong ( ptr1 > = ptr2 ) ;
}
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
# else
2011-08-10 17:15:18 +04:00
static int pytalloc_default_cmp ( PyObject * _obj1 , PyObject * _obj2 )
2010-12-01 02:19:37 +03:00
{
2011-08-10 17:15:18 +04:00
pytalloc_Object * obj1 = ( pytalloc_Object * ) _obj1 ,
* obj2 = ( pytalloc_Object * ) _obj2 ;
2010-12-01 02:19:37 +03:00
if ( obj1 - > ob_type ! = obj2 - > ob_type )
2015-03-06 20:57:00 +03:00
return ( ( char * ) obj1 - > ob_type - ( char * ) obj2 - > ob_type ) ;
2010-12-01 02:19:37 +03:00
2011-08-10 17:15:18 +04:00
return ( ( char * ) pytalloc_get_ptr ( obj1 ) - ( char * ) pytalloc_get_ptr ( obj2 ) ) ;
2010-12-01 02:19:37 +03:00
}
2015-01-15 16:07:09 +03:00
# endif
2010-12-01 02:19:37 +03:00
2010-12-01 00:22:15 +03:00
static PyTypeObject TallocObject_Type = {
. tp_name = " talloc.Object " ,
2010-12-05 19:06:58 +03:00
. tp_doc = " Python wrapper for a talloc-maintained object. " ,
2011-08-10 17:15:18 +04:00
. tp_basicsize = sizeof ( pytalloc_Object ) ,
. tp_dealloc = ( destructor ) pytalloc_dealloc ,
2010-12-01 00:22:15 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
2011-08-10 17:15:18 +04:00
. tp_repr = pytalloc_default_repr ,
2015-01-15 16:07:09 +03:00
# if PY_MAJOR_VERSION >= 3
. tp_richcompare = pytalloc_default_richcmp ,
# else
2011-08-10 17:15:18 +04:00
. tp_compare = pytalloc_default_cmp ,
2015-01-15 16:07:09 +03:00
# endif
2010-12-01 00:22:15 +03:00
} ;
2016-02-22 04:02:28 +03:00
/**
* Default ( but only slightly more useful than the default ) implementation of Repr ( ) .
*/
static PyObject * pytalloc_base_default_repr ( PyObject * obj )
{
pytalloc_BaseObject * talloc_obj = ( pytalloc_BaseObject * ) obj ;
PyTypeObject * type = ( PyTypeObject * ) PyObject_Type ( obj ) ;
2019-06-07 12:08:55 +03:00
return PyUnicode_FromFormat ( " <%s talloc based object at %p> " ,
2016-02-22 04:02:28 +03:00
type - > tp_name , talloc_obj - > ptr ) ;
}
/**
* Simple dealloc for talloc - wrapping PyObjects
*/
static void pytalloc_base_dealloc ( PyObject * self )
{
pytalloc_BaseObject * obj = ( pytalloc_BaseObject * ) self ;
assert ( talloc_unlink ( NULL , obj - > talloc_ctx ) ! = - 1 ) ;
obj - > talloc_ctx = NULL ;
self - > ob_type - > tp_free ( self ) ;
}
/**
* Default ( but only slightly more useful than the default ) implementation of cmp .
*/
# if PY_MAJOR_VERSION >= 3
static PyObject * pytalloc_base_default_richcmp ( PyObject * obj1 , PyObject * obj2 , int op )
{
void * ptr1 ;
void * ptr2 ;
if ( Py_TYPE ( obj1 ) = = Py_TYPE ( obj2 ) ) {
/* When types match, compare pointers */
ptr1 = pytalloc_get_ptr ( obj1 ) ;
ptr2 = pytalloc_get_ptr ( obj2 ) ;
} else if ( PyObject_TypeCheck ( obj2 , & TallocObject_Type ) ) {
/* Otherwise, compare types */
ptr1 = Py_TYPE ( obj1 ) ;
ptr2 = Py_TYPE ( obj2 ) ;
} else {
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
switch ( op ) {
case Py_EQ : return PyBool_FromLong ( ptr1 = = ptr2 ) ;
case Py_NE : return PyBool_FromLong ( ptr1 ! = ptr2 ) ;
case Py_LT : return PyBool_FromLong ( ptr1 < ptr2 ) ;
case Py_GT : return PyBool_FromLong ( ptr1 > ptr2 ) ;
case Py_LE : return PyBool_FromLong ( ptr1 < = ptr2 ) ;
case Py_GE : return PyBool_FromLong ( ptr1 > = ptr2 ) ;
}
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
# else
static int pytalloc_base_default_cmp ( PyObject * _obj1 , PyObject * _obj2 )
{
pytalloc_BaseObject * obj1 = ( pytalloc_BaseObject * ) _obj1 ,
* obj2 = ( pytalloc_BaseObject * ) _obj2 ;
if ( obj1 - > ob_type ! = obj2 - > ob_type )
return ( ( char * ) obj1 - > ob_type - ( char * ) obj2 - > ob_type ) ;
return ( ( char * ) pytalloc_get_ptr ( obj1 ) - ( char * ) pytalloc_get_ptr ( obj2 ) ) ;
}
# endif
static PyTypeObject TallocBaseObject_Type = {
. tp_name = " talloc.BaseObject " ,
. tp_doc = " Python wrapper for a talloc-maintained object. " ,
. tp_basicsize = sizeof ( pytalloc_BaseObject ) ,
. tp_dealloc = ( destructor ) pytalloc_base_dealloc ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
. tp_repr = pytalloc_base_default_repr ,
# if PY_MAJOR_VERSION >= 3
. tp_richcompare = pytalloc_base_default_richcmp ,
# else
. tp_compare = pytalloc_base_default_cmp ,
# endif
} ;
2017-02-20 19:33:42 +03:00
static PyTypeObject TallocGenericObject_Type = {
. tp_name = " talloc.GenericObject " ,
. tp_doc = " Python wrapper for a talloc-maintained object. " ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
. tp_base = & TallocBaseObject_Type ,
. tp_basicsize = sizeof ( pytalloc_BaseObject ) ,
} ;
2015-01-15 16:07:09 +03:00
# define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
# if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " talloc " ,
. m_doc = MODULE_DOC ,
. m_size = - 1 ,
. m_methods = talloc_methods ,
} ;
# endif
static PyObject * module_init ( void ) ;
static PyObject * module_init ( void )
2010-11-05 05:00:45 +03:00
{
PyObject * m ;
2010-12-01 00:22:15 +03:00
if ( PyType_Ready ( & TallocObject_Type ) < 0 )
2015-01-15 16:07:09 +03:00
return NULL ;
2010-12-01 00:22:15 +03:00
2016-02-22 04:02:28 +03:00
if ( PyType_Ready ( & TallocBaseObject_Type ) < 0 )
return NULL ;
2017-02-20 19:33:42 +03:00
if ( PyType_Ready ( & TallocGenericObject_Type ) < 0 )
return NULL ;
2015-01-15 16:07:09 +03:00
# if PY_MAJOR_VERSION >= 3
m = PyModule_Create ( & moduledef ) ;
# else
m = Py_InitModule3 ( " talloc " , talloc_methods , MODULE_DOC ) ;
# endif
2010-11-05 05:00:45 +03:00
if ( m = = NULL )
2015-01-15 16:07:09 +03:00
return NULL ;
2010-12-01 00:22:15 +03:00
Py_INCREF ( & TallocObject_Type ) ;
2019-03-06 17:08:40 +03:00
if ( PyModule_AddObject ( m , " Object " , ( PyObject * ) & TallocObject_Type ) ) {
goto err ;
}
2016-02-22 04:02:28 +03:00
Py_INCREF ( & TallocBaseObject_Type ) ;
2019-03-06 17:08:40 +03:00
if ( PyModule_AddObject ( m , " BaseObject " , ( PyObject * ) & TallocBaseObject_Type ) ) {
goto err ;
}
2017-02-20 19:33:42 +03:00
Py_INCREF ( & TallocGenericObject_Type ) ;
2019-03-06 17:08:40 +03:00
if ( PyModule_AddObject ( m , " GenericObject " , ( PyObject * ) & TallocGenericObject_Type ) ) {
goto err ;
}
2015-01-15 16:07:09 +03:00
return m ;
2019-03-06 17:08:40 +03:00
err :
Py_DECREF ( m ) ;
return NULL ;
2015-01-15 16:07:09 +03:00
}
# if PY_MAJOR_VERSION >= 3
PyMODINIT_FUNC PyInit_talloc ( void ) ;
PyMODINIT_FUNC PyInit_talloc ( void )
{
return module_init ( ) ;
}
# else
void inittalloc ( void ) ;
void inittalloc ( void )
{
module_init ( ) ;
2010-11-05 05:00:45 +03:00
}
2015-01-15 16:07:09 +03:00
# endif