/* Chrysalide - Outil d'analyse de fichiers binaires * helpers.c - simplification des interactions de base avec Python * * Copyright (C) 2012-2013 Cyrille Bagard * * This file is part of Chrysalide. * * OpenIDA 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. * * OpenIDA 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 Foobar. If not, see . */ #include "helpers.h" #include #include /****************************************************************************** * * * Paramètres : target = propriétaire de la routine visée. * * method = désignation de la fonction à appeler. * * * * Description : Indique si une routine Python existe ou non. * * * * Retour : Bilan de l'analyse. * * * * Remarques : - * * * ******************************************************************************/ bool has_python_method(PyObject *module, const char *method) { bool result; /* Bilan à retourner */ PyObject *func; /* Fonction visée */ func = PyObject_GetAttrString(module, method); if (func == NULL) return false; result = PyCallable_Check(func); Py_DECREF(func); return result; } /****************************************************************************** * * * Paramètres : func = fonction Python à appeler. * * args = arguments à associer à l'opération. * * * * Description : Appelle une routine Python. * * * * Retour : Retour obtenu ou NULL si erreur. * * * * Remarques : - * * * ******************************************************************************/ PyObject *_run_python_method(PyObject *func, PyObject *args) { PyObject *result; /* Bilan à retourner */ result = NULL; if (PyCallable_Check(func)) { result = PyObject_CallObject(func, args); if (result == NULL) PyErr_Print(); } else if (PyErr_Occurred()) PyErr_Print(); return result; } /****************************************************************************** * * * Paramètres : target = propriétaire de la routine visée. * * method = désignation de la fonction à appeler. * * args = arguments à associer à l'opération. * * * * Description : Appelle une routine Python. * * * * Retour : Retour obtenu ou NULL si erreur. * * * * Remarques : - * * * ******************************************************************************/ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args) { PyObject *result; /* Bilan à retourner */ PyObject *func; /* Fonction visée */ result = NULL; func = PyObject_GetAttrString(module, method); if (func == NULL) return NULL; result = _run_python_method(func, args); Py_DECREF(func); return result; } /****************************************************************************** * * * Paramètres : obj_type = type dont le dictionnaire est à compléter. * * key = désignation de la constante à intégrer. * * value = valeur de la constante à intégrer. * * * * Description : Ajoute une constante au dictionnaire d'un type Python donné. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool PyDict_AddIntConstant(PyTypeObject *obj_type, const char *key, long value) { bool result; /* Bilan à retourner */ PyObject *item; /* Nouvel élément à insérer */ int ret; /* Bilan d'un ajout */ item = PyLong_FromLong(value); ret = PyDict_SetItemString(obj_type->tp_dict, key, item); result = (ret != -1); Py_DECREF(item); return result; } /****************************************************************************** * * * Paramètres : obj_type = type dont le dictionnaire est à compléter. * * key = désignation de la constante à intégrer. * * value = valeur de la constante à intégrer. * * * * Description : Ajoute une constante au dictionnaire d'un type Python donné. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool PyDict_AddStringConstant(PyTypeObject *obj_type, const char *key, const char *value) { bool result; /* Bilan à retourner */ PyObject *item; /* Nouvel élément à insérer */ int ret; /* Bilan d'un ajout */ item = PyUnicode_FromString(value); ret = PyDict_SetItemString(obj_type->tp_dict, key, item); result = (ret != -1); Py_DECREF(item); return result; } /****************************************************************************** * * * Paramètres : module = module où conserver une référence au type créé. * * gtype = type dans sa version GLib. * * type = type dans sa version Python. * * base = type de base de l'objet. * * * * Description : Enregistre correctement une surcouche de conversion GObject. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *type, PyTypeObject *base) { /** * pygobject_register_class() définit type->tp_base à partir des arguments fournis, * puis fait appel à PyType_Ready(). * * PyType_Ready() complète la définition via inherit_special() : * * type->tp_basicsize = type->tp_base->tp_basicsize * * Cependant, il y a un appel à mro_internal() avant, qui mène à solid_base() * puis à extra_ivars(). Et là : * * size_t t_size = type->tp_basicsize; * size_t b_size = base->tp_basicsize; * * assert(t_size >= b_size); * * Si le type de base est spécifié, une taille doit être indiquée. * * Et quelqu'un doit se coller à la tâche. PyGObject ne fait rien, donc... */ if (type->tp_basicsize < base->tp_basicsize) { assert(type->tp_basicsize == 0); type->tp_basicsize = base->tp_basicsize; } pygobject_register_class(dict, NULL, gtype, type, Py_BuildValue("(O)", base)); return true; }