diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2021-02-07 23:18:18 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2021-02-07 23:18:18 (GMT) | 
| commit | 3071d472057feb974bd5167d3a3ef9297b602b26 (patch) | |
| tree | 3b8617cb2aaa91184853903f76d54a4f4c8040bc /plugins | |
| parent | 42540e681161aab0a1c27c66541ed5dc833ca411 (diff) | |
Extended the Python API to list plugins.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/pychrysalide/plugins/constants.c | 47 | ||||
| -rw-r--r-- | plugins/pychrysalide/plugins/constants.h | 3 | ||||
| -rw-r--r-- | plugins/pychrysalide/plugins/module.c | 201 | 
3 files changed, 249 insertions, 2 deletions
diff --git a/plugins/pychrysalide/plugins/constants.c b/plugins/pychrysalide/plugins/constants.c index 9de044a..8791d91 100644 --- a/plugins/pychrysalide/plugins/constants.c +++ b/plugins/pychrysalide/plugins/constants.c @@ -98,3 +98,50 @@ bool define_plugin_module_constants(PyTypeObject *type)      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : arg = argument quelconque à tenter de convertir.             * +*                dst = destination des valeurs récupérées en cas de succès.   * +*                                                                             * +*  Description : Tente de convertir en constante PluginAction.                * +*                                                                             * +*  Retour      : Bilan de l'opération, voire indications supplémentaires.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int convert_to_plugin_action(PyObject *arg, void *dst) +{ +    int result;                             /* Bilan à retourner           */ +    unsigned long value;                    /* Valeur récupérée            */ + +    result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type); + +    switch (result) +    { +        case -1: +            /* L'exception est déjà fixée par Python */ +            result = 0; +            break; + +        case 0: +            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to PluginAction"); +            break; + +        case 1: +            value = PyLong_AsUnsignedLong(arg); +            *((PluginAction *)dst) = value; +            break; + +        default: +            assert(false); +            break; + +    } + +    return result; + +} diff --git a/plugins/pychrysalide/plugins/constants.h b/plugins/pychrysalide/plugins/constants.h index 71abcff..56612c9 100644 --- a/plugins/pychrysalide/plugins/constants.h +++ b/plugins/pychrysalide/plugins/constants.h @@ -33,6 +33,9 @@  /* Définit les constantes relatives aux greffons Python. */  bool define_plugin_module_constants(PyTypeObject *); +/* Tente de convertir en constante PluginAction. */ +int convert_to_plugin_action(PyObject *, void *); +  #endif  /* _PLUGINS_PYCHRYSALIDE_PLUGINS_CONSTANTS_H */ diff --git a/plugins/pychrysalide/plugins/module.c b/plugins/pychrysalide/plugins/module.c index c38caa3..1c7b326 100644 --- a/plugins/pychrysalide/plugins/module.c +++ b/plugins/pychrysalide/plugins/module.c @@ -26,13 +26,201 @@  #include <assert.h> +#include <malloc.h> +#include <pygobject.h> +#include <plugins/pglist.h> + + +#include "constants.h"  #include "plugin.h"  #include "../helpers.h" +/* Fournit le greffon répondant à un nom donné. */ +static PyObject *py_plugins_get_plugin_by_name(PyObject *, PyObject *); + +/* Fournit la liste de l'ensemble des greffons. */ +static PyObject *py_plugins_get_all_plugins(PyObject *, PyObject *); + +/* Fournit les greffons offrant le service demandé. */ +static PyObject *py_plugins_get_all_plugins_for_action(PyObject *, PyObject *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = NULL car méthode statique.                            * +*                args = désignation du greffon recherché.                     * +*                                                                             * +*  Description : Fournit le greffon répondant à un nom donné.                 * +*                                                                             * +*  Retour      : Instance du greffon trouvé avec son indice, ou None si aucun.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_plugins_get_plugin_by_name(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Valeur à retourner          */ +    const char *name;                       /* Désignation de greffon      */ +    int ret;                                /* Bilan de lecture des args.  */ +    size_t index;                           /* Indice de la trouvaille     */ +    GPluginModule *plugin;                  /* Greffon retrouvé ou NULL    */ + +#define PY_PLUGINS_GET_PLUGIN_BY_NAME_METHOD PYTHON_METHOD_DEF  \ +(                                                               \ +     get_plugin_by_name, "name",                                \ +     METH_VARARGS, py_plugins,                                  \ +     "Find a given plugin from the list of loaded plugins.\n"   \ +     "\n"                                                       \ +     "The *name* string define the target to find.\n"           \ +     "\n"                                                       \ +     "The returned value is a tuple of the found"               \ +     " pychrysalide.plugins.PluginModule instance and its"      \ +     " value, or None in case of search failure."               \ +) + +    ret = PyArg_ParseTuple(args, "s", &name); +    if (!ret) return NULL; + +    lock_plugin_list_for_reading(); + +    plugin = get_plugin_by_name(name, &index); + +    unlock_plugin_list_for_reading(); + +    if (plugin != NULL) +    { +        result = PyTuple_New(2); + +        PyTuple_SetItem(result, 0, pygobject_new(G_OBJECT(plugin))); +        PyTuple_SetItem(result, 1, PyLong_FromSize_t(index)); + +        g_object_unref(G_OBJECT(plugin)); + +    } + +    else +    { +        result = Py_None; +        Py_INCREF(result); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = NULL car méthode statique.                            * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Fournit la liste de l'ensemble des greffons.                 * +*                                                                             * +*  Retour      : Liste de tous les greffons chargés.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_plugins_get_all_plugins(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Valeur à retourner          */ +    size_t count;                           /* Taille de la liste finale   */ +    GPluginModule **plugins;                /* Liste de greffons chargés   */ +    size_t i;                               /* Boucle de parcours          */ + +#define PY_PLUGINS_GET_ALL_PLUGINS_METHOD PYTHON_METHOD_DEF     \ +(                                                               \ +     get_all_plugins, "/",                                      \ +     METH_NOARGS, py_plugins,                                   \ +     "Provide the list of all loaded plugins.\n"                \ +     "\n"                                                       \ +     "The returned value is a tuple of"                         \ +     " pychrysalide.plugins.PluginModule instances."            \ +) + +    plugins = get_all_plugins(&count); + +    result = PyTuple_New(count); + +    for (i = 0; i < count; i++) +    { +        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(plugins[i]))); +        g_object_unref(G_OBJECT(plugins[i])); +    } + +    if (plugins != NULL) +        free(plugins); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = NULL car méthode statique.                            * +*                args = fonctionnalité recherchée.                            * +*                                                                             * +*  Description : Fournit les greffons offrant le service demandé.             * +*                                                                             * +*  Retour      : Liste de greffons correspondants issue d'un tri interne.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_plugins_get_all_plugins_for_action(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Valeur à retourner          */ +    PluginAction action;                    /* Fonctionnalité recherchée   */ +    int ret;                                /* Bilan de lecture des args.  */ + +    size_t count;                           /* Taille de la liste finale   */ +    GPluginModule **plugins;                /* Liste de greffons chargés   */ +    size_t i;                               /* Boucle de parcours          */ + +#define PY_PLUGINS_GET_ALL_PLUGINS_FOR_ACTION_METHOD PYTHON_METHOD_DEF  \ +(                                                                       \ +     get_all_plugins_for_action, "action",                              \ +     METH_VARARGS, py_plugins,                                          \ +     "Provide the list of all loaded plugins suitable for a given"      \ +     " action.\n"                                                       \ +     "\n"                                                               \ +     "The *action* has to be one of the"                                \ +     " pychrysalide.plugins.PluginModule.PluginAction values.\n"        \ +     "\n"                                                               \ +     "The returned value is a tuple of"                                 \ +     " matching pychrysalide.plugins.PluginModule instances."           \ +) + +    ret = PyArg_ParseTuple(args, "O&", convert_to_plugin_action, &action); +    if (!ret) return NULL; + +    plugins = get_all_plugins_for_action(action, &count); + +    result = PyTuple_New(count); + +    for (i = 0; i < count; i++) +    { +        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(plugins[i]))); +        g_object_unref(G_OBJECT(plugins[i])); +    } + +    if (plugins != NULL) +        free(plugins); + +    return result; + +} + +  /******************************************************************************  *                                                                             *  *  Paramètres  : super = module dont la définition est à compléter.           * @@ -52,11 +240,18 @@ bool add_plugins_module(PyObject *super)  #define PYCHRYSALIDE_PLUGINS_DOC                                            \      "This module provides features to deal with plugins: the definitions"   \ -    " required to build new Python plugins as well as functions to"         \ -    " interact with existing plugins.\n"                                    \ +    " required to build new Python plugins as well as the functions"        \ +    " suitable to interact with existing plugins.\n"                        \      "\n"                                                                    \      "The module is also the place for all plugins without another home." +    static PyMethodDef py_plugins_methods[] = { +        PY_PLUGINS_GET_PLUGIN_BY_NAME_METHOD, +        PY_PLUGINS_GET_ALL_PLUGINS_METHOD, +        PY_PLUGINS_GET_ALL_PLUGINS_FOR_ACTION_METHOD, +        { NULL } +    }; +      static PyModuleDef py_chrysalide_plugins_module = {          .m_base = PyModuleDef_HEAD_INIT, @@ -66,6 +261,8 @@ bool add_plugins_module(PyObject *super)          .m_size = -1, +        .m_methods = py_plugins_methods +      };      module = build_python_module(super, &py_chrysalide_plugins_module);  | 
