diff options
Diffstat (limited to 'plugins/pychrysalide/format')
| -rw-r--r-- | plugins/pychrysalide/format/symbol.c | 236 | 
1 files changed, 201 insertions, 35 deletions
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c index 86a321c..962c627 100644 --- a/plugins/pychrysalide/format/symbol.c +++ b/plugins/pychrysalide/format/symbol.c @@ -27,13 +27,15 @@  #include <assert.h>  #include <malloc.h> +#include <string.h>  #include <pygobject.h>  #include <i18n.h> -#include <format/symbol.h> +#include <format/symbol-int.h> +#include <plugins/dt.h>  #include "constants.h" @@ -47,12 +49,29 @@ -/* Effectue une comparaison avec un objet Python 'BinSymbol'. */ -static PyObject *py_binary_symbol_richcompare(PyObject *, PyObject *, int); +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + -/* Crée un nouvel objet Python de type 'BinSymbol'. */ +/* Accompagne la création d'une instance dérivée en Python. */  static PyObject *py_binary_symbol_new(PyTypeObject *, PyObject *, PyObject *); +/* Initialise la classe des symboles d'exécutables. */ +static void py_binary_symbol_init_gclass(GBinSymbolClass *, gpointer); + +/* Fournit une étiquette pour viser un symbole. */ +static char *g_binary_symbol_get_label_wrapper(const GBinSymbol *); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_binary_symbol_init(PyObject *, PyObject *, PyObject *); + + + +/* --------------------- FONCTIONNALITES BASIQUES POUR SYMBOLES --------------------- */ + + +/* Effectue une comparaison avec un objet Python 'BinSymbol'. */ +static PyObject *py_binary_symbol_richcompare(PyObject *, PyObject *, int); +  /* Fournit l'emplacement où se situe un symbole. */  static PyObject *py_binary_symbol_get_range(PyObject *, void *); @@ -79,45 +98,129 @@ static int py_binary_symbol_set_label(PyObject *, PyObject *, void *); +/* ---------------------------------------------------------------------------------- */ +/*                          GLUE POUR CREATION DEPUIS PYTHON                          */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : a  = premier object Python à consulter.                      * -*                b  = second object Python à consulter.                       * -*                op = type de comparaison menée.                              * +*  Paramètres  : type = type du nouvel objet à mettre en place.               * +*                args = éventuelle liste d'arguments.                         * +*                kwds = éventuel dictionnaire de valeurs mises à disposition. *  *                                                                             * -*  Description : Effectue une comparaison avec un objet Python 'BinSymbol'.   * +*  Description : Accompagne la création d'une instance dérivée en Python.     *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static PyObject *py_binary_symbol_richcompare(PyObject *a, PyObject *b, int op) +static PyObject *py_binary_symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds)  { -    PyObject *result;                       /* Bilan à retourner           */ -    int ret;                                /* Bilan de lecture des args.  */ -    const GBinSymbol *sym_a;                /* Premier élément à traiter   */ -    const GBinSymbol *sym_b;                /* Second élément à traiter    */ -    int status;                             /* Résultat d'une comparaison  */ +    PyObject *result;                       /* Objet à retourner           */ +    PyTypeObject *base;                     /* Type de base à dériver      */ +    bool first_time;                        /* Evite les multiples passages*/ +    GType gtype;                            /* Nouveau type de processeur  */ +    bool status;                            /* Bilan d'un enregistrement   */ -    ret = PyObject_IsInstance(b, (PyObject *)get_python_binary_symbol_type()); -    if (!ret) +    /* Validations diverses */ + +    base = get_python_binary_symbol_type(); + +    if (type == base) +        goto simple_way; + +    /* Mise en place d'un type dédié */ + +    first_time = (g_type_from_name(type->tp_name) == 0); + +    gtype = build_dynamic_type(G_TYPE_BIN_SYMBOL, type->tp_name, +                               (GClassInitFunc)py_binary_symbol_init_gclass, NULL, NULL); + +    if (first_time)      { -        result = Py_NotImplemented; -        goto cmp_done; +        status = register_class_for_dynamic_pygobject(gtype, type, base); + +        if (!status) +        { +            result = NULL; +            goto exit; +        } +      } -    sym_a = G_BIN_SYMBOL(pygobject_get(a)); -    sym_b = G_BIN_SYMBOL(pygobject_get(b)); +    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ -    status = g_binary_symbol_cmp(&sym_a, &sym_b); + simple_way: -    result = status_to_rich_cmp_state(status, op); +    result = PyType_GenericNew(type, args, kwds); - cmp_done: + exit: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class  = classe à initialiser.                               * +*                unused = données non utilisées ici.                          * +*                                                                             * +*  Description : Initialise la classe des symboles d'exécutables.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void py_binary_symbol_init_gclass(GBinSymbolClass *class, gpointer unused) +{ +    class->get_label = g_binary_symbol_get_label_wrapper; + +} -    Py_INCREF(result); + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit une étiquette pour viser un symbole.                 * +*                                                                             * +*  Retour      : Chaîne de caractères renvoyant au symbole.                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_binary_symbol_get_label_wrapper(const GBinSymbol *symbol) +{ +    char *result;                           /* Etiquette à retourner       */ +    PyObject *pyobj;                        /* Objet Python concerné       */ +    PyObject *pyret;                        /* Bilan de consultation       */ + +    result = NULL; + +    pyobj = pygobject_new(G_OBJECT(symbol)); + +    if (has_python_method(pyobj, "_get_label")) +    { +        pyret = run_python_method(pyobj, "_get_label", NULL); +        if (pyret == NULL) goto exit; + +        if (PyUnicode_Check(pyret)) +            result = strdup(PyUnicode_DATA(pyret)); + +        Py_DECREF(pyret); + +    } + + exit: + +    Py_DECREF(pyobj);      return result; @@ -126,21 +229,20 @@ static PyObject *py_binary_symbol_richcompare(PyObject *a, PyObject *b, int op)  /******************************************************************************  *                                                                             * -*  Paramètres  : type = type de l'objet à instancier.                         * +*  Paramètres  : self = objet à initialiser (théoriquement).                  *  *                args = arguments fournis à l'appel.                          *  *                kwds = arguments de type key=val fournis.                    *  *                                                                             * -*  Description : Crée un nouvel objet Python de type 'BinSymbol'.             * +*  Description : Initialise une instance sur la base du dérivé de GObject.    *  *                                                                             * -*  Retour      : Instance Python mise en place.                               * +*  Retour      : 0.                                                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static PyObject *py_binary_symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_binary_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)  { -    PyObject *result;                       /* Bilan à retourner           */      SymbolType stype;                       /* Type prévu pour le  symbole */      mrange_t range;                         /* Version native d'un espace  */      int ret;                                /* Bilan de lecture des args.  */ @@ -157,20 +259,82 @@ static PyObject *py_binary_symbol_new(PyTypeObject *type, PyObject *args, PyObje      "\n"                                                                        \      "Where stype is a pychrysalide.format.BinSymbol.SymbolType value, and"      \      " range a memory space defined by pychrysalide.arch.mrange."                \ +    "\n"                                                                        \ +    "The following special method can be overridden:\n"                         \ +    "* _get_label(self): provides a default label for the symbol." + +    /* Récupération des paramètres */      ret = PyArg_ParseTuple(args, "kO&", &stype, convert_any_to_mrange, &range); -    if (!ret) return NULL; +    if (!ret) return -1;      if (stype >= STP_COUNT)      {          PyErr_SetString(PyExc_ValueError, _("Invalid type of symbol.")); -        return NULL; +        return -1;      } -    symbol = g_binary_symbol_new(&range, stype); +    /* Initialisation d'un objet GLib */ + +    ret = forward_pygobjet_init(self); +    if (ret == -1) return -1; + +    /* Eléments de base */ + +    symbol = G_BIN_SYMBOL(pygobject_get(self)); + +    g_binary_symbol_set_range(symbol, &range); +    g_binary_symbol_set_stype(symbol, stype); + +    return 0; + +} + + +/* ---------------------------------------------------------------------------------- */ +/*                       FONCTIONNALITES BASIQUES POUR SYMBOLES                       */ +/* ---------------------------------------------------------------------------------- */ -    result = pygobject_new(G_OBJECT(symbol)); -    g_object_unref(symbol); + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a  = premier object Python à consulter.                      * +*                b  = second object Python à consulter.                       * +*                op = type de comparaison menée.                              * +*                                                                             * +*  Description : Effectue une comparaison avec un objet Python 'BinSymbol'.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_binary_symbol_richcompare(PyObject *a, PyObject *b, int op) +{ +    PyObject *result;                       /* Bilan à retourner           */ +    int ret;                                /* Bilan de lecture des args.  */ +    const GBinSymbol *sym_a;                /* Premier élément à traiter   */ +    const GBinSymbol *sym_b;                /* Second élément à traiter    */ +    int status;                             /* Résultat d'une comparaison  */ + +    ret = PyObject_IsInstance(b, (PyObject *)get_python_binary_symbol_type()); +    if (!ret) +    { +        result = Py_NotImplemented; +        goto cmp_done; +    } + +    sym_a = G_BIN_SYMBOL(pygobject_get(a)); +    sym_b = G_BIN_SYMBOL(pygobject_get(b)); + +    status = g_binary_symbol_cmp(&sym_a, &sym_b); + +    result = status_to_rich_cmp_state(status, op); + + cmp_done: + +    Py_INCREF(result);      return result; @@ -507,6 +671,8 @@ PyTypeObject *get_python_binary_symbol_type(void)          .tp_methods     = py_bin_symbol_methods,          .tp_getset      = py_bin_symbol_getseters, + +        .tp_init        = py_binary_symbol_init,          .tp_new         = py_binary_symbol_new      };  | 
