Blame pytalloc.c

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