summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/arch/operands
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-05-28 22:25:26 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-05-28 22:25:26 (GMT)
commit2700e6892a0c0d78baf7228040aa07a1e21c6f53 (patch)
treec8c74971b53ec4333c7c7eef2b6e102a33f57fe5 /plugins/pychrysalide/arch/operands
parent614b0d9febfffc8c8ee6c554d5132b9ecd9bff78 (diff)
Adapted the API for renamed operands.
Diffstat (limited to 'plugins/pychrysalide/arch/operands')
-rw-r--r--plugins/pychrysalide/arch/operands/rename.c352
-rw-r--r--plugins/pychrysalide/arch/operands/rename.h6
2 files changed, 347 insertions, 11 deletions
diff --git a/plugins/pychrysalide/arch/operands/rename.c b/plugins/pychrysalide/arch/operands/rename.c
index da1543b..7a5be98 100644
--- a/plugins/pychrysalide/arch/operands/rename.c
+++ b/plugins/pychrysalide/arch/operands/rename.c
@@ -28,7 +28,7 @@
#include <pygobject.h>
-#include <arch/operands/rename.h>
+#include <arch/operands/rename-int.h>
#include "../../access.h"
@@ -36,12 +36,18 @@
-/* ------------------------ INTERFACE POUR OPERANDE RENOMMEE ------------------------ */
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de renom. */
+static void py_renamed_operand_init(GRenamedOperandIface *, gpointer *);
+
+/* Fournit un texte comme représentation alternative d'opérande. */
+static char *py_renamed_operand_get_text_wrapper(const GRenamedOperand *);
+
-#define RENAMED_OPERAND_DOC \
- "The RenamedOperand interface depicts operands renamed with an" \
- " alternative text."
+/* ------------------------ INTERFACE POUR OPERANDE RENOMMEE ------------------------ */
/* Fournit un texte comme représentation alternative d'opérande. */
@@ -49,12 +55,18 @@ static PyObject *py_renamed_operand_get_text(PyObject *, void *);
-/* ----------------------- INTERFACE POUR OPERANDE RENOMMABLE ----------------------- */
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+/* Procède à l'initialisation de l'interface de renommage. */
+static void py_renameable_operand_init(GRenameableOperandIface *, gpointer *);
+
+/* Construit un opérande de représentation alternative. */
+static GRenamedOperand *py_renameable_operand_build_wrapper(const GRenameableOperand *, const char *);
-#define RENAMEABLE_OPERAND_DOC \
- "The RenameableOperand interface depicts operands which can get" \
- " renamed with an alternative text." \
+
+
+/* ----------------------- INTERFACE POUR OPERANDE RENOMMABLE ----------------------- */
/* Construit un opérande de représentation alternative. */
@@ -63,6 +75,107 @@ static PyObject *py_renameable_operand_build(PyObject *, PyObject *);
/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
+* *
+* Description : Procède à l'initialisation de l'interface de renom. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_renamed_operand_init(GRenamedOperandIface *iface, gpointer *unused)
+{
+
+#define RENAMED_OPERAND_DOC \
+ "The RenamedOperand interface depicts operands renamed with an" \
+ " alternative text." \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(GObject.Object, RenamedOperand):\n" \
+ " ...\n" \
+ "\n" \
+ "The following method has to be defined for new implementations:\n" \
+ "* pychrysalide.arch.operands.RenamedOperand._get_text();\n" \
+
+ iface->get_text = py_renamed_operand_get_text_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = operande à consulter. *
+* *
+* Description : Fournit un texte comme représentation alternative d'opérande.*
+* *
+* Retour : Chaîne de caractère de représentation alternative. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_renamed_operand_get_text_wrapper(const GRenamedOperand *operand)
+{
+ char *result; /* Texte à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Bilan d'une conversion */
+
+#define RENAMED_OPERAND_GET_TEXT_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_text, "$self", \
+ METH_NOARGS, \
+ "Abstract method used to provide the alternative text for" \
+ " rendering." \
+ "\n" \
+ "The result of the call has to be a string." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(operand));
+
+ if (has_python_method(pyobj, "_get_text"))
+ {
+ pyret = run_python_method(pyobj, "_get_text", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyret));
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* INTERFACE POUR OPERANDE RENOMMEE */
/* ---------------------------------------------------------------------------------- */
@@ -117,6 +230,7 @@ static PyObject *py_renamed_operand_get_text(PyObject *self, void *closure)
PyTypeObject *get_python_renamed_operand_type(void)
{
static PyMethodDef py_renamed_operand_methods[] = {
+ RENAMED_OPERAND_GET_TEXT_WRAPPER,
{ NULL }
};
@@ -164,6 +278,14 @@ bool ensure_python_renamed_operand_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_renamed_operand_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_renamed_operand_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -172,7 +294,7 @@ bool ensure_python_renamed_operand_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_RENAMED_OPERAND, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_RENAMED_OPERAND, type, &info))
return false;
}
@@ -182,6 +304,160 @@ bool ensure_python_renamed_operand_is_registered(void)
}
+/******************************************************************************
+* *
+* 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 opérande renommé. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_renamed_operand(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_renamed_operand_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 renamed operand");
+ break;
+
+ case 1:
+ *((GRenamedOperand **)dst) = G_RENAMED_OPERAND(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
+* *
+* Description : Procède à l'initialisation de l'interface de renommage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_renameable_operand_init(GRenameableOperandIface *iface, gpointer *unused)
+{
+
+#define RENAMEABLE_OPERAND_DOC \
+ "The RenameableOperand interface depicts operands which can get" \
+ " renamed with an alternative text." \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(GObject.Object, RenameableOperand):\n" \
+ " ...\n" \
+ "\n" \
+ "The following method has to be defined for new implementations:\n" \
+ "* pychrysalide.arch.operands.RenameableOperand._build();\n" \
+
+ iface->build = py_renameable_operand_build_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = operande à consulter. *
+* text = texte alternatif de représentation. *
+* *
+* Description : Construit un opérande de représentation alternative. *
+* *
+* Retour : Nouvel opérande, en version renommée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GRenamedOperand *py_renameable_operand_build_wrapper(const GRenameableOperand *operand, const char *text)
+{
+ GRenamedOperand *result; /* Instance à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Bilan d'une conversion */
+
+#define RENAMEABLE_OPERAND_BUILD_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _build, "$self, text", \
+ METH_VARARGS, \
+ "Abstract method used to build a new operand with an" \
+ " alternative text as rendering." \
+ "\n" \
+ "The result of the call has to be an object implementing the" \
+ " pychrysalide.arch.operands.RenamedOperand interface." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(operand));
+
+ if (has_python_method(pyobj, "_build"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, PyUnicode_FromString(text));
+
+ pyret = run_python_method(pyobj, "_build", args);
+
+ if (pyret != NULL)
+ {
+ ret = convert_to_renamed_operand(pyret, &result);
+
+ if (ret == 1)
+ g_object_ref(G_OBJECT(result));
+
+ Py_DECREF(pyret);
+
+ Py_DECREF(args);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* INTERFACE POUR OPERANDE RENOMMABLE */
@@ -249,6 +525,7 @@ static PyObject *py_renameable_operand_build(PyObject *self, PyObject *args)
PyTypeObject *get_python_renameable_operand_type(void)
{
static PyMethodDef py_renameable_operand_methods[] = {
+ RENAMEABLE_OPERAND_BUILD_WRAPPER,
RENAMEABLE_OPERAND_BUILD_METHOD,
{ NULL }
};
@@ -296,6 +573,14 @@ bool ensure_python_renameable_operand_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_renameable_operand_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_renameable_operand_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -304,7 +589,7 @@ bool ensure_python_renameable_operand_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_RENAMEABLE_OPERAND, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_RENAMEABLE_OPERAND, type, &info))
return false;
}
@@ -312,3 +597,48 @@ bool ensure_python_renameable_operand_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 opérande renommable. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_renameable_operand(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_renameable_operand_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 renameable operand");
+ break;
+
+ case 1:
+ *((GRenameableOperand **)dst) = G_RENAMEABLE_OPERAND(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/rename.h b/plugins/pychrysalide/arch/operands/rename.h
index a7f9233..6e81436 100644
--- a/plugins/pychrysalide/arch/operands/rename.h
+++ b/plugins/pychrysalide/arch/operands/rename.h
@@ -40,6 +40,9 @@ PyTypeObject *get_python_renamed_operand_type(void);
/* Prend en charge l'objet 'pychrysalide.arch.RenamedOperand'. */
bool ensure_python_renamed_operand_is_registered(void);
+/* Tente de convertir en opérande renommé. */
+int convert_to_renamed_operand(PyObject *, void *);
+
/* ----------------------- INTERFACE POUR OPERANDE RENOMMABLE ----------------------- */
@@ -51,6 +54,9 @@ PyTypeObject *get_python_renameable_operand_type(void);
/* Prend en charge l'objet 'pychrysalide.arch.RenameableOperand'. */
bool ensure_python_renameable_operand_is_registered(void);
+/* Tente de convertir en opérande renommable. */
+int convert_to_renameable_operand(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_RENAME_H */