2 Unix SMB/CIFS implementation.
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010-2011
6 ** NOTE! The following LGPL license applies to the talloc
7 ** library. This does NOT imply that all of Samba is released
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.
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.
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/>.
27 #include "pytalloc_private.h"
29 static PyTypeObject TallocObject_Type
;
31 /* print a talloc tree report for a talloc python object */
32 static PyObject
*pytalloc_report_full(PyObject
*self
, PyObject
*args
)
34 PyObject
*py_obj
= Py_None
;
36 if (!PyArg_ParseTuple(args
, "|O", &py_obj
))
39 if (py_obj
== Py_None
) {
40 talloc_report_full(NULL
, stdout
);
42 talloc_report_full(pytalloc_get_mem_ctx(py_obj
), stdout
);
47 /* enable null tracking */
48 static PyObject
*pytalloc_enable_null_tracking(PyObject
*self
,
49 PyObject
*Py_UNUSED(ignored
))
51 talloc_enable_null_tracking();
55 /* return the number of talloc blocks */
56 static PyObject
*pytalloc_total_blocks(PyObject
*self
, PyObject
*args
)
58 PyObject
*py_obj
= Py_None
;
60 if (!PyArg_ParseTuple(args
, "|O", &py_obj
))
63 if (py_obj
== Py_None
) {
64 return PyLong_FromLong(talloc_total_blocks(NULL
));
67 return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj
)));
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"},
81 * Default (but only slightly more useful than the default) implementation of Repr().
83 static PyObject
*pytalloc_default_repr(PyObject
*obj
)
85 pytalloc_Object
*talloc_obj
= (pytalloc_Object
*)obj
;
86 PyTypeObject
*type
= (PyTypeObject
*)PyObject_Type(obj
);
88 return PyUnicode_FromFormat("<%s talloc object at %p>",
89 type
->tp_name
, talloc_obj
->ptr
);
93 * Simple dealloc for talloc-wrapping PyObjects
95 static void pytalloc_dealloc(PyObject
* self
)
97 pytalloc_Object
*obj
= (pytalloc_Object
*)self
;
98 assert(talloc_unlink(NULL
, obj
->talloc_ctx
) != -1);
99 obj
->talloc_ctx
= NULL
;
100 self
->ob_type
->tp_free(self
);
104 * Default (but only slightly more useful than the default) implementation of cmp.
106 #if PY_MAJOR_VERSION >= 3
107 static PyObject
*pytalloc_default_richcmp(PyObject
*obj1
, PyObject
*obj2
, int op
)
111 if (Py_TYPE(obj1
) == Py_TYPE(obj2
)) {
112 /* When types match, compare pointers */
113 ptr1
= pytalloc_get_ptr(obj1
);
114 ptr2
= pytalloc_get_ptr(obj2
);
115 } else if (PyObject_TypeCheck(obj2
, &TallocObject_Type
)) {
116 /* Otherwise, compare types */
117 ptr1
= Py_TYPE(obj1
);
118 ptr2
= Py_TYPE(obj2
);
120 Py_INCREF(Py_NotImplemented
);
121 return Py_NotImplemented
;
124 case Py_EQ
: return PyBool_FromLong(ptr1
== ptr2
);
125 case Py_NE
: return PyBool_FromLong(ptr1
!= ptr2
);
126 case Py_LT
: return PyBool_FromLong(ptr1
< ptr2
);
127 case Py_GT
: return PyBool_FromLong(ptr1
> ptr2
);
128 case Py_LE
: return PyBool_FromLong(ptr1
<= ptr2
);
129 case Py_GE
: return PyBool_FromLong(ptr1
>= ptr2
);
131 Py_INCREF(Py_NotImplemented
);
132 return Py_NotImplemented
;
135 static int pytalloc_default_cmp(PyObject
*_obj1
, PyObject
*_obj2
)
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
);
142 return ((char *)pytalloc_get_ptr(obj1
) - (char *)pytalloc_get_ptr(obj2
));
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
,
156 .tp_compare
= pytalloc_default_cmp
,
161 * Default (but only slightly more useful than the default) implementation of Repr().
163 static PyObject
*pytalloc_base_default_repr(PyObject
*obj
)
165 pytalloc_BaseObject
*talloc_obj
= (pytalloc_BaseObject
*)obj
;
166 PyTypeObject
*type
= (PyTypeObject
*)PyObject_Type(obj
);
168 return PyUnicode_FromFormat("<%s talloc based object at %p>",
169 type
->tp_name
, talloc_obj
->ptr
);
173 * Simple dealloc for talloc-wrapping PyObjects
175 static void pytalloc_base_dealloc(PyObject
* self
)
177 pytalloc_BaseObject
*obj
= (pytalloc_BaseObject
*)self
;
178 assert(talloc_unlink(NULL
, obj
->talloc_ctx
) != -1);
179 obj
->talloc_ctx
= NULL
;
180 self
->ob_type
->tp_free(self
);
184 * Default (but only slightly more useful than the default) implementation of cmp.
186 #if PY_MAJOR_VERSION >= 3
187 static PyObject
*pytalloc_base_default_richcmp(PyObject
*obj1
, PyObject
*obj2
, int op
)
191 if (Py_TYPE(obj1
) == Py_TYPE(obj2
)) {
192 /* When types match, compare pointers */
193 ptr1
= pytalloc_get_ptr(obj1
);
194 ptr2
= pytalloc_get_ptr(obj2
);
195 } else if (PyObject_TypeCheck(obj2
, &TallocObject_Type
)) {
196 /* Otherwise, compare types */
197 ptr1
= Py_TYPE(obj1
);
198 ptr2
= Py_TYPE(obj2
);
200 Py_INCREF(Py_NotImplemented
);
201 return Py_NotImplemented
;
204 case Py_EQ
: return PyBool_FromLong(ptr1
== ptr2
);
205 case Py_NE
: return PyBool_FromLong(ptr1
!= ptr2
);
206 case Py_LT
: return PyBool_FromLong(ptr1
< ptr2
);
207 case Py_GT
: return PyBool_FromLong(ptr1
> ptr2
);
208 case Py_LE
: return PyBool_FromLong(ptr1
<= ptr2
);
209 case Py_GE
: return PyBool_FromLong(ptr1
>= ptr2
);
211 Py_INCREF(Py_NotImplemented
);
212 return Py_NotImplemented
;
215 static int pytalloc_base_default_cmp(PyObject
*_obj1
, PyObject
*_obj2
)
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
);
222 return ((char *)pytalloc_get_ptr(obj1
) - (char *)pytalloc_get_ptr(obj2
));
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
,
236 .tp_compare
= pytalloc_base_default_cmp
,
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
),
248 #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
250 #if PY_MAJOR_VERSION >= 3
251 static struct PyModuleDef moduledef
= {
252 PyModuleDef_HEAD_INIT
,
256 .m_methods
= talloc_methods
,
260 static PyObject
*module_init(void);
261 static PyObject
*module_init(void)
265 if (PyType_Ready(&TallocObject_Type
) < 0)
268 if (PyType_Ready(&TallocBaseObject_Type
) < 0)
271 if (PyType_Ready(&TallocGenericObject_Type
) < 0)
274 #if PY_MAJOR_VERSION >= 3
275 m
= PyModule_Create(&moduledef
);
277 m
= Py_InitModule3("talloc", talloc_methods
, MODULE_DOC
);
282 Py_INCREF(&TallocObject_Type
);
283 if (PyModule_AddObject(m
, "Object", (PyObject
*)&TallocObject_Type
)) {
286 Py_INCREF(&TallocBaseObject_Type
);
287 if (PyModule_AddObject(m
, "BaseObject", (PyObject
*)&TallocBaseObject_Type
)) {
290 Py_INCREF(&TallocGenericObject_Type
);
291 if (PyModule_AddObject(m
, "GenericObject", (PyObject
*)&TallocGenericObject_Type
)) {
301 #if PY_MAJOR_VERSION >= 3
302 PyMODINIT_FUNC
PyInit_talloc(void);
303 PyMODINIT_FUNC
PyInit_talloc(void)
305 return module_init();
308 void inittalloc(void);
309 void inittalloc(void)