summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/core.c')
-rw-r--r--plugins/pychrysalide/core.c298
1 files changed, 113 insertions, 185 deletions
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index 3c551c7..0fea9c4 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -24,24 +24,14 @@
#include "core.h"
-#include "core-int.h"
-
-
-
-
-
#undef NO_IMPORT_PYGOBJECT
#include <pygobject.h>
#define NO_IMPORT_PYGOBJECT
-#include "core.h"
-
-
#include <assert.h>
#include <errno.h>
#include <malloc.h>
-//#include <pygobject.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
@@ -60,10 +50,9 @@
#include <plugins/self.h>
-
-
#include "access.h"
#include "bindings.h"
+#include "core-int.h"
@@ -72,14 +61,6 @@ static bool _standalone = true;
-
-
-
-
-
-
-
-
/* ---------------------- COMPOSITION DE NOUVEAU GREFFON NATIF ---------------------- */
@@ -93,10 +74,10 @@ static void g_pychrysalide_plugin_plugin_manager_interface_init(GPluginManagerIn
static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *);
/* Supprime toutes les références externes. */
-static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_finalize(GObject *);
@@ -104,19 +85,16 @@ static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *);
/* Prend acte de l'activation du greffon. */
-static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *);
+static bool g_pychrysalide_plugin_enable(GPluginModule *);
/* Prend acte de la désactivation du greffon. */
-static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *);
+static bool g_pychrysalide_plugin_disable(GPluginModule *);
/* -------------------- INTERVENTION DANS LA GESTION DE GREFFONS -------------------- */
-/* Complète les chemins de recherches de Python. */
-static void extend_python_path(const char *);
-
/* Crée un greffon à partir de code Python. */
static GPluginModule *create_python_plugin(const char *, const char *);
@@ -124,7 +102,7 @@ static GPluginModule *create_python_plugin(const char *, const char *);
static void load_python_plugins(GPluginModule *);
/* Prend acte du chargement de l'ensemble des greffons natifs. */
-static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPluginManager *);
@@ -160,13 +138,13 @@ static void g_pychrysalide_plugin_class_init(GPyChrysalidePluginClass *class)
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_pychrysalide_plugin_dispose;
- object->finalize = (GObjectFinalizeFunc)g_pychrysalide_plugin_finalize;
+ object->dispose = g_pychrysalide_plugin_dispose;
+ object->finalize = g_pychrysalide_plugin_finalize;
plugin = G_PLUGIN_MODULE_CLASS(class);
- plugin->enable = (pg_management_fc)g_pychrysalide_plugin_enable;
- plugin->disable = (pg_management_fc)g_pychrysalide_plugin_disable;
+ plugin->enable = g_pychrysalide_plugin_enable;
+ plugin->disable = g_pychrysalide_plugin_disable;
}
@@ -185,7 +163,7 @@ static void g_pychrysalide_plugin_class_init(GPyChrysalidePluginClass *class)
static void g_pychrysalide_plugin_plugin_manager_interface_init(GPluginManagerInterface *iface)
{
- iface->handle_native = (handle_native_plugins_cb)g_pychrysalide_plugin_handle_native_plugins_loaded_event;
+ iface->handle_native = g_pychrysalide_plugin_handle_native_plugins_loaded_event;
}
@@ -213,7 +191,7 @@ static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *plugin)
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -223,16 +201,16 @@ static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_dispose(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->dispose(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -242,16 +220,16 @@ static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->finalize(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->finalize(object);
}
/******************************************************************************
* *
-* Paramètres : filename = nom du fichier à charger. *
+* Paramètres : module = extension vue du système. *
* *
* Description : Crée un module pour un greffon de support Python. *
* *
@@ -278,7 +256,7 @@ GPluginModule *g_pychrysalide_plugin_new(GModule *module)
/******************************************************************************
* *
* Paramètres : plugin = instance à initialiser pleinement. *
-* module = module système correspondant. *
+* module = extension vue du système. *
* *
* Description : Met en place un module pour un greffon de support Python. *
* *
@@ -306,68 +284,6 @@ bool g_pychrysalide_plugin_create(GPyChrysalidePlugin *plugin, GModule *module)
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = greffon à manipuler. *
-* action = type d'action attendue. *
-* type = type d'objet à mettre en place. *
-* *
-* Description : Crée une instance à partir d'un type dynamique externe. *
-* *
-* Retour : Instance d'objet gérée par l'extension ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *plugin, PluginAction action, GType type)
-{
- gpointer result; /* Instance à retourner */
- PyGILState_STATE gstate; /* Sauvegarde d'environnement */
- PyTypeObject *pytype; /* Classe Python concernée */
- PyObject *instance; /* Initialisation forcée */
-
- result = NULL;
-
- gstate = PyGILState_Ensure();
-
- pytype = pygobject_lookup_class(type);
-
- if (pytype != NULL)
- {
- instance = PyObject_CallObject((PyObject *)pytype, NULL);
- assert(instance != NULL);
-
- result = pygobject_get(instance);
-
- }
-
- PyGILState_Release(gstate);
-
- return result;
-
-}
-
-#endif
-
-
-
-
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
/* ---------------------------------------------------------------------------------- */
@@ -385,22 +301,24 @@ G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *pl
* *
******************************************************************************/
-static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
+static bool g_pychrysalide_plugin_enable(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
+ GPyChrysalidePlugin *pychr_plugin; /* Version spécialisée */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
int ret; /* Bilan de préparatifs */
_standalone = false;
+ pychr_plugin = G_PYCHRYSALIDE_PLUGIN(plugin);
+
/* Chargement du module pour Python */
ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide);
if (ret == -1)
{
- g_plugin_module_log_simple_message(G_PLUGIN_MODULE(plugin),
- LMT_ERROR,
+ g_plugin_module_log_simple_message(plugin, LMT_ERROR,
_("Can not extend the existing table of Python built-in modules."));
result = false;
@@ -412,7 +330,7 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
gstate = PyGILState_Ensure();
- plugin->py_module = PyImport_ImportModule("pychrysalide");
+ pychr_plugin->py_module = PyImport_ImportModule("pychrysalide");
/**
* Pour mémoire, une situation concrête conduisant à un échec :
@@ -427,7 +345,7 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
// TODO : check (2025)
- result = (plugin->py_module != NULL);
+ result = (pychr_plugin->py_module != NULL);
PyGILState_Release(gstate);
@@ -450,58 +368,66 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin)
+static bool g_pychrysalide_plugin_disable(GPluginModule *plugin)
{
+ bool result; /* Bilan à retourner */
+ GPyChrysalidePlugin *pychr_plugin; /* Version spécialisée */
+ bool standalone; /* Nature du chargement */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
- gstate = PyGILState_Ensure();
+ result = true;
- clear_all_accesses_to_python_modules();
-
- Py_XDECREF(plugin->py_module);
- plugin->py_module = NULL;
-
- PyGILState_Release(gstate);
-
-}
+ pychr_plugin = G_PYCHRYSALIDE_PLUGIN(plugin);
+ /**
+ * Le champ plugin->py_module n'est défini que via la fonction
+ * g_pychrysalide_plugin_enable(), qui n'est pas sollicitée lorsque
+ * le module PyChrysalide est mis en place directement par Python.
+ *
+ * L'analyse de ce champ pour retrouver la situation courante est
+ * plus fiable que celle du champ _standalone, potentiellement
+ * cohérent dans la version UI du greffon et resté à son état
+ * initial ici.
+ */
+ standalone = (pychr_plugin->py_module == NULL);
-/* ---------------------------------------------------------------------------------- */
-/* INTERVENTION DANS LA GESTION DE GREFFONS */
-/* ---------------------------------------------------------------------------------- */
+ /**
+ * Si on se trouve embarqué dans un interpréteur Python, le déchargement
+ * des greffons est organisé à partir de la fonction PyExit_pychrysalide(),
+ * directement appelée depuis un contexte Python.
+ *
+ * Un verrou n'est alors pas souhaité ici :
+ *
+ * python3d: ../Python/pystate.c:1687: PyGILState_Ensure: Assertion `gilstate->autoInterpreterState' failed.
+ *
+ * Avec :
+ *
+ * $ python3d --version
+ * Python 3.11.2
+ *
+ */
+ if (!standalone)
+ gstate = PyGILState_Ensure();
-/******************************************************************************
-* *
-* Paramètres : path = chemin supplémentaire pour l'espace de recherche. *
-* *
-* Description : Complète les chemins de recherches de Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ clear_all_accesses_to_python_modules();
-static void extend_python_path(const char *path)
-{
- PyObject *list; /* Liste de chemins à compléter*/
- PyObject *new; /* Nouveau chemin à intégrer */
+ Py_XDECREF(pychr_plugin->py_module);
+ pychr_plugin->py_module = NULL;
- list = PySys_GetObject("path");
- assert(list != NULL);
+ if (!standalone)
+ PyGILState_Release(gstate);
- new = PyUnicode_FromString(path);
- assert(new != NULL);
+ return result;
- PyList_Append(list, new);
+}
- Py_DECREF(new);
- add_to_env_var("PYTHONPATH", path, ":");
-}
+/* ---------------------------------------------------------------------------------- */
+/* INTERVENTION DANS LA GESTION DE GREFFONS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -593,48 +519,18 @@ static GPluginModule *create_python_plugin(const char *modname, const char *file
static void load_python_plugins(GPluginModule *plugin)
{
-#ifdef DISCARD_LOCAL
- char *edir; /* Répertoire de base effectif */
-#endif
- DIR *dir; /* Répertoire à parcourir */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
char *paths; /* Emplacements de greffons */
char *save; /* Sauvegarde pour ré-entrance */
char *path; /* Chemin à fouiller */
+ DIR *dir; /* Répertoire à parcourir */
struct dirent *entry; /* Elément trouvé */
char *modname; /* Nom du module pour Python */
char *filename; /* Chemin d'accès reconstruit */
GPluginModule *pyplugin; /* Lien vers un grffon Python */
bool status; /* Bilan d'une opération */
- /* Définition des zones d'influence */
-
-#ifndef DISCARD_LOCAL
-
- extend_python_path(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "python");
-
-#else
-
- edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
-
- dir = opendir(edir);
-
- if (dir != NULL)
- {
- closedir(dir);
-
- extend_python_path(edir);
-
- }
-
- free(edir);
-
-#endif
-
- g_plugin_module_log_variadic_message(plugin, LMT_INFO,
- _("PYTHONPATH environment variable set to '%s'"),
- getenv("PYTHONPATH"));
-
- /* Chargements des extensions Python */
+ gstate = PyGILState_Ensure();
paths = get_env_var("PYTHONPATH");
@@ -647,7 +543,7 @@ static void load_python_plugins(GPluginModule *plugin)
dir = opendir(path);
if (dir == NULL)
{
- perror("opendir");
+ LOG_ERROR_N("opendir");
continue;
}
@@ -664,7 +560,7 @@ static void load_python_plugins(GPluginModule *plugin)
if (entry == NULL)
{
if (errno != 0)
- perror("readdir");
+ LOG_ERROR_N("readdir");
break;
@@ -728,12 +624,14 @@ static void load_python_plugins(GPluginModule *plugin)
free(paths);
+ PyGILState_Release(gstate);
+
}
/******************************************************************************
* *
-* Paramètres : plugin = interface à manipuler. *
+* Paramètres : manager = interface à manipuler. *
* *
* Description : Accompagne la fin du chargement des modules natifs. *
* *
@@ -743,15 +641,43 @@ static void load_python_plugins(GPluginModule *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPluginManager *manager)
{
- PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ GPluginModule *plugin; /* Version de base du greffon */
+#ifdef DISCARD_LOCAL
+ char *edir; /* Répertoire de base effectif */
+ DIR *dir; /* Répertoire à parcourir */
+#endif
- gstate = PyGILState_Ensure();
+ plugin = G_PLUGIN_MODULE(manager);
- load_python_plugins(G_PLUGIN_MODULE(plugin));
+ /* Définition des zones d'influence */
- PyGILState_Release(gstate);
+#ifndef DISCARD_LOCAL
+
+ extend_python_path(plugin, PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "python");
+
+#else
+
+ edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+
+ dir = opendir(edir);
+
+ if (dir != NULL)
+ {
+ closedir(dir);
+
+ extend_python_path(plugin, edir);
+
+ }
+
+ free(edir);
+
+#endif
+
+ /* Chargements des extensions Python */
+
+ load_python_plugins(plugin);
}
@@ -781,7 +707,9 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
details.standalone = _standalone;
+ details.add_extra = NULL;
details.populate_extra = NULL;
+ details.create_self = g_pychrysalide_plugin_new;
result = init_python_pychrysalide_module(&details);