summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-04-28 21:44:18 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-04-28 21:44:18 (GMT)
commit2e867fcae6e91594ae47528ca097952398ffcca4 (patch)
treec3897d1f27ab3f4f5813a570e7fb0f6988466e7f
parent4d370b81498fc93e0199232110e9edeb526fd53b (diff)
Extended the Python bindings for registers.
-rw-r--r--plugins/pychrysalide/arch/processor.c10
-rw-r--r--plugins/pychrysalide/arch/register.c407
-rw-r--r--plugins/pychrysalide/glibext/Makefile.am1
-rw-r--r--plugins/pychrysalide/glibext/bufferline.c145
-rw-r--r--plugins/pychrysalide/glibext/constants.c142
-rw-r--r--plugins/pychrysalide/glibext/constants.h42
-rw-r--r--plugins/pychrysalide/helpers.c45
-rw-r--r--plugins/pychrysalide/helpers.h10
-rw-r--r--src/glibext/gbufferline.c2
9 files changed, 775 insertions, 29 deletions
diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c
index 37f97a4..557e7a7 100644
--- a/plugins/pychrysalide/arch/processor.c
+++ b/plugins/pychrysalide/arch/processor.c
@@ -677,6 +677,8 @@ static GArchInstruction *py_arch_processor_disassemble_wrapper(const GArchProces
PyObject *pyins; /* Instruction en objet Python */
int ret; /* Bilan d'une conversion */
+ result = NULL;
+
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(proc));
@@ -696,10 +698,7 @@ static GArchInstruction *py_arch_processor_disassemble_wrapper(const GArchProces
Py_DECREF(args);
- if (pyins == NULL)
- result = NULL;
-
- else
+ if (pyins != NULL)
{
ret = convert_to_arch_instruction(pyins, &result);
@@ -721,9 +720,6 @@ static GArchInstruction *py_arch_processor_disassemble_wrapper(const GArchProces
}
- else
- result = NULL;
-
PyGILState_Release(gstate);
return result;
diff --git a/plugins/pychrysalide/arch/register.c b/plugins/pychrysalide/arch/register.c
index 7ecdb0e..84d3180 100644
--- a/plugins/pychrysalide/arch/register.c
+++ b/plugins/pychrysalide/arch/register.c
@@ -48,17 +48,35 @@ static PyObject *py_arch_register_new(PyTypeObject *, PyObject *, PyObject *);
/* Initialise la classe des descriptions de fichier binaire. */
static void py_arch_register_init_gclass(GArchRegisterClass *, gpointer);
+/* Produit une empreinte à partir d'un registre. */
+static guint py_arch_register___hash___wrapper(const GArchRegister *);
+
+/* Compare un registre avec un autre. */
+static int py_arch_register___cmp___wrapper(const GArchRegister *, const GArchRegister *);
+
+/* Traduit un registre en version humainement lisible. */
+static void py_arch_register_print_wrapper(const GArchRegister *, GBufferLine *);
+
/* Indique si le registre correspond à ebp ou similaire. */
-static bool g_arch_register_is_base_pointer_wrapper(const GArchRegister *);
+static bool py_arch_register_is_base_pointer_wrapper(const GArchRegister *);
+
+/* Indique si le registre correspond à esp ou similaire. */
+static bool py_arch_register_is_stack_pointer_wrapper(const GArchRegister *);
/* ---------------------------- PUR REGISTRE DU MATERIEL ---------------------------- */
+/* Effectue une comparaison avec un objet Python 'ArchRegister'. */
+static PyObject *py_arch_register_richcompare(PyObject *, PyObject *, int);
+
/* Indique si le registre correspond à ebp ou similaire. */
static PyObject *py_arch_register_is_base_pointer(PyObject *, void *);
+/* Indique si le registre correspond à esp ou similaire. */
+static PyObject *py_arch_register_is_stack_pointer(PyObject *, void *);
+
/* ---------------------------------------------------------------------------------- */
@@ -88,6 +106,23 @@ static PyObject *py_arch_register_new(PyTypeObject *type, PyObject *args, PyObje
GType gtype; /* Nouveau type de registre */
bool status; /* Bilan d'un enregistrement */
+#define ARCH_REGISTER_DOC \
+ "The ArchRegister object aims to get subclassed to create" \
+ " registers suitable for new architectures.\n" \
+ "\n" \
+ "Calls to the *__init__* constructor of this abstract object expect"\
+ " no particular argument.\n" \
+ "\n" \
+ "The following methods have to be defined for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister.__hash__();\n" \
+ "* pychrysalide.arch.ArchRegister.__cmp__();\n" \
+ "* pychrysalide.arch.ArchRegister._print();\n" \
+ "* pychrysalide.arch.ArchRegister._is_base_pointer();\n" \
+ "* pychrysalide.arch.ArchRegister._is_stack_pointer().\n" \
+ "\n" \
+ "Chrysalide creates an internal glue to provide rich comparisons" \
+ " for registers based on the old-style *__cmp__* function."
+
/* Validations diverses */
base = get_python_arch_register_type();
@@ -144,7 +179,182 @@ static PyObject *py_arch_register_new(PyTypeObject *type, PyObject *args, PyObje
static void py_arch_register_init_gclass(GArchRegisterClass *class, gpointer unused)
{
- class->is_bp = g_arch_register_is_base_pointer_wrapper;
+ class->hash = py_arch_register___hash___wrapper;
+ class->compare = py_arch_register___cmp___wrapper;
+ class->print = py_arch_register_print_wrapper;
+ class->is_bp = py_arch_register_is_base_pointer_wrapper;
+ class->is_sp = py_arch_register_is_stack_pointer_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre visé par la procédure. *
+* *
+* Description : Produit une empreinte à partir d'un registre. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint py_arch_register___hash___wrapper(const GArchRegister *reg)
+{
+ guint result; /* Empreinte à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define ARCH_REGISTER_HASH_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ __hash__, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to produce a hash of the object. The" \
+ " result must be an integer value." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(reg));
+
+ if (has_python_method(pyobj, "__hash__"))
+ {
+ pyret = run_python_method(pyobj, "__hash__", NULL);
+
+ if (pyret != NULL)
+ {
+ if (PyLong_Check(pyret))
+ result = PyLong_AsUnsignedLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* *
+* Description : Compare un registre avec un autre. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_arch_register___cmp___wrapper(const GArchRegister *a, const GArchRegister *b)
+{
+ int result; /* Empreinte à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define ARCH_REGISTER_CMP_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ __cmp__, "$self, other, /", \
+ METH_VARARGS, \
+ "Abstract method used to produce a compare the register" \
+ " with another one. This second object is always an" \
+ " pychrysalide.arch.ArchRegister instance.\n" \
+ "\n" \
+ " This is the old-style comparison method, but Chrysalide" \
+ " provides a glue to automatically build a rich version of" \
+ " this function." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(a));
+
+ if (has_python_method(pyobj, "__cmp__"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(b)));
+
+ pyret = run_python_method(pyobj, "__cmp__", args);
+
+ if (pyret != NULL)
+ {
+ if (PyLong_Check(pyret))
+ result = PyLong_AsLong(pyret);
+ }
+
+ Py_DECREF(args);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre visé par la procédure. *
+* *
+* Description : Traduit un registre en version humainement lisible. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_arch_register_print_wrapper(const GArchRegister *reg, GBufferLine *line)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define ARCH_REGISTER_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _print, "$self, line, /", \
+ METH_VARARGS, \
+ "Abstract method used to print the register into a rendering" \
+ " line, which is a provided pychrysalide.glibext.BufferLine" \
+ " instance." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(reg));
+
+ if (has_python_method(pyobj, "_print"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(line)));
+
+ pyret = run_python_method(pyobj, "_print", args);
+
+ Py_DECREF(args);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ PyGILState_Release(gstate);
}
@@ -161,21 +371,96 @@ static void py_arch_register_init_gclass(GArchRegisterClass *class, gpointer unu
* *
******************************************************************************/
-static bool g_arch_register_is_base_pointer_wrapper(const GArchRegister *reg)
+static bool py_arch_register_is_base_pointer_wrapper(const GArchRegister *reg)
+{
+ bool result; /* Bilan à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define ARCH_REGISTER_IS_BASE_POINTER_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _is_base_pointer, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to tell if the register is handling a" \
+ " base pointer. The result must be a boolean value." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(reg));
+
+ if (has_python_method(pyobj, "_is_base_pointer"))
+ {
+ pyret = run_python_method(pyobj, "_is_base_pointer", NULL);
+
+ if (pyret != NULL)
+ {
+ result = (pyret == Py_True);
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre visé par la procédure. *
+* *
+* Description : Indique si le registre correspond à esp ou similaire. *
+* *
+* Retour : true si la correspondance est avérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_arch_register_is_stack_pointer_wrapper(const GArchRegister *reg)
{
bool result; /* Bilan à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
+#define ARCH_REGISTER_IS_STACK_POINTER_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _is_stack_pointer, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to tell if the register is handling a" \
+ " stack pointer. The result must be a boolean value." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(reg));
- assert(has_python_method(pyobj, "_is_base_pointer"));
+ if (has_python_method(pyobj, "_is_stack_pointer"))
+ {
+ pyret = run_python_method(pyobj, "_is_stack_pointer", NULL);
+
+ if (pyret != NULL)
+ {
+ result = (pyret == Py_True);
- pyret = run_python_method(pyobj, "_is_base_pointer", NULL);
+ Py_DECREF(pyret);
- result = (pyret == Py_True);
+ }
+
+ }
- Py_XDECREF(pyret);
+ PyGILState_Release(gstate);
return result;
@@ -190,6 +475,51 @@ static bool g_arch_register_is_base_pointer_wrapper(const GArchRegister *reg)
/******************************************************************************
* *
+* Paramètres : a = premier object Python à consulter. *
+* b = second object Python à consulter. *
+* op = type de comparaison menée. *
+* *
+* Description : Effectue une comparaison avec un objet Python 'ArchRegister'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_register_richcompare(PyObject *a, PyObject *b, int op)
+{
+ PyObject *result; /* Bilan à retourner */
+ int ret; /* Bilan de lecture des args. */
+ const GArchRegister *reg_a; /* Premier élément à traiter */
+ const GArchRegister *reg_b; /* Second élément à traiter */
+ int status; /* Résultat d'une comparaison */
+
+ ret = PyObject_IsInstance(b, (PyObject *)get_python_arch_register_type());
+ if (!ret)
+ {
+ result = Py_NotImplemented;
+ goto cmp_done;
+ }
+
+ reg_a = G_ARCH_REGISTER(pygobject_get(a));
+ reg_b = G_ARCH_REGISTER(pygobject_get(b));
+
+ status = py_arch_register___cmp___wrapper(reg_a, reg_b);
+
+ result = status_to_rich_cmp_state(status, op);
+
+ cmp_done:
+
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -207,6 +537,12 @@ static PyObject *py_arch_register_is_base_pointer(PyObject *self, void *closure)
GArchRegister *reg; /* Registre visé */
bool status; /* Bilan de consultation */
+#define ARCH_REGISTER_IS_BASE_POINTER_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ base_pointer, py_arch_register, \
+ "Tell if the register is a base pointer or not." \
+)
+
reg = G_ARCH_REGISTER(pygobject_get(self));
status = g_arch_register_is_base_pointer(reg);
@@ -221,6 +557,43 @@ static PyObject *py_arch_register_is_base_pointer(PyObject *self, void *closure)
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique si le registre correspond à esp ou similaire. *
+* *
+* Retour : True si la correspondance est avérée, False sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_register_is_stack_pointer(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GArchRegister *reg; /* Registre visé */
+ bool status; /* Bilan de consultation */
+
+#define ARCH_REGISTER_IS_STACK_POINTER_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ stack_pointer, py_arch_register, \
+ "Tell if the register is a stack pointer or not." \
+)
+
+ reg = G_ARCH_REGISTER(pygobject_get(self));
+
+ status = g_arch_register_is_stack_pointer(reg);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -234,19 +607,17 @@ static PyObject *py_arch_register_is_base_pointer(PyObject *self, void *closure)
PyTypeObject *get_python_arch_register_type(void)
{
static PyMethodDef py_arch_register_methods[] = {
- {
- "_is_base_pointer", not_yet_implemented_method,
- METH_NOARGS,
- "_is_base_pointer($self, /)\n--\n\nDefine an implementation to provide the relative member value."
- },
+ ARCH_REGISTER_HASH_WRAPPER,
+ ARCH_REGISTER_CMP_WRAPPER,
+ ARCH_REGISTER_PRINT_WRAPPER,
+ ARCH_REGISTER_IS_BASE_POINTER_WRAPPER,
+ ARCH_REGISTER_IS_STACK_POINTER_WRAPPER,
{ NULL }
};
static PyGetSetDef py_arch_register_getseters[] = {
- {
- "is_base_pointer", py_arch_register_is_base_pointer, NULL,
- "Tell if the register is a base pointer or not.", NULL
- },
+ ARCH_REGISTER_IS_BASE_POINTER_ATTRIB,
+ ARCH_REGISTER_IS_STACK_POINTER_ATTRIB,
{ NULL }
};
@@ -259,7 +630,9 @@ PyTypeObject *get_python_arch_register_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide register for a given architecture.",
+ .tp_doc = ARCH_REGISTER_DOC,
+
+ .tp_richcompare = py_arch_register_richcompare,
.tp_methods = py_arch_register_methods,
.tp_getset = py_arch_register_getseters,
diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index 28d27f6..c5fee67 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -2,6 +2,7 @@
noinst_LTLIBRARIES = libpychrysaglibext.la
libpychrysaglibext_la_SOURCES = \
+ constants.h constants.c \
binarycursor.h binarycursor.c \
binportion.h binportion.c \
buffercache.h buffercache.c \
diff --git a/plugins/pychrysalide/glibext/bufferline.c b/plugins/pychrysalide/glibext/bufferline.c
index d6b391a..47b2bc4 100644
--- a/plugins/pychrysalide/glibext/bufferline.c
+++ b/plugins/pychrysalide/glibext/bufferline.c
@@ -31,17 +31,23 @@
#include <i18n.h>
-
-
#include <glibext/gbufferline.h>
+#include <plugins/dt.h>
+#include "constants.h"
#include "../access.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_buffer_line_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Ajoute du texte à formater dans une ligne donnée. */
+static PyObject *py_buffer_line_append_text(PyObject *, PyObject *);
+
/* Reconstruit et fournit le texte présent sur une ligne tampon. */
static PyObject *py_buffer_line_get_text(PyObject *, PyObject *);
@@ -64,6 +70,131 @@ static bool py_buffer_line_define_constants(PyTypeObject *);
/******************************************************************************
* *
+* Paramètres : type = type du nouvel objet à mettre en place. *
+* args = éventuelle liste d'arguments. *
+* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* *
+* Description : Accompagne la création d'une instance dérivée en Python. *
+* *
+* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
+
+#define BUFFER_LINE_DOC \
+ "The BufferLine object is used to display processed data: disassembled" \
+ " instruction, binary content in hexadecimal form, aso.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " BufferLine()" \
+ "\n" \
+ "Such objets aim to be created from the Chrysalide core only, and" \
+ " then get populated by plugins on demand."
+
+ /* Validations diverses */
+
+ base = get_python_buffer_line_type();
+
+ if (type == base)
+ goto simple_way;
+
+ /* Mise en place d'un type dédié */
+
+ first_time = (g_type_from_name(type->tp_name) == 0);
+
+ gtype = build_dynamic_type(G_TYPE_BUFFER_LINE, type->tp_name, NULL, NULL, NULL);
+
+ if (first_time)
+ {
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant une ligne de tampon. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Ajoute du texte à formater dans une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_buffer_line_append_text(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Trouvailles à retourner */
+ unsigned long column; /* Indice de colonne */
+ const char *text; /* Texte à ajouter */
+ RenderingTagType type; /* Type de rendu attendu */
+ GObject *creator; /* Eventuel créateur à associer*/
+ int ret; /* Bilan de lecture des args. */
+ GBufferLine *line; /* Version native */
+
+#define BUFFER_LINE_APPEND_TEXT_METHOD PYTHON_METHOD_DEF \
+( \
+ append_text, "$self, column, text, tag, /, creator=None", \
+ METH_VARARGS, py_buffer_line, \
+ "Append some text to a line at a given column index. The" \
+ " expected rendering for this text is defined by the tag, which"\
+ " must be a pychrysalide.glibext.BufferLine.RenderingTagType" \
+ " value." \
+ "\n" \
+ "An optional GObject instance may be provided as origin of the" \
+ " creation." \
+)
+
+ creator = NULL;
+
+ ret = PyArg_ParseTuple(args, "ksO&|O&", &column, &text,
+ convert_to_rendering_tag_type, &type, convert_to_gobject, &creator);
+ if (!ret) return NULL;
+
+ line = G_BUFFER_LINE(pygobject_get(self));
+
+ g_buffer_line_append_text(line, column, text, strlen(text), type, creator);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = classe représentant une ligne de tampon. *
* args = arguments fournis à l'appel. *
* *
@@ -292,6 +423,7 @@ static bool py_buffer_line_define_constants(PyTypeObject *obj_type)
PyTypeObject *get_python_buffer_line_type(void)
{
static PyMethodDef py_buffer_line_methods[] = {
+ BUFFER_LINE_APPEND_TEXT_METHOD,
{
"get_text", py_buffer_line_get_text,
METH_VARARGS,
@@ -329,13 +461,15 @@ PyTypeObject *get_python_buffer_line_type(void)
.tp_name = "pychrysalide.glibext.BufferLine",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide buffer line",
+ .tp_doc = BUFFER_LINE_DOC,
.tp_methods = py_buffer_line_methods,
.tp_getset = py_buffer_line_getseters,
+ .tp_new = py_buffer_line_new
+
};
return &py_buffer_line_type;
@@ -372,6 +506,9 @@ bool ensure_python_buffer_line_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_BUFFER_LINE, type, &PyGObject_Type))
return false;
+ if (!define_line_segment_constants(type))
+ return false;
+
if (!py_buffer_line_define_constants(type))
return false;
diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c
new file mode 100644
index 0000000..d18e051
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants.c
@@ -0,0 +1,142 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes de base pour les extensions à la GLib
+ *
+ * Copyright (C) 2020 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 "constants.h"
+
+
+#include <glibext/linesegment.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux segments de ligne. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_line_segment_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", RTT_NONE);
+ if (result) result = add_const_to_group(values, "RAW", RTT_RAW);
+ if (result) result = add_const_to_group(values, "RAW_FULL", RTT_RAW_FULL);
+ if (result) result = add_const_to_group(values, "RAW_NULL", RTT_RAW_NULL);
+ if (result) result = add_const_to_group(values, "PRINTABLE", RTT_PRINTABLE);
+ if (result) result = add_const_to_group(values, "NOT_PRINTABLE", RTT_NOT_PRINTABLE);
+ if (result) result = add_const_to_group(values, "COMMENT", RTT_COMMENT);
+ if (result) result = add_const_to_group(values, "INDICATION", RTT_INDICATION);
+ if (result) result = add_const_to_group(values, "PHYS_ADDR_PAD", RTT_PHYS_ADDR_PAD);
+ if (result) result = add_const_to_group(values, "PHYS_ADDR", RTT_PHYS_ADDR);
+ if (result) result = add_const_to_group(values, "VIRT_ADDR_PAD", RTT_VIRT_ADDR_PAD);
+ if (result) result = add_const_to_group(values, "VIRT_ADDR", RTT_VIRT_ADDR);
+ if (result) result = add_const_to_group(values, "RAW_CODE", RTT_RAW_CODE);
+ if (result) result = add_const_to_group(values, "RAW_CODE_NULL", RTT_RAW_CODE_NULL);
+ if (result) result = add_const_to_group(values, "LABEL", RTT_LABEL);
+ if (result) result = add_const_to_group(values, "INSTRUCTION", RTT_INSTRUCTION);
+ if (result) result = add_const_to_group(values, "IMMEDIATE", RTT_IMMEDIATE);
+ if (result) result = add_const_to_group(values, "REGISTER", RTT_REGISTER);
+ if (result) result = add_const_to_group(values, "PUNCT", RTT_PUNCT);
+ if (result) result = add_const_to_group(values, "HOOK", RTT_HOOK);
+ if (result) result = add_const_to_group(values, "SIGNS", RTT_SIGNS);
+ if (result) result = add_const_to_group(values, "LTGT", RTT_LTGT);
+ if (result) result = add_const_to_group(values, "SECTION", RTT_SECTION);
+ if (result) result = add_const_to_group(values, "SEGMENT", RTT_SEGMENT);
+ if (result) result = add_const_to_group(values, "STRING", RTT_STRING);
+ if (result) result = add_const_to_group(values, "VAR_NAME", RTT_VAR_NAME);
+ if (result) result = add_const_to_group(values, "KEY_WORD", RTT_KEY_WORD);
+ if (result) result = add_const_to_group(values, "ERROR", RTT_ERROR);
+ if (result) result = add_const_to_group(values, "COUNT", RTT_COUNT);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "RenderingTagType", values,
+ "Kinds of text rendering.");
+
+ exit:
+
+ 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 RenderingTagType. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_rendering_tag_type(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ 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 RenderingTagType");
+ break;
+
+ case 1:
+ *((RenderingTagType *)dst) = PyLong_AsUnsignedLong(arg);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h
new file mode 100644
index 0000000..472507b
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes de base pour les extensions à la GLib
+ *
+ * Copyright (C) 2020 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_GLIBEXT_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux segments de ligne. */
+bool define_line_segment_constants(PyTypeObject *);
+
+/* Tente de convertir en constante RenderingTagType. */
+int convert_to_rendering_tag_type(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_H */
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 59fd323..47285f0 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -1016,6 +1016,51 @@ int forward_pygobjet_init(PyObject *self)
}
+/******************************************************************************
+* *
+* 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 instance GObject. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_gobject(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyGObject_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 GObject instance");
+ break;
+
+ case 1:
+ *((GObject **)dst) = G_OBJECT(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* TRANSFERT DES VALEURS CONSTANTES */
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index fe13f84..8ed9d9a 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -90,6 +90,13 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
#name "(" args ")\n--\n\n" doc \
}
+#define PYTHON_WRAPPER_DEF(name, args, flags, doc) \
+ { \
+ #name, (PyCFunction)not_yet_implemented_method, \
+ flags, \
+ #name "(" args ")\n--\n\n" doc \
+ }
+
#define PYTHON_GETSET_DEF(name, get, set, doc, closure) \
{ \
name, get, set, \
@@ -163,6 +170,9 @@ bool register_class_for_dynamic_pygobject(GType, PyTypeObject *, PyTypeObject *)
/* Fait suivre à la partie GObject une initialisation nouvelle. */
int forward_pygobjet_init(PyObject *);
+/* Tente de convertir en instance GObject. */
+int convert_to_gobject(PyObject *, void *);
+
/* ----------------------- TRANSFERT DES VALEURS CONSTANTES ------------------------- */
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index b7c6a4a..9b0a5a9 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -540,7 +540,7 @@ GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *line, Buffe
* *
* Description : Ajoute du texte à formater dans une ligne donnée. *
* *
-* Retour : Portion de texte mis en place, voire NULL. *
+* Retour : - *
* *
* Remarques : - *
* *