diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2023-05-20 22:22:47 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2023-05-20 22:22:47 (GMT) | 
| commit | d7ede72c4351b11c064ccfee7036c7d8461ad2e8 (patch) | |
| tree | f7f23ae8a19e9267385054c1d2f9a8deecda8a8a /plugins | |
| parent | 4293dfb9d679799fc46240436636fdcd431bccad (diff) | |
Simplify the Python plugins interface by deleting one of the relative GLib type.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/pychrysalide/core.c | 6 | ||||
| -rw-r--r-- | plugins/pychrysalide/helpers.h | 29 | ||||
| -rw-r--r-- | plugins/pychrysalide/plugins/plugin.c | 592 | ||||
| -rw-r--r-- | plugins/pychrysalide/plugins/plugin.h | 32 | 
4 files changed, 250 insertions, 409 deletions
| diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index d4f2292..c3a6cf2 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -312,7 +312,7 @@ static bool install_metaclass_for_python_gobjects(void)      /**       * Les extensions Python sont chargées à partir de la fonction load_python_plugins(), -     * qui fait appel à g_python_plugin_new(). Une instance y est construite via un +     * qui fait appel à create_python_plugin(). Une instance y est construite via un       * appel à PyObject_CallFunction() avec la classe spécifiée par l'alias AutoLoad       * dans le fichier __init__.py présent dans chaque module d'extension.       * @@ -862,7 +862,7 @@ static void load_python_plugins(GPluginModule *plugin)              filename = stradd(filename, G_DIR_SEPARATOR_S);              filename = stradd(filename, entry->d_name); -            pyplugin = g_python_plugin_new(modname, filename); +            pyplugin = create_python_plugin(modname, filename);              if (pyplugin == NULL)              { @@ -1227,7 +1227,7 @@ void log_pychrysalide_exception(const char *prefix, ...)           *           * C'est par exemple le cas quand un greffon Python ne peut se lancer           * correctement ; l'exception est alors levée à partir de la fonction -         * g_python_plugin_new() et le plantage intervient en sortie d'exécution, +         * create_python_plugin() et le plantage intervient en sortie d'exécution,           * au moment de la libération de l'extension Python :           *           *    ==14939== Jump to the invalid address stated on the next line diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h index 348c110..c9cc098 100644 --- a/plugins/pychrysalide/helpers.h +++ b/plugins/pychrysalide/helpers.h @@ -87,26 +87,21 @@ bool register_python_module_object(PyObject *, PyTypeObject *);          #name "(" args ")\n--\n\n" doc                  \      } -#define PYTHON_VOID_WRAPPER_DEF(name, args, flags, doc) \ -    {                                                   \ -        #name, (PyCFunction)py_return_none,             \ -        flags,                                          \ -        #name "(" args ")\n--\n\n" doc                  \ +#define PYTHON_WRAPPER_DEF_WITH(name, args, flags, defcb, doc)  \ +    {                                                           \ +        #name, (PyCFunction)defcb,                              \ +        flags,                                                  \ +        #name "(" args ")\n--\n\n" doc                          \      } -#define PYTHON_FALSE_WRAPPER_DEF(name, args, flags, doc)\ -    {                                                   \ -        #name, (PyCFunction)py_return_false,            \ -        flags,                                          \ -        #name "(" args ")\n--\n\n" doc                  \ -    } +#define PYTHON_VOID_WRAPPER_DEF(name, args, flags, doc) \ +    PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_none, doc) -#define PYTHON_TRUE_WRAPPER_DEF(name, args, flags, doc)\ -    {                                                   \ -        #name, (PyCFunction)py_return_true,             \ -        flags,                                          \ -        #name "(" args ")\n--\n\n" doc                  \ -    } +#define PYTHON_FALSE_WRAPPER_DEF(name, args, flags, doc) \ +    PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_false, doc) + +#define PYTHON_TRUE_WRAPPER_DEF(name, args, flags, doc) \ +    PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_true, doc)  /**   * Il ne semble pas exister de moyen de déterminer diff --git a/plugins/pychrysalide/plugins/plugin.c b/plugins/pychrysalide/plugins/plugin.c index a87d0a6..06bbd83 100644 --- a/plugins/pychrysalide/plugins/plugin.c +++ b/plugins/pychrysalide/plugins/plugin.c @@ -51,21 +51,29 @@  /* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ -/* Accompagne la création d'une instance dérivée en Python. */ -static PyObject *py_plugin_module_new(PyTypeObject *, PyObject *, PyObject *); -  /* Initialise la classe des greffons d'extension. */  static void py_plugin_module_init_gclass(GPluginModuleClass *, gpointer); +CREATE_DYN_ABSTRACT_CONSTRUCTOR(plugin_module, G_TYPE_PLUGIN_MODULE, py_plugin_module_init_gclass); +  /* Initialise une instance sur la base du dérivé de GObject. */  static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds);  /* Encadre une étape de la vie d'un greffon. */  static bool py_plugin_module_manage_wrapper(GPluginModule *); +/* Assiste la désactivation d'un greffon. */ +static bool py_plugin_module_exit(GPluginModule *); +  /* Accompagne la fin du chargement des modules natifs. */  static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *, PluginAction); +/* Fournit le nom brut associé au greffon par défaut. */ +static PyObject *py_plugin_module_get_modname_by_default(PyObject *, PyObject *); + +/* Fournit le nom brut associé au greffon. */ +static char *py_plugin_module_get_modname_wrapper(const GPluginModule *); +  #ifdef HAVE_GTK_SUPPORT  /* Complète une liste de resources pour thème. */ @@ -102,42 +110,6 @@ static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule * -/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */ - - -/* Ligne de représentation de code binaire (instance) */ -struct _GPythonPlugin -{ -    GPluginModule parent;                   /* Instance parente            */ - -}; - - -/* Ligne de représentation de code binaire (classe) */ -struct _GPythonPluginClass -{ -    GPluginModuleClass parent;              /* Classe parente              */ - -}; - - -/* Initialise la classe des greffons Python. */ -static void g_python_plugin_class_init(GPythonPluginClass *); - -/* Initialise l'instance d'un greffon Python. */ -static void g_python_plugin_init(GPythonPlugin *); - -/* Supprime toutes les références externes. */ -static void g_python_plugin_dispose(GPythonPlugin *); - -/* Description : Procède à la libération totale de la mémoire. */ -static void g_python_plugin_finalize(GPythonPlugin *); - -/* Fournit le nom brut associé au greffon. */ -static char *g_python_plugin_get_modname(const GPythonPlugin *); - - -  /* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */ @@ -165,69 +137,6 @@ static PyObject *py_plugin_module_get_interface(PyObject *, void *);  /******************************************************************************  *                                                                             * -*  Paramètres  : type = type du nouvel objet à mettre en place.               * -*                args = éventuelle liste d'arguments.                         * -*                kwds = éventuel dictionnaire de valeurs mises à disposition. * -*                                                                             * -*  Description : Accompagne la création d'une instance dérivée en Python.     * -*                                                                             * -*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static PyObject *py_plugin_module_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ -    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   */ - -    /* Validations diverses */ - -    base = get_python_plugin_module_type(); - -    if (type == base) -    { -        result = NULL; -        PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name); -        goto exit; -    } - -    /* Mise en place d'un type dédié */ - -    first_time = (g_type_from_name(type->tp_name) == 0); - -    gtype = build_dynamic_type(G_TYPE_PYTHON_PLUGIN, type->tp_name, -                               (GClassInitFunc)py_plugin_module_init_gclass, NULL, NULL); - -    if (first_time) -    { -        status = register_class_for_dynamic_pygobject(gtype, type, base); - -        if (!status) -        { -            result = NULL; -            goto exit; -        } - -    } - -    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ - -    result = PyType_GenericNew(type, args, kwds); - - exit: - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : class  = classe à initialiser.                               *  *                unused = données non utilisées ici.                          *  *                                                                             * @@ -243,10 +152,12 @@ static void py_plugin_module_init_gclass(GPluginModuleClass *class, gpointer unu  {      class->init = NULL;      class->manage = py_plugin_module_manage_wrapper; -    class->exit = NULL; +    class->exit = py_plugin_module_exit;      class->plugins_loaded = py_plugin_module_notify_plugins_loaded_wrapper; +    class->get_modname = py_plugin_module_get_modname_wrapper; +  #ifdef HAVE_GTK_SUPPORT      class->include_theme = py_plugin_module_include_theme_wrapper;      class->notify_panel = py_plugin_module_notify_panel_creation_wrapper; @@ -504,6 +415,51 @@ static bool py_plugin_module_manage_wrapper(GPluginModule *plugin)  /******************************************************************************  *                                                                             *  *  Paramètres  : plugin = greffon à manipuler.                                * +*                                                                             * +*  Description : Assiste la désactivation d'un greffon.                       * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool py_plugin_module_exit(GPluginModule *plugin) +{ +    bool result;                            /* Bilan à faire remonter      */ +    plugin_interface *final;                /* Interface finale conservée  */ + +    result = true; + +    final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface; + +    if (final != NULL) +    { +        if (final->name != NULL) free(final->name); +        if (final->desc != NULL) free(final->desc); +        if (final->version != NULL) free(final->version); +        if (final->url != NULL) free(final->url); + +        assert(final->required_count == 1); + +        if (final->required != NULL) +            free(final->required); + +        if (final->actions != NULL) +            free(final->actions); + +        free(final); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à manipuler.                                *  *                action = type d'action attendue.                             *  *                                                                             *  *  Description : Accompagne la fin du chargement des modules natifs.          * @@ -559,6 +515,98 @@ static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *plugin  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = objet Python concerné par l'appel.                    * +*                args = arguments fournis à l'appel.                          * +*                                                                             * +*  Description : Fournit le nom brut associé au greffon par défaut.           * +*                                                                             * +*  Retour      : Désignation brute du greffon.                                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_plugin_module_get_modname_by_default(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Bilan à retourner           */ +    GPluginModule *plugin;                  /* Version native du greffon   */ +    char *path;                             /* Chemin à traiter            */ + +    plugin = G_PLUGIN_MODULE(pygobject_get(self)); + +    path = strdup(g_plugin_module_get_filename(plugin)); + +    result = PyUnicode_FromString(basename(path)); + +    free(path); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à valider.                                  * +*                                                                             * +*  Description : Fournit le nom brut associé au greffon.                      * +*                                                                             * +*  Retour      : Désignation brute du greffon.                                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *py_plugin_module_get_modname_wrapper(const GPluginModule *plugin) +{ +    char *result;                           /* Désignation brute à renvoyer*/ +    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */ +    PyObject *pyobj;                        /* Objet Python concerné       */ +    PyObject *pyret;                        /* Bilan d'exécution           */ + +#define PLUGIN_MODULE_GET_MODNAME_WRAPPER PYTHON_WRAPPER_DEF_WITH       \ +(                                                                       \ +    _get_modname, "$self, /",                                           \ +    METH_VARARGS, py_plugin_module_get_modname_by_default,              \ +    "(Abstract) method providing the raw module name of the plugin.\n"  \ +    " loaded.\n"                                                        \ +    "\n"                                                                \ +    "The result should be a short string value.\n"                      \ +    "\n"                                                                \ +    "A default implementation builds the module name from the Python"   \ +    " script filename."                                                 \ +) + +    gstate = PyGILState_Ensure(); + +    pyobj = pygobject_new(G_OBJECT(plugin)); + +    if (has_python_method(pyobj, "_get_modname")) +    { +        pyret = run_python_method(pyobj, "_get_modname", NULL); + +        if (!PyUnicode_Check(pyret)) +            g_plugin_module_log_variadic_message(plugin, LMT_ERROR, +                                                 _("The returned raw name must be a string")); + +        else +            result = strdup(PyUnicode_DATA(pyret)); + +        Py_XDECREF(pyret); + +    } + +    Py_DECREF(pyobj); + +    PyGILState_Release(gstate); + +    return result; + +} + +  #ifdef HAVE_GTK_SUPPORT @@ -1312,262 +1360,6 @@ static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule *  /* ---------------------------------------------------------------------------------- */ -/*                       INTERFACE INTERNE POUR GREFFONS PYTHON                       */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini par la GLib pour le greffon Python. */ -G_DEFINE_TYPE(GPythonPlugin, g_python_plugin, G_TYPE_PLUGIN_MODULE); - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : klass = classe à initialiser.                                * -*                                                                             * -*  Description : Initialise la classe des greffons Python.                    * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_python_plugin_class_init(GPythonPluginClass *klass) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ -    GPluginModuleClass *plugin;             /* Version parente de la classe*/ - -    object = G_OBJECT_CLASS(klass); - -    object->dispose = (GObjectFinalizeFunc/* ! */)g_python_plugin_dispose; -    object->finalize = (GObjectFinalizeFunc)g_python_plugin_finalize; - -    plugin = G_PLUGIN_MODULE_CLASS(klass); - -    plugin->get_modname = (pg_get_modname_fc)g_python_plugin_get_modname; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : plugin = instance à initialiser.                             * -*                                                                             * -*  Description : Initialise l'instance d'un greffon Python.                   * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_python_plugin_init(GPythonPlugin *plugin) -{ - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : plugin = instance d'objet GLib à traiter.                    * -*                                                                             * -*  Description : Supprime toutes les références externes.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_python_plugin_dispose(GPythonPlugin *plugin) -{ -#if 0 -    PyThreadState *tstate;                  /* Contexte d'environnement    */ - -    /** -     * Cf. https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock -     * -     * Cependant, comme on se trouve à priori dans le thread principal de l'interpréteur, -     * PyGILState_Ensure() ne pose aucun verrou. Ce qui aboutit à la situation suivante : -     * -     *    Fatal Python error: drop_gil: GIL is not locked -     * -     * On peut forcer les choses avec PyEval_AcquireLock(), mais cette fonction est marquée -     * comme dépréciée depuis Python 3.2. -     * -     * Donc on choisit les alternatives officielles. -     * -     * Cependant, PyThreadState_Get() renvoit l'erreur suivante : -     * -     *    Fatal Python error: PyThreadState_Get: no current thread -     * -     * Donc on se rabat sur une sauvegarde, qui n'est initialisée que lorsque l'interpréteur -     * est intégré dans l'éditeur. -     */ - -    tstate = get_pychrysalide_main_tstate(); - -    if (tstate != NULL) -        PyEval_RestoreThread(tstate); - -    if (tstate != NULL) -        PyEval_SaveThread(); -#endif - -    G_OBJECT_CLASS(g_python_plugin_parent_class)->dispose(G_OBJECT(plugin)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : plugin = instance d'objet GLib à traiter.                    * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_python_plugin_finalize(GPythonPlugin *plugin) -{ -    plugin_interface *final;                /* Interface finale conservée  */ - -    final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface; - -    if (final != NULL) -    { -        if (final->name != NULL) free(final->name); -        if (final->desc != NULL) free(final->desc); -        if (final->version != NULL) free(final->version); -        if (final->url != NULL) free(final->url); - -        assert(final->required_count == 1); - -        if (final->required != NULL) -            free(final->required); - -        if (final->actions != NULL) -            free(final->actions); - -        free(final); - -    } - -    G_OBJECT_CLASS(g_python_plugin_parent_class)->finalize(G_OBJECT(plugin)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : plugin = greffon à valider.                                  * -*                                                                             * -*  Description : Fournit le nom brut associé au greffon.                      * -*                                                                             * -*  Retour      : Désignation brute du greffon.                                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static char *g_python_plugin_get_modname(const GPythonPlugin *plugin) -{ -    char *result;                           /* Désignation brute à renvoyer*/ -    char *path;                             /* Chemin à traiter            */ - -    path = strdup(g_plugin_module_get_filename(G_PLUGIN_MODULE(plugin))); - -    result = strdup(basename(path)); - -    free(path); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : modname  = nom du module à charger.                          * -*                filename = chemin d'accès au code Python à charger.          * -*                                                                             * -*  Description : Crée un greffon à partir de code Python.                     * -*                                                                             * -*  Retour      : Adresse de la structure mise en place ou NULL si erreur.     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GPluginModule *g_python_plugin_new(const char *modname, const char *filename) -{ -    GPythonPlugin *result;                  /* Structure à retourner       */ -    PyObject *name;                         /* Chemin d'accès pour Python  */ -    PyObject *module;                       /* Script Python chargé        */ -    PyObject *dict;                         /* Dictionnaire associé        */ -    PyObject *class;                        /* Classe à instancier         */ -    PyObject *instance;                     /* Instance Python du greffon  */ - -    name = PyUnicode_FromString(modname); -    if (name == NULL) goto bad_exit; - -    module = PyImport_Import(name); -    Py_DECREF(name); - -    if (module == NULL) goto no_import; - -    dict = PyModule_GetDict(module); -    class = PyDict_GetItemString(dict, "AutoLoad"); - -    if (class == NULL) goto no_class; -    if (!PyType_Check(class->ob_type)) goto no_class; - -    instance = PyObject_CallFunction(class, NULL); -    if (instance == NULL) goto no_instance; - -    result = G_PYTHON_PLUGIN(pygobject_get(instance)); - -    G_PLUGIN_MODULE(result)->filename = strdup(filename); - -    /** -     * L'instance Python et l'objet GLib résultante sont un même PyGObject. -     * -     * Donc pas besoin de toucher au comptage des références ici, la libération -     * se réalisera à la fin, quand l'objet GLib sera libéré. -     */ - -    Py_DECREF(module); - -    return G_PLUGIN_MODULE(result); - - no_instance: - -    log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance")); - - no_class: - -    if (class == NULL) -        log_plugin_simple_message(LMT_ERROR, -                                  _("An error occured when looking for the 'AutoLoad': item not found!")); - - no_import: - -    Py_XDECREF(module); - -    log_pychrysalide_exception(_("An error occured when importing '%s'"), modname); - - bad_exit: - -    return NULL; - -} - - - -/* ---------------------------------------------------------------------------------- */  /*                           MODULE PYTHON POUR LES SCRIPTS                           */  /* ---------------------------------------------------------------------------------- */ @@ -1877,6 +1669,7 @@ PyTypeObject *get_python_plugin_module_type(void)      static PyMethodDef py_plugin_module_methods[] = {          PLUGIN_MODULE_MANAGE_WRAPPER,          PLUGIN_MODULE_NOTIFY_PLUGINS_LOADED_WRAPPER, +        PLUGIN_MODULE_GET_MODNAME_WRAPPER,  #ifdef HAVE_GTK_SUPPORT          PLUGIN_MODULE_INCLUDE_THEME_WRAPPER,          PLUGIN_MODULE_ON_PANEL_CREATION_WRAPPER, @@ -1952,7 +1745,7 @@ bool ensure_python_plugin_module_is_registered(void)          dict = PyModule_GetDict(module); -        if (!register_class_for_pygobject(dict, G_TYPE_PYTHON_PLUGIN, type, &PyGObject_Type)) +        if (!register_class_for_pygobject(dict, G_TYPE_PLUGIN_MODULE, type, &PyGObject_Type))              return false;          if (!define_plugin_module_constants(type)) @@ -1963,3 +1756,82 @@ bool ensure_python_plugin_module_is_registered(void)      return true;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : modname  = nom du module à charger.                          * +*                filename = chemin d'accès au code Python à charger.          * +*                                                                             * +*  Description : Crée un greffon à partir de code Python.                     * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL si erreur.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GPluginModule *create_python_plugin(const char *modname, const char *filename) +{ +    GPluginModule *result;                  /* Structure à retourner       */ +    PyObject *name;                         /* Chemin d'accès pour Python  */ +    PyObject *module;                       /* Script Python chargé        */ +    PyObject *dict;                         /* Dictionnaire associé        */ +    PyObject *class;                        /* Classe à instancier         */ +    PyObject *instance;                     /* Instance Python du greffon  */ + +    name = PyUnicode_FromString(modname); +    if (name == NULL) goto bad_exit; + +    module = PyImport_Import(name); +    Py_DECREF(name); + +    if (module == NULL) goto no_import; + +    dict = PyModule_GetDict(module); +    class = PyDict_GetItemString(dict, "AutoLoad"); + +    if (class == NULL) goto no_class; +    if (!PyType_Check(class->ob_type)) goto no_class; + +    Py_INCREF(class); + +    instance = PyObject_CallFunction(class, NULL); +    if (instance == NULL) goto no_instance; + +    result = G_PLUGIN_MODULE(pygobject_get(instance)); + +    result->filename = strdup(filename); + +    /** +     * L'instance Python et l'objet GLib résultante sont un même PyGObject. +     * +     * Donc pas besoin de toucher au comptage des références ici, la libération +     * se réalisera à la fin, quand l'objet GLib sera libéré. +     */ + +    Py_DECREF(module); + +    return result; + + no_instance: + +    log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance")); + + no_class: + +    if (class == NULL) +        log_plugin_simple_message(LMT_ERROR, +                                  _("An error occured when looking for the 'AutoLoad': item not found!")); + + no_import: + +    Py_XDECREF(module); + +    log_pychrysalide_exception(_("An error occured when importing '%s'"), modname); + + bad_exit: + +    return NULL; + +} diff --git a/plugins/pychrysalide/plugins/plugin.h b/plugins/pychrysalide/plugins/plugin.h index ff805f4..ad54b8e 100644 --- a/plugins/pychrysalide/plugins/plugin.h +++ b/plugins/pychrysalide/plugins/plugin.h @@ -35,41 +35,15 @@ -/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */ - - -#define G_TYPE_PYTHON_PLUGIN                (g_python_plugin_get_type()) -#define G_PYTHON_PLUGIN(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PYTHON_PLUGIN, GPythonPlugin)) -#define G_IS_PYTHON_PLUGIN(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PYTHON_PLUGIN)) -#define G_PYTHON_PLUGIN_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PYTHON_PLUGIN, GPythonPluginClass)) -#define G_IS_PYTHON_PLUGIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PYTHON_PLUGIN)) -#define G_PYTHON_PLUGIN_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PYTHON_PLUGIN, GPythonPluginClass)) - - -/* Ligne de représentation de code binaire (instance) */ -typedef struct _GPythonPlugin GPythonPlugin; - -/* Ligne de représentation de code binaire (classe) */ -typedef struct _GPythonPluginClass GPythonPluginClass; - - -/* Indique le type défini par la GLib pour le greffon Python. */ -GType g_python_plugin_get_type(void); - -/* Crée un greffon à partir de code Python. */ -GPluginModule *g_python_plugin_new(const char *, const char *); - - - -/* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */ - -  /* Fournit un accès à une définition de type à diffuser. */  PyTypeObject *get_python_plugin_module_type(void);  /* Prend en charge l'objet 'pychrysalide.plugins.PluginModule'. */  bool ensure_python_plugin_module_is_registered(void); +/* Crée un greffon à partir de code Python. */ +GPluginModule *create_python_plugin(const char *, const char *); +  #endif  /* _PLUGINS_PYCHRYSALIDE_PLUGINS_PLUGIN_H */ | 
