diff options
Diffstat (limited to 'plugins/pychrysa')
| -rw-r--r-- | plugins/pychrysa/glibext/configuration.c | 3 | ||||
| -rw-r--r-- | plugins/pychrysa/gtkext/blockdisplay.c | 19 | ||||
| -rw-r--r-- | plugins/pychrysa/gtkext/bufferdisplay.c | 19 | ||||
| -rw-r--r-- | plugins/pychrysa/gtkext/displaypanel.c | 14 | ||||
| -rw-r--r-- | plugins/pychrysa/helpers.c | 152 | ||||
| -rw-r--r-- | plugins/pychrysa/helpers.h | 10 | ||||
| -rw-r--r-- | plugins/pychrysa/pychrysa.c | 35 | 
7 files changed, 189 insertions, 63 deletions
| diff --git a/plugins/pychrysa/glibext/configuration.c b/plugins/pychrysa/glibext/configuration.c index 58eafb3..3ced957 100644 --- a/plugins/pychrysa/glibext/configuration.c +++ b/plugins/pychrysa/glibext/configuration.c @@ -1155,9 +1155,6 @@ bool register_python_generic_config(PyObject *module)      py_generic_config_type = get_python_generic_config_type(); -    if (PyType_Ready(py_generic_config_type) != 0) -        return false; -      dict = PyModule_GetDict(module);      if (!register_class_for_pygobject(dict, G_TYPE_GEN_CONFIG, py_generic_config_type, &PyGObject_Type)) diff --git a/plugins/pychrysa/gtkext/blockdisplay.c b/plugins/pychrysa/gtkext/blockdisplay.c index a329daf..c2ccfbb 100644 --- a/plugins/pychrysa/gtkext/blockdisplay.c +++ b/plugins/pychrysa/gtkext/blockdisplay.c @@ -66,7 +66,7 @@ PyTypeObject *get_python_block_display_type(void)          .tp_name        = "pychrysalide.gtkext.BlockDisplay",          .tp_basicsize   = sizeof(PyGObject), -        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, +        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,          .tp_doc         = "PyChrysalide block display.", @@ -78,12 +78,7 @@ PyTypeObject *get_python_block_display_type(void)      static PyTypeObject *result = NULL;      if (result == NULL) -    { -        result = calloc(1, sizeof(PyTypeObject)); - -        memcpy(result, &py_block_display_type, sizeof(PyTypeObject)); - -    } +        result = define_python_dynamic_type(&py_block_display_type);      return result; @@ -104,17 +99,17 @@ PyTypeObject *get_python_block_display_type(void)  bool register_python_block_display(PyObject *module)  { -    PyTypeObject *py_block_display_type;    /* Type Python 'BlockDisplay'     */ +    bool result;                            /* Bilan à retourner           */ +    PyTypeObject *py_block_display_type;    /* Type Python 'BlockDisplay'  */      PyObject *dict;                         /* Dictionnaire du module      */      py_block_display_type = get_python_block_display_type();      dict = PyModule_GetDict(module); -    if (!register_class_for_pygobject(dict, GTK_TYPE_BLOCK_DISPLAY, -                                      py_block_display_type, get_python_buffer_display_type())) -        return false; +    result = register_class_for_pygobject(dict, GTK_TYPE_BLOCK_DISPLAY, +                                          py_block_display_type, get_python_buffer_display_type()); -    return true; +    return result;  } diff --git a/plugins/pychrysa/gtkext/bufferdisplay.c b/plugins/pychrysa/gtkext/bufferdisplay.c index a6e5327..9aa1bca 100644 --- a/plugins/pychrysa/gtkext/bufferdisplay.c +++ b/plugins/pychrysa/gtkext/bufferdisplay.c @@ -66,7 +66,7 @@ PyTypeObject *get_python_buffer_display_type(void)          .tp_name        = "pychrysalide.gtkext.BufferDisplay",          .tp_basicsize   = sizeof(PyGObject), -        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, +        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,          .tp_doc         = "PyChrysalide buffer display.", @@ -78,12 +78,7 @@ PyTypeObject *get_python_buffer_display_type(void)      static PyTypeObject *result = NULL;      if (result == NULL) -    { -        result = calloc(1, sizeof(PyTypeObject)); - -        memcpy(result, &py_buffer_display_type, sizeof(PyTypeObject)); - -    } +        result = define_python_dynamic_type(&py_buffer_display_type);      return result; @@ -104,17 +99,17 @@ PyTypeObject *get_python_buffer_display_type(void)  bool register_python_buffer_display(PyObject *module)  { -    PyTypeObject *py_buffer_display_type;   /* Type Python 'Bufferdisplay'    */ +    bool result;                            /* Bilan à retourner           */ +    PyTypeObject *py_buffer_display_type;   /* Type Python 'BufferDisplay' */      PyObject *dict;                         /* Dictionnaire du module      */      py_buffer_display_type = get_python_buffer_display_type();      dict = PyModule_GetDict(module); -    if (!register_class_for_pygobject(dict, GTK_TYPE_BUFFER_DISPLAY, -                                      py_buffer_display_type, get_python_display_panel_type())) -        return false; +    result = register_class_for_pygobject(dict, GTK_TYPE_BUFFER_DISPLAY, +                                          py_buffer_display_type, get_python_display_panel_type()); -    return true; +    return result;  } diff --git a/plugins/pychrysa/gtkext/displaypanel.c b/plugins/pychrysa/gtkext/displaypanel.c index e857475..aa166e5 100644 --- a/plugins/pychrysa/gtkext/displaypanel.c +++ b/plugins/pychrysa/gtkext/displaypanel.c @@ -197,7 +197,7 @@ PyTypeObject *get_python_display_panel_type(void)          .tp_name        = "pychrysalide.gtkext.DisplayPanel",          .tp_basicsize   = sizeof(PyGObject), -        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, +        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,          .tp_doc         = "PyChrysalide view panel.", @@ -211,12 +211,7 @@ PyTypeObject *get_python_display_panel_type(void)      static PyTypeObject *result = NULL;      if (result == NULL) -    { -        result = calloc(1, sizeof(PyTypeObject)); - -        memcpy(result, &py_display_panel_type, sizeof(PyTypeObject)); - -    } +        result = define_python_dynamic_type(&py_display_panel_type);      return result; @@ -248,7 +243,9 @@ bool register_python_display_panel(PyObject *module)      py_display_panel_type = get_python_display_panel_type();      parent_mod = PyImport_ImportModule("gi.repository.Gtk"); -    if (parent_mod == NULL) return false; + +    if (parent_mod == NULL) +        goto rpdp_exit;      fixed = PyObject_GetAttrString(parent_mod, "Fixed"); @@ -258,7 +255,6 @@ bool register_python_display_panel(PyObject *module)      result = register_class_for_pygobject(dict, GTK_TYPE_DISPLAY_PANEL,                                            py_display_panel_type, (PyTypeObject *)fixed); -      Py_DECREF(fixed);      if (!result) diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c index a0a828f..17a396d 100644 --- a/plugins/pychrysa/helpers.c +++ b/plugins/pychrysa/helpers.c @@ -27,9 +27,15 @@  #include <assert.h>  #include <pygobject.h>  #include <stdarg.h> +#include <string.h> +/* ---------------------------------------------------------------------------------- */ +/*                        ACCELERATEURS POUR PYTHON UNIQUEMENT                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             *  *  Paramètres  : status = bilan de comparaison à traduire.                    * @@ -242,6 +248,126 @@ bool PyDict_AddStringConstant(PyTypeObject *obj_type, const char *key, const cha  } + +/* ---------------------------------------------------------------------------------- */ +/*                             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éé.     * @@ -259,6 +385,7 @@ bool PyDict_AddStringConstant(PyTypeObject *obj_type, const char *key, const cha  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      */ @@ -314,10 +441,33 @@ bool _register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *ty      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 true; +    return result;  } diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h index 9fb83d0..3eee6a0 100644 --- a/plugins/pychrysa/helpers.h +++ b/plugins/pychrysa/helpers.h @@ -31,6 +31,9 @@ +/* ---------------------- ACCELERATEURS POUR PYTHON UNIQUEMENT ---------------------- */ + +  /* Traduit pour Python le bilan d'une comparaison riche. */  PyObject *status_to_rich_cmp_state(int, int); @@ -54,6 +57,10 @@ bool PyDict_AddStringConstant(PyTypeObject *, const char *, const char *);  #define PyDict_AddStringMacro(tp, c) PyDict_AddStringConstant(tp, #c, c) + +/* --------------------------- CONFORTS CIBLANT PYGOBJECT --------------------------- */ + +  /**   * Quelque chose est mal fait au niveau de l'abstraction GObject.   * Du coup, Py_TPFLAGS_IS_ABSTRACT n'est pas pris en compte. @@ -64,6 +71,9 @@ bool PyDict_AddStringConstant(PyTypeObject *, const char *, const char *);  #define APPLY_ABSTRACT_FLAG(tp) tp->tp_new = PyBaseObject_Type.tp_new +/* Définit dans le tas de Python un nouveau type. */ +PyTypeObject *define_python_dynamic_type(const PyTypeObject *); +  /* Enregistre correctement une surcouche de conversion GObject. */  bool _register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObject *, ...); diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index f959671..bcd2284 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -332,7 +332,6 @@ static bool set_version_for_gtk_namespace(const char *version)  PyMODINIT_FUNC PyInit_pychrysalide(void)  {      PyObject *result;                       /* Module Python à retourner   */ -    PyObject *pygobj_mod;                   /* Module Python-GObject       */      bool status;                            /* Bilan des inclusions        */      static PyMethodDef py_chrysalide_methods[] = { @@ -370,8 +369,6 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)      }; - -  #if 0      do      { @@ -425,20 +422,6 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)          return NULL;      } -    /* Préparatifs préalables aux chargements */ - -    /** -     * Pour une raison non identifiée, si le module n'est pas préchargé, -     * le flot d'exécution plante dans la fonction insertdict() de Objects/dictobject.c:818. -     */ - -    pygobj_mod = PyImport_ImportModule("gi.repository.GObject"); -    if (pygobj_mod == NULL) -    { -        PyErr_SetString(PyExc_ImportError, "could not import gi.gobject"); -        return NULL; -    } -      /* Mise en place des fonctionnalités offertes */      result = PyModule_Create(&py_chrysalide_module); @@ -446,15 +429,15 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)      /* Interface 'LineGenerator' en premier... */      status = add_glibext_module_to_python_module(result); -    status &= register_python_plugin_module(result); -    status &= add_analysis_module_to_python_module(result); -    status &= add_arch_module_to_python_module(result); -    status &= add_common_module_to_python_module(result); -    status &= add_core_module_to_python_module(result); -    status &= add_debug_module_to_python_module(result); -    status &= add_format_module_to_python_module(result); -    status &= add_gtkext_module_to_python_module(result); -    status &= add_gui_module_to_python_module(result); +    if (status) status = register_python_plugin_module(result); +    if (status) status = add_analysis_module_to_python_module(result); +    if (status) status = add_arch_module_to_python_module(result); +    if (status) status = add_common_module_to_python_module(result); +    if (status) status = add_core_module_to_python_module(result); +    if (status) status = add_debug_module_to_python_module(result); +    if (status) status = add_format_module_to_python_module(result); +    if (status) status = add_gtkext_module_to_python_module(result); +    if (status) status = add_gui_module_to_python_module(result);      if (!status)      { | 
