summaryrefslogtreecommitdiff
path: root/plugins/pychrysa
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysa')
-rw-r--r--plugins/pychrysa/arch/instruction.c215
-rw-r--r--plugins/pychrysa/glibext/Makefile.am1
-rw-r--r--plugins/pychrysa/glibext/linegen.c404
-rw-r--r--plugins/pychrysa/glibext/linegen.h42
-rw-r--r--plugins/pychrysa/glibext/module.c2
-rw-r--r--plugins/pychrysa/gtkext/Makefile.am1
-rw-r--r--plugins/pychrysa/gtkext/blockdisplay.c15
-rw-r--r--plugins/pychrysa/gtkext/bufferdisplay.c15
-rw-r--r--plugins/pychrysa/gtkext/displaypanel.c35
-rw-r--r--plugins/pychrysa/gtkext/dockable.c102
-rw-r--r--plugins/pychrysa/gtkext/dockable.h42
-rw-r--r--plugins/pychrysa/gtkext/module.c2
-rw-r--r--plugins/pychrysa/gui/panels/panel.c4
-rw-r--r--plugins/pychrysa/helpers.c35
-rw-r--r--plugins/pychrysa/helpers.h5
-rw-r--r--plugins/pychrysa/pychrysa.c86
16 files changed, 775 insertions, 231 deletions
diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c
index 0efca5a..61d1987 100644
--- a/plugins/pychrysa/arch/instruction.c
+++ b/plugins/pychrysa/arch/instruction.c
@@ -34,6 +34,7 @@
#include "vmpa.h"
#include "../helpers.h"
+#include "../glibext/linegen.h"
@@ -440,6 +441,7 @@ bool register_python_arch_instruction(PyObject *module)
{
PyTypeObject *py_arch_instruction_type; /* Type Python 'ArchInstruc...'*/
PyObject *dict; /* Dictionnaire du module */
+ PyTypeObject *py_line_generator_type; /* Type Python 'LineGenerator' */
py_arch_instruction_type = get_python_arch_instruction_type();
@@ -447,217 +449,12 @@ bool register_python_arch_instruction(PyObject *module)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_type, &PyGObject_Type))
- return false;
-
- return true;
-
-}
-
-
-
-
-
-
-
-#if 0
-
-
-#include <pygobject.h>
-#include <stdbool.h>
-#include <string.h>
-
-
-#include <arch/instruction.h>
-
-
-#include "../quirks.h"
-
-
-
-/* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */
-
-
-/* Crée un nouvel objet Python de type 'ArchInstruction'. */
-static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *);
-
-/* Prépare un parcours d'instructions. */
-static PyObject *py_arch_instruction_get_iter(PyObject *);
-
-/* Fournit la valeur associée à une propriété donnée. */
-static PyObject *py_arch_instruction_get_location(PyObject *, char *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* INSTRUCTIONS D'ARCHITECTURES EN PYTHON */
-/* ---------------------------------------------------------------------------------- */
-
+ py_line_generator_type = get_python_line_generator_type();
-/******************************************************************************
-* *
-* Paramètres : type = type de l'objet à instancier. *
-* args = arguments fournis à l'appel. *
-* kwds = arguments de type key=val fournis. *
-* *
-* Description : Crée un nouvel objet Python de type 'ArchInstruction'. *
-* *
-* Retour : Instance Python mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_arch_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Py_RETURN_NONE;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = instance manipulée à traiter. *
-* *
-* Description : Prépare un parcours d'instructions. *
-* *
-* Retour : Point de départ d'un parcours. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_arch_instruction_get_iter(PyObject *self)
-{
- return py_arch_instruction_iterator_create(self);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = classe représentant une instruction. *
-* name = nom de la propriété à lire. *
-* *
-* Description : Fournit la valeur associée à une propriété donnée. *
-* *
-* Retour : Valeur associée à la propriété consultée. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_arch_instruction_get_location(PyObject *self, char *name)
-{
- PyObject *result; /* Trouvailles à retourner */
- GArchInstruction *instr; /* Version native */
- off_t offset; /* Position dans le fichier */
- off_t length; /* Taille de l'instruction */
- vmpa_t address; /* Position en mémoire */
-
- instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_get_location(instr, &offset, &length, &address);
-
- if (strcmp(name, "offset") == 0)
- result = PyLong_FromLong(offset);
-
- else if (strcmp(name, "length") == 0)
- result = PyLong_FromLong(length);
-
- else if (strcmp(name, "address") == 0)
- result = PyLong_FromLongLong(address);
-
- else
- result = NULL;
-
- return result;
-
-}
-
-
-
-/******************************************************************************
-* *
-* Paramètres : module = module dont la définition est à compléter. *
-* *
-* Description : Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool register_python_arch_instruction(PyObject *module)
-{
- PyObject *pygobj_mod; /* Module Python-GObject */
- int ret; /* Bilan d'un appel */
-
- static PyMethodDef py_arch_instruction_methods[] = {
- { NULL }
- };
-
- static PyGetSetDef py_arch_instruction_getseters[] = {
- {
- "offset", (getter)py_arch_instruction_get_location, (setter)NULL,
- "Provide the location of the instruction in the binary file.", "offset"
- },
- {
- "length", (getter)py_arch_instruction_get_location, (setter)NULL,
- "Provide the length of the instruction.", "length"
- },
- {
- "address", (getter)py_arch_instruction_get_location, (setter)NULL,
- "Provide the location of the instruction in memory.", "address"
- },
- {
- "keyword", (getter)py_arch_instruction_get_keyword, (setter)NULL,
- "Give le name of the assembly instruction.", NULL
- },
- { NULL }
- };
-
- static PyTypeObject py_arch_instruction_type = {
-
- PyObject_HEAD_INIT(NULL)
-
- .tp_name = "pychrysalide.arch.ArchInstruction",
- .tp_basicsize = sizeof(PyGObject),
-
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-
- .tp_doc = "PyChrysalide architecture instruction",
-
- .tp_methods = py_arch_instruction_methods,
- .tp_getset = py_arch_instruction_getseters,
- .tp_new = (newfunc)py_arch_instruction_new,
-
- .tp_iter = (getiterfunc)py_arch_instruction_get_iter
-
- };
-
- pygobj_mod = PyImport_ImportModule("gobject");
- if (pygobj_mod == NULL) return false;
-
- py_arch_instruction_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
- Py_DECREF(pygobj_mod);
-
- if (PyType_Ready(&py_arch_instruction_type) < 0)
+ if (!_register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_type,
+ &PyGObject_Type, py_line_generator_type, NULL))
return false;
- Py_INCREF(&py_arch_instruction_type);
- ret = PyModule_AddObject(module, "ArchInstruction", (PyObject *)&py_arch_instruction_type);
-
- register_class_for_pygobject(module, "GArchInstruction", G_TYPE_ARCH_INSTRUCTION,
- &py_arch_instruction_type,
- Py_BuildValue("(O)", py_arch_instruction_type.tp_base));
-
- return (ret == 0);
+ return true;
}
-
-
-#endif
diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am
index b53f4b0..d1b2569 100644
--- a/plugins/pychrysa/glibext/Makefile.am
+++ b/plugins/pychrysa/glibext/Makefile.am
@@ -5,6 +5,7 @@ libpychrysaglibext_la_SOURCES = \
buffercache.h buffercache.c \
bufferline.h bufferline.c \
configuration.h configuration.c \
+ linegen.h linegen.c \
module.h module.c
diff --git a/plugins/pychrysa/glibext/linegen.c b/plugins/pychrysa/glibext/linegen.c
new file mode 100644
index 0000000..b6aad6b
--- /dev/null
+++ b/plugins/pychrysa/glibext/linegen.c
@@ -0,0 +1,404 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.c - équivalent Python du fichier "glibext/linegen.h"
+ *
+ * Copyright (C) 2017 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 "linegen.h"
+
+
+#include <pygobject.h>
+
+
+#include <common/cpp.h>
+#include <glibext/linegen.h>
+
+
+#include "../helpers.h"
+#include "../analysis/content.h"
+#include "../arch/vmpa.h"
+#include "../glibext/bufferline.h"
+
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static PyObject *py_line_generator_count_lines(PyObject *, PyObject *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static PyObject *py_line_generator_compute_addr(PyObject *, PyObject *);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static PyObject *py_line_generator_contains_addr(PyObject *, PyObject *);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static PyObject *py_line_generator_print(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant un générateur à manipuler. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Décompte à retourner */
+ GLineGenerator *generator; /* Version native */
+ size_t count; /* Nombre de lignes présentes */
+
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
+ count = g_line_generator_count_lines(generator);
+
+ result = Py_BuildValue("k", count);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Localisation à retourner */
+ GLineGenerator *generator; /* Version native */
+ gint x; /* Position géographique */
+ size_t index; /* Indice dans le tampon */
+ size_t repeat; /* Utilisations successives */
+ int ret; /* Bilan de lecture des args. */
+ vmpa2t addr; /* Adresse visée par l'opérat° */
+
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "ikk", &x, &index, &repeat);
+ if (!ret) return NULL;
+
+ g_line_generator_compute_addr(generator, x, &addr, index, repeat);
+
+ result = build_from_internal_vmpa(&addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args)
+{
+ GLineGenerator *generator; /* Version native */
+ PyObject *py_vmpa; /* Localisation version Python */
+ size_t index; /* Indice dans le tampon */
+ size_t repeat; /* Utilisations successives */
+ int ret; /* Bilan de lecture des args. */
+ vmpa2t *addr; /* Adresse visée par l'opérat° */
+
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "O!kk", get_python_vmpa_type(), &py_vmpa, &index, &repeat);
+ if (!ret) return NULL;
+
+ addr = get_internal_vmpa(py_vmpa);
+ if (addr == NULL) return NULL;
+
+ g_line_generator_contains_addr(generator, addr, index, repeat);
+
+ Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Propriétés à retourner */
+ GLineGenerator *generator; /* Version native */
+ size_t index; /* Indice dans le tampon */
+ size_t repeat; /* Utilisations successives */
+ int ret; /* Bilan de lecture des args. */
+ BufferLineFlags flags; /* Propriétés courantes */
+
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "kk", &index, &repeat);
+ if (!ret) return NULL;
+
+ flags = g_line_generator_get_flags(generator, index, repeat);
+
+ result = Py_BuildValue("I", flags);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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é. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
+{
+ GLineGenerator *generator; /* Version native */
+ PyObject *py_line; /* Ligne version Python */
+ size_t index; /* Indice dans le tampon */
+ size_t repeat; /* Utilisations successives */
+ PyObject *py_content; /* Contenu version Python */
+ int ret; /* Bilan de lecture des args. */
+ GBufferLine *line; /* Ligne de rendu à compléter */
+ GBinContent *content; /* Contenu binaire associé */
+
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "O!kkO!", get_python_buffer_line_type(), &py_line, &index,
+ &repeat, get_python_binary_content_type(), &py_content);
+ if (!ret) return NULL;
+
+ line = G_BUFFER_LINE(pygobject_get(py_line));
+
+ content = G_BIN_CONTENT(pygobject_get(py_content));
+
+ g_line_generator_print(generator, line, index, repeat, content);
+
+ Py_RETURN_NONE;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void python_line_generator_interface_init(GLineGeneratorIface *iface, PyTypeObject *type)
+{
+ GLineGeneratorIface *parent; /* Défintion parente */
+ size_t i; /* Boucle de parcours */
+ PyObject *method; /* Méthode à associer */
+
+ static const char *meth_names[] = {
+ "count_lines",
+ "compute_addr",
+ "contains_addr",
+ "get_flags",
+ "print"
+ };
+
+ parent = g_type_interface_peek_parent(iface);
+
+ for (i = 0; i < ARRAY_SIZE(meth_names); i++)
+ {
+ method = NULL;
+
+ if (type != NULL)
+ method = PyObject_GetAttrString((PyObject *)type, meth_names[i]);
+
+ if (method != NULL && PyObject_TypeCheck(method, &PyCFunction_Type) == 0)
+ /*iface->iface_method = _wrap_TestInterface__proxy_do_iface_method*/;
+
+ else
+ {
+ PyErr_Clear();
+
+ if (parent != NULL)
+ /*iface->iface_method = parent->iface_method*/;
+
+ }
+
+ Py_XDECREF(method);
+
+ }
+
+}
+
+
+#endif
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_line_generator_type(void)
+{
+ static PyMethodDef py_line_generator_methods[] = {
+ {
+ "count_lines", py_line_generator_count_lines,
+ METH_NOARGS,
+ "count_lines($self, /)\n--\n\nCount the number of lines which can be displayed."
+ },
+ {
+ "compute_addr", py_line_generator_compute_addr,
+ METH_VARARGS,
+ "compute_addr($self, x, index, repeat, /)\n--\n\nReturn the position at a given location."
+ },
+ {
+ "contains_addr", py_line_generator_contains_addr,
+ METH_VARARGS,
+ "contains_addr($self, addr, index, repeat, /)\n--\n\nTell if the generator contains an address."
+ },
+ {
+ "get_flags", py_line_generator_get_flags,
+ METH_VARARGS,
+ "get_flags($self, index, repeat, /)\n--\n\nGet the flags of a position from the generator."
+ },
+ {
+ "print", py_line_generator_print,
+ METH_VARARGS,
+ "print($self, line, index, repeat, content, /)\n--\n\nProduce output into a line from content."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_line_generator_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_line_generator_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.LineGenerator",
+ //.tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide line content generator",
+
+ .tp_methods = py_line_generator_methods,
+ .tp_getset = py_line_generator_getseters,
+
+ };
+
+ return &py_line_generator_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_line_generator(PyObject *module)
+{
+ PyTypeObject *py_line_generator_type; /* Type Python 'LineGenerator' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_line_generator_type = get_python_line_generator_type();
+
+ dict = PyModule_GetDict(module);
+ pyg_register_interface(dict, "LineGenerator", G_TYPE_LINE_GENERATOR, py_line_generator_type);
+
+ return true;
+
+}
diff --git a/plugins/pychrysa/glibext/linegen.h b/plugins/pychrysa/glibext/linegen.h
new file mode 100644
index 0000000..8669bb7
--- /dev/null
+++ b/plugins/pychrysa/glibext/linegen.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.h - prototypes pour l'équivalent Python du fichier "glibext/linegen.h"
+ *
+ * Copyright (C) 2017 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_PYCHRYSA_GLIBEXT_LINEGEN_H
+#define _PLUGINS_PYCHRYSA_GLIBEXT_LINEGEN_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_line_generator_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'. */
+bool register_python_line_generator(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_LINEGEN_H */
diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c
index eb5c892..f62b17b 100644
--- a/plugins/pychrysa/glibext/module.c
+++ b/plugins/pychrysa/glibext/module.c
@@ -31,6 +31,7 @@
#include "buffercache.h"
#include "bufferline.h"
#include "configuration.h"
+#include "linegen.h"
@@ -85,6 +86,7 @@ bool add_glibext_module_to_python_module(PyObject *super)
result &= register_python_config_param(module);
result &= register_python_config_param_iterator(module);
result &= register_python_generic_config(module);
+ result &= register_python_line_generator(module);
agmtpm_exit:
diff --git a/plugins/pychrysa/gtkext/Makefile.am b/plugins/pychrysa/gtkext/Makefile.am
index fee2032..4a36e63 100644
--- a/plugins/pychrysa/gtkext/Makefile.am
+++ b/plugins/pychrysa/gtkext/Makefile.am
@@ -5,6 +5,7 @@ libpychrysagtkext_la_SOURCES = \
blockdisplay.h blockdisplay.c \
bufferdisplay.h bufferdisplay.c \
displaypanel.h displaypanel.c \
+ dockable.h dockable.c \
module.h module.c
diff --git a/plugins/pychrysa/gtkext/blockdisplay.c b/plugins/pychrysa/gtkext/blockdisplay.c
index 06f14d8..a329daf 100644
--- a/plugins/pychrysa/gtkext/blockdisplay.c
+++ b/plugins/pychrysa/gtkext/blockdisplay.c
@@ -25,6 +25,7 @@
#include "blockdisplay.h"
+#include <string.h>
#include <pygobject.h>
@@ -65,7 +66,7 @@ PyTypeObject *get_python_block_display_type(void)
.tp_name = "pychrysalide.gtkext.BlockDisplay",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
.tp_doc = "PyChrysalide block display.",
@@ -74,7 +75,17 @@ PyTypeObject *get_python_block_display_type(void)
};
- return &py_block_display_type;
+ static PyTypeObject *result = NULL;
+
+ if (result == NULL)
+ {
+ result = calloc(1, sizeof(PyTypeObject));
+
+ memcpy(result, &py_block_display_type, sizeof(PyTypeObject));
+
+ }
+
+ return result;
}
diff --git a/plugins/pychrysa/gtkext/bufferdisplay.c b/plugins/pychrysa/gtkext/bufferdisplay.c
index 7cc82ff..a6e5327 100644
--- a/plugins/pychrysa/gtkext/bufferdisplay.c
+++ b/plugins/pychrysa/gtkext/bufferdisplay.c
@@ -25,6 +25,7 @@
#include "bufferdisplay.h"
+#include <string.h>
#include <pygobject.h>
@@ -65,7 +66,7 @@ PyTypeObject *get_python_buffer_display_type(void)
.tp_name = "pychrysalide.gtkext.BufferDisplay",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
.tp_doc = "PyChrysalide buffer display.",
@@ -74,7 +75,17 @@ PyTypeObject *get_python_buffer_display_type(void)
};
- return &py_buffer_display_type;
+ static PyTypeObject *result = NULL;
+
+ if (result == NULL)
+ {
+ result = calloc(1, sizeof(PyTypeObject));
+
+ memcpy(result, &py_buffer_display_type, sizeof(PyTypeObject));
+
+ }
+
+ return result;
}
diff --git a/plugins/pychrysa/gtkext/displaypanel.c b/plugins/pychrysa/gtkext/displaypanel.c
index d085f4f..e857475 100644
--- a/plugins/pychrysa/gtkext/displaypanel.c
+++ b/plugins/pychrysa/gtkext/displaypanel.c
@@ -25,6 +25,7 @@
#include "displaypanel.h"
+#include <string.h>
#include <pygobject.h>
@@ -196,7 +197,7 @@ PyTypeObject *get_python_display_panel_type(void)
.tp_name = "pychrysalide.gtkext.DisplayPanel",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,
.tp_doc = "PyChrysalide view panel.",
@@ -207,7 +208,17 @@ PyTypeObject *get_python_display_panel_type(void)
};
- return &py_display_panel_type;
+ static PyTypeObject *result = NULL;
+
+ if (result == NULL)
+ {
+ result = calloc(1, sizeof(PyTypeObject));
+
+ memcpy(result, &py_display_panel_type, sizeof(PyTypeObject));
+
+ }
+
+ return result;
}
@@ -226,27 +237,37 @@ PyTypeObject *get_python_display_panel_type(void)
bool register_python_display_panel(PyObject *module)
{
+ bool result; /* Bilan à retourner */
PyTypeObject *py_display_panel_type; /* Type Python 'DisplayPanel' */
PyObject *parent_mod; /* Module Python Fixed */
PyObject *fixed; /* Module "GtkFixed" */
PyObject *dict; /* Dictionnaire du module */
+ result = false;
+
py_display_panel_type = get_python_display_panel_type();
parent_mod = PyImport_ImportModule("gi.repository.Gtk");
if (parent_mod == NULL) return false;
fixed = PyObject_GetAttrString(parent_mod, "Fixed");
+
Py_DECREF(parent_mod);
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, GTK_TYPE_DISPLAY_PANEL, py_display_panel_type, (PyTypeObject *)fixed))
- return false;
+ result = register_class_for_pygobject(dict, GTK_TYPE_DISPLAY_PANEL,
+ py_display_panel_type, (PyTypeObject *)fixed);
+
+ Py_DECREF(fixed);
- if (!py_display_panel_define_constants(py_display_panel_type))
- return false;
+ if (!result)
+ goto rpdp_exit;
- return true;
+ result = py_display_panel_define_constants(py_display_panel_type);
+
+ rpdp_exit:
+
+ return result;
}
diff --git a/plugins/pychrysa/gtkext/dockable.c b/plugins/pychrysa/gtkext/dockable.c
new file mode 100644
index 0000000..9c66159
--- /dev/null
+++ b/plugins/pychrysa/gtkext/dockable.c
@@ -0,0 +1,102 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * dockable.c - équivalent Python du fichier "gtkext/gtkdockable.c"
+ *
+ * Copyright (C) 2017 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 "dockable.h"
+
+
+#include <pygobject.h>
+
+
+#include <gtkext/gtkdockable.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_gtk_dockable_type(void)
+{
+ static PyMethodDef py_gtk_dockable_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_gtk_dockable_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_gtk_dockable_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.gtkext.GtkDockable",
+ //.tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide interface for Gtk dockable widgets",
+
+ .tp_methods = py_gtk_dockable_methods,
+ .tp_getset = py_gtk_dockable_getseters,
+
+ };
+
+ return &py_gtk_dockable_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.gtkext.GtkDockable'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_gtk_dockable(PyObject *module)
+{
+ PyTypeObject *py_gtk_dockable_type; /* Type Python 'LineGenerator' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_gtk_dockable_type = get_python_gtk_dockable_type();
+
+ dict = PyModule_GetDict(module);
+ pyg_register_interface(dict, "LineGenerator", GTK_TYPE_DOCKABLE, py_gtk_dockable_type);
+
+ return true;
+
+}
diff --git a/plugins/pychrysa/gtkext/dockable.h b/plugins/pychrysa/gtkext/dockable.h
new file mode 100644
index 0000000..1709966
--- /dev/null
+++ b/plugins/pychrysa/gtkext/dockable.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * dockable.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkdockable.h"
+ *
+ * Copyright (C) 2017 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_PYCHRYSA_GTKEXT_DOCKABLE_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_DOCKABLE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_gtk_dockable_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.gtkext.GtkDockable'. */
+bool register_python_gtk_dockable(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_GTKEXT_DOCKABLE_H */
diff --git a/plugins/pychrysa/gtkext/module.c b/plugins/pychrysa/gtkext/module.c
index 00720bb..8b2cc5e 100644
--- a/plugins/pychrysa/gtkext/module.c
+++ b/plugins/pychrysa/gtkext/module.c
@@ -31,6 +31,7 @@
#include "blockdisplay.h"
#include "bufferdisplay.h"
#include "displaypanel.h"
+#include "dockable.h"
@@ -83,6 +84,7 @@ bool add_gtkext_module_to_python_module(PyObject *super)
result &= register_python_display_panel(module);
result &= register_python_buffer_display(module);
result &= register_python_block_display(module);
+ result &= register_python_gtk_dockable(module);
agmtpm_exit:
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index 26637e0..9ca271f 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -36,6 +36,7 @@
#include "../editem.h"
#include "../../helpers.h"
#include "../../quirks.h"
+#include "../../gtkext/dockable.h"
@@ -232,7 +233,8 @@ bool register_python_panel_item(PyObject *module)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_PANEL_ITEM, py_panel_item_type, get_python_editor_item_type()))
+ if (!_register_class_for_pygobject(dict, G_TYPE_PANEL_ITEM, py_panel_item_type,
+ get_python_editor_item_type(), get_python_gtk_dockable_type(), NULL))
return false;
if (!py_panel_item_define_constants(py_panel_item_type))
diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c
index df1df05..a0a828f 100644
--- a/plugins/pychrysa/helpers.c
+++ b/plugins/pychrysa/helpers.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include <pygobject.h>
+#include <stdarg.h>
@@ -256,8 +257,13 @@ bool PyDict_AddStringConstant(PyTypeObject *obj_type, const char *key, const cha
* *
******************************************************************************/
-bool register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *type, PyTypeObject *base)
+bool _register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *type, PyTypeObject *base, ...)
{
+ Py_ssize_t size; /* Taille de liste actuelle */
+ PyObject *static_bases; /* Base(s) de l'objet */
+ va_list ap; /* Parcours des arguments */
+ PyTypeObject *static_base; /* Base à rajouter à la liste */
+
/**
* pygobject_register_class() définit type->tp_base à partir des arguments fournis,
* puis fait appel à PyType_Ready().
@@ -285,7 +291,32 @@ bool register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *typ
type->tp_basicsize = base->tp_basicsize;
}
- pygobject_register_class(dict, NULL, gtype, type, Py_BuildValue("(O)", base));
+ size = 1;
+ static_bases = PyTuple_New(size);
+
+ Py_INCREF(base);
+ PyTuple_SetItem(static_bases, 0, (PyObject *)base);
+
+ va_start(ap, base);
+
+ while (1)
+ {
+ static_base = va_arg(ap, PyTypeObject *);
+
+ if (static_base == NULL) break;
+
+ _PyTuple_Resize(&static_bases, ++size);
+
+ Py_INCREF(static_base);
+ PyTuple_SetItem(static_bases, size - 1, (PyObject *)static_base);
+
+ }
+
+ va_end(ap);
+
+ pygobject_register_class(dict, NULL, gtype, type, static_bases);
+
+ assert(PyErr_Occurred() == NULL);
return true;
diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h
index 950c85b..9fb83d0 100644
--- a/plugins/pychrysa/helpers.h
+++ b/plugins/pychrysa/helpers.h
@@ -65,7 +65,10 @@ bool PyDict_AddStringConstant(PyTypeObject *, const char *, const char *);
/* Enregistre correctement une surcouche de conversion GObject. */
-bool register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObject *);
+bool _register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObject *, ...);
+
+#define register_class_for_pygobject(dict, gtype, type, base) \
+ _register_class_for_pygobject(dict, gtype, type, base, NULL)
/**
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index 45e32b4..f09c234 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -40,6 +40,7 @@
#include <plugins/plugin-int.h>
+#include "helpers.h"
#include "plugin.h"
#include "quirks.h"
#include "analysis/module.h"
@@ -72,6 +73,9 @@ static PyObject *py_chrysalide_get_global_gobject(PyObject *, PyObject *);
/* Détermine si l'interpréteur lancé est celui pris en compte. */
static bool is_current_abi_suitable(void);
+/* Définit la version attendue de GTK à charger dans Python. */
+static bool set_version_for_gtk_namespace(const char *);
+
/* Charge autant de greffons composés en Python que possible. */
static bool load_python_plugins(GPluginModule *plugin, GObject *);
@@ -251,6 +255,55 @@ static bool is_current_abi_suitable(void)
/******************************************************************************
* *
+* Paramètres : version = idenfiant de la version de GTK à stipuler. *
+* *
+* Description : Définit la version attendue de GTK à charger dans Python. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool set_version_for_gtk_namespace(const char *version)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *gi_mod; /* Module Python-GObject */
+ PyObject *args; /* Arguments à fournir */
+
+ result = false;
+
+ /**
+ * On cherche ici à éviter le message suivant si on charge 'gi.repository.Gtk' directement :
+ *
+ *
+ * PyGIWarning: Gtk was imported without specifying a version first. \
+ * Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded.
+ *
+ */
+
+ gi_mod = PyImport_ImportModule("gi");
+
+ if (gi_mod != NULL)
+ {
+ args = Py_BuildValue("ss", "Gtk", "3.0");
+
+ run_python_method(gi_mod, "require_version", args);
+
+ result = (PyErr_Occurred() == NULL);
+
+ Py_DECREF(args);
+ Py_DECREF(gi_mod);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Point d'entrée pour l'initialisation de Python. *
@@ -362,6 +415,9 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
return NULL;
}
+ if (!set_version_for_gtk_namespace("3.0"))
+ return NULL;
+
if (!load_all_basic_components())
{
PyErr_SetString(PyExc_SystemError, "unable to load all basic components.");
@@ -386,15 +442,16 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
result = PyModule_Create(&py_chrysalide_module);
- status = register_python_plugin_module(result);
+ /* Interface 'LineGenerator' en premier... */
+ status = add_glibext_module_to_python_module(result);
+ status &= register_python_plugin_module(result);
status &= add_analysis_module_to_python_module(result);
status &= add_arch_module_to_python_module(result);
status &= add_common_module_to_python_module(result);
status &= add_core_module_to_python_module(result);
status &= add_debug_module_to_python_module(result);
status &= add_format_module_to_python_module(result);
- status &= add_glibext_module_to_python_module(result);
status &= add_gtkext_module_to_python_module(result);
status &= add_gui_module_to_python_module(result);
@@ -439,9 +496,9 @@ static bool load_python_plugins(GPluginModule *plugin, GObject *ref)
save = NULL; /* gcc... */
- for (path = strtok_r(paths, ";", &save);
+ for (path = strtok_r(paths, ":", &save);
path != NULL;
- path = strtok_r(NULL, ";", &save))
+ path = strtok_r(NULL, ":", &save))
{
dir = opendir(path);
if (dir == NULL)
@@ -514,6 +571,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref)
{
bool result; /* Bilan à retourner */
DIR *dir; /* Répertoire à parcourir */
+ int ret; /* Bilan de préparatifs */
define_internal_ref(ref);
@@ -524,15 +582,27 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref)
if (dir != NULL)
{
closedir(dir);
- add_to_env_var("PYTHONPATH", PLUGINS_DIR G_DIR_SEPARATOR_S "python", ";");
+ add_to_env_var("PYTHONPATH", PLUGINS_DIR G_DIR_SEPARATOR_S "python", ":");
}
else
add_to_env_var("PYTHONPATH", PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" \
- G_DIR_SEPARATOR_S "python", ";");
+ G_DIR_SEPARATOR_S "python", ":");
+
+ g_plugin_module_log_variadic_message(plugin, LMT_INFO,
+ _("PYTHONPATH environment variable set to '%s'"),
+ getenv("PYTHONPATH"));
/* Chargement du module pour Python */
- PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide);
+ ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide);
+
+ if (ret == -1)
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("Can not extend the existing table of Python built-in modules."));
+ result = false;
+ goto cpi_done;
+ }
Py_Initialize();
@@ -540,6 +610,8 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref)
result = load_python_plugins(plugin, ref);
+ cpi_done:
+
return result;
}