From 6c898505ec8b018a32683feb7d5dc598390ec677 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 14 Feb 2021 00:03:54 +0100
Subject: Give access to the plugin interfaces from Python.

---
 plugins/pychrysalide/helpers.h           |  52 +++++++++++++++
 plugins/pychrysalide/plugins/Makefile.am |   3 +-
 plugins/pychrysalide/plugins/plugin.c    |  63 ++++++++++++++++++
 plugins/pychrysalide/plugins/translate.c | 110 +++++++++++++++++++++++++++++++
 plugins/pychrysalide/plugins/translate.h |  41 ++++++++++++
 5 files changed, 268 insertions(+), 1 deletion(-)
 create mode 100644 plugins/pychrysalide/plugins/translate.c
 create mode 100644 plugins/pychrysalide/plugins/translate.h

diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 72a5489..931be95 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -237,6 +237,58 @@ int convert_to_gdk_rgba(PyObject *, void *);
 /* ----------------------- TRANSFERT DES VALEURS CONSTANTES ------------------------- */
 
 
+/**
+ * Aides à la traduction.
+ */
+
+#define ADD_FIELD_TRANSLATION(dict, name, attrib)                   \
+    ({                                                              \
+        int __ret;                                                  \
+        bool __status;                                              \
+        __ret = PyDict_SetItemString(dict, name, attrib);           \
+        Py_DECREF(attrib);                                          \
+        __status = (__ret == 0);                                    \
+        __status;                                                   \
+    })
+
+
+#define TRANSLATE_BOOLEAN_FIELD(dict, base, field)                  \
+    ({                                                              \
+        PyObject *__attrib;                                         \
+        __attrib = (base->field ? Py_True : Py_False);              \
+        Py_INCREF(__attrib);                                        \
+        ADD_FIELD_TRANSLATION(dict, #field, __attrib);              \
+    })
+
+
+#define TRANSLATE_STRING_FIELD(dict, base, field)                   \
+    ({                                                              \
+        PyObject *__attrib;                                         \
+        if (base->field != NULL)                                    \
+            __attrib = PyUnicode_FromString(base->field);           \
+        else                                                        \
+        {                                                           \
+            __attrib = Py_None;                                     \
+            Py_INCREF(Py_None);                                     \
+        }                                                           \
+        ADD_FIELD_TRANSLATION(dict, #field, __attrib);              \
+    })
+
+
+#define TRANSLATE_ARRAY_FIELD(dict, base, field, array)             \
+    ({                                                              \
+        PyObject *__attrib;                                         \
+        bool __status;                                              \
+        __attrib = PyTuple_New(base->field ## _count);              \
+        __status = ADD_FIELD_TRANSLATION(dict, #field, __attrib);   \
+        if (__status)                                               \
+            (*array) = __attrib;                                    \
+        else                                                        \
+            (*array) = NULL;                                        \
+        __status;                                                   \
+    })
+
+
 /* Simplification d'un ajout de constante pour l'appelant */
 #define add_const_to_group(d, n, v)                         \
     ({                                                      \
diff --git a/plugins/pychrysalide/plugins/Makefile.am b/plugins/pychrysalide/plugins/Makefile.am
index 0ab8c15..8a0d4c9 100644
--- a/plugins/pychrysalide/plugins/Makefile.am
+++ b/plugins/pychrysalide/plugins/Makefile.am
@@ -4,7 +4,8 @@ noinst_LTLIBRARIES = libpychrysaplugins.la
 libpychrysaplugins_la_SOURCES =			\
 	constants.h constants.c				\
 	plugin.h plugin.c					\
-	module.h module.c
+	module.h module.c					\
+	translate.h translate.c
 
 libpychrysaplugins_la_LIBADD = 
 
diff --git a/plugins/pychrysalide/plugins/plugin.c b/plugins/pychrysalide/plugins/plugin.c
index c1cc794..bd9cdfe 100644
--- a/plugins/pychrysalide/plugins/plugin.c
+++ b/plugins/pychrysalide/plugins/plugin.c
@@ -40,6 +40,7 @@
 
 
 #include "constants.h"
+#include "translate.h"
 #include "../access.h"
 #include "../core.h"
 #include "../helpers.h"
@@ -148,6 +149,9 @@ static PyObject *py_plugin_module_get_modname(PyObject *, void *);
 /* Indique le fichier contenant le greffon manipulé. */
 static PyObject *py_plugin_module_get_filename(PyObject *, void *);
 
+/* Fournit la description du greffon dans son intégralité. */
+static PyObject *py_plugin_module_get_interface(PyObject *, void *);
+
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -1736,6 +1740,64 @@ static PyObject *py_plugin_module_get_filename(PyObject *self, void *closure)
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
+*  Description : Fournit la description du greffon dans son intégralité.      *
+*                                                                             *
+*  Retour      : Interfaçage renseigné.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_plugin_module_get_interface(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GPluginModule *plugin;                  /* Version native du greffon   */
+    const plugin_interface *iface;          /* Interface liée à traduire   */
+
+#define PLUGIN_MODULE_INTERFACE_ATTRIB PYTHON_GET_DEF_FULL      \
+(                                                               \
+    interface, py_plugin_module,                                \
+    "Interface exported by the plugin..\n"                      \
+    "\n"                                                        \
+    "This property is a pychrysalide.StructObject instance."    \
+    "\n"                                                        \
+    "The provided information is composed of the following"     \
+    " properties :\n"                                           \
+    "\n"                                                        \
+    "* gtp_name;\n"                                             \
+    "* name;\n"                                                 \
+    "* desc;\n"                                                 \
+    "* version;\n"                                              \
+    "* url;\n"                                                  \
+    "* container;\n"                                            \
+    "* required;\n"                                             \
+    "* actions.\n"                                              \
+    "\n"                                                        \
+    "The *gtp_name* value may be *None* for non-native plugin." \
+    " All other fields carry a string value except:\n"          \
+    "* *container*: a boolean status indicating if the plugin"  \
+    " can embed other plugins;\n"                               \
+    "* *required*: a tuple of depedencies names;\n"             \
+    "* *actions*: a tuple of available features from the plugin"\
+    " coded as pychrysalide.plugins.PluginModule.PluginAction"  \
+    " values."                                                  \
+)
+
+    plugin = G_PLUGIN_MODULE(pygobject_get(self));
+    iface = g_plugin_module_get_interface(plugin);
+
+    result = translate_plugin_interface_to_python(iface);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
 *  Description : Fournit la configuration mise en place pour le greffon.      *
 *                                                                             *
 *  Retour      : Configuration dédiée à l'extension.                          *
@@ -1821,6 +1883,7 @@ PyTypeObject *get_python_plugin_module_type(void)
     static PyGetSetDef py_plugin_module_getseters[] = {
         PLUGIN_MODULE_MODNAME_ATTRIB,
         PLUGIN_MODULE_FILENAME_ATTRIB,
+        PLUGIN_MODULE_INTERFACE_ATTRIB,
         PLUGIN_MODULE_CONFIG_ATTRIB,
         { NULL }
     };
diff --git a/plugins/pychrysalide/plugins/translate.c b/plugins/pychrysalide/plugins/translate.c
new file mode 100644
index 0000000..055788c
--- /dev/null
+++ b/plugins/pychrysalide/plugins/translate.c
@@ -0,0 +1,110 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * translate.c - conversion de structures liées aux greffons en objets Python
+ *
+ * Copyright (C) 2021 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "translate.h"
+
+
+#include <assert.h>
+
+
+#include "plugin.h"
+#include "../helpers.h"
+#include "../struct.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = ensemble d'informations à transcrire en Python.      *
+*                                                                             *
+*  Description : Traduit une description d'interface de greffon.              *
+*                                                                             *
+*  Retour      : Structure mise en place ou NULL en cas d'erreur.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyObject *translate_plugin_interface_to_python(const plugin_interface *iface)
+{
+    PyObject *result;                       /* Construction à retourner    */
+    PyTypeObject *base;                     /* Modèle d'objet à créer      */
+    bool status;                            /* Bilan d'une traduction      */
+    PyObject *array;                        /* Tableau à insérer           */
+    size_t i;                               /* Boucle de parcours          */
+    PyTypeObject *itype;                    /* Type d'élément à créer      */
+    PyObject *item;                         /* Elément mis en place        */
+
+    base = get_python_py_struct_type();
+
+    result = PyObject_CallFunction((PyObject *)base, NULL);
+    assert(result != NULL);
+
+    status = true;
+
+    if (status) status = TRANSLATE_STRING_FIELD(result, iface, gtp_name);
+    if (status) status = TRANSLATE_STRING_FIELD(result, iface, name);
+    if (status) status = TRANSLATE_STRING_FIELD(result, iface, desc);
+    if (status) status = TRANSLATE_STRING_FIELD(result, iface, version);
+    if (status) status = TRANSLATE_STRING_FIELD(result, iface, url);
+
+    if (status) status = TRANSLATE_BOOLEAN_FIELD(result, iface, container);
+
+    if (status) status = TRANSLATE_ARRAY_FIELD(result, iface, required, &array);
+
+    if (status)
+    {
+        itype = get_python_plugin_module_type();
+
+        for (i = 0; i < iface->required_count; i++)
+        {
+            item = PyUnicode_FromString(iface->required[i]);
+            PyTuple_SetItem(array, i, item);
+        }
+
+    }
+
+    if (status) status = TRANSLATE_ARRAY_FIELD(result, iface, actions, &array);
+
+    if (status)
+    {
+        itype = get_python_plugin_module_type();
+
+        for (i = 0; i < iface->actions_count; i++)
+        {
+            item = cast_with_constants_group_from_type(itype, "PluginAction", iface->actions[i]);
+            PyTuple_SetItem(array, i, item);
+        }
+
+    }
+
+    if (!status)
+    {
+        Py_DECREF(result);
+        result = NULL;
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/plugins/translate.h b/plugins/pychrysalide/plugins/translate.h
new file mode 100644
index 0000000..facffd2
--- /dev/null
+++ b/plugins/pychrysalide/plugins/translate.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * translate.h - prototypes pour la conversion de structures liées aux greffons en objets Python
+ *
+ * Copyright (C) 2021 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_PLUGINS_TRANSLATE_H
+#define _PLUGINS_PYCHRYSALIDE_PLUGINS_TRANSLATE_H
+
+
+#include <Python.h>
+
+
+#include <plugins/plugin-def.h>
+
+
+
+/* Traduit une description d'interface de greffon. */
+PyObject *translate_plugin_interface_to_python(const plugin_interface *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_PLUGINS_TRANSLATE_H */
-- 
cgit v0.11.2-87-g4458