diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-01-16 19:02:56 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-01-16 19:02:56 (GMT) |
commit | 9da8f8b37e3edebc917b4e223dd2447cd7cbc818 (patch) | |
tree | 3f330b13e7ca2a0a163882be3043ca9571f25211 /plugins/pychrysa/helpers.c | |
parent | eb9b7fd76451db5c9f07a800c0394480e4b88c9c (diff) |
Changed the Python bindings source directory and updated code.
Diffstat (limited to 'plugins/pychrysa/helpers.c')
-rw-r--r-- | plugins/pychrysa/helpers.c | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c deleted file mode 100644 index 17a396d..0000000 --- a/plugins/pychrysa/helpers.c +++ /dev/null @@ -1,473 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers.c - simplification des interactions de base avec Python - * - * Copyright (C) 2012-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 <http://www.gnu.org/licenses/>. - */ - - -#include "helpers.h" - - -#include <assert.h> -#include <pygobject.h> -#include <stdarg.h> -#include <string.h> - - - -/* ---------------------------------------------------------------------------------- */ -/* ACCELERATEURS POUR PYTHON UNIQUEMENT */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : status = bilan de comparaison à traduire. * -* op = type de comparaison menée. * -* * -* Description : Traduit pour Python le bilan d'une comparaison riche. * -* * -* Retour : Objet Python à référencer. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *status_to_rich_cmp_state(int status, int op) -{ - PyObject *result; /* Bilan àretourner */ - - switch (op) - { - case Py_LT: - result = status < 0 ? Py_True : Py_False; - break; - - case Py_LE: - result = status <= 0 ? Py_True : Py_False; - break; - - case Py_EQ: - result = status == 0 ? Py_True : Py_False; - break; - - case Py_NE: - result = status != 0 ? Py_True : Py_False; - break; - - case Py_GT: - result = status > 0 ? Py_True : Py_False; - break; - - case Py_GE: - result = status >= 0 ? Py_True : Py_False; - break; - - default: - result = Py_NotImplemented; - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* 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; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONFORTS CIBLANT PYGOBJECT */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : spec = définition à mettre en place dynamiquement. * -* * -* Description : Définit dans le tas de Python un nouveau type. * -* * -* Retour : Nouveau type prêt à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *define_python_dynamic_type(const PyTypeObject *spec) -{ - PyTypeObject *result; /* Définition créée à renvoyer */ - PyTypeObject *type; /* Type de tous les types */ - size_t size; /* Taille de la définition */ - char *s; /* Marqueur de début de chaîne */ - PyHeapTypeObject *hobj; /* Version réelle du type créé */ - - /** - * Le cahier des charges est ici d'éviter les erreurs suivantes : - * - * TypeError: type 'XXX' is not dynamically allocated but its base type 'YYY' is dynamically allocated - * Fatal Python error: unexpected exception during garbage collection - * - * L'allocation dynamique est marquée par le fanion Py_TPFLAGS_HEAPTYPE. - * - * Une des rares fonctions qui appliquent ce fanion est PyType_FromSpecWithBases(), - * mais elle appelle ensuite PyType_Ready(), ce qui est incompatible avec des modifications - * utltérieures avant un appel à pygobject_register_class(). - * - * Le code suivant s'inspire fortement des méthodes originales de Python, - * dont les mécanismes employés par PyType_GenericAlloc(). - */ - - type = &PyType_Type; - size = _PyObject_SIZE(type); - - if (PyType_IS_GC(type)) - result = (PyTypeObject *)_PyObject_GC_Malloc(size); - else - result = (PyTypeObject *)PyObject_MALLOC(size); - - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(type); - - /* Définitions sommaires */ - - memset(result, 0, sizeof(PyHeapTypeObject)); - - memcpy(result, spec, sizeof(PyTypeObject)); - - result->tp_flags |= Py_TPFLAGS_HEAPTYPE; - - /* Définitions des noms */ - - /** - * Pour un type dynamique, les désignations ne s'appuient pas sur la partie réservée - * au type, mais sur les données suivantes (cf. type_name() et type_qualname()). - * - * Les deux fonctions désignées sont par ailleurs facilement accessibles : - * - * #0 0x0000555555689bf0 in type_qualname (...) at Objects/typeobject.c:393 - * #1 0x000055555568b3b4 in type_repr (...) at Objects/typeobject.c:855 - * #2 0x0000555555693574 in object_str (...) at Objects/typeobject.c:3511 - * #3 0x0000555555670d02 in PyObject_Str (...) at Objects/object.c:535 - * ... - * - * On s'inspire donc du contenu de PyType_FromSpecWithBases() pour éviter tout - * plantage du fait de données non initialisées. - */ - - hobj = (PyHeapTypeObject *)result; - - s = strrchr(spec->tp_name, '.'); - - if (s == NULL) - s = (char *)spec->tp_name; - else - s++; - - hobj->ht_name = PyUnicode_FromString(s); - assert(hobj->ht_name != NULL); - - hobj->ht_qualname = hobj->ht_name; - Py_INCREF(hobj->ht_qualname); - - result->tp_as_async = &hobj->as_async; - result->tp_as_number = &hobj->as_number; - result->tp_as_sequence = &hobj->as_sequence; - result->tp_as_mapping = &hobj->as_mapping; - result->tp_as_buffer = &hobj->as_buffer; - - hobj->ht_cached_keys = _PyDict_NewKeysForClass(); - - - - -#if 0 - if (type->tp_itemsize == 0) - (void)PyObject_INIT(result, type); - else - (void) PyObject_INIT_VAR((PyVarObject *)result, type, 0); - - if (PyType_IS_GC(type)) - _PyObject_GC_TRACK(result); -#endif - - 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, ...) -{ - bool result; /* Bilan à retourner */ - Py_ssize_t size; /* Taille de liste actuelle */ - PyObject *static_bases; /* Base(s) de l'objet */ - va_list ap; /* Parcours des arguments */ - PyTypeObject *static_base; /* Base à rajouter à la liste */ - - /** - * 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; - } - - size = 1; - static_bases = PyTuple_New(size); - - Py_INCREF(base); - PyTuple_SetItem(static_bases, 0, (PyObject *)base); - - va_start(ap, base); - - while (1) - { - static_base = va_arg(ap, PyTypeObject *); - - if (static_base == NULL) break; - - _PyTuple_Resize(&static_bases, ++size); - - Py_INCREF(static_base); - PyTuple_SetItem(static_bases, size - 1, (PyObject *)static_base); - - } - - va_end(ap); - - - - /* -#0 0x000055555565aad4 in insertdict (mp=0x7fffe7c2c8a8, key='GenConfig', hash=262970853803706525, value=<unknown at remote 0x7ffff6bd9ce0>) at ../Objects/dictobject.c:801 -#1 0x000055555565bf62 in PyDict_SetItem (op={'__doc__': 'Python module for Chrysalide.glibext', '__name__': 'pychrysalide.glibext', 'BufferLine': <type at remote 0x7ffff6bd9760>, '__spec__': None, 'ConfigParam': <type at remote 0x7ffff6bd9a00>, '__package__': None, 'Buffercache': <type at remote 0x7ffff6bd95c0>, 'ConfigParamIterator': <type at remote 0x7ffff6bd9fc0>, '__loader__': None}, key='GenConfig', value=<unknown at remote 0x7ffff6bd9ce0>) at ../Objects/dictobject.c:1227 -#2 0x00005555556610b0 in PyDict_SetItemString (v={'__doc__': 'Python module for Chrysalide.glibext', '__name__': 'pychrysalide.glibext', 'BufferLine': <type at remote 0x7ffff6bd9760>, '__spec__': None, 'ConfigParam': <type at remote 0x7ffff6bd9a00>, '__package__': None, 'Buffercache': <type at remote 0x7ffff6bd95c0>, 'ConfigParamIterator': <type at remote 0x7ffff6bd9fc0>, '__loader__': None}, key=0x7ffff69cd0bd "GenConfig", item=<unknown at remote 0x7ffff6bd9ce0>) at ../Objects/dictobject.c:2870 -#3 0x00007ffff69b3d12 in _register_class_for_pygobject (dict={'__doc__': 'Python module for Chrysalide.glibext', '__name__': 'pychrysalide.glibext', 'BufferLine': <type at remote 0x7ffff6bd9760>, '__spec__': None, 'ConfigParam': <type at remote 0x7ffff6bd9a00>, '__package__': None, 'Buffercache': <type at remote 0x7ffff6bd95c0>, 'ConfigParamIterator': <type at remote 0x7ffff6bd9fc0>, '__loader__': None}, gtype=93824998785328, type=0x7ffff6bd9ce0 <py_generic_config_type>, base=0x7fffe80e72a0 <PyGObject_Type>) at helpers.c:320 - */ - - - - //type->tp_weaklistoffset = offsetof(PyGObject, weakreflist); - //type->tp_dictoffset = offsetof(PyGObject, inst_dict); - - pygobject_register_class(dict, NULL, gtype, type, static_bases); - - if (PyErr_Occurred() == NULL) - result = true; - - else - { - PyErr_Print(); - result = false; - } - - assert(PyErr_Occurred() == NULL); - - return result; - -} |