summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r--plugins/pychrysalide/Makefile.am17
-rw-r--r--plugins/pychrysalide/arch/Makefile.am32
-rw-r--r--plugins/pychrysalide/arch/constants.c5
-rw-r--r--plugins/pychrysalide/arch/constants.h5
-rw-r--r--plugins/pychrysalide/arch/instruction.c866
-rw-r--r--plugins/pychrysalide/arch/instructions/Makefile.am3
-rw-r--r--plugins/pychrysalide/arch/instructions/constants.c58
-rw-r--r--plugins/pychrysalide/arch/instructions/constants.h5
-rw-r--r--plugins/pychrysalide/arch/instructions/raw.c142
-rw-r--r--plugins/pychrysalide/arch/instructions/undefined.c145
-rw-r--r--plugins/pychrysalide/arch/instructions/undefined.h4
-rw-r--r--plugins/pychrysalide/arch/module-ui.c66
-rw-r--r--plugins/pychrysalide/arch/module-ui.h38
-rw-r--r--plugins/pychrysalide/arch/module.c14
-rw-r--r--plugins/pychrysalide/arch/operand-ui.c461
-rw-r--r--plugins/pychrysalide/arch/operand-ui.h45
-rw-r--r--plugins/pychrysalide/arch/operand.c480
-rw-r--r--plugins/pychrysalide/arch/operand.h5
-rw-r--r--plugins/pychrysalide/arch/operands/Makefile.am16
-rw-r--r--plugins/pychrysalide/arch/operands/constants.c19
-rw-r--r--plugins/pychrysalide/arch/operands/constants.h7
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.c384
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.h10
-rw-r--r--plugins/pychrysalide/arch/operands/known.c125
-rw-r--r--plugins/pychrysalide/arch/operands/known.h10
-rw-r--r--plugins/pychrysalide/arch/operands/module.c16
-rw-r--r--plugins/pychrysalide/arch/operands/register.c196
-rw-r--r--plugins/pychrysalide/arch/register.c361
-rw-r--r--plugins/pychrysalide/bindings.c93
-rw-r--r--plugins/pychrysalide/bindings.h17
-rw-r--r--plugins/pychrysalide/common/Makefile.am2
-rw-r--r--plugins/pychrysalide/common/leb128.c139
-rw-r--r--plugins/pychrysalide/common/module.c4
-rw-r--r--plugins/pychrysalide/constants.h3
-rw-r--r--plugins/pychrysalide/convert.c31
-rw-r--r--plugins/pychrysalide/convert.h3
-rw-r--r--plugins/pychrysalide/core-ui.c222
-rw-r--r--plugins/pychrysalide/core.c198
-rw-r--r--plugins/pychrysalide/glibext/Makefile.am21
-rw-r--r--plugins/pychrysalide/glibext/bufferline.c109
-rw-r--r--plugins/pychrysalide/glibext/constants-ui.c131
-rw-r--r--plugins/pychrysalide/glibext/constants-ui.h41
-rw-r--r--plugins/pychrysalide/glibext/constants.c100
-rw-r--r--plugins/pychrysalide/glibext/constants.h6
-rw-r--r--plugins/pychrysalide/glibext/generator.c (renamed from plugins/pychrysalide/glibext/linegen.c)584
-rw-r--r--plugins/pychrysalide/glibext/generator.h (renamed from plugins/pychrysalide/glibext/linegen.h)18
-rw-r--r--plugins/pychrysalide/glibext/module-ui.c62
-rw-r--r--plugins/pychrysalide/glibext/module-ui.h38
-rw-r--r--plugins/pychrysalide/glibext/module.c4
-rw-r--r--plugins/pychrysalide/glibext/objhole.c102
-rw-r--r--plugins/pychrysalide/glibext/secstorage.c9
-rw-r--r--plugins/pychrysalide/glibext/serialize.c (renamed from plugins/pychrysalide/analysis/storage/serialize.c)141
-rw-r--r--plugins/pychrysalide/glibext/serialize.h (renamed from plugins/pychrysalide/analysis/storage/serialize.h)12
-rw-r--r--plugins/pychrysalide/glibext/storage.c (renamed from plugins/pychrysalide/analysis/storage/storage.c)225
-rw-r--r--plugins/pychrysalide/glibext/storage.h (renamed from plugins/pychrysalide/analysis/storage/storage.h)12
-rw-r--r--plugins/pychrysalide/glibext/tpmem.c (renamed from plugins/pychrysalide/analysis/storage/tpmem.c)0
-rw-r--r--plugins/pychrysalide/glibext/tpmem.h (renamed from plugins/pychrysalide/analysis/storage/tpmem.h)0
-rw-r--r--plugins/pychrysalide/gtkext/Makefile.am30
-rw-r--r--plugins/pychrysalide/gtkext/module.c34
-rw-r--r--plugins/pychrysalide/gtkext/panel.c130
-rw-r--r--plugins/pychrysalide/gtkext/panel.h42
-rw-r--r--plugins/pychrysalide/helpers-ui.c141
-rw-r--r--plugins/pychrysalide/helpers-ui.h44
-rw-r--r--plugins/pychrysalide/helpers.c121
-rw-r--r--plugins/pychrysalide/helpers.h13
65 files changed, 3834 insertions, 2583 deletions
diff --git a/plugins/pychrysalide/Makefile.am b/plugins/pychrysalide/Makefile.am
index d1bf457..c574727 100644
--- a/plugins/pychrysalide/Makefile.am
+++ b/plugins/pychrysalide/Makefile.am
@@ -15,12 +15,6 @@ endif
# if BUILD_GTK_SUPPORT
-# GTKEXT_LIBADD = \
-# gtkext/libpychrysagtkext.la
-
-# GTKEXT_SUBDIR = \
-# gtkext
-
# GUI_LIBADD = \
# gui/libpychrysagui.la
@@ -51,7 +45,6 @@ AM_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFL
# common/libpychrysacommon.la \
# core/libpychrysacore.la \
# debug/libpychrysadebug.la \
-# $(GTKEXT_LIBADD) \
# $(GUI_LIBADD) \
# mangling/libpychrysamangling.la \
# plugins/libpychrysaplugins.la
@@ -78,9 +71,13 @@ EXTRA_pychrysalideui_la_DEPENDENCIES = pychrysalide.la
pychrysalideui_la_SOURCES = \
core-ui-int.h \
- core-ui.h core-ui.c
+ core-ui.h core-ui.c \
+ helpers-ui.h helpers-ui.c
-pychrysalideui_la_LIBADD =
+pychrysalideui_la_LIBADD = \
+ arch/libpychrysaarchui.la \
+ glibext/libpychrysaglibextui.la \
+ gtkext/libpychrysagtkext.la
# -ldl: dladdr(), dlerror()
pychrysalideui_la_LDFLAGS = \
@@ -98,4 +95,4 @@ dev_HEADERS = $(pychrysalide_la_SOURCES:%c=)
#SUBDIRS = analysis arch common core debug $(GTKEXT_SUBDIR) $(GUI_SUBDIR) mangling plugins
-SUBDIRS = analysis arch common core format glibext plugins
+SUBDIRS = analysis arch common core format glibext gtkext plugins
diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am
index d3ee3f0..a0dcfdb 100644
--- a/plugins/pychrysalide/arch/Makefile.am
+++ b/plugins/pychrysalide/arch/Makefile.am
@@ -1,19 +1,13 @@
-noinst_LTLIBRARIES = libpychrysaarch4.la # libpychrysaarch.la
+noinst_LTLIBRARIES = libpychrysaarch4.la libpychrysaarchui.la # libpychrysaarch.la
# libpychrysaarch_la_SOURCES = \
-# constants.h constants.c \
# context.h context.c \
# instriter.h instriter.c \
-# instruction.h instruction.c \
-# module.h module.c \
-# operand.h operand.c \
-# processor.h processor.c \
-# register.h register.c \
-# vmpa.h vmpa.c
+# processor.h processor.c
# libpychrysaarch_la_LIBADD = \
-# instructions/libpychrysaarchinstructions.la \
+# \
# operands/libpychrysaarchoperands.la
# libpychrysaarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
@@ -22,21 +16,33 @@ noinst_LTLIBRARIES = libpychrysaarch4.la # libpychrysaarch.la
libpychrysaarch4_la_SOURCES = \
constants.h constants.c \
+ instruction.h instruction.c \
module.h module.c \
+ operand.h operand.c \
+ register.h register.c \
vmpa.h vmpa.c
-# libpychrysaarch4_la_LIBADD = \
-# instructions/libpychrysaarchinstructions.la \
-# operands/libpychrysaarchoperands.la
+libpychrysaarch4_la_LIBADD = \
+ instructions/libpychrysaarchinstructions.la \
+ operands/libpychrysaarchoperands.la
libpychrysaarch4_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
$(TOOLKIT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+libpychrysaarchui_la_SOURCES = \
+ module-ui.h module-ui.c \
+ operand-ui.h operand-ui.c
+
+libpychrysaarchui_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ $(TOOLKIT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
devdir = $(includedir)/chrysalide/$(subdir)
dev_HEADERS = $(libpychrysaarch_la_SOURCES:%c=)
-# SUBDIRS = instructions operands
+SUBDIRS = instructions operands
diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c
index 3604795..5db59ff 100644
--- a/plugins/pychrysalide/arch/constants.c
+++ b/plugins/pychrysalide/arch/constants.c
@@ -25,7 +25,7 @@
#include "constants.h"
-//#include <arch/instruction.h>
+#include <arch/instruction.h>
//#include <arch/processor.h>
#include <arch/vmpa.h>
@@ -33,7 +33,6 @@
#include "../helpers.h"
-#if 0 // FIXME
/******************************************************************************
* *
@@ -116,6 +115,8 @@ bool define_arch_instruction_constants(PyTypeObject *type)
}
+#if 0 // FIXME
+
/******************************************************************************
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h
index b12579e..2f16c4f 100644
--- a/plugins/pychrysalide/arch/constants.h
+++ b/plugins/pychrysalide/arch/constants.h
@@ -30,10 +30,13 @@
#include <stdbool.h>
-#if 0 // FIXME
+
/* Définit les constantes relatives aux instructions. */
bool define_arch_instruction_constants(PyTypeObject *);
+
+#if 0 // FIXME
+
/* Définit les constantes relatives aux processeurs. */
bool define_arch_processor_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 0a9ba16..49daa9c 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -27,13 +27,12 @@
#include <assert.h>
#include <malloc.h>
-#include <string.h>
#include <pygobject.h>
#include <i18n.h>
+#include <plugins/self.h>
#include <arch/instruction-int.h>
-#include <plugins/dt.h>
#include "constants.h"
@@ -41,30 +40,38 @@
#include "vmpa.h"
#include "../access.h"
#include "../helpers.h"
-#include "../glibext/linegen.h"
-
-
-
-static G_DEFINE_QUARK(cached_keyword, get_cached_keyword);
+#include "../glibext/objhole.h"
+#include "../glibext/serialize.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe générique des instructions. */
-static void py_arch_instruction_init_gclass(GArchInstructionClass *, gpointer);
+static int py_arch_instruction_init_gclass(GArchInstructionClass *, PyTypeObject *);
-CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_instruction, G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_init_gclass);
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_instruction, G_TYPE_ARCH_INSTRUCTION);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_arch_instruction_init(PyObject *, PyObject *, PyObject *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static char *py_arch_instruction_get_encoding_wrapper(const GArchInstruction *);
+
/* Fournit le nom humain de l'instruction manipulée. */
-static const char *py_arch_instruction_get_class_keyword(GArchInstruction *);
+static char *py_arch_instruction_get_keyword_wrapper(const GArchInstruction *);
+
+
+
+/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
+
+
+/* Fournit les origines d'une instruction donnée. */
+static PyObject *py_arch_instruction_get_sources(PyObject *, void *);
+
+/* Fournit les destinations d'une instruction donnée. */
+static PyObject *py_arch_instruction_get_destinations(PyObject *, void *);
@@ -72,10 +79,7 @@ static const char *py_arch_instruction_get_class_keyword(GArchInstruction *);
/* Attache un opérande supplémentaire à une instruction. */
-static PyObject *py_arch_instruction_attach_extra_operand(PyObject *, PyObject *);
-
-/* Fournit tous les opérandes d'une instruction. */
-static PyObject *py_arch_instruction_get_operands(PyObject *, void *);
+static PyObject *py_arch_instruction_attach_operand(PyObject *, PyObject *);
/* Remplace un opérande d'une instruction par un autre. */
static PyObject *py_arch_instruction_replace_operand(PyObject *, PyObject *);
@@ -89,34 +93,35 @@ static PyObject *py_arch_instruction_find_operand_path(PyObject *, PyObject *);
/* Obtient l'opérande correspondant à un chemin donné. */
static PyObject *py_arch_instruction_get_operand_from_path(PyObject *, PyObject *);
+/* Fournit tous les opérandes d'une instruction. */
+static PyObject *py_arch_instruction_get_operands(PyObject *, void *);
-/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
-/* Fournit les origines d'une instruction donnée. */
-static PyObject *py_arch_instruction_get_sources(PyObject *, void *);
-/* Fournit les destinations d'une instruction donnée. */
-static PyObject *py_arch_instruction_get_destinations(PyObject *, void *);
+/* Ajoute une information complémentaire à une instruction. */
+static PyObject *py_arch_instruction_set_flag(PyObject *, PyObject *);
+/* Retire une information complémentaire à une instruction. */
+static PyObject *py_arch_instruction_unset_flag(PyObject *, PyObject *);
+/* Détermine si une instruction possède un fanion particulier. */
+static PyObject *py_arch_instruction_has_flag(PyObject *, PyObject *);
-/* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */
+/* Fournit l'identifiant correspondant à un type d'instructions. */
+static PyObject *py_arch_instruction_get_type_id(PyObject *, void *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static PyObject *py_arch_instruction_get_encoding(PyObject *, void *);
-/* Fournit l'identifiant unique pour un ensemble d'instructions. */
-static PyObject *py_arch_instruction_get_unique_id(PyObject *, void *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
/* Fournit la place mémoire d'une instruction. */
static PyObject *py_arch_instruction_get_range(PyObject *, void *);
-/* Définit la localisation d'une instruction. */
-static int py_arch_instruction_set_range(PyObject *, PyObject *, void *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
-
/* ---------------------------------------------------------------------------------- */
@@ -126,24 +131,23 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : class = classe à initialiser. *
-* unused = données non utilisées ici. *
+* Paramètres : gclass = classe GLib à initialiser. *
+* pyclass = classe Python à initialiser. *
* *
* Description : Initialise la classe générique des instructions. *
* *
-* Retour : - *
+* Retour : 0 pour indiquer un succès de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_arch_instruction_init_gclass(GArchInstructionClass *class, gpointer unused)
+static int py_arch_instruction_init_gclass(GArchInstructionClass *gclass, PyTypeObject *pyclass)
{
- GArchInstructionClass *instr; /* Encore une autre vision... */
-
- instr = G_ARCH_INSTRUCTION_CLASS(class);
+ PY_CLASS_SET_WRAPPER(gclass->get_encoding, py_arch_instruction_get_encoding_wrapper);
+ PY_CLASS_SET_WRAPPER(gclass->get_keyword, py_arch_instruction_get_keyword_wrapper);
- instr->get_keyword = (get_instruction_keyword_fc)py_arch_instruction_get_class_keyword;
+ return 0;
}
@@ -164,17 +168,25 @@ static void py_arch_instruction_init_gclass(GArchInstructionClass *class, gpoint
static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- unsigned short int uid; /* Indentifiant unique de type */
- const char *keyword; /* Désignation d'instruction */
+ unsigned short int tid; /* Indentifiant unique de type */
int ret; /* Bilan de lecture des args. */
GArchInstruction *instr; /* Instruction à manipuler */
- GQuark cache_key; /* Emplacement local */
- static char *kwlist[] = { "uid", "keyword", NULL };
+#define ARCH_INSTRUCTION_DOC \
+ "The ArchInstruction object provides a base class for instructions" \
+ " of any architecture.\n" \
+ " operands of any kind for new architectures.\n" \
+ "\n" \
+ "Calls to the *__init__* constructor of this abstract object expect"\
+ " one argument: an unique identifier, as an integer value.\n" \
+ "\n" \
+ "The following methods have to be defined for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister._get_encoding();\n" \
+ "* pychrysalide.arch.ArchRegister._get_keyword().\n"
/* Récupération des paramètres */
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "Hs", kwlist, &uid, &keyword);
+ ret = PyArg_ParseTuple(args, "H", &tid);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -186,13 +198,72 @@ static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kw
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- cache_key = get_cached_keyword_quark();
+ if (!g_arch_instruction_create(instr, tid))
+ return -1;
+
+ return 0;
- g_object_set_qdata_full(G_OBJECT(instr), cache_key, strdup(keyword), g_free);
+}
- g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(instr), uid);
- return 0;
+/******************************************************************************
+* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
+* *
+* Retour : Description humaine de l'encodage utilisé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_arch_instruction_get_encoding_wrapper(const GArchInstruction *instr)
+{
+ char *result; /* Encodage à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_GET_ENCODING_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_encoding, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method describing the encoding related to an" \
+ " instruction.\n" \
+ "\n" \
+ "The result should be the string value.\n" \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(instr));
+
+ if (has_python_method(pyobj, "_get_encoding"))
+ {
+ pyret = run_python_method(pyobj, "_get_encoding", NULL);
+
+ if (pyret != NULL)
+ {
+ if (!PyUnicode_Check(pyret))
+ log_variadic_message(LMT_ERROR, _("The returned raw name must be a string"));
+
+ else
+ result = strdup(PyUnicode_DATA(pyret));
+
+ }
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
}
@@ -209,15 +280,50 @@ static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kw
* *
******************************************************************************/
-static const char *py_arch_instruction_get_class_keyword(GArchInstruction *instr)
+static char *py_arch_instruction_get_keyword_wrapper(const GArchInstruction *instr)
{
- const char *result; /* Désignation à retourner */
- GQuark cache_key; /* Emplacement local */
+ char *result; /* Etiquette à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_GET_KEYWORD_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_keyword, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method giving the official name of the assembly" \
+ " instruction.\n" \
+ "\n" \
+ "The result should be the string value.\n" \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(instr));
+
+ if (has_python_method(pyobj, "_get_keyword"))
+ {
+ pyret = run_python_method(pyobj, "_get_keyword", NULL);
+
+ if (pyret != NULL)
+ {
+ if (!PyUnicode_Check(pyret))
+ log_variadic_message(LMT_ERROR, _("The returned raw name must be a string"));
- cache_key = get_cached_keyword_quark();
+ else
+ result = strdup(PyUnicode_DATA(pyret));
- result = g_object_get_qdata(G_OBJECT(instr), cache_key);
- assert(result != NULL);
+ }
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
return result;
@@ -226,94 +332,201 @@ static const char *py_arch_instruction_get_class_keyword(GArchInstruction *instr
/* ---------------------------------------------------------------------------------- */
-/* MANIPULATION DES OPERANDES */
+/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : self = architecture concernée par la procédure. *
-* args = instruction représentant le point de départ. *
+* Paramètres : self = instruction d'architecture à manipuler. *
+* unused = adresse non utilisée ici. *
* *
-* Description : Attache un opérande supplémentaire à une instruction. *
+* Description : Fournit les origines d'une instruction donnée. *
* *
-* Retour : None. *
+* Retour : Nombre de ces origines. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_attach_extra_operand(PyObject *self, PyObject *args)
+static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
{
- GArchOperand *op; /* Opérande concerné à ajouter */
- int ret; /* Bilan de lecture des args. */
- GArchInstruction *instr; /* Instruction manipulée */
+ PyObject *result; /* Instance à retourner */
+ GArchInstruction *instr; /* Version native */
+ size_t count; /* Nombre de liens présents */
+ size_t i; /* Boucle de parcours */
- ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &op);
- if (!ret) return NULL;
+
+ GArchInstruction *src; /* Instruction en source */
+ InstructionLinkType src_type; /* Type de lien */
+ PyObject *linked; /* Source de lien Python */
+ PyObject *lnk_type; /* Nature du lien en Python */
+#ifndef NDEBUG
+ int ret; /* Bilan d'une écriture d'arg. */
+#endif
+
+#define ARCH_INSTRUCTION_SOURCES_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ sources, py_arch_instruction, \
+ "Provide the instructions list driving to the current instruction.\n" \
+ "\n" \
+ "Each item of the resulting tuple is a pair of" \
+ " pychrysalide.arch.ArchInstruction instance and" \
+ " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_object_ref(G_OBJECT(op));
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ count = g_arch_instruction_count_src_links(instr);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ src = g_arch_instruction_get_linked_source(instr, i, &src_type);
+
+ linked = pygobject_new(G_OBJECT(src));
+ lnk_type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
+ "InstructionLinkType", src_type);
+
+#ifndef NDEBUG
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
+ assert(ret == 0);
+#else
+ PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
+#endif
+
+ unref_object(src);
+
+ }
- g_arch_instruction_attach_extra_operand(instr, op);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- Py_RETURN_NONE;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : self = objet représentant une instruction. *
+* Paramètres : self = instruction d'architecture à manipuler. *
* unused = adresse non utilisée ici. *
* *
-* Description : Fournit tous les opérandes d'une instruction. *
+* Description : Fournit les destinations d'une instruction donnée. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Nombre de ces destinations. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unused)
{
PyObject *result; /* Instance à retourner */
GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre d'opérandes présents */
+ size_t count; /* Nombre de liens présents */
size_t i; /* Boucle de parcours */
- GArchOperand *operand; /* Opérande à manipuler */
- PyObject *opobj; /* Version Python */
+ GArchInstruction *dest; /* Instruction en source */
+ InstructionLinkType dest_type; /* Type de lien */
+ PyObject *linked; /* Destination de lien Python */
+ PyObject *lnk_type; /* Nature du lien en Python */
#ifndef NDEBUG
int ret; /* Bilan d'une écriture d'arg. */
#endif
+#define ARCH_INSTRUCTION_DESTINATIONS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ destinations, py_arch_instruction, \
+ "Provide the instructions list following the current instruction.\n" \
+ "\n" \
+ "Each item of the resulting tuple is a pair of" \
+ " pychrysalide.arch.ArchInstruction instance and" \
+ " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+)
+
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_operands(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- count = _g_arch_instruction_count_operands(instr);
+ count = g_arch_instruction_count_dest_links(instr);
result = PyTuple_New(count);
for (i = 0; i < count; i++)
{
- operand = _g_arch_instruction_get_operand(instr, i);
+ dest = g_arch_instruction_get_linked_destination(instr, i, &dest_type);
- opobj = pygobject_new(G_OBJECT(operand));
+ linked = pygobject_new(G_OBJECT(dest));
+ lnk_type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
+ "InstructionLinkType", dest_type);
#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
assert(ret == 0);
#else
- PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
+ PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
#endif
- g_object_unref(G_OBJECT(operand));
+ unref_object(dest);
}
- g_arch_instruction_unlock_operands(instr);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION DES OPERANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Attache un opérande supplémentaire à une instruction. *
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_attach_operand(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ GArchOperand *op; /* Opérande concerné à ajouter */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+
+#define ARCH_INSTRUCTION_ATTACH_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ attach_operand, "$self, operand, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Add an extra operand to an instruction.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "The *operand* argument has to be a pychrysalide.arch.ArchOperand" \
+ " instance." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &op);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ g_arch_instruction_attach_operand(instr, op);
+
+ result = Py_None;
+ Py_INCREF(result);
return result;
@@ -342,6 +555,21 @@ static PyObject *py_arch_instruction_replace_operand(PyObject *self, PyObject *a
GArchInstruction *instr; /* Instruction manipulée */
bool status; /* Bilan de l'opération */
+#define ARCH_INSTRUCTION_REPLACE_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ replace_operand, "$self, old, new, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Replace an old instruction operand by a another one.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "Both the *old* and *new* arguments have to be a" \
+ " pychrysalide.arch.ArchOperand instance.\n" \
+ "\n" \
+ "The status of the operation is returned as a boolean value: *True*"\
+ " if the operand has been replaced, *False* in case of failure." \
+)
+
ret = PyArg_ParseTuple(args, "O&O&", convert_to_arch_operand, &old, convert_to_arch_operand, &new);
if (!ret) return NULL;
@@ -349,9 +577,6 @@ static PyObject *py_arch_instruction_replace_operand(PyObject *self, PyObject *a
status = g_arch_instruction_replace_operand(instr, old, new);
- if (status)
- g_object_ref(G_OBJECT(new));
-
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -381,6 +606,21 @@ static PyObject *py_arch_instruction_detach_operand(PyObject *self, PyObject *ar
GArchInstruction *instr; /* Instruction manipulée */
bool status; /* Bilan de l'opération */
+#define ARCH_INSTRUCTION_DETACH_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ detach_operand, "$self, operand, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Remove an operand from the instruction.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "The *operand* argument has to be a pychrysalide.arch.ArchOperand" \
+ " instance.\n" \
+ "\n" \
+ "The status of the operation is returned as a boolean value: *True*"\
+ " if the operand has been removed, *False* in case of failure." \
+)
+
ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &target);
if (!ret) return NULL;
@@ -500,7 +740,7 @@ static PyObject *py_arch_instruction_get_operand_from_path(PyObject *self, PyObj
if (op != NULL)
{
result = pygobject_new(G_OBJECT(op));
- g_object_unref(G_OBJECT(op));
+ unref_object(op);
}
else
{
@@ -513,182 +753,258 @@ static PyObject *py_arch_instruction_get_operand_from_path(PyObject *self, PyObj
}
-
-/* ---------------------------------------------------------------------------------- */
-/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : self = instruction d'architecture à manipuler. *
+* Paramètres : self = objet représentant une instruction. *
* unused = adresse non utilisée ici. *
* *
-* Description : Fournit les origines d'une instruction donnée. *
+* Description : Fournit tous les opérandes d'une instruction. *
* *
-* Retour : Nombre de ces origines. *
+* Retour : Valeur associée à la propriété consultée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)
{
PyObject *result; /* Instance à retourner */
GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre de liens présents */
+ size_t count; /* Nombre d'opérandes présents */
size_t i; /* Boucle de parcours */
- const instr_link_t *source; /* Origine des liens */
- PyObject *linked; /* Source de lien Python */
- PyObject *type; /* Nature du lien en Python */
+ GArchOperand *operand; /* Opérande à manipuler */
+ PyObject *opobj; /* Version Python */
#ifndef NDEBUG
int ret; /* Bilan d'une écriture d'arg. */
#endif
-#define ARCH_INSTRUCTION_SOURCES_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- sources, py_arch_instruction, \
- "Provide the instructions list driving to the current instruction.\n" \
- "\n" \
- "Each item of the resulting tuple is a pair of" \
- " pychrysalide.arch.ArchInstruction instance and" \
- " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+#define ARCH_INSTRUCTION_OPERANDS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ operands, py_arch_instruction, \
+ "List of instruction attached operands.\n" \
+ "\n" \
+ "The result is a list of pychrysalide.arch.ArchOperand" \
+ " instances, which can be empty." \
)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_src(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- count = g_arch_instruction_count_sources(instr);
+ count = g_arch_instruction_count_operands(instr);
result = PyTuple_New(count);
for (i = 0; i < count; i++)
{
- source = g_arch_instruction_get_source(instr, i);
+ operand = g_arch_instruction_get_operand(instr, i);
- linked = pygobject_new(G_OBJECT(source->linked));
- type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
- "InstructionLinkType", source->type);
+ opobj = pygobject_new(G_OBJECT(operand));
#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
assert(ret == 0);
#else
- PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
+ PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
#endif
- unref_instr_link(source);
+ unref_object(operand);
}
- g_arch_instruction_unlock_src(instr);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : self = instruction d'architecture à manipuler. *
-* unused = adresse non utilisée ici. *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
* *
-* Description : Fournit les destinations d'une instruction donnée. *
+* Description : Ajoute une information complémentaire à une instruction. *
* *
-* Retour : Nombre de ces destinations. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_set_flag(PyObject *self, PyObject *args)
{
- PyObject *result; /* Instance à retourner */
- GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre de liens présents */
- size_t i; /* Boucle de parcours */
- const instr_link_t *dest; /* Destination des liens */
- PyObject *linked; /* Destination de lien Python */
- PyObject *type; /* Nature du lien en Python */
-#ifndef NDEBUG
- int ret; /* Bilan d'une écriture d'arg. */
-#endif
-
-#define ARCH_INSTRUCTION_DESTINATIONS_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- destinations, py_arch_instruction, \
- "Provide the instructions list following the current instruction.\n" \
- "\n" \
- "Each item of the resulting tuple is a pair of" \
- " pychrysalide.arch.ArchInstruction instance and" \
- " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_SET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ set_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Add some flags to the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to apply to the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
)
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_dest(instr);
+ status = g_arch_instruction_set_flag(instr, flag);
- count = g_arch_instruction_count_destinations(instr);
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
- result = PyTuple_New(count);
+ return result;
- for (i = 0; i < count; i++)
- {
- dest = g_arch_instruction_get_destination(instr, i);
+}
- linked = pygobject_new(G_OBJECT(dest->linked));
- type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
- "InstructionLinkType", dest->type);
-#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
- assert(ret == 0);
-#else
- PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
-#endif
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Retire une information complémentaire à une instruction. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_unset_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_UNSET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ unset_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Remove some flags from the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to delete from the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
+)
- unref_instr_link(dest);
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
- }
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_unlock_dest(instr);
+ status = g_arch_instruction_unset_flag(instr, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
}
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Détermine si une instruction possède un fanion particulier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-/* ---------------------------------------------------------------------------------- */
-/* INSTRUCTIONS D'ARCHITECTURES EN PYTHON */
-/* ---------------------------------------------------------------------------------- */
+static PyObject *py_arch_instruction_has_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_HAS_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ has_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Tell if some flags are set for the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to test for the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* if the bits" \
+ " are active, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ status = g_arch_instruction_has_flag(instr, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* closure = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit l'identifiant unique pour un ensemble d'instructions.*
+* Description : Fournit l'identifiant correspondant à un type d'instructions.*
* *
-* Retour : Identifiant unique par type d'instruction. *
+* Retour : Identifiant unique par type d'instruction et architecture. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_unique_id(PyObject *self, void *closure)
+static PyObject *py_arch_instruction_get_type_id(PyObject *self, void *closure)
{
- PyObject *result; /* Conversion à retourner */
- GArchInstruction *instr; /* Version native */
- itid_t uid; /* Identifiant unique associé */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ itid_t tid; /* Identifiant à transmettre */
+
+#define ARCH_INSTRUCTION_TYPE_ID_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ type_id, py_arch_instruction, \
+ "Provide the unique identifier given to this kind of" \
+ " instruction.\n" \
+ "\n" \
+ "The returned value is an integer." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- uid = g_arch_instruction_get_unique_id(instr);
+ tid = g_arch_instruction_get_type_id(instr);
- result = PyLong_FromUnsignedLong(uid);
+ result = PyLong_FromUnsignedLong(tid);
return result;
@@ -697,27 +1013,61 @@ static PyObject *py_arch_instruction_get_unique_id(PyObject *self, void *closure
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* closure = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit la place mémoire d'une instruction. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure)
+static PyObject *py_arch_instruction_get_encoding(PyObject *self, void *closure)
{
- PyObject *result; /* Conversion à retourner */
- GArchInstruction *instr; /* Version native */
- const mrange_t *range; /* Espace mémoire à exporter */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ char *encoding; /* Encodage d'une instruction */
+
+#define ARCH_INSTRUCTION_ENCODING_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ encoding, py_arch_instruction, \
+ "Describe the encoding related to an instruction.\n" \
+ "\n" \
+ "The returned value is an arbitrary string value." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- range = g_arch_instruction_get_range(instr);
- result = build_from_internal_mrange(range);
+ encoding = g_arch_instruction_get_encoding(instr);
+
+ if (encoding != NULL)
+ {
+ result = PyUnicode_FromString(encoding);
+
+ free(encoding);
+
+ }
+
+ else
+ {
+ /**
+ * La méthode de classe sollicitée a renvoyé une valeur nulle.
+ *
+ * Si cette méthode correspond à une implémentation Python
+ * (avec un appel à not_yet_implemented_method()), une exception
+ * est déjà en place.
+ *
+ * Si aucune exception n'a été prévue, un rattrapage est effectué ici.
+ */
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_NotImplementedError, _("unexpected NULL value as encoding"));
+
+ result = NULL;
+
+ }
return result;
@@ -727,59 +1077,108 @@ static PyObject *py_arch_instruction_get_range(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. *
+* closure = non utilisé ici. *
* *
-* Description : Définit la localisation d'une instruction. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Bilan de l'opération pour Python. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static int py_arch_instruction_set_range(PyObject *self, PyObject *value, void *closure)
+static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *closure)
{
- int ret; /* Bilan d'analyse */
- mrange_t *range; /* Espace mémoire à manipuler */
- GArchInstruction *instr; /* Version native */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ char *keyword; /* Désignation d'une instruct° */
+
+#define ARCH_INSTRUCTION_KEYWORD_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ keyword, py_arch_instruction, \
+ "Give the official name of the assembly instruction.\n" \
+ "\n" \
+ "The returned value is a string value." \
+)
- ret = PyObject_IsInstance(value, (PyObject *)get_python_mrange_type());
- if (!ret) return -1;
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- range = get_internal_mrange(value);
+ keyword = g_arch_instruction_get_keyword(instr);
- instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_set_range(instr, range);
+ if (keyword != NULL)
+ {
+ result = PyUnicode_FromString(keyword);
- return 0;
+ free(keyword);
+
+ }
+
+ else
+ {
+ /**
+ * La méthode de classe sollicitée a renvoyé une valeur nulle.
+ *
+ * Si cette méthode correspond à une implémentation Python
+ * (avec un appel à not_yet_implemented_method()), une exception
+ * est déjà en place.
+ *
+ * Si aucune exception n'a été prévue, un rattrapage est effectué ici.
+ */
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_NotImplementedError, _("unexpected NULL value as keyword"));
+
+ result = NULL;
+
+ }
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* unused = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Fournit la place mémoire d'une instruction. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Définition de localisation ou *None*. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure)
{
- PyObject *result; /* Trouvailles à retourner */
- GArchInstruction *instr; /* Version native */
- const char *kw; /* Valeur récupérée */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ mrange_t range; /* Localisation d'instruction */
+ bool valid; /* Validité de la localisation */
+
+#define ARCH_INSTRUCTION_RANGE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ range, py_arch_instruction, \
+ "Give access to the memory range covered by the" \
+ " current instruction.\n" \
+ "\n" \
+ "The returned value is a pychrysalide.arch.mrange" \
+ " instance or *None* if no location is currently" \
+ " defined." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- kw = g_arch_instruction_get_keyword(instr);
- result = PyUnicode_FromString(kw);
+ valid = g_arch_instruction_get_range(instr, &range);
+
+ if (valid)
+ result = build_from_internal_mrange(&range);
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -801,45 +1200,25 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)
PyTypeObject *get_python_arch_instruction_type(void)
{
static PyMethodDef py_arch_instruction_methods[] = {
- {
- "attach_operand", py_arch_instruction_attach_extra_operand,
- METH_VARARGS,
- "attach_operand($self, op, /)\n--\n\nAdd a new operand to the instruction."
- },
- {
- "replace_operand", py_arch_instruction_replace_operand,
- METH_VARARGS,
- "replace_operand($self, old, new, /)\n--\n\nReplace an old instruction operand by a another one."
- },
- {
- "detach_operand", py_arch_instruction_detach_operand,
- METH_VARARGS,
- "detach_operand($self, target, /)\n--\n\nRemove an operand from the instruction."
- },
+ ARCH_INSTRUCTION_ATTACH_OPERAND_METHOD,
+ ARCH_INSTRUCTION_REPLACE_OPERAND_METHOD,
+ ARCH_INSTRUCTION_DETACH_OPERAND_METHOD,
ARCH_INSTRUCTION_FIND_OPERAND_PATH_METHOD,
ARCH_INSTRUCTION_GET_OPERAND_FROM_PATH_METHOD,
+ ARCH_INSTRUCTION_SET_FLAG_METHOD,
+ ARCH_INSTRUCTION_UNSET_FLAG_METHOD,
+ ARCH_INSTRUCTION_HAS_FLAG_METHOD,
{ NULL }
};
static PyGetSetDef py_arch_instruction_getseters[] = {
- {
- "uid", py_arch_instruction_get_unique_id, NULL,
- "Provide the unique identification number given to this kind of instruction.", NULL
- },
- {
- "range", py_arch_instruction_get_range, py_arch_instruction_set_range,
- "Give access to the memory range covered by the current instruction.", NULL
- },
- {
- "keyword", (getter)py_arch_instruction_get_keyword, (setter)NULL,
- "Give le name of the assembly instruction.", NULL
- },
- {
- "operands", (getter)py_arch_instruction_get_operands, (setter)NULL,
- "Provide the list of instruction attached operands.", NULL
- },
ARCH_INSTRUCTION_SOURCES_ATTRIB,
ARCH_INSTRUCTION_DESTINATIONS_ATTRIB,
+ ARCH_INSTRUCTION_OPERANDS_ATTRIB,
+ ARCH_INSTRUCTION_TYPE_ID_ATTRIB,
+ ARCH_INSTRUCTION_ENCODING_ATTRIB,
+ ARCH_INSTRUCTION_KEYWORD_ATTRIB,
+ ARCH_INSTRUCTION_RANGE_ATTRIB,
{ NULL }
};
@@ -852,7 +1231,7 @@ PyTypeObject *get_python_arch_instruction_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide instruction for a given architecture.",
+ .tp_doc = ARCH_INSTRUCTION_DOC,
.tp_methods = py_arch_instruction_methods,
.tp_getset = py_arch_instruction_getseters,
@@ -893,9 +1272,14 @@ bool ensure_python_arch_instruction_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_line_generator_is_registered())
+ if (!ensure_python_thick_object_is_registered())
return false;
+ if (!ensure_python_serializable_object_is_registered())
+ return false;
+
+ pyg_register_class_init(G_TYPE_ARCH_INSTRUCTION, (PyGClassInitFunc)py_arch_instruction_init_gclass);
+
if (!register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, type))
return false;
diff --git a/plugins/pychrysalide/arch/instructions/Makefile.am b/plugins/pychrysalide/arch/instructions/Makefile.am
index 65efe42..29c2a45 100644
--- a/plugins/pychrysalide/arch/instructions/Makefile.am
+++ b/plugins/pychrysalide/arch/instructions/Makefile.am
@@ -7,7 +7,8 @@ libpychrysaarchinstructions_la_SOURCES = \
raw.h raw.c \
undefined.h undefined.c
-libpychrysaarchinstructions_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+libpychrysaarchinstructions_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ $(TOOLKIT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/arch/instructions/constants.c b/plugins/pychrysalide/arch/instructions/constants.c
index af7baa9..257c501 100644
--- a/plugins/pychrysalide/arch/instructions/constants.c
+++ b/plugins/pychrysalide/arch/instructions/constants.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.c - ajout des constantes de base pour les instructions
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -112,3 +112,59 @@ bool define_undefined_instruction_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 ExpectedBehavior. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_undefined_expected_behavior(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 ExpectedBehavior");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if (value > IEB_RESERVED)
+ {
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ExpectedBehavior");
+ result = 0;
+ }
+
+ else
+ *((InstrExpectedBehavior *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/instructions/constants.h b/plugins/pychrysalide/arch/instructions/constants.h
index 2f0c587..b6ef9a4 100644
--- a/plugins/pychrysalide/arch/instructions/constants.h
+++ b/plugins/pychrysalide/arch/instructions/constants.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.h - prototypes pour l'ajout des constantes de base pour les instructions
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -37,6 +37,9 @@ bool define_raw_instruction_constants(PyTypeObject *);
/* Définit les constantes liées aux comportements erratiques. */
bool define_undefined_instruction_constants(PyTypeObject *);
+/* Tente de convertir en constante ExpectedBehavior. */
+int convert_to_undefined_expected_behavior(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/instructions/raw.c b/plugins/pychrysalide/arch/instructions/raw.c
index 7e58b96..ae730e8 100644
--- a/plugins/pychrysalide/arch/instructions/raw.c
+++ b/plugins/pychrysalide/arch/instructions/raw.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* raw.c - équivalent Python du fichier "arch/instructions/raw.h"
*
- * Copyright (C) 2018-2020 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,26 +28,33 @@
#include <pygobject.h>
-#include <i18n.h>
-#include <arch/instructions/raw.h>
-#include <plugins/dt.h>
+#include <arch/instructions/raw-int.h>
#include "constants.h"
#include "../instruction.h"
#include "../vmpa.h"
#include "../../access.h"
+#include "../../constants.h"
#include "../../helpers.h"
#include "../../analysis/content.h"
+#include "../../glibext/portion.h"
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_raw_instruction_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(raw_instruction, G_TYPE_RAW_INSTRUCTION);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_raw_instruction_init(PyObject *, PyObject *, PyObject *);
+
+
+/* ------------------------ FONCTIONNALITES DE L'INSTRUCTION ------------------------ */
+
+
/* Indique si le contenu de l'instruction est du bourrage. */
static PyObject *py_raw_instruction_get_padding(PyObject *, void *);
@@ -62,64 +69,9 @@ static int py_raw_instruction_set_string(PyObject *, PyObject *, void *);
-/******************************************************************************
-* *
-* 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_raw_instruction_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 */
-
- /* Validations diverses */
-
- base = get_python_raw_instruction_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_RAW_INSTRUCTION, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
-
- 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;
-
-}
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -139,20 +91,17 @@ static PyObject *py_raw_instruction_new(PyTypeObject *type, PyObject *args, PyOb
static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
int result; /* Bilan à retourner */
+ GBinaryPortion *area; /* Zone de contenance */
vmpa2t *addr; /* Texte de lecture */
- unsigned long mem_size; /* Taille de portion brute */
+ MemoryDataSize size; /* Taille de portion brute */
unsigned long long value; /* Valeur brute à considérer */
GBinContent *content; /* Contenu à lire au besoin */
unsigned long count; /* Nombre d'éléments à lister */
- unsigned int endian; /* Type de boutisme impliqué */
+ SourceEndian endian; /* Type de boutisme impliqué */
int ret; /* Bilan de lecture des args. */
- GArchInstruction *fake; /* Instruction à copier */
- GArchInstruction *instr; /* Instruction à manipuler */
- size_t op_count; /* Nombre d'opérande à copier */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à transférer */
+ GRawInstruction *instr; /* Instruction à manipuler */
- static char *kwlist[] = { "addr", "mem_size", "value", "content", "count", "endian", NULL };
+ static char *kwlist[] = { "area", "addr", "size", "value", "content", "count", "endian", NULL };
#define RAW_INSTRUCTION_DOC \
"The RawInstruction object handles data which is not (yet?) disassembled" \
@@ -187,9 +136,14 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
count = 0;
endian = 0;
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&k|KO&kI", kwlist,
- convert_any_to_vmpa, &addr, &mem_size,
- &value, convert_to_binary_content, &content, &count, &endian);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&|KO&kO&", kwlist,
+ convert_to_binary_portion, &area,
+ convert_any_to_vmpa, &addr,
+ convert_to_memory_data_size, &size,
+ &value,
+ convert_to_binary_content, &content,
+ &count,
+ convert_to_source_endian, &endian);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -199,35 +153,19 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
/* Eléments de base */
- if (content != NULL)
- fake = g_raw_instruction_new_array(content, mem_size, count, addr, endian);
- else
- fake = g_raw_instruction_new_from_value(addr, mem_size, value);
+ instr = G_RAW_INSTRUCTION(pygobject_get(self));
- if (fake == NULL)
+ if (content != NULL)
{
- PyErr_SetString(PyExc_ValueError, _("Unable to build the object with the given parameters."));
- goto clean_exit;
+ if (!g_raw_instruction_create_array(instr, area, addr, size, content, count, endian))
+ goto clean_exit;
}
-
- instr = G_ARCH_INSTRUCTION(pygobject_get(self));
-
- g_arch_instruction_lock_operands(fake);
-
- op_count = _g_arch_instruction_count_operands(fake);
-
- for (i = 0; i < op_count; i++)
+ else
{
- op = _g_arch_instruction_get_operand(fake, i);
- g_arch_instruction_attach_extra_operand(instr, op);
+ if (!g_raw_instruction_create_value(instr, area, addr, size, value))
+ goto clean_exit;
}
- g_arch_instruction_unlock_operands(fake);
-
- g_arch_instruction_set_range(instr, g_arch_instruction_get_range(fake));
-
- g_object_unref(G_OBJECT(fake));
-
result = 0;
clean_exit:
@@ -239,6 +177,12 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
}
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES DE L'INSTRUCTION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une instruction. *
@@ -271,7 +215,6 @@ static PyObject *py_raw_instruction_get_padding(PyObject *self, void *closure)
result = state ? Py_True : Py_False;
Py_INCREF(result);
-
return result;
}
@@ -342,7 +285,6 @@ static PyObject *py_raw_instruction_get_string(PyObject *self, void *closure)
result = state ? Py_True : Py_False;
Py_INCREF(result);
-
return result;
}
diff --git a/plugins/pychrysalide/arch/instructions/undefined.c b/plugins/pychrysalide/arch/instructions/undefined.c
index 1246daa..1c2bccc 100644
--- a/plugins/pychrysalide/arch/instructions/undefined.c
+++ b/plugins/pychrysalide/arch/instructions/undefined.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.c - équivalent Python du fichier "arch/instructions/undefined.h"
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,9 +28,7 @@
#include <pygobject.h>
-#include <i18n.h>
#include <arch/instructions/undefined-int.h>
-#include <plugins/dt.h>
#include "constants.h"
@@ -40,75 +38,27 @@
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_undef_instruction_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_undef_instruction_init(PyObject *, PyObject *, PyObject *);
-
-/* Indique le type de conséquences réél de l'instruction. */
-static PyObject *py_undef_instruction_get_behavior(PyObject *, void *);
-
-
-
-/******************************************************************************
-* *
-* 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_undef_instruction_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 */
-
- /* Validations diverses */
- base = get_python_undefined_instruction_type();
+CREATE_DYN_CONSTRUCTOR(undefined_instruction, G_TYPE_UNDEFINED_INSTRUCTION);
- 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_UNDEF_INSTRUCTION, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_undefined_instruction_init(PyObject *, PyObject *, PyObject *);
- if (!status)
- {
- result = NULL;
- goto exit;
- }
- }
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+/* ------------------------ FONCTIONNALITES DE L'INSTRUCTION ------------------------ */
- simple_way:
- result = PyType_GenericNew(type, args, kwds);
+/* Indique le type de conséquences réél de l'instruction. */
+static PyObject *py_undefined_instruction_get_behavior(PyObject *, void *);
- exit:
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -125,30 +75,27 @@ static PyObject *py_undef_instruction_new(PyTypeObject *type, PyObject *args, Py
* *
******************************************************************************/
-static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
+static int py_undefined_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- unsigned long behavior; /* Conséquence pour l'instruct°*/
+ InstrExpectedBehavior behavior; /* Conséquence pour l'instruct°*/
int ret; /* Bilan de lecture des args. */
- GUndefInstruction *instr; /* Instruction à manipuler */
- undef_extra_data_t *extra; /* Données insérées à modifier */
+ GUndefinedInstruction *instr; /* Instruction à manipuler */
- static char *kwlist[] = { "behavior", NULL };
-
-#define UNDEF_INSTRUCTION_DOC \
- "UndefInstruction represents all kinds of instructions which are" \
+#define UNDEFINED_INSTRUCTION_DOC \
+ "UndefinedInstruction represents all kinds of instructions which are" \
" officially not part of a runnable instruction set.\n" \
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " UndefInstruction(behavior)" \
+ " UndefinedInstruction(behavior)" \
"\n" \
"Where behavior is a" \
- " pychrysalide.arch.instructions.UndefInstruction.ExpectedBehavior" \
+ " pychrysalide.arch.instructions.UndefinedInstruction.ExpectedBehavior" \
" constant describing the state of the CPU once the instruction is run."
/* Récupération des paramètres */
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "k", kwlist, &behavior);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_undefined_expected_behavior, &behavior);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -158,17 +105,22 @@ static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *k
/* Eléments de base */
- instr = G_UNDEF_INSTRUCTION(pygobject_get(self));
-
- extra = GET_UNDEF_INSTR_EXTRA(instr);
+ instr = G_UNDEFINED_INSTRUCTION(pygobject_get(self));
- extra->behavior = behavior;
+ if (!g_undefined_instruction_create(instr, behavior))
+ return -1;
return 0;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES DE L'INSTRUCTION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une instruction. *
@@ -182,24 +134,25 @@ static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *k
* *
******************************************************************************/
-static PyObject *py_undef_instruction_get_behavior(PyObject *self, void *closure)
+static PyObject *py_undefined_instruction_get_behavior(PyObject *self, void *closure)
{
PyObject *result; /* Conversion à retourner */
- GUndefInstruction *instr; /* Version native */
+ GUndefinedInstruction *instr; /* Version native */
InstrExpectedBehavior behavior; /* Comportement attendu */
-#define UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- behavior, py_undef_instruction, \
- "Consequence carried by the undefined instruction.\n" \
- "\n" \
- "The result is provided as a" \
- " pychrysalide.arch.instructions.UndefInstruction.ExpectedBehavior" \
- " constant." \
+#define UNDEFINED_INSTRUCTION_BEHAVIOR_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ behavior, py_undefined_instruction, \
+ "Consequence carried by the undefined instruction.\n" \
+ "\n" \
+ "The result is provided as a" \
+ " pychrysalide.arch.instructions.UndefinedInstruction.ExpectedBehavior" \
+ " constant." \
)
- instr = G_UNDEF_INSTRUCTION(pygobject_get(self));
- behavior = g_undef_instruction_get_behavior(instr);
+ instr = G_UNDEFINED_INSTRUCTION(pygobject_get(self));
+
+ behavior = g_undefined_instruction_get_behavior(instr);
result = cast_with_constants_group_from_type(get_python_undefined_instruction_type(),
"ExpectedBehavior", behavior);
@@ -228,7 +181,7 @@ PyTypeObject *get_python_undefined_instruction_type(void)
};
static PyGetSetDef py_undefined_instruction_getseters[] = {
- UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB,
+ UNDEFINED_INSTRUCTION_BEHAVIOR_ATTRIB,
{ NULL }
};
@@ -236,18 +189,18 @@ PyTypeObject *get_python_undefined_instruction_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.instructions.UndefInstruction",
+ .tp_name = "pychrysalide.arch.instructions.UndefinedInstruction",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = UNDEF_INSTRUCTION_DOC,
+ .tp_doc = UNDEFINED_INSTRUCTION_DOC,
.tp_methods = py_undefined_instruction_methods,
.tp_getset = py_undefined_instruction_getseters,
- .tp_init = py_undef_instruction_init,
- .tp_new = py_undef_instruction_new,
+ .tp_init = py_undefined_instruction_init,
+ .tp_new = py_undefined_instruction_new,
};
@@ -260,7 +213,7 @@ PyTypeObject *get_python_undefined_instruction_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.....UndefInstruction'. *
+* Description : Prend en charge l'objet '....UndefinedInstruction'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -285,7 +238,7 @@ bool ensure_python_undefined_instruction_is_registered(void)
if (!ensure_python_arch_instruction_is_registered())
return false;
- if (!register_class_for_pygobject(dict, G_TYPE_UNDEF_INSTRUCTION, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_UNDEFINED_INSTRUCTION, type))
return false;
if (!define_undefined_instruction_constants(type))
@@ -329,7 +282,7 @@ int convert_to_undefined_instruction(PyObject *arg, void *dst)
break;
case 1:
- *((GUndefInstruction **)dst) = G_UNDEF_INSTRUCTION(pygobject_get(arg));
+ *((GUndefinedInstruction **)dst) = G_UNDEFINED_INSTRUCTION(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/arch/instructions/undefined.h b/plugins/pychrysalide/arch/instructions/undefined.h
index 3fa0453..1453612 100644
--- a/plugins/pychrysalide/arch/instructions/undefined.h
+++ b/plugins/pychrysalide/arch/instructions/undefined.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.h - prototypes pour l'équivalent Python du fichier "arch/instructions/undefined.h"
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -34,7 +34,7 @@
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_undefined_instruction_type(void);
-/* Prend en charge l'objet 'pychrysalide.arch.instructions.UndefInstruction'. */
+/* Prend en charge l'objet 'pychrysalide.arch.instructions.UndefinedInstruction'. */
bool ensure_python_undefined_instruction_is_registered(void);
/* Tente de convertir en instruction non définie. */
diff --git a/plugins/pychrysalide/arch/module-ui.c b/plugins/pychrysalide/arch/module-ui.c
new file mode 100644
index 0000000..65d1290
--- /dev/null
+++ b/plugins/pychrysalide/arch/module-ui.c
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire arch (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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 "module-ui.h"
+
+
+#include <assert.h>
+
+
+#include "operand-ui.h"
+#include "../glibext/generator.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les objets du module 'arch' (mode UI). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_arch_module_ui(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_arch_operand_ui_is_registered();
+
+ /**
+ * Préparation du terrain pour les instructions, sans lien directe
+ * de la partie UI depuis la partie NOX.
+ */
+ if (result) result = ensure_python_token_generator_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/module-ui.h b/plugins/pychrysalide/arch/module-ui.h
new file mode 100644
index 0000000..afa31d2
--- /dev/null
+++ b/plugins/pychrysalide/arch/module-ui.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire arch (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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_ARCH_MODULE_UI_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_MODULE_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Intègre les objets du module 'arch' (mode UI). */
+bool populate_arch_module_ui(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_MODULE_UI_H */
diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c
index 0127348..94f5ad7 100644
--- a/plugins/pychrysalide/arch/module.c
+++ b/plugins/pychrysalide/arch/module.c
@@ -31,16 +31,14 @@
/*
#include "context.h"
#include "instriter.h"
+*/
#include "instruction.h"
#include "operand.h"
-#include "processor.h"
+//#include "processor.h"
#include "register.h"
-*/
#include "vmpa.h"
-/*
#include "instructions/module.h"
#include "operands/module.h"
-*/
#include "../helpers.h"
@@ -77,10 +75,8 @@ bool add_arch_module(PyObject *super)
result = (module != NULL);
- /*
if (result) result = add_arch_instructions_module(module);
if (result) result = add_arch_operands_module(module);
- */
return result;
@@ -108,18 +104,16 @@ bool populate_arch_module(void)
/*
if (result) result = ensure_python_proc_context_is_registered();
if (result) result = ensure_python_instr_iterator_is_registered();
+ */
if (result) result = ensure_python_arch_instruction_is_registered();
if (result) result = ensure_python_arch_operand_is_registered();
- if (result) result = ensure_python_arch_processor_is_registered();
+ //if (result) result = ensure_python_arch_processor_is_registered();
if (result) result = ensure_python_arch_register_is_registered();
- */
if (result) result = ensure_python_vmpa_is_registered();
if (result) result = ensure_python_mrange_is_registered();
- /*
if (result) result = populate_arch_instructions_module();
if (result) result = populate_arch_operands_module();
- */
assert(result);
diff --git a/plugins/pychrysalide/arch/operand-ui.c b/plugins/pychrysalide/arch/operand-ui.c
new file mode 100644
index 0000000..5062513
--- /dev/null
+++ b/plugins/pychrysalide/arch/operand-ui.c
@@ -0,0 +1,461 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand-ui.c - équivalent Python du fichier "arch/operand-ui.c"
+ *
+ * Copyright (C) 2025 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 "operand-ui.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <arch/operand-ui-int.h>
+
+
+#include "../access.h"
+#include "../helpers.h"
+
+
+
+/* Procède à l'initialisation de l'interface d'exportation. */
+static void py_arch_operand_ui_interface_init(GArchOperandUIInterface *, gpointer *);
+
+/* Traduit un opérande en version humainement lisible. */
+static void py_arch_operand_ui_print_wrapper(const GArchOperandUI *, GBufferLine *);
+
+/* Construit un petit résumé concis de l'opérande. */
+static char *py_arch_operand_ui_build_tooltip_wrapper(const GArchOperandUI *, const GLoadedBinary *);
+
+/* Traduit un opérande en version humainement lisible. */
+static PyObject *py_arch_operand_ui_print(PyObject *, PyObject *);
+
+/* Construit un petit résumé concis de l'opérande. */
+static PyObject *py_arch_operand_ui_build_tooltip(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
+* *
+* Description : Procède à l'initialisation de l'interface d'exportation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_arch_operand_ui_interface_init(GArchOperandUIInterface *iface, gpointer *unused)
+{
+#define ARCH_OPERAND_UI_DOC \
+ "The ArchOperandUI interface ensure pychrysalide.arch.ArchOperand" \
+ " implementations provide UI features when Chrysalide is running with" \
+ " a GUI.\n" \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(ArchOperand, ArchOperandUi):\n" \
+ " ...\n" \
+ "\n" \
+ "The following method has to be defined for new implementations:\n" \
+ "* pychrysalide.arch.ArchOperandUI._print();\n" \
+ "* pychrysalide.arch.ArchOperandUI._build_tooltip().\n"
+
+ iface->print = py_arch_operand_ui_print_wrapper;
+ iface->build_tooltip = py_arch_operand_ui_build_tooltip_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = registre visé par la procédure. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_arch_operand_ui_print_wrapper(const GArchOperandUI *operand, 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_OPERAND_UI_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _print, "$self, line, /", \
+ METH_VARARGS, \
+ "Abstract method used to print an operand into a rendering" \
+ " *line*, which is a provided pychrysalide.glibext.BufferLine" \
+ " instance." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(operand));
+
+ 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_XDECREF(pyret);
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* binary = informations relatives au binaire chargé. *
+* *
+* Description : Construit un petit résumé concis de l'opérande. *
+* *
+* Retour : Chaîne de caractères à libérer après usage ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_arch_operand_ui_build_tooltip_wrapper(const GArchOperandUI *operand, const GLoadedBinary *binary)
+{
+ char *result; /* Description à 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_OPERAND_UI_BUILD_TOOLTIP_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _build_tooltip, "$self, binary, /", \
+ METH_VARARGS, \
+ "Abstract method used to build a tooltip text shown when the" \
+ " mouse is over an operand.\n" \
+ "\n" \
+ "A pychrysalide.analysis.LoadedBinary instance is provided in" \
+ " case of need." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(operand));
+
+ if (has_python_method(pyobj, "_build_tooltip"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary)));
+
+ pyret = run_python_method(pyobj, "_build_tooltip", args);
+
+ if (pyret != NULL)
+ {
+ if (PyUnicode_Check(pyret))
+ result = strdup(PyUnicode_AsUTF8(pyret));
+ }
+
+ Py_XDECREF(pyret);
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet manipulé ici. *
+* args = adresse non utilisée ici. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_ui_print(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Emplacement à retourner */
+
+#if 0 // TODO
+
+ GBufferLine *line; /* Zone d'impression du rendu */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperandUI *operand; /* Mécanismes natifs */
+
+#define ARCH_OPERAND_UI_PRINT_METHOD PYTHON_METHOD_DEF \
+( \
+ print, "$self, line", \
+ METH_VARARGS, py_arch_operand_ui, \
+ "Translate an operand into a human readable version.\n" \
+ "\n" \
+ "The *line* arguement is a pychrysalide.glibext.BufferLine" \
+ " instance which has to get filled with rendering" \
+ " information.\n" \
+ "\n" \
+ "The result returns nothing (*None*)." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_buffer_line, &line);
+ if (!ret) return NULL;
+
+ operand = G_ARCH_OPERAND_UI(pygobject_get(self));
+
+ g_arch_operand_ui_print(operand, line);
+
+#endif
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet manipulé ici. *
+* args = adresse non utilisée ici. *
+* *
+* Description : Construit un petit résumé concis de l'opérande. *
+* *
+* Retour : Chaîne de caractères à libérer après usage ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_ui_build_tooltip(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Emplacement à retourner */
+
+#if 0 // TODO
+
+ GLoadedBinary *binary; /* Infos sur le binaire chargé */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperandUI *operand; /* Mécanismes natifs */
+ char *tooltip; /* Eventuelle indication */
+
+#define ARCH_OPERAND_UI_BUILD_TOOLTIP_METHOD PYTHON_METHOD_DEF \
+( \
+ build_tooltip, "$self, binary", \
+ METH_VARARGS, py_arch_operand_ui, \
+ "Build a tooltip text shown when the mouse is over an" \
+ " operand.\n" \
+ "\n" \
+ "The *binary* argument is a pychrysalide.analysis.LoadedBinary" \
+ " instance provided in case of need." \
+ "\n" \
+ "The result is a string or *None* in case of error." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_loaded_binary, &binary);
+ if (!ret) return NULL;
+
+ operand = G_ARCH_OPERAND_UI(pygobject_get(self));
+
+ tooltip = g_arch_operand_ui_build_tooltip(operand, binary);
+
+ if (tooltip != NULL)
+ {
+ PyUnicode_FromString(tooltip);
+ free(tooltip);
+ }
+ else
+
+#endif
+
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_arch_operand_ui_type(void)
+{
+ static PyMethodDef py_arch_operand_ui_methods[] = {
+ ARCH_OPERAND_UI_PRINT_WRAPPER,
+ ARCH_OPERAND_UI_BUILD_TOOLTIP_WRAPPER,
+#if 0 // TODO
+ ARCH_OPERAND_UI_PRINT_METHOD,
+ ARCH_OPERAND_UI_BUILD_TOOLTIP_METHOD,
+#endif
+ { NULL }
+ };
+
+ static PyGetSetDef py_arch_operand_ui_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_arch_operand_ui_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.arch.ArchOperandUI",
+ .tp_basicsize = sizeof(PyObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = ARCH_OPERAND_UI_DOC,
+
+ .tp_methods = py_arch_operand_ui_methods,
+ .tp_getset = py_arch_operand_ui_getseters
+
+ };
+
+ return &py_arch_operand_ui_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.arch.ArchOperandUI'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_arch_operand_ui_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'ArchOperandUI' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_arch_operand_ui_interface_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
+ type = get_python_arch_operand_ui_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.arch");
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_interface_for_pygobject(dict, G_TYPE_ARCH_OPERAND_UI, type, &info))
+ return false;
+
+ }
+
+ 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 interface d'exportation graphique. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_arch_operand_ui(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_arch_operand_ui_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 UI arch operand");
+ break;
+
+ case 1:
+ *((GArchOperandUI **)dst) = G_ARCH_OPERAND_UI(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/operand-ui.h b/plugins/pychrysalide/arch/operand-ui.h
new file mode 100644
index 0000000..b9e2131
--- /dev/null
+++ b/plugins/pychrysalide/arch/operand-ui.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand-ui.h - prototypes pour l'équivalent Python du fichier "arch/operand-ui.h"
+ *
+ * Copyright (C) 2025 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_ARCH_OPERAND_UI_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERAND_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_arch_operand_ui_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.arch.ArchOperandUI'. */
+bool ensure_python_arch_operand_ui_is_registered(void);
+
+/* Tente de convertir en interface d'exportation graphique. */
+int convert_to_arch_operand_ui(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERAND_UI_H */
diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c
index 0aee4f7..2281dae 100644
--- a/plugins/pychrysalide/arch/operand.c
+++ b/plugins/pychrysalide/arch/operand.c
@@ -30,23 +30,32 @@
#include <i18n.h>
#include <arch/operand-int.h>
-#include <plugins/dt.h>
+#include <glibext/strbuilder-int.h>
#include "../access.h"
#include "../helpers.h"
+#include "../glibext/comparable.h"
+#include "../glibext/hashable.h"
+#include "../glibext/objhole.h"
+#include "../glibext/serialize.h"
#include "../glibext/singleton.h"
+#include "../glibext/strbuilder.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_arch_operand_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe générique des opérandes. */
-static void py_arch_operand_init_gclass(GArchOperandClass *, gpointer);
+static int py_arch_operand_init_gclass(GArchOperandClass *, PyTypeObject *);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_operand, G_TYPE_ARCH_OPERAND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_arch_operand_init(PyObject *, PyObject *, PyObject *);
+
+#if 0
/* Compare un opérande avec un autre. */
static int py_arch_operand___cmp___wrapper(const GArchOperand *, const GArchOperand *, bool);
@@ -57,14 +66,6 @@ static char *py_arch_operand_find_inner_operand_path_wrapper(const GArchOperand
/* Obtient l'opérande correspondant à un chemin donné. */
static GArchOperand *py_arch_operand_get_inner_operand_from_path_wrapper(const GArchOperand *, const char *);
-/* Traduit un opérande en version humainement lisible. */
-static void py_arch_operand_print_wrapper(const GArchOperand *, GBufferLine *);
-
-#ifdef INCLUDE_GTK_SUPPORT
-
-/* Construit un petit résumé concis de l'opérande. */
-static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *, const GLoadedBinary *);
-
#endif
@@ -72,6 +73,9 @@ static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *, const G
/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */
+#if 0
+
+
/* Effectue une comparaison avec un objet Python 'ArchOperand'. */
static PyObject *py_arch_operand_richcompare(PyObject *, PyObject *, int);
@@ -81,6 +85,19 @@ static PyObject *py_arch_operand_find_inner_operand_path(PyObject *, PyObject *)
/* Obtient l'opérande correspondant à un chemin donné. */
static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *, PyObject *);
+#endif
+
+
+/* Ajoute une information complémentaire à un opérande. */
+static PyObject *py_arch_operand_set_flag(PyObject *, PyObject *);
+
+/* Retire une information complémentaire à un opérande. */
+static PyObject *py_arch_operand_unset_flag(PyObject *, PyObject *);
+
+/* Détermine si un opérande possède un fanion particulier. */
+static PyObject *py_arch_operand_has_flag(PyObject *, PyObject *);
+
+
/* ---------------------------------------------------------------------------------- */
@@ -90,113 +107,109 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *, PyObjec
/******************************************************************************
* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* Paramètres : gclass = classe GLib à initialiser. *
+* pyclass = classe Python à initialiser. *
* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
+* Description : Initialise la classe générique des opérandes. *
* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* Retour : 0 pour indiquer un succès de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_arch_operand_init_gclass(GArchOperandClass *gclass, PyTypeObject *pyclass)
{
- 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 ARCH_OPERAND_DOC \
- "The ArchOperand object aims to get subclassed to create" \
- " operands of any kind 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.__cmp__();\n" \
- "* pychrysalide.arch.ArchRegister._print();\n" \
- "* pychrysalide.arch.ArchRegister._build_tooltip().\n" \
- "\n" \
- "Some extra method definitions are optional for new classes:\n" \
- "* pychrysalide.arch.ArchRegister._find_inner_operand_path();\n" \
- "* pychrysalide.arch.ArchRegister._get_inner_operand_from_path().\n"\
- "\n" \
- "Chrysalide creates an internal glue to provide rich comparisons" \
- " for operands based on the old-style *__cmp__* function."
- /* Validations diverses */
+#if 0
+ GStringBuilderInterface *iface; /* Interface utilisée */
- base = get_python_arch_operand_type();
+ iface = g_type_interface_peek(gclass, G_TYPE_STRING_BUILDER);
- if (type == base)
- {
- result = NULL;
- PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
- goto exit;
- }
- /* Mise en place d'un type dédié */
+ /*
+ printf("???????? init Python Operand ?????????????? -> class: %p '%s' - strbuilder iface: %p\n",
+ gclass, g_type_name(G_TYPE_FROM_CLASS(gclass)), iface);
+ */
- first_time = (g_type_from_name(type->tp_name) == 0);
+#endif
- gtype = build_dynamic_type(G_TYPE_ARCH_OPERAND, type->tp_name,
- (GClassInitFunc)py_arch_operand_init_gclass, NULL, NULL);
+#if 0
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
+ class->compare = py_arch_operand___cmp___wrapper;
+ class->find_inner = py_arch_operand_find_inner_operand_path_wrapper;
+ class->get_inner = py_arch_operand_get_inner_operand_from_path_wrapper;
- if (!status)
- {
- result = NULL;
- goto exit;
- }
- }
+#endif
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
- result = PyType_GenericNew(type, args, kwds);
- exit:
+ //PY_CLASS_SET_WRAPPER(gclass->xxx, py_arch_operand_xxx_wrapper);
- return result;
+ return 0;
}
/******************************************************************************
* *
-* Paramètres : class = classe à initialiser. *
-* unused = données non utilisées ici. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Initialise la classe générique des opérandes. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : - *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unused)
+static int py_arch_operand_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- class->compare = py_arch_operand___cmp___wrapper;
- class->find_inner = py_arch_operand_find_inner_operand_path_wrapper;
- class->get_inner = py_arch_operand_get_inner_operand_from_path_wrapper;
+ //unsigned int endianness; /* Boutisme du processeur */
+ int ret; /* Bilan de lecture des args. */
+ //GArchProcessor *proc; /* Processeur à manipuler */
- class->print = py_arch_operand_print_wrapper;
-#ifdef INCLUDE_GTK_SUPPORT
- class->build_tooltip = py_arch_operand_build_tooltip_wrapper;
-#endif
+#define ARCH_OPERAND_DOC \
+ "The ArchOperand object aims to get subclassed to create" \
+ " operands of any kind 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.__cmp__();\n" \
+ "* pychrysalide.arch.ArchRegister._print();\n" \
+ "* pychrysalide.arch.ArchRegister._build_tooltip().\n" \
+ "\n" \
+ "Some extra method definitions are optional for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister._find_inner_operand_path();\n" \
+ "* pychrysalide.arch.ArchRegister._get_inner_operand_from_path().\n"\
+ "\n" \
+ "Chrysalide creates an internal glue to provide rich comparisons" \
+ " for operands based on the old-style *__cmp__* function."
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ //proc = G_ARCH_PROCESSOR(pygobject_get(self));
+
+ //proc->endianness = endianness;
+
+ return 0;
}
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : a = premier opérande à consulter. *
@@ -410,126 +423,6 @@ static GArchOperand *py_arch_operand_get_inner_operand_from_path_wrapper(const G
}
-/******************************************************************************
-* *
-* Paramètres : operand = registre visé par la procédure. *
-* *
-* Description : Traduit un opérande en version humainement lisible. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void py_arch_operand_print_wrapper(const GArchOperand *operand, 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_OPERAND_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
-( \
- _print, "$self, line, /", \
- METH_VARARGS, \
- "Abstract method used to print the operand into a rendering" \
- " line, which is a provided pychrysalide.glibext.BufferLine" \
- " instance." \
-)
-
- gstate = PyGILState_Ensure();
-
- pyobj = pygobject_new(G_OBJECT(operand));
-
- 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_XDECREF(pyret);
-
- Py_DECREF(args);
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
-}
-
-
-#ifdef INCLUDE_GTK_SUPPORT
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* binary = informations relatives au binaire chargé. *
-* *
-* Description : Construit un petit résumé concis de l'opérande. *
-* *
-* Retour : Chaîne de caractères à libérer après usage ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *operand, const GLoadedBinary *binary)
-{
- char *result; /* Description à 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_OPERAND_BUILD_TOOLTIP_WRAPPER PYTHON_WRAPPER_DEF \
-( \
- _build_tooltip, "$self, line, /", \
- METH_VARARGS, \
- "Abstract method used to build a tooltip text shown when the" \
- " mouse is over the operand.\n" \
- "\n" \
- "A pychrysalide.analysis.LoadedBinary instance is provided in" \
- " case of need." \
-)
-
- result = NULL;
-
- gstate = PyGILState_Ensure();
-
- pyobj = pygobject_new(G_OBJECT(operand));
-
- if (has_python_method(pyobj, "_build_tooltip"))
- {
- args = PyTuple_New(1);
- PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary)));
-
- pyret = run_python_method(pyobj, "_build_tooltip", args);
-
- if (pyret != NULL)
- {
- if (PyUnicode_Check(pyret))
- result = strdup(PyUnicode_AsUTF8(pyret));
- }
-
- Py_XDECREF(pyret);
-
- Py_DECREF(args);
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
- return result;
-
-}
-
#endif
@@ -540,6 +433,9 @@ static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *operand,
/* ---------------------------------------------------------------------------------- */
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : a = premier object Python à consulter. *
@@ -701,6 +597,164 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *self, PyO
}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Ajoute une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_set_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_SET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ set_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Add some flags to the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to apply to the operand state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_set_flag(operand, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Retire une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_unset_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_UNSET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ unset_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Remove some flags from the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to delete from the operand state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_unset_flag(operand, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Détermine si un opérande possède un fanion particulier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_has_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_HAS_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ has_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Tell if some flags are set for the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to test for the operand state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* if the bits" \
+ " are active, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_has_flag(operand, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
/******************************************************************************
* *
@@ -717,6 +771,11 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *self, PyO
PyTypeObject *get_python_arch_operand_type(void)
{
static PyMethodDef py_arch_operand_methods[] = {
+ ARCH_OPERAND_SET_FLAG_METHOD,
+ ARCH_OPERAND_UNSET_FLAG_METHOD,
+ ARCH_OPERAND_HAS_FLAG_METHOD,
+
+ /*
ARCH_OPERAND_CMP_WRAPPER,
ARCH_OPERAND_FIND_INNER_OPERAND_PATH_WRAPPER,
ARCH_OPERAND_GET_INNER_OPERAND_FROM_PATH_WRAPPER,
@@ -726,6 +785,7 @@ PyTypeObject *get_python_arch_operand_type(void)
#endif
ARCH_OPERAND_FIND_INNER_OPERAND_PATH_METHOD,
ARCH_OPERAND_GET_INNER_OPERAND_FROM_PATH_METHOD,
+ */
{ NULL }
};
@@ -744,11 +804,12 @@ PyTypeObject *get_python_arch_operand_type(void)
.tp_doc = ARCH_OPERAND_DOC,
- .tp_richcompare = py_arch_operand_richcompare,
+ //.tp_richcompare = py_arch_operand_richcompare,
.tp_methods = py_arch_operand_methods,
.tp_getset = py_arch_operand_getseters,
+ .tp_init = py_arch_operand_init,
.tp_new = py_arch_operand_new,
};
@@ -784,9 +845,26 @@ bool ensure_python_arch_operand_is_registered(void)
dict = PyModule_GetDict(module);
+ if (!ensure_python_thick_object_is_registered())
+ return false;
+
+ if (!ensure_python_comparable_object_is_registered())
+ return false;
+
+ if (!ensure_python_hashable_object_is_registered())
+ return false;
+
+ if (!ensure_python_serializable_object_is_registered())
+ return false;
+
if (!ensure_python_singleton_candidate_is_registered())
return false;
+ if (!ensure_python_string_builder_is_registered())
+ return false;
+
+ pyg_register_class_init(G_TYPE_ARCH_OPERAND, (PyGClassInitFunc)py_arch_operand_init_gclass);
+
if (!register_class_for_pygobject(dict, G_TYPE_ARCH_OPERAND, type))
return false;
diff --git a/plugins/pychrysalide/arch/operand.h b/plugins/pychrysalide/arch/operand.h
index 9cb40a0..f3bfbf2 100644
--- a/plugins/pychrysalide/arch/operand.h
+++ b/plugins/pychrysalide/arch/operand.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* operand.h - prototypes pour l'équivalent Python du fichier "arch/operand.h"
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2024 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -31,9 +31,6 @@
-/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */
-
-
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_arch_operand_type(void);
diff --git a/plugins/pychrysalide/arch/operands/Makefile.am b/plugins/pychrysalide/arch/operands/Makefile.am
index a41cbbb..3b753cc 100644
--- a/plugins/pychrysalide/arch/operands/Makefile.am
+++ b/plugins/pychrysalide/arch/operands/Makefile.am
@@ -1,19 +1,21 @@
noinst_LTLIBRARIES = libpychrysaarchoperands.la
+# libpychrysaarchoperands_la_SOURCES = \
+# feeder.h feeder.c \
+# proxy.h proxy.c \
+# rename.h rename.c \
+# target.h target.c \
+# targetable.h targetable.c
+
libpychrysaarchoperands_la_SOURCES = \
constants.h constants.c \
- feeder.h feeder.c \
immediate.h immediate.c \
known.h known.c \
module.h module.c \
- proxy.h proxy.c \
- register.h register.c \
- rename.h rename.c \
- target.h target.c \
- targetable.h targetable.c
+ register.h register.c
-libpychrysaarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+libpychrysaarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/arch/operands/constants.c b/plugins/pychrysalide/arch/operands/constants.c
index b9d80e4..78eeded 100644
--- a/plugins/pychrysalide/arch/operands/constants.c
+++ b/plugins/pychrysalide/arch/operands/constants.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.c - ajout des constantes de base pour les opérandes
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -47,20 +47,33 @@
* *
******************************************************************************/
-bool define_imm_operand_constants(PyTypeObject *type)
+bool define_immediate_operand_constants(PyTypeObject *type)
{
bool result; /* Bilan à retourner */
PyObject *values; /* Groupe de valeurs à établir */
values = PyDict_New();
+ result = add_const_to_group(values, "ZERO_PADDING_BY_DEFAULT", IOF_ZERO_PADDING_BY_DEFAULT);
+ if (result) result = add_const_to_group(values, "ZERO_PADDING", IOF_ZERO_PADDING);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, true, "ImmOperandFlag", values,
+ "Specific state bits for immediate operands.");
+
+ values = PyDict_New();
+
result = add_const_to_group(values, "BIN", IOD_BIN);
if (result) result = add_const_to_group(values, "OCT", IOD_OCT);
if (result) result = add_const_to_group(values, "DEC", IOD_DEC);
if (result) result = add_const_to_group(values, "HEX", IOD_HEX);
if (result) result = add_const_to_group(values, "CHAR", IOD_CHAR);
if (result) result = add_const_to_group(values, "COUNT", IOD_COUNT);
- if (result) result = add_const_to_group(values, "LAST_VALID", IOD_LAST_VALID);
if (!result)
{
diff --git a/plugins/pychrysalide/arch/operands/constants.h b/plugins/pychrysalide/arch/operands/constants.h
index 71a26cc..5170faa 100644
--- a/plugins/pychrysalide/arch/operands/constants.h
+++ b/plugins/pychrysalide/arch/operands/constants.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.h - prototypes pour l'ajout des constantes de base pour les opérandes
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -32,11 +32,14 @@
/* Définit les constantes relatives aux opérandes d'immédiats. */
-bool define_imm_operand_constants(PyTypeObject *);
+bool define_immediate_operand_constants(PyTypeObject *);
/* Tente de convertir en constante ImmOperandDisplay. */
int convert_to_imm_operand_display(PyObject *, void *);
+#define cast_imm_operand_display_to_python(v) \
+ cast_with_constants_group_from_type(get_python_immediate_operand_type(), "ImmOperandDisplay", v)
+
#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/operands/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c
index 2239eb2..a335db3 100644
--- a/plugins/pychrysalide/arch/operands/immediate.c
+++ b/plugins/pychrysalide/arch/operands/immediate.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* immediate.c - équivalent Python du fichier "arch/operands/immediate.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -30,201 +30,119 @@
#include <i18n.h>
-
-
-#include <arch/operands/immediate.h>
+#include <arch/operands/immediate-int.h>
#include "constants.h"
-#include "rename.h"
-#include "targetable.h"
#include "../operand.h"
#include "../../access.h"
+#include "../../constants.h"
#include "../../helpers.h"
#include "../../analysis/content.h"
-#include "../../glibext/bufferline.h"
-/* Crée un nouvel objet Python de type 'ImmOperand'. */
-static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(immediate_operand, G_TYPE_IMMEDIATE_OPERAND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_immediate_operand_init(PyObject *, PyObject *, PyObject *);
+
+
-/* Compare un opérande avec un autre. */
-static PyObject *py_imm_operand___cmp__(PyObject *, PyObject *);
+/* ---------------------------- DEFINITION D'UN IMMEDIAT ---------------------------- */
-/* Traduit un opérande en version humainement lisible. */
-static PyObject *py_imm_operand__print(PyObject *, PyObject *);
/* Renseigne la taille de la valeur indiquée à la construction. */
-static PyObject *py_imm_operand_get_size(PyObject *, void *);
+static PyObject *py_immediate_operand_get_size(PyObject *, void *);
/* Fournit la valeur portée par une opérande numérique. */
-static PyObject *py_imm_operand_get_value(PyObject *, void *);
+static PyObject *py_immediate_operand_get_value(PyObject *, void *);
+
+/* Indique le signe d'une valeur immédiate. */
+static PyObject *py_immediate_operand_is_negative(PyObject *, void *);
/* Indique le format textuel par défaut de la valeur. */
-static PyObject *py_imm_operand_get_default_display(PyObject *, void *);
+static PyObject *py_immediate_operand_get_default_display(PyObject *, void *);
/* Définit le format textuel par défaut de la valeur. */
-static int py_imm_operand_set_default_display(PyObject *, PyObject *, void *);
+static int py_immediate_operand_set_default_display(PyObject *, PyObject *, void *);
/* Indique la grande ligne du format textuel de la valeur. */
-static PyObject *py_imm_operand_get_display(PyObject *, void *);
+static PyObject *py_immediate_operand_get_display(PyObject *, void *);
/* Définit la grande ligne du format textuel de la valeur. */
-static int py_imm_operand_set_display(PyObject *, PyObject *, void *);
+static int py_immediate_operand_set_display(PyObject *, PyObject *, void *);
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'ImmOperand'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_immediate_operand_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
- unsigned int raw_size; /* Taille obtenue de Python */
+ MemoryDataSize size; /* Taille des données finale */
unsigned long long value; /* Valeur brute à représenter */
int ret; /* Bilan de lecture des args. */
- MemoryDataSize size; /* Taille des données finale */
- GArchOperand *operand; /* Création GLib à transmettre */
+ GImmediateOperand *operand; /* Opérande natif à manipuler */
-#define IMM_OPERAND_DOC \
- "The ImmOperand deals with immediate value as operand." \
+#define IMMEDIATE_OPERAND_DOC \
+ "The ImmediateOperand deals with immediate value as operand." \
"\n" \
"There are several ways to display these values in a disassembly," \
" the operand handles that.\n" \
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " ImmOperand(size, value)" \
+ " ImmediateOperand(size, value)" \
"\n" \
- "Where size specifies the original size of the provided value, as" \
- " a pychrysalide.analysis.BinContent.MemoryDataSize."
+ "Where *size* specifies the original size of the provided *value*," \
+ " as a pychrysalide.MemoryDataSize."
- ret = PyArg_ParseTuple(args, "IK", &raw_size, &value);
- if (!ret) return NULL;
+ /* Récupération des paramètres */
- size = raw_size;
+ ret = PyArg_ParseTuple(args, "O&K", convert_to_memory_data_size, &size, &value);
+ if (!ret) return -1;
- if (size != MDS_UNDEFINED
- && !(MDS_4_BITS_UNSIGNED <= size && size <= MDS_64_BITS_UNSIGNED)
- && !(MDS_4_BITS_SIGNED <= size && size <= MDS_64_BITS_SIGNED))
- {
- PyErr_SetString(PyExc_ValueError, _("Invalid size to build an immediate operand"));
- return NULL;
- }
+ /* Initialisation d'un objet GLib */
- operand = g_imm_operand_new_from_value(size, value);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- result = pygobject_new(G_OBJECT(operand));
+ /* Eléments de base */
- g_object_unref(operand);
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
- return (PyObject *)result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = serveur à manipuler. *
-* args = arguments associés à l'appel. *
-* *
-* Description : Compare un opérande avec un autre. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_imm_operand___cmp__(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Bilan à retourner */
- GImmOperand *other; /* Autre opérande à manipuler */
- int ret; /* Bilan de lecture des args. */
- GImmOperand *operand; /* Elément à manipuler */
- int status; /* Bilan de comparaison */
-
-#define IMM_OPERAND_CMP_METHOD PYTHON_METHOD_DEF \
-( \
- __cmp__, "$self, other, /", \
- METH_VARARGS, py_imm_operand, \
- "Implementation of the required method used to compare the" \
- " operand with another one. This second object is always" \
- " an pychrysalide.arch.ImmOperand instance.\n" \
- "\n" \
- "See the parent class for more information about this method." \
-)
-
- ret = PyArg_ParseTuple(args, "O&", convert_to_imm_operand, &other);
- if (!ret) return NULL;
-
- operand = G_IMM_OPERAND(pygobject_get(self));
-
- status = g_arch_operand_compare(G_ARCH_OPERAND(operand), G_ARCH_OPERAND(other));
-
- result = PyLong_FromLong(status);
+ if (!g_immediate_operand_create_from_value(operand, size, value))
+ return -1;
- return result;
+ return 0;
}
-/******************************************************************************
-* *
-* Paramètres : self = serveur à manipuler. *
-* args = arguments associés à l'appel. *
-* *
-* Description : Traduit un opérande en version humainement lisible. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-static PyObject *py_imm_operand__print(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Bilan à retourner */
- GBufferLine *line; /* Ligne fournie à peupler */
- int ret; /* Bilan de lecture des args. */
- GImmOperand *operand; /* Elément à manipuler */
-
-#define IMM_OPERAND_PRINT_METHOD PYTHON_METHOD_DEF \
-( \
- _print, "$self, line, /", \
- METH_VARARGS, py_imm_operand, \
- "Implementation of the required method used to print the operand" \
- " into a rendering line, which is a provided" \
- " pychrysalide.glibext.BufferLine instance.\n" \
- "\n" \
- "See the parent class for more information about this method." \
-)
-
- ret = PyArg_ParseTuple(args, "O&", convert_to_buffer_line, &line);
- if (!ret) return NULL;
-
- operand = G_IMM_OPERAND(pygobject_get(self));
-
- g_arch_operand_print(G_ARCH_OPERAND(operand), line);
-
- result = Py_None;
- Py_INCREF(result);
-
- return result;
-
-}
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN IMMEDIAT */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -240,25 +158,26 @@ static PyObject *py_imm_operand__print(PyObject *self, PyObject *args)
* *
******************************************************************************/
-static PyObject *py_imm_operand_get_size(PyObject *self, void *closure)
+static PyObject *py_immediate_operand_get_size(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
MemoryDataSize size; /* Type de donnée représentée */
-#define IMM_OPERAND_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+#define IMMEDIATE_OPERAND_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
( \
- size, py_imm_operand, \
+ size, py_immediate_operand, \
"Get or set the size of the value contained in the operand." \
"\n" \
"The property is a value of type" \
- " pychrysalide.analysis.BinContent.MemoryDataSize." \
+ " pychrysalide.MemoryDataSize." \
)
- operand = G_IMM_OPERAND(pygobject_get(self));
- size = g_imm_operand_get_size(operand);
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
+
+ size = g_immediate_operand_get_size(operand);
- result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", size);
+ result = cast_memory_data_size_to_python(size);
return result;
@@ -278,10 +197,10 @@ static PyObject *py_imm_operand_get_size(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
+static PyObject *py_immediate_operand_get_value(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
MemoryDataSize size; /* Type de donnée représentée */
uint8_t uval8; /* Valeur sur 8 bits */
uint16_t uval16; /* Valeur sur 16 bits */
@@ -292,15 +211,15 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
int32_t sval32; /* Valeur sur 32 bits */
int64_t sval64; /* Valeur sur 64 bits */
-#define IMM_OPERAND_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- value, py_imm_operand, \
- "Value of the immediate operand, as an integer." \
+#define IMMEDIATE_OPERAND_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ value, py_immediate_operand, \
+ "Value of the immediate operand, as an integer." \
)
- operand = G_IMM_OPERAND(pygobject_get(self));
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
- size = g_imm_operand_get_size(operand);
+ size = g_immediate_operand_get_size(operand);
switch (size)
{
@@ -311,36 +230,36 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
break;
case MDS_4_BITS_UNSIGNED:
case MDS_8_BITS_UNSIGNED:
- g_imm_operand_get_value(operand, size, &uval8);
+ g_immediate_operand_get_value(operand, size, &uval8);
result = PyLong_FromUnsignedLong(uval8);
break;
case MDS_16_BITS_UNSIGNED:
- g_imm_operand_get_value(operand, size, &uval16);
+ g_immediate_operand_get_value(operand, size, &uval16);
result = PyLong_FromUnsignedLong(uval16);
break;
case MDS_32_BITS_UNSIGNED:
- g_imm_operand_get_value(operand, size, &uval32);
+ g_immediate_operand_get_value(operand, size, &uval32);
result = PyLong_FromUnsignedLong(uval32);
break;
case MDS_64_BITS_UNSIGNED:
- g_imm_operand_get_value(operand, size, &uval64);
+ g_immediate_operand_get_value(operand, size, &uval64);
result = PyLong_FromUnsignedLongLong(uval64);
break;
case MDS_4_BITS_SIGNED:
case MDS_8_BITS_SIGNED:
- g_imm_operand_get_value(operand, size, &sval8);
+ g_immediate_operand_get_value(operand, size, &sval8);
result = PyLong_FromLong(sval8);
break;
case MDS_16_BITS_SIGNED:
- g_imm_operand_get_value(operand, size, &sval16);
+ g_immediate_operand_get_value(operand, size, &sval16);
result = PyLong_FromLong(sval16);
break;
case MDS_32_BITS_SIGNED:
- g_imm_operand_get_value(operand, size, &sval32);
+ g_immediate_operand_get_value(operand, size, &sval32);
result = PyLong_FromLong(sval32);
break;
case MDS_64_BITS_SIGNED:
- g_imm_operand_get_value(operand, size, &sval64);
+ g_immediate_operand_get_value(operand, size, &sval64);
result = PyLong_FromLongLong(sval64);
break;
@@ -363,6 +282,43 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
+* Description : Indique le signe d'une valeur immédiate. *
+* *
+* Retour : True si la valeur est strictement négative, False sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_immediate_operand_is_negative(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
+ bool status; /* Etat à faire connaître */
+
+#define IMMEDIATE_OPERAND_NEGATIVE_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ negative, py_immediate_operand, \
+ "Sign of the value, as a boolean status." \
+)
+
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
+
+ status = g_immediate_operand_is_negative(operand);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
* Description : Indique le format textuel par défaut de la valeur. *
* *
* Retour : Format global d'un affichage de valeur. *
@@ -371,25 +327,26 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_imm_operand_get_default_display(PyObject *self, void *closure)
+static PyObject *py_immediate_operand_get_default_display(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
ImmOperandDisplay display; /* Type d'affichage courant */
-#define IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+#define IMMEDIATE_OPERAND_DEFAULT_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
( \
- default_display, py_imm_operand, \
+ default_display, py_immediate_operand, \
"Define of the immediate operand default textual representation." \
"\n" \
"The property is a value of type" \
" pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
)
- operand = G_IMM_OPERAND(pygobject_get(self));
- display = g_imm_operand_get_default_display(operand);
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
+
+ display = g_immediate_operand_get_default_display(operand);
- result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", display);
+ result = cast_imm_operand_display_to_python(display);
return result;
@@ -410,10 +367,10 @@ static PyObject *py_imm_operand_get_default_display(PyObject *self, void *closur
* *
******************************************************************************/
-static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, void *closure)
+static int py_immediate_operand_set_default_display(PyObject *self, PyObject *value, void *closure)
{
ImmOperandDisplay display; /* Type d'affichage demandé */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
if (!PyLong_Check(value))
{
@@ -429,9 +386,9 @@ static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, v
return -1;
}
- operand = G_IMM_OPERAND(pygobject_get(self));
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
- g_imm_operand_set_default_display(operand, display);
+ g_immediate_operand_set_default_display(operand, display);
return 0;
@@ -451,25 +408,27 @@ static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, v
* *
******************************************************************************/
-static PyObject *py_imm_operand_get_display(PyObject *self, void *closure)
+static PyObject *py_immediate_operand_get_display(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
ImmOperandDisplay display; /* Type d'affichage courant */
-#define IMM_OPERAND_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
-( \
- display, py_imm_operand, \
- "Define of the immediate operand current textual representation." \
- "\n" \
- "The property is a value of type" \
- " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
+#define IMMEDIATE_OPERAND_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ display, py_immediate_operand, \
+ "Retrieve or define of the immediate operand current textual" \
+ " representation." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
)
- operand = G_IMM_OPERAND(pygobject_get(self));
- display = g_imm_operand_get_display(operand);
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
- result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", display);
+ display = g_immediate_operand_get_display(operand);
+
+ result = cast_imm_operand_display_to_python(display);
return result;
@@ -490,10 +449,10 @@ static PyObject *py_imm_operand_get_display(PyObject *self, void *closure)
* *
******************************************************************************/
-static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *closure)
+static int py_immediate_operand_set_display(PyObject *self, PyObject *value, void *closure)
{
ImmOperandDisplay display; /* Type d'affichage demandé */
- GImmOperand *operand; /* Version GLib de l'opérande */
+ GImmediateOperand *operand; /* Version GLib de l'opérande */
if (!PyLong_Check(value))
{
@@ -509,9 +468,9 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo
return -1;
}
- operand = G_IMM_OPERAND(pygobject_get(self));
+ operand = G_IMMEDIATE_OPERAND(pygobject_get(self));
- g_imm_operand_set_display(operand, display);
+ g_immediate_operand_set_display(operand, display);
return 0;
@@ -530,40 +489,41 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo
* *
******************************************************************************/
-PyTypeObject *get_python_imm_operand_type(void)
+PyTypeObject *get_python_immediate_operand_type(void)
{
- static PyMethodDef py_imm_operand_methods[] = {
- IMM_OPERAND_CMP_METHOD,
- IMM_OPERAND_PRINT_METHOD,
+ static PyMethodDef py_immediate_operand_methods[] = {
{ NULL }
};
- static PyGetSetDef py_imm_operand_getseters[] = {
- IMM_OPERAND_SIZE_ATTRIB,
- IMM_OPERAND_VALUE_ATTRIB,
- IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB,
- IMM_OPERAND_DISPLAY_ATTRIB,
+ static PyGetSetDef py_immediate_operand_getseters[] = {
+ IMMEDIATE_OPERAND_SIZE_ATTRIB,
+ IMMEDIATE_OPERAND_VALUE_ATTRIB,
+ IMMEDIATE_OPERAND_NEGATIVE_ATTRIB,
+ IMMEDIATE_OPERAND_DEFAULT_DISPLAY_ATTRIB,
+ IMMEDIATE_OPERAND_DISPLAY_ATTRIB,
{ NULL }
};
- static PyTypeObject py_imm_operand_type = {
+ static PyTypeObject py_immediate_operand_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.operands.ImmOperand",
+ .tp_name = "pychrysalide.arch.operands.ImmediateOperand",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = IMM_OPERAND_DOC,
+ .tp_doc = IMMEDIATE_OPERAND_DOC,
+
+ .tp_methods = py_immediate_operand_methods,
+ .tp_getset = py_immediate_operand_getseters,
- .tp_methods = py_imm_operand_methods,
- .tp_getset = py_imm_operand_getseters,
- .tp_new = py_imm_operand_new
+ .tp_init = py_immediate_operand_init,
+ .tp_new = py_immediate_operand_new,
};
- return &py_imm_operand_type;
+ return &py_immediate_operand_type;
}
@@ -580,13 +540,13 @@ PyTypeObject *get_python_imm_operand_type(void)
* *
******************************************************************************/
-bool ensure_python_imm_operand_is_registered(void)
+bool ensure_python_immediate_operand_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'ImmOperand' */
+ PyTypeObject *type; /* Type 'ImmediateOperand' */
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
- type = get_python_imm_operand_type();
+ type = get_python_immediate_operand_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -597,16 +557,10 @@ bool ensure_python_imm_operand_is_registered(void)
if (!ensure_python_arch_operand_is_registered())
return false;
- if (!ensure_python_targetable_operand_is_registered())
- return false;
-
- if (!ensure_python_renameable_operand_is_registered())
- return false;
-
- if (!register_class_for_pygobject(dict, G_TYPE_IMM_OPERAND, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_IMMEDIATE_OPERAND, type))
return false;
- if (!define_imm_operand_constants(type))
+ if (!define_immediate_operand_constants(type))
return false;
}
@@ -629,11 +583,11 @@ bool ensure_python_imm_operand_is_registered(void)
* *
******************************************************************************/
-int convert_to_imm_operand(PyObject *arg, void *dst)
+int convert_to_immediate_operand(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_imm_operand_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_immediate_operand_type());
switch (result)
{
@@ -647,7 +601,7 @@ int convert_to_imm_operand(PyObject *arg, void *dst)
break;
case 1:
- *((GImmOperand **)dst) = G_IMM_OPERAND(pygobject_get(arg));
+ *((GImmediateOperand **)dst) = G_IMMEDIATE_OPERAND(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/arch/operands/immediate.h b/plugins/pychrysalide/arch/operands/immediate.h
index 4a1e6de..8b8de83 100644
--- a/plugins/pychrysalide/arch/operands/immediate.h
+++ b/plugins/pychrysalide/arch/operands/immediate.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* immediate.h - prototypes pour l'équivalent Python du fichier "arch/operands/immediate.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -32,13 +32,13 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_imm_operand_type(void);
+PyTypeObject *get_python_immediate_operand_type(void);
-/* Prend en charge l'objet 'pychrysalide.arch.ImmOperand'. */
-bool ensure_python_imm_operand_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.arch.ImmediateOperand'. */
+bool ensure_python_immediate_operand_is_registered(void);
/* Tente de convertir en opérande de valeur immédiate. */
-int convert_to_imm_operand(PyObject *, void *);
+int convert_to_immediate_operand(PyObject *, void *);
diff --git a/plugins/pychrysalide/arch/operands/known.c b/plugins/pychrysalide/arch/operands/known.c
index fab426e..85cabc2 100644
--- a/plugins/pychrysalide/arch/operands/known.c
+++ b/plugins/pychrysalide/arch/operands/known.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* known.c - équivalent Python du fichier "arch/operands/known.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -29,70 +29,92 @@
#include <pygobject.h>
-#include <arch/operands/known.h>
+#include <arch/operands/known-int.h>
#include "immediate.h"
-#include "rename.h"
#include "../../access.h"
#include "../../helpers.h"
-/* Crée un nouvel objet Python de type 'KnownImmOperand'. */
-static PyObject *py_known_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+CREATE_DYN_CONSTRUCTOR(known_immediate_operand, G_TYPE_KNOWN_IMMEDIATE_OPERAND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_known_immediate_operand_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'KnownImmOperand'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_known_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_known_immediate_operand_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
- GImmOperand *imm; /* Opérande à remplacer */
+ GImmediateOperand *imm; /* Opérande à remplacer */
const char *alt; /* Impression alternative */
int ret; /* Bilan de lecture des args. */
- GArchOperand *operand; /* Création GLib à transmettre */
-
-#define KNOWN_IMM_OPERAND_DOC \
- "The KnownImmOperand provides replacement of" \
- " pychrysalide.arch.operands.ImmOperand instances by an alternative" \
- " text.\n" \
- "\n" \
- "Instances can be created using the following constructor:\n" \
- "\n" \
- " KnownImmOperand(imm, alt)" \
- "\n" \
- "Where imm is an operand of type pychrysalide.arch.operands.ImmOperand" \
- " and alt is a string providing the text to be rendered at object" \
+ GKnownImmediateOperand *operand; /* Opérande natif à manipuler */
+
+#define KNOWN_IMMEDIATE_OPERAND_DOC \
+ "The KnownImmediateOperand provides replacement of" \
+ " pychrysalide.arch.operands.ImmediateOperand instances by an alternative" \
+ " text.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " KnownImmediateOperand(imm, alt)" \
+ "\n" \
+ "Where *imm* is an operand of type pychrysalide.arch.operands.ImmediateOperand" \
+ " and *alt* is a string providing the text to be rendered at object" \
" display."
- ret = PyArg_ParseTuple(args, "O&s", convert_to_imm_operand, &imm, &alt);
- if (!ret) return NULL;
+ /* Récupération des paramètres */
+
+ ret = PyArg_ParseTuple(args, "O&s", convert_to_immediate_operand, &imm, &alt);
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
- operand = g_known_imm_operand_new(imm, alt);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- result = pygobject_new(G_OBJECT(operand));
+ /* Eléments de base */
- g_object_unref(operand);
+ operand = G_KNOWN_IMMEDIATE_OPERAND(pygobject_get(self));
- return (PyObject *)result;
+ if (!g_known_immediate_operand_create(operand, imm, alt))
+ return -1;
+
+ return 0;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN IMMEDIAT CONNU */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : - *
@@ -105,34 +127,36 @@ static PyObject *py_known_imm_operand_new(PyTypeObject *type, PyObject *args, Py
* *
******************************************************************************/
-PyTypeObject *get_python_known_imm_operand_type(void)
+PyTypeObject *get_python_known_immediate_operand_type(void)
{
- static PyMethodDef py_known_imm_operand_methods[] = {
+ static PyMethodDef py_known_immediate_operand_methods[] = {
{ NULL }
};
- static PyGetSetDef py_known_imm_operand_getseters[] = {
+ static PyGetSetDef py_known_immediate_operand_getseters[] = {
{ NULL }
};
- static PyTypeObject py_known_imm_operand_type = {
+ static PyTypeObject py_known_immediate_operand_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.operands.KnownImmOperand",
+ .tp_name = "pychrysalide.arch.operands.KnownImmediateOperand",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = KNOWN_IMM_OPERAND_DOC,
+ .tp_doc = KNOWN_IMMEDIATE_OPERAND_DOC,
- .tp_methods = py_known_imm_operand_methods,
- .tp_getset = py_known_imm_operand_getseters,
- .tp_new = py_known_imm_operand_new
+ .tp_methods = py_known_immediate_operand_methods,
+ .tp_getset = py_known_immediate_operand_getseters,
+
+ .tp_init = py_known_immediate_operand_init,
+ .tp_new = py_known_immediate_operand_new,
};
- return &py_known_imm_operand_type;
+ return &py_known_immediate_operand_type;
}
@@ -141,7 +165,7 @@ PyTypeObject *get_python_known_imm_operand_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.arch.KnownImmOperand'. *
+* Description : Prend en charge l'objet '....KnownImmediateOperand'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -149,13 +173,13 @@ PyTypeObject *get_python_known_imm_operand_type(void)
* *
******************************************************************************/
-bool ensure_python_known_imm_operand_is_registered(void)
+bool ensure_python_known_immediate_operand_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'ImmOperand' */
+ PyTypeObject *type; /* Type 'KnownImmediateOperand'*/
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
- type = get_python_known_imm_operand_type();
+ type = get_python_known_immediate_operand_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -163,13 +187,10 @@ bool ensure_python_known_imm_operand_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_imm_operand_is_registered())
- return false;
-
- if (!ensure_python_renamed_operand_is_registered())
+ if (!ensure_python_immediate_operand_is_registered())
return false;
- if (!register_class_for_pygobject(dict, G_TYPE_KNOWN_IMM_OPERAND, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_KNOWN_IMMEDIATE_OPERAND, type))
return false;
}
@@ -192,11 +213,11 @@ bool ensure_python_known_imm_operand_is_registered(void)
* *
******************************************************************************/
-int convert_to_known_imm_operand(PyObject *arg, void *dst)
+int convert_to_known_immediate_operand(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_known_imm_operand_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_known_immediate_operand_type());
switch (result)
{
@@ -210,7 +231,7 @@ int convert_to_known_imm_operand(PyObject *arg, void *dst)
break;
case 1:
- *((GKnownImmOperand **)dst) = G_KNOWN_IMM_OPERAND(pygobject_get(arg));
+ *((GKnownImmediateOperand **)dst) = G_KNOWN_IMMEDIATE_OPERAND(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/arch/operands/known.h b/plugins/pychrysalide/arch/operands/known.h
index b5ced68..f5b80e8 100644
--- a/plugins/pychrysalide/arch/operands/known.h
+++ b/plugins/pychrysalide/arch/operands/known.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* known.h - prototypes pour l'équivalent Python du fichier "arch/operands/known.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -32,13 +32,13 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_known_imm_operand_type(void);
+PyTypeObject *get_python_known_immediate_operand_type(void);
-/* Prend en charge l'objet 'pychrysalide.arch.KnownImmOperand'. */
-bool ensure_python_known_imm_operand_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.arch.KnownImmediateOperand'. */
+bool ensure_python_known_immediate_operand_is_registered(void);
/* Tente de convertir en remplaçant d'opérande d'immédiat. */
-int convert_to_known_imm_operand(PyObject *, void *);
+int convert_to_known_immediate_operand(PyObject *, void *);
diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c
index 89adecc..486e259 100644
--- a/plugins/pychrysalide/arch/operands/module.c
+++ b/plugins/pychrysalide/arch/operands/module.c
@@ -28,14 +28,20 @@
#include <assert.h>
+/*
#include "feeder.h"
+*/
#include "immediate.h"
#include "known.h"
+/*
#include "proxy.h"
+*/
#include "register.h"
+/*
#include "rename.h"
#include "target.h"
#include "targetable.h"
+*/
#include "../../helpers.h"
@@ -101,15 +107,21 @@ bool populate_arch_operands_module(void)
result = true;
+ /*
if (result) result = ensure_python_proxy_feeder_is_registered();
- if (result) result = ensure_python_imm_operand_is_registered();
- if (result) result = ensure_python_known_imm_operand_is_registered();
+ */
+ if (result) result = ensure_python_immediate_operand_is_registered();
+ if (result) result = ensure_python_known_immediate_operand_is_registered();
+ /*
if (result) result = ensure_python_proxy_operand_is_registered();
+ */
if (result) result = ensure_python_register_operand_is_registered();
+ /*
if (result) result = ensure_python_renamed_operand_is_registered();
if (result) result = ensure_python_renameable_operand_is_registered();
if (result) result = ensure_python_target_operand_is_registered();
if (result) result = ensure_python_targetable_operand_is_registered();
+ */
assert(result);
diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c
index 2a48a0f..707524a 100644
--- a/plugins/pychrysalide/arch/operands/register.c
+++ b/plugins/pychrysalide/arch/operands/register.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* register.c - équivalent Python du fichier "arch/operands/register.c"
*
- * Copyright (C) 2019-2020 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -30,25 +30,19 @@
#include <i18n.h>
#include <arch/operands/register-int.h>
-#include <plugins/dt.h>
#include "../operand.h"
#include "../register.h"
#include "../../access.h"
#include "../../helpers.h"
-#include "../../glibext/bufferline.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_register_operand_new(PyTypeObject *, PyObject *, PyObject *);
-
-/* Initialise la classe des descriptions de fichier binaire. */
-static void py_register_operand_init_gclass(GRegisterOperandClass *, gpointer);
+CREATE_DYN_CONSTRUCTOR(register_operand, G_TYPE_REGISTER_OPERAND);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_register_operand_init(PyObject *, PyObject *, PyObject *);
@@ -58,12 +52,6 @@ static int py_register_operand_init(PyObject *, PyObject *, PyObject *);
/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */
-/* Compare un opérande avec un autre. */
-static PyObject *py_register_operand___cmp__(PyObject *, PyObject *);
-
-/* Traduit un opérande en version humainement lisible. */
-static PyObject *py_register_operand__print(PyObject *, PyObject *);
-
/* Fournit le registre associé à l'opérande. */
static PyObject *py_register_operand_get_register(PyObject *, void *);
@@ -76,86 +64,6 @@ static PyObject *py_register_operand_get_register(PyObject *, void *);
/******************************************************************************
* *
-* 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_register_operand_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 */
-
- /* Validations diverses */
-
- base = get_python_register_operand_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_REGISTER_OPERAND, type->tp_name,
- (GClassInitFunc)py_register_operand_init_gclass, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
-
- 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 : class = classe à initialiser. *
-* unused = données non utilisées ici. *
-* *
-* Description : Initialise la classe des descriptions de fichier binaire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void py_register_operand_init_gclass(GRegisterOperandClass *class, gpointer unused)
-{
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
@@ -182,7 +90,7 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw
"\n" \
" RegisterOperand(reg)" \
"\n" \
- "Where reg is an architecture register defined from a subclass of" \
+ "Where *reg* is an architecture register defined from a subclass of" \
" pychrysalide.arch.ArchRegister."
/* Récupération des paramètres */
@@ -199,8 +107,8 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw
operand = G_REGISTER_OPERAND(pygobject_get(self));
- g_object_ref(G_OBJECT(reg));
- operand->reg = reg;
+ if (!g_register_operand_create(operand, reg))
+ return -1;
return 0;
@@ -215,98 +123,6 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw
/******************************************************************************
* *
-* Paramètres : self = serveur à manipuler. *
-* args = arguments associés à l'appel. *
-* *
-* Description : Compare un opérande avec un autre. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_register_operand___cmp__(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Bilan à retourner */
- GRegisterOperand *other; /* Autre opérande à manipuler */
- int ret; /* Bilan de lecture des args. */
- GRegisterOperand *operand; /* Elément à manipuler */
- int status; /* Bilan de comparaison */
-
-#define REGISTER_OPERAND_CMP_METHOD PYTHON_METHOD_DEF \
-( \
- __cmp__, "$self, other, /", \
- METH_VARARGS, py_register_operand, \
- "Implementation of the required method used to compare the" \
- " operand with another one. This second object is always" \
- " a pychrysalide.arch.RegisterOperand instance.\n" \
- "\n" \
- "See the parent class for more information about this method." \
-)
-
- ret = PyArg_ParseTuple(args, "O&", convert_to_register_operand, &other);
- if (!ret) return NULL;
-
- operand = G_REGISTER_OPERAND(pygobject_get(self));
-
- status = g_arch_operand_compare(G_ARCH_OPERAND(operand), G_ARCH_OPERAND(other));
-
- result = PyLong_FromLong(status);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = serveur à manipuler. *
-* args = arguments associés à l'appel. *
-* *
-* Description : Traduit un opérande en version humainement lisible. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_register_operand__print(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Bilan à retourner */
- GBufferLine *line; /* Ligne fournie à peupler */
- int ret; /* Bilan de lecture des args. */
- GRegisterOperand *operand; /* Elément à manipuler */
-
-#define REGISTER_OPERAND_PRINT_METHOD PYTHON_METHOD_DEF \
-( \
- _print, "$self, line, /", \
- METH_VARARGS, py_register_operand, \
- "Implementation of the required method used to print the operand" \
- " into a rendering line, which is a provided" \
- " pychrysalide.glibext.BufferLine instance.\n" \
- "\n" \
- "See the parent class for more information about this method." \
-)
-
- ret = PyArg_ParseTuple(args, "O&", convert_to_buffer_line, &line);
- if (!ret) return NULL;
-
- operand = G_REGISTER_OPERAND(pygobject_get(self));
-
- g_arch_operand_print(G_ARCH_OPERAND(operand), line);
-
- result = Py_None;
- Py_INCREF(result);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -367,8 +183,6 @@ static PyObject *py_register_operand_get_register(PyObject *self, void *closure)
PyTypeObject *get_python_register_operand_type(void)
{
static PyMethodDef py_register_operand_methods[] = {
- REGISTER_OPERAND_CMP_METHOD,
- REGISTER_OPERAND_PRINT_METHOD,
{ NULL }
};
diff --git a/plugins/pychrysalide/arch/register.c b/plugins/pychrysalide/arch/register.c
index 615a5b7..7139e47 100644
--- a/plugins/pychrysalide/arch/register.c
+++ b/plugins/pychrysalide/arch/register.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* register.c - équivalent Python du fichier "arch/register.c"
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -31,32 +31,27 @@
#include <i18n.h>
#include <arch/register-int.h>
-#include <plugins/dt.h>
#include "../access.h"
#include "../helpers.h"
-#include "../analysis/storage/serialize.h"
+#include "../glibext/comparable.h"
+#include "../glibext/hashable.h"
+#include "../glibext/serialize.h"
+#include "../glibext/strbuilder.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_arch_register_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe des registres. */
-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 *);
+static int py_arch_register_init_gclass(GArchRegisterClass *, PyTypeObject *);
-/* Compare un registre avec un autre. */
-static int py_arch_register___cmp___wrapper(const GArchRegister *, const GArchRegister *);
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_register, G_TYPE_ARCH_REGISTER);
-/* Traduit un registre en version humainement lisible. */
-static void py_arch_register_print_wrapper(const GArchRegister *, GBufferLine *);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_arch_register_init(PyObject *, PyObject *, PyObject *);
/* Indique si le registre correspond à ebp ou similaire. */
static bool py_arch_register_is_base_pointer_wrapper(const GArchRegister *);
@@ -69,9 +64,6 @@ 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 *);
@@ -87,88 +79,8 @@ static PyObject *py_arch_register_is_stack_pointer(PyObject *, void *);
/******************************************************************************
* *
-* 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_arch_register_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 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();
-
- if (type == base)
- {
- result = NULL;
- PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
- goto exit;
- }
-
- /* Mise en place d'un type dédié */
-
- first_time = (g_type_from_name(type->tp_name) == 0);
-
- gtype = build_dynamic_type(G_TYPE_ARCH_REGISTER, type->tp_name,
- (GClassInitFunc)py_arch_register_init_gclass, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
-
- if (!status)
- {
- result = NULL;
- goto exit;
- }
-
- }
-
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
-
- result = PyType_GenericNew(type, args, kwds);
-
- exit:
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : class = classe à initialiser. *
-* unused = données non utilisées ici. *
+* Paramètres : gclass = classe GLib à initialiser. *
+* pyclass = classe Python à initialiser. *
* *
* Description : Initialise la classe des registres. *
* *
@@ -178,190 +90,51 @@ static PyObject *py_arch_register_new(PyTypeObject *type, PyObject *args, PyObje
* *
******************************************************************************/
-static void py_arch_register_init_gclass(GArchRegisterClass *class, gpointer unused)
-{
- 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);
-
- }
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : a = premier registre à consulter. *
-* b = second registre à 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)
+static int py_arch_register_init_gclass(GArchRegisterClass *gclass, PyTypeObject *pyclass)
{
- 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 compare the register with another" \
- " one. This second object is always an" \
- " pychrysalide.arch.ArchRegister instance.\n" \
- "\n" \
- " This is the Python 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_CLASS_SET_WRAPPER(gclass->is_bp, py_arch_register_is_base_pointer_wrapper);
+ PY_CLASS_SET_WRAPPER(gclass->is_sp, py_arch_register_is_stack_pointer_wrapper);
- Py_DECREF(args);
-
- Py_XDECREF(pyret);
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
- return result;
+ return 0;
}
/******************************************************************************
* *
-* Paramètres : reg = registre visé par la procédure. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Traduit un registre en version humainement lisible. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : - *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_arch_register_print_wrapper(const GArchRegister *reg, GBufferLine *line)
+static int py_arch_register_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- 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);
+ int ret; /* Bilan de lecture des args. */
- Py_XDECREF(pyret);
+#define ARCH_REGISTER_DOC \
+ "The ArchRegister object aims to get subclassed in order 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 may to be implemnted for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister._is_base_pointer();\n" \
+ "* pychrysalide.arch.ArchRegister._is_stack_pointer().\n"
- }
+ /* Initialisation d'un objet GLib */
- Py_DECREF(pyobj);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- PyGILState_Release(gstate);
+ return 0;
}
@@ -486,51 +259,6 @@ static bool py_arch_register_is_stack_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. *
* *
@@ -618,9 +346,6 @@ static PyObject *py_arch_register_is_stack_pointer(PyObject *self, void *closure
PyTypeObject *get_python_arch_register_type(void)
{
static PyMethodDef py_arch_register_methods[] = {
- 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 }
@@ -643,11 +368,10 @@ PyTypeObject *get_python_arch_register_type(void)
.tp_doc = ARCH_REGISTER_DOC,
- .tp_richcompare = py_arch_register_richcompare,
-
.tp_methods = py_arch_register_methods,
.tp_getset = py_arch_register_getseters,
+ .tp_init = py_arch_register_init,
.tp_new = py_arch_register_new,
};
@@ -683,9 +407,20 @@ bool ensure_python_arch_register_is_registered(void)
dict = PyModule_GetDict(module);
+ if (!ensure_python_comparable_object_is_registered())
+ return false;
+
+ if (!ensure_python_hashable_object_is_registered())
+ return false;
+
if (!ensure_python_serializable_object_is_registered())
return false;
+ if (!ensure_python_string_builder_is_registered())
+ return false;
+
+ pyg_register_class_init(G_TYPE_ARCH_REGISTER, (PyGClassInitFunc)py_arch_register_init_gclass);
+
if (!register_class_for_pygobject(dict, G_TYPE_ARCH_REGISTER, type))
return false;
diff --git a/plugins/pychrysalide/bindings.c b/plugins/pychrysalide/bindings.c
index 7e87e27..f120c3b 100644
--- a/plugins/pychrysalide/bindings.c
+++ b/plugins/pychrysalide/bindings.c
@@ -33,6 +33,7 @@
#include <common/cpp.h>
+#include <common/environment.h>
#include <common/extstr.h>
#include <core/core.h>
#include <plugins/pglist.h>
@@ -52,10 +53,6 @@
#include "glibext/module.h"
/* #include "debug/module.h" */
#include "format/module.h"
-/* #ifdef INCLUDE_GTK_SUPPORT */
-/* # include "gtkext/module.h" */
-/* # include "gui/module.h" */
-/* #endif */
/* #include "mangling/module.h" */
#include "plugins/module.h"
@@ -149,7 +146,7 @@ static void ensure_native_pygobject_type(PyTypeObject **);
static PyObject *get_existing_modules(void);
/* Définit les différents modules du support Python. */
-static PyObject *create_basic_modules(void);
+static PyObject *create_basic_modules(const pyinit_details_t *);
/* Inscrit les défintions des objets Python de Chrysalide. */
static bool populate_python_modules(const pyinit_details_t *);
@@ -158,6 +155,7 @@ static bool populate_python_modules(const pyinit_details_t *);
static void restore_original_pygobject_type(PyTypeObject *);
+
/* ------------------------ FONCTIONS GLOBALES DE CHRYSALIDE ------------------------ */
@@ -978,7 +976,7 @@ static PyObject *get_existing_modules(void)
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : details = précisions de chargement complémentaires. *
* *
* Description : Définit les différents modules du support Python. *
* *
@@ -988,7 +986,7 @@ static PyObject *get_existing_modules(void)
* *
******************************************************************************/
-static PyObject *create_basic_modules(void)
+static PyObject *create_basic_modules(const pyinit_details_t *details)
{
PyObject *result; /* Module Python à retourner */
bool status; /* Bilan des inclusions */
@@ -1036,14 +1034,17 @@ static PyObject *create_basic_modules(void)
*/
if (status) status = add_format_module(result);
/*
-#ifdef INCLUDE_GTK_SUPPORT
- if (status) status = add_gtkext_module(result);
- if (status) status = add_gui_module(result);
-#endif
if (status) status = add_mangling_module(result);
*/
if (status) status = add_plugins_module(result);
+ /**
+ * Ajout de modules UI supplémentaires éventuels.
+ */
+
+ if (status && details->add_extra != NULL)
+ status = details->add_extra(result);
+
if (!status)
{
Py_DECREF(result);
@@ -1081,8 +1082,8 @@ static bool populate_python_modules(const pyinit_details_t *details)
* un chargement préliminaire, si besoin est.
*/
- if (details->populate_extra)
- result = details->populate_extra();
+ if (details->populate_extra != NULL)
+ result = details->populate_extra(false);
else
result = true;
@@ -1101,14 +1102,22 @@ static bool populate_python_modules(const pyinit_details_t *details)
*/
if (result) result = populate_format_module();
/*
-#ifdef INCLUDE_GTK_SUPPORT
- if (result) result = populate_gtkext_module();
- if (result) result = populate_gui_module();
-#endif
if (result) result = populate_mangling_module();
*/
if (result) result = populate_plugins_module();
+ /**
+ * Certaines définitions reposent sur une déclinaison de GtkWidget,
+ * dont le chargement va remplacer la définition statique de GObject
+ * par une version allouée dynamiquement.
+ *
+ * De telles définitions doivent donc être prise en compte à la fin
+ * du chargement.
+ */
+
+ if (result && details->populate_extra != NULL)
+ result = details->populate_extra(true);
+
return result;
}
@@ -1202,7 +1211,7 @@ PyObject *init_python_pychrysalide_module(const pyinit_details_t *details)
ensure_native_pygobject_type(&py_gobj_def);
- result = create_basic_modules();
+ result = create_basic_modules(details);
if (result == NULL)
PyErr_SetString(PyExc_SystemError, "failed to create all PyChrysalide modules.");
@@ -1356,6 +1365,54 @@ void log_pychrysalide_exception(const char *prefix, ...)
/* ---------------------------------------------------------------------------------- */
+/* INTERVENTION DANS LA GESTION DE GREFFONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = instance représentant le greffon courant. *
+* path = chemin supplémentaire pour l'espace de recherche. *
+* *
+* Description : Complète les chemins de recherches de Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void extend_python_path(const GPluginModule *plugin, const char *path)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *list; /* Liste de chemins à compléter*/
+ PyObject *new; /* Nouveau chemin à intégrer */
+
+ gstate = PyGILState_Ensure();
+
+ list = PySys_GetObject("path");
+ assert(list != NULL);
+
+ new = PyUnicode_FromString(path);
+ assert(new != NULL);
+
+ PyList_Append(list, new);
+
+ Py_DECREF(new);
+
+ add_to_env_var("PYTHONPATH", path, ":");
+
+ PyGILState_Release(gstate);
+
+ g_plugin_module_log_variadic_message(plugin, LMT_INFO,
+ _("PYTHONPATH environment variable set to '%s'"),
+ getenv("PYTHONPATH"));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* FONCTIONS GLOBALES DE CHRYSALIDE */
/* ---------------------------------------------------------------------------------- */
diff --git a/plugins/pychrysalide/bindings.h b/plugins/pychrysalide/bindings.h
index 1758747..036f852 100644
--- a/plugins/pychrysalide/bindings.h
+++ b/plugins/pychrysalide/bindings.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* bindings.h - prototypes pour les éléments d'un socle commun aux fonctionnalités graphiques et non graphiques
*
- * Copyright (C) 2024 Cyrille Bagard
+ * Copyright (C) 2024-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -44,6 +44,9 @@
+/* ------------------------ FONCTIONNALITES DE MISE EN PLACE ------------------------ */
+
+
/* Charge un module GI dans Python avec une version attendue. */
bool import_namespace_from_gi_repository(const char *, const char *);
@@ -52,7 +55,9 @@ typedef struct _pyinit_details_t
{
bool standalone; /* Chargement depuis Python ? */
- bool (* populate_extra) (void); /* Ajout de types ? */
+ bool (* add_extra) (PyObject *); /* Ajout de modules ? */
+
+ bool (* populate_extra) (bool); /* Ajout de types ? */
/**
* Prototype de la fonction de création, à garder synchronisé avec
@@ -70,4 +75,12 @@ void log_pychrysalide_exception(const char *, ...);
+/* -------------------- INTERVENTION DANS LA GESTION DE GREFFONS -------------------- */
+
+
+/* Complète les chemins de recherches de Python. */
+void extend_python_path(const GPluginModule *, const char *);
+
+
+
#endif /* _PLUGINS_PYCHRYSALIDE_BINDINGS_H */
diff --git a/plugins/pychrysalide/common/Makefile.am b/plugins/pychrysalide/common/Makefile.am
index 43e1fc4..ad58900 100644
--- a/plugins/pychrysalide/common/Makefile.am
+++ b/plugins/pychrysalide/common/Makefile.am
@@ -6,7 +6,6 @@ noinst_LTLIBRARIES = libpychrysacommon.la
# fnv1a.h fnv1a.c \
# hex.h hex.c \
# itoa.h itoa.c \
-# leb128.h leb128.c \
# module.h module.c \
# packed.h packed.c \
# pathname.h pathname.c \
@@ -15,6 +14,7 @@ noinst_LTLIBRARIES = libpychrysacommon.la
libpychrysacommon_la_SOURCES = \
bits.h bits.c \
entropy.h entropy.c \
+ leb128.h leb128.c \
module.h module.c \
xdg.h xdg.c
diff --git a/plugins/pychrysalide/common/leb128.c b/plugins/pychrysalide/common/leb128.c
index 8b15303..2eeb191 100644
--- a/plugins/pychrysalide/common/leb128.c
+++ b/plugins/pychrysalide/common/leb128.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* leb128.c - équivalent Python du fichier "common/leb128.c"
*
- * Copyright (C) 2018-2020 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,13 +26,13 @@
#include <assert.h>
+#include <malloc.h>
#include <pygobject.h>
#include <common/leb128.h>
-#include "packed.h"
#include "../access.h"
#include "../helpers.h"
@@ -69,31 +69,29 @@ static PyObject *py_leb128_pack_uleb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
uleb128_t value; /* Valeur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de l'opération */
-
-#define LEB128_PACK_ULEB128_METHOD PYTHON_METHOD_DEF \
-( \
- pack_uleb128, "value, pbuf", \
- METH_VARARGS, py_leb128, \
- "Pack an unsigned LEB128 value into a data buffer.\n" \
- "\n" \
- "The *value* is an integer value. The *pbuf* argument has to" \
- " be a pychrysalide.common.PackedBuffer instance where data" \
- " will be appended.\n" \
- "\n" \
- "The returned value is the operation status: *True* for" \
- " success, *False* for failure." \
+ size_t count; /* Nombre d'octets produits */
+ void *bytes; /* Octets de représentation */
+
+#define LEB128_PACK_ULEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ pack_uleb128, "value", \
+ METH_VARARGS, py_leb128, \
+ "Pack an unsigned LEB128 value into bytes.\n" \
+ "\n" \
+ "The *value* has to be an integer value.\n" \
+ "\n" \
+ "The returned value is byte data." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_uleb128_value, &value, convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_uleb128_value, &value);
if (!ret) return NULL;
- status = pack_uleb128(&value, pbuf);
+ bytes = pack_uleb128(&value, &count);
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ result = PyBytes_FromStringAndSize(bytes, count);
+
+ free(bytes);
return result;
@@ -117,31 +115,29 @@ static PyObject *py_leb128_pack_leb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
leb128_t value; /* Valeur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de l'opération */
-
-#define LEB128_PACK_LEB128_METHOD PYTHON_METHOD_DEF \
-( \
- pack_leb128, "value, pbuf", \
- METH_VARARGS, py_leb128, \
- "Pack a signed LEB128 value into a data buffer.\n" \
- "\n" \
- "The *value* is an integer value. The *pbuf* argument has to" \
- " be a pychrysalide.common.PackedBuffer instance where data" \
- " will be appended.\n" \
- "\n" \
- "The returned value is the operation status: *True* for" \
- " success, *False* for failure." \
+ size_t count; /* Nombre d'octets produits */
+ void *bytes; /* Octets de représentation */
+
+#define LEB128_PACK_LEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ pack_leb128, "value", \
+ METH_VARARGS, py_leb128, \
+ "Pack a signed LEB128 value into bytes.\n" \
+ "\n" \
+ "The *value* has to be an integer value.\n" \
+ "\n" \
+ "The returned value is byte data." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_leb128_value, &value, convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_leb128_value, &value);
if (!ret) return NULL;
- status = pack_leb128(&value, pbuf);
+ bytes = pack_leb128(&value, &count);
+
+ result = PyBytes_FromStringAndSize(bytes, count);
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ free(bytes);
return result;
@@ -164,33 +160,42 @@ static PyObject *py_leb128_pack_leb128(PyObject *self, PyObject *args)
static PyObject *py_leb128_unpack_uleb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *bytes; /* Octets brutes transmis */
+ Py_ssize_t count; /* Quantité de ces octets */
int ret; /* Bilan de lecture des args. */
+ const void *pos; /* Tëte de lecture */
+ const void *max; /* Position de lecture maximale*/
uleb128_t value; /* Valeur à manipuler */
bool status; /* Bilan de l'opération */
#define LEB128_UNPACK_ULEB128_METHOD PYTHON_METHOD_DEF \
( \
- unpack_uleb128, "pbuf", \
+ unpack_uleb128, "buf", \
METH_VARARGS, py_leb128, \
- "Unpack an unsigned LEB128 value into a data buffer.\n" \
+ "Unpack an unsigned LEB128 value from bytes.\n" \
"\n" \
- "The *pbuf* argument has to be a" \
- " pychrysalide.common.PackedBuffer instance from where data" \
- " will be read.\n" \
+ "The *buf* argument needs to be bytes with enough data aimed" \
+ " to get translated into an unsigned LEB128 value.\n" \
"\n" \
"The returned value depends on the operation status: *None*" \
- " for failure or a integer value for success." \
+ " for failure or a tuple with two items for success: the" \
+ " decoded value and the remaining bytes." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "y#", &bytes, &count);
if (!ret) return NULL;
- status = unpack_uleb128(&value, pbuf);
+ pos = bytes;
+ max = bytes + count;
- if (status)
- result = PyLong_FromUnsignedLongLong(value);
+ status = unpack_uleb128(&value, &pos, max);
+ if (status)
+ {
+ result = PyTuple_New(2);
+ PyTuple_SetItem(result, 0, PyLong_FromUnsignedLongLong(value));
+ PyTuple_SetItem(result, 1, PyBytes_FromStringAndSize(pos, (char *)max - (char *)pos));
+ }
else
{
result = Py_None;
@@ -218,33 +223,43 @@ static PyObject *py_leb128_unpack_uleb128(PyObject *self, PyObject *args)
static PyObject *py_leb128_unpack_leb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *bytes; /* Octets brutes transmis */
+ Py_ssize_t count; /* Quantité de ces octets */
int ret; /* Bilan de lecture des args. */
+ const void *pos; /* Tëte de lecture */
+ const void *max; /* Position de lecture maximale*/
leb128_t value; /* Valeur à manipuler */
bool status; /* Bilan de l'opération */
#define LEB128_UNPACK_LEB128_METHOD PYTHON_METHOD_DEF \
( \
- unpack_leb128, "pbuf", \
+ unpack_leb128, "buf", \
METH_VARARGS, py_leb128, \
- "Unpack a signed LEB128 value into a data buffer.\n" \
+ "Unpack a signed LEB128 value from bytes.\n" \
"\n" \
- "The *pbuf* argument has to be a" \
- " pychrysalide.common.PackedBuffer instance from where data" \
- " will be read.\n" \
+ "\n" \
+ "The *buf* argument needs to be bytes with enough data aimed" \
+ " to get translated into a signed LEB128 value.\n" \
"\n" \
"The returned value depends on the operation status: *None*" \
- " for failure or a integer value for success." \
+ " for failure or a tuple with two items for success: the" \
+ " decoded value and the remaining bytes." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "y#", &bytes, &count);
if (!ret) return NULL;
- status = unpack_leb128(&value, pbuf);
+ pos = bytes;
+ max = bytes + count;
- if (status)
- result = PyLong_FromLongLong(value);
+ status = unpack_leb128(&value, &pos, max);
+ if (status)
+ {
+ result = PyTuple_New(2);
+ PyTuple_SetItem(result, 0, PyLong_FromLongLong(value));
+ PyTuple_SetItem(result, 1, PyBytes_FromStringAndSize(pos, (char *)max - (char *)pos));
+ }
else
{
result = Py_None;
diff --git a/plugins/pychrysalide/common/module.c b/plugins/pychrysalide/common/module.c
index fa2b4de..c82c7bc 100644
--- a/plugins/pychrysalide/common/module.c
+++ b/plugins/pychrysalide/common/module.c
@@ -30,7 +30,7 @@
//#include "fnv1a.h"
//#include "hex.h"
//#include "itoa.h"
-//#include "leb128.h"
+#include "leb128.h"
//#include "packed.h"
//#include "pathname.h"
//#include "pearson.h"
@@ -104,11 +104,11 @@ bool populate_common_module(void)
if (result) result = populate_common_module_with_fnv1a();
if (result) result = populate_common_module_with_hex();
if (result) result = populate_common_module_with_itoa();
- if (result) result = populate_common_module_with_leb128();
if (result) result = populate_common_module_with_pathname();
if (result) result = populate_common_module_with_pearson();
*/
if (result) result = populate_common_module_with_entropy();
+ if (result) result = populate_common_module_with_leb128();
if (result) result = populate_common_module_with_xdg();
if (result) result = ensure_python_bitfield_is_registered();
diff --git a/plugins/pychrysalide/constants.h b/plugins/pychrysalide/constants.h
index 332afe0..151f1eb 100644
--- a/plugins/pychrysalide/constants.h
+++ b/plugins/pychrysalide/constants.h
@@ -46,6 +46,9 @@ int convert_to_source_endian(PyObject *, void *);
/* Tente de convertir en constante MemoryDataSize. */
int convert_to_memory_data_size(PyObject *, void *);
+#define cast_memory_data_size_to_python(v) \
+ cast_with_constants_group_from_module("pychrysalide", "MemoryDataSize", v)
+
#endif /* _PLUGINS_PYCHRYSALIDE_CONSTANTS_H */
diff --git a/plugins/pychrysalide/convert.c b/plugins/pychrysalide/convert.c
index c67c8ba..08866cb 100644
--- a/plugins/pychrysalide/convert.c
+++ b/plugins/pychrysalide/convert.c
@@ -87,3 +87,34 @@ int convert_to_gsettings(PyObject *arg, void *dst)
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 instance GSettings ou NULL. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_gsettings_or_none(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ if (arg == Py_None)
+ {
+ *((GSettings **)dst) = NULL;
+ result = 1;
+ }
+
+ else
+ result = convert_to_gsettings(arg, dst);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/convert.h b/plugins/pychrysalide/convert.h
index 7bdf7da..86d7528 100644
--- a/plugins/pychrysalide/convert.h
+++ b/plugins/pychrysalide/convert.h
@@ -33,6 +33,9 @@
/* Tente de convertir en instance GSettings. */
int convert_to_gsettings(PyObject *, void *);
+/* Tente de convertir en instance GSettings ou NULL. */
+int convert_to_gsettings_or_none(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_CONVERT_H */
diff --git a/plugins/pychrysalide/core-ui.c b/plugins/pychrysalide/core-ui.c
index 1b332b7..00d1cc1 100644
--- a/plugins/pychrysalide/core-ui.c
+++ b/plugins/pychrysalide/core-ui.c
@@ -28,11 +28,19 @@
#include <i18n.h>
+#ifdef DISCARD_LOCAL
+# include <core/paths.h>
+#endif
+#include <plugins/manager-int.h>
#include <plugins/self.h>
#include "bindings.h"
#include "core-ui-int.h"
+#include "arch/module-ui.h"
+#include "glibext/module-ui.h"
+#include "gtkext/module.h"
+//#include "gui/module.h"
@@ -47,14 +55,17 @@ static bool _standalone = true;
/* Initialise la classe des greffons de support Python. */
static void g_pychrysalide_plugin_ui_class_init(GPyChrysalidePluginUIClass *);
+/* Procède à l'initialisation de l'interface de gestion. */
+static void g_pychrysalide_plugin_ui_plugin_manager_interface_init(GPluginManagerInterface *);
+
/* Initialise une instance de greffon de support Python. */
static void g_pychrysalide_plugin_ui_init(GPyChrysalidePluginUI *);
/* Supprime toutes les références externes. */
-static void g_pychrysalide_plugin_ui_dispose(GPyChrysalidePluginUI *);
+static void g_pychrysalide_plugin_ui_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_pychrysalide_plugin_ui_finalize(GPyChrysalidePluginUI *);
+static void g_pychrysalide_plugin_ui_finalize(GObject *);
@@ -62,7 +73,26 @@ static void g_pychrysalide_plugin_ui_finalize(GPyChrysalidePluginUI *);
/* Prend acte de l'activation du greffon. */
-static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *);
+static bool g_pychrysalide_plugin_ui_enable(GPluginModule *);
+
+
+
+/* -------------------- INTERVENTION DANS LA GESTION DE GREFFONS -------------------- */
+
+
+/* Prend acte du chargement de l'ensemble des greffons natifs. */
+static void g_pychrysalide_plugin_ui_handle_native_plugins_loaded_event(GPluginManager *);
+
+
+
+/* --------------------------- POINT D'ENTREE POUR PYTHON --------------------------- */
+
+
+/*Ajoute des modules UI aux extensions Python. */
+static bool add_python_ui_modules(PyObject *);
+
+/* Inscrit les défintions des objets UI Python de Chrysalide. */
+static bool populate_python_modules_ui(bool);
@@ -72,7 +102,8 @@ static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *);
/* Indique le type défini pour un greffon de liaison Python */
-G_DEFINE_TYPE(GPyChrysalidePluginUI, g_pychrysalide_plugin_ui, G_TYPE_PYCHRYSALIDE_PLUGIN);
+G_DEFINE_TYPE_WITH_CODE(GPyChrysalidePluginUI, g_pychrysalide_plugin_ui, G_TYPE_PYCHRYSALIDE_PLUGIN,
+ G_IMPLEMENT_INTERFACE(G_TYPE_PLUGIN_MANAGER, g_pychrysalide_plugin_ui_plugin_manager_interface_init));
NATIVE_PLUGIN_ENTRYPOINT(g_pychrysalide_plugin_ui_new);
@@ -97,12 +128,31 @@ static void g_pychrysalide_plugin_ui_class_init(GPyChrysalidePluginUIClass *clas
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_pychrysalide_plugin_ui_dispose;
- object->finalize = (GObjectFinalizeFunc)g_pychrysalide_plugin_ui_finalize;
+ object->dispose = g_pychrysalide_plugin_ui_dispose;
+ object->finalize = g_pychrysalide_plugin_ui_finalize;
plugin = G_PLUGIN_MODULE_CLASS(class);
- plugin->enable = (pg_management_fc)g_pychrysalide_plugin_ui_enable;
+ plugin->enable = g_pychrysalide_plugin_ui_enable;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de gestion. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pychrysalide_plugin_ui_plugin_manager_interface_init(GPluginManagerInterface *iface)
+{
+ iface->handle_native = g_pychrysalide_plugin_ui_handle_native_plugins_loaded_event;
}
@@ -127,7 +177,7 @@ static void g_pychrysalide_plugin_ui_init(GPyChrysalidePluginUI *plugin)
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -137,16 +187,16 @@ static void g_pychrysalide_plugin_ui_init(GPyChrysalidePluginUI *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_ui_dispose(GPyChrysalidePluginUI *plugin)
+static void g_pychrysalide_plugin_ui_dispose(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_ui_parent_class)->dispose(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_ui_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -156,16 +206,16 @@ static void g_pychrysalide_plugin_ui_dispose(GPyChrysalidePluginUI *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_ui_finalize(GPyChrysalidePluginUI *plugin)
+static void g_pychrysalide_plugin_ui_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_ui_parent_class)->finalize(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_ui_parent_class)->finalize(object);
}
/******************************************************************************
* *
-* Paramètres : filename = nom du fichier à charger. *
+* Paramètres : module = extension vue du système. *
* *
* Description : Crée un module pour un greffon de support Python. *
* *
@@ -192,7 +242,7 @@ GPluginModule *g_pychrysalide_plugin_ui_new(GModule *module)
/******************************************************************************
* *
* Paramètres : plugin = instance à initialiser pleinement. *
-* module = module système correspondant. *
+* module = extension vue du système. *
* *
* Description : Met en place un module pour un greffon de support Python. *
* *
@@ -231,22 +281,24 @@ bool g_pychrysalide_plugin_ui_create(GPyChrysalidePluginUI *plugin, GModule *mod
* *
******************************************************************************/
-static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *plugin)
+static bool g_pychrysalide_plugin_ui_enable(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
+ GPyChrysalidePlugin *pychr_plugin; /* Version spécialisée */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
int ret; /* Bilan de préparatifs */
_standalone = false;
+ pychr_plugin = G_PYCHRYSALIDE_PLUGIN(plugin);
+
/* Chargement du module pour Python */
ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalideui);
if (ret == -1)
{
- g_plugin_module_log_simple_message(G_PLUGIN_MODULE(plugin),
- LMT_ERROR,
+ g_plugin_module_log_simple_message(plugin, LMT_ERROR,
_("Can not extend the existing table of Python built-in modules."));
result = false;
@@ -258,7 +310,7 @@ static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *plugin)
gstate = PyGILState_Ensure();
- G_PYCHRYSALIDE_PLUGIN(plugin)->py_module = PyImport_ImportModule("pychrysalide");
+ pychr_plugin->py_module = PyImport_ImportModule("pychrysalide");
/**
* Pour mémoire, une situation concrête conduisant à un échec :
@@ -273,7 +325,7 @@ static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *plugin)
// TODO : check (2025)
- result = (G_PYCHRYSALIDE_PLUGIN(plugin)->py_module != NULL);
+ result = (pychr_plugin->py_module != NULL);
PyGILState_Release(gstate);
@@ -286,12 +338,139 @@ static bool g_pychrysalide_plugin_ui_enable(GPyChrysalidePluginUI *plugin)
/* ---------------------------------------------------------------------------------- */
+/* INTERVENTION DANS LA GESTION DE GREFFONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = interface à manipuler. *
+* *
+* Description : Accompagne la fin du chargement des modules natifs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pychrysalide_plugin_ui_handle_native_plugins_loaded_event(GPluginManager *manager)
+{
+ GPluginModule *plugin; /* Version de base du greffon */
+#ifdef DISCARD_LOCAL
+ char *edir; /* Répertoire de base effectif */
+ DIR *dir; /* Répertoire à parcourir */
+#endif
+ GPluginManagerInterface *iface; /* Interface utilisée */
+ GPluginManagerInterface *parent_iface; /* Interface parente */
+
+ plugin = G_PLUGIN_MODULE(manager);
+
+ /* Définition des zones d'influence */
+
+#ifndef DISCARD_LOCAL
+
+ extend_python_path(plugin, PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "pythonui");
+
+#else
+
+ edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "pythonui");
+
+ dir = opendir(edir);
+
+ if (dir != NULL)
+ {
+ closedir(dir);
+
+ extend_python_path(plugin, edir);
+
+ }
+
+ free(edir);
+
+#endif
+
+ /* Chargements des extensions Python */
+
+ iface = G_PLUGIN_MANAGER_GET_IFACE(manager);
+
+ parent_iface = g_type_interface_peek_parent(iface);
+
+ parent_iface->handle_native(manager);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* POINT D'ENTREE POUR PYTHON */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
+* Paramètres : super = module dont la définition est à compléter. *
+* *
+* Description : Ajoute des modules UI aux extensions Python. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool add_python_ui_modules(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = add_gtkext_module(super);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modify = autorisation de motification du type GObject. *
+* *
+* Description : Inscrit les défintions des objets UI Python de Chrysalide. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool populate_python_modules_ui(bool modify)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (!modify)
+ {
+ if (result) result = populate_arch_module_ui();
+ if (result) result = populate_glibext_module_ui();
+
+ }
+
+ else
+ {
+ if (result) result = populate_gtkext_module();
+ //if (result) result = populate_gui_module();
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Point d'entrée pour l'initialisation de Python. *
@@ -309,7 +488,8 @@ PyMODINIT_FUNC PyInit_pychrysalideui(void)
details.standalone = _standalone;
- details.populate_extra = NULL;
+ details.add_extra = add_python_ui_modules;
+ details.populate_extra = populate_python_modules_ui;
details.create_self = g_pychrysalide_plugin_ui_new;
result = init_python_pychrysalide_module(&details);
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index 0e72b46..0fea9c4 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -24,24 +24,14 @@
#include "core.h"
-#include "core-int.h"
-
-
-
-
-
#undef NO_IMPORT_PYGOBJECT
#include <pygobject.h>
#define NO_IMPORT_PYGOBJECT
-#include "core.h"
-
-
#include <assert.h>
#include <errno.h>
#include <malloc.h>
-//#include <pygobject.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
@@ -60,10 +50,9 @@
#include <plugins/self.h>
-
-
#include "access.h"
#include "bindings.h"
+#include "core-int.h"
@@ -72,14 +61,6 @@ static bool _standalone = true;
-
-
-
-
-
-
-
-
/* ---------------------- COMPOSITION DE NOUVEAU GREFFON NATIF ---------------------- */
@@ -93,10 +74,10 @@ static void g_pychrysalide_plugin_plugin_manager_interface_init(GPluginManagerIn
static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *);
/* Supprime toutes les références externes. */
-static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_finalize(GObject *);
@@ -104,19 +85,16 @@ static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *);
/* Prend acte de l'activation du greffon. */
-static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *);
+static bool g_pychrysalide_plugin_enable(GPluginModule *);
/* Prend acte de la désactivation du greffon. */
-static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *);
+static bool g_pychrysalide_plugin_disable(GPluginModule *);
/* -------------------- INTERVENTION DANS LA GESTION DE GREFFONS -------------------- */
-/* Complète les chemins de recherches de Python. */
-static void extend_python_path(const char *);
-
/* Crée un greffon à partir de code Python. */
static GPluginModule *create_python_plugin(const char *, const char *);
@@ -124,7 +102,7 @@ static GPluginModule *create_python_plugin(const char *, const char *);
static void load_python_plugins(GPluginModule *);
/* Prend acte du chargement de l'ensemble des greffons natifs. */
-static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPyChrysalidePlugin *);
+static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPluginManager *);
@@ -160,13 +138,13 @@ static void g_pychrysalide_plugin_class_init(GPyChrysalidePluginClass *class)
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_pychrysalide_plugin_dispose;
- object->finalize = (GObjectFinalizeFunc)g_pychrysalide_plugin_finalize;
+ object->dispose = g_pychrysalide_plugin_dispose;
+ object->finalize = g_pychrysalide_plugin_finalize;
plugin = G_PLUGIN_MODULE_CLASS(class);
- plugin->enable = (pg_management_fc)g_pychrysalide_plugin_enable;
- plugin->disable = (pg_management_fc)g_pychrysalide_plugin_disable;
+ plugin->enable = g_pychrysalide_plugin_enable;
+ plugin->disable = g_pychrysalide_plugin_disable;
}
@@ -185,7 +163,7 @@ static void g_pychrysalide_plugin_class_init(GPyChrysalidePluginClass *class)
static void g_pychrysalide_plugin_plugin_manager_interface_init(GPluginManagerInterface *iface)
{
- iface->handle_native = (handle_native_plugins_cb)g_pychrysalide_plugin_handle_native_plugins_loaded_event;
+ iface->handle_native = g_pychrysalide_plugin_handle_native_plugins_loaded_event;
}
@@ -213,7 +191,7 @@ static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *plugin)
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -223,16 +201,16 @@ static void g_pychrysalide_plugin_init(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_dispose(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->dispose(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -242,16 +220,16 @@ static void g_pychrysalide_plugin_dispose(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_finalize(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->finalize(G_OBJECT(plugin));
+ G_OBJECT_CLASS(g_pychrysalide_plugin_parent_class)->finalize(object);
}
/******************************************************************************
* *
-* Paramètres : filename = nom du fichier à charger. *
+* Paramètres : module = extension vue du système. *
* *
* Description : Crée un module pour un greffon de support Python. *
* *
@@ -278,7 +256,7 @@ GPluginModule *g_pychrysalide_plugin_new(GModule *module)
/******************************************************************************
* *
* Paramètres : plugin = instance à initialiser pleinement. *
-* module = module système correspondant. *
+* module = extension vue du système. *
* *
* Description : Met en place un module pour un greffon de support Python. *
* *
@@ -323,22 +301,24 @@ bool g_pychrysalide_plugin_create(GPyChrysalidePlugin *plugin, GModule *module)
* *
******************************************************************************/
-static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
+static bool g_pychrysalide_plugin_enable(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
+ GPyChrysalidePlugin *pychr_plugin; /* Version spécialisée */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
int ret; /* Bilan de préparatifs */
_standalone = false;
+ pychr_plugin = G_PYCHRYSALIDE_PLUGIN(plugin);
+
/* Chargement du module pour Python */
ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide);
if (ret == -1)
{
- g_plugin_module_log_simple_message(G_PLUGIN_MODULE(plugin),
- LMT_ERROR,
+ g_plugin_module_log_simple_message(plugin, LMT_ERROR,
_("Can not extend the existing table of Python built-in modules."));
result = false;
@@ -350,7 +330,7 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
gstate = PyGILState_Ensure();
- plugin->py_module = PyImport_ImportModule("pychrysalide");
+ pychr_plugin->py_module = PyImport_ImportModule("pychrysalide");
/**
* Pour mémoire, une situation concrête conduisant à un échec :
@@ -365,7 +345,7 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
// TODO : check (2025)
- result = (plugin->py_module != NULL);
+ result = (pychr_plugin->py_module != NULL);
PyGILState_Release(gstate);
@@ -388,14 +368,17 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin)
* *
******************************************************************************/
-static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin)
+static bool g_pychrysalide_plugin_disable(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
+ GPyChrysalidePlugin *pychr_plugin; /* Version spécialisée */
bool standalone; /* Nature du chargement */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
result = true;
+ pychr_plugin = G_PYCHRYSALIDE_PLUGIN(plugin);
+
/**
* Le champ plugin->py_module n'est défini que via la fonction
* g_pychrysalide_plugin_enable(), qui n'est pas sollicitée lorsque
@@ -407,7 +390,7 @@ static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin)
* initial ici.
*/
- standalone = (plugin->py_module == NULL);
+ standalone = (pychr_plugin->py_module == NULL);
/**
* Si on se trouve embarqué dans un interpréteur Python, le déchargement
@@ -430,8 +413,8 @@ static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin)
clear_all_accesses_to_python_modules();
- Py_XDECREF(plugin->py_module);
- plugin->py_module = NULL;
+ Py_XDECREF(pychr_plugin->py_module);
+ pychr_plugin->py_module = NULL;
if (!standalone)
PyGILState_Release(gstate);
@@ -449,38 +432,6 @@ static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin)
/******************************************************************************
* *
-* Paramètres : path = chemin supplémentaire pour l'espace de recherche. *
-* *
-* Description : Complète les chemins de recherches de Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void extend_python_path(const char *path)
-{
- PyObject *list; /* Liste de chemins à compléter*/
- PyObject *new; /* Nouveau chemin à intégrer */
-
- list = PySys_GetObject("path");
- assert(list != NULL);
-
- new = PyUnicode_FromString(path);
- assert(new != NULL);
-
- PyList_Append(list, new);
-
- Py_DECREF(new);
-
- add_to_env_var("PYTHONPATH", path, ":");
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : modname = nom du module à charger. *
* filename = chemin d'accès au code Python à charger. *
* *
@@ -568,48 +519,18 @@ static GPluginModule *create_python_plugin(const char *modname, const char *file
static void load_python_plugins(GPluginModule *plugin)
{
-#ifdef DISCARD_LOCAL
- char *edir; /* Répertoire de base effectif */
-#endif
- DIR *dir; /* Répertoire à parcourir */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
char *paths; /* Emplacements de greffons */
char *save; /* Sauvegarde pour ré-entrance */
char *path; /* Chemin à fouiller */
+ DIR *dir; /* Répertoire à parcourir */
struct dirent *entry; /* Elément trouvé */
char *modname; /* Nom du module pour Python */
char *filename; /* Chemin d'accès reconstruit */
GPluginModule *pyplugin; /* Lien vers un grffon Python */
bool status; /* Bilan d'une opération */
- /* Définition des zones d'influence */
-
-#ifndef DISCARD_LOCAL
-
- extend_python_path(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "python");
-
-#else
-
- edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
-
- dir = opendir(edir);
-
- if (dir != NULL)
- {
- closedir(dir);
-
- extend_python_path(edir);
-
- }
-
- free(edir);
-
-#endif
-
- g_plugin_module_log_variadic_message(plugin, LMT_INFO,
- _("PYTHONPATH environment variable set to '%s'"),
- getenv("PYTHONPATH"));
-
- /* Chargements des extensions Python */
+ gstate = PyGILState_Ensure();
paths = get_env_var("PYTHONPATH");
@@ -622,7 +543,7 @@ static void load_python_plugins(GPluginModule *plugin)
dir = opendir(path);
if (dir == NULL)
{
- perror("opendir");
+ LOG_ERROR_N("opendir");
continue;
}
@@ -639,7 +560,7 @@ static void load_python_plugins(GPluginModule *plugin)
if (entry == NULL)
{
if (errno != 0)
- perror("readdir");
+ LOG_ERROR_N("readdir");
break;
@@ -703,12 +624,14 @@ static void load_python_plugins(GPluginModule *plugin)
free(paths);
+ PyGILState_Release(gstate);
+
}
/******************************************************************************
* *
-* Paramètres : plugin = interface à manipuler. *
+* Paramètres : manager = interface à manipuler. *
* *
* Description : Accompagne la fin du chargement des modules natifs. *
* *
@@ -718,15 +641,43 @@ static void load_python_plugins(GPluginModule *plugin)
* *
******************************************************************************/
-static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPyChrysalidePlugin *plugin)
+static void g_pychrysalide_plugin_handle_native_plugins_loaded_event(GPluginManager *manager)
{
- PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ GPluginModule *plugin; /* Version de base du greffon */
+#ifdef DISCARD_LOCAL
+ char *edir; /* Répertoire de base effectif */
+ DIR *dir; /* Répertoire à parcourir */
+#endif
- gstate = PyGILState_Ensure();
+ plugin = G_PLUGIN_MODULE(manager);
- load_python_plugins(G_PLUGIN_MODULE(plugin));
+ /* Définition des zones d'influence */
- PyGILState_Release(gstate);
+#ifndef DISCARD_LOCAL
+
+ extend_python_path(plugin, PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "python");
+
+#else
+
+ edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+
+ dir = opendir(edir);
+
+ if (dir != NULL)
+ {
+ closedir(dir);
+
+ extend_python_path(plugin, edir);
+
+ }
+
+ free(edir);
+
+#endif
+
+ /* Chargements des extensions Python */
+
+ load_python_plugins(plugin);
}
@@ -756,6 +707,7 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
details.standalone = _standalone;
+ details.add_extra = NULL;
details.populate_extra = NULL;
details.create_self = g_pychrysalide_plugin_new;
diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index af1d9f2..6d3d746 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -1,14 +1,11 @@
-noinst_LTLIBRARIES = libpychrysaglibext.la
+noinst_LTLIBRARIES = libpychrysaglibext.la libpychrysaglibextui.la
# libpychrysaglibext_la_SOURCES = \
# binarycursor.h binarycursor.c \
# buffercache.h buffercache.c \
-# bufferline.h bufferline.c \
# configuration.h configuration.c \
-# linecursor.h linecursor.c \
-# linegen.h linegen.c \
-# module.h module.c
+# linecursor.h linecursor.c
# if BUILD_GTK_SUPPORT
@@ -27,7 +24,9 @@ libpychrysaglibext_la_SOURCES = \
objhole.h objhole.c \
portion.h portion.c \
secstorage.h secstorage.c \
+ serialize.h serialize.c \
singleton.h singleton.c \
+ storage.h storage.c \
strbuilder.h strbuilder.c \
work.h work.c \
workqueue.h workqueue.c
@@ -36,6 +35,16 @@ libpychrysaglibext_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS)
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+libpychrysaglibextui_la_SOURCES = \
+ bufferline.h bufferline.c \
+ constants-ui.h constants-ui.c \
+ generator.h generator.c \
+ module-ui.h module-ui.c
+
+libpychrysaglibextui_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
devdir = $(includedir)/chrysalide/$(subdir)
-dev_HEADERS = $(libpychrysaglibext_la_SOURCES:%c=)
+dev_HEADERS = $(libpychrysaglibext_la_SOURCES:%c=) $(libpychrysaglibextui_la_SOURCES:%c=)
diff --git a/plugins/pychrysalide/glibext/bufferline.c b/plugins/pychrysalide/glibext/bufferline.c
index 09404bc..c5b3664 100644
--- a/plugins/pychrysalide/glibext/bufferline.c
+++ b/plugins/pychrysalide/glibext/bufferline.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* bufferline.c - équivalent Python du fichier "glibext/bufferline.h"
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,25 +26,38 @@
#include <assert.h>
-#include <malloc.h>
+//#include <malloc.h>
#include <pygobject.h>
-#include <i18n.h>
-#include <glibext/bufferline.h>
-#include <plugins/dt.h>
+#include <glibext/bufferline-int.h>
-#include "constants.h"
+//#include "constants.h"
#include "../access.h"
#include "../helpers.h"
-#include "../arch/vmpa.h"
+//#include "../arch/vmpa.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(buffer_line, G_TYPE_BUFFER_LINE);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_buffer_line_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
+
+
/* Accompagne la création d'une instance dérivée en Python. */
static PyObject *py_buffer_line_new(PyTypeObject *, PyObject *, PyObject *);
+#if 0
+
/* Ajoute du texte à formater dans une ligne donnée. */
static PyObject *py_buffer_line_append_text(PyObject *, PyObject *);
@@ -54,29 +67,34 @@ static PyObject *py_buffer_line_get_text(PyObject *, PyObject *);
/* Renseigne sur les propriétés particulières liées à une ligne. */
static PyObject *py_buffer_line_get_flags(PyObject *, void *);
+#endif
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_buffer_line_init(PyObject *self, 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 */
+ unsigned char col_count; /* Qté de colonnes attendues */
+ int ret; /* Bilan de lecture des args. */
+ GBufferLine *line; /* Ligne en version native */
#define BUFFER_LINE_DOC \
"The BufferLine object is used to display processed data: disassembled" \
@@ -84,51 +102,40 @@ static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " BufferLine()" \
+ " BufferLine(col_count)" \
+ "\n" \
+ " Where *col_count* is a integer value providing the expected number of"\
+ " rendering columns." \
"\n" \
"Such objets aim to be created from the Chrysalide core only, and" \
" then get populated on demand. Thus, these lines can be viewed as" \
" cached lines and their properties have to be set through the" \
" pychrysalide.glibext.BufferCache instance which contains them."
- /* Validations diverses */
-
- base = get_python_buffer_line_type();
+ /* Récupération des paramètres */
- if (type == base)
- goto simple_way;
+ ret = PyArg_ParseTuple(args, "B", &col_count);
+ if (!ret) return -1;
- /* Mise en place d'un type dédié */
+ /* Initialisation d'un objet GLib */
- first_time = (g_type_from_name(type->tp_name) == 0);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- 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);
+ /* Eléments de 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);
+ line = G_BUFFER_LINE(pygobject_get(self));
- exit:
+ if (!g_buffer_line_create(line, col_count))
+ return -1;
- return result;
+ return 0;
}
+#if 0
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une ligne de tampon. *
@@ -256,6 +263,7 @@ static PyObject *py_buffer_line_get_flags(PyObject *self, void *closure)
return result;
}
+#endif
/******************************************************************************
@@ -273,20 +281,24 @@ static PyObject *py_buffer_line_get_flags(PyObject *self, void *closure)
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,
"get_text($self, first_col, last_col, markup, /)\n--\n\nProvide the text of a buffer line."
},
+ */
{ NULL }
};
static PyGetSetDef py_buffer_line_getseters[] = {
+ /*
{
"flags", py_buffer_line_get_flags, NULL,
"Current flags of the buffer line.", NULL
},
+ */
{ NULL }
};
@@ -304,7 +316,8 @@ PyTypeObject *get_python_buffer_line_type(void)
.tp_methods = py_buffer_line_methods,
.tp_getset = py_buffer_line_getseters,
- .tp_new = py_buffer_line_new
+ .tp_init = py_buffer_line_init,
+ .tp_new = py_buffer_line_new,
};
@@ -342,11 +355,13 @@ bool ensure_python_buffer_line_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_BUFFER_LINE, type))
return false;
+ /*
if (!define_line_segment_constants(type))
return false;
if (!define_buffer_line_constants(type))
return false;
+ */
}
diff --git a/plugins/pychrysalide/glibext/constants-ui.c b/plugins/pychrysalide/glibext/constants-ui.c
new file mode 100644
index 0000000..4101600
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants-ui.c
@@ -0,0 +1,131 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants-ui.c - ajout des constantes pour les extensions graphique à la GLib
+ *
+ * Copyright (C) 2025 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-ui.h"
+
+
+#include <glibext/bufferline.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux lignes de tampon. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_buffer_line_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", BLF_NONE);
+ if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
+ if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
+ if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
+ if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
+ if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
+ if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
+ "Optional flags linked to a rendering line.");
+
+ 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 BufferLineFlags. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_buffer_line_flags(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur transcrite */
+
+ 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 BufferLineFlags");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if ((value & BLF_ALL) != value)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
+ result = 0;
+ }
+
+ else
+ *((BufferLineFlags *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/constants-ui.h b/plugins/pychrysalide/glibext/constants-ui.h
new file mode 100644
index 0000000..6c7bc6e
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants-ui.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants-ui.h - prototypes pour l'ajout des constantes pour les extensions graphique à la GLib
+ *
+ * Copyright (C) 2025 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_UI_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Définit les constantes relatives aux lignes de tampon. */
+bool define_buffer_line_constants(PyTypeObject *);
+
+/* Tente de convertir en constante BufferLineFlags. */
+int convert_to_buffer_line_flags(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_UI_H */
diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c
index 90ce8cd..f733cf6 100644
--- a/plugins/pychrysalide/glibext/constants.c
+++ b/plugins/pychrysalide/glibext/constants.c
@@ -29,7 +29,6 @@
/*
#include <i18n.h>
-#include <glibext/bufferline.h>
#include <glibext/comparison.h>
#include <glibext/configuration.h>
#include <glibext/linesegment.h>
@@ -159,105 +158,6 @@ int convert_to_portion_access_rights(PyObject *arg, void *dst)
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
-* Description : Définit les constantes relatives aux lignes de tampon. *
-* *
-* Retour : true en cas de succès de l'opération, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool define_buffer_line_constants(PyTypeObject *type)
-{
- bool result; /* Bilan à retourner */
- PyObject *values; /* Groupe de valeurs à établir */
-
- values = PyDict_New();
-
- result = add_const_to_group(values, "NONE", BLF_NONE);
- if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
- if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
- if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
- if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
- if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
- if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
-
- if (!result)
- {
- Py_DECREF(values);
- goto exit;
- }
-
- result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
- "Optional flags linked to a rendering line.");
-
- 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 BufferLineFlags. *
-* *
-* Retour : Bilan de l'opération, voire indications supplémentaires. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-int convert_to_buffer_line_flags(PyObject *arg, void *dst)
-{
- int result; /* Bilan à retourner */
- unsigned long value; /* Valeur transcrite */
-
- 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 BufferLineFlags");
- break;
-
- case 1:
- value = PyLong_AsUnsignedLong(arg);
-
- if ((value & BLF_ALL) != value)
- {
- PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
- result = 0;
- }
-
- else
- *((BufferLineFlags *)dst) = value;
-
- break;
-
- default:
- assert(false);
- break;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : type = type dont le dictionnaire est à compléter. *
-* *
* Description : Définit les constantes relatives aux modes de comparaison. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h
index a950125..c695aa9 100644
--- a/plugins/pychrysalide/glibext/constants.h
+++ b/plugins/pychrysalide/glibext/constants.h
@@ -39,12 +39,6 @@ int convert_to_portion_access_rights(PyObject *, void *);
#if 0
-/* Définit les constantes relatives aux lignes de tampon. */
-bool define_buffer_line_constants(PyTypeObject *);
-
-/* Tente de convertir en constante BufferLineFlags. */
-int convert_to_buffer_line_flags(PyObject *, void *);
-
/* Définit les constantes relatives aux modes de comparaison. */
bool define_comparable_item_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/glibext/linegen.c b/plugins/pychrysalide/glibext/generator.c
index d7e96fd..3a9a8ab 100644
--- a/plugins/pychrysalide/glibext/linegen.c
+++ b/plugins/pychrysalide/glibext/generator.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * linegen.c - équivalent Python du fichier "glibext/linegen.h"
+ * generator.c - équivalent Python du fichier "glibext/generator.h"
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,21 +22,21 @@
*/
-#include "linegen.h"
+#include "generator.h"
#include <pygobject.h>
-#include <glibext/linegen-int.h>
+#include <glibext/generator-int.h>
#include "bufferline.h"
-#include "constants.h"
-#include "linecursor.h"
+#include "constants-ui.h"
+//#include "linecursor.h"
#include "../access.h"
#include "../helpers.h"
-#include "../analysis/content.h"
+//#include "../analysis/content.h"
@@ -44,42 +44,55 @@
/* Procède à l'initialisation de l'interface de génération. */
-static void py_line_generator_interface_init(GLineGeneratorIface *, gpointer *);
+static void py_token_generator_interface_init(GTokenGeneratorInterface *, gpointer *);
/* Indique le nombre de ligne prêtes à être générées. */
-static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *);
+static size_t py_token_generator_count_lines_wrapper(const GTokenGenerator *);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags py_token_generator_get_flags_wrapper(const GTokenGenerator *, size_t, size_t);
+
+/*Description : Etablit dans une ligne de rendu le contenu représenté. */
+static void py_token_generator_populate_line_wrappper(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *);
+
+
+#if 0
+
/* Retrouve l'emplacement correspondant à une position donnée. */
-static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *, gint, size_t, size_t, GLineCursor **);
+static void py_token_generator_compute_cursor_wrapper(const GTokenGenerator *, gint, size_t, size_t, GLineCursor **);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *, size_t, size_t, const GLineCursor *);
+static int py_token_generator_contain_cursor_wrapper(const GTokenGenerator *, size_t, size_t, const GLineCursor *);
+
+
+#endif
-/* Renseigne sur les propriétés liées à un générateur. */
-static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *, size_t, size_t);
-/* Imprime dans une ligne de rendu le contenu représenté. */
-static void py_line_generator_print_wrapper(GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
-/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+/* Renseigne sur les propriétés liées à un générateur. */
+static PyObject *py_token_generator_get_flags(PyObject *, PyObject *);
+
+/* Etablit dans une ligne de rendu le contenu représenté. */
+static PyObject *py_token_generator_populate_line(PyObject *self, PyObject *args);
+
+#if 0
/* Retrouve l'emplacement correspondant à une position donnée. */
-static PyObject *py_line_generator_compute_cursor(PyObject *, PyObject *);
+static PyObject *py_token_generator_compute_cursor(PyObject *, PyObject *);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static PyObject *py_line_generator_contain_cursor(PyObject *, PyObject *);
+static PyObject *py_token_generator_contain_cursor(PyObject *, PyObject *);
-/* Renseigne sur les propriétés liées à un générateur. */
-static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
+#endif
-/* Imprime dans une ligne de rendu le contenu représenté. */
-static PyObject *py_line_generator_print(PyObject *, PyObject *);
/* Indique le nombre de ligne prêtes à être générées. */
-static PyObject *py_line_generator_get_lines_count(PyObject *, void *);
+static PyObject *py_token_generator_get_lines_count(PyObject *, void *);
@@ -101,31 +114,33 @@ static PyObject *py_line_generator_get_lines_count(PyObject *, void *);
* *
******************************************************************************/
-static void py_line_generator_interface_init(GLineGeneratorIface *iface, gpointer *unused)
+static void py_token_generator_interface_init(GTokenGeneratorInterface *iface, gpointer *unused)
{
-#define LINE_GENERATOR_DOC \
- "LineGenerator gives an interface to all objects which aim to produce" \
+#define TOKEN_GENERATOR_DOC \
+ "TokenGenerator gives an interface to all objects which aim to produce" \
" content for rendering lines. Such lines can be exported to graphical" \
" interfaces or text files.\n" \
"\n" \
"A typical class declaration for a new implementation looks like:\n" \
"\n" \
- " class NewImplem(GObject.Object, LineGenerator):\n" \
+ " class NewImplem(GObject.Object, TokenGenerator):\n" \
" ...\n" \
"\n" \
"The following methods have to be defined for new implementations:\n" \
- "* pychrysalide.glibext.LineGenerator._count_lines();\n" \
- "* pychrysalide.glibext.LineGenerator._compute_cursor();\n" \
- "* pychrysalide.glibext.LineGenerator._contain_cursor();\n" \
- "* pychrysalide.glibext.LineGenerator._get_flags();\n" \
- "* pychrysalide.glibext.LineGenerator._print();\n" \
-
- iface->count = py_line_generator_count_lines_wrapper;
- iface->compute = py_line_generator_compute_cursor_wrapper;
- iface->contain = py_line_generator_contain_cursor_wrapper;
- iface->get_flags = py_line_generator_get_flags_wrapper;
- iface->print = py_line_generator_print_wrapper;
+ "* pychrysalide.glibext.TokenGenerator._count_lines();\n" \
+ "* pychrysalide.glibext.TokenGenerator._get_flags();\n" \
+ "* pychrysalide.glibext.TokenGenerator._populate_line();\n" \
+ "* pychrysalide.glibext.TokenGenerator._compute_cursor();\n" \
+ "* pychrysalide.glibext.TokenGenerator._contain_cursor().\n"
+
+ iface->count = py_token_generator_count_lines_wrapper;
+ iface->get_flags = py_token_generator_get_flags_wrapper;
+ iface->populate = py_token_generator_populate_line_wrappper;
+#if 0
+ iface->compute = py_token_generator_compute_cursor_wrapper;
+ iface->contain = py_token_generator_contain_cursor_wrapper;
+#endif
}
@@ -142,7 +157,7 @@ static void py_line_generator_interface_init(GLineGeneratorIface *iface, gpointe
* *
******************************************************************************/
-static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *generator)
+static size_t py_token_generator_count_lines_wrapper(const GTokenGenerator *generator)
{
size_t result; /* Décompte à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
@@ -150,7 +165,7 @@ static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *genera
PyObject *pyret; /* Bilan de consultation */
int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \
( \
_count_lines, "$self, /", \
METH_NOARGS, \
@@ -193,61 +208,61 @@ static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *genera
/******************************************************************************
* *
* Paramètres : generator = générateur à consulter. *
-* x = position géographique sur la ligne concernée. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
* *
-* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* Description : Renseigne sur les propriétés liées à un générateur. *
* *
-* Retour : Emplacement constitué. *
+* Retour : Propriétés particulières associées. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
+static BufferLineFlags py_token_generator_get_flags_wrapper(const GTokenGenerator *generator, size_t index, size_t repeat)
{
+ BufferLineFlags result; /* Fanions à 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 LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _compute_cursor, "$self, x, index, repeat, /", \
+ _get_flags, "$self, index, repeat, /", \
METH_VARARGS, \
- "Abstract method used to create a new cursor for a given" \
- " location inside displayed lines.\n" \
+ "Abstract method used to provide flags for a given rendering" \
+ " line.\n" \
"\n" \
- "The position on the horizontal axis, the line index and the" \
- " number of repetitions (only relevant if the generator" \
- " produces several lines) give indications about the active" \
- " position.\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position.\n" \
"\n" \
- "The result has to be a pychrysalide.glibext.LineCursor" \
- " instance." \
+ "The result has to be a" \
+ " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \
)
+ result = BLF_NONE;
+
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_compute_cursor"))
+ if (has_python_method(pyobj, "_get_flags"))
{
- args = PyTuple_New(3);
- PyTuple_SetItem(args, 0, PyLong_FromSize_t(x));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
- pyret = run_python_method(pyobj, "_compute_cursor", args);
+ pyret = run_python_method(pyobj, "_get_flags", args);
if (pyret != NULL)
{
- ret = convert_to_line_cursor(pyret, cursor);
+ ret = convert_to_buffer_line_flags(pyret, &result);
if (ret != 1)
- *cursor = NULL;
+ result = BLF_NONE;
Py_DECREF(pyret);
@@ -261,75 +276,66 @@ static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *gener
PyGILState_Release(gstate);
+ return result;
+
}
/******************************************************************************
* *
-* Paramètres : generator = générateur à consulter. *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
-* cursor = emplacement à analyser. *
+* line = ligne de rendu à compléter. *
+* data = éventuelle donnée complémentaire fournie. *
* *
-* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
* *
-* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
+static void py_token_generator_populate_line_wrappper(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)
{
- int result; /* Bilan d'analyse à 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 LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_POPULATE_LINE_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _contain_cursor, "$self, index, repeat, cursor, /", \
+ _populate_line, "$self, index, repeat, line, /", \
METH_VARARGS, \
- "Abstract method used to check the position of a cursor in" \
- " relation to rendering lines.\n" \
+ "Abstract method used to generate content into a rendering" \
+ " line.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
+ "This rendering output is pointed by the *line* argument, which"\
+ " is a provided pychrysalide.glibext.BufferLine instance. The" \
+ " line *index* and the number of repetitions (only relevant" \
" if the generator produces several lines) give indications" \
- " about the active position. The cursor is a" \
- " pychrysalide.glibext.LineCursor instance.\n" \
+ " about the current rendering position.\n" \
"\n" \
- "The result has to be an integer less than, equal to, or" \
- " greater than zero if the cursor is, respectively, before," \
- " inside or after the area covered by the generator." \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
)
- result = 0;
-
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_contain_cursor"))
+ if (has_python_method(pyobj, "_populate_line"))
{
args = PyTuple_New(3);
PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
- PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(cursor)));
+ PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(line)));
+ //PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(content)));
- pyret = run_python_method(pyobj, "_contain_cursor", args);
-
- if (pyret != NULL)
- {
- ret = PyLong_Check(pyret);
+ pyret = run_python_method(pyobj, "_populate_line", args);
- if (ret)
- result = PyLong_AsLong(pyret);
-
- Py_DECREF(pyret);
-
- }
+ Py_XDECREF(pyret);
Py_DECREF(args);
@@ -339,69 +345,70 @@ static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *genera
PyGILState_Release(gstate);
- return result;
-
}
+#if 0
+
+
/******************************************************************************
* *
* Paramètres : generator = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
* *
-* Description : Renseigne sur les propriétés liées à un générateur. *
+* Description : Retrouve l'emplacement correspondant à une position donnée. *
* *
-* Retour : Propriétés particulières associées. *
+* Retour : Emplacement constitué. *
* *
* Remarques : - *
* *
******************************************************************************/
-static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *generator, size_t index, size_t repeat)
+static void py_token_generator_compute_cursor_wrapper(const GTokenGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
{
- BufferLineFlags result; /* Fanions à 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 LINE_GENERATOR_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_COMPUTE_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _get_flags, "$self, index, repeat, /", \
+ _compute_cursor, "$self, x, index, repeat, /", \
METH_VARARGS, \
- "Abstract method used to provide flags for a given rendering" \
- " line.\n" \
+ "Abstract method used to create a new cursor for a given" \
+ " location inside displayed lines.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position.\n" \
+ "The position on the horizontal axis, the line index and the" \
+ " number of repetitions (only relevant if the generator" \
+ " produces several lines) give indications about the active" \
+ " position.\n" \
"\n" \
- "The result has to be a" \
- " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \
+ "The result has to be a pychrysalide.glibext.LineCursor" \
+ " instance." \
)
- result = BLF_NONE;
-
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_get_flags"))
+ if (has_python_method(pyobj, "_compute_cursor"))
{
- args = PyTuple_New(2);
- PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(x));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
- pyret = run_python_method(pyobj, "_get_flags", args);
+ pyret = run_python_method(pyobj, "_compute_cursor", args);
if (pyret != NULL)
{
- ret = convert_to_buffer_line_flags(pyret, &result);
+ ret = convert_to_line_cursor(pyret, cursor);
if (ret != 1)
- result = BLF_NONE;
+ *cursor = NULL;
Py_DECREF(pyret);
@@ -415,65 +422,75 @@ static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator
PyGILState_Release(gstate);
- return result;
-
}
/******************************************************************************
* *
-* Paramètres : generator = générateur à utiliser pour l'impression. *
-* line = ligne de rendu à compléter. *
+* Paramètres : generator = générateur à consulter. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
+* cursor = emplacement à analyser. *
* *
-* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
* *
-* Retour : - *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
+static int py_token_generator_contain_cursor_wrapper(const GTokenGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
{
+ int result; /* Bilan d'analyse à 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 LINE_GENERATOR_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _print, "$self, line, index, repeat, content, /", \
+ _contain_cursor, "$self, index, repeat, cursor, /", \
METH_VARARGS, \
- "Abstract method used to generate content into a rendering" \
- " line, which is a provided pychrysalide.glibext.BufferLine" \
- " instance.\n" \
+ "Abstract method used to check the position of a cursor in" \
+ " relation to rendering lines.\n" \
"\n" \
"The line index and the number of repetitions (only relevant" \
" if the generator produces several lines) give indications" \
- " about the current rendering position.\n" \
+ " about the active position. The cursor is a" \
+ " pychrysalide.glibext.LineCursor instance.\n" \
"\n" \
- "If set, the content is a pychrysalide.analysis.BinContent" \
- " instance providing access to the processed binary data." \
+ "The result has to be an integer less than, equal to, or" \
+ " greater than zero if the cursor is, respectively, before," \
+ " inside or after the area covered by the generator." \
)
+ result = 0;
+
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_print"))
+ if (has_python_method(pyobj, "_contain_cursor"))
{
- args = PyTuple_New(4);
- PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(line)));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
- PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(content)));
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
+ PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(cursor)));
- pyret = run_python_method(pyobj, "_print", args);
+ pyret = run_python_method(pyobj, "_contain_cursor", args);
- Py_XDECREF(pyret);
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
Py_DECREF(args);
@@ -483,12 +500,16 @@ static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLi
PyGILState_Release(gstate);
+ return result;
+
}
+#endif
+
/* ---------------------------------------------------------------------------------- */
-/* CONNEXION AVEC L'API DE PYTHON */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
/* ---------------------------------------------------------------------------------- */
@@ -497,57 +518,45 @@ static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLi
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* Description : Renseigne sur les propriétés liées à un générateur. *
* *
-* Retour : Emplacement constitué. *
+* Retour : Propriétés particulières associées. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_get_flags(PyObject *self, PyObject *args)
{
PyObject *result; /* Propriétés à retourner */
- int x; /* Position horizontale */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- GLineCursor *cursor; /* Curseur nouveau obtenu */
+ GTokenGenerator *generator; /* Version native */
+ BufferLineFlags flags; /* Propriétés courantes */
-#define LINE_GENERATOR_COMPUTE_CURSOR_METHOD PYTHON_METHOD_DEF \
-( \
- compute_cursor, "$self, x, index, repeat, /", \
- METH_VARARGS, py_line_generator, \
- "Create a a new cursor for a given location inside displayed" \
- " lines.\n" \
- "\n" \
- "The position on the horizontal axis, the line index and the" \
- " number of repetitions (only relevant if the generator" \
- " produces several lines) give indications about the active" \
- " position.\n" \
- "\n" \
- "The result has to be a pychrysalide.glibext.LineCursor" \
- " instance." \
+#define TOKEN_GENERATOR_GET_FLAGS_METHOD PYTHON_METHOD_DEF \
+( \
+ get_flags, "$self, index, repeat, /", \
+ METH_VARARGS, py_token_generator, \
+ "Get the flags of a given position from the generator.\n" \
+ "\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position.\n" \
+ "\n" \
+ "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \
+ " value." \
)
- ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat);
+ ret = PyArg_ParseTuple(args, "nn", &index, &repeat);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- cursor = g_line_generator_compute_cursor(generator, x, index, repeat);
+ flags = g_token_generator_get_flags(generator, index, repeat);
- if (cursor != NULL)
- {
- result = pygobject_new(G_OBJECT(cursor));
- g_object_unref(G_OBJECT(cursor));
- }
- else
- {
- result = Py_None;
- Py_INCREF(result);
- }
+ result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
return result;
@@ -559,99 +568,108 @@ static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
* *
-* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_contain_cursor(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_populate_line(PyObject *self, PyObject *args)
{
- PyObject *result; /* Propriétés à retourner */
+ GBufferLine *line; /* Ligne de rendu à compléter */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
- GLineCursor *cursor; /* Curseur à venir situer */
+ GTokenGenerator *generator; /* Version native */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- int status; /* Bilan d'une analyse */
-#define LINE_GENERATOR_CONTAIN_CURSOR_METHOD PYTHON_METHOD_DEF \
+#define TOKEN_GENERATOR_POPULATE_LINE_METHOD PYTHON_METHOD_DEF \
( \
- contain_cursor, "$self, index, repeat, cursor, /", \
- METH_VARARGS, py_line_generator, \
- "Check the position of a cursor in relation to rendering" \
- " lines.\n" \
+ populate_line, "$self, index, repeat, line, /", \
+ METH_VARARGS, py_token_generator, \
+ "Produce output into a rendering line with optional content.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position. The cursor is a" \
- " pychrysalide.glibext.LineCursor instance.\n" \
+ "The provided *line* is a pychrysalide.glibext.BufferLine" \
+ " instance. The *index* and the number of repetitions (only" \
+ " relevant if the generator produces several lines) give" \
+ " indications about the current rendering position.\n" \
"\n" \
- "The result has to be an integer less than, equal to, or" \
- " greater than zero if the cursor is, respectively, before," \
- " inside or after the area covered by the generator." \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
)
- ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor);
+ ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_buffer_line, &line);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- status = g_line_generator_contain_cursor(generator, index, repeat, cursor);
+ g_token_generator_populate_line(generator, index, repeat, line, NULL);
- result = PyLong_FromLong(status);
-
- return result;
+ Py_RETURN_NONE;
}
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Renseigne sur les propriétés liées à un générateur. *
+* Description : Retrouve l'emplacement correspondant à une position donnée. *
* *
-* Retour : Propriétés particulières associées. *
+* Retour : Emplacement constitué. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_compute_cursor(PyObject *self, PyObject *args)
{
PyObject *result; /* Propriétés à retourner */
+ int x; /* Position horizontale */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- BufferLineFlags flags; /* Propriétés courantes */
+ GTokenGenerator *generator; /* Version native */
+ GLineCursor *cursor; /* Curseur nouveau obtenu */
-#define LINE_GENERATOR_GET_FLAGS_METHOD PYTHON_METHOD_DEF \
-( \
- get_flags, "$self, index, repeat, /", \
- METH_VARARGS, py_line_generator, \
- "Get the flags of a given position from the generator.\n" \
- "\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position.\n" \
- "\n" \
- "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \
- " value." \
+#define TOKEN_GENERATOR_COMPUTE_CURSOR_METHOD PYTHON_METHOD_DEF \
+( \
+ compute_cursor, "$self, x, index, repeat, /", \
+ METH_VARARGS, py_token_generator, \
+ "Create a a new cursor for a given location inside displayed" \
+ " lines.\n" \
+ "\n" \
+ "The position on the horizontal axis, the line index and the" \
+ " number of repetitions (only relevant if the generator" \
+ " produces several lines) give indications about the active" \
+ " position.\n" \
+ "\n" \
+ "The result has to be a pychrysalide.glibext.LineCursor" \
+ " instance." \
)
- ret = PyArg_ParseTuple(args, "nn", &index, &repeat);
+ ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- flags = g_line_generator_get_flags(generator, index, repeat);
+ cursor = g_token_generator_compute_cursor(generator, x, index, repeat);
- result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
+ if (cursor != NULL)
+ {
+ result = pygobject_new(G_OBJECT(cursor));
+ g_object_unref(G_OBJECT(cursor));
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -663,50 +681,56 @@ static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
* *
-* Retour : - *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_contain_cursor(PyObject *self, PyObject *args)
{
- GBufferLine *line; /* Ligne de rendu à compléter */
+ PyObject *result; /* Propriétés à retourner */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
- GBinContent *content; /* Contenu binaire associé */
- GLineGenerator *generator; /* Version native */
+ GLineCursor *cursor; /* Curseur à venir situer */
int ret; /* Bilan de lecture des args. */
+ GTokenGenerator *generator; /* Version native */
+ int status; /* Bilan d'une analyse */
-#define LINE_GENERATOR_PRINT_METHOD PYTHON_METHOD_DEF \
+#define TOKEN_GENERATOR_CONTAIN_CURSOR_METHOD PYTHON_METHOD_DEF \
( \
- print, "$self, line, index, repeat, content, /", \
- METH_VARARGS, py_line_generator, \
- "Produce output into a rendering line with optional content.\n" \
+ contain_cursor, "$self, index, repeat, cursor, /", \
+ METH_VARARGS, py_token_generator, \
+ "Check the position of a cursor in relation to rendering" \
+ " lines.\n" \
"\n" \
- "The provided line is a pychrysalide.glibext.BufferLine" \
- " instance. The index and the number of repetitions (only" \
- " relevant if the generator produces several lines) give" \
- " indications about the current rendering position.\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position. The cursor is a" \
+ " pychrysalide.glibext.LineCursor instance.\n" \
"\n" \
- "If set, the content is a pychrysalide.analysis.BinContent" \
- " instance providing access to the processed binary data." \
+ "The result has to be an integer less than, equal to, or" \
+ " greater than zero if the cursor is, respectively, before," \
+ " inside or after the area covered by the generator." \
)
- ret = PyArg_ParseTuple(args, "O&nnO&", convert_to_buffer_line, &line, &index,
- &repeat, convert_to_binary_content, &content);
+ ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- g_line_generator_print(generator, line, index, repeat, content);
+ status = g_token_generator_contain_cursor(generator, index, repeat, cursor);
- Py_RETURN_NONE;
+ result = PyLong_FromLong(status);
+
+ return result;
}
+#endif
+
/******************************************************************************
* *
@@ -721,24 +745,24 @@ static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
* *
******************************************************************************/
-static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure)
+static PyObject *py_token_generator_get_lines_count(PyObject *self, void *closure)
{
PyObject *result; /* Décompte à retourner */
- GLineGenerator *generator; /* Version native */
+ GTokenGenerator *generator; /* Version native */
size_t count; /* Nombre de lignes présentes */
-#define LINE_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \
+#define TOKEN_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \
( \
- lines_count, py_line_generator, \
+ lines_count, py_token_generator, \
"Quantity of lines produced by the generator.\n" \
"\n" \
"This number may vary between calls, if a width has changed" \
" for instance." \
)
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- count = g_line_generator_count_lines(generator);
+ count = g_token_generator_count_lines(generator);
result = PyLong_FromSize_t(count);
@@ -759,43 +783,47 @@ static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure
* *
******************************************************************************/
-PyTypeObject *get_python_line_generator_type(void)
+PyTypeObject *get_python_token_generator_type(void)
{
- static PyMethodDef py_line_generator_methods[] = {
- LINE_GENERATOR_COUNT_LINES_WRAPPER,
- LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER,
- LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER,
- LINE_GENERATOR_GET_FLAGS_WRAPPER,
- LINE_GENERATOR_PRINT_WRAPPER,
- LINE_GENERATOR_COMPUTE_CURSOR_METHOD,
- LINE_GENERATOR_CONTAIN_CURSOR_METHOD,
- LINE_GENERATOR_GET_FLAGS_METHOD,
- LINE_GENERATOR_PRINT_METHOD,
+ static PyMethodDef py_token_generator_methods[] = {
+ TOKEN_GENERATOR_COUNT_LINES_WRAPPER,
+ TOKEN_GENERATOR_GET_FLAGS_WRAPPER,
+ TOKEN_GENERATOR_POPULATE_LINE_WRAPPER,
+ /*
+ TOKEN_GENERATOR_COMPUTE_CURSOR_WRAPPER,
+ TOKEN_GENERATOR_CONTAIN_CURSOR_WRAPPER,
+ */
+ TOKEN_GENERATOR_GET_FLAGS_METHOD,
+ TOKEN_GENERATOR_POPULATE_LINE_METHOD,
+ /*
+ TOKEN_GENERATOR_COMPUTE_CURSOR_METHOD,
+ TOKEN_GENERATOR_CONTAIN_CURSOR_METHOD,
+ */
{ NULL }
};
- static PyGetSetDef py_line_generator_getseters[] = {
- LINE_GENERATOR_LINES_COUNT_ATTRIB,
+ static PyGetSetDef py_token_generator_getseters[] = {
+ TOKEN_GENERATOR_LINES_COUNT_ATTRIB,
{ NULL }
};
- static PyTypeObject py_line_generator_type = {
+ static PyTypeObject py_token_generator_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.glibext.LineGenerator",
+ .tp_name = "pychrysalide.glibext.TokenGenerator",
.tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = LINE_GENERATOR_DOC,
+ .tp_doc = TOKEN_GENERATOR_DOC,
- .tp_methods = py_line_generator_methods,
- .tp_getset = py_line_generator_getseters,
+ .tp_methods = py_token_generator_methods,
+ .tp_getset = py_token_generator_getseters,
};
- return &py_line_generator_type;
+ return &py_token_generator_type;
}
@@ -804,7 +832,7 @@ PyTypeObject *get_python_line_generator_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'.*
+* Description : Prend en charge l'objet 'pychrysalide.....TokenGenerator'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -812,21 +840,21 @@ PyTypeObject *get_python_line_generator_type(void)
* *
******************************************************************************/
-bool ensure_python_line_generator_is_registered(void)
+bool ensure_python_token_generator_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'LineGenerator' */
+ PyTypeObject *type; /* Type Python 'TokenGenerator'*/
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
static GInterfaceInfo info = { /* Paramètres d'inscription */
- .interface_init = (GInterfaceInitFunc)py_line_generator_interface_init,
+ .interface_init = (GInterfaceInitFunc)py_token_generator_interface_init,
.interface_finalize = NULL,
.interface_data = NULL,
};
- type = get_python_line_generator_type();
+ type = get_python_token_generator_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -834,7 +862,7 @@ bool ensure_python_line_generator_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_LINE_GENERATOR, type, &info))
+ if (!register_interface_for_pygobject(dict, G_TYPE_TOKEN_GENERATOR, type, &info))
return false;
}
@@ -857,11 +885,11 @@ bool ensure_python_line_generator_is_registered(void)
* *
******************************************************************************/
-int convert_to_line_generator(PyObject *arg, void *dst)
+int convert_to_token_generator(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_line_generator_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_token_generator_type());
switch (result)
{
@@ -871,11 +899,11 @@ int convert_to_line_generator(PyObject *arg, void *dst)
break;
case 0:
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to line generator");
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to token generator");
break;
case 1:
- *((GLineGenerator **)dst) = G_LINE_GENERATOR(pygobject_get(arg));
+ *((GTokenGenerator **)dst) = G_TOKEN_GENERATOR(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/glibext/linegen.h b/plugins/pychrysalide/glibext/generator.h
index bfad885..b2672a8 100644
--- a/plugins/pychrysalide/glibext/linegen.h
+++ b/plugins/pychrysalide/glibext/generator.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * linegen.h - prototypes pour l'équivalent Python du fichier "glibext/linegen.h"
+ * generator.h - prototypes pour l'équivalent Python du fichier "glibext/generator.h"
*
- * Copyright (C) 2018 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H
-#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H
#include <Python.h>
@@ -32,14 +32,14 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_line_generator_type(void);
+PyTypeObject *get_python_token_generator_type(void);
-/* Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'. */
-bool ensure_python_line_generator_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.glibext.TokenGenerator'. */
+bool ensure_python_token_generator_is_registered(void);
/* Tente de convertir en générateur de lignes. */
-int convert_to_line_generator(PyObject *, void *);
+int convert_to_token_generator(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H */
diff --git a/plugins/pychrysalide/glibext/module-ui.c b/plugins/pychrysalide/glibext/module-ui.c
new file mode 100644
index 0000000..8fa6d0e
--- /dev/null
+++ b/plugins/pychrysalide/glibext/module-ui.c
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire glibext (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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 "module-ui.h"
+
+
+#include <assert.h>
+
+
+#include "bufferline.h"
+#include "generator.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les objets du module 'glibext' (mode UI). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_glibext_module_ui(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_token_generator_is_registered();
+
+ if (result) result = ensure_python_buffer_line_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/module-ui.h b/plugins/pychrysalide/glibext/module-ui.h
new file mode 100644
index 0000000..d91a2fa
--- /dev/null
+++ b/plugins/pychrysalide/glibext/module-ui.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire glibext (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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_MODULE_UI_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Intègre les objets du module 'glibext' (mode UI). */
+bool populate_glibext_module_ui(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_UI_H */
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index 6ce0709..bbe357d 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -44,7 +44,9 @@
#include "objhole.h"
#include "portion.h"
#include "secstorage.h"
+#include "serialize.h"
#include "singleton.h"
+#include "storage.h"
#include "strbuilder.h"
#include "work.h"
#include "workqueue.h"
@@ -116,12 +118,14 @@ bool populate_glibext_module(void)
if (result) result = ensure_python_comparable_object_is_registered();
if (result) result = ensure_python_hashable_object_is_registered();
+ if (result) result = ensure_python_serializable_object_is_registered();
if (result) result = ensure_python_singleton_candidate_is_registered();
if (result) result = ensure_python_string_builder_is_registered();
if (result) result = ensure_python_thick_object_is_registered();
if (result) result = ensure_python_binary_portion_is_registered();
if (result) result = ensure_python_generic_work_is_registered();
+ if (result) result = ensure_python_object_storage_is_registered();
if (result) result = ensure_python_secret_storage_is_registered();
if (result) result = ensure_python_singleton_factory_is_registered();
if (result) result = ensure_python_work_queue_is_registered();
diff --git a/plugins/pychrysalide/glibext/objhole.c b/plugins/pychrysalide/glibext/objhole.c
index 2a3ad6f..6bea5d1 100644
--- a/plugins/pychrysalide/glibext/objhole.c
+++ b/plugins/pychrysalide/glibext/objhole.c
@@ -37,12 +37,25 @@
-CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_thick_object_init(PyObject *, PyObject *, PyObject *);
+
+
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
+
+
+/* Pose un verrou à l'aide du bit dédié de GObject. */
+static PyObject *py_thick_object_lock(PyObject *, PyObject *);
+
+/* Retire un verrou via le bit dédié de GObject. */
+static PyObject *py_thick_object_unlock(PyObject *, PyObject *);
+
/* Indique le nombre de bits accaparés par la GLib. */
static PyObject *py_thick_object_get__GOBJECT_RESERVED_EXTRA_BITS(PyObject *, void *);
@@ -54,6 +67,11 @@ static int py_thick_object_set_extra(PyObject *, PyObject *, void *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = objet à initialiser (théoriquement). *
@@ -92,6 +110,86 @@ static int py_thick_object_init(PyObject *self, PyObject *args, PyObject *kwds)
}
+
+/* ---------------------------------------------------------------------------------- */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance représentant une extension d'objet. *
+* args = arguments fournis à l'appel, non utilisé ici. *
+* *
+* Description : Pose un verrou à l'aide du bit dédié de GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_thick_object_lock(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Résultat à retourner */
+ GThickObject *obj; /* Version GLib de l'instance */
+
+#define THICK_OBJECT_LOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ lock, "$self", \
+ METH_NOARGS, py_thick_object, \
+ "Lock the object using the internal GLib bit.\n" \
+)
+
+ obj = G_THICK_OBJECT(pygobject_get(self));
+
+ g_thick_object_lock(obj);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance représentant une extension d'objet. *
+* args = arguments fournis à l'appel, non utilisé ici. *
+* *
+* Description : Retire un verrou via le bit dédié de GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_thick_object_unlock(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Résultat à retourner */
+ GThickObject *obj; /* Version GLib de l'instance */
+
+#define THICK_OBJECT_UNLOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ unlock, "$self", \
+ METH_NOARGS, py_thick_object, \
+ "Unlock the object using the internal GLib bit.\n" \
+)
+
+ obj = G_THICK_OBJECT(pygobject_get(self));
+
+ g_thick_object_unlock(obj);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : self = objet Python concerné par l'appel. *
@@ -215,6 +313,8 @@ static int py_thick_object_set_extra(PyObject *self, PyObject *value, void *clos
PyTypeObject *get_python_thick_object_type(void)
{
static PyMethodDef py_thick_object_methods[] = {
+ THICK_OBJECT_LOCK_METHOD,
+ THICK_OBJECT_UNLOCK_METHOD,
{ NULL }
};
diff --git a/plugins/pychrysalide/glibext/secstorage.c b/plugins/pychrysalide/glibext/secstorage.c
index b5adb7c..5935d29 100644
--- a/plugins/pychrysalide/glibext/secstorage.c
+++ b/plugins/pychrysalide/glibext/secstorage.c
@@ -106,14 +106,15 @@ static int py_secret_storage_init(PyObject *self, PyObject *args, PyObject *kwds
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " SecretStorage(settings)" \
+ " SecretStorage(settings=None)" \
"\n" \
- "The *settings* arguement must point to a GSettings intance;" \
- " the main configuration settings are used by default." \
+ "The *settings* arguement may point to a GSettings instance." \
+ " This optional argument is mainly used for testing purpose;" \
+ " the main configuration settings are used by default."
settings = NULL;
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings_or_none, &settings);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
diff --git a/plugins/pychrysalide/analysis/storage/serialize.c b/plugins/pychrysalide/glibext/serialize.c
index 40fcef7..61f359f 100644
--- a/plugins/pychrysalide/analysis/storage/serialize.c
+++ b/plugins/pychrysalide/glibext/serialize.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.c - équivalent Python du fichier "analysis/storage/serialize.h"
+ * serialize.c - équivalent Python du fichier "glibext/serialize.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,13 +28,12 @@
#include <pygobject.h>
-#include <analysis/storage/serialize-int.h>
+#include <glibext/serialize-int.h>
#include "storage.h"
-#include "../../access.h"
-#include "../../helpers.h"
-#include "../../common/packed.h"
+#include "../access.h"
+#include "../helpers.h"
@@ -42,23 +41,23 @@
/* Procède à l'initialisation de l'interface de génération. */
-static void py_serializable_object_interface_init(GSerializableObjectIface *, gpointer *);
+static void py_serializable_object_interface_init(GSerializableObjectInterface *, gpointer *);
-/* Charge un objet depuis une mémoire tampon. */
-static bool py_serializable_object_load_wrapper(GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+/* Charge un objet depuis un flux de données. */
+static bool py_serializable_object_load_wrapper(GSerializableObject *, GObjectStorage *, int);
-/* Sauvegarde un objet dans une mémoire tampon. */
-static bool py_serializable_object_store_wrapper(const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+/* Sauvegarde un objet dans un flux de données. */
+static bool py_serializable_object_store_wrapper(const GSerializableObject *, GObjectStorage *, int);
/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
-/* Charge un objet depuis une mémoire tampon. */
+/* Charge un objet depuis un flux de données. */
static bool py_serializable_object_load(PyObject *, PyObject *);
-/* Sauvegarde un objet dans une mémoire tampon. */
+/* Sauvegarde un objet dans un flux de données. */
static bool py_serializable_object_store(PyObject *, PyObject *);
@@ -81,7 +80,7 @@ static bool py_serializable_object_store(PyObject *, PyObject *);
* *
******************************************************************************/
-static void py_serializable_object_interface_init(GSerializableObjectIface *iface, gpointer *unused)
+static void py_serializable_object_interface_init(GSerializableObjectInterface *iface, gpointer *unused)
{
#define SERIALIZABLE_OBJECT_DOC \
@@ -94,8 +93,8 @@ static void py_serializable_object_interface_init(GSerializableObjectIface *ifac
" ...\n" \
"\n" \
"The following methods have to be defined for new implementations:\n" \
- "* pychrysalide.analysis.storage.SerializableObject._load();\n" \
- "* pychrysalide.analysis.storage.SerializableObject._store();\n"
+ "* pychrysalide.glibext.SerializableObject._load();\n" \
+ "* pychrysalide.glibext.SerializableObject._store();\n"
iface->load = py_serializable_object_load_wrapper;
iface->store = py_serializable_object_store_wrapper;
@@ -106,10 +105,10 @@ static void py_serializable_object_interface_init(GSerializableObjectIface *ifac
/******************************************************************************
* *
* Paramètres : object = instruction d'assemblage à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en lecture. *
* *
-* Description : Charge un objet depuis une mémoire tampon. *
+* Description : Charge un objet depuis un flux de données. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -117,25 +116,24 @@ static void py_serializable_object_interface_init(GSerializableObjectIface *ifac
* *
******************************************************************************/
-static bool py_serializable_object_load_wrapper(GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+static bool py_serializable_object_load_wrapper(GSerializableObject *object, GObjectStorage *storage, int fd)
{
bool result; /* Bilan à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
- PyObject *storage_obj; /* Objet Python à emmployer */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
#define SERIALIZABLE_OBJECT_LOAD_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _load, "$self, storage, pbuf, /", \
+ _load, "$self, storage, fd, /", \
METH_VARARGS, \
- "Abstract method used to load an object definition from buffered data.\n" \
+ "Abstract method used to load an object definition from a data stream.\n" \
"\n" \
- "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance" \
- " provided to store inner objects, if relevant, or None. The *pbuf*" \
- " argument points to a pychrysalide.common.PackedBuffer object containing" \
- " the data to process.\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " provided as a file descriptor which as to be kept open after" \
+ " processing.\n" \
"\n" \
"The result is a boolean indicating the status of the operation." \
)
@@ -148,17 +146,9 @@ static bool py_serializable_object_load_wrapper(GSerializableObject *object, GOb
if (has_python_method(pyobj, "_load"))
{
- if (storage == NULL)
- {
- storage_obj = Py_None;
- Py_INCREF(storage_obj);
- }
- else
- storage_obj = pygobject_new(G_OBJECT(storage));
-
args = PyTuple_New(2);
- PyTuple_SetItem(args, 0, storage_obj);
- PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(storage)));
+ PyTuple_SetItem(args, 1, PyLong_FromLong(fd));
pyret = run_python_method(pyobj, "_load", args);
@@ -182,10 +172,10 @@ static bool py_serializable_object_load_wrapper(GSerializableObject *object, GOb
/******************************************************************************
* *
* Paramètres : object = instruction d'assemblage à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en écriture. *
* *
-* Description : Sauvegarde un objet dans une mémoire tampon. *
+* Description : Sauvegarde un objet dans un flux de données. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -193,25 +183,24 @@ static bool py_serializable_object_load_wrapper(GSerializableObject *object, GOb
* *
******************************************************************************/
-static bool py_serializable_object_store_wrapper(const GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+static bool py_serializable_object_store_wrapper(const GSerializableObject *object, GObjectStorage *storage, int fd)
{
bool result; /* Bilan à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
- PyObject *storage_obj; /* Objet Python à emmployer */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
#define SERIALIZABLE_OBJECT_STORE_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _store, "$self, storage, pbuf, /", \
+ _store, "$self, storage, fd, /", \
METH_VARARGS, \
- "Abstract method used to store an object definition into buffered data.\n" \
+ "Abstract method used to store an object definition into a data stream.\n" \
"\n" \
- "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance" \
- " provided to store inner objects, if relevant, or None. The *pbuf*" \
- " argument points to a pychrysalide.common.PackedBuffer object containing" \
- " the data to process.\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " provided as a file descriptor which as to be kept open after" \
+ " processing.\n" \
"\n" \
"The result is a boolean indicating the status of the operation." \
)
@@ -224,17 +213,9 @@ static bool py_serializable_object_store_wrapper(const GSerializableObject *obje
if (has_python_method(pyobj, "_store"))
{
- if (storage == NULL)
- {
- storage_obj = Py_None;
- Py_INCREF(storage_obj);
- }
- else
- storage_obj = pygobject_new(G_OBJECT(storage));
-
args = PyTuple_New(2);
- PyTuple_SetItem(args, 0, storage_obj);
- PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(storage)));
+ PyTuple_SetItem(args, 1, PyLong_FromLong(fd));
pyret = run_python_method(pyobj, "_store", args);
@@ -266,7 +247,7 @@ static bool py_serializable_object_store_wrapper(const GSerializableObject *obje
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Charge un objet depuis une mémoire tampon. *
+* Description : Charge un objet depuis un flux de données. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -278,32 +259,30 @@ static bool py_serializable_object_load(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
GObjectStorage *storage; /* Conservateur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ int fd; /* Flux ouvert (en lecture) */
int ret; /* Bilan de lecture des args. */
GSerializableObject *object; /* Version native */
bool status; /* Bilan de l'opération */
#define SERIALIZABLE_OBJECT_LOAD_METHOD PYTHON_METHOD_DEF \
( \
- load, "$self, storage, pbuf, /", \
+ load, "$self, storage, fd, /", \
METH_VARARGS, py_serializable_object, \
- "Load an object definition from buffered data.\n" \
+ "Load an object definition from a data stream.\n" \
"\n" \
- "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance" \
- " provided to store inner objects, if relevant, or None. The *pbuf*" \
- " argument points to a pychrysalide.common.PackedBuffer object containing" \
- " the data to process.\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " used as a file descriptor for writing data\n" \
"\n" \
"The result is a boolean indicating the status of the operation." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
- convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&i", convert_to_object_storage, &storage, &fd);
if (!ret) return NULL;
object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
- status = g_serializable_object_load(object, storage, pbuf);
+ status = g_serializable_object_load(object, storage, fd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -318,7 +297,7 @@ static bool py_serializable_object_load(PyObject *self, PyObject *args)
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Sauvegarde un objet dans une mémoire tampon. *
+* Description : Sauvegarde un objet dans un flux de données. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -330,32 +309,30 @@ static bool py_serializable_object_store(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
GObjectStorage *storage; /* Conservateur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ int fd; /* Flux ouvert (en lecture) */
int ret; /* Bilan de lecture des args. */
GSerializableObject *object; /* Version native */
bool status; /* Bilan de l'opération */
#define SERIALIZABLE_OBJECT_STORE_METHOD PYTHON_METHOD_DEF \
( \
- store, "$self, storage, pbuf, /", \
+ store, "$self, storage, fd, /", \
METH_VARARGS, py_serializable_object, \
- "Store an object definition into buffered data.\n" \
+ "Store an object definition into a data stream.\n" \
"\n" \
- "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance" \
- " provided to store inner objects, if relevant, or None. The *pbuf*" \
- " argument points to a pychrysalide.common.PackedBuffer object containing" \
- " the data to process.\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " used as a file descriptor for writing data\n" \
"\n" \
"The result is a boolean indicating the status of the operation." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
- convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&i", convert_to_object_storage, &storage, &fd);
if (!ret) return NULL;
object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
- status = g_serializable_object_store(object, storage, pbuf);
+ status = g_serializable_object_store(object, storage, fd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -395,7 +372,7 @@ PyTypeObject *get_python_serializable_object_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.analysis.storage.SerializableObject",
+ .tp_name = "pychrysalide.glibext.SerializableObject",
.tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
@@ -442,7 +419,7 @@ bool ensure_python_serializable_object_is_registered(void)
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
- module = get_access_to_python_module("pychrysalide.analysis.storage");
+ module = get_access_to_python_module("pychrysalide.glibext");
dict = PyModule_GetDict(module);
diff --git a/plugins/pychrysalide/analysis/storage/serialize.h b/plugins/pychrysalide/glibext/serialize.h
index 7e831e5..90688ba 100644
--- a/plugins/pychrysalide/analysis/storage/serialize.h
+++ b/plugins/pychrysalide/glibext/serialize.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.h - prototypes pour l'équivalent Python du fichier "analysis/storage/serialize.h"
+ * serialize.h - prototypes pour l'équivalent Python du fichier "glibext/serialize.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
-#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_SERIALIZE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_SERIALIZE_H
#include <Python.h>
@@ -34,7 +34,7 @@
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_serializable_object_type(void);
-/* Prend en charge l'objet 'pychrysalide.analysis.storage.SerializableObject'. */
+/* Prend en charge l'objet 'pychrysalide.glibext.SerializableObject'. */
bool ensure_python_serializable_object_is_registered(void);
/* Tente de convertir en objet adapté à une mise en cache. */
@@ -42,4 +42,4 @@ int convert_to_serializable_object(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_SERIALIZE_H */
diff --git a/plugins/pychrysalide/analysis/storage/storage.c b/plugins/pychrysalide/glibext/storage.c
index c54fe0f..f2962bf 100644
--- a/plugins/pychrysalide/analysis/storage/storage.c
+++ b/plugins/pychrysalide/glibext/storage.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.c - équivalent Python du fichier "analysis/storage/storage.c"
+ * storage.c - équivalent Python du fichier "glibext/storage.c"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,25 +25,23 @@
#include "storage.h"
+#include <assert.h>
#include <pygobject.h>
-#include <analysis/storage/storage-int.h>
-#include <plugins/dt.h>
+#include <glibext/storage-int.h>
#include "serialize.h"
-#include "../../access.h"
-#include "../../helpers.h"
-#include "../../common/packed.h"
+#include "../access.h"
+#include "../helpers.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_object_storage_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(object_storage, G_TYPE_OBJECT_STORAGE);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_object_storage_init(PyObject *, PyObject *, PyObject *);
@@ -68,9 +66,6 @@ static PyObject *py_object_storage_unpack_object(PyObject *, PyObject *);
/* Sauvegarde un object sous forme de données rassemblées. */
static PyObject *py_object_storage_store_object(PyObject *, PyObject *);
-/* Sauvegarde un object interne sous forme de données. */
-static PyObject *py_object_storage_pack_object(PyObject *, PyObject *);
-
/* ---------------------------------------------------------------------------------- */
@@ -80,66 +75,6 @@ static PyObject *py_object_storage_pack_object(PyObject *, PyObject *);
/******************************************************************************
* *
-* 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_object_storage_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 */
-
- /* Validations diverses */
-
- base = get_python_object_storage_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_OBJECT_STORAGE, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
-
- 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 = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
@@ -154,7 +89,9 @@ static PyObject *py_object_storage_new(PyTypeObject *type, PyObject *args, PyObj
static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- const char *hash; /* Empreinte de contenu */
+ const char *type; /* Type global de conservation */
+ unsigned char version; /* Version de ce type */
+ const char *uid; /* Identifiant de distinction */
int ret; /* Bilan de lecture des args. */
GObjectStorage *storage; /* Mécanismes natifs */
@@ -164,14 +101,15 @@ static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " ObjectStorage(hash)" \
+ " ObjectStorage(type, version uid)" \
"\n" \
- "Where *hash* should a string built from the checksum of the" \
- " relative binary content linked to the storage.pychrysalide."
+ "Where *type* is a short string describing the storage kind," \
+ " *version* provides a version control for this type and *uid* is" \
+ " an arbitrary unique identifier used for creating temporary files."
/* Récupération des paramètres */
- ret = PyArg_ParseTuple(args, "s", &hash);
+ ret = PyArg_ParseTuple(args, "sbs", &type, &version, &uid);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -183,7 +121,8 @@ static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds
storage = G_OBJECT_STORAGE(pygobject_get(self));
- storage->hash = strdup(hash);
+ if (!g_object_storage_create(storage, type, version, uid))
+ return -1;
return 0;
@@ -212,27 +151,27 @@ static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds
static PyObject *py_object_storage_load(PyObject *self, PyObject *args)
{
PyObject *result; /* Emplacement à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *filename; /* Fichier de source à traiter */
int ret; /* Bilan de lecture des args. */
GObjectStorage *storage; /* Mécanismes natifs */
-#define OBJECT_STORAGE_LOAD_METHOD PYTHON_METHOD_DEF \
-( \
- load, "pbuf, /", \
- METH_STATIC | METH_VARARGS, py_object_storage, \
- "Construct a new storage from a buffer.\n" \
- "\n" \
- "The *pbuf* has to be an instance of type" \
- " pychrysalide.common.PackedBuffer.\n" \
- "\n" \
- "The result is a new pychrysalide.analysis.storage.ObjectStorage" \
- " object on success, *None* otherwise." \
+#define OBJECT_STORAGE_LOAD_METHOD PYTHON_METHOD_DEF \
+( \
+ load, "filename, /", \
+ METH_STATIC | METH_VARARGS, py_object_storage, \
+ "Construct a new storage from a filename.\n" \
+ "\n" \
+ "The *filename* argument points to the source file to" \
+ " read.\n" \
+ "\n" \
+ "The result is a new pychrysalide.glibext.ObjectStorage" \
+ " object on success, *None* otherwise." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "s", &filename);
if (!ret) return NULL;
- storage = g_object_storage_load(pbuf);
+ storage = g_object_storage_load(filename);
if (storage == NULL)
{
@@ -242,7 +181,7 @@ static PyObject *py_object_storage_load(PyObject *self, PyObject *args)
else
{
result = pygobject_new(G_OBJECT(storage));
- g_object_unref(G_OBJECT(storage));
+ unref_object(storage);
}
return result;
@@ -266,29 +205,29 @@ static PyObject *py_object_storage_load(PyObject *self, PyObject *args)
static PyObject *py_object_storage_store(PyObject *self, PyObject *args)
{
PyObject *result; /* Emplacement à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *filename; /* Fichier de destination */
int ret; /* Bilan de lecture des args. */
GObjectStorage *storage; /* Mécanismes natifs */
bool status; /* Bilan de l'opération */
#define OBJECT_STORAGE_STORE_METHOD PYTHON_METHOD_DEF \
( \
- store, "$self, pbuf, /", \
+ store, "$self, filename, /", \
METH_VARARGS, py_object_storage, \
- "Save a storage into a buffer.\n" \
+ "Save a storage into a file.\n" \
"\n" \
- "The *pbuf* has to be an instance of type" \
- " pychrysalide.common.PackedBuffer.\n" \
+ "The *filename* argument points to the destination" \
+ " file to write.\n" \
"\n" \
"The result is *True* on success, *False* otherwise." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "s", &filename);
if (!ret) return NULL;
storage = G_OBJECT_STORAGE(pygobject_get(self));
- status = g_object_storage_store(storage, pbuf);
+ status = g_object_storage_store(storage, filename);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -331,7 +270,7 @@ static PyObject *py_object_storage_load_object(PyObject *self, PyObject *args)
" the data to unserialize.\n" \
"\n" \
"The result is a pychrysalide.analysis.storage.SerializableObject" \
- " instancet in case of success, or None in case of failure." \
+ " instancet in case of success, or *None* in case of failure." \
)
ret = PyArg_ParseTuple(args, "sK", &name, &pos);
@@ -370,31 +309,34 @@ static PyObject *py_object_storage_load_object(PyObject *self, PyObject *args)
static PyObject *py_object_storage_unpack_object(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
+ int fd; /* Flux de fonnées courant */
const char *name; /* Désignation de groupe */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
int ret; /* Bilan de lecture des args. */
GObjectStorage *storage; /* Mécanismes natifs */
GSerializableObject *object; /* Objet reconstruit ou NULL */
#define OBJECT_STORAGE_UNPACK_OBJECT_METHOD PYTHON_METHOD_DEF \
( \
- unpack_object, "$self, name, pbuf, /", \
+ unpack_object, "$self, fd, name, /", \
METH_VARARGS, py_object_storage, \
- "Load an object from a buffer with a location pointing to data.\n" \
+ "Load an object from a reference to serialized data.\n" \
"\n" \
- "The *name* is a string label for the group of target objects and" \
- " *pbuf* has to be a pychrysalide.common.PackedBuffer instance.\n" \
+ "The *fd* argument is a file descriptor pointing to the data" \
+ " stream for a current object being restored. A reference to" \
+ " another object belonging to a group pointed by the string *name*" \
+ " should be available at the current read position for this data" \
+ " stream.\n" \
"\n" \
"The result is a pychrysalide.analysis.storage.SerializableObject" \
- " instancet in case of success, or None in case of failure." \
+ " instancet in case of success, or *None* in case of failure." \
)
- ret = PyArg_ParseTuple(args, "sO&", &name, convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "is", &fd, &name);
if (!ret) return NULL;
storage = G_OBJECT_STORAGE(pygobject_get(self));
- object = g_object_storage_unpack_object(storage, name, pbuf);
+ object = g_object_storage_unpack_object(storage, fd, name);
if (object != NULL)
result = pygobject_new(G_OBJECT(object));
@@ -443,7 +385,7 @@ static PyObject *py_object_storage_store_object(PyObject *self, PyObject *args)
" pychrysalide.analysis.storage.SerializableObject instance.\n" \
"\n" \
"The result is the position of the data for stored object," \
- " provided as an integer offset, in case of success or None" \
+ " provided as an integer offset, in case of success or *None*" \
" in case of failure." \
)
@@ -469,62 +411,6 @@ static PyObject *py_object_storage_store_object(PyObject *self, PyObject *args)
/******************************************************************************
* *
-* Paramètres : self = classe représentant une mémorisation de types. *
-* args = arguments fournis à l'appel. *
-* *
-* Description : Sauvegarde un object interne sous forme de données. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_object_storage_pack_object(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Emplacement à retourner */
- const char *name; /* Désignation de groupe */
- GSerializableObject *object; /* Objet à traiter */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
- int ret; /* Bilan de lecture des args. */
- GObjectStorage *storage; /* Mécanismes natifs */
- bool status; /* Bilan de l'opération */
-
-#define OBJECT_STORAGE_PACK_OBJECT_METHOD PYTHON_METHOD_DEF \
-( \
- pack_object, "$self, name, object, pbuf/", \
- METH_VARARGS, py_object_storage, \
- "Save an object as serialized data and store the location of" \
- " the data intro a buffer.\n" \
- "\n" \
- "The *name* is a string label for the group of target objects," \
- " the processed *object* has to be a" \
- " pychrysalide.analysis.storage.SerializableObject instance" \
- " and *pbuf* is expected to be a" \
- " pychrysalide.common.PackedBuffer instance.\n" \
- "\n" \
- "The status of the operation is returned as a boolean value:" \
- " *True* for success, *False* for failure." \
-)
-
- ret = PyArg_ParseTuple(args, "sO&O&", &name, convert_to_serializable_object, &object,
- convert_to_packed_buffer, &pbuf);
- if (!ret) return NULL;
-
- storage = G_OBJECT_STORAGE(pygobject_get(self));
-
- status = g_object_storage_pack_object(storage, name, object, pbuf);
-
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -543,7 +429,6 @@ PyTypeObject *get_python_object_storage_type(void)
OBJECT_STORAGE_LOAD_OBJECT_METHOD,
OBJECT_STORAGE_UNPACK_OBJECT_METHOD,
OBJECT_STORAGE_STORE_OBJECT_METHOD,
- OBJECT_STORAGE_PACK_OBJECT_METHOD,
{ NULL }
};
@@ -555,7 +440,7 @@ PyTypeObject *get_python_object_storage_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.analysis.storage.ObjectStorage",
+ .tp_name = "pychrysalide.glibext.ObjectStorage",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
@@ -579,7 +464,7 @@ PyTypeObject *get_python_object_storage_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide....ObjectStorage'. *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.ObjectStorage'.*
* *
* Retour : Bilan de l'opération. *
* *
@@ -597,7 +482,7 @@ bool ensure_python_object_storage_is_registered(void)
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
- module = get_access_to_python_module("pychrysalide.analysis.storage");
+ module = get_access_to_python_module("pychrysalide.glibext");
dict = PyModule_GetDict(module);
diff --git a/plugins/pychrysalide/analysis/storage/storage.h b/plugins/pychrysalide/glibext/storage.h
index a0a2c18..681f99a 100644
--- a/plugins/pychrysalide/analysis/storage/storage.h
+++ b/plugins/pychrysalide/glibext/storage.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.h - prototypes pour l'équivalent Python du fichier "analysis/storage/storage.h"
+ * storage.h - prototypes pour l'équivalent Python du fichier "glibext/storage.h"
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
-#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_STORAGE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_STORAGE_H
#include <Python.h>
@@ -34,7 +34,7 @@
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_object_storage_type(void);
-/* Prend en charge l'objet 'pychrysalide.analysis.storage.ObjectStorage'. */
+/* Prend en charge l'objet 'pychrysalide.glibext.ObjectStorage'. */
bool ensure_python_object_storage_is_registered(void);
/* Tente de convertir en conservateur d'objets. */
@@ -45,4 +45,4 @@ int convert_to_object_storage_or_none(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_STORAGE_H */
diff --git a/plugins/pychrysalide/analysis/storage/tpmem.c b/plugins/pychrysalide/glibext/tpmem.c
index ae07008..ae07008 100644
--- a/plugins/pychrysalide/analysis/storage/tpmem.c
+++ b/plugins/pychrysalide/glibext/tpmem.c
diff --git a/plugins/pychrysalide/analysis/storage/tpmem.h b/plugins/pychrysalide/glibext/tpmem.h
index 1085632..1085632 100644
--- a/plugins/pychrysalide/analysis/storage/tpmem.h
+++ b/plugins/pychrysalide/glibext/tpmem.h
diff --git a/plugins/pychrysalide/gtkext/Makefile.am b/plugins/pychrysalide/gtkext/Makefile.am
index 2e1260f..1d91751 100644
--- a/plugins/pychrysalide/gtkext/Makefile.am
+++ b/plugins/pychrysalide/gtkext/Makefile.am
@@ -1,19 +1,23 @@
noinst_LTLIBRARIES = libpychrysagtkext.la
+# libpychrysagtkext_la_SOURCES = \
+# blockdisplay.h blockdisplay.c \
+# bufferdisplay.h bufferdisplay.c \
+# displaypanel.h displaypanel.c \
+# dockable.h dockable.c \
+# easygtk.h easygtk.c \
+# module.h module.c \
+# named.h named.c
+
libpychrysagtkext_la_SOURCES = \
- blockdisplay.h blockdisplay.c \
- bufferdisplay.h bufferdisplay.c \
- displaypanel.h displaypanel.c \
- dockable.h dockable.c \
- easygtk.h easygtk.c \
- module.h module.c \
- named.h named.c
-
-libpychrysagtkext_la_LIBADD = \
- graph/libpychrysagtkextgraph.la
-
-libpychrysagtkext_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ panel.h panel.c \
+ module.h module.c
+
+# libpychrysagtkext_la_LIBADD = \
+# graph/libpychrysagtkextgraph.la
+
+libpychrysagtkext_la_CFLAGS = $(LIBGTK4_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
@@ -22,4 +26,4 @@ devdir = $(includedir)/chrysalide/$(subdir)
dev_HEADERS = $(libpychrysagtkext_la_SOURCES:%c=)
-SUBDIRS = graph
+#SUBDIRS = graph
diff --git a/plugins/pychrysalide/gtkext/module.c b/plugins/pychrysalide/gtkext/module.c
index f8264af..fa59b2b 100644
--- a/plugins/pychrysalide/gtkext/module.c
+++ b/plugins/pychrysalide/gtkext/module.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* module.c - intégration du répertoire gtkext en tant que module
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,13 +28,13 @@
#include <assert.h>
-#include "blockdisplay.h"
-#include "bufferdisplay.h"
-#include "displaypanel.h"
-#include "dockable.h"
-#include "easygtk.h"
-#include "named.h"
-#include "graph/module.h"
+//#include "blockdisplay.h"
+//#include "bufferdisplay.h"
+//#include "displaypanel.h"
+//#include "dockable.h"
+//#include "named.h"
+#include "panel.h"
+//#include "graph/module.h"
#include "../helpers.h"
@@ -71,7 +71,7 @@ bool add_gtkext_module(PyObject *super)
result = (module != NULL);
- if (result) result = add_gtkext_graph_module(module);
+ //if (result) result = add_gtkext_graph_module(module);
if (!result)
Py_XDECREF(module);
@@ -99,14 +99,16 @@ bool populate_gtkext_module(void)
result = true;
- if (result) result = ensure_python_block_display_is_registered();
- if (result) result = ensure_python_buffer_display_is_registered();
- if (result) result = ensure_python_display_panel_is_registered();
- if (result) result = ensure_python_dockable_is_registered();
- if (result) result = ensure_python_easygtk_is_registered();
- if (result) result = ensure_python_built_named_widget_is_registered();
+ if (result) result = ensure_python_tiled_panel_is_registered();
- if (result) result = populate_gtkext_graph_module();
+ //if (result) result = ensure_python_block_display_is_registered();
+ //if (result) result = ensure_python_buffer_display_is_registered();
+ //if (result) result = ensure_python_display_panel_is_registered();
+ //if (result) result = ensure_python_dockable_is_registered();
+ //if (result) result = ensure_python_easygtk_is_registered();
+ //if (result) result = ensure_python_built_named_widget_is_registered();
+
+ //if (result) result = populate_gtkext_graph_module();
assert(result);
diff --git a/plugins/pychrysalide/gtkext/panel.c b/plugins/pychrysalide/gtkext/panel.c
new file mode 100644
index 0000000..9f6589a
--- /dev/null
+++ b/plugins/pychrysalide/gtkext/panel.c
@@ -0,0 +1,130 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * panel.c - prototypes pour l'équivalent Python du fichier "gtkext/panel.c"
+ *
+ * Copyright (C) 2025 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 "panel.h"
+
+
+#include <pygobject.h>
+
+
+#include <gtkext/panel.h>
+
+
+#include "../access.h"
+#include "../helpers.h"
+#include "../helpers-ui.h"
+
+
+
+#define TILED_PANEL_DOC \
+ "The TiledPanel class defines a panel widget for the framework main" \
+ " window."
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_tiled_panel_type(void)
+{
+ static PyMethodDef py_tiled_panel_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_tiled_panel_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_tiled_panel_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.gtkext.TiledPanel",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = TILED_PANEL_DOC,
+
+ .tp_methods = py_tiled_panel_methods,
+ .tp_getset = py_tiled_panel_getseters,
+
+ };
+
+ static PyTypeObject *result = NULL;
+
+ if (result == NULL)
+ result = define_python_dynamic_type(&py_tiled_panel_type);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.gtkext.TiledPanel'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_tiled_panel_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'TiledPanel' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_tiled_panel_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.gtkext");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_gtk_widget_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, GTK_TYPE_TILED_PANEL, type))
+ return false;
+
+ }
+
+ return true;
+
+}
diff --git a/plugins/pychrysalide/gtkext/panel.h b/plugins/pychrysalide/gtkext/panel.h
new file mode 100644
index 0000000..c5cbe86
--- /dev/null
+++ b/plugins/pychrysalide/gtkext/panel.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * panel.h - prototypes pour l'équivalent Python du fichier "gtkext/panel.h"
+ *
+ * Copyright (C) 2025 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_GTKEXT_PANEL_H
+#define _PLUGINS_PYCHRYSALIDE_GTKEXT_PANEL_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_tiled_panel_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.gtkext.TiledPanel'. */
+bool ensure_python_tiled_panel_is_registered(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GTKEXT_PANEL_H */
diff --git a/plugins/pychrysalide/helpers-ui.c b/plugins/pychrysalide/helpers-ui.c
new file mode 100644
index 0000000..982e676
--- /dev/null
+++ b/plugins/pychrysalide/helpers-ui.c
@@ -0,0 +1,141 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers-ui.c - simplification des interactions UI de base avec Python
+ *
+ * Copyright (C) 2025 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers-ui.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+#include <gtk/gtk.h>
+
+
+#include "bindings.h"
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONFORTS CIBLANT PYGOBJECT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Assure une prise en charge de l'objet Gtk.WIdget. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_gtk_widget_is_registered(void)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *gtk_mod; /* Module Python Gtk */
+ PyObject *widget_type; /* Module "GtkWidget" */
+
+ /**
+ * Afin d'éviter le message d'avertissement suivant, la version attendue
+ * est demandée :
+ *
+ * PyGIWarning: Gtk was imported without specifying a version first.
+ * Use gi.require_version('Gtk', '4.0') before import to ensure that the right version gets loaded.
+ *
+ */
+ result = import_namespace_from_gi_repository("Gtk", "4.0");
+
+ if (result)
+ {
+ gtk_mod = PyImport_ImportModule("gi.repository.Gtk");
+ assert(gtk_mod != NULL);
+
+ widget_type = PyObject_GetAttrString(gtk_mod, "Widget");
+
+ result = (widget_type != NULL);
+
+ Py_DECREF(gtk_mod);
+ Py_XDECREF(widget_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 instance de composant GTK. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_gtk_widget(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ PyObject *gtk_mod; /* Module Python Gtk */
+ PyObject *widget_type; /* Module "GtkWidget" */
+ int ret; /* Bilan d'une conversion */
+
+ result = 0;
+
+ gtk_mod = PyImport_ImportModule("gi.repository.Gtk");
+
+ if (gtk_mod == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module");
+ goto done;
+ }
+
+ widget_type = PyObject_GetAttrString(gtk_mod, "Widget");
+
+ Py_DECREF(gtk_mod);
+
+ ret = PyObject_TypeCheck(arg, (PyTypeObject *)widget_type);
+
+ Py_DECREF(widget_type);
+
+ if (!ret)
+ {
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to GTK widget");
+ goto done;
+ }
+
+ *((GtkWidget **)dst) = GTK_WIDGET(pygobject_get(arg));
+
+ result = 1;
+
+ done:
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/helpers-ui.h b/plugins/pychrysalide/helpers-ui.h
new file mode 100644
index 0000000..b575905
--- /dev/null
+++ b/plugins/pychrysalide/helpers-ui.h
@@ -0,0 +1,44 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers-ui.h - prototypes pour la simplification des interactions UI de base avec Python
+ *
+ * Copyright (C) 2025 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_HELPERS_UI_H
+#define _PLUGINS_PYCHRYSALIDE_HELPERS_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* --------------------------- CONFORTS CIBLANT PYGOBJECT --------------------------- */
+
+
+/* Assure une prise en charge de l'objet Gtk.WIdget. */
+bool ensure_gtk_widget_is_registered(void);
+
+/* Tente de convertir en instance de composant GTK. */
+int convert_to_gtk_widget(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_HELPERS_UI_H */
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 0c84278..4ff768c 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* helpers.c - simplification des interactions de base avec Python
*
- * Copyright (C) 2018-2024 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -32,9 +32,6 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#ifdef INCLUDE_GTK_SUPPORT
-# include <gtk/gtk.h>
-#endif
#include <i18n.h>
@@ -1260,122 +1257,6 @@ int convert_to_gobject(PyObject *arg, void *dst)
#if 0
-#ifdef INCLUDE_GTK_SUPPORT
-
-
-/******************************************************************************
-* *
-* 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 de composant GTK. *
-* *
-* Retour : Bilan de l'opération, voire indications supplémentaires. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-int convert_to_gtk_widget(PyObject *arg, void *dst)
-{
- int result; /* Bilan à retourner */
- PyObject *gtk_mod; /* Module Python Gtk */
- PyObject *widget_type; /* Module "GtkWidget" */
- int ret; /* Bilan d'une conversion */
-
- result = 0;
-
- gtk_mod = PyImport_ImportModule("gi.repository.Gtk");
-
- if (gtk_mod == NULL)
- {
- PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module");
- goto done;
- }
-
- widget_type = PyObject_GetAttrString(gtk_mod, "Widget");
-
- Py_DECREF(gtk_mod);
-
- ret = PyObject_TypeCheck(arg, (PyTypeObject *)widget_type);
-
- Py_DECREF(widget_type);
-
- if (!ret)
- {
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to GTK widget");
- goto done;
- }
-
- *((GtkWidget **)dst) = GTK_WIDGET(pygobject_get(arg));
-
- result = 1;
-
- done:
-
- 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 instance de conteneur GTK. *
-* *
-* Retour : Bilan de l'opération, voire indications supplémentaires. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-int convert_to_gtk_container(PyObject *arg, void *dst)
-{
- int result; /* Bilan à retourner */
- PyObject *gtk_mod; /* Module Python Gtk */
- PyObject *container_type; /* Module "GtkContainer" */
- int ret; /* Bilan d'une conversion */
-
- result = 0;
-
- gtk_mod = PyImport_ImportModule("gi.repository.Gtk");
-
- if (gtk_mod == NULL)
- {
- PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module");
- goto done;
- }
-
- container_type = PyObject_GetAttrString(gtk_mod, "Container");
-
- Py_DECREF(gtk_mod);
-
- ret = PyObject_TypeCheck(arg, (PyTypeObject *)container_type);
-
- Py_DECREF(container_type);
-
- if (!ret)
- {
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to GTK container");
- goto done;
- }
-
- *((GtkContainer **)dst) = GTK_CONTAINER(pygobject_get(arg));
-
- result = 1;
-
- done:
-
- return result;
-
-}
-
-
-#endif
-
-
/******************************************************************************
* *
* Paramètres : color = couleur dans sa définition native à copier. *
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 745d013..f1c6337 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* helpers.h - prototypes pour la simplification des interactions de base avec Python
*
- * Copyright (C) 2018-2024 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -313,17 +313,6 @@ int convert_to_gobject(PyObject *, void *);
#if 0
-#ifdef INCLUDE_GTK_SUPPORT
-
-/* Tente de convertir en instance de composant GTK. */
-int convert_to_gtk_widget(PyObject *, void *);
-
-/* Tente de convertir en instance de conteneur GTK. */
-int convert_to_gtk_container(PyObject *, void *);
-
-#endif
-
-
#if !defined(INCLUDE_GTK_SUPPORT) && !defined(HOMEMADE_RGBA)
# define HOMEMADE_RGBA