From c806bc75910c129c6d78115cfdc571316e060412 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 12 Dec 2018 18:07:05 +0100 Subject: Reorganized the global variables access in the Python bindings. --- plugins/pychrysalide/analysis/project.c | 45 ++++++++++ plugins/pychrysalide/analysis/project.h | 3 + plugins/pychrysalide/core/global.c | 140 ++++++++++---------------------- plugins/pychrysalide/core/global.h | 7 +- plugins/pychrysalide/core/module.c | 2 +- plugins/pychrysalide/core/queue.c | 2 +- src/core/global.c | 5 +- tests/core/global.py | 22 +++++ 8 files changed, 119 insertions(+), 107 deletions(-) create mode 100644 tests/core/global.py diff --git a/plugins/pychrysalide/analysis/project.c b/plugins/pychrysalide/analysis/project.c index 06a67b6..1a85f71 100644 --- a/plugins/pychrysalide/analysis/project.c +++ b/plugins/pychrysalide/analysis/project.c @@ -335,3 +335,48 @@ bool ensure_python_study_project_is_registered(void) return true; } + + +/****************************************************************************** +* * +* 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 projet d'étude. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_study_project(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_study_project_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 study project"); + break; + + case 1: + *((GStudyProject **)dst) = G_STUDY_PROJECT(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/analysis/project.h b/plugins/pychrysalide/analysis/project.h index 1e0c698..357d958 100644 --- a/plugins/pychrysalide/analysis/project.h +++ b/plugins/pychrysalide/analysis/project.h @@ -37,6 +37,9 @@ PyTypeObject *get_python_study_project_type(void); /* Prend en charge l'objet 'pychrysalide.analysis.StudyProject'. */ bool ensure_python_study_project_is_registered(void); +/* Tente de convertir en projet d'étude. */ +int convert_to_study_project(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_PROJECT_H */ diff --git a/plugins/pychrysalide/core/global.c b/plugins/pychrysalide/core/global.c index e84af68..0a56825 100644 --- a/plugins/pychrysalide/core/global.c +++ b/plugins/pychrysalide/core/global.c @@ -38,23 +38,23 @@ /* Fournit l'adresse de l'explorateur de contenus courant. */ -static PyObject *py_global_get_content_explorer(PyObject *, void *); +static PyObject *py_global_get_content_explorer(PyObject *, PyObject *); /* Fournit l'adresse du résolveur de contenus courant. */ -static PyObject *py_global_get_content_resolver(PyObject *, void *); +static PyObject *py_global_get_content_resolver(PyObject *, PyObject *); /* Fournit l'adresse du projet courant. */ -static PyObject *py_global_get_current_project(PyObject *, void *); +static PyObject *py_global_get_current_project(PyObject *, PyObject *); /* Définit l'adresse du projet courant. */ -static int py_global_set_current_project(PyObject *, PyObject *, void *); +static PyObject *py_global_set_current_project(PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * +* Paramètres : self = objet Python concerné par l'appel. * +* args = non utilisé ici. * * * * Description : Fournit l'adresse de l'explorateur de contenus courant. * * * @@ -64,7 +64,7 @@ static int py_global_set_current_project(PyObject *, PyObject *, void *); * * ******************************************************************************/ -static PyObject *py_global_get_content_explorer(PyObject *self, void *closure) +static PyObject *py_global_get_content_explorer(PyObject *self, PyObject *args) { PyObject *result; /* Instance Python à retourner */ GContentExplorer *explorer; /* Gestionnaire natif récupéré */ @@ -89,8 +89,8 @@ static PyObject *py_global_get_content_explorer(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * +* Paramètres : self = objet Python concerné par l'appel. * +* args = non utilisé ici. * * * * Description : Fournit l'adresse du résolveur de contenus courant. * * * @@ -100,7 +100,7 @@ static PyObject *py_global_get_content_explorer(PyObject *self, void *closure) * * ******************************************************************************/ -static PyObject *py_global_get_content_resolver(PyObject *self, void *closure) +static PyObject *py_global_get_content_resolver(PyObject *self, PyObject *args) { PyObject *result; /* Instance Python à retourner */ GContentResolver *resolver; /* Gestionnaire natif récupéré */ @@ -125,8 +125,8 @@ static PyObject *py_global_get_content_resolver(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * +* Paramètres : self = objet Python concerné par l'appel. * +* args = non utilisé ici. * * * * Description : Fournit l'adresse du projet courant. * * * @@ -136,7 +136,7 @@ static PyObject *py_global_get_content_resolver(PyObject *self, void *closure) * * ******************************************************************************/ -static PyObject *py_global_get_current_project(PyObject *self, void *closure) +static PyObject *py_global_get_current_project(PyObject *self, PyObject *args) { PyObject *result; /* Instance Python à retourner */ GStudyProject *project; /* Projet courant récupéré */ @@ -154,8 +154,6 @@ static PyObject *py_global_get_current_project(PyObject *self, void *closure) Py_INCREF(result); } - printf("result: %p (project=%p)\n", result, project); - return result; } @@ -163,9 +161,8 @@ static PyObject *py_global_get_current_project(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* value = valeur fournie à intégrer ou prendre en compte. * -* closure = adresse non utilisée ici. * +* Paramètres : self = objet Python concerné par l'appel. * +* args = valeur fournie à intégrer ou prendre en compte. * * * * Description : Définit l'adresse du projet courant. * * * @@ -175,21 +172,19 @@ static PyObject *py_global_get_current_project(PyObject *self, void *closure) * * ******************************************************************************/ -static int py_global_set_current_project(PyObject *self, PyObject *value, void *closure) +static PyObject *py_global_set_current_project(PyObject *self, PyObject *args) { - int ret; /* Bilan d'analyse */ - GStudyProject *project; /* Version GLib du format */ - - ret = PyObject_IsInstance(value, (PyObject *)get_python_study_project_type()); - if (!ret) return -1; + GStudyProject *project; /* Version GLib du projet */ + int ret; /* Bilan de lecture des args. */ - project = G_STUDY_PROJECT(pygobject_get(value)); + ret = PyArg_ParseTuple(args, "O&", convert_to_study_project, &project); + if (!ret) return NULL; g_object_ref(G_OBJECT(project)); set_current_project(project); - return 0; + Py_RETURN_NONE; } @@ -198,94 +193,45 @@ static int py_global_set_current_project(PyObject *self, PyObject *value, void * * * * Paramètres : - * * * -* Description : Fournit un accès à une définition de type à diffuser. * +* Description : Définit une extension du module 'core' à compléter. * * * -* Retour : Définition d'objet pour Python. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -PyTypeObject *get_python_global_type(void) +bool populate_core_module_with_global(void) { + bool result; /* Bilan à retourner */ + PyObject *module; /* Module à recompléter */ + static PyMethodDef py_global_methods[] = { - { NULL } - }; - static PyGetSetDef py_global_getseters[] = { - { - "content_explorer", py_global_get_content_explorer, NULL, - "Get the global exploration manager discovering contents.", NULL + { "get_content_explorer", py_global_get_content_explorer, + METH_NOARGS, + "get_content_explorer(, /)\n--\n\nGet the global exploration manager discovering contents." + }, + { "get_content_resolver", py_global_get_content_resolver, + METH_NOARGS, + "get_content_resolver(, /)\n--\n\nGet the global resolution manager translating binary contents into loaded contents." }, - { - "content_resolver", py_global_get_content_resolver, NULL, - "Get the global resolution manager translating binary contents into loaded contents.", NULL + { "get_current_project", py_global_get_current_project, + METH_NOARGS, + "get_current_project(, /)\n--\n\nGet the current global project." }, - { - "current_project", py_global_get_current_project, py_global_set_current_project, - "Get or set the current global project.", NULL + { "set_current_project", py_global_set_current_project, + METH_VARARGS, + "set_current_project(, /)\n--\n\nSet the current global project." }, { NULL } - }; - - static PyTypeObject py_global_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.core._global", - .tp_basicsize = sizeof(PyObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = "Access to the global properties", - - .tp_methods = py_global_methods, - .tp_getset = py_global_getseters }; - return &py_global_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.core._global'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool ensure_python_global_is_registered(void) -{ - PyTypeObject *type; /* Type Python de 'global' */ - PyObject *module; /* Module à recompléter */ - int ret; /* Bilan d'un appel */ - - type = get_python_global_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - type->tp_new = PyType_GenericNew; - - if (PyType_Ready(type) != 0) - return false; + module = get_access_to_python_module("pychrysalide.core"); - module = get_access_to_python_module("pychrysalide.core"); + result = register_python_module_methods(module, py_global_methods); - Py_INCREF(type); - ret = PyModule_AddObject(module, "_global", (PyObject *)type); - - if (ret != 0) - return false; - - } - - return true; + return result; } diff --git a/plugins/pychrysalide/core/global.h b/plugins/pychrysalide/core/global.h index 3246947..07fb0ad 100644 --- a/plugins/pychrysalide/core/global.h +++ b/plugins/pychrysalide/core/global.h @@ -31,11 +31,8 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_global_type(void); - -/* Prend en charge l'objet 'pychrysalide.core._global'. */ -bool ensure_python_global_is_registered(void); +/* Définit une extension du module 'core' à compléter. */ +bool populate_core_module_with_global(void); diff --git a/plugins/pychrysalide/core/module.c b/plugins/pychrysalide/core/module.c index aade384..900bf83 100644 --- a/plugins/pychrysalide/core/module.c +++ b/plugins/pychrysalide/core/module.c @@ -93,7 +93,7 @@ bool populate_core_module(void) result = true; if (result) result = ensure_python_demanglers_is_registered(); - if (result) result = ensure_python_global_is_registered(); + if (result) result = populate_core_module_with_global(); if (result) result = ensure_python_logs_is_registered(); if (result) result = ensure_python_params_is_registered(); if (result) result = populate_core_module_with_queue(); diff --git a/plugins/pychrysalide/core/queue.c b/plugins/pychrysalide/core/queue.c index 8d530e6..39dd576 100644 --- a/plugins/pychrysalide/core/queue.c +++ b/plugins/pychrysalide/core/queue.c @@ -43,7 +43,7 @@ static PyObject *py_queue_wait_for_all_global_works(PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : self = NULL car méthode statique. * +* Paramètres : self = objet Python concerné par l'appel. * * args = non utilisé ici. * * * * Description : Attend que toutes les tâches de tout groupe soient traitées. * diff --git a/src/core/global.c b/src/core/global.c index 8736b30..3777fd9 100644 --- a/src/core/global.c +++ b/src/core/global.c @@ -261,9 +261,8 @@ void set_current_project(GStudyProject *project) GStudyProject *get_current_project(void) { - assert(_project != NULL); - - g_object_ref(G_OBJECT(_project)); + if (_project != NULL) + g_object_ref(G_OBJECT(_project)); return _project; diff --git a/tests/core/global.py b/tests/core/global.py new file mode 100644 index 0000000..a929940 --- /dev/null +++ b/tests/core/global.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3-dbg +# -*- coding: utf-8 -*- + + +from chrysacase import ChrysalideTestCase +from pychrysalide.analysis import StudyProject +from pychrysalide.core import get_current_project, set_current_project + + +class TestCoreGlobal(ChrysalideTestCase): + """TestCase for analysis.core.global.""" + + def testProject(self): + """Get and set the current project.""" + + self.assertIsNone(get_current_project()) + + prj = StudyProject() + + set_current_project(prj) + + self.assertEqual(get_current_project(), prj) -- cgit v0.11.2-87-g4458