summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-30 10:38:52 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-30 10:38:52 (GMT)
commit932ea7c83c07d3982fee605c6dd9895fd2753874 (patch)
tree766ad53bab9e3e3005334c30e823493de8e84168
parent1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff)
Rewritten the line buffers using generators and on-demand building to save memory.
-rw-r--r--ChangeLog220
-rw-r--r--configure.ac5
-rw-r--r--plugins/Makefile.am3
-rw-r--r--plugins/pychrysa/analysis/binary.c16
-rw-r--r--plugins/pychrysa/glibext/Makefile.am2
-rw-r--r--plugins/pychrysa/glibext/buffercache.c (renamed from plugins/pychrysa/glibext/codebuffer.c)40
-rw-r--r--plugins/pychrysa/glibext/buffercache.h (renamed from plugins/pychrysa/glibext/codebuffer.h)12
-rw-r--r--plugins/pychrysa/glibext/module.c4
-rw-r--r--plugins/pychrysa/gtkext/Makefile.am4
-rw-r--r--plugins/pychrysa/gtkext/blockdisplay.c (renamed from plugins/pychrysa/gtkext/blockview.c)37
-rw-r--r--plugins/pychrysa/gtkext/blockdisplay.h (renamed from plugins/pychrysa/gtkext/bufferview.h)14
-rw-r--r--plugins/pychrysa/gtkext/bufferdisplay.c (renamed from plugins/pychrysa/gtkext/bufferview.c)35
-rw-r--r--plugins/pychrysa/gtkext/bufferdisplay.h (renamed from plugins/pychrysa/gtkext/blockview.h)14
-rw-r--r--plugins/pychrysa/gtkext/module.c8
-rw-r--r--plugins/ropgadgets/select.c23
-rwxr-xr-xsrc/analysis/Makefile.am3
-rw-r--r--src/analysis/binary.c29
-rw-r--r--src/analysis/binary.h7
-rw-r--r--src/analysis/content.c2
-rw-r--r--src/analysis/db/items/bookmark.c4
-rw-r--r--src/analysis/db/items/comment.c335
-rw-r--r--src/analysis/db/items/comment.h9
-rw-r--r--src/analysis/db/items/move.h2
-rw-r--r--src/analysis/db/items/switcher.c5
-rw-r--r--src/analysis/disass/area.h1
-rw-r--r--src/analysis/disass/disassembler.c127
-rw-r--r--src/analysis/disass/disassembler.h2
-rw-r--r--src/analysis/disass/output.c183
-rw-r--r--src/analysis/disass/output.h8
-rwxr-xr-xsrc/analysis/human/Makefile.am19
-rwxr-xr-xsrc/analysis/human/asm/Makefile.am17
-rw-r--r--src/analysis/human/asm/lang.c221
-rw-r--r--src/analysis/human/asm/lang.h58
-rw-r--r--src/analysis/human/lang-int.h58
-rw-r--r--src/analysis/human/lang.c167
-rw-r--r--src/analysis/human/lang.h58
-rw-r--r--src/analysis/project.c18
-rw-r--r--src/arch/dalvik/link.c5
-rw-r--r--src/arch/instruction-int.h2
-rw-r--r--src/arch/instruction.c293
-rw-r--r--src/arch/instruction.h4
-rw-r--r--src/arch/raw.c45
-rw-r--r--src/arch/undefined.c23
-rw-r--r--src/arch/vmpa.h4
-rwxr-xr-xsrc/format/dex/dex.c4
-rw-r--r--src/format/dex/pool.h1
-rw-r--r--src/format/dwarf/v2/dwarf.h3
-rw-r--r--src/format/dwarf/v3/dwarf.h3
-rw-r--r--src/format/dwarf/v4/dwarf.h3
-rw-r--r--src/format/elf/symbols.h1
-rw-r--r--src/format/format-int.h5
-rwxr-xr-xsrc/format/java/java.h2
-rw-r--r--src/format/pe/pe.h2
-rw-r--r--src/format/symbol.c221
-rw-r--r--src/format/symbol.h12
-rw-r--r--src/glibext/Makefile.am9
-rw-r--r--src/glibext/gbinportion.c345
-rw-r--r--src/glibext/gbinportion.h4
-rw-r--r--src/glibext/gbuffercache.c1625
-rw-r--r--src/glibext/gbuffercache.h121
-rw-r--r--src/glibext/gbufferline.c176
-rw-r--r--src/glibext/gbufferline.h9
-rw-r--r--src/glibext/gbufferview.c810
-rw-r--r--src/glibext/gbufferview.h47
-rw-r--r--src/glibext/gcodebuffer.c1778
-rw-r--r--src/glibext/gcodebuffer.h155
-rw-r--r--src/glibext/generator-int.h52
-rw-r--r--src/glibext/generators/Makefile.am15
-rw-r--r--src/glibext/generators/prologue.c359
-rw-r--r--src/glibext/generators/prologue.h58
-rw-r--r--src/glibext/generators/rborder.c361
-rw-r--r--src/glibext/generators/rborder.h60
-rw-r--r--src/glibext/gwidthtracker.c59
-rw-r--r--src/glibext/gwidthtracker.h10
-rw-r--r--src/glibext/linecolumn.c2
-rw-r--r--src/glibext/linegen-int.h67
-rw-r--r--src/glibext/linegen.c208
-rw-r--r--src/glibext/linegen.h68
-rw-r--r--src/glibext/linesegment.c9
-rw-r--r--src/glibext/linesegment.h9
-rw-r--r--src/gtkext/Makefile.am29
-rw-r--r--src/gtkext/graph/cluster.c48
-rw-r--r--src/gtkext/graph/cluster.h4
-rw-r--r--src/gtkext/graph/edge.c27
-rw-r--r--src/gtkext/graph/edge.h3
-rw-r--r--src/gtkext/gtkblockdisplay.c (renamed from src/gtkext/gtkblockview.c)214
-rw-r--r--src/gtkext/gtkblockdisplay.h (renamed from src/gtkext/gtkblockview.h)28
-rw-r--r--src/gtkext/gtkbufferdisplay-int.h (renamed from src/gtkext/gtkbufferview-int.h)29
-rw-r--r--src/gtkext/gtkbufferdisplay.c (renamed from src/gtkext/gtkbufferview.c)795
-rw-r--r--src/gtkext/gtkbufferdisplay.h70
-rw-r--r--src/gtkext/gtkbufferview.h70
-rw-r--r--src/gtkext/gtkdisplaypanel-int.h6
-rw-r--r--src/gtkext/gtkdisplaypanel.c16
-rw-r--r--src/gtkext/gtkgraphdisplay.c (renamed from src/gtkext/gtkgraphview.c)745
-rw-r--r--src/gtkext/gtkgraphdisplay.h64
-rw-r--r--src/gtkext/gtkgraphview.h64
-rw-r--r--src/gtkext/gtksourceview.c156
-rw-r--r--src/gtkext/gtksourceview.h56
-rw-r--r--src/gui/dialogs/export.c11
-rw-r--r--src/gui/dialogs/gotox.c3
-rw-r--r--src/gui/editem-int.h1
-rw-r--r--src/gui/editem.c11
-rw-r--r--src/gui/editor.c6
-rw-r--r--src/gui/menus/edition.c1
-rw-r--r--src/gui/menus/view.c75
-rw-r--r--src/gui/status.c15
-rw-r--r--src/gui/tb/Makefile.am1
-rw-r--r--src/gui/tb/source.c321
-rw-r--r--src/gui/tb/source.h56
-rw-r--r--src/plugins/plugin.h1
110 files changed, 6727 insertions, 5018 deletions
diff --git a/ChangeLog b/ChangeLog
index 68ece4c..3130325 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,223 @@
+16-12-30 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Extend AC_CONFIG_COMMANDS. Add the new Makefiles from the
+ 'src/analysis/human', 'src/analysis/human/asm' and
+ 'src/glibext/generators' directories.
+
+ * plugins/Makefile.am:
+ Remove the 'androhelpers' plugin from the compilation process.
+
+ * plugins/pychrysa/analysis/binary.c:
+ Move from buffer to cache.
+
+ * plugins/pychrysa/glibext/Makefile.am:
+ Replace 'codebuffer.[ch]' by 'buffercache.[ch]' in
+ libpychrysaglibext_la_SOURCES.
+
+ * plugins/pychrysa/glibext/buffercache.c:
+ * plugins/pychrysa/glibext/buffercache.h:
+ * plugins/pychrysa/glibext/codebuffer.c:
+ * plugins/pychrysa/glibext/codebuffer.h:
+ Renamed entries.
+
+ * plugins/pychrysa/glibext/module.c:
+ Update code.
+
+ * plugins/pychrysa/gtkext/Makefile.am:
+ Replace 'blockview.[ch]' by 'blockdisplay.[ch]' and 'bufferview.[ch]'
+ by 'bufferdisplay.[ch]' in libpychrysagtkext_la_SOURCES.
+
+ * plugins/pychrysa/gtkext/blockdisplay.c:
+ * plugins/pychrysa/gtkext/blockdisplay.h:
+ * plugins/pychrysa/gtkext/blockview.c:
+ * plugins/pychrysa/gtkext/blockview.h:
+ * plugins/pychrysa/gtkext/bufferdisplay.c:
+ * plugins/pychrysa/gtkext/bufferdisplay.h:
+ * plugins/pychrysa/gtkext/bufferview.c:
+ * plugins/pychrysa/gtkext/bufferview.h:
+ Renamed entries.
+
+ * plugins/pychrysa/gtkext/module.c:
+ Update code.
+
+ * plugins/ropgadgets/select.c:
+ Print lines using the new generation interface.
+
+ * src/analysis/Makefile.am:
+ Add 'human/libanalysishuman.la' to libanalysis_la_LIBADD and 'human'
+ to SUBDIRS.
+
+ * src/analysis/binary.c:
+ * src/analysis/binary.h:
+ Move from buffer to cache. Remove the source view.
+
+ * src/analysis/content.c:
+ Typo.
+
+ * src/analysis/db/items/bookmark.c:
+ Disable the item action.
+
+ * src/analysis/db/items/comment.c:
+ * src/analysis/db/items/comment.h:
+ Print comments using the new generation interface.
+
+ * src/analysis/db/items/move.h:
+ Typo.
+
+ * src/analysis/db/items/switcher.c:
+ Disable the item action.
+
+ * src/analysis/disass/area.h:
+ * src/analysis/disass/disassembler.c:
+ * src/analysis/disass/disassembler.h:
+ * src/analysis/disass/output.c:
+ * src/analysis/disass/output.h:
+ Use the new defined generators and update the code.
+
+ * src/analysis/human/Makefile.am:
+ * src/analysis/human/asm/Makefile.am:
+ * src/analysis/human/asm/lang.c:
+ * src/analysis/human/asm/lang.h:
+ * src/analysis/human/lang-int.h:
+ * src/analysis/human/lang.c:
+ * src/analysis/human/lang.h:
+ New entries: prepare ASM-like comments.
+
+ * src/analysis/project.c:
+ Update code and remove the source view.
+
+ * src/arch/dalvik/link.c:
+ Fix code to build local comments.
+
+ * src/arch/instruction-int.h:
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ * src/arch/raw.c:
+ * src/arch/undefined.c:
+ Define instructions as generators.
+
+ * src/arch/vmpa.h:
+ Create is_invalid_vmpa().
+
+ * src/format/dex/dex.c:
+ * src/format/dex/pool.h:
+ * src/format/dwarf/v2/dwarf.h:
+ * src/format/dwarf/v3/dwarf.h:
+ * src/format/dwarf/v4/dwarf.h:
+ * src/format/elf/symbols.h:
+ * src/format/format-int.h:
+ * src/format/java/java.h:
+ * src/format/pe/pe.h:
+ Update code.
+
+ * src/format/symbol.c:
+ * src/format/symbol.h:
+ Define symbols as generators.
+
+ * src/glibext/Makefile.am:
+ Replace 'gcodebuffer.[ch]' by 'gbuffercache.[ch]' and add 'linegen*[ch]'
+ in libglibext_la_SOURCES. Add 'generators/libglibextgenerators.la' to
+ libglibext_la_LIBADD and 'generators' to SUBDIRS.
+
+ * src/glibext/gbinportion.c:
+ * src/glibext/gbinportion.h:
+ Define portions as generators.
+
+ * src/glibext/gbuffercache.c:
+ * src/glibext/gbuffercache.h:
+ Renamed entries.
+
+ * src/glibext/gbufferline.c:
+ * src/glibext/gbufferline.h:
+ Update code.
+
+ * src/glibext/gbufferview.c:
+ * src/glibext/gbufferview.h:
+ Rewrite the line buffers using generators and on-demand building to save
+ memory.
+
+ * src/glibext/gcodebuffer.c:
+ * src/glibext/gcodebuffer.h:
+ Renamed entries.
+
+ * src/glibext/generator-int.h:
+ * src/glibext/generators/Makefile.am:
+ * src/glibext/generators/prologue.c:
+ * src/glibext/generators/prologue.h:
+ * src/glibext/generators/rborder.c:
+ * src/glibext/generators/rborder.h:
+ New entries: provide some useful basic generators.
+
+ * src/glibext/gwidthtracker.c:
+ * src/glibext/gwidthtracker.h:
+ Update code.
+
+ * src/glibext/linecolumn.c:
+ Improve one assertion.
+
+ * src/glibext/linegen-int.h:
+ * src/glibext/linegen.c:
+ * src/glibext/linegen.h:
+ New entries: define an interface to deal with line content.
+
+ * src/glibext/linesegment.c:
+ * src/glibext/linesegment.h:
+ Extend CSS definitions.
+
+ * src/gtkext/Makefile.am:
+ Update libgtkext_la_SOURCES.
+
+ * src/gtkext/graph/cluster.c:
+ * src/gtkext/graph/cluster.h:
+ * src/gtkext/graph/edge.c:
+ * src/gtkext/graph/edge.h:
+ Update code.
+
+ * src/gtkext/gtkblockdisplay.c:
+ * src/gtkext/gtkblockdisplay.h:
+ * src/gtkext/gtkblockview.c:
+ * src/gtkext/gtkblockview.h:
+ * src/gtkext/gtkbufferdisplay-int.h:
+ * src/gtkext/gtkbufferdisplay.c:
+ * src/gtkext/gtkbufferdisplay.h:
+ * src/gtkext/gtkbufferview-int.h:
+ * src/gtkext/gtkbufferview.c:
+ * src/gtkext/gtkbufferview.h:
+ * src/gtkext/gtkdisplaypanel-int.h:
+ * src/gtkext/gtkdisplaypanel.c:
+ * src/gtkext/gtkgraphdisplay.c:
+ * src/gtkext/gtkgraphdisplay.h:
+ * src/gtkext/gtkgraphview.c:
+ * src/gtkext/gtkgraphview.h:
+ Renamed entries.
+
+ * src/gtkext/gtksourceview.c:
+ * src/gtkext/gtksourceview.h:
+ Deleted entries.
+
+ * src/gui/dialogs/export.c:
+ * src/gui/dialogs/gotox.c:
+ Disable code.
+
+ * src/gui/editem-int.h:
+ * src/gui/editem.c:
+ * src/gui/editor.c:
+ * src/gui/menus/edition.c:
+ * src/gui/menus/view.c:
+ * src/gui/status.c:
+ Update code.
+
+ * src/gui/tb/Makefile.am:
+ Remove 'source.[ch]' from libguitb_la_SOURCES.
+
+ * src/gui/tb/source.c:
+ * src/gui/tb/source.h:
+ Deleted entries.
+
+ * src/plugins/plugin.h:
+ Update code.
+
16-12-29 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/disass/limit.c:
diff --git a/configure.ac b/configure.ac
index d6a96b7..04be709 100644
--- a/configure.ac
+++ b/configure.ac
@@ -309,7 +309,7 @@ AC_SUBST(LIBPYGOBJECT_LIBS)
AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,ULONG,ULONG" > src/glibext/chrysamarshal.list])
AC_CONFIG_FILES([Makefile
pixmaps/Makefile
@@ -355,6 +355,8 @@ AC_CONFIG_FILES([Makefile
src/analysis/db/misc/Makefile
src/analysis/decomp/Makefile
src/analysis/disass/Makefile
+ src/analysis/human/Makefile
+ src/analysis/human/asm/Makefile
src/analysis/types/Makefile
src/arch/Makefile
src/arch/arm/Makefile
@@ -393,6 +395,7 @@ AC_CONFIG_FILES([Makefile
src/format/mangling/itanium/Makefile
src/format/pe/Makefile
src/glibext/Makefile
+ src/glibext/generators/Makefile
src/gtkext/Makefile
src/gtkext/graph/Makefile
src/gui/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 0500b07..9b5cd17 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -3,4 +3,5 @@ if HAVE_PYTHON3_CONFIG
PYTHON3_SUBDIRS = pychrysa python
endif
-SUBDIRS = androhelpers devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets stackvars
+# androhelpers
+SUBDIRS = devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets stackvars
diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c
index 32e4a71..5b857d5 100644
--- a/plugins/pychrysa/analysis/binary.c
+++ b/plugins/pychrysa/analysis/binary.c
@@ -55,7 +55,7 @@ static PyObject *py_loaded_binary_get_format(PyObject *, void *);
static PyObject *py_loaded_binary_get_processor(PyObject *, void *);
/* Fournit le tampon associé au contenu assembleur d'un binaire. */
-static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *);
+static PyObject *py_loaded_binary_get_disassembled_cache(PyObject *, void *);
@@ -234,16 +234,18 @@ static PyObject *py_loaded_binary_get_processor(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void *closure)
+static PyObject *py_loaded_binary_get_disassembled_cache(PyObject *self, void *closure)
{
PyObject *result; /* Trouvailles à retourner */
GLoadedBinary *binary; /* Version native */
- GCodeBuffer *buffer; /* Tampon à récupérer */
+ GBufferCache *cache; /* Tampon à récupérer */
binary = G_LOADED_BINARY(pygobject_get(self));
- buffer = g_loaded_binary_get_disassembled_buffer(binary);
+ cache = g_loaded_binary_get_disassembled_cache(binary);
- result = pygobject_new(G_OBJECT(buffer));
+ result = pygobject_new(G_OBJECT(cache));
+
+ g_object_unref(G_OBJECT(cache));
return result;
@@ -288,8 +290,8 @@ PyTypeObject *get_python_loaded_binary_type(void)
"Handler for the current binary processor.", NULL
},
{
- "disassembled_buffer", py_loaded_binary_get_disassembled_buffer, NULL,
- "Disassembled code buffer.", NULL
+ "disassembled_cache", py_loaded_binary_get_disassembled_cache, NULL,
+ "Disassembled buffer cache.", NULL
},
{ NULL }
};
diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am
index 74def8a..b53f4b0 100644
--- a/plugins/pychrysa/glibext/Makefile.am
+++ b/plugins/pychrysa/glibext/Makefile.am
@@ -2,8 +2,8 @@
noinst_LTLIBRARIES = libpychrysaglibext.la
libpychrysaglibext_la_SOURCES = \
+ buffercache.h buffercache.c \
bufferline.h bufferline.c \
- codebuffer.h codebuffer.c \
configuration.h configuration.c \
module.h module.c
diff --git a/plugins/pychrysa/glibext/codebuffer.c b/plugins/pychrysa/glibext/buffercache.c
index 7ca9435..c79fda2 100644
--- a/plugins/pychrysa/glibext/codebuffer.c
+++ b/plugins/pychrysa/glibext/buffercache.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * codebuffer.c - équivalent Python du fichier "glibext/gcodebuffer.h"
+ * buffercache.c - équivalent Python du fichier "glibext/gbuffercache.h"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,13 +22,13 @@
*/
-#include "codebuffer.h"
+#include "buffercache.h"
#include <pygobject.h>
-#include <glibext/gcodebuffer.h>
+#include <glibext/gbuffercache.h>
#include "../arch/vmpa.h"
@@ -36,6 +36,7 @@
+#if 0
/* Retrouve une ligne au sein d'un tampon avec une adresse. */
static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *);
@@ -60,7 +61,7 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args
PyObject *py_vmpa; /* Localisation version Python */
int ret; /* Bilan de lecture des args. */
vmpa2t *addr; /* Adresse visée par l'opérat° */
- GCodeBuffer *buffer; /* Version native */
+ GBuffercache *buffer; /* Version native */
GBufferLine *line; /* Ligne trouvée */
ret = PyArg_ParseTuple(args, "O", &py_vmpa);
@@ -82,6 +83,7 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args
return result;
}
+#endif
/******************************************************************************
@@ -96,38 +98,40 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args
* *
******************************************************************************/
-PyTypeObject *get_python_code_buffer_type(void)
+PyTypeObject *get_python_buffer_cache_type(void)
{
- static PyMethodDef py_code_buffer_methods[] = {
+ static PyMethodDef py_buffer_cache_methods[] = {
+#if 0
{
- "find_line_by_addr", (PyCFunction)py_code_buffer_find_line_by_addr,
+ "find_line_by_addr", (PyCFunction)py_buffer_cache_find_line_by_addr,
METH_VARARGS,
"find_line_by_addr($self, addr, /)\n--\n\nFind a buffer line with a given address."
},
+#endif
{ NULL }
};
- static PyGetSetDef py_code_buffer_getseters[] = {
+ static PyGetSetDef py_buffer_cache_getseters[] = {
{ NULL }
};
- static PyTypeObject py_code_buffer_type = {
+ static PyTypeObject py_buffer_cache_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.glibext.CodeBuffer",
+ .tp_name = "pychrysalide.glibext.Buffercache",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "PyChrysalide code buffer",
- .tp_methods = py_code_buffer_methods,
- .tp_getset = py_code_buffer_getseters,
+ .tp_methods = py_buffer_cache_methods,
+ .tp_getset = py_buffer_cache_getseters,
};
- return &py_code_buffer_type;
+ return &py_buffer_cache_type;
}
@@ -136,7 +140,7 @@ PyTypeObject *get_python_code_buffer_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.BufferCache'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -144,16 +148,16 @@ PyTypeObject *get_python_code_buffer_type(void)
* *
******************************************************************************/
-bool register_python_code_buffer(PyObject *module)
+bool register_python_buffer_cache(PyObject *module)
{
- PyTypeObject *py_code_buffer_type; /* Type Python 'CodeBuffer' */
+ PyTypeObject *py_buffer_cache_type; /* Type Python 'BufferCache' */
PyObject *dict; /* Dictionnaire du module */
- py_code_buffer_type = get_python_code_buffer_type();
+ py_buffer_cache_type = get_python_buffer_cache_type();
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_CODE_BUFFER, py_code_buffer_type, &PyGObject_Type))
+ if (!register_class_for_pygobject(dict, G_TYPE_BUFFER_CACHE, py_buffer_cache_type, &PyGObject_Type))
return false;
return true;
diff --git a/plugins/pychrysa/glibext/codebuffer.h b/plugins/pychrysa/glibext/buffercache.h
index e806e36..6476f5f 100644
--- a/plugins/pychrysa/glibext/codebuffer.h
+++ b/plugins/pychrysa/glibext/buffercache.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * codebuffer.h - prototypes pour l'équivalent Python du fichier "glibext/codebuffer.h"
+ * buffercache.h - prototypes pour l'équivalent Python du fichier "glibext/buffercache.h"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H
-#define _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H
+#ifndef _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H
+#define _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H
#include <Python.h>
@@ -32,11 +32,11 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_code_buffer_type(void);
+PyTypeObject *get_python_buffer_cache_type(void);
/* Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. */
-bool register_python_code_buffer(PyObject *);
+bool register_python_buffer_cache(PyObject *);
-#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H */
+#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H */
diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c
index 2306c44..847e6d6 100644
--- a/plugins/pychrysa/glibext/module.c
+++ b/plugins/pychrysa/glibext/module.c
@@ -28,8 +28,8 @@
#include <assert.h>
+#include "buffercache.h"
#include "bufferline.h"
-#include "codebuffer.h"
#include "configuration.h"
@@ -80,8 +80,8 @@ bool add_glibext_module_to_python_module(PyObject *super)
result = true;
+ result &= register_python_buffer_cache(module);
result &= register_python_buffer_line(module);
- result &= register_python_code_buffer(module);
result &= register_python_config_param(module);
result &= register_python_config_param_iterator(module);
result &= register_python_generic_config(module);
diff --git a/plugins/pychrysa/gtkext/Makefile.am b/plugins/pychrysa/gtkext/Makefile.am
index e7303e8..fee2032 100644
--- a/plugins/pychrysa/gtkext/Makefile.am
+++ b/plugins/pychrysa/gtkext/Makefile.am
@@ -2,8 +2,8 @@
noinst_LTLIBRARIES = libpychrysagtkext.la
libpychrysagtkext_la_SOURCES = \
- blockview.h blockview.c \
- bufferview.h bufferview.c \
+ blockdisplay.h blockdisplay.c \
+ bufferdisplay.h bufferdisplay.c \
displaypanel.h displaypanel.c \
module.h module.c
diff --git a/plugins/pychrysa/gtkext/blockview.c b/plugins/pychrysa/gtkext/blockdisplay.c
index 73095b2..8262aa7 100644
--- a/plugins/pychrysa/gtkext/blockview.c
+++ b/plugins/pychrysa/gtkext/blockdisplay.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * blockview.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockview.c"
+ * blockdisplay.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockdisplay.c"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,16 +22,16 @@
*/
-#include "blockview.h"
+#include "blockdisplay.h"
#include <pygobject.h>
-#include <gtkext/gtkblockview.h>
+#include <gtkext/gtkblockdisplay.h>
-#include "bufferview.h"
+#include "bufferdisplay.h"
#include "../helpers.h"
@@ -48,33 +48,33 @@
* *
******************************************************************************/
-PyTypeObject *get_python_block_view_type(void)
+PyTypeObject *get_python_block_display_type(void)
{
- static PyMethodDef py_block_view_methods[] = {
+ static PyMethodDef py_block_display_methods[] = {
{ NULL }
};
- static PyGetSetDef py_block_view_getseters[] = {
+ static PyGetSetDef py_block_display_getseters[] = {
{ NULL }
};
- static PyTypeObject py_block_view_type = {
+ static PyTypeObject py_block_display_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.gtkext.BlockView",
+ .tp_name = "pychrysalide.gtkext.BlockDisplay",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "PyChrysalide block view.",
+ .tp_doc = "PyChrysalide block display.",
- .tp_methods = py_block_view_methods,
- .tp_getset = py_block_view_getseters
+ .tp_methods = py_block_display_methods,
+ .tp_getset = py_block_display_getseters
};
- return &py_block_view_type;
+ return &py_block_display_type;
}
@@ -83,7 +83,7 @@ PyTypeObject *get_python_block_view_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.gtkext.BlockView'. *
+* Description : Prend en charge l'objet 'pychrysalide.gtkext.BlockDisplay'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -91,16 +91,17 @@ PyTypeObject *get_python_block_view_type(void)
* *
******************************************************************************/
-bool register_python_block_view(PyObject *module)
+bool register_python_block_display(PyObject *module)
{
- PyTypeObject *py_block_view_type; /* Type Python 'BlockView' */
+ PyTypeObject *py_block_display_type; /* Type Python 'BlockDisplay' */
PyObject *dict; /* Dictionnaire du module */
- py_block_view_type = get_python_block_view_type();
+ py_block_display_type = get_python_block_display_type();
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, GTK_TYPE_BLOCK_VIEW, py_block_view_type, get_python_buffer_view_type()))
+ if (!register_class_for_pygobject(dict, GTK_TYPE_BLOCK_DISPLAY,
+ py_block_display_type, get_python_buffer_display_type()))
return false;
return true;
diff --git a/plugins/pychrysa/gtkext/bufferview.h b/plugins/pychrysa/gtkext/blockdisplay.h
index d4a1581..1a45e15 100644
--- a/plugins/pychrysa/gtkext/bufferview.h
+++ b/plugins/pychrysa/gtkext/blockdisplay.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * bufferview.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferview.h"
+ * blockdisplay.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockdisplay.h"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H
-#define _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H
+#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H
#include <Python.h>
@@ -32,11 +32,11 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_buffer_view_type(void);
+PyTypeObject *get_python_block_display_type(void);
-/* Prend en charge l'objet 'pychrysalide.gtkext.Bufferview'. */
-bool register_python_buffer_view(PyObject *module);
+/* Prend en charge l'objet 'pychrysalide.gtkext.BlockDisplay'. */
+bool register_python_block_display(PyObject *module);
-#endif /* _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H */
+#endif /* _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H */
diff --git a/plugins/pychrysa/gtkext/bufferview.c b/plugins/pychrysa/gtkext/bufferdisplay.c
index 3be54fd..d26d9d9 100644
--- a/plugins/pychrysa/gtkext/bufferview.c
+++ b/plugins/pychrysa/gtkext/bufferdisplay.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * bufferview.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferview.c"
+ * bufferdisplay.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferdisplay.c"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,13 +22,13 @@
*/
-#include "bufferview.h"
+#include "bufferdisplay.h"
#include <pygobject.h>
-#include <gtkext/gtkbufferview.h>
+#include <gtkext/gtkbufferdisplay.h>
#include "displaypanel.h"
@@ -48,33 +48,33 @@
* *
******************************************************************************/
-PyTypeObject *get_python_buffer_view_type(void)
+PyTypeObject *get_python_buffer_display_type(void)
{
- static PyMethodDef py_buffer_view_methods[] = {
+ static PyMethodDef py_buffer_display_methods[] = {
{ NULL }
};
- static PyGetSetDef py_buffer_view_getseters[] = {
+ static PyGetSetDef py_buffer_display_getseters[] = {
{ NULL }
};
- static PyTypeObject py_buffer_view_type = {
+ static PyTypeObject py_buffer_display_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.gtkext.Bufferview",
+ .tp_name = "pychrysalide.gtkext.BufferDisplay",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "PyChrysalide buffer view.",
+ .tp_doc = "PyChrysalide buffer display.",
- .tp_methods = py_buffer_view_methods,
- .tp_getset = py_buffer_view_getseters
+ .tp_methods = py_buffer_display_methods,
+ .tp_getset = py_buffer_display_getseters
};
- return &py_buffer_view_type;
+ return &py_buffer_display_type;
}
@@ -83,7 +83,7 @@ PyTypeObject *get_python_buffer_view_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.gtkext.Bufferview'. *
+* Description : Prend en charge l'objet 'pychrysalide.gtkext.Bufferdisplay'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -91,16 +91,17 @@ PyTypeObject *get_python_buffer_view_type(void)
* *
******************************************************************************/
-bool register_python_buffer_view(PyObject *module)
+bool register_python_buffer_display(PyObject *module)
{
- PyTypeObject *py_buffer_view_type; /* Type Python 'Bufferview' */
+ PyTypeObject *py_buffer_display_type; /* Type Python 'Bufferdisplay' */
PyObject *dict; /* Dictionnaire du module */
- py_buffer_view_type = get_python_buffer_view_type();
+ py_buffer_display_type = get_python_buffer_display_type();
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, GTK_TYPE_BUFFER_VIEW, py_buffer_view_type, get_python_display_panel_type()))
+ if (!register_class_for_pygobject(dict, GTK_TYPE_BUFFER_DISPLAY,
+ py_buffer_display_type, get_python_display_panel_type()))
return false;
return true;
diff --git a/plugins/pychrysa/gtkext/blockview.h b/plugins/pychrysa/gtkext/bufferdisplay.h
index acb97a9..332f402 100644
--- a/plugins/pychrysa/gtkext/blockview.h
+++ b/plugins/pychrysa/gtkext/bufferdisplay.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * blockview.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockview.h"
+ * bufferdisplay.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferdisplay.h"
*
* Copyright (C) 2012 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H
-#define _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H
+#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H
#include <Python.h>
@@ -32,11 +32,11 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_block_view_type(void);
+PyTypeObject *get_python_buffer_display_type(void);
-/* Prend en charge l'objet 'pychrysalide.gtkext.BlockView'. */
-bool register_python_block_view(PyObject *module);
+/* Prend en charge l'objet 'pychrysalide.gtkext.BufferDisplay'. */
+bool register_python_buffer_display(PyObject *module);
-#endif /* _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H */
+#endif /* _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H */
diff --git a/plugins/pychrysa/gtkext/module.c b/plugins/pychrysa/gtkext/module.c
index 2230ed0..d826814 100644
--- a/plugins/pychrysa/gtkext/module.c
+++ b/plugins/pychrysa/gtkext/module.c
@@ -28,8 +28,8 @@
#include <assert.h>
-#include "blockview.h"
-#include "bufferview.h"
+#include "blockdisplay.h"
+#include "bufferdisplay.h"
#include "displaypanel.h"
@@ -81,8 +81,8 @@ bool add_gtkext_module_to_python_module(PyObject *super)
result = true;
result &= register_python_display_panel(module);
- result &= register_python_buffer_view(module);
- result &= register_python_block_view(module);
+ result &= register_python_buffer_display(module);
+ result &= register_python_block_display(module);
agmtpm_exit:
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index 881cd39..0fedfb1 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -1746,11 +1746,7 @@ static gboolean filter_visible_rop_gadgets(GtkTreeModel *model, GtkTreeIter *ite
static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, GArchInstruction **gadgets, size_t count)
{
- const char *target; /* Sous-traitance requise */
- GArchProcessor *proc; /* Architecture du binaire */
- MemoryDataSize msize; /* Taille du bus d'adresses */
const GBinContent *content; /* Contenu binaire global */
- GCodeBuffer *buffer; /* Tampon de rassemblement */
size_t i; /* Boucle de parcours */
GArchInstruction *instr; /* Elément de liste de gadgets */
GBufferLine *line; /* Ligne présente à l'adresse */
@@ -1762,21 +1758,10 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
char *content_markup; /* Contenu assemblé de chaîne */
GtkTreeIter iter; /* Point d'insertion */
- /* Définition de l'écosystème nécessaire */
-
- target = g_exe_format_get_target_machine(format);
- proc = get_arch_processor_for_type(target);
-
- msize = g_arch_processor_get_memory_size(proc);
-
- g_object_unref(G_OBJECT(proc));
-
content = g_binary_format_get_content(G_BIN_FORMAT(format));
/* Conversion en contenu textuel */
- buffer = g_code_buffer_new(BLC_ASSEMBLY);
-
for (i = 0; i < count; i++)
{
/* Parcours des différentes lignes */
@@ -1788,8 +1773,8 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
for (instr = gadgets[i]; instr != NULL; instr = g_arch_instruction_get_next_iter(gadgets[i], instr, ~0))
{
- line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL);
- if (line == NULL) continue;
+ line = g_buffer_line_new(NULL, BLC_ASSEMBLY);
+ g_line_generator_print(G_LINE_GENERATOR(instr), line, -1, 0);
if (instr == gadgets[i])
{
@@ -1800,6 +1785,8 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
partial_raw = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, false);
partial_markup = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
+ g_object_unref(G_OBJECT(line));
+
if (content_raw != NULL)
content_raw = stradd(content_raw, " ; ");
@@ -1836,8 +1823,6 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
}
- g_object_unref(G_OBJECT(buffer));
-
g_object_unref(G_OBJECT(content));
/* Rajout de la catégorie et filtre au besoin */
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index 8b346f9..a8b1538 100755
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -20,6 +20,7 @@ libanalysis_la_LIBADD = \
db/libanalysisdb.la \
db/libanalysiskeys.la \
disass/libanalysisdisass.la \
+ human/libanalysishuman.la \
types/libanalysistypes.la
# decomp/libanalysisdecomp.la
@@ -31,4 +32,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = blocks contents db disass types
+SUBDIRS = blocks contents db disass human types
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 3af62cf..ac8863e 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -37,7 +37,7 @@
#include "routine.h"
#include "db/client.h"
-#include "decomp/decompiler.h"
+//#include "decomp/decompiler.h"
#include "disass/disassembler.h"
#include "../common/extstr.h"
#include "../common/cpp.h"
@@ -78,8 +78,9 @@ struct _GLoadedBinary
GDbgFormat *debug; /* Informations de débogage */ //// REMME
GArchProcessor *proc; /* Architecture du binaire */
- GCodeBuffer *disass_buffer; /* Instructions lisibles */
- GCodeBuffer **dec_buffers; /* Sources sous forme de texte */
+
+ GBufferCache *disass_cache; /* Instructions lisibles */
+ //GCodeBuffer **dec_buffers; /* Sources sous forme de texte */
size_t decbuf_count; /* Taille des tableaux */
size_t defsrc; /* Fichier source principal */
@@ -220,9 +221,6 @@ static void g_loaded_binary_init(GLoadedBinary *binary)
binary->col_display[BVW_GRAPH][BLC_PHYSICAL] = false;
binary->col_display[BVW_GRAPH][BLC_VIRTUAL] = false;
binary->col_display[BVW_GRAPH][BLC_BINARY] = false;
- binary->col_display[BVW_SOURCE][BLC_PHYSICAL] = false;
- binary->col_display[BVW_SOURCE][BLC_VIRTUAL] = false;
- binary->col_display[BVW_SOURCE][BLC_BINARY] = false;
binary->lines_display = true;
@@ -1377,7 +1375,7 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
g_loaded_binary_connect_internal(binary);
- disassemble_binary(binary, &binary->disass_buffer, ack_completed_disassembly);
+ disassemble_binary(binary, &binary->disass_cache, ack_completed_disassembly);
@@ -1508,9 +1506,16 @@ GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *binary)
* *
******************************************************************************/
-GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary)
+GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *binary)
{
- return binary->disass_buffer;
+ GBufferCache *result; /* Instance à retourner */
+
+ result = binary->disass_cache;
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
}
@@ -1527,7 +1532,7 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
* Remarques : - *
* *
******************************************************************************/
-
+#if 0
GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary, size_t index)
{
GCodeBuffer *result; /* Tampon à retourner */
@@ -1544,6 +1549,7 @@ GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary,
return result;
}
+#endif
/******************************************************************************
@@ -1659,6 +1665,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar
files = g_binary_format_get_source_files(G_BIN_FORMAT(binary->format),
&binary->decbuf_count, &binary->defsrc);
+#if 0
if (binary->decbuf_count > 0)
{
binary->dec_buffers = (GCodeBuffer **)calloc(binary->decbuf_count, sizeof(GCodeBuffer *));
@@ -1668,7 +1675,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar
binary->dec_buffers[i] = decompile_all_from_file(binary, files[i]);
*/
}
-
+#endif
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 41c7f7a..501ffe6 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -36,7 +36,7 @@
#include "../common/xml.h"
#include "../format/debuggable.h"
#include "../format/executable.h"
-#include "../glibext/gcodebuffer.h"
+#include "../glibext/gbuffercache.h"
@@ -76,7 +76,6 @@ typedef enum _BinaryView
{
BVW_BLOCK, /* Version basique */
BVW_GRAPH, /* Affichage en graphique */
- BVW_SOURCE, /* Code décompilé */
BVW_COUNT
@@ -181,10 +180,10 @@ GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *);
GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *);
/* Fournit le tampon associé au contenu assembleur d'un binaire. */
-GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *);
+GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *);
/* Fournit le tampon associé au contenu d'un fichier source. */
-GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
+//GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
/* Définit si une colonne donnée doit apparaître dans le rendu. */
void g_loaded_binary_set_column_display(GLoadedBinary *, BinaryView, BufferLineColumn, bool);
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 484599f..09f293c 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -47,7 +47,7 @@ G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT)
/******************************************************************************
* *
-* Paramètres : iface = interface GTK à initialiser. *
+* Paramètres : iface = interface GLib à initialiser. *
* *
* Description : Procède à l'initialisation de l'interface de rassemblement. *
* *
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 086b9f2..18e4bb5 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -409,6 +409,8 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark)
static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool *prev, bool set)
{
+ return false;
+#if 0
bool result; /* Bilan à faire remonter */
GCodeBuffer *buffer; /* Tampon de lignes à traiter */
GBufferLine *line; /* Ligne de tampon à marquer */
@@ -437,7 +439,7 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool
exit:
return result;
-
+#endif
}
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 55893d1..3517f38 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -35,7 +35,10 @@
#include "../collection-int.h"
#include "../item-int.h"
+#include "../../human/asm/lang.h"
#include "../../../common/io.h"
+#include "../../../common/extstr.h"
+#include "../../../glibext/linegen-int.h"
@@ -52,6 +55,9 @@ struct _GDbComment
rle_string text; /* Contenu du commentaire */
+ char **lines; /* Lignes brutes à représenter */
+ size_t count; /* Quantité de ces lignes */
+
bool inlined; /* Intégration dans une ligne ?*/
union
@@ -60,7 +66,9 @@ struct _GDbComment
bool before; /* Zone dédiée au dessus ? */
};
- GDbComment **oldies; /* Commentaires d'origine ? */
+ GLineGenerator *previous; /* Commentaire remplacé */
+
+ GLineGenerator **old_inlined; /* Commentaires d'origine ? */
size_t old_count; /* Nombre de places à restaurer*/
};
@@ -112,6 +120,29 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **
/* Charge les valeurs utiles pour un commentaire. */
static bool g_db_comment_load(GDbComment *, const bound_value *, size_t);
+/* Définit le commentaire associé à un commentaire. */
+static void g_db_comment_set_text(GDbComment *, const char *);
+
+
+
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_db_comment_count_lines(const GDbComment *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_db_comment_compute_addr(const GDbComment *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_db_comment_contains_addr(const GDbComment *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_db_comment_get_flags(const GDbComment *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_db_comment_print(GDbComment *, GBufferLine *, size_t, size_t);
+
/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
@@ -138,6 +169,9 @@ static void g_comment_collection_class_init(GCommentCollectionClass *);
/* Initialise un commentaire sous forme de zone de texte. */
static void g_comment_collection_init(GCommentCollection *);
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_db_comment_interface_init(GLineGeneratorInterface *);
+
/* Supprime toutes les références externes. */
static void g_comment_collection_dispose(GCommentCollection *);
@@ -161,7 +195,8 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *, va_list);
/* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
-G_DEFINE_TYPE(GDbComment, g_db_comment, G_TYPE_DB_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GDbComment, g_db_comment, G_TYPE_DB_ITEM,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_db_comment_interface_init));
/******************************************************************************
@@ -219,6 +254,31 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
static void g_db_comment_init(GDbComment *comment)
{
+ comment->lines = NULL;
+ comment->count = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_db_comment_count_lines;
+ iface->compute = (linegen_compute_fc)g_db_comment_compute_addr;
+ iface->contains = (linegen_contains_fc)g_db_comment_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags;
+ iface->print = (linegen_print_fc)g_db_comment_print;
}
@@ -239,11 +299,17 @@ static void g_db_comment_dispose(GDbComment *comment)
{
size_t i; /* Boucle de parcours */
+ for (i = 0; i < comment->count; i++)
+ free(comment->lines[i]);
+
+ if (comment->lines != NULL)
+ free(comment->lines);
+
for (i = 0; i < comment->old_count; i++)
- g_object_unref(G_OBJECT(comment->oldies[i]));
+ g_object_unref(G_OBJECT(comment->old_inlined[i]));
- if (comment->oldies != NULL)
- free(comment->oldies);
+ if (comment->old_inlined != NULL)
+ free(comment->old_inlined);
G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
@@ -516,6 +582,134 @@ static void g_db_comment_build_label(GDbComment *comment)
static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool apply)
{
bool result; /* Bilan à faire remonter */
+ GBufferCache *cache; /* Ensemble de lignes à traiter*/
+ size_t index; /* Point d'insertion */
+ GArchProcessor *proc; /* Propriétaire d'instructions */
+ GArchInstruction *instr; /* Instruction à traiter */
+ instr_link_t *sources; /* Instructions diverses liées */
+ size_t scount; /* Nbre de sources affichées */
+ size_t i; /* Boucle de parcours */
+ const mrange_t *range; /* Emplacement d'instruction */
+ size_t linked; /* Indice lié à traiter */
+
+ result = true;
+
+ cache = g_loaded_binary_get_disassembled_cache(binary);
+
+ index = g_buffer_cache_find_index_by_addr(cache, &comment->addr, true);
+
+ index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+
+ if (comment->inlined)
+ {
+
+#define RUN_INLINED_COMMENT(idx, new, old) \
+ if (apply) \
+ { \
+ old = g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \
+ \
+ g_buffer_cache_insert_at(cache, idx, G_LINE_GENERATOR(new), false, false); \
+ \
+ } \
+ else \
+ { \
+ g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \
+ \
+ if (old != NULL) \
+ { \
+ g_buffer_cache_insert_at(cache, idx, old, false, false); \
+ g_object_unref(G_OBJECT(old)); \
+ } \
+ \
+ }
+
+ /* Commentaire principal */
+
+ RUN_INLINED_COMMENT(index, comment, comment->previous);
+
+ /* Renvois répétés */
+
+ if (comment->repeatable)
+ {
+ proc = g_loaded_binary_get_processor(binary);
+
+ instr = g_arch_processor_find_instr_by_address(proc, &comment->addr);
+ assert(instr != NULL);
+
+ scount = g_arch_instruction_get_sources(instr, &sources);
+
+ if (apply)
+ {
+ comment->old_count = scount;
+ comment->old_inlined = (GLineGenerator **)realloc(comment->old_inlined,
+ comment->old_count * sizeof(GLineGenerator *));
+ }
+
+ for (i = 0; i < scount && result; i++)
+ {
+ range = g_arch_instruction_get_range(sources[i].linked);
+
+ /**
+ * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL.
+ * Comme on ne peut pas traiter les deux cas, on prend la première qui vient
+ * avec BLF_NONE.
+ */
+
+ linked = g_buffer_cache_find_index_by_addr(cache, get_mrange_addr(range), true);
+ assert(linked != g_buffer_cache_count_lines(cache));
+
+ RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]);
+
+ }
+
+ if (!apply)
+ {
+ free(comment->old_inlined);
+
+ comment->old_inlined = NULL;
+ comment->old_count = 0;
+
+ }
+
+ g_object_unref(G_OBJECT(proc));
+
+ }
+
+
+
+ }
+
+ else
+ {
+
+
+
+
+
+
+
+
+
+ }
+
+
+ //void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
+
+ //GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
+
+
+
+
+ g_object_unref(G_OBJECT(cache));
+
+ return result;
+
+
+
+
+#if 0
+
+ bool result; /* Bilan à faire remonter */
GCodeBuffer *buffer; /* Tampon de lignes à traiter */
GBufferLine *line; /* Ligne de tampon à marquer */
GArchProcessor *proc; /* Propriétaire d'instructions */
@@ -658,7 +852,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
/* TODO g_object_unref(G_OBJECT(buffer));*/
return result;
-
+#endif
}
@@ -884,10 +1078,137 @@ const char *g_db_comment_get_text(const GDbComment *comment)
* *
******************************************************************************/
-void g_db_comment_set_text(GDbComment *comment, const char *text)
+static void g_db_comment_set_text(GDbComment *comment, const char *text)
{
+ GCodingLanguage *lang; /* Langage de sortie préféré */
+
set_rle_string(&comment->text, text);
+ lang = g_asm_language_new();
+
+ comment->lines = strtoka(text, "\n", &comment->count);
+
+ g_coding_language_encapsulate_comments(lang, &comment->lines, &comment->count);
+
+ g_object_unref(G_OBJECT(lang));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OFFRE DE CAPACITES DE GENERATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_db_comment_count_lines(const GDbComment *comment)
+{
+ return comment->count;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ copy_vmpa(addr, &comment->addr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_db_comment_contains_addr(const GDbComment *comment, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ int result; /* Conclusion à retourner */
+
+ result = cmp_vmpa(addr, &comment->addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = générateur à consulter. *
+* 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. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t index, size_t repeat)
+{
+ return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t index, size_t repeat)
+{
+ g_buffer_line_append_text(line, BLC_COMMENTS, SL(comment->lines[repeat]), RTT_COMMENT, NULL);
+
}
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index c5bd335..16046bc 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -69,15 +69,6 @@ const vmpa2t *g_db_comment_get_address(GDbComment *);
/* Fournit le commentaire associé à un commentaire. */
const char *g_db_comment_get_text(const GDbComment *);
-/* Définit le commentaire associé à un commentaire. */
-void g_db_comment_set_text(GDbComment *, const char *);
-
-
-
-
-
-
-
/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
diff --git a/src/analysis/db/items/move.h b/src/analysis/db/items/move.h
index a9d6d8d..115bdc8 100644
--- a/src/analysis/db/items/move.h
+++ b/src/analysis/db/items/move.h
@@ -96,4 +96,4 @@ GMoveCollection *g_move_collection_new(void);
-#endif /* _ANALYSIS_DB_ITEMS_SWITCH_H */
+#endif /* _ANALYSIS_DB_ITEMS_MOVE_H */
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 748c934..3d5841c 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -496,6 +496,9 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher)
static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmOperandDisplay *old, ImmOperandDisplay new)
{
+ return false;
+
+#if 0
bool result; /* Bilan à faire remonter */
GArchProcessor *proc; /* Propriétaire d'instructions */
GArchInstruction *instr; /* Instruction à traiter */
@@ -568,7 +571,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
g_object_unref(G_OBJECT(proc));
return result;
-
+#endif
}
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index d5f910b..155db7c 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -28,6 +28,7 @@
#include "../binary.h"
#include "../../arch/instruction.h"
#include "../../format/symbol.h"
+#include "../../glibext/delayed.h"
#include "../../gtkext/gtkstatusstack.h"
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 5326c36..246a5b2 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -39,11 +39,16 @@
#include "routines.h"
#include "../../format/format.h"
#include "../../glibext/delayed-int.h"
+#include "../../glibext/generators/prologue.h"
#include "../../gui/panels/log.h"
#include "../../plugins/pglist.h"
+#include "../human/asm/lang.h" // TODO : REMME -> format !
+
+
+
/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
@@ -54,8 +59,9 @@ struct _GDelayedDisassembly
GLoadedBinary *binary; /* Destinataire final */
GExeFormat *format; /* Format du binaire représenté*/
+ GCodingLanguage *lang; /* Traduction en ASM préférée */
- GCodeBuffer *buffer; /* Tampon pour le rendu */
+ GBufferCache *cache; /* Tampon pour le rendu */
};
@@ -80,7 +86,7 @@ static void g_delayed_disassembly_dispose(GDelayedDisassembly *);
static void g_delayed_disassembly_finalize(GDelayedDisassembly *);
/* Crée une tâche de désassemblage différé. */
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GCodeBuffer *);
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GBufferCache *);
/* Opère sur toutes les instructions. */
static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *);
@@ -97,7 +103,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack
/* Construit la description d'introduction du désassemblage. */
-static void build_disass_prologue(GCodeBuffer *, const char *, const char *);
+static void build_disass_prologue(GBufferCache *, const GCodingLanguage *, const char *, const char *);
@@ -172,6 +178,7 @@ static void g_delayed_disassembly_init(GDelayedDisassembly *disass)
static void g_delayed_disassembly_dispose(GDelayedDisassembly *disass)
{
g_object_unref(G_OBJECT(disass->format));
+ g_object_unref(G_OBJECT(disass->lang));
G_OBJECT_CLASS(g_delayed_disassembly_parent_class)->dispose(G_OBJECT(disass));
@@ -211,7 +218,7 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass)
* *
******************************************************************************/
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCodeBuffer *buffer)
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GBufferCache *cache)
{
GDelayedDisassembly *result; /* Tâche à retourner */
@@ -219,8 +226,9 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCo
result->binary = binary;
result->format = g_loaded_binary_get_format(binary);
+ result->lang = g_asm_language_new();
- result->buffer = buffer;
+ result->cache = cache;
return result;
@@ -568,7 +576,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
- print_disassembled_instructions(disass->buffer, disass->format, proc, status);
+ print_disassembled_instructions(disass->cache, disass->lang, disass->binary, status);
@@ -612,10 +620,10 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
/******************************************************************************
* *
-* Paramètres : buffer = tampon de destination pour le texte. *
+* Paramètres : cache = tampon de destination pour le texte. *
+* lang = trauducteur pour l'impression finale. *
* filename = nom du fichier ciblé à décompiler. *
-* data = données en mémoire pour l'empreinte. *
-* length = quantité de données à prendre en compte. *
+* checksum = empreinte identifiant le binaire chargé. *
* *
* Description : Construit la description d'introduction du désassemblage. *
* *
@@ -625,96 +633,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
* *
******************************************************************************/
-static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, const char *checksum)
+static void build_disass_prologue(GBufferCache *cache, const GCodingLanguage *lang, const char *filename, const char *checksum)
{
-#if 0
- GLangOutput *output; /* Modèle de sortie adéquat */
- GBufferLine *line; /* Ligne de destination */
- bool managed; /* Groupe déjà défini ? */
- size_t len; /* Taille du texte */
- char *content; /* Contenu textuel d'une ligne */
-
- output = g_asm_output_new();
+ char **text; /* Contenu brute à imprimer */
+ GIntroGenerator *generator; /* Générateur constitué */
- line = g_lang_output_start_comments(output, buffer);
- if (line != NULL)
- {
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
- g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
- g_code_buffer_append_new_line(buffer, line);
-
- }
-
- managed = (line != NULL);
+ text = calloc(4, sizeof(char *));
/* Introduction */
- line = g_lang_output_continue_comments(output, buffer,
- SL(_("Disassembly generated by Chrysalide")));
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
- if (!managed)
- g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_lang_output_continue_comments(output, buffer,
- SL(_("Chrysalide is free software - © 2008-2015 Cyrille Bagard")));
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_lang_output_continue_comments(output, buffer, NULL, 0);
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
- g_code_buffer_append_new_line(buffer, line);
+ text[0] = strdup(_("Disassembly generated by Chrysalide"));
+ text[1] = strdup(_("Chrysalide is free software - © 2008-2016 Cyrille Bagard"));
/* Fichier */
- len = strlen(_("File: ")) + strlen(filename) + 1;
- content = (char *)calloc(len, sizeof(char));
-
- snprintf(content, len, "%s%s", _("File: "), filename);
-
- line = g_lang_output_continue_comments(output, buffer, content, len - 1);
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- free(content);
+ asprintf(&text[2], "%s%s", _("File: "), filename);
/* Checksum SHA256 */
- len = strlen(_("Sha256: ")) + strlen(checksum);
- content = (char *)calloc(len + 1, sizeof(char));
-
- snprintf(content, len + 1, "%s%s", _("Sha256: "), checksum);
-
- line = g_lang_output_continue_comments(output, buffer, content, len - 1);
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
- g_code_buffer_append_new_line(buffer, line);
+ asprintf(&text[3], "%s%s", _("Sha256: "), checksum);
- free(content);
+ /* Intégration finale */
- /* Ligne de séparation */
+ generator = g_intro_generator_new(lang, text, 4);
- line = g_lang_output_continue_comments(output, buffer, NULL, 0);
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
- g_code_buffer_append_new_line(buffer, line);
+ g_buffer_cache_append(cache, G_LINE_GENERATOR(generator), BLF_NONE);
- /* Conclusion */
-
- line = g_lang_output_end_comments(output, buffer);
- if (line != NULL)
- {
- g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
- g_code_buffer_append_new_line(buffer, line);
- }
-
- g_object_unref(G_OBJECT(output));
-#endif
}
@@ -724,7 +668,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* parts = parties binaires à désassembler. *
* count = nombre de parties à traiter. *
* instrs = liste des instructions chargées. [OUT] *
-* buffer = tampon de code mis en place. [OUT] *
+* cache = tampon de code mis en place. [OUT] *
* ack = fonction à appeler une fois l'opération terminée. *
* *
* Description : Procède au désassemblage d'un contenu binaire donné. *
@@ -735,30 +679,35 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* *
******************************************************************************/
-void disassemble_binary(GLoadedBinary *binary, GCodeBuffer **buffer, disassembly_ack_fc ack)
+void disassemble_binary(GLoadedBinary *binary, GBufferCache **cache, disassembly_ack_fc ack)
{
GBinFormat *format; /* Format associé au binaire */
+ GCodingLanguage *lang; /* Langage de sortie préféré */
GBinContent *content; /* Contenu bianire manipulé */
const gchar *checksum; /* Identifiant de binaire */
GDelayedDisassembly *disass; /* Désassemblage à mener */
GWorkQueue *queue; /* Gestionnaire de différés */
- *buffer = g_code_buffer_new(BLC_ASSEMBLY);
+ *cache = g_buffer_cache_new();
format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+ lang = g_asm_language_new();
+
content = g_binary_format_get_content(format);
checksum = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
g_object_unref(G_OBJECT(format));
- build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
+ build_disass_prologue(*cache, lang, g_binary_content_describe(content, true), checksum);
- disass = g_delayed_disassembly_new(binary, *buffer);
+ disass = g_delayed_disassembly_new(binary, *cache);
g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
queue = get_work_queue();
g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass), DEFAULT_WORK_GROUP);
+ g_object_unref(G_OBJECT(lang));
+
}
diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h
index 9151d23..20c7bdd 100644
--- a/src/analysis/disass/disassembler.h
+++ b/src/analysis/disass/disassembler.h
@@ -59,7 +59,7 @@ GType g_delayed_disassembly_get_type(void);
typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *);
/* Procède à la décompilation des routines d'un fichier donné. */
-void disassemble_binary(GLoadedBinary *, GCodeBuffer **, disassembly_ack_fc);
+void disassemble_binary(GLoadedBinary *, GBufferCache **, disassembly_ack_fc);
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index fe4d705..6c044be 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -27,27 +27,18 @@
#include <i18n.h>
-#include "../../arch/processor.h"
-#include "../../common/extstr.h"
#include "../../format/format.h"
+#include "../../glibext/generators/rborder.h"
#include "../../gui/panels/log.h"
-#define ROUTINE_INTRO_MSG "; --------------- BEGIN OF PROCEDURE ---------------"
-
-#define ROUTINE_OUTRO_MSG "; ---------------- END OF PROCEDURE ----------------"
-
-
-
/******************************************************************************
* *
-* Paramètres : buffer = tampon de récueil des résultats d'impression. *
-* format = format du binaire traité. *
-* instrs = ensemble d'instructions à traiter. *
-* routines = liste de routines intervenant dans le flot. *
-* count = quantité de ces routines. *
-* status = barre de statut avec progression à mettre à jour. *
+* Paramètres : cache = tampon de récueil des résultats d'impression. *
+* lang = langage de haut niveau préféré pour l'impression. *
+* binary = tampon de récueil des résultats d'impression. *
+* status = barre de statut avec progression à mettre à jour. *
* *
* Description : Transcrit du code désassemblé en texte humainement lisible. *
* *
@@ -57,8 +48,10 @@
* *
******************************************************************************/
-void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GArchProcessor *proc, GtkStatusStack *status)
+void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLoadedBinary *binary, GtkStatusStack *status)
{
+ GExeFormat *format; /* Format associé au binaire */
+ GArchProcessor *proc; /* Processeur de l'architecture*/
GBinPortion *root; /* Couche première de portions */
GBinPortion **portions; /* Morceaux d'encadrement */
size_t portions_count; /* Taille de cette liste */
@@ -74,22 +67,21 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
size_t i; /* Boucle de parcours */
GArchInstruction *instr; /* Instruction à traiter */
const vmpa2t *iaddr; /* Adresse d'instruction */
- vmpa2t outro_addr; /* Adresse de fin de code */
- GBufferLine *line;
+ GBorderGenerator *border; /* Délimitation de routine */
const vmpa2t *paddr; /* Adresse de portion */
+ GLineGenerator *generator; /* Générateur de contenu ajouté*/
const vmpa2t *saddr; /* Adresse de symbole */
int compared; /* Bilan d'une comparaison */
SymbolType stype; /* Type de symbole trouvé */
- const char *label; /* Etiquette ciblant un symbole*/
- mrange_t range; /* Couverture sans surface */
+ vmpa2t intro_addr; /* Adresse de début de code */
+ vmpa2t outro_addr; /* Adresse de fin de code */
+ BufferLineFlags flags; /* Propriétés pour la ligne */
+ //mrange_t range; /* Couverture sans surface */
GDbComment *comment; /* Commentaire à ajouter */
- const char *text;
-
- char *prefixed;
@@ -98,6 +90,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
+ format = g_loaded_binary_get_format(binary);
+ proc = g_loaded_binary_get_processor(binary);
bool collect_all_portions(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, void *unused)
{
@@ -149,29 +143,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
{
expect_outro = false;
- init_mrange(&range, &outro_addr, 0);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
- ROUTINE_OUTRO_MSG, strlen(ROUTINE_OUTRO_MSG), RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_code_buffer_append_new_line(buffer, line);
+ border = g_border_generator_new(lang, &outro_addr, false, msize);
+ g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE);
}
@@ -184,7 +157,11 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
if (cmp_vmpa_by_phy(iaddr, paddr) != 0)
break;
- g_binary_portion_print(portions[portion_index], buffer, msize);
+ generator = G_LINE_GENERATOR(portions[portion_index]);
+
+ /* Si elle comporte une description ! */
+ if (g_line_generator_count_lines(generator) > 0)
+ g_buffer_cache_append(cache, generator, BLF_NONE);
portion_index++;
@@ -192,7 +169,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
/* Début d'un nouveau symbole ? */
- if (sym_index < sym_count)
+ if (sym_index == sym_count)
+ compared = -1;
+
+ else
{
iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
@@ -225,29 +205,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
{
/* Impression de la marque de début */
- init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
- ROUTINE_INTRO_MSG, strlen(ROUTINE_INTRO_MSG), RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
+ copy_vmpa(&intro_addr, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])));
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_code_buffer_append_new_line(buffer, line);
+ border = g_border_generator_new(lang, &intro_addr, true, msize);
+ g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE);
/* Mémorisation de la fin */
@@ -259,23 +220,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
/* Etiquette ? */
- label = g_binary_symbol_get_label(symbols[sym_index]);
-
- if (label != NULL)
- {
- init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_add_flag(line, BLF_IS_LABEL);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_LABEL, NULL);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
+ generator = g_binary_symbol_produce_label(symbols[sym_index]);
- }
+ if (generator != NULL)
+ g_buffer_cache_append(cache, generator, BLF_NONE);
}
@@ -283,64 +231,37 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
no_more_symbol_finally:
+ flags = BLF_NONE;
-
- line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL);
-
-
- if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
- g_buffer_line_add_flag(line, BLF_BOOKMARK);
-
-
- if (sym_index < sym_count)
+ if (compared == 0)
{
- iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
- saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
-
- if (cmp_vmpa(iaddr, saddr) == 0)
- {
- /* Point d'entrée ? */
-
- if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)
- g_buffer_line_add_flag(line, BLF_ENTRYPOINT);
+ /* Point d'entrée ? */
- /* Début d'un groupe bien cohérent avec les alignements ? */
+ if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)
+ flags |= BLF_ENTRYPOINT;
- if (g_binary_symbol_is_block_start(symbols[sym_index]))
- g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
+ /* Début d'un groupe bien cohérent avec les alignements ? */
- /* Commentaire ? */
-
- comment = g_binary_symbol_get_comment(symbols[sym_index]);
-
- if (comment != NULL)
- {
+ if (g_binary_symbol_is_block_start(symbols[sym_index]))
+ flags |= BLF_WIDTH_MANAGER;
- /* FIXME : appliquer ! */
-
- text = g_db_comment_get_text(comment);
-
-
- prefixed = strdup("; ");
- prefixed = stradd(prefixed, text);
-
-
-
- g_buffer_line_append_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT, NULL);
+ }
+ g_buffer_cache_append(cache, G_LINE_GENERATOR(instr), flags);
- free(prefixed);
+ if (compared == 0)
+ {
+ /* Commentaire ? */
- }
+ comment = g_binary_symbol_get_comment(symbols[sym_index]);
- sym_index++;
+ if (comment != NULL)
+ g_db_item_apply(G_DB_ITEM(comment), binary);
- }
+ sym_index++;
}
- g_code_buffer_append_new_line(buffer, line);
-
g_object_unref(G_OBJECT(instr));
gtk_status_stack_update_activity_value(status, id, 1);
@@ -356,6 +277,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
if (portions != NULL)
free(portions);
+ g_object_unref(G_OBJECT(proc));
+ g_object_unref(G_OBJECT(format));
+
+
fprintf(stderr, "MISSING :: %u symbols\n", _missing);
diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h
index 801d3f4..35a0108 100644
--- a/src/analysis/disass/output.h
+++ b/src/analysis/disass/output.h
@@ -25,15 +25,15 @@
#define _ANALYSIS_DISASS_OUTPUT_H
-#include "../../arch/processor.h"
-#include "../../format/executable.h"
-#include "../../glibext/gcodebuffer.h"
+#include "../binary.h"
+#include "../human/lang.h"
+#include "../../glibext/gbuffercache.h"
#include "../../gtkext/gtkstatusstack.h"
/* Transcrit du code désassemblé en texte humainement lisible. */
-void print_disassembled_instructions(GCodeBuffer *, GExeFormat *, GArchProcessor *, GtkStatusStack *);
+void print_disassembled_instructions(GBufferCache *, GCodingLanguage *, GLoadedBinary *, GtkStatusStack *);
diff --git a/src/analysis/human/Makefile.am b/src/analysis/human/Makefile.am
new file mode 100755
index 0000000..0cfc4e3
--- /dev/null
+++ b/src/analysis/human/Makefile.am
@@ -0,0 +1,19 @@
+
+noinst_LTLIBRARIES = libanalysishuman.la
+
+
+libanalysishuman_la_SOURCES = \
+ lang-int.h \
+ lang.h lang.c
+
+libanalysishuman_la_LIBADD = \
+ asm/libanalysishumanasm.la
+
+libanalysishuman_la_LDFLAGS =
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = asm
diff --git a/src/analysis/human/asm/Makefile.am b/src/analysis/human/asm/Makefile.am
new file mode 100755
index 0000000..da94071
--- /dev/null
+++ b/src/analysis/human/asm/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libanalysishumanasm.la
+
+
+libanalysishumanasm_la_SOURCES = \
+ lang.h lang.c
+
+libanalysishumanasm_la_LIBADD =
+
+libanalysishumanasm_la_LDFLAGS =
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS =
diff --git a/src/analysis/human/asm/lang.c b/src/analysis/human/asm/lang.c
new file mode 100644
index 0000000..27a26dd
--- /dev/null
+++ b/src/analysis/human/asm/lang.c
@@ -0,0 +1,221 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.c - traduction en language d'assembleur classique
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "lang.h"
+
+
+#include "../lang-int.h"
+#include "../../../common/extstr.h"
+
+
+
+/* Traduction d'éléments en language d'assembleur (instance) */
+struct _GAsmLanguage
+{
+ GCodingLanguage parent; /* A laisser en premier */
+
+};
+
+/* Traduction d'éléments en language d'assembleur (classe) */
+struct _GAsmLanguageClass
+{
+ GCodingLanguageClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des traductions en langage d'assembleur. */
+static void g_asm_language_class_init(GAsmLanguageClass *);
+
+/* Initialise une traduction d'éléments en langage d'assembleur. */
+static void g_asm_language_init(GAsmLanguage *);
+
+/* Supprime toutes les références externes. */
+static void g_asm_language_dispose(GAsmLanguage *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_asm_language_finalize(GAsmLanguage *);
+
+/* Complète du texte pour en faire un vrai commentaire. */
+static void g_asm_language_encapsulate_comment(const GAsmLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+static void g_asm_language_encapsulate_comments(const GAsmLanguage *, char ***, size_t *);
+
+
+
+/* Indique le type défini pour une traduction en langage d'assembleur. */
+G_DEFINE_TYPE(GAsmLanguage, g_asm_language, G_TYPE_CODING_LANGUAGE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des traductions en langage d'assembleur.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_class_init(GAsmLanguageClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GCodingLanguageClass *lang; /* Encore une autre vision... */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_asm_language_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_asm_language_finalize;
+
+ lang = G_CODING_LANGUAGE_CLASS(klass);
+
+ lang->encaps_comment = (encapsulate_comment_fc)g_asm_language_encapsulate_comment;
+ lang->encaps_comments = (encapsulate_comments_fc)g_asm_language_encapsulate_comments;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance à initialiser. *
+* *
+* Description : Initialise une traduction d'éléments en langage d'assembleur.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_init(GAsmLanguage *lang)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_dispose(GAsmLanguage *lang)
+{
+ G_OBJECT_CLASS(g_asm_language_parent_class)->dispose(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_finalize(GAsmLanguage *lang)
+{
+ G_OBJECT_CLASS(g_asm_language_parent_class)->finalize(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une instance de traduction en langage d'assembleur. *
+* *
+* Retour : Instance mis en place et prête à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GCodingLanguage *g_asm_language_new(void)
+{
+ GAsmLanguage *result; /* Instance à retourner */
+
+ result = g_object_new(G_TYPE_ASM_LANGUAGE, NULL);
+
+ return G_CODING_LANGUAGE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = langage de haut niveau à manipuler. *
+* text = adresse de la ligne à compléter. [OUT] *
+* *
+* Description : Complète du texte pour en faire un vrai commentaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_encapsulate_comment(const GAsmLanguage *lang, char **text)
+{
+ *text = strprep(*text, "; ");
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = langage de haut niveau à manipuler. *
+* text = adresse du tableau de lignes à conserver. [OUT] *
+* count = adresse de la taille du tableau fourni. [OUT] *
+* *
+* Description : Complète du texte pour en faire de vrais commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_asm_language_encapsulate_comments(const GAsmLanguage *lang, char ***text, size_t *count)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < *count; i++)
+ (*text)[i] = strprep((*text)[i], "; ");
+
+}
diff --git a/src/analysis/human/asm/lang.h b/src/analysis/human/asm/lang.h
new file mode 100644
index 0000000..7381048
--- /dev/null
+++ b/src/analysis/human/asm/lang.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.h - prototypes pour la traduction en language d'assembleur classique
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_HUMAN_ASM_LANG_H
+#define _ANALYSIS_HUMAN_ASM_LANG_H
+
+
+#include <glib-object.h>
+
+
+#include "../lang.h"
+
+
+
+#define G_TYPE_ASM_LANGUAGE g_asm_language_get_type()
+#define G_ASM_LANGUAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_asm_language_get_type(), GAsmLanguage))
+#define G_IS_ASM_LANGUAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_asm_language_get_type()))
+#define G_ASM_LANGUAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ASM_LANGUAGE, GAsmLanguageClass))
+#define G_IS_ASM_LANGUAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ASM_LANGUAGE))
+#define G_ASM_LANGUAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ASM_LANGUAGE, GAsmLanguageClass))
+
+
+/* Traduction d'éléments en language d'assembleur (instance) */
+typedef struct _GAsmLanguage GAsmLanguage;
+
+/* Traduction d'éléments en language d'assembleur (classe) */
+typedef struct _GAsmLanguageClass GAsmLanguageClass;
+
+
+/* Indique le type défini pour une traduction en langage d'assembleur. */
+GType g_asm_language_get_type(void);
+
+/* Crée une instance de traduction en langage d'assembleur. */
+GCodingLanguage *g_asm_language_new(void);
+
+
+
+#endif /* _ANALYSIS_HUMAN_ASM_LANG_H */
diff --git a/src/analysis/human/lang-int.h b/src/analysis/human/lang-int.h
new file mode 100644
index 0000000..c20bc8a
--- /dev/null
+++ b/src/analysis/human/lang-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang-int.h - prototypes utiles aux traductions en langages de haut niveau
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_HUMAN_LANG_INT_H
+#define _ANALYSIS_HUMAN_LANG_INT_H
+
+
+#include "lang.h"
+
+
+
+/* Complète du texte pour en faire un vrai commentaire. */
+typedef void (* encapsulate_comment_fc) (const GCodingLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+typedef void (* encapsulate_comments_fc) (const GCodingLanguage *, char ***, size_t *);
+
+
+/* Traduction générique en langage humain (instance) */
+struct _GCodingLanguage
+{
+ GObject parent; /* A laisser en premier */
+
+};
+
+/* Traduction générique en langage humain (classe) */
+struct _GCodingLanguageClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+ encapsulate_comment_fc encaps_comment; /* Encadrement de commentaire */
+ encapsulate_comments_fc encaps_comments;/* Encadrement de commentaires */
+
+};
+
+
+
+#endif /* _ANALYSIS_HUMAN_LANG_INT_H */
diff --git a/src/analysis/human/lang.c b/src/analysis/human/lang.c
new file mode 100644
index 0000000..72002d3
--- /dev/null
+++ b/src/analysis/human/lang.c
@@ -0,0 +1,167 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.c - traduction en langages de haut niveau
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "lang.h"
+
+
+#include "lang-int.h"
+
+
+
+/* Initialise la classe des traductions en langage humain. */
+static void g_coding_language_class_init(GCodingLanguageClass *);
+
+/* Initialise une instance de traduction en langage humain. */
+static void g_coding_language_init(GCodingLanguage *);
+
+/* Supprime toutes les références externes. */
+static void g_coding_language_dispose(GCodingLanguage *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_coding_language_finalize(GCodingLanguage *);
+
+
+
+/* Indique le type défini pour une traduction en langage humain. */
+G_DEFINE_TYPE(GCodingLanguage, g_coding_language, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des traductions en langage humain. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_coding_language_class_init(GCodingLanguageClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_coding_language_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_coding_language_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance à initialiser. *
+* *
+* Description : Initialise une instance de traduction en langage humain. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_coding_language_init(GCodingLanguage *lang)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_coding_language_dispose(GCodingLanguage *lang)
+{
+ G_OBJECT_CLASS(g_coding_language_parent_class)->dispose(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_coding_language_finalize(GCodingLanguage *lang)
+{
+ G_OBJECT_CLASS(g_coding_language_parent_class)->finalize(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = langage de haut niveau à manipuler. *
+* text = adresse de la ligne à compléter. [OUT] *
+* *
+* Description : Complète du texte pour en faire un vrai commentaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_coding_language_encapsulate_comment(const GCodingLanguage *lang, char **text)
+{
+ G_CODING_LANGUAGE_GET_CLASS(lang)->encaps_comment(lang, text);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = langage de haut niveau à manipuler. *
+* text = adresse du tableau de lignes à conserver. [OUT] *
+* count = adresse de la taille du tableau fourni. [OUT] *
+* *
+* Description : Complète du texte pour en faire de vrais commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_coding_language_encapsulate_comments(const GCodingLanguage *lang, char ***text, size_t *count)
+{
+ G_CODING_LANGUAGE_GET_CLASS(lang)->encaps_comments(lang, text, count);
+
+}
diff --git a/src/analysis/human/lang.h b/src/analysis/human/lang.h
new file mode 100644
index 0000000..dc8e398
--- /dev/null
+++ b/src/analysis/human/lang.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.h - prototypes pour les traductions en langages de haut niveau
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_HUMAN_LANG_H
+#define _ANALYSIS_HUMAN_LANG_H
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_CODING_LANGUAGE g_coding_language_get_type()
+#define G_CODING_LANGUAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODING_LANGUAGE, GCodingLanguage))
+#define G_IS_CODING_LANGUAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODING_LANGUAGE))
+#define G_CODING_LANGUAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODING_LANGUAGE, GCodingLanguageClass))
+#define G_IS_CODING_LANGUAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODING_LANGUAGE))
+#define G_CODING_LANGUAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODING_LANGUAGE, GCodingLanguageClass))
+
+
+/* Traduction générique en langage humain (instance) */
+typedef struct _GCodingLanguage GCodingLanguage;
+
+/* Traduction générique en langage humain (classe) */
+typedef struct _GCodingLanguageClass GCodingLanguageClass;
+
+
+/* Indique le type défini pour une traduction en langage humain. */
+GType g_coding_language_get_type(void);
+
+/* Complète du texte pour en faire un vrai commentaire. */
+void g_coding_language_encapsulate_comment(const GCodingLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+void g_coding_language_encapsulate_comments(const GCodingLanguage *, char ***, size_t *);
+
+
+
+#endif /* _ANALYSIS_HUMAN_LANG_H */
diff --git a/src/analysis/project.c b/src/analysis/project.c
index dce55b6..4251dcc 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -39,9 +39,8 @@
#include "../glibext/signal.h"
#include "../gtkext/easygtk.h"
#include "../glibext/delayed-int.h"
-#include "../gtkext/gtkblockview.h"
-#include "../gtkext/gtkgraphview.h"
-#include "../gtkext/gtksourceview.h"
+#include "../gtkext/gtkblockdisplay.h"
+#include "../gtkext/gtkgraphdisplay.h"
#include "../gui/core/panels.h"
#include "../gui/panels/log.h"
#include "../gui/panels/panel.h"
@@ -836,13 +835,10 @@ GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBina
switch (i)
{
case BVW_BLOCK:
- display = gtk_block_view_new();
+ display = gtk_block_display_new();
break;
case BVW_GRAPH:
- display = gtk_graph_view_new();
- break;
- case BVW_SOURCE:
- display = gtk_source_view_new();
+ display = gtk_graph_display_new();
break;
default: /* GCC ! */
break;
@@ -894,9 +890,6 @@ GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBina
case BVW_GRAPH:
g_object_set_data(G_OBJECT(displays[i]), "graph_alt_view", displays[j]);
break;
- case BVW_SOURCE:
- g_object_set_data(G_OBJECT(displays[i]), "source_alt_view", displays[j]);
- break;
default: /* GCC ! */
break;
}
@@ -1033,9 +1026,6 @@ GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *panel, BinaryView
case BVW_GRAPH:
result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "graph_alt_view"));
break;
- case BVW_SOURCE:
- result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "source_alt_view"));
- break;
default:
assert(false);
result = NULL;
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index 694ec65..3f9ab8c 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -58,6 +58,9 @@ typedef struct _case_comment
} case_comment;
+/* REMME */
+#define COMMENT_LINE_SEP "\n"
+
/******************************************************************************
* *
@@ -262,6 +265,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
for (k = 0; k < comment->count; k++)
{
if (k > 0)
+ /* FIXME : encapsuler ! */
msg = stradd(msg, COMMENT_LINE_SEP);
asprintf(&int_val, _("Case %d:"), comment->keys[k]);
@@ -280,6 +284,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
msg = strdup(_("Defaut case:"));
else
{
+ /* FIXME : encapsuler ! */
msg = stradd(msg, COMMENT_LINE_SEP);
msg = stradd(msg, _("Defaut case"));
}
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index c7f32e7..dbb2f2c 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -38,7 +38,7 @@ typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegi
typedef const char * (* get_instruction_encoding_fc) (const GArchInstruction *);
/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBufferLine *, size_t, size_t);
/* Fournit le nom humain de l'instruction manipulée. */
typedef const char * (* get_instruction_keyword_fc) (GArchInstruction *, AsmSyntax );
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 5f35db4..fc474ea 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -30,6 +30,7 @@
#include "instruction-int.h"
+#include "../glibext/linegen-int.h"
@@ -39,6 +40,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
/* Initialise une instance d'opérande d'architecture. */
static void g_arch_instruction_init(GArchInstruction *);
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_arch_instruction_interface_init(GLineGeneratorInterface *);
+
/* Supprime toutes les références externes. */
static void g_arch_instruction_dispose(GArchInstruction *);
@@ -47,16 +51,32 @@ static void g_arch_instruction_finalize(GArchInstruction *);
-/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_arch_instruction_count_lines(const GArchInstruction *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_arch_instruction_compute_addr(const GArchInstruction *, gint, vmpa2t *, size_t, size_t);
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_arch_instruction_contains_addr(const GArchInstruction *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t);
/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *_g_arch_instruction_print(GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t);
/* Indique le type défini pour une instruction d'architecture. */
-G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init));
/******************************************************************************
@@ -116,6 +136,29 @@ static void g_arch_instruction_init(GArchInstruction *instr)
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
+ iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr;
+ iface->contains = (linegen_contains_fc)g_arch_instruction_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;
+ iface->print = (linegen_print_fc)g_arch_instruction_print;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -897,84 +940,6 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t
}
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* buffer = espace où placer ledit contenu. *
-* msize = taille idéale des positions et adresses; *
-* content = contenu binaire global à venir lire. *
-* syntax = type de représentation demandée. *
-* *
-* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
-{
- GBufferLine *result; /* Ligne de destination */
- const char *key; /* Mot clef principal */
- size_t klen; /* Taille de ce mot clef */
- size_t i; /* Boucle de parcours */
-
- result = g_code_buffer_prepare_new_line(buffer, &instr->range);
-
- g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
- g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->max_displayed_len);
-
- /* Instruction proprement dite */
-
- key = g_arch_instruction_get_keyword(instr, syntax);
- klen = strlen(key);
-
- g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
-
- if (instr->operands_count > 0)
- {
- g_arch_operand_print(instr->operands[0], result, syntax);
-
- for (i = 1; i < instr->operands_count; i++)
- {
- g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
-
- g_arch_operand_print(instr->operands[i], result, syntax);
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* buffer = espace où placer ledit contenu. *
-* msize = taille idéale des positions et adresses; *
-* content = contenu binaire global à venir lire. *
-* syntax = type de représentation demandée. *
-* *
-* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
-{
- return G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax);
-
-}
-
/* ---------------------------------------------------------------------------------- */
/* TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE */
@@ -1110,3 +1075,169 @@ GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, con
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OFFRE DE CAPACITES DE GENERATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
+{
+ return 1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ copy_vmpa(addr, get_mrange_addr(&instr->range));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_arch_instruction_contains_addr(const GArchInstruction *instr, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ int result; /* Conclusion à retourner */
+
+ result = cmp_mrange_with_vmpa(&instr->range, addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* 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. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *instr, size_t index, size_t repeat)
+{
+ return BLF_HAS_CODE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction d'assemblage à représenter. *
+* buffer = espace où placer ledit contenu. *
+* msize = taille idéale des positions et adresses; *
+* content = contenu binaire global à venir lire. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
+{
+ const char *key; /* Mot clef principal */
+ size_t klen; /* Taille de ce mot clef */
+ size_t i; /* Boucle de parcours */
+
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+ /* Instruction proprement dite */
+
+ key = g_arch_instruction_get_keyword(instr, 0/*, syntax*/);
+ klen = strlen(key);
+
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
+
+ if (instr->operands_count > 0)
+ {
+ g_arch_operand_print(instr->operands[0], line, 0/*syntax*/);
+
+ for (i = 1; i < instr->operands_count; i++)
+ {
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+
+ g_arch_operand_print(instr->operands[i], line, 0/*syntax*/);
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
+{
+ G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat);
+
+}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 54778b5..814cc86 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -35,7 +35,6 @@
#include "../analysis/content.h"
#include "../analysis/type.h"
#include "../format/executable.h"
-#include "../glibext/gcodebuffer.h"
@@ -222,9 +221,6 @@ phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *);
/* Définit la quantité maximale de code affiché. */
void g_arch_instruction_set_displayed_max_length(GArchInstruction *, phys_t);
-/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-GBufferLine *g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
-
/* -------------------- TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE -------------------- */
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 61a37e0..d0348c9 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -78,7 +78,7 @@ static const char *g_raw_instruction_get_encoding(const GRawInstruction *);
static const char *g_raw_instruction_get_keyword(const GRawInstruction *, AsmSyntax);
/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *g_raw_instruction_print(GRawInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void g_raw_instruction_print(GRawInstruction *, GBufferLine *, size_t, size_t);
@@ -444,11 +444,11 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* buffer = espace où placer ledit contenu. *
+* Paramètres : instr = instruction d'assemblage à représenter. *
+* buffer = espace où placer ledit contenu. *
* msize = taille idéale des positions et adresses; *
* content = contenu binaire global à venir lire. *
-* syntax = type de représentation demandée. *
+* syntax = type de représentation demandée. *
* *
* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
* *
@@ -458,9 +458,8 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A
* *
******************************************************************************/
-static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
+static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
{
- GBufferLine *result; /* Ligne de destination */
GArchInstruction *base; /* Autre version de l'instance */
const char *key; /* Mot clef principal */
size_t klen; /* Taille de ce mot clef */
@@ -474,25 +473,21 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
base = G_ARCH_INSTRUCTION(instr);
if (!instr->is_padding && !instr->is_string)
- result = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, buffer, msize, content, syntax);
+ G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, line, index, repeat);
else
{
- result = g_code_buffer_prepare_new_line(buffer, &base->range);
-
- g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
- g_buffer_line_fill_mrange(result, msize/* TODO ! */, msize);
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
/* Instruction proprement dite */
- key = g_arch_instruction_get_keyword(base, syntax);
+ key = g_arch_instruction_get_keyword(base, 0/*, syntax*/);
klen = strlen(key);
- g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
if (instr->is_padding)
- g_buffer_line_append_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
else /*if (instr->is_string)*/
{
@@ -516,15 +511,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
{
if (!first)
{
- g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
}
else
first = false;
string[iter++] = '"';
- g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
iter = 1;
@@ -534,13 +529,13 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
if (!first)
{
- g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
}
else
first = false;
- g_arch_operand_print(base->operands[i], result, syntax);
+ g_arch_operand_print(base->operands[i], line, 0/*, syntax*/);
}
@@ -554,15 +549,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
{
if (!first)
{
- g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
}
else
first = false;
string[iter++] = '"';
- g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
}
@@ -572,8 +567,6 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
}
- return result;
-
}
diff --git a/src/arch/undefined.c b/src/arch/undefined.c
index 0957764..d239dd5 100644
--- a/src/arch/undefined.c
+++ b/src/arch/undefined.c
@@ -70,7 +70,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *);
static const char *g_undef_instruction_get_keyword(const GUndefInstruction *, AsmSyntax);
/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *g_undef_instruction_print(GUndefInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t);
@@ -262,11 +262,11 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* buffer = espace où placer ledit contenu. *
+* Paramètres : instr = instruction d'assemblage à représenter. *
+* buffer = espace où placer ledit contenu. *
* msize = taille idéale des positions et adresses; *
* content = contenu binaire global à venir lire. *
-* syntax = type de représentation demandée. *
+* syntax = type de représentation demandée. *
* *
* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
* *
@@ -276,29 +276,22 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS
* *
******************************************************************************/
-static GBufferLine *g_undef_instruction_print(GUndefInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
+static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
{
- GBufferLine *result; /* Ligne de destination */
GArchInstruction *base; /* Version de base */
const char *key; /* Mot clef principal */
size_t klen; /* Taille de ce mot clef */
base = G_ARCH_INSTRUCTION(instr);
- result = g_code_buffer_prepare_new_line(buffer, &base->range);
-
- g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
- g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->max_displayed_len);
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
/* Instruction proprement dite */
- key = g_arch_instruction_get_keyword(base, syntax);
+ key = g_arch_instruction_get_keyword(base, 0/*, syntax*/);
klen = strlen(key);
- g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL);
-
- return result;
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL);
}
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 1e17f17..16fada4 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -104,7 +104,9 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *);
#define has_phys_addr(a) ((a)->physical != VMPA_NO_PHYSICAL)
#define has_virt_addr(a) ((a)->virtual != VMPA_NO_VIRTUAL)
-#define dup_vmpa(src) \
+#define is_invalid_vmpa(a) (!has_phys_addr(a) && !has_virt_addr(a))
+
+#define dup_vmpa(src) \
make_vmpa(get_phy_addr(src), get_virt_addr(src))
/* Décalle une position d'une certaine quantité. */
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index df920b2..d93346a 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -79,7 +79,7 @@ static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const cha
//static void g_dex_format_find_all_sources(GDexFormat *);
/* Procède à la décompilation complète du format. */
-static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *);
+static void g_dex_format_decompile(const GDexFormat *, void/*GCodeBuffer*/ *, const char *);
@@ -470,7 +470,7 @@ static void g_dex_format_find_all_sources(GDexFormat *format)
* *
******************************************************************************/
-static void g_dex_format_decompile(const GDexFormat *format, GCodeBuffer *buffer, const char *filename)
+static void g_dex_format_decompile(const GDexFormat *format, void/*GCodeBuffer*/ *buffer, const char *filename)
{
#if 0
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index 38065fa..b819156 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -29,6 +29,7 @@
#include "dex.h"
#include "method.h"
#include "../../analysis/routine.h"
+#include "../../glibext/delayed.h"
diff --git a/src/format/dwarf/v2/dwarf.h b/src/format/dwarf/v2/dwarf.h
index 54c6b37..867ae39 100644
--- a/src/format/dwarf/v2/dwarf.h
+++ b/src/format/dwarf/v2/dwarf.h
@@ -28,8 +28,7 @@
#include <glib-object.h>
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
diff --git a/src/format/dwarf/v3/dwarf.h b/src/format/dwarf/v3/dwarf.h
index e95ed16..bac5ccc 100644
--- a/src/format/dwarf/v3/dwarf.h
+++ b/src/format/dwarf/v3/dwarf.h
@@ -28,8 +28,7 @@
#include <glib-object.h>
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
diff --git a/src/format/dwarf/v4/dwarf.h b/src/format/dwarf/v4/dwarf.h
index 29059b5..6eda64e 100644
--- a/src/format/dwarf/v4/dwarf.h
+++ b/src/format/dwarf/v4/dwarf.h
@@ -28,8 +28,7 @@
#include <glib-object.h>
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
diff --git a/src/format/elf/symbols.h b/src/format/elf/symbols.h
index d1b0fae..90e2f61 100644
--- a/src/format/elf/symbols.h
+++ b/src/format/elf/symbols.h
@@ -28,6 +28,7 @@
#include "elf.h"
+#include "../../glibext/delayed.h"
#include "../../gtkext/gtkstatusstack.h"
diff --git a/src/format/format-int.h b/src/format/format-int.h
index e11e378..ea6b770 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -28,6 +28,9 @@
#include "format.h"
+#include "../gtkext/gtkstatusstack.h"
+
+
/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */
@@ -36,7 +39,7 @@
typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *);
/* Procède à la décompilation complète du format. */
-typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *);
+typedef void (* format_decompile_fc) (const GBinFormat *, void/*GCodeBuffer*/ *, const char *);
/* Rythme des allocations pour les entrées de code */
diff --git a/src/format/java/java.h b/src/format/java/java.h
index 074c797..a33870f 100755
--- a/src/format/java/java.h
+++ b/src/format/java/java.h
@@ -30,7 +30,7 @@
#include <sys/types.h>
-#include "../format.h"
+#include "../../core/formats.h"
diff --git a/src/format/pe/pe.h b/src/format/pe/pe.h
index 3ac5f49..d6c8dde 100644
--- a/src/format/pe/pe.h
+++ b/src/format/pe/pe.h
@@ -30,7 +30,7 @@
#include <sys/types.h>
-#include "../format.h"
+#include "../../core/formats.h"
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 97ff114..82321c2 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -28,6 +28,12 @@
#include <string.h>
+#include "../glibext/linegen-int.h"
+
+
+
+/* --------------------- FONCTIONNALITES BASIQUES POUR SYMBOLES --------------------- */
+
/* Symbole d'exécutable (instance) */
struct _GBinSymbol
@@ -64,6 +70,9 @@ static void g_binary_symbol_class_init(GBinSymbolClass *);
/* Initialise une instance de symbole d'exécutable. */
static void g_binary_symbol_init(GBinSymbol *);
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_binary_symbol_interface_init(GLineGeneratorInterface *);
+
/* Supprime toutes les références externes. */
static void g_binary_symbol_dispose(GBinSymbol *);
@@ -72,8 +81,34 @@ static void g_binary_symbol_finalize(GBinSymbol *);
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_binary_symbol_count_lines(const GBinSymbol *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_binary_symbol_compute_addr(const GBinSymbol *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_binary_symbol_contains_addr(const GBinSymbol *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_binary_symbol_print(GBinSymbol *, GBufferLine *, size_t, size_t);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES BASIQUES POUR SYMBOLES */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Indique le type défini pour un symbole d'exécutable. */
-G_DEFINE_TYPE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_binary_symbol_interface_init));
/******************************************************************************
@@ -120,6 +155,29 @@ static void g_binary_symbol_init(GBinSymbol *symbol)
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_symbol_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_binary_symbol_count_lines;
+ iface->compute = (linegen_compute_fc)g_binary_symbol_compute_addr;
+ iface->contains = (linegen_contains_fc)g_binary_symbol_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_binary_symbol_get_flags;
+ iface->print = (linegen_print_fc)g_binary_symbol_print;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : symbol = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -665,3 +723,164 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *symbol)
return symbol->comment;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OFFRE DE CAPACITES DE GENERATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à consulter pour futur usage. *
+* *
+* Description : Détermine si un symbole pour faire office de générateur. *
+* *
+* Retour : Instance de générateur si les capacités sont là. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GLineGenerator *g_binary_symbol_produce_label(GBinSymbol *symbol)
+{
+ GLineGenerator *result; /* Instance à retourner */
+ const char *label; /* Etiquette à insérer */
+
+ label = g_binary_symbol_get_label(symbol);
+
+ result = (label != NULL ? G_LINE_GENERATOR(symbol) : NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_binary_symbol_count_lines(const GBinSymbol *symbol)
+{
+ return 1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_symbol_compute_addr(const GBinSymbol *symbol, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ const mrange_t *range; /* Emplacement à manipuler */
+
+ range = g_binary_symbol_get_range(symbol);
+
+ copy_vmpa(addr, get_mrange_addr(range));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_binary_symbol_contains_addr(const GBinSymbol *symbol, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ int result; /* Conclusion à retourner */
+ const mrange_t *range; /* Emplacement à manipuler */
+
+ range = g_binary_symbol_get_range(symbol);
+
+ result = cmp_mrange_with_vmpa(range, addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à consulter. *
+* 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. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *symbol, size_t index, size_t repeat)
+{
+ return BLF_IS_LABEL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : symbol = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_symbol_print(GBinSymbol *symbol, GBufferLine *line, size_t index, size_t repeat)
+{
+ const mrange_t *range; /* Emplacement à manipuler */
+ const char *label; /* Etiquette à insérer */
+
+ range = g_binary_symbol_get_range(symbol);
+
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+ label = g_binary_symbol_get_label(symbol);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(label), RTT_LABEL, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
+
+}
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 78741cb..e73bb27 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -32,9 +32,13 @@
#include "../analysis/db/item.h"
#include "../analysis/db/items/comment.h"
#include "../arch/instruction.h"
+#include "../glibext/linegen.h"
+/* --------------------- FONCTIONNALITES BASIQUES POUR SYMBOLES --------------------- */
+
+
/* Types de symbole */
typedef enum _SymbolType
{
@@ -164,4 +168,12 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Détermine si un symbole pour faire office de générateur. */
+GLineGenerator *g_binary_symbol_produce_label(GBinSymbol *);
+
+
+
#endif /* _FORMAT_SYMBOL_H */
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index aa7a9a3..fe7565a 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -9,16 +9,21 @@ libglibext_la_SOURCES = \
delayed-int.h \
delayed.h delayed.c \
gbinportion.h gbinportion.c \
+ gbuffercache.h gbuffercache.c \
gbufferline.h gbufferline.c \
gbufferview.h gbufferview.c \
- gcodebuffer.h gcodebuffer.c \
gnhash.h gnhash.c \
gwidthtracker.h gwidthtracker.c \
linecolumn.h linecolumn.c \
+ linegen-int.h \
+ linegen.h linegen.c \
linesegment.h linesegment.c \
proto.h \
signal.h signal.c
+libglibext_la_LIBADD = \
+ generators/libglibextgenerators.la
+
libglibext_la_LDFLAGS =
@@ -26,7 +31,7 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS =
+SUBDIRS = generators
chrysamarshal.h: chrysamarshal.list
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 4137763..eec9651 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include <malloc.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -33,8 +34,10 @@
#include <i18n.h>
+#include "../analysis/human/asm/lang.h" // TODO : REMME -> format !
#include "../common/extstr.h"
#include "../common/sort.h"
+#include "../glibext/linegen-int.h"
@@ -49,6 +52,8 @@ struct _GBinPortion
char *code; /* Code de la couleur de fond */
char *desc; /* Désignation humaine */
+ char **text; /* Lignes brutes à représenter */
+ size_t lcount; /* Quantité de ces lignes */
mrange_t range; /* Emplacement dans le code */
@@ -73,6 +78,9 @@ static void g_binary_portion_class_init(GBinPortionClass *);
/* Initialise une instance de portion de données binaires. */
static void g_binary_portion_init(GBinPortion *);
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_binary_portion_interface_init(GLineGeneratorInterface *);
+
/* Supprime toutes les références externes. */
static void g_binary_portion_dispose(GBinPortion *);
@@ -84,6 +92,26 @@ static bool g_binary_portion_compute_sub_area(const GBinPortion *, phys_t, const
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_binary_portion_count_lines(const GBinPortion *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_binary_portion_compute_addr(const GBinPortion *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_binary_portion_contains_addr(const GBinPortion *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_binary_portion_print(GBinPortion *, GBufferLine *, size_t, size_t);
+
+
+
/* ------------------------ PARCOURS D'ENSEMBLES DE PORTIONS ------------------------ */
@@ -98,7 +126,8 @@ static bool g_portion_layer_contains_addr(const GBinPortion *, const vmpa2t *);
/* Indique le type défini par la GLib pour les portions de données binaires. */
-G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GBinPortion, g_binary_portion, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_binary_portion_interface_init));
/******************************************************************************
@@ -140,6 +169,32 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
static void g_binary_portion_init(GBinPortion *portion)
{
+ portion->desc = NULL;
+ portion->text = NULL;
+ portion->lcount = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_binary_portion_count_lines;
+ iface->compute = (linegen_compute_fc)g_binary_portion_compute_addr;
+ iface->contains = (linegen_contains_fc)g_binary_portion_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_binary_portion_get_flags;
+ iface->print = (linegen_print_fc)g_binary_portion_print;
}
@@ -177,11 +232,19 @@ static void g_binary_portion_dispose(GBinPortion *portion)
static void g_binary_portion_finalize(GBinPortion *portion)
{
+ size_t i; /* Boucle de parcours */
+
free(portion->code);
if (portion->desc != NULL)
free(portion->desc);
+ for (i = 0; i < portion->lcount; i++)
+ free(portion->text[i]);
+
+ if (portion->text != NULL)
+ free(portion->text);
+
G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
}
@@ -260,9 +323,66 @@ int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b)
void g_binary_portion_set_desc(GBinPortion *portion, const char *desc)
{
- if (portion->desc != NULL) free(portion->desc);
+ size_t i; /* Boucle de parcours */
+ GCodingLanguage *lang; /* Langage de sortie préféré */
+
+ if (portion->desc != NULL)
+ {
+ free(portion->desc);
+
+ for (i = 0; i < portion->lcount; i++)
+ free(portion->text[i]);
+
+ if (portion->text != NULL)
+ {
+ free(portion->text);
+ portion->text = NULL;
+ }
+
+ }
+
+ if (desc == NULL)
+ portion->desc = NULL;
+
+ else
+ {
+ portion->desc = strdup(desc);
+
+ /* Constitution du rendu */
+
+ portion->text = calloc(4, sizeof(char *));
+ portion->lcount = 4;
+
+ portion->text[0] = strdup("======================================================");
+ portion->text[1] = strdup("");
+
+ asprintf(&portion->text[2], "%s (%s%s%s%s)", portion->desc, _("rights: "),
+ portion->rights & PAC_READ ? "r" : "-",
+ portion->rights & PAC_WRITE ? "w" : "-",
+ portion->rights & PAC_EXEC ? "x" : "-");
- portion->desc = strdup(desc);
+ portion->text[3] = strdup("");
+ portion->text[4] = strdup("======================================================");
+
+ /* Ajout de la touche "commentaires" */
+
+ lang = g_asm_language_new();
+
+ g_coding_language_encapsulate_comments(lang, &portion->text, &portion->lcount);
+
+ g_object_unref(G_OBJECT(lang));
+
+ /* Ajout de deux bordures vides */
+
+ portion->lcount += 2;
+ portion->text = realloc(portion->text, portion->lcount * sizeof(char *));
+
+ memmove(&portion->text[1], &portion->text[0], (portion->lcount - 2) * sizeof(char *));
+
+ portion->text[0] = NULL;
+ portion->text[portion->lcount - 1] = NULL;
+
+ }
}
@@ -346,98 +466,6 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
/******************************************************************************
* *
-* Paramètres : portion = description de partie à consulter. *
-* buffer = espace où placer ledit contenu. *
-* msize = taille idéale des positions et adresses; *
-* *
-* Description : Insère dans un tampon une description de portion. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize)
-{
- mrange_t range; /* Couverture à fournir */
- GBufferLine *line; /* Nouvelle ligne à éditer */
- char rights[64]; /* Traduction en texte */
-
- /* On ne traite pas les portions anonymes ! */
- if (portion->desc == NULL) return;
-
- init_mrange(&range, get_mrange_addr(&portion->range), 0);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
- g_code_buffer_append_new_line(buffer, line);
-
- /* Séparation */
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
- "; ======================================================", 56, RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- /* Retour à la ligne */
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- /* Description */
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT, NULL);
-
- snprintf(rights, sizeof(rights), " (%s%s%s%s)",
- _("rights: "),
- portion->rights & PAC_READ ? "r" : "-",
- portion->rights & PAC_WRITE ? "w" : "-",
- portion->rights & PAC_EXEC ? "x" : "-");
-
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- /* Retour à la ligne */
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
- g_code_buffer_append_new_line(buffer, line);
-
- line = g_code_buffer_prepare_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
- g_code_buffer_append_new_line(buffer, line);
-
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : portion = description de partie à mettre à jour. *
* tooltip = astuce à compléter. [OUT] *
* *
@@ -724,6 +752,133 @@ bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void
/* ---------------------------------------------------------------------------------- */
+/* OFFRE DE CAPACITES DE GENERATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_binary_portion_count_lines(const GBinPortion *portion)
+{
+ return portion->lcount;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_compute_addr(const GBinPortion *portion, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ copy_vmpa(addr, get_mrange_addr(&portion->range));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_binary_portion_contains_addr(const GBinPortion *portion, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ int result; /* Conclusion à retourner */
+
+ result = cmp_vmpa(addr, get_mrange_addr(&portion->range));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = générateur à consulter. *
+* 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. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *portion, size_t index, size_t repeat)
+{
+ return (repeat == 0 ? BLF_WIDTH_MANAGER : BLF_HAS_CODE);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_print(GBinPortion *portion, GBufferLine *line, size_t index, size_t repeat)
+{
+ assert(repeat < portion->lcount);
+
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(&portion->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+ if (portion->text[repeat] != NULL)
+ {
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(portion->text[repeat]), RTT_COMMENT, NULL);
+
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* PARCOURS D'ENSEMBLES DE PORTIONS */
/* ---------------------------------------------------------------------------------- */
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index 2aa5e1a..4f4b3be 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -30,7 +30,6 @@
#include <gtk/gtk.h>
-#include "gcodebuffer.h"
#include "../arch/vmpa.h"
#include "../common/fnv1a.h"
@@ -100,9 +99,6 @@ void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights);
/* Fournit les droits associés à une partie de code. */
PortionAccessRights g_binary_portion_get_rights(const GBinPortion *);
-/* Insère dans un tampon une description de portion. */
-void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize);
-
/* Prépare une astuce concernant une portion pour son affichage. */
void g_binary_portion_query_tooltip(GBinPortion *, GtkTooltip *);
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
new file mode 100644
index 0000000..57a9487
--- /dev/null
+++ b/src/glibext/gbuffercache.c
@@ -0,0 +1,1625 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gbuffercache.c - affichage à la demande d'un ensemble de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "gbuffercache.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+
+#include "chrysamarshal.h"
+
+
+
+/* --------------------- FONCTIONS AUXILIAIRES DE MANIPULATIONS --------------------- */
+
+
+/* Informations rattachées à la génération d'une ligne */
+typedef struct _generator_link
+{
+ GLineGenerator *instance; /* Fournisseur de contenu */
+ size_t repeat; /* Compteur de successions */
+
+} generator_link;
+
+/* Suivi interne de l'état d'une ligne */
+typedef struct _cache_info
+{
+ union
+ {
+ generator_link generator; /* Générateur unique */
+ generator_link *generators; /* Liste de générateurs */
+ };
+ size_t count; /* Taille de cette liste */
+
+ GBufferLine *line; /* Ligne en place ou NULL */
+
+ BufferLineFlags extra_flags; /* Propriétés supplémentaires */
+
+} cache_info;
+
+
+/* Gros verrou global pour alléger les structures... */
+G_LOCK_DEFINE_STATIC(_line_update);
+
+
+/* Met en place un nouvel ensemble d'information sur une ligne. */
+static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFlags);
+
+/* Libère la mémoire occupée par des informations sur une ligne. */
+static void release_cache_info(cache_info *);
+
+/* Ajoute un générateur aux informations sur une ligne. */
+static void extend_cache_info(cache_info *, GLineGenerator *);
+
+/* Retire un générateur aux informations d'une ligne. */
+static void remove_from_cache_info(cache_info *, GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position de ligne. */
+static void get_cache_info_addr(const cache_info *, size_t, gint, vmpa2t *);
+
+/* Suivit les variations du compteur de références d'une ligne. */
+static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean);
+
+/* Fournit la ligne de tampon correspondant aux générateurs. */
+static GBufferLine *get_cache_info_line(cache_info *, size_t);
+
+/* Force la réinitialisation d'une éventuelle ligne cachée. */
+static void reset_cache_info_line(cache_info *);
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+/* Tampon pour gestion de lignes optimisée (instance) */
+struct _GBufferCache
+{
+ GObject parent; /* A laisser en premier */
+
+ cache_info *lines; /* Liste des lignes intégrées */
+ size_t count; /* Quantité en cache */
+ size_t used; /* Quantité utilisée */
+
+ GWidthTracker *tracker; /* Suivi des largeurs */
+
+};
+
+/* Tampon pour gestion de lignes optimisée (classe) */
+struct _GBufferCacheClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+ gint line_height; /* Hauteur maximale des lignes */
+ gint left_margin; /* Marge gauche + espace */
+ gint text_pos; /* Début d'impression du code */
+
+ /* Signaux */
+
+ void (* size_changed) (GBufferCache *, bool, size_t, size_t);
+
+};
+
+
+/* Taille des allocations de masse */
+#define LINE_ALLOC_BULK 1000
+
+
+/* Procède à l'initialisation d'une classe de tampon de lignes. */
+static void g_buffer_cache_class_init(GBufferCacheClass *);
+
+/* Procède à l'initialisation d'un tampon de gestion de lignes. */
+static void g_buffer_cache_init(GBufferCache *);
+
+/* Supprime toutes les références externes. */
+static void g_buffer_cache_dispose(GBufferCache *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_buffer_cache_finalize(GBufferCache *);
+
+/* Calcule l'indice d'apparition d'un générateur dans le tampon. */
+static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGenerator *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONS AUXILIAIRES DE MANIPULATIONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations concernant une ligne à constituer. *
+* generator = générateur à associer à toutes les lignes. *
+* repeat = compteur de répétition entre les lignes. *
+* flags = propriétés supplémentaires à associer à la ligne.*
+* *
+* Description : Met en place un nouvel ensemble d'information sur une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t repeat, BufferLineFlags flags)
+{
+ info->generator.instance = generator;
+ info->generator.repeat = repeat;
+
+ g_object_ref(G_OBJECT(generator));
+
+ info->count = 1;
+
+ info->line = NULL;
+
+ info->extra_flags = flags;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations concernant une ligne à constituer. *
+* *
+* Description : Libère la mémoire occupée par des informations sur une ligne.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void release_cache_info(cache_info *info)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (info->count == 1)
+ g_object_unref(G_OBJECT(info->generator.instance));
+
+ else
+ for (i = 0; i < info->count; i++)
+ g_object_unref(G_OBJECT(info->generators[i].instance));
+
+ reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations concernant une ligne à actualiser. *
+* generator = générateur à associer à toutes les lignes. *
+* *
+* Description : Ajoute un générateur aux informations sur une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void extend_cache_info(cache_info *info, GLineGenerator *generator)
+{
+ generator_link first; /* Générateur déjà en place */
+ generator_link *new; /* Nouveau générateur placé */
+
+ if (info->count == 1)
+ {
+ first = info->generator;
+
+ info->generators = (generator_link *)calloc(2, sizeof(generator_link));
+
+ info->generators[0] = first;
+ info->count = 2;
+
+ new = &info->generators[1];
+
+ }
+ else
+ {
+ info->generators = (generator_link *)realloc(info->generators,
+ ++info->count * sizeof(generator_link));
+
+ new = &info->generators[info->count - 1];
+
+ }
+
+ new->instance = generator;
+ new->repeat = 0;
+
+ g_object_ref(G_OBJECT(generator));
+
+ reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations concernant une ligne à actualiser. *
+* generator = générateur à dissocier de toutes les lignes. *
+* *
+* Description : Retire un générateur aux informations d'une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
+{
+ generator_link *link; /* Accès simplifié */
+ size_t i; /* Boucle de parcours */
+ generator_link *old; /* Mémorisation avant opérat° */
+
+ if (info->count == 1)
+ {
+ link = &info->generator;
+
+ assert(link->instance == generator);
+
+ g_object_unref(G_OBJECT(generator));
+
+ info->count = 0;
+
+ }
+
+ else
+ {
+ for (i = 0; i < info->count; i++)
+ {
+ link = &info->generators[i];
+
+ if (link->instance == generator)
+ {
+ if ((i + 1) < info->count)
+ memmove(&info->generators[i], &info->generators[i + 1],
+ (info->count - i - 1) * sizeof(generator_link));
+
+ if (info->count == 2)
+ {
+ old = info->generators;
+
+ info->count = 1;
+ info->generator = info->generators[0];
+
+ free(old);
+
+ }
+ else
+ info->generators = (generator_link *)realloc(info->generators,
+ --info->count * sizeof(generator_link));
+
+ break;
+
+ }
+
+ }
+
+#ifndef NDEBUG
+
+ /**
+ * Attention : si l'élément était en dernière position,
+ * l'indice de parcours est désormais égal au nombre de générateurs présents !
+ */
+ assert(i <= info->count);
+
+ for ( ; i < info->count; i++)
+ {
+ link = &info->generators[i];
+
+ assert(link->instance != generator);
+
+ }
+
+#endif
+
+ }
+
+ reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations sur une ligne à venir consulter. *
+* index = indice de la ligne visée par la consultation. *
+* x = position géographique sur la ligne concernée. *
+* addr = adresse à renseigner. [OUT] *
+* *
+* Description : Retrouve l'emplacement correspondant à une position de ligne.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void get_cache_info_addr(const cache_info *info, size_t index, gint x, vmpa2t *addr)
+{
+ const generator_link *generator; /* Générateur retenu */
+
+ if (info->count == 1)
+ generator = &info->generator;
+ else
+ generator = &info->generators[0];
+
+ g_line_generator_compute_addr(generator->instance, x, addr, index, generator->repeat);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations sur une ligne à venir manipuler. *
+* line = tampon de lignes à venir supprimer au besoin. *
+* last = indication sur la valeur du compteur de références. *
+* *
+* Description : Suivit les variations du compteur de références d'une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_ref_toggle(cache_info *info, GBufferLine *line, gboolean last)
+{
+ if (last)
+ {
+ G_LOCK(_line_update);
+
+ assert(info->line != NULL);
+
+ info->line = NULL;
+
+ G_UNLOCK(_line_update);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations sur une ligne à venir manipuler. *
+* index = indice de la ligne à constituer. *
+* *
+* Description : Fournit la ligne de tampon correspondant aux générateurs. *
+* *
+* Retour : Ligne déjà en place ou créée pour le besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBufferLine *get_cache_info_line(cache_info *info, size_t index)
+{
+ GBufferLine *result; /* Construction à retourner */
+ size_t i; /* Boucle de parcours */
+
+ G_LOCK(_line_update);
+
+ result = info->line;
+
+ if (result == NULL)
+ {
+ result = g_buffer_line_new((mrange_t []){ { { 0 }, 0 } }, 0/* !! */);
+
+ g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info);
+
+ if (info->count == 1)
+ g_line_generator_print(info->generator.instance, result, index, info->generator.repeat);
+
+ else
+ for (i = 0; i < info->count; i++)
+ g_line_generator_print(info->generators[i].instance, result, index, info->generators[i].repeat);
+
+ info->line = result;
+
+ }
+
+ else
+ g_object_ref(G_OBJECT(result));
+
+ G_UNLOCK(_line_update);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations sur une ligne à venir manipuler. *
+* *
+* Description : Force la réinitialisation d'une éventuelle ligne cachée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void reset_cache_info_line(cache_info *info)
+{
+ G_LOCK(_line_update);
+
+ if (info->line != NULL)
+ {
+ g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info);
+
+ g_object_unref(G_OBJECT(info->line));
+
+ info->line = NULL;
+
+ }
+
+ G_UNLOCK(_line_update);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* TAMPON POUR CODE DESASSEMBLE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type du composant de tampon pour gestion de lignes optimisée. */
+G_DEFINE_TYPE(GBufferCache, g_buffer_cache, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de tampon de lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_cache_class_init(GBufferCacheClass *class)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_cache_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_buffer_cache_finalize;
+
+ class->line_height = 17;
+ class->left_margin = 2 * class->line_height;
+ class->text_pos = 2.5 * class->line_height;
+
+ /* Signaux */
+
+ g_signal_new("size-changed",
+ G_TYPE_BUFFER_CACHE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GBufferCacheClass, size_changed),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG,
+ G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un tampon de gestion de lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_cache_init(GBufferCache *cache)
+{
+ cache->tracker = g_width_tracker_new(cache);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_cache_dispose(GBufferCache *cache)
+{
+ size_t i; /* Boucle de parcours #1 */
+ cache_info *info; /* Accès directe à une ligne */
+ size_t j; /* Boucle de parcours #2 */
+
+ for (i = 0; i < cache->used; i++)
+ {
+ info = &cache->lines[i];
+
+ if (info->count == 1)
+ g_object_unref(G_OBJECT(info->generator.instance));
+
+ else
+ for (j = 0; j < info->count; j++)
+ g_object_unref(G_OBJECT(info->generators[j].instance));
+
+ if (info->line)
+ g_object_unref(G_OBJECT(info->line));
+
+ }
+
+ g_object_unref(G_OBJECT(cache->tracker));
+
+ G_OBJECT_CLASS(g_buffer_cache_parent_class)->dispose(G_OBJECT(cache));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_cache_finalize(GBufferCache *cache)
+{
+ size_t i; /* Boucle de parcours */
+ cache_info *info; /* Accès directe à une ligne */
+
+ for (i = 0; i < cache->used; i++)
+ {
+ info = &cache->lines[i];
+
+ if (info->count > 1)
+ free(info->generators);
+
+ }
+
+ if (cache->lines != NULL)
+ free(cache->lines);
+
+ G_OBJECT_CLASS(g_buffer_cache_parent_class)->finalize(G_OBJECT(cache));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée un nouveau composant de tampon pour code désassemblé. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferCache *g_buffer_cache_new(void)
+{
+ GBufferCache *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_BUFFER_CACHE, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* *
+* Description : Fournit la hauteur d'impression d'une ligne visualisée. *
+* *
+* Retour : Hauteur de ligne en pixels. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_cache_get_line_height(const GBufferCache *cache)
+{
+ GBufferCacheClass *class; /* Classe des tampons */
+
+ class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+ return class->line_height;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* *
+* Description : Fournit la taille réservée pour la marge gauche. *
+* *
+* Retour : Largeur en pixels. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_cache_get_left_margin(const GBufferCache *cache)
+{
+ GBufferCacheClass *class; /* Classe des tampons */
+
+ class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+ return class->left_margin;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* *
+* Description : Fournit la position de départ pour l'impression de texte. *
+* *
+* Retour : Position en pixels. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_cache_get_text_position(const GBufferCache *cache)
+{
+ GBufferCacheClass *class; /* Classe des tampons */
+
+ class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+ return class->text_pos;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à consulter. *
+* *
+* Description : Compte le nombre de lignes rassemblées dans un tampon. *
+* *
+* Retour : Nombre de lignes constituant le tampon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_buffer_cache_count_lines(const GBufferCache *cache)
+{
+ return cache->used;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = composant GLib à consulter. *
+* *
+* Description : Fournit un lien vers la structure de suivi de largeurs. *
+* *
+* Retour : Gestionnaire de largeurs de lignes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache)
+{
+ return cache->tracker;
+
+}
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à consulter. *
+* index = indice de la ligne où se trouve le générateur. *
+* generator = générateur associé à au moins une ligne. *
+* *
+* Description : Calcule l'indice d'apparition d'un générateur dans le tampon.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator)
+{
+ size_t result; /* Compteur à retourner */
+ cache_info *info; /* Accès directe à une ligne */
+ size_t i; /* Boucle de parcours */
+
+ result = 0;
+
+ if (index > 0)
+ {
+ info = &cache->lines[index - 1];
+
+ if (info->count == 1)
+ {
+ if (info->generator.instance == generator)
+ result = info->generator.repeat + 1;
+
+ }
+
+ else
+ for (i = 0; i < info->count; i++)
+ if (info->generators[i].instance == generator)
+ {
+ result = info->generators[i].repeat + 1;
+ break;
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à modifier. *
+* index = point d'insertion, puis de sauvegarde. *
+* generator = générateur à insérer dans les lignes. *
+* before = précise l'emplacement final des nouvelles lignes.*
+* after = précise l'emplacement final des nouvelles lignes.*
+* *
+* Description : Insère un générateur dans des lignes à une position donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
+{
+#ifndef NDEBUG
+ vmpa2t gen_addr; /* Position du générateur */
+ vmpa2t line_addr; /* Position de la ligne */
+#endif
+ size_t needed; /* Emplacements nécessaires */
+ size_t i; /* Boucle de parcours */
+
+ assert(index < cache->used);
+
+ assert(!(before && after));
+
+#ifndef NDEBUG
+
+ g_line_generator_compute_addr(generator, 0, &gen_addr, index, 0);
+
+ get_cache_info_addr(&cache->lines[index], index, 0, &line_addr);
+
+ ///////////////////////////////////////
+ if (cmp_vmpa(&gen_addr, &line_addr) != 0) return;
+
+ assert(cmp_vmpa(&gen_addr, &line_addr) == 0);
+
+#endif
+
+ /* Cas particulier d'ajout en fin de cache... */
+ if (after && (index + 1) == cache->used)
+ {
+ g_buffer_cache_append(cache, generator, BLF_NONE);
+ goto gbcia_done;
+ }
+
+ /* Adaptation de l'espace */
+
+ needed = g_line_generator_count_lines(generator);
+
+ if (before || after)
+ {
+ if ((cache->used + needed) >= cache->count)
+ {
+ cache->count += needed + LINE_ALLOC_BULK;
+ cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
+ }
+ }
+#ifndef NDEBUG
+ else
+ assert(needed == 1);
+#endif
+
+ /* Insertion du générateur */
+
+ if (after)
+ index++;
+
+ if (before || after)
+ {
+ memmove(&cache->lines[index], &cache->lines[index + needed], (cache->used - index) * sizeof(cache_info));
+
+ for (i = 0; i < needed; i++)
+ init_cache_info(&cache->lines[index + i], generator, i, BLF_NONE);
+
+ cache->used += needed;
+
+ g_width_tracker_update_added(cache->tracker, index, needed);
+
+ g_signal_emit_by_name(cache, "size-changed", true, index, needed);
+
+ }
+
+ else
+ {
+ extend_cache_info(&cache->lines[index], generator);
+
+ g_width_tracker_update(cache->tracker, index);
+
+ g_signal_emit_by_name(cache, "size-changed", true, index, 1);
+
+ }
+
+ gbcia_done:
+
+ ;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à modifier. *
+* index = point d'insertion, puis de sauvegarde. *
+* type = type de générateurs à retirer des lignes visées. *
+* before = précise l'emplacement final de l'élément visé. *
+* after = précise l'emplacement final de l'élément visé. *
+* *
+* Description : Retire un type de générateur de lignes. *
+* *
+* Retour : Générateur éventuellement trouvé ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
+{
+ GLineGenerator *result; /* Prédécesseur à retourner */
+ cache_info *info; /* Accès directe à une ligne */
+ generator_link *link; /* Accès simplifié */
+ size_t i; /* Boucle de parcours */
+ size_t count; /* Emplacements occupés */
+ size_t delete; /* Indice de suppression */
+
+ assert(index < cache->used);
+
+ assert(!(before && after));
+
+ result = NULL;
+
+ /* Recherche d'un générateur correspondant */
+
+ if (before)
+ info = &cache->lines[index - 1];
+ else if (after)
+ info = &cache->lines[index + 1];
+ else
+ info = &cache->lines[index];
+
+ if (info->count == 1)
+ {
+ link = &info->generator;
+
+ if (G_OBJECT_TYPE(link->instance) == type)
+ result = link->instance;
+
+ }
+
+ else
+ for (i = 0; i < info->count && result == NULL; i++)
+ {
+ link = &info->generators[i];
+
+ if (G_OBJECT_TYPE(link->instance) == type)
+ result = link->instance;
+
+ }
+
+ /* Retrait de l'instance trouvée */
+
+ if (result != NULL)
+ {
+ count = g_line_generator_count_lines(result);
+
+#ifndef NDEBUG
+ if (!before && !after)
+ assert(count == 1);
+#endif
+
+ g_object_ref(G_OBJECT(result));
+
+ /* Suppression de l'élément */
+
+ for (i = 0; i < count; i++)
+ {
+ if (before)
+ info = &cache->lines[index - 1 - i];
+ else if (after)
+ info = &cache->lines[index + 1 + i];
+ else
+ info = &cache->lines[index];
+
+ remove_from_cache_info(info, result);
+
+ }
+
+ /* Suppression des lignes associées */
+
+ for (i = 0; i < count; i++)
+ {
+ if (before)
+ delete = index - 1;
+ else if (after)
+ delete = index + 1;
+ else
+ delete = index;
+
+ info = &cache->lines[delete];
+
+ if (info->count == 0)
+ {
+ release_cache_info(info);
+
+ if ((delete + 1) < cache->used)
+ memmove(&cache->lines[delete], &cache->lines[delete + 1],
+ (cache->used - delete - 1) * sizeof(cache_info));
+
+ cache->used--;
+
+ g_width_tracker_update_deleted(cache->tracker, delete, delete);
+
+ g_signal_emit_by_name(cache, "size-changed", false, delete, 1);
+
+ }
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à modifier. *
+* generator = générateur à associer à toutes les lignes. *
+* flags = propriétés supplémentaires à associer à la ligne.*
+* *
+* Description : Ajoute en fin de tampon un générateur de lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, BufferLineFlags flags)
+{
+ size_t count; /* Nombre de lignes générées */
+ size_t index; /* Point d'insertion */
+ size_t i; /* Boucle de parcours */
+ cache_info *info; /* Accès directe à une ligne */
+
+ count = g_line_generator_count_lines(generator);
+
+ assert(count > 0);
+
+ assert((flags != BLF_NONE && count == 1) || flags == BLF_NONE);
+
+ if ((cache->used + count) > cache->count)
+ {
+ cache->count += count + LINE_ALLOC_BULK;
+ cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
+ }
+
+ index = cache->used;
+
+ for (i = 0; i < count; i++)
+ {
+ info = &cache->lines[index + i];
+
+ info->generator.instance = generator;
+ info->generator.repeat = g_buffer_cache_compute_repetition(cache, index + i, generator);
+
+ g_object_ref(G_OBJECT(generator));
+
+ info->count = 1;
+
+ info->line = NULL;
+
+ info->extra_flags = flags;
+
+ }
+
+ cache->used += count;
+
+ g_object_unref(G_OBJECT(generator));
+
+ g_width_tracker_update_added(cache->tracker, index, count);
+
+ g_signal_emit_by_name(cache, "size-changed", true, index, count);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à modifier. *
+* count = quantité totale de lignes à avoir à disposition. *
+* generator = générateur à associer à toutes les lignes. *
+* *
+* Description : Etend un tampon avec un générateur de lignes unique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerator *generator)
+{
+ size_t index; /* Point d'insertion */
+ size_t i; /* Boucle de parcours */
+ cache_info *info; /* Accès directe à une ligne */
+ size_t added; /* Nombre d'ajouts effectués */
+
+ assert(count >= cache->used);
+
+ if (count > cache->count)
+ {
+ cache->lines = (cache_info *)realloc(cache->lines, count * sizeof(cache_info));
+ cache->count = count;
+ }
+
+ index = cache->used;
+
+ for (i = index; i < count; i++)
+ {
+ info = &cache->lines[i];
+
+ info->generator.instance = generator;
+ info->generator.repeat = g_buffer_cache_compute_repetition(cache, i, generator);
+
+ g_object_ref(G_OBJECT(generator));
+
+ info->count = 1;
+
+ info->line = NULL;
+
+ }
+
+ added = count - cache->used;
+
+ cache->used = count;
+
+ g_object_unref(G_OBJECT(generator));
+
+ if (added > 0)
+ {
+ g_width_tracker_update_added(cache->tracker, index, added);
+
+ g_signal_emit_by_name(cache, "size-changed", true, index, added);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = instance GLib à modifier. *
+* max = nombre maximal de lignes à conserver. *
+* *
+* Description : Réduit le tampon à une quantité de lignes précise. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
+{
+ size_t i; /* Boucle de parcours #1 */
+ cache_info *info; /* Accès directe à une ligne */
+ size_t j; /* Boucle de parcours #2 */
+ size_t removed; /* Nombre de retraits effectués*/
+
+ assert(max <= cache->used);
+
+ for (i = max; i < cache->used; i++)
+ {
+ info = &cache->lines[i];
+
+ if (info->count == 1)
+ g_object_unref(G_OBJECT(info->generator.instance));
+
+ else
+ {
+ for (j = 0; j < info->count; j++)
+ g_object_unref(G_OBJECT(info->generators[j].instance));
+
+ free(info->generators);
+
+ }
+
+ reset_cache_info_line(info);
+
+ }
+
+ removed = cache->used - max;
+
+ cache->used = max - 1;
+
+ if (removed > 0)
+ {
+ g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1);
+
+ g_signal_emit_by_name(cache, "size-changed", false, max, removed);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à venir consulter. *
+* index = indice de la ligne visée par la consultation. *
+* x = position géographique sur la ligne concernée. *
+* addr = adresse à renseigner. [OUT] *
+* *
+* Description : Retrouve l'emplacement correspondant à une position de ligne.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_get_line_addr(const GBufferCache *cache, size_t index, gint x, vmpa2t *addr)
+{
+ assert(index < cache->used);
+
+ get_cache_info_addr(&cache->lines[index], index, x, addr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à venir consulter. *
+* index = indice de la ligne visée par la consultation. *
+* *
+* Description : Détermine l'ensemble des propriétés attachées à une ligne. *
+* *
+* Retour : Somme de toutes les propriétés enregistrées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *cache, size_t index)
+{
+ BufferLineFlags result; /* Somme à renvoyer */
+ cache_info *info; /* Accès directe à une ligne */
+ const generator_link *generator; /* Générateur retenu */
+ size_t i; /* Boucle de parcours */
+
+ assert(index < cache->used);
+
+ info = &cache->lines[index];
+
+ result = info->extra_flags;
+
+ if (info->count == 1)
+ {
+ generator = &info->generator;
+ result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
+ }
+
+ else
+ for (i = 0; i < info->count; i++)
+ {
+ generator = &info->generators[i];
+ result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* index = indice de la ligne recherchée. *
+* *
+* Description : Retrouve une ligne au sein d'un tampon avec un indice. *
+* *
+* Retour : Line retrouvée ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *cache, size_t index)
+{
+ GBufferLine *result; /* Ligne trouvée à retourner */
+
+ if (index < cache->used)
+ result = get_cache_info_line(&cache->lines[index], index);
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à venir consulter. *
+* index = indice de la ligne à mesurer. *
+* summary = largeurs maximales à faire évoluer. *
+* *
+* Description : Fait remonter les largeurs requises par une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_collect_widths(GBufferCache *cache, size_t index, line_width_summary *summary)
+{
+ GBufferLine *line; /* Ligne éphémère à mesurer */
+
+ line = get_cache_info_line(&cache->lines[index], index);
+
+ g_buffer_line_collect_widths(line, summary);
+
+ g_object_unref(G_OBJECT(line));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = visualisation à représenter. *
+* cr = contexte graphique dédié à la procédure. *
+* first = première ligne à dessiner. *
+* last = dernière ligne à dessiner. *
+* area = position et surface à traiter. *
+* display = règles d'affichage des colonnes modulables. *
+* selected = ordonnée d'une ligne sélectionnée ou NULL. *
+* list = liste de contenus à mettre en évidence. *
+* *
+* Description : Imprime une partie choisie du tampon contenant des lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, size_t last, const cairo_rectangle_int_t *area, const bool *display, const gint *selected, const segcnt_list *list)
+{
+ GBufferCacheClass *class; /* Classe des tampons */
+ gint y; /* Point de départ en ordonnée */
+ bool wait_selection; /* Sélection déjà passée ? */
+ size_t i; /* Boucle de parcours */
+ cache_info *info; /* Accès directe à une ligne */
+ line_width_summary summary; /* Résumé concis des largeurs */
+ GBufferLine *line; /* Ligne à venir dessiner */
+
+ class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+ y = 0;
+
+ wait_selection = true;
+
+ if (cache->used > 0)
+ for (i = first; i <= last; i++)
+ {
+ /* Si sélection, on sousligne la ligne concernée */
+ if (wait_selection && selected != NULL && *selected == y)
+ {
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
+
+ cairo_rectangle(cr, area->x, y, area->width, class->line_height);
+ cairo_fill(cr);
+
+ wait_selection = false;
+
+ }
+
+ info = &cache->lines[i];
+
+ if (i == first || (g_buffer_cache_get_line_flags(cache, i) & BLF_WIDTH_MANAGER))
+ g_width_tracker_get_local_width_summary(cache->tracker, i, &summary);
+
+ line = get_cache_info_line(info, i);
+
+ g_buffer_line_draw(line, cr, &summary, class->text_pos, y, display, list);
+
+ g_object_unref(G_OBJECT(line));
+
+ y += class->line_height;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* addr = adresse à retrouver dans le tampon. *
+* first = indique si on l'arrête à la première ou la dernière. *
+* start = borne inférieure des recherches (incluse). *
+* end = borne supérieure des recherches (incluse). *
+* *
+* Description : Indique l'indice correspondant à une adresse donnée. *
+* *
+* Retour : Indice des infos à l'adresse demandée, ou nombre de lignes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2t *addr, bool first, size_t start, size_t end)
+{
+ size_t result; /* Indice à retourner */
+ cache_info *found; /* Eventuel élément trouvé */
+
+ int find_containing_generator(const vmpa2t *a, const cache_info *i)
+ {
+ const generator_link *generator; /* Générateur retenu */
+
+ if (i->count == 1)
+ generator = &i->generator;
+ else
+ generator = &i->generators[0];
+
+ return g_line_generator_contains_addr(generator->instance, addr,
+ i - cache->lines, generator->repeat);
+
+ }
+
+ found = (cache_info *)bsearch(addr, &cache->lines[start], end - start + 1,
+ sizeof(cache_info), (__compar_fn_t)find_containing_generator);
+
+ if (found == NULL)
+ result = cache->used;
+
+ else
+ {
+ result = (found - cache->lines);
+ assert(start <= result && result <= end);
+
+ /* On s'assure d'un arrêt sur la bonne ligne */
+
+ if (first)
+ for (; result > start; result--)
+ {
+ found = &cache->lines[result - 1];
+
+ if (find_containing_generator(addr, found) != 0)
+ break;
+
+ }
+
+ else
+ for (; result < end; result++)
+ {
+ found = &cache->lines[result + 1];
+
+ if (find_containing_generator(addr, found) != 0)
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* addr = adresse à retrouver dans le tampon. *
+* first = indique si on l'arrête à la première ou la dernière. *
+* *
+* Description : Indique l'indice correspondant à une adresse donnée. *
+* *
+* Retour : Indice des infos à l'adresse demandée, ou nombre de lignes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2t *addr, bool first)
+{
+ size_t result; /* Indice à retourner */
+
+ if (cache->used == 0)
+ result = 0;
+ else
+ result = _g_buffer_cache_find_index_by_addr(cache, addr, first, 0, cache->used - 1);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* start = point de départ du parcours. *
+* flag = propriétés à retrouver si possible. *
+* *
+* Description : Avance autant que possible vers une ligne idéale. *
+* *
+* Retour : Indice de la ligne recherchée, si elle existe. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_buffer_cache_look_for_flag(const GBufferCache *cache, size_t start, BufferLineFlags flag)
+{
+ size_t result; /* Indice de ligne à retourner */
+ vmpa2t start_addr; /* Localisation de départ */
+ size_t i; /* Boucle de parcours */
+ vmpa2t addr; /* Localisation suivante */
+
+ assert(start < cache->used);
+
+ result = start;
+
+ get_cache_info_addr(&cache->lines[start], start, 0, &start_addr);
+
+ for (i = start + 1; i < cache->used; i++)
+ {
+ get_cache_info_addr(&cache->lines[i], i, 0, &addr);
+
+ if (cmp_vmpa(&start_addr, &addr) != 0)
+ break;
+
+ if ((g_buffer_cache_get_line_flags(cache, i) & flag) != 0)
+ {
+ result = i;
+ break;
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cache = tampon de lignes à consulter. *
+* addr = adresse à présenter à l'écran. *
+* first = borne inférieure des recherches (incluse). *
+* last = borne supérieure des recherches (incluse). *
+* code = s'arrête si possible à une ligne avec code. *
+* x = position horizontale au sein du composant. [OUT] *
+* y = position verticale au sein du composant. [OUT] *
+* *
+* Description : Indique la position d'affichage d'une adresse donnée. *
+* *
+* Retour : true si l'adresse fait partie du composant, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_buffer_cache_get_address_coordinates(const GBufferCache *cache, const vmpa2t *addr, size_t first, size_t last, bool code, gint *x, gint *y)
+{
+ bool result; /* Bilan à retourner */
+ size_t index; /* Indice de correspondance */
+ gint lheight; /* Hauteur d'une ligne */
+ const cache_info *info; /* Infos sur une ligne donnée */
+ const generator_link *generator; /* Générateur retenu */
+
+ index = _g_buffer_cache_find_index_by_addr(cache, addr, true, first, last);
+
+ result = (index < cache->used);
+
+ if (result)
+ {
+ lheight = G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
+
+ *x = 0;
+ *y = (index - first) * G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
+
+ for (; code && index <= last; index++)
+ {
+ if (g_buffer_cache_get_line_flags(cache, index) & BLF_HAS_CODE)
+ break;
+
+ if (index == last)
+ break;
+
+ info = &cache->lines[index + 1];
+
+ if (info->count == 1)
+ generator = &info->generator;
+ else
+ generator = &info->generators[0];
+
+ if (!g_line_generator_contains_addr(generator->instance, addr, index + 1, generator->repeat))
+ break;
+
+ *y += lheight;
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
new file mode 100644
index 0000000..6e9c314
--- /dev/null
+++ b/src/glibext/gbuffercache.h
@@ -0,0 +1,121 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gbuffercache.h - prototypes pour l'affichage à la demande d'un ensemble de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_GBUFFERCACHE_H
+#define _GLIBEXT_GBUFFERCACHE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <gdk/gdk.h>
+
+
+#include "gwidthtracker.h"
+#include "linegen.h"
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+#define G_TYPE_BUFFER_CACHE (g_buffer_cache_get_type())
+#define G_BUFFER_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GBufferCache))
+#define G_BUFFER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GBufferCacheClass))
+#define G_IS_BUFFER_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_BUFFER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_BUFFER_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GBufferCacheClass))
+
+
+/* Tampon pour gestion de lignes optimisée (instance) */
+typedef struct _GBufferCache GBufferCache;
+
+/* Tampon pour gestion de lignes optimisée (classe) */
+typedef struct _GBufferCacheClass GBufferCacheClass;
+
+
+/* Détermine le type du composant de tampon pour gestion de lignes optimisée. */
+GType g_buffer_cache_get_type(void);
+
+/* Crée un nouveau composant de tampon pour code désassemblé. */
+GBufferCache *g_buffer_cache_new(void);
+
+/* Fournit la hauteur d'impression d'une ligne visualisée. */
+gint g_buffer_cache_get_line_height(const GBufferCache *);
+
+/* Fournit la taille réservée pour la marge gauche. */
+gint g_buffer_cache_get_left_margin(const GBufferCache *);
+
+/* Fournit la position de départ pour l'impression de texte. */
+gint g_buffer_cache_get_text_position(const GBufferCache *);
+
+/* Compte le nombre de lignes rassemblées dans un tampon. */
+size_t g_buffer_cache_count_lines(const GBufferCache *);
+
+/* Fournit un lien vers la structure de suivi de largeurs. */
+const GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *);
+
+/* Insère un générateur dans des lignes à une position donnée. */
+void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, bool, bool);
+
+/* Retire un type de générateur de lignes. */
+GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *, size_t, GType, bool, bool);
+
+/* Ajoute en fin de tampon un générateur de lignes. */
+void g_buffer_cache_append(GBufferCache *, GLineGenerator *, BufferLineFlags);
+
+/* Etend un tampon avec un générateur de lignes unique. */
+void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *);
+
+/* Réduit le tampon à une quantité de lignes précise. */
+void g_buffer_cache_truncate(GBufferCache *, size_t);
+
+/* Retrouve l'emplacement correspondant à une position de ligne. */
+void g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
+/* Détermine l'ensemble des propriétés attachées à une ligne. */
+BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t);
+
+/* Retrouve une ligne au sein d'un tampon avec un indice. */
+GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *, size_t);
+
+/* Fait remonter les largeurs requises par une ligne donnée. */
+void g_buffer_cache_collect_widths(GBufferCache *, size_t, line_width_summary *);
+
+/* Imprime une partie choisie du tampon contenant des lignes. */
+void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const bool *, const gint *, const segcnt_list *);
+
+/* Indique l'indice correspondant à une adresse donnée. */
+size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *, const vmpa2t *, bool, size_t, size_t);
+
+/* Indique l'indice correspondant à une adresse donnée. */
+size_t g_buffer_cache_find_index_by_addr(const GBufferCache *, const vmpa2t *, bool);
+
+/* Avance autant que possible vers une ligne idéale. */
+size_t g_buffer_cache_look_for_flag(const GBufferCache *, size_t, BufferLineFlags);
+
+/* Indique la position d'affichage d'une adresse donnée. */
+bool g_buffer_cache_get_address_coordinates(const GBufferCache *, const vmpa2t *, size_t, size_t, bool, gint *, gint *);
+
+
+
+#endif /* _GLIBEXT_GBUFFERCACHE_H */
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 5f1756d..768cbca 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -56,7 +56,7 @@ struct _GBufferLine
mrange_t range; /* Couverture geographique */
BufferLineColumn main_column; /* Colonne principale */
- line_column columns[BLC_COUNT]; /* Répartition du texte */
+ line_column columns[BLC_COUNT]; /* Répartition du texte */
BufferLineColumn merge_start; /* Début de la zone globale */
BufferLineColumn last_used; /* Dernière colonne utilisée */
@@ -72,7 +72,6 @@ struct _GBufferLine
gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */
gint merged_width; /* Largeur cumulée avant fusion*/
};
- GBufferLine *manager; /* Représentante d'un groupe */
};
};
@@ -214,9 +213,6 @@ static void g_buffer_line_dispose(GBufferLine *line)
{
size_t i; /* Boucle de parcours */
- if (line->flags & BLF_WIDTH_MANAGER)
- g_object_unref(G_OBJECT(line->manager));
-
for (i = 0; i < line->ocount; i++)
g_object_unref(G_OBJECT(line->origins[i].creator));
@@ -298,9 +294,9 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
/******************************************************************************
* *
-* Paramètres : line = ligne à venir compléter. *
-* psize = taille souhaitée de l'impression des positions. *
-* vsize = taille souhaitée de l'impression des adresses. *
+* Paramètres : line = ligne à venir compléter. *
+* size = taille souhaitée de l'impression des positions. *
+* addr = localisation physique à venir représenter. *
* *
* Description : Construit le tronc commun d'une ligne autour de sa position. *
* *
@@ -310,61 +306,105 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
* *
******************************************************************************/
-void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize)
+void g_buffer_line_fill_phys(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
{
+ VMPA_BUFFER(position); /* Emplacement au format texte */
size_t len; /* Taille de l'élément inséré */
- VMPA_BUFFER(address); /* Adresse au format texte */
- size_t i; /* Boucle de parcours */
+ size_t i; /* Boucle de parcours #1 */
- /* Position physique */
+ vmpa2_phys_to_string(addr, size, position, &len);
- if (has_phys_addr(get_mrange_addr(&line->range)))
- {
- mrange_phys_to_string(&line->range, psize, true, address, &len);
+ for (i = 2; i < len; i++)
+ if (position[i] != '0') break;
- for (i = 2; i < len; i++)
- if (address[i] != '0') break;
+ if (i == len)
+ i = len - 1;
- if (i == len)
- g_buffer_line_append_text(line, BLC_PHYSICAL, address, len, RTT_PHYS_ADDR_PAD, NULL);
+ if (i > 0)
+ g_buffer_line_append_text(line, BLC_PHYSICAL, position, i, RTT_PHYS_ADDR_PAD, NULL);
- else
- {
- g_buffer_line_append_text(line, BLC_PHYSICAL, address, 2, RTT_PHYS_ADDR, NULL);
+ g_buffer_line_append_text(line, BLC_PHYSICAL, &position[i], len - i, RTT_PHYS_ADDR, NULL);
- if (i > 2)
- g_buffer_line_append_text(line, BLC_PHYSICAL, &address[2], i - 2, RTT_PHYS_ADDR_PAD, NULL);
+}
- g_buffer_line_append_text(line, BLC_PHYSICAL, &address[i], len - i, RTT_PHYS_ADDR, NULL);
- }
+/******************************************************************************
+* *
+* Paramètres : line = ligne à venir compléter. *
+* size = taille souhaitée de l'impression des positions. *
+* addr = localisation virtuelle à venir représenter. *
+* *
+* Description : Construit le tronc commun d'une ligne autour de sa position. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- }
+void g_buffer_line_fill_virt(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
+{
+ VMPA_BUFFER(position); /* Emplacement au format texte */
+ size_t len; /* Taille de l'élément inséré */
+ size_t i; /* Boucle de parcours #1 */
+
+ vmpa2_virt_to_string(addr, size, position, &len);
+
+ for (i = 2; i < len; i++)
+ if (position[i] != '0') break;
+
+ if (i == len)
+ i = len - 1;
+
+ if (i > 0)
+ g_buffer_line_append_text(line, BLC_VIRTUAL, position, i, RTT_PHYS_ADDR_PAD, NULL);
- /* Adresse virtuelle */
+ g_buffer_line_append_text(line, BLC_VIRTUAL, &position[i], len - i, RTT_PHYS_ADDR, NULL);
+
+}
- if (has_virt_addr(get_mrange_addr(&line->range)))
- {
- mrange_virt_to_string(&line->range, vsize, true, address, &len);
- for (i = 2; i < len; i++)
- if (address[i] != '0') break;
+/******************************************************************************
+* *
+* Paramètres : line = ligne à venir compléter. *
+* addr = localisation à afficher. *
+* psize = taille souhaitée de l'impression des positions. *
+* vsize = taille souhaitée de l'impression des adresses. *
+* *
+* Description : Construit le tronc commun d'une ligne autour de sa position. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- if (i == len)
- g_buffer_line_append_text(line, BLC_VIRTUAL, address, len, RTT_VIRT_ADDR_PAD, NULL);
+void g_buffer_line_fill_vmpa(GBufferLine *line, const vmpa2t *addr, MemoryDataSize psize, MemoryDataSize vsize)
+{
+ g_buffer_line_fill_phys(line, psize, addr);
- else
- {
- g_buffer_line_append_text(line, BLC_VIRTUAL, address, 2, RTT_VIRT_ADDR, NULL);
+ g_buffer_line_fill_virt(line, vsize, addr);
- if (i > 2)
- g_buffer_line_append_text(line, BLC_VIRTUAL, &address[2], i - 2, RTT_VIRT_ADDR_PAD, NULL);
+}
- g_buffer_line_append_text(line, BLC_VIRTUAL, &address[i], len - i, RTT_VIRT_ADDR, NULL);
- }
+/******************************************************************************
+* *
+* Paramètres : line = ligne à venir compléter. *
+* psize = taille souhaitée de l'impression des positions. *
+* vsize = taille souhaitée de l'impression des adresses. *
+* *
+* Description : Construit le tronc commun d'une ligne autour de sa position. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- }
+void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize)
+{
+ g_buffer_line_fill_vmpa(line, get_mrange_addr(&line->range), psize, vsize);
}
@@ -531,7 +571,7 @@ void g_buffer_line_append_text(GBufferLine *line, BufferLineColumn column, const
assert(length > 0);
if (column == BLC_MAIN)
- column = line->main_column;
+ column = BLC_ASSEMBLY;//line->main_column;
if (column == BLC_LAST_USED)
column = line->last_used;
@@ -938,6 +978,13 @@ void g_buffer_line_collect_widths(GBufferLine *line, line_width_summary *summary
{
width = get_column_width(&line->columns[i]);
+
+ /*
+ if (i == BLC_ASSEMBLY_HEAD)
+ assert(width > 0);
+ */
+
+
if (i < line->merge_start)
summary->max_widths[i] = MAX(summary->max_widths[i], width);
@@ -1008,7 +1055,10 @@ const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line
{
line_segment *result; /* Trouvaille à retourner */
- result = get_line_column_content_from_index(&line->columns[coord->column], coord->index);
+ if (coord->column < BLC_COUNT)
+ result = get_line_column_content_from_index(&line->columns[coord->column], coord->index);
+ else
+ result = false;
return result;
@@ -1069,6 +1119,9 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
{
width = g_buffer_line_compute_max_width(line, i, summary);
+ /* Si la colonne n'est absolument pas visible, on ne s'arrête pas dessus ! */
+ if (width == 0) continue;
+
if ((i + 1) < BLC_COUNT) limit = width + COL_MARGIN / 2;
else limit = width;
@@ -1139,7 +1192,10 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
if ((i - 1) < line->merge_start)
{
width = g_buffer_line_compute_max_width(line, i - 1, summary);
- *base += (width + COL_MARGIN);
+
+ if (width > 0)
+ *base += (width + COL_MARGIN);
+
}
else
*base += get_column_width(&line->columns[i - 1]);
@@ -1183,8 +1239,19 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
}
}
+
+ /* Il n'y a rien sur la ligne ! */
else
- result = false;
+ {
+ result = true;
+
+ *base = 0;
+ *offset = 0;
+
+ coord->column = BLC_COUNT;
+ coord->index = -1;
+
+ }
}
else
@@ -1305,6 +1372,7 @@ bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord,
BufferLineColumn i; /* Boucle de parcours #1 */
bool displayed; /* Confort de lecture */
BufferLineColumn k; /* Boucle de parcours #2 */
+ gint width; /* Largeur d'une colonne donnée*/
result = false;
@@ -1381,8 +1449,14 @@ bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord,
if (displayed)
{
- *offset += g_buffer_line_compute_max_width(line, k, summary);
- if (k < line->merge_start) *offset += COL_MARGIN;
+ width = g_buffer_line_compute_max_width(line, k, summary);
+
+ if (width > 0)
+ {
+ *offset += width;
+ if (k < line->merge_start) *offset += COL_MARGIN;
+ }
+
}
}
@@ -1469,10 +1543,8 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const line_width_summ
{
max_width = g_buffer_line_compute_max_width(line, i, summary);
- x += max_width;
-
if (max_width > 0)
- x += COL_MARGIN;
+ x += max_width + COL_MARGIN;
}
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index be7e138..a8d2f3f 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -109,6 +109,15 @@ GBufferLine *g_buffer_line_new(const mrange_t *, BufferLineColumn);
const mrange_t *g_buffer_line_get_range(const GBufferLine *);
/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_phys(GBufferLine *, MemoryDataSize, const vmpa2t *);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_virt(GBufferLine *, MemoryDataSize, const vmpa2t *);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_vmpa(GBufferLine *, const vmpa2t *, MemoryDataSize, MemoryDataSize);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize);
/* Construit le tronc commun d'une ligne d'instruction. */
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index 20d60ed..cd17191 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -24,14 +24,21 @@
#include "gbufferview.h"
+#include <assert.h>
+
+
/* Vue d'un tampon pour code désassemblé (instance) */
struct _GBufferView
{
GObject parent; /* A laisser en premier */
- GCodeBuffer *buffer; /* Tampon de code visualisé */
+ GBufferCache *cache; /* Tampon du contenu visualisé */
+
+ segcnt_list *highlighted; /* Segments mis en évidence */
+ bool external; /* Note l'origine de la liste */
+ bool unrestricted; /* Validité des informations */
vmpa2t start; /* Première ligne intégrée */
vmpa2t end; /* Dernière ligne intégrée */
@@ -45,11 +52,6 @@ struct _GBufferView
GWidthTracker *tracker; /* Suivi pour usage interne */
};
- bool unrestricted; /* Validité des informations */
-
- segcnt_list *highlighted; /* Segments mis en évidence */
- bool external; /* Note l'origine de la liste */
-
};
/* Vue d'un tampon pour code désassemblé (classe) */
@@ -57,10 +59,6 @@ struct _GBufferViewClass
{
GObjectClass parent; /* A laisser en premier */
- gint line_height; /* Hauteur maximale des lignes */
- gint left_margin; /* Marge gauche + espace */
- gint left_text; /* Début d'impression du code */
-
/* Signaux */
void (* need_redraw) (GBufferView *);
@@ -81,15 +79,23 @@ static void g_buffer_view_dispose(GBufferView *);
static void g_buffer_view_finalize(GBufferView *);
/* Accompagne une variation de la quantité de lignes du tampon. */
-static void on_buffer_size_changed(const GCodeBuffer *, bool, size_t, size_t, GBufferView *);
+static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *);
-/* Réagit à un changement de contenu d'une ligne donnée. */
-static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, line_segment *, GBufferView *);
+/* Calcule la position idéale de curseur pour un point donné. */
+bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const bool *, GdkRectangle *, vmpa2t *);
/* Déplace le curseur au sein d'une vue de tampon. */
static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, GdkRectangle *, bool, GdkScrollDirection, const bool *);
+/* Fournit la ligne présente à une ordonnée donnée. */
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
+
+
+
+
+
+
/* Détermine le type de la vue d'un tampon pour code désassemblé. */
G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT);
@@ -116,10 +122,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_view_dispose;
object->finalize = (GObjectFinalizeFunc)g_buffer_view_finalize;
- class->line_height = 17;
- class->left_margin = 2 * class->line_height;
- class->left_text = 2.5 * class->line_height;
-
+ /* Sigaux */
g_signal_new("need-redraw",
G_TYPE_BUFFER_VIEW,
@@ -146,7 +149,10 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
static void g_buffer_view_init(GBufferView *view)
{
- view->unrestricted = true;
+ /**
+ * Inversion du statut pour forcer l'actualisation lors de la création.
+ */
+ view->unrestricted = false;
}
@@ -165,7 +171,10 @@ static void g_buffer_view_init(GBufferView *view)
static void g_buffer_view_dispose(GBufferView *view)
{
- g_object_unref(G_OBJECT(view->buffer));
+ g_object_unref(G_OBJECT(view->cache));
+
+ if (!view->unrestricted)
+ g_object_unref(G_OBJECT(view->int_tracker));
G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view));
@@ -207,22 +216,17 @@ static void g_buffer_view_finalize(GBufferView *view)
* *
******************************************************************************/
-GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
+GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted)
{
GBufferView *result; /* Composant à retourner */
result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
- g_object_ref(G_OBJECT(buffer));
- result->buffer = buffer;
+ result->cache = cache;
g_buffer_view_restrict(result, NULL, NULL);
- g_code_buffer_register_view_callback(buffer,
- (buffer_size_changed_cb)on_buffer_size_changed,
- G_OBJECT(result));
-
- g_signal_connect(buffer, "line-changed", G_CALLBACK(on_buffer_line_changed), result);
+ g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result);
if (highlighted != NULL)
result->highlighted = highlighted;
@@ -238,11 +242,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
/******************************************************************************
* *
-* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
-* added = indication sur la variation de la taille du tampon. *
-* index = indice de la première ligne à traiter. *
-* count = nombre de lignes à traiter. *
-* view = vue active du tampon de lignes concerné. *
+* Paramètres : cache = tampon de lignes cohérentes à manipuler. *
+* added = indication sur la variation de la taille du tampon. *
+* index = indice de la première ligne à traiter. *
+* count = nombre de lignes à traiter. *
+* view = vue active du tampon de lignes concerné. *
* *
* Description : Accompagne une variation de la quantité de lignes du tampon. *
* *
@@ -252,11 +256,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
* *
******************************************************************************/
-static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t index, size_t count, GBufferView *view)
+static void on_buffer_cache_size_changed(const GBufferCache *cache, bool added, size_t index, size_t count, GBufferView *view)
{
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à manipuler */
- const vmpa2t *addr; /* Localisation de ligne */
+ //size_t i; /* Boucle de parcours */
+ //GBufferLine *line; /* Ligne à manipuler */
+ //const vmpa2t *addr; /* Localisation de ligne */
/**
* Il n'y a pas besoin de verrou ici car la fonction est appelée directement par le tampon.
@@ -270,6 +274,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else
{
+#if 0
+
/* Avant la zone représentée ? */
if (index < view->first)
{
@@ -281,6 +287,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else if (view->first == index)
for (i = 0; i < count; i++)
{
+ g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
line = g_code_buffer_find_line_by_index(buffer, index + i);
addr = get_mrange_addr(g_buffer_line_get_range(line));
@@ -302,6 +310,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else if ((view->last + 1) == index)
for (i = 0; i < count; i++)
{
+ g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
line = g_code_buffer_find_line_by_index(buffer, index + i);
addr = get_mrange_addr(g_buffer_line_get_range(line));
@@ -312,7 +322,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
}
- g_width_tracker_update_added(view->int_tracker, index, count);
+ //g_width_tracker_update_added(view->int_tracker, index, count);
+#endif
}
@@ -338,38 +349,36 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
}
- g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
+ //g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
}
- g_signal_emit_by_name(view, "need-redraw");
+ //g_signal_emit_by_name(view, "need-redraw");
}
/******************************************************************************
* *
-* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
-* line = ligne dont la définition vient d'évoluer. *
-* segment = éventuel segment qui vient d'évoluer ou NULL. *
-* view = vue active du tampon de lignes concerné. *
+* Paramètres : view = visualisateur à consulter. *
* *
-* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* Description : Fournit le tampon de code lié à un visualisateur donné. *
* *
-* Retour : - *
+* Retour : Tampon de code associé au gestionnaire d'affichage. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_segment *segment, GBufferView *view)
+GBufferCache *g_buffer_view_get_cache(const GBufferView *view)
{
- const vmpa2t *addr; /* Localisation de ligne */
+ GBufferCache *result; /* Instance à retourner */
- addr = get_mrange_addr(g_buffer_line_get_range(line));
+ result = view->cache;
- if (cmp_vmpa(&view->start, addr) <= 0 && cmp_vmpa(addr, &view->end) <= 0)
- g_signal_emit_by_name(view, "need-redraw");
+ g_object_ref(G_OBJECT(result));
+
+ return result;
}
@@ -390,33 +399,41 @@ static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_
void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t *end)
{
+ bool state; /* Nouvel état à proclamer */
const GWidthTracker *template; /* Suivi déjà en place */
- if (!view->unrestricted)
- g_object_unref(G_OBJECT(view->int_tracker));
+ state = (start == NULL || end == NULL);
- view->unrestricted = (start == NULL || end == NULL);
+ if (view->unrestricted != state)
+ {
+ view->unrestricted = state;
- template = g_code_buffer_get_width_tracker(view->buffer);
+ template = g_buffer_cache_get_width_tracker(view->cache);
- if (view->unrestricted)
- {
- view->first = 0;
- view->last = g_code_buffer_count_lines(view->buffer) - 1;
+ if (view->unrestricted)
+ {
+ /* Vérification pour le cas particulier du démarrage */
+ if (view->int_tracker != NULL)
+ g_object_unref(G_OBJECT(view->int_tracker));
- view->ext_tracker = template;
+ view->first = 0;
+ view->last = g_buffer_cache_count_lines(view->cache) - 1;
- }
+ view->ext_tracker = template;
- else
- {
- copy_vmpa(&view->start, start);
- copy_vmpa(&view->end, end);
+ }
+
+ else
+ {
+ copy_vmpa(&view->start, start);
+ copy_vmpa(&view->end, end);
+
+ view->first = g_buffer_cache_find_index_by_addr(view->cache, start, true);
+ view->last = g_buffer_cache_find_index_by_addr(view->cache, end, false);
- view->first = g_code_buffer_get_index_from_address(view->buffer, start, true);
- view->last = g_code_buffer_get_index_from_address(view->buffer, end, false);
+ view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
- view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
+ }
}
@@ -425,7 +442,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
/******************************************************************************
* *
-* Paramètres : view = visualisateur à mettre à jour. *
+* Paramètres : view = visualisateur à consulter. *
* first = première ligne à imprimer ou NULL. [OUT] *
* last = première ligne hors cadre ou NULL. [OUT] *
* *
@@ -437,7 +454,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
* *
******************************************************************************/
-bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *end)
+bool g_buffer_view_get_restrictions(const GBufferView *view, vmpa2t *start, vmpa2t *end)
{
if (!view->unrestricted)
{
@@ -450,44 +467,11 @@ bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *en
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisateur à consulter. *
-* *
-* Description : Fournit le tampon de code lié à un visualisateur donné. *
-* *
-* Retour : Tampon de code associé au gestionnaire d'affichage. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *view)
-{
- g_object_ref(G_OBJECT(view->buffer));
-
- return view->buffer;
-}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* *
-* Description : Fournit la hauteur d'impression d'une ligne visualisée. *
-* *
-* Retour : Hauteur de ligne en pixel. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-gint g_buffer_view_get_line_height(GBufferView *view)
-{
- return G_BUFFER_VIEW_GET_CLASS(view)->line_height;
-}
/******************************************************************************
@@ -507,7 +491,7 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+ result = g_buffer_cache_get_text_position(view->cache);
result += g_width_tracker_get_width(view->tracker, display);
@@ -533,7 +517,7 @@ gint g_buffer_view_get_margin(GBufferView *view, const bool *display)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+ result = g_buffer_cache_get_text_position(view->cache);
result += g_width_tracker_get_margin(view->tracker, display);
@@ -558,7 +542,7 @@ gint g_buffer_view_get_height(const GBufferView *view)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->line_height;
+ result = g_buffer_cache_get_line_height(view->cache);
result *= (view->last - view->first + 1);
@@ -567,50 +551,66 @@ gint g_buffer_view_get_height(const GBufferView *view)
}
+
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
-* x = abscisse de la zone principale à traiter. *
-* y = ordonnée de la zone principale à traiter. *
+* x = abscisse proposée pour le nouvel emplacement. *
+* y = ordonnée proposée pour le nouvel emplacement. *
* display = règles d'affichage des colonnes modulables. *
* caret = position du curseur à construire. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Calcule la position idéale de curseur pour un point donné. *
* *
-* Retour : Adresse si une a pu être déterminée, NULL sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret)
+bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- gint remaining; /* Copie de travail modifiable */
+ bool result; /* Bilan à retourner */
+ gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice de ligne de tampon */
GBufferLine *line; /* Ligne à la position courante*/
- const line_segment *segment; /* Segment présent sur la place*/
- GBufferViewClass *class; /* Classe pour les vues */
- remaining = x;
+ result = false;
- line = g_buffer_view_find_line_and_segment_at(view, &remaining, y, &index, display, &segment);
+ /* Détermination de la ligne courante */
- /* FIXME : unref() ! */
- if (line == NULL) return NULL;
- if (segment == NULL) printf(" -- no segment\n");
- if (segment == NULL) return NULL;
+ lheight = g_buffer_cache_get_line_height(view->cache);
+ index = y / lheight;
+ index += view->first;
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ if (index > view->last)
+ goto gbvccf_done;
- caret->x = /*view->left_text +*/ (x - remaining) + get_caret_position_from_line_segment(segment, remaining);
+ line = g_buffer_cache_find_line_by_index(view->cache, index);
- caret->y = (index - view->first) * class->line_height;
+ assert(line != NULL);
- caret->width = 2;
- caret->height = class->line_height;
+ /* Calcul d'une position */
+
+ result = _g_buffer_view_compute_caret_full(view, x, line, index, display, caret, addr);
+
+ g_object_unref(G_OBJECT(line));
+
+ gbvccf_done:
- return get_mrange_addr(g_buffer_line_get_range(line));
+ return result;
}
@@ -618,50 +618,69 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, con
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
+* x = abscisse proposée pour le nouvel emplacement. *
* line = ligne correspondant à la position. *
* index = indice de cette même ligne dans le tampon. *
-* x = abscisse de la zone principale à traiter. *
* display = règles d'affichage des colonnes modulables. *
* caret = position du curseur à construire. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Calcule la position idéale de curseur pour un point donné. *
* *
-* Retour : Adresse si une a pu être déterminée, NULL sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret)
+bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *line, size_t index, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- GBufferViewClass *class; /* Classe pour les vues */
- gint offset; /* Point de travail modifiable */
+ bool result; /* Bilan à retourner */
+ gint text_pos; /* Abscisse de départ du texte */
line_width_summary summary; /* Résumé concis des largeurs */
gint base; /* Position absolue de segment */
bool status; /* Bilan de la localisation */
+ gint lheight; /* Hauteur d'une ligne */
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ result = false;
- offset = x;
+ /* Zone d'intervention bornée ! */
- offset -= class->left_text;
- if (offset < 0) return NULL;
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (x < text_pos)
+ goto gbvccf_done;
+
+ /* Calcul d'une position */
g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
- /* Traitement pour mise à jour de l'abscisse uniquement */
- status = g_buffer_line_get_coord_at(line, &summary, display, &base, &offset,
+ x -= text_pos;
+
+ status = g_buffer_line_get_coord_at(line, &summary, display, &base, &x,
GDK_SCROLL_LEFT, true, (col_coord_t []) { { 0 } });
- if (!status) return NULL;
- caret->x = class->left_text + base + offset;
+ if (!status)
+ goto gbvccf_done;
+
+ /* Transmission des informations */
+
+ lheight = g_buffer_cache_get_line_height(view->cache);
- caret->y = (index - view->first) * class->line_height;
+ caret->x = text_pos + base + x;
+
+ caret->y = (index - view->first) * lheight;
caret->width = 2;
- caret->height = class->line_height;
+ caret->height = lheight;
+
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+
+ result = true;
- return get_mrange_addr(g_buffer_line_get_range(line));
+ gbvccf_done:
+
+ return result;
}
@@ -687,16 +706,24 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l
static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line, size_t index, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
{
bool result; /* Bilan à retourner */
+ gint text_pos; /* Abscisse de départ du texte */
gint offset; /* Point de travail modifiable */
line_width_summary summary; /* Résumé concis des largeurs */
gint base; /* Position absolue de segment */
col_coord_t coord; /* Coordonnées en interne */
const line_segment *segment; /* Bribe de texte trouvée */
- offset = caret->x;
- offset -= G_BUFFER_VIEW_GET_CLASS(view)->left_text;
- if (offset < 0) return false;
+ result = false;
+
+ /* Zone d'intervention bornée ! */
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (caret->x < text_pos)
+ goto gbvmc_done;
+
+ offset = caret->x - text_pos;
g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
@@ -725,7 +752,9 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
/* Mise à jour éventuelle */
if (result)
- caret->x = G_BUFFER_VIEW_GET_CLASS(view)->left_text + base + offset;
+ caret->x = text_pos + base + offset;
+
+ gbvmc_done:
return result;
@@ -735,82 +764,35 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
-* caret = position du curseur à faire évoluer. *
* ctrl = indique la demande d'un parcours rapide. *
* dir = direction du parcours. *
* display = règles d'affichage des colonnes modulables. *
+* caret = position du curseur à faire évoluer. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Déplace le curseur au sein d'une vue de tampon. *
* *
-* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
+bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection dir, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- const vmpa2t *result; /* Actualisation à renvoyer */
+ bool result; /* Bilan à retourner */
size_t index; /* Indice de ligne de tampon */
GBufferLine *line; /* Ligne sous le pointeur */
-
-
- line_width_summary summary; /* Résumé concis des largeurs */
- gint left_pos; /* Retour à la ligne */
- gint right_pos; /* Position d'extrème droite */
- BufferLineColumn i; /* Boucle de parcours */
size_t first; /* Première ligne intégrée */
size_t last; /* Dernière ligne intégrée */
-
-
-
-
+ GBufferLine *other; /* Ligne voisine à visiter */
bool moved; /* Mémorisation d'une évolut° */
+ gint text_pos; /* Abscisse de départ du texte */
-
-
-
-
-
-
-
-
- result = NULL;
-
-
+ result = false;
line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) return NULL;
-
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
- switch (dir)
- {
- case GDK_SCROLL_UP:
- case GDK_SCROLL_DOWN:
- break;
- case GDK_SCROLL_LEFT:
- case GDK_SCROLL_RIGHT:
- left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
- if (display[BLC_PHYSICAL]) left_pos += summary.max_widths[BLC_PHYSICAL] + COL_MARGIN;
- if (display[BLC_VIRTUAL]) left_pos += summary.max_widths[BLC_VIRTUAL] + COL_MARGIN;
- if (display[BLC_BINARY]) left_pos += summary.max_widths[BLC_BINARY] + COL_MARGIN;
- right_pos = left_pos;
- for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)
- right_pos += summary.max_widths[i] + COL_MARGIN;
-
- /*
-gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn index, const gint *max_widths)
-
-BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
- */
-
- left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
-
- break;
- default: /* GDK_SCROLL_SMOOTH */
- break;
- }
+ if (line == NULL) goto gbvmc_done;
first = view->first;
last = view->last;
@@ -821,8 +803,12 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
if (index > first)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
- result = g_buffer_view_compute_caret_full(view, line, index - 1, caret->x, display, caret);
+ index--;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
@@ -831,48 +817,58 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
if (index < last)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
- result = g_buffer_view_compute_caret_full(view, line, index + 1, caret->x, display, caret);
+ index++;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
case GDK_SCROLL_LEFT:
- /*
- line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) break;
- */
-
moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_LEFT, display);
if (moved)
- result = get_mrange_addr(g_buffer_line_get_range(line));
+ {
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+ result = true;
+ }
else if (index > first)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
- result = g_buffer_view_compute_caret_full(view, line, index - 1, INT_MAX, display, caret);
+ index--;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, INT_MAX, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
case GDK_SCROLL_RIGHT:
- /*
- line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) break;
- */
-
moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_RIGHT, display);
if (moved)
- result = get_mrange_addr(g_buffer_line_get_range(line));
+ {
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+ result = true;
+ }
else if (index < last)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
- result = g_buffer_view_compute_caret_full(view, line, index + 1, left_pos, display, caret);
+ index++;
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, text_pos, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
@@ -882,11 +878,27 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
}
+ g_object_unref(G_OBJECT(line));
+
+ gbvmc_done:
+
return result;
}
+
+
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
@@ -927,23 +939,64 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view)
bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const bool *display)
{
- bool need_redraw; /* Besoin d'actualisation ? */
+ bool result; /* Besoin à faire remonter */
+ gint text_pos; /* Abscisse de départ du texte */
+ gint lheight; /* Hauteur d'une ligne */
+ size_t index; /* Indice de ligne de tampon */
+ GBufferLine *line; /* Ligne à la position courante*/
+ line_width_summary summary; /* Résumé concis des largeurs */
const line_segment *segment; /* Segment sélectionnable */
+ /* Réinitialisation */
+
if (view->highlighted != NULL)
- need_redraw = g_buffer_view_unhighlight_segments(view);
+ result = g_buffer_view_unhighlight_segments(view);
else
- need_redraw = false;
+ result = false;
+
+ /* Zone d'intervention bornée ! */
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (x < text_pos)
+ goto gbvhs_done;
+
+ /* Détermination de la ligne concernée */
- g_buffer_view_find_line_and_segment_at(view, &x, y, NULL, display, &segment);
+ lheight = g_buffer_cache_get_line_height(view->cache);
+ index = y / lheight;
+
+ index += view->first;
+
+ if (index > view->last)
+ goto gbvhs_done;
+
+ line = g_buffer_cache_find_line_by_index(view->cache, index);
+
+ assert(line != NULL);
+
+ /* Recherche d'un segment et de son empreinte */
+
+ g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
+
+ x -= text_pos;
+
+ segment = g_buffer_line_get_segment_at(line, &summary, display,
+ (gint []) { 0 }, &x, GDK_SCROLL_LEFT, true);
- if (segment)
- need_redraw |= add_segment_content_to_selection_list(view->highlighted, segment);
+ g_object_unref(G_OBJECT(line));
- if (need_redraw)
+ /* Conclusion */
+
+ if (segment != NULL)
+ result |= add_segment_content_to_selection_list(view->highlighted, segment);
+
+ if (result)
g_signal_emit_by_name(view, "need-redraw");
- return true;
+ gbvhs_done:
+
+ return result;
}
@@ -952,13 +1005,12 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
* *
* Paramètres : view = visualisation à représenter. *
* cr = contexte graphique dédié à la procédure. *
-* fake_x = abscisse réelle du point 0 à l'écran. *
-* fake_y = ordonnée réelle du point 0 à l'écran. *
+* virt_y = ordonnée réelle du point 0 à l'écran. *
* area = position et surface à traiter. *
* display = règles d'affichage des colonnes modulables. *
* selected = ordonnée d'une ligne sélectionnée ou NULL. *
* *
-* Description : Imprime la visualisation du tampon de code désassemblé. *
+* Description : Imprime la visualisation du tampon de lignes quelconques. *
* *
* Retour : - *
* *
@@ -966,148 +1018,57 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
* *
******************************************************************************/
-void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint fake_y, const cairo_rectangle_int_t *area, const bool *display, const gint *selected)
+void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const cairo_rectangle_int_t *area, const bool *display, gint *selected)
{
- GBufferViewClass *class; /* Classe pour les vues */
- gint real_x; /* Abscisse réelle pour tampon */
- gint real_y; /* Ordonnée réelle pour tampon */
+ gint line_height; /* Hauteur d'une ligne */
+ gint cr_y; /* Ordonnée pour le dessin */
size_t first; /* Première ligne visée */
- size_t last; /* Dernière ligne visée + 1 */
- gint y; /* Point de départ + décallage */
- bool wait_selection; /* Sélection déjà passée ? */
- gint rel_selected; /* Position relative de sélect°*/
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à dessiner à l'écran */
- line_width_summary summary; /* Résumé concis des largeurs */
+ size_t last; /* Dernière ligne visée */
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ line_height = g_buffer_cache_get_line_height(view->cache);
- real_x = fake_x + class->left_text;
- real_y = fake_y + area->y;
+ /* Indice et point de départ */
first = view->first;
- first += (real_y / class->line_height);
-
- last = first + (area->height / class->line_height);
- if (area->height % class->line_height > 0) last++;
-
- last = MIN(last, view->last);
-
- y = area->y - (real_y % class->line_height);
-
- wait_selection = true;
+ first += (virt_y / line_height);
- if (selected != NULL)
- rel_selected = *selected - fake_y;
-
- if (g_code_buffer_count_lines(view->buffer) > 0)
- for (i = first; i <= last; i++)
- {
- /* Si sélection, on sousligne la ligne concernée */
- if (wait_selection && selected != NULL && rel_selected == y)
- {
- cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
+ cr_y = area->y - (virt_y % line_height);
- cairo_rectangle(cr, area->x, y, area->width, class->line_height);
- cairo_fill(cr);
+ /* Indice de d'arrivée */
- wait_selection = false;
+ last = first + (area->height / line_height);
+ if (area->height % line_height > 0) last++;
- }
+ last = MIN(last, view->last);
- line = g_code_buffer_find_line_by_index(view->buffer, i);
+ /* Phase de dessin ! */
- if (i == first || (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER))
- g_width_tracker_get_local_width_summary(view->tracker, i, &summary);
+ /**
+ * Le contexte n'est pas sauvegardé avant modification ici car
+ * l'appelant l'a fait pour nous avant sa translation sur les abscisses.
+ */
- g_buffer_line_draw(line, cr, &summary, real_x, y, display, view->highlighted);
+ cairo_translate(cr, 0, cr_y);
- y += class->line_height;
+ if (selected != NULL)
+ *selected -= cr_y;
- }
+ g_buffer_cache_draw(view->cache, cr, first, last, area, display, selected, view->highlighted);
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* addr = adresse où retrouver la ligne recherchée. *
-* flags = propriétés à vérifier en tout ou partie. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec une adresse. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *view, const vmpa2t *addr, BufferLineFlags flags, size_t *idx)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- phys_t length; /* Taille de la vue */
- mrange_t vrange; /* Couverture de la vue */
- bool allowed; /* Rechercher validée ? */
-
- /* Vérification des bornes */
-
- if (!view->unrestricted)
- {
- length = compute_vmpa_diff(&view->start, &view->end);
- init_mrange(&vrange, &view->start, length);
- allowed = mrange_contains_addr_inclusive(&vrange, addr);
- }
- else allowed = true;
- /* Lancement des recherches ? */
- if (allowed)
- result = g_code_buffer_find_line_by_addr(view->buffer, addr, flags, idx);
- else
- result = NULL;
- return result;
-
-}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* index = indice de la ligne recherchée. *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec un indice. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t index)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- bool allowed; /* Rechercher validée ? */
- /* Vérification des bornes */
- allowed = (view->first <= index && index <= view->last);
- /* Lancement des recherches ? */
-
- if (allowed)
- result = g_code_buffer_find_line_by_index(view->buffer, index);
- else
- result = NULL;
-
- return result;
-
-}
/******************************************************************************
@@ -1124,19 +1085,19 @@ GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t in
* *
******************************************************************************/
-GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
{
GBufferLine *result; /* Ligne trouvée à retourner */
gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice attendu */
- lheight = g_buffer_view_get_line_height(view);
+ lheight = g_buffer_cache_get_line_height(view->cache);
index = y / lheight;
index += view->first;
if (index <= view->last)
- result = g_code_buffer_find_line_by_index(view->buffer, index);
+ result = g_buffer_cache_find_line_by_index(view->cache, index);
else
result = NULL;
@@ -1148,125 +1109,26 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* x = abscisse comprise dans le segment recherché. [OUT] *
-* y = ordonnée comprise dans la ligne recherchée. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* display = règles d'affichage des colonnes modulables. *
-* segment = portion de texte recherchée ou NULL. [OUT] *
-* *
-* Description : Fournit la ligne et son segment présents à une position. *
-* *
-* Retour : Ligne retrouvée ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, const line_segment **segment)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- size_t index; /* Indice de la ligne trouvée */
- GBufferViewClass *class; /* Classe pour les vues */
- line_width_summary summary; /* Résumé concis des largeurs */
-
- /* Recherche d'une ligne correspondante */
- result = g_buffer_view_find_line_at(view, y, &index);
- if (idx != NULL) *idx = index;
- /* Recherche du segment visé éventuel */
- if (result != NULL && segment != NULL)
- {
- class = G_BUFFER_VIEW_GET_CLASS(view);
- if (*x < class->left_text)
- *segment = NULL;
- else
- {
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
- *x -= class->left_text;
- *segment = g_buffer_line_get_segment_at(result, &summary, display,
- (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
- }
- }
- return result;
-}
/******************************************************************************
* *
-* Paramètres : view = visualisation à consulter. *
-* x = abscisse comprise dans le segment recherché. [OUT] *
-* y = ordonnée comprise dans la ligne recherchée. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* display = règles d'affichage des colonnes modulables. *
-* creator = instance à l'origine de la représentation. [OUT] *
-* *
-* Description : Fournit la ligne et son segment présents à une position. *
-* *
-* Retour : Ligne retrouvée ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, GObject **creator)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- size_t index; /* Indice de la ligne trouvée */
- GBufferViewClass *class; /* Classe pour les vues */
- line_width_summary summary; /* Résumé concis des largeurs */
-
- /* Recherche d'une ligne correspondante */
-
- result = g_buffer_view_find_line_at(view, y, &index);
-
- if (idx != NULL) *idx = index;
-
- /* Recherche du segment visé éventuel */
-
- if (result != NULL && creator != NULL)
- {
- class = G_BUFFER_VIEW_GET_CLASS(view);
-
- if (*x < class->left_text)
- *creator = NULL;
-
- else
- {
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
- *x -= class->left_text;
- *creator = g_buffer_line_get_creator_at(result, &summary, display,
- (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : view = composant GTK à consulter. *
+* Paramètres : view = visualisation à consulter. *
* addr = adresse à présenter à l'écran. *
+* code = s'arrête si possible à une ligne avec code. *
* x = position horizontale au sein du composant. [OUT] *
* y = position verticale au sein du composant. [OUT] *
-* code = s'arrête si possible à une ligne avec code. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -1276,61 +1138,11 @@ GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x,
* *
******************************************************************************/
-bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, gint *x, gint *y, bool code)
+bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, bool code, gint *x, gint *y)
{
bool result; /* Bilan à retourner */
- gint lheight; /* Hauteur d'une ligne */
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à consulter */
- const mrange_t *range; /* Emplacement parcouru */
-
- result = false;
-
- *x = 0;
- *y = 0;
-
- lheight = g_buffer_view_get_line_height(view);
-
- for (i = view->first; i <= view->last; i++)
- {
- /**
- * Si l'adresse recherchée est plus petite que l'adresse de départ,
- * on va effectuer un parcours complet pour rien.
- *
- * On considère cependant que le seul cas où celà peut arriver
- * est lorsque que des découpages en blocs sont impliqués.
- *
- * Les découpages conduisent alors à la formation de petites zones,
- * rapides à parcourir.
- */
-
- line = g_code_buffer_find_line_by_index(view->buffer, i);
- range = g_buffer_line_get_range(line);
-
- result = mrange_contains_addr(range, addr);
- if (result) break;
-
- *y += lheight;
- }
-
- if (result && code)
- for (; i <= view->last; i++)
- {
- line = g_code_buffer_find_line_by_index(view->buffer, i);
-
- if (g_buffer_line_get_flags(line) & BLF_HAS_CODE) break;
-
- if (i == view->last) break;
-
- line = g_code_buffer_find_line_by_index(view->buffer, i + 1);
-
- range = g_buffer_line_get_range(line);
- if (!mrange_contains_addr(range, addr)) break;
-
- *y += lheight;
-
- }
+ result = g_buffer_cache_get_address_coordinates(view->cache, addr, view->first, view->last, code, x, y);
return result;
diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h
index 0aa26a6..dc1d704 100644
--- a/src/glibext/gbufferview.h
+++ b/src/glibext/gbufferview.h
@@ -28,7 +28,7 @@
#include <glib-object.h>
-#include "gcodebuffer.h"
+#include "gbuffercache.h"
@@ -47,23 +47,22 @@ typedef struct _GBufferView GBufferView;
typedef struct _GBufferViewClass GBufferViewClass;
-/* Détermine le type de la vue d'un tampon pour code désassemblé. */
+/* Détermine le type de la vue d'un tampon pour lignes générées. */
GType g_buffer_view_get_type(void);
-/* Crée une nouvelle vue d'un tampon pour code désassemblé. */
-GBufferView *g_buffer_view_new(GCodeBuffer *, segcnt_list *);
+/* Crée une nouvelle vue d'un tampon pour lignes générées. */
+GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *);
+
+/* Fournit le tampon de code lié à un visualisateur donné. */
+GBufferCache *g_buffer_view_get_cache(const GBufferView *);
/* Restreint le champ d'application de l'affichage. */
void g_buffer_view_restrict(GBufferView *, const vmpa2t *, const vmpa2t *);
/* Indique le champ d'application de l'affichage. */
-bool g_buffer_view_get_restrictions(GBufferView *, vmpa2t *, vmpa2t *);
+bool g_buffer_view_get_restrictions(const GBufferView *, vmpa2t *, vmpa2t *);
-/* Fournit le tampon de code lié à un visualisateur donné. */
-GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *);
-/* Fournit la hauteur d'impression d'une ligne visualisée. */
-gint g_buffer_view_get_line_height(GBufferView *);
/* Fournit la largeur requise par une visualisation. */
gint g_buffer_view_get_width(GBufferView *, const bool *);
@@ -74,14 +73,18 @@ gint g_buffer_view_get_margin(GBufferView *, const bool *);
/* Fournit la hauteur requise par une visualisation. */
gint g_buffer_view_get_height(const GBufferView *);
-/* Calcule la position idéale de curseur pour un point donné. */
-const vmpa2t *g_buffer_view_compute_caret(GBufferView *, gint, gint, const bool *, GdkRectangle *);
+
+
+
/* Calcule la position idéale de curseur pour un point donné. */
-const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *, GBufferLine *, size_t, gint, const bool *, GdkRectangle *);
+bool g_buffer_view_compute_caret_full(GBufferView *, gint, gint, const bool *, GdkRectangle *, vmpa2t *);
/* Déplace le curseur au sein d'une vue de tampon. */
-const vmpa2t *g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, const bool *);
+bool g_buffer_view_move_caret(GBufferView *, bool, GdkScrollDirection, const bool *, GdkRectangle *, vmpa2t *);
+
+
+
/* Supprime toute mise en évidence de segments. */
bool g_buffer_view_unhighlight_segments(GBufferView *);
@@ -89,26 +92,18 @@ bool g_buffer_view_unhighlight_segments(GBufferView *);
/* Surligne tous les segments similaires à celui sous la souris. */
bool g_buffer_view_highlight_segments(GBufferView *, gint, gint, const bool *);
-/* Imprime la visualisation du tampon de code désassemblé. */
-void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_rectangle_int_t *, const bool *, const gint *);
+/* Imprime la visualisation du tampon de lignes quelconques. */
+void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, const cairo_rectangle_int_t *, const bool *, gint *);
-/* Retrouve une ligne au sein d'un tampon avec une adresse. */
-GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *, const vmpa2t *, BufferLineFlags, size_t *);
-/* Retrouve une ligne au sein d'un tampon avec un indice. */
-GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *, size_t );
-/* Fournit la ligne présente à une ordonnée donnée. */
-GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
-/* Fournit la ligne et son segment présents à une position. */
-GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *, gint *, gint, size_t *, const bool *, const line_segment **);
-/* Fournit la ligne et son segment présents à une position. */
-GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *, gint *, gint, size_t *, const bool *, GObject **);
/* Indique la position d'affichage d'une adresse donnée. */
-bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, gint *, gint *, bool);
+bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, bool, gint *, gint *);
+
+
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
deleted file mode 100644
index e9f1762..0000000
--- a/src/glibext/gcodebuffer.c
+++ /dev/null
@@ -1,1778 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gcodebuffer.c - affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2010-2014 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "gcodebuffer.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "chrysamarshal.h"
-#include "delayed-int.h"
-#include "../common/extstr.h"
-
-
-
-/* -------------------------- PARCOURS DU CODE D'UN TAMPON -------------------------- */
-
-
-#define G_TYPE_BUFFER_SCAN g_buffer_scan_get_type()
-#define G_BUFFER_SCAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_buffer_scan_get_type(), GDelayedExport))
-#define G_IS_BUFFER_SCAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_buffer_scan_get_type()))
-#define G_BUFFER_SCAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_SCAN, GDelayedExportClass))
-#define G_IS_BUFFER_SCAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_SCAN))
-#define G_BUFFER_SCAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_SCAN, GDelayedExportClass))
-
-
-/* Ensembles binaires à désassembler (instance) */
-typedef struct _GBufferScan
-{
- GDelayedWork parent; /* A laisser en premier */
-
- GCodeBuffer *buffer; /* Tampon à manipuler */
-
- vmpa2t start; /* Début du parcours */
- bool has_start; /* Validité des données #1 */
- vmpa2t end; /* Fin du parcours */
- bool has_end; /* Validité des données #2 */
-
- char *message; /* Message de progression */
-
- process_line_fc process; /* Fonction de traitement réel */
- void *user_data; /* Données à faire suivre */
-
-} GBufferScan;
-
-/* Ensembles binaires à désassembler (classe) */
-typedef struct _GBufferScanClass
-{
- GDelayedWorkClass parent; /* A laisser en premier */
-
-} GBufferScanClass;
-
-
-/* Indique le type défini pour les tâches d'exportation différée. */
-static GType g_buffer_scan_get_type(void);
-
-/* Initialise la classe des tâches d'exportation différée. */
-static void g_buffer_scan_class_init(GBufferScanClass *);
-
-/* Initialise une tâche d'exportation différée. */
-static void g_buffer_scan_init(GBufferScan *);
-
-/* Supprime toutes les références externes. */
-static void g_buffer_scan_dispose(GBufferScan *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_buffer_scan_finalize(GBufferScan *);
-
-/* Crée une tâche d'exportation différée. */
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
-
-/* Assure l'exportation en différé. */
-static void g_buffer_scan_process(GBufferScan *, GtkStatusStack *);
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-/* Suivi distant des évolutions */
-typedef struct _view_callback
-{
- buffer_size_changed_cb size_changed; /* Evolution de taille */
- GObject *data; /* Données à associer */
-
-} view_callback;
-
-
-/* Tampon pour code désassemblé (instance) */
-struct _GCodeBuffer
-{
- GObject parent; /* A laisser en premier */
-
- BufferLineColumn main_column; /* Colonne principale */
-
- GBufferLine **lines; /* Liste des lignes intégrées */
- size_t count; /* Quantité en cache */
- size_t used; /* Quantité utilisée */
-
- GWidthTracker *tracker; /* Suivi des largeurs */
-
- size_t indent; /* Indentation des lignes */
-
- view_callback *vcallbacks; /* Vues à mettre à jour */
- size_t vcount; /* Quantité de ces vues */
-
-};
-
-/* Tampon pour code désassemblé (classe) */
-struct _GCodeBufferClass
-{
- GObjectClass parent; /* A laisser en premier */
-
- /* Signaux */
-
- void (* line_changed) (GCodeBuffer *, GBufferLine *, line_segment *);
-
-};
-
-
-/* Taille des allocations de masse */
-#define LINE_ALLOC_BULK 20
-
-
-/* Procède à l'initialisation d'une classe de tampon de code. */
-static void g_code_buffer_class_init(GCodeBufferClass *);
-
-/* Procède à l'initialisation d'un tampon pour code désassemblé. */
-static void g_code_buffer_init(GCodeBuffer *);
-
-/* Réagit à un changement de contenu d'une ligne donnée. */
-static void on_line_content_change(GBufferLine *, line_segment *, GCodeBuffer *);
-
-/* Réagit à un changement de propriété rattachée à une ligne. */
-static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *);
-
-/* Ajoute de nouvelles lignes à une position donnée. */
-static void g_code_buffer_insert_lines_at(GCodeBuffer *, GBufferLine **, size_t, size_t);
-
-
-
-/* ------------------------- CONFORTS POUR LES COMMENTAIRES ------------------------- */
-
-
-/* Affiche un commentaire sur une ligne de tampon donnée. */
-static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *, GBufferLine *, const char *, GObject *);
-
-/* Affiche un commentaire sur une ligne de tampon dédiée. */
-static bool _g_code_buffer_write_comment_area(GCodeBuffer *, GBufferLine *, const char *, bool, GObject *);
-
-/* Retrouve la première ligne d'une zone de commentaire. */
-static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *, size_t);
-
-/* Retrouve la dernière ligne d'une zone de commentaire. */
-static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *, size_t);
-
-/* Supprime un commentaire existant. */
-static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *, GBufferLine *);
-
-
-
-/* ------------------------- SIGNAUX IMMEDIATS POUR UNE VUE ------------------------- */
-
-
-/* Fait suivre une variation de la quantité de lignes du tampon. */
-static void g_code_buffer_notify_size_changed(const GCodeBuffer *, bool, size_t, size_t);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* PARCOURS DU CODE D'UN TAMPON */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour les tâches d'exportation différée. */
-G_DEFINE_TYPE(GBufferScan, g_buffer_scan, G_TYPE_DELAYED_WORK);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des tâches d'exportation différée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_scan_class_init(GBufferScanClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GDelayedWorkClass *work; /* Version en classe parente */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_scan_dispose;
- object->finalize = (GObjectFinalizeFunc)g_buffer_scan_finalize;
-
- work = G_DELAYED_WORK_CLASS(klass);
-
- work->run = (run_task_fc)g_buffer_scan_process;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : scan = instance à initialiser. *
-* *
-* Description : Initialise une tâche d'exportation différée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_scan_init(GBufferScan *scan)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : scan = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_scan_dispose(GBufferScan *scan)
-{
- g_object_unref(G_OBJECT(scan->buffer));
-
- G_OBJECT_CLASS(g_buffer_scan_parent_class)->dispose(G_OBJECT(scan));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : scan = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_scan_finalize(GBufferScan *scan)
-{
- free(scan->message);
-
- G_OBJECT_CLASS(g_buffer_scan_parent_class)->finalize(G_OBJECT(scan));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon à manipuler. *
-* start = première adresse visée ou NULL. *
-* end = dernière adresse visée ou NULL. *
-* message = message à afficher lors de la progression. *
-* process = fonction assurant le traitement effectif. *
-* data = données utilisateur à faire suivre. *
-* *
-* Description : Crée une tâche d'exportation différée. *
-* *
-* Retour : Tâche créée. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
-{
- GBufferScan *result; /* Tâche à retourner */
-
- result = g_object_new(G_TYPE_BUFFER_SCAN, NULL);
-
- result->buffer = buffer;
- g_object_ref(G_OBJECT(buffer));
-
- result->has_start = (start != NULL);
-
- if (result->has_start)
- copy_vmpa(&result->start, start);
-
- result->has_end = (end != NULL);
-
- if (result->has_end)
- copy_vmpa(&result->end, end);
-
- result->message = strdup(message);
-
- result->process = process;
- result->user_data = data;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : scan = parcours à mener. *
-* status = barre de statut à tenir informée. *
-* *
-* Description : Assure l'exportation en différé. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_scan_process(GBufferScan *scan, GtkStatusStack *status)
-{
- size_t first; /* Première ligne visée */
- size_t last; /* Dernière ligne visée + 1 */
- GBufferLine **lines; /* Liste des lignes à traiter */
- //bstatus_id_t id; /* Identifiant de statut */
- size_t i; /* Boucle de parcours */
-
- /* TODO : lock scan->buffer->lines */
-
- if (scan->has_start)
- first = g_code_buffer_get_index_from_address(scan->buffer, &scan->start, true);
- else
- first = 0;
-
- if (scan->has_end)
- last = g_code_buffer_get_index_from_address(scan->buffer, &scan->end, false);
- else
- last = scan->buffer->used - 1;
-
- lines = scan->buffer->lines;
-
- //id = gtk_extended_status_bar_push(statusbar, scan->message, true);
-
- if (scan->buffer->used > 0)
- for (i = first; i <= last; i++)
- {
- if (!scan->process(scan->buffer, lines[i], scan->user_data))
- break;
-
- /*
- gtk_extended_status_bar_update_activity(statusbar, id,
- (i - first) * 1.0 / (last - first));
- */
-
- }
-
- /* TODO : unlock scan->buffer->lines */
-
- //gtk_extended_status_bar_remove(statusbar, id);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* TAMPON POUR CODE DESASSEMBLE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant de tampon pour code désassemblé. */
-G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-* *
-* Paramètres : class = classe de composant GTK à initialiser. *
-* *
-* Description : Procède à l'initialisation d'une classe de tampon de code. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_code_buffer_class_init(GCodeBufferClass *class)
-{
- g_signal_new("line-changed",
- G_TYPE_CODE_BUFFER,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GCodeBufferClass, line_changed),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GTK à initialiser. *
-* *
-* Description : Procède à l'initialisation d'un tampon pour code désassemblé.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_code_buffer_init(GCodeBuffer *buffer)
-{
- buffer->tracker = g_width_tracker_new(buffer);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : main = colonne à référencer comme étant la principale. *
-* *
-* Description : Crée un nouveau composant de tampon pour code désassemblé. *
-* *
-* Retour : Composant GTK créé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GCodeBuffer *g_code_buffer_new(BufferLineColumn main)
-{
- GCodeBuffer *result; /* Composant à retourner */
-
- result = g_object_new(G_TYPE_CODE_BUFFER, NULL);
-
- result->main_column = main;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à consulter. *
-* *
-* Description : Compte le nombre de lignes rassemblées dans un tampon. *
-* *
-* Retour : Nombre de lignes constituant le tampon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_code_buffer_count_lines(const GCodeBuffer *buffer)
-{
- return buffer->used;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à consulter. *
-* *
-* Description : Fournit un lien vers la structure de suivi de largeurs. *
-* *
-* Retour : Gestionnaire de largeurs de lignes. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const GWidthTracker *g_code_buffer_get_width_tracker(const GCodeBuffer *buffer)
-{
- return buffer->tracker;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à consulter. *
-* range = emplacement où va se situer la ligne. *
-* *
-* Description : Initie une nouvelle ligne devant être insérée dans le tampon.*
-* *
-* Retour : Nouvelle ligne vierge à écrire. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *buffer, const mrange_t *range)
-{
- GBufferLine *result; /* Instance à retourner */
- size_t i; /* Boucle de parcours */
-
- result = g_buffer_line_new(range, buffer->main_column);
-
- for (i = 0; i < buffer->indent; i++)
- g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW, NULL);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne dont la définition vient d'évoluer. *
-* segment = éventuel segment qui vient d'évoluer ou NULL. *
-* buffer = tampon de lignes cohérentes à manipuler. *
-* *
-* Description : Réagit à un changement de contenu d'une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_line_content_change(GBufferLine *line, line_segment *segment, GCodeBuffer *buffer)
-{
- g_signal_emit_by_name(buffer, "line-changed", line, segment);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne dont la définition vient d'évoluer. *
-* old = ancien groupe de propriétés associées. *
-* old = nouveau groupe de propriétés associées. *
-* buffer = tampon de lignes cohérentes à manipuler. *
-* *
-* Description : Réagit à un changement de propriété rattachée à une ligne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_line_flag_flip(GBufferLine *line, BufferLineFlags old, BufferLineFlags new, GCodeBuffer *buffer)
-{
- g_signal_emit_by_name(buffer, "line-changed", line, NULL);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à mettre à jour. *
-* lines = liste de lignes à insérer. *
-* count = taille de cette liste. *
-* index = point d'insertion de la première ligne. *
-* *
-* Description : Ajoute de nouvelles lignes à une position donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_code_buffer_insert_lines_at(GCodeBuffer *buffer, GBufferLine **lines, size_t count, size_t index)
-{
- size_t i; /* Boucle de parcours */
-
- /* Elaboration d'un espace suffisant */
-
- if ((buffer->used + count) > buffer->count)
- {
- if (count > LINE_ALLOC_BULK)
- buffer->count += count;
- else
- buffer->count += LINE_ALLOC_BULK;
-
- buffer->lines = (GBufferLine **)realloc(buffer->lines,
- buffer->count * sizeof(GBufferLine *));
-
- }
-
- /* Insertion des lignes */
-
- if (index < buffer->used)
- {
- memmove(&buffer->lines[index + count], &buffer->lines[index],
- (buffer->used - index) * sizeof(GBufferLine *));
- }
-
- buffer->used += count;
-
- for (i = 0; i < count; i++)
- {
- assert((index + i) < buffer->used);
-
- buffer->lines[index + i] = lines[i];
-
- g_signal_connect(lines[i], "content-changed", G_CALLBACK(on_line_content_change), buffer);
- g_signal_connect(lines[i], "flip-flag", G_CALLBACK(on_line_flag_flip), buffer);
-
- }
-
- /* Recueil initial des largeurs */
-
- g_width_tracker_update_added(buffer->tracker, index, count);
-
- g_code_buffer_notify_size_changed(buffer, true, index, count);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à mettre à jour. *
-* line = lign à insérer à la fin du tampon. *
-* *
-* Description : Ajoute une nouvelle ligne en fin de tampon. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_append_new_line(GCodeBuffer *buffer, GBufferLine *line)
-{
- g_code_buffer_insert_lines_at(buffer, (GBufferLine *[]) { line }, 1, buffer->used);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à mettre à jour. *
-* lines = liste de lignes à insérer. *
-* count = taille de cette liste. *
-* point = point d'insertion du bloc de ligne. *
-* before = emplacement de l'insertion par rapport au point. *
-* *
-* Description : Ajoute de nouvelles lignes par rapport à une ligne donnée. *
-* *
-* Retour : Bilan : insertion réussie ou non ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_code_buffer_insert_lines(GCodeBuffer *buffer, GBufferLine **lines, size_t count, const GBufferLine *point, bool before)
-{
- bool result; /* Bilan à retourner */
- size_t index; /* Indice d'insertion final */
-
- result = false;
-
- index = g_code_buffer_find_index_by_line(buffer, point);
-
- if (index == buffer->used)
- goto gcbil_exit;
-
- if (!before)
- index++;
-
- g_code_buffer_insert_lines_at(buffer, lines, count, index);
-
-
-
-
- result = true;
-
- gcbil_exit:
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GLib à mettre à jour. *
-* start = première ligne devant être supprimée. *
-* end = dernière ligne devant être supprimée. *
-* *
-* Description : Supprime une ou plusieurs lignes du tampon indiqué. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_delete_lines(GCodeBuffer *buffer, size_t start, size_t end)
-{
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne en cours de traitement*/
-
- assert(start < buffer->used);
- assert(end < buffer->used);
-
- for (i = start; i <= end; i++)
- {
- line = buffer->lines[i];
-
- g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_content_change), buffer);
- g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_flag_flip), buffer);
-
- g_object_unref(G_OBJECT(line));
-
- }
-
- if ((end + 1) < buffer->used)
- memmove(&buffer->lines[start], &buffer->lines[end + 1],
- (buffer->used - end - 1) * sizeof(GBufferLine *));
-
- buffer->used -= (end - start + 1);
-
- g_width_tracker_update_deleted(buffer->tracker, start, end);
-
- g_code_buffer_notify_size_changed(buffer, false, start, end - start + 1);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
-* addr = adresse où retrouver la ligne recherchée. *
-* flags = propriétés à vérifier en tout ou partie. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec une adresse. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *buffer, const vmpa2t *addr, BufferLineFlags flags, size_t *idx)
-{
- GBufferLine *result; /* Instance à retourner */
- size_t index; /* Indice de la ligne visée */
-
- index = g_code_buffer_get_index_from_address(buffer, addr, true);
-
- if (index == buffer->used)
- result = NULL;
-
- else
- {
- if (idx != NULL)
- *idx = index;
-
- result = buffer->lines[index];
-
- if (flags != BLF_NONE)
- while ((g_buffer_line_get_flags(result) & flags) != flags)
- {
- if ((index + 1) == buffer->used) break;
-
- /* FIXME : vérifier que l'adresse est toujours celle recherchée ! */
-
- if (idx != NULL)
- (*idx)++;
-
- result = buffer->lines[++index];
-
- }
-
- g_object_ref(G_OBJECT(result));
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* index = indice de la ligne recherchée. *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec un indice. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_find_line_by_index(const GCodeBuffer *buffer, size_t index)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
-
- /* TODO : ref */
-
- if (index < buffer->used)
- result = buffer->lines[index];
- else
- result = NULL;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
-* addr = adresse où va se situer la ligne. *
-* first = indique si on l'arrête à la première ou la dernière.*
-* *
-* Description : Convertit une adresse en indice de ligne. *
-* *
-* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, const vmpa2t *addr, bool first)
-{
- size_t result; /* Indice à retourner */
- GBufferLine **found; /* Renvoi vers une trouvaille */
- const mrange_t *range; /* Couverture d'une ligne */
-
- /**
- * Si aucune adresse (ie. aucune limite ?) n'est précisée, on se base sur
- * la direction pour trouver le bon indice.
- */
-
- if (addr == NULL)
- result = (first ? 0 : buffer->used - 1);
-
- /**
- * Sinon on parcourt méthodiquement toutes les lignes !
- */
-
- else
- {
- /* Recherche dichotomique grossière */
-
- int cmp_addr_and_line(const vmpa2t *addr, const GBufferLine **line)
- {
- int status; /* Bilan d'une comparaison */
- const mrange_t *lrange; /* Couverture d'une ligne */
-
- lrange = g_buffer_line_get_range(*line);
-
- status = cmp_mrange_with_vmpa(lrange, addr);
-
- return status;
-
- }
-
- found = bsearch(addr, buffer->lines, buffer->used, sizeof(GBufferLine *),
- (__compar_fn_t)cmp_addr_and_line);
-
- /* Dernier raffinage pour approcher la cible réelle */
-
- if (found == NULL)
- result = buffer->used;
-
- else
- {
- result = found - buffer->lines;
-
- if (first)
- for (; result > 0; result--)
- {
- range = g_buffer_line_get_range(buffer->lines[result - 1]);
- if (!mrange_contains_addr(range, addr)) break;
- }
-
- else
- for (; (result + 1) < buffer->used; result++)
- {
- range = g_buffer_line_get_range(buffer->lines[result + 1]);
- if (!mrange_contains_addr(range, addr)) break;
- }
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne dont l'indice est à retrouver. *
-* *
-* Description : Retrouve l'indice associé à une ligne au sein d'un tampon. *
-* *
-* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_code_buffer_find_index_by_line(const GCodeBuffer *buffer, const GBufferLine *line)
-{
- size_t result; /* Indice trouvé à retourner */
- const mrange_t *range; /* Emplacement de la ligne */
- const mrange_t *next; /* Emplacement suivant */
-
- range = g_buffer_line_get_range(line);
-
- result = g_code_buffer_get_index_from_address(buffer, get_mrange_addr(range), true);
-
- /**
- * Comme plusieurs lignes consécutives peuvent avoir la même adresse,
- * on parcourt les lignes suivantes pour retrouver la ligne recherchée.
- */
-
- if (result < buffer->used)
- {
- while (buffer->lines[result] != line)
- {
- if (++result == buffer->used)
- break;
-
- next = g_buffer_line_get_range(buffer->lines[result]);
-
- if (cmp_vmpa(get_mrange_addr(range), get_mrange_addr(next)) != 0)
- {
- result = buffer->used;
- break;
- }
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
-* *
-* Description : Augmente l'indentation des prochaines lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_inc_indentation(GCodeBuffer *buffer)
-{
- buffer->indent++;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
-* *
-* Description : Diminue l'indentation des prochaines lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_dec_indentation(GCodeBuffer *buffer)
-{
- /* BUG_ON(buffer->indent == 0) */
-
- buffer->indent--;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de données à utiliser. *
-* start = première adresse visée ou 0. *
-* end = dernière adresse visée ou VMPA_MAX. *
-* message = message à afficher lors de la progression. *
-* process = fonction assurant le traitement effectif. *
-* data = données utilisateur à faire suivre. *
-* *
-* Description : Lance un parcours des différentes lignes du tampon de code. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GDelayedWork *g_buffer_code_scan(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
-{
- GBufferScan *result; /* Procédure à créer / renvoyer*/
- GWorkQueue *queue; /* Gestionnaire de différés */
-
- result = g_buffer_scan_new(buffer, start, end, message, process, data);
- g_object_ref(G_OBJECT(result));
-
- queue = get_work_queue();
- g_work_queue_schedule_work(queue, G_DELAYED_WORK(result), DEFAULT_WORK_GROUP);
-
- return G_DELAYED_WORK(result);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* CONFORTS POUR LES COMMENTAIRES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* comment = nouveau commentaire à inscrire à la ligne donnée. *
-* creator = créateur à l'origine de la construction. *
-* *
-* Description : Affiche un commentaire sur une ligne de tampon donnée. *
-* *
-* Retour : Bilan de l'opération : ajout ou non ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment, GObject *creator)
-{
- bool result; /* Bilan à retourner */
- const mrange_t *range; /* Emplace de ligne à utiliser */
- char *wcopy; /* Copie de travail */
- GBufferLine **extra; /* Lignes supplémentaires */
- size_t extra_count; /* Quantité de ces lignes */
- char *saveptr; /* Sauvegarde pour la sécurité */
- char *token; /* Fragment à insérer */
- size_t len; /* Taille dudit fragment */
- GBufferLine *new; /* Nouvelle ligne créée */
- size_t i; /* Boucle de parcours */
-
- assert(!g_buffer_line_has_comment(line));
-
- result = false;
-
- range = g_buffer_line_get_range(line);
-
- wcopy = strdup(comment);
-
- extra = NULL;
- extra_count = 0;
-
- for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr);
- token != NULL;
- token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr))
- {
- len = strlen(token);
-
- if (!result)
- g_buffer_line_append_text(line, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
-
- else
- {
- new = g_code_buffer_prepare_new_line(buffer, range);
-
- g_buffer_line_append_text(new, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
-
- extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
-
- extra[extra_count - 1] = new;
-
- }
-
- result = true;
-
- }
-
- free(wcopy);
-
- if (extra_count > 0)
- {
- result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, false);
-
- if (!result)
- for (i = 0; i < extra_count; i++)
- g_object_unref(G_OBJECT(extra[i]));
-
- free(extra);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* comment = nouveau commentaire à inscrire à la ligne donnée. *
-* creator = créateur à l'origine de la construction. *
-* *
-* Description : Affiche un commentaire sur une ligne de tampon donnée. *
-* *
-* Retour : Bilan de l'opération : ajout ou non ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_code_buffer_update_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment, GObject *creator)
-{
- bool result; /* Bilan à retourner */
-
- if (g_buffer_line_has_comment(line))
- result = _g_code_buffer_delete_lines_comment(buffer, line);
- else
- result = true;
-
- if (result)
- result = _g_code_buffer_write_inlined_comment(buffer, line, comment, creator);
-
- /* TODO : emit() */
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* comment = nouveau commentaire à inscrire à la ligne donnée. *
-* before = précise la position du commentaire. *
-* creator = créateur à l'origine de la construction. *
-* *
-* Description : Affiche un commentaire sur une ligne de tampon dédiée. *
-* *
-* Retour : Bilan de l'opération : ajout ou non ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool _g_code_buffer_write_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before, GObject *creator)
-{
- bool result; /* Bilan à retourner */
- const mrange_t *range; /* Emplace de ligne à utiliser */
- char *wcopy; /* Copie de travail */
- GBufferLine **extra; /* Lignes supplémentaires */
- size_t extra_count; /* Quantité de ces lignes */
- char *saveptr; /* Sauvegarde pour la sécurité */
- char *token; /* Fragment à insérer */
- size_t len; /* Taille dudit fragment */
- GBufferLine *new; /* Nouvelle ligne créée */
- size_t i; /* Boucle de parcours */
-
- assert(!g_buffer_line_has_comment(line));
-
- result = false;
-
- range = g_buffer_line_get_range(line);
-
- wcopy = strdup(comment);
-
- extra = NULL;
- extra_count = 0;
-
- for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr);
- token != NULL;
- token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr))
- {
- len = strlen(token);
-
- new = g_code_buffer_prepare_new_line(buffer, range);
- g_buffer_line_start_merge_at(new, BLC_DISPLAY);
-
- g_buffer_line_append_text(new, BLC_DISPLAY, token, len, RTT_COMMENT, creator);
-
- extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
-
- extra[extra_count - 1] = new;
-
- result = true;
-
- }
-
- free(wcopy);
-
- if (extra_count > 0)
- {
- result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, before);
-
- if (!result)
- for (i = 0; i < extra_count; i++)
- g_object_unref(G_OBJECT(extra[i]));
-
- free(extra);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* comment = nouveau commentaire à inscrire à la ligne donnée. *
-* before = précise la position du commentaire. *
-* creator = créateur à l'origine de la construction. *
-* *
-* Description : Affiche un commentaire sur une ligne de tampon dédiée. *
-* *
-* Retour : Bilan de l'opération : ajout ou non ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_code_buffer_update_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before, GObject *creator)
-{
- bool result; /* Bilan à retourner */
-
- if (g_buffer_line_has_comment(line))
- result = _g_code_buffer_delete_lines_comment(buffer, line);
- else
- result = true;
-
- if (result)
- result = _g_code_buffer_write_comment_area(buffer, line, comment, before, creator);
-
- /* TODO : emit() */
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* index = indice de ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Retrouve la première ligne d'une zone de commentaire. *
-* *
-* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *buffer, size_t index)
-{
- size_t result; /* Indice trouvé à retourner */
- GBufferLine *prev; /* Ligne précédente */
-
- assert(index < buffer->used);
-
- bool is_first_line_of_comment(const GBufferLine *ln, const GBufferLine *pv)
- {
- bool first; /* Statut à renvoyer */
- BufferLineColumn merge_col; /* Colonne de fusion #1 */
- BufferLineColumn prev_merge_col; /* Colonne de fusion #2 */
-
- merge_col = g_buffer_line_get_merge_start(ln);
-
- /**
- * La ligne consultée contient toujours un commentaire.
- *
- * Deux cas de figures sont possibles ici :
- *
- * - soit du texte est présent dans la colonne "commentaires".
- * Si du texte est présent avant, alors il s'agit forcément de
- * la première (et unique ?) ligne de commentaire.
- *
- * - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY.
- * Si la ligne qui précède fait de même, il s'agit alors d'une étiquette
- * ou de l'amont du commentaire.
- *
- */
-
- if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT))
- {
- first = g_buffer_line_has_text(ln, BLC_DISPLAY, BLC_COMMENTS);
-
- if (!first)
- {
- /* La ligne d'avant doit avoir un commentaire ! */
- first = !g_buffer_line_has_text(pv, BLC_COMMENTS, BLC_COUNT);
- }
-
- }
-
- else
- {
- /**
- * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable,
- * la seule fusion possible ici est la suivante.
- */
- assert(merge_col == BLC_DISPLAY);
-
- /**
- * La première ligne d'un tampon est toujours un prologue.
- */
- assert(pv != NULL);
-
- prev_merge_col = g_buffer_line_get_merge_start(pv);
-
- first = (prev_merge_col != BLC_DISPLAY);
-
- if (!first)
- first = (g_buffer_line_get_flags(pv) & BLF_IS_LABEL);
-
- }
-
- return first;
-
- }
-
- for (result = index; result > 0; result--)
- {
- prev = (result > 0 ? buffer->lines[result - 1] : NULL);
-
- if (is_first_line_of_comment(buffer->lines[result], prev))
- break;
-
- }
-
- if (result == 0)
- {
- if (!is_first_line_of_comment(buffer->lines[0], NULL))
- result = buffer->used;
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* index = indice de ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Retrouve la dernière ligne d'une zone de commentaire. *
-* *
-* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *buffer, size_t index)
-{
- size_t result; /* Indice trouvé à retourner */
- GBufferLine *next; /* Ligne suivante */
-
- assert(index < buffer->used);
-
- bool is_last_line_of_comment(const GBufferLine *ln, const GBufferLine *nx)
- {
- bool last; /* Statut à renvoyer */
- BufferLineColumn merge_col; /* Colonne de fusion #1 */
- BufferLineColumn next_merge_col; /* Colonne de fusion #2 */
-
- merge_col = g_buffer_line_get_merge_start(ln);
-
- /**
- * La ligne consultée contient toujours un commentaire.
- *
- * Deux cas de figures sont possibles ici :
- *
- * - soit du texte est présent dans la colonne "commentaires".
- * Si la ligne suivante est similaire et si du texte est présent avant,
- * alors il s'agit forcément de d'un nouveau commentaire. S'il n'y a
- * aucun texte, il s'agit de la suite du commentaire.
- *
- * - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY.
- * Si la ligne qui suit fait de même, il s'agit alors d'une étiquette
- * ou de l'aval du commentaire.
- *
- */
-
- if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT))
- {
- last = !g_buffer_line_has_text(nx, BLC_COMMENTS, BLC_COUNT);
-
- if (!last)
- last = g_buffer_line_has_text(nx, BLC_DISPLAY, BLC_COMMENTS);
-
- }
-
- else
- {
- /**
- * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable,
- * la seule fusion possible ici est la suivante.
- */
- assert(merge_col == BLC_DISPLAY);
-
- if (nx == NULL)
- last = true;
-
- else
- {
- next_merge_col = g_buffer_line_get_merge_start(nx);
-
- last = (next_merge_col != BLC_DISPLAY);
-
- if (!last)
- last = (g_buffer_line_get_flags(nx) & BLF_IS_LABEL);
-
- }
-
- }
-
- return last;
-
- }
-
- for (result = index; result < buffer->used; result++)
- {
- next = ((result + 1) < buffer->used ? buffer->lines[result + 1] : NULL);
-
- if (is_last_line_of_comment(buffer->lines[result], next))
- break;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Retrouve le créateur d'un commentaire existant. *
-* *
-* Retour : Instance trouvée à déréférencer ensuite ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GObject *g_code_buffer_get_comment_creator(const GCodeBuffer *buffer, const GBufferLine *line)
-{
- GObject *result; /* Instance à retourner */
- BufferLineColumn merge_col; /* Colonne de fusion */
-
- if (g_buffer_line_has_comment(line))
- {
- merge_col = g_buffer_line_get_merge_start(line);
-
- if (merge_col == BLC_DISPLAY)
- result = g_buffer_line_find_first_segment_creator(line, BLC_DISPLAY);
- else
- result = g_buffer_line_find_first_segment_creator(line, BLC_COMMENTS);
-
- }
-
- else
- result = NULL;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à consulter. *
-* line = ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Récupère le contenu d'un commentaire existant. *
-* *
-* Retour : Commentaire retrouver à libérer ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-char *g_code_buffer_get_lines_comment(const GCodeBuffer *buffer, const GBufferLine *line)
-{
- char *result; /* Contenu à retourner */
- size_t index; /* Indice de la ligne fournie */
- size_t start; /* Ligne de départ */
- size_t end; /* Ligne d'arrivée */
- BufferLineColumn merge_col; /* Colonne de fusion */
- size_t i; /* Boucle de parcours */
- char *extra; /* Commentaire supplémentaire */
-
- /* Pas de prologue ici ! */
- assert(g_buffer_line_has_comment(line));
-
- result = NULL;
-
- index = g_code_buffer_find_index_by_line(buffer, line);
-
- if (index == buffer->used)
- goto gcbglc_exit;
-
- start = g_code_buffer_find_first_line_comment(buffer, index);
-
- if (start == buffer->used)
- goto gcbglc_exit;
-
- end = g_code_buffer_find_last_line_comment(buffer, index);
-
- if (end == buffer->used)
- goto gcbglc_exit;
-
- merge_col = g_buffer_line_get_merge_start(line);
-
- for (i = start; i <= end; i++)
- {
- if (merge_col == BLC_DISPLAY)
- extra = g_buffer_line_get_text(buffer->lines[i], BLC_DISPLAY, BLC_COUNT, false);
-
- else
- extra = g_buffer_line_get_text(buffer->lines[i], BLC_COMMENTS, BLC_COUNT, false);
-
- assert(extra != NULL);
-
- if (result == NULL)
- result = extra;
-
- else
- {
- result = stradd(result, extra);
- free(extra);
- }
-
- }
-
- gcbglc_exit:
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à modifier. *
-* line = ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Supprime un commentaire existant. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line)
-{
- bool result; /* Bilan à retourner */
- size_t index; /* Indice de la ligne fournie */
- size_t start; /* Ligne de départ */
- size_t end; /* Ligne d'arrivée */
- BufferLineColumn merge_col; /* Colonne de fusion */
-
- /* Pas de prologue ici ! */
- assert(g_buffer_line_has_comment(line));
-
- result = false;
-
- index = g_code_buffer_find_index_by_line(buffer, line);
-
- if (index == buffer->used)
- goto gcbdlc_exit;
-
- start = g_code_buffer_find_first_line_comment(buffer, index);
-
- if (start == buffer->used)
- goto gcbdlc_exit;
-
- end = g_code_buffer_find_last_line_comment(buffer, index);
-
- if (end == buffer->used)
- goto gcbdlc_exit;
-
- result = true;
-
- merge_col = g_buffer_line_get_merge_start(line);
-
- if (merge_col == BLC_DISPLAY)
- g_code_buffer_delete_lines(buffer, start, end);
-
- else
- {
- g_buffer_line_delete_text(buffer->lines[start], BLC_COMMENTS, BLC_COUNT);
-
- if (end > start)
- g_code_buffer_delete_lines(buffer, start + 1, end);
-
- }
-
- gcbdlc_exit:
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à modifier. *
-* line = ligne à l'intérieur d'un commentaire. *
-* *
-* Description : Supprime un commentaire existant. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line)
-{
- bool result; /* Bilan à retourner */
-
- result = _g_code_buffer_delete_lines_comment(buffer, line);
-
- /* TODO : emit() */
-
- return result;
-
-}
-
-
-/* ---------------------------------------------------------------------------------- */
-/* SIGNAUX IMMEDIATS POUR UNE VUE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à modifier. *
-* cb = fonction à appeler au moment opportun. *
-* data = object GLib à associer à l'appel. *
-* *
-* Description : Enregistre l'adresse d'une fonction de mise à jour de vue. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_register_view_callback(GCodeBuffer *buffer, buffer_size_changed_cb cb, GObject *data)
-{
- view_callback *new; /* Informations sur l'appel */
-
- buffer->vcount++;
-
- buffer->vcallbacks = (view_callback *)realloc(buffer->vcallbacks, buffer->vcount * sizeof(view_callback));
-
- new = &buffer->vcallbacks[buffer->vcount - 1];
-
- new->size_changed = cb;
- new->data = data;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à modifier. *
-* data = object GLib à associer à l'appel. *
-* *
-* Description : Supprime un élément des vues à contacter pour mises à jour. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_code_buffer_unregister_view_callback(GCodeBuffer *buffer, GObject *data)
-{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < buffer->vcount; i++)
- if (buffer->vcallbacks[i].data == data)
- {
- if ((i + 1) < buffer->vcount)
- memmove(&buffer->vcallbacks[i], &buffer->vcallbacks[i + 1],
- (buffer->vcount - i - 1) * sizeof(view_callback));
-
- buffer->vcount--;
-
- buffer->vcallbacks = (view_callback *)realloc(buffer->vcallbacks,
- buffer->vcount * sizeof(view_callback));
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : buffer = tampon de lignes à diffuser. *
-* added = indication sur la variation de la taille du tampon. *
-* index = indice de la première ligne à traiter. *
-* count = nombre de lignes à traiter. *
-* *
-* Description : Fait suivre une variation de la quantité de lignes du tampon.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_code_buffer_notify_size_changed(const GCodeBuffer *buffer, bool added, size_t index, size_t count)
-{
- size_t i; /* Boucle de parcours */
- view_callback *cb; /* Informations sur l'appel */
-
- for (i = 0; i < buffer->vcount; i++)
- {
- cb = &buffer->vcallbacks[i];
-
- cb->size_changed(buffer, added, index, count, cb->data);
-
- }
-
-}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
deleted file mode 100644
index f600aee..0000000
--- a/src/glibext/gcodebuffer.h
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gcodebuffer.h - prototypes pour l'affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2010-2014 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _GLIBEXT_GCODEBUFFER_H
-#define _GLIBEXT_GCODEBUFFER_H
-
-
-#include <glib-object.h>
-
-
-#include "delayed.h"
-#include "gbufferline.h"
-#include "gwidthtracker.h"
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-#define G_TYPE_CODE_BUFFER (g_code_buffer_get_type())
-#define G_CODE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GCodeBuffer))
-#define G_CODE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GCodeBufferClass))
-#define G_IS_CODE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
-#define G_IS_CODE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
-#define G_CODE_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GCodeBufferClass))
-
-
-/* Tampon pour code désassemblé (instance) */
-typedef struct _GCodeBuffer GCodeBuffer;
-
-/* Tampon pour code désassemblé (classe) */
-typedef struct _GCodeBufferClass GCodeBufferClass;
-
-
-/* Détermine le type du composant de tampon pour code désassemblé. */
-GType g_code_buffer_get_type(void);
-
-/* Crée un nouveau composant de tampon pour code désassemblé. */
-GCodeBuffer *g_code_buffer_new(BufferLineColumn);
-
-/* Compte le nombre de lignes rassemblées dans un tampon. */
-size_t g_code_buffer_count_lines(const GCodeBuffer *);
-
-/* Fournit un lien vers la structure de suivi de largeurs. */
-const GWidthTracker *g_code_buffer_get_width_tracker(const GCodeBuffer *);
-
-/* Initie une nouvelle ligne devant être insérée dans le tampon. */
-GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *, const mrange_t *);
-
-/* Ajoute une nouvelle ligne en fin de tampon. */
-void g_code_buffer_append_new_line(GCodeBuffer *, GBufferLine *);
-
-/* Ajoute de nouvelles lignes par rapport à une ligne donnée. */
-bool g_code_buffer_insert_lines(GCodeBuffer *, GBufferLine **, size_t, const GBufferLine *, bool);
-
-/* Supprime une ou plusieurs lignes du tampon indiqué. */
-void g_code_buffer_delete_lines(GCodeBuffer *, size_t, size_t);
-
-
-
-/* FIXME */
-#define g_code_buffer_append_new_line_fixme(b) \
- g_code_buffer_prepare_new_line(b, (mrange_t []){ { 0, 0 }, 0 })
-
-/* FIXME */
-#define g_code_buffer_insert_at(buf, a, b) NULL
-
-
-
-/* Retrouve une ligne au sein d'un tampon avec une adresse. */
-GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *, const vmpa2t *, BufferLineFlags, size_t *);
-
-/* Retrouve une ligne au sein d'un tampon avec un indice. */
-GBufferLine *g_code_buffer_find_line_by_index(const GCodeBuffer *, size_t);
-
-/* Convertit une adresse en indice de ligne. */
-size_t g_code_buffer_get_index_from_address(const GCodeBuffer *, const vmpa2t *, bool);
-
-/* Retrouve l'indice associé à une ligne au sein d'un tampon. */
-size_t g_code_buffer_find_index_by_line(const GCodeBuffer *, const GBufferLine *);
-
-/* Augmente l'indentation des prochaines lignes. */
-void g_code_buffer_inc_indentation(GCodeBuffer *);
-
-/* Diminue l'indentation des prochaines lignes. */
-void g_code_buffer_dec_indentation(GCodeBuffer *);
-
-/* Traitement d'une ligne parcourue. */
-typedef bool (* process_line_fc) (GCodeBuffer *, GBufferLine *, void *);
-
-/* Lance un parcours des différentes lignes du tampon de code. */
-GDelayedWork *g_buffer_code_scan(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
-
-
-
-/* ------------------------- CONFORTS POUR LES COMMENTAIRES ------------------------- */
-
-
-/* Séparateur commun à tous les plateformes */
-#define COMMENT_LINE_SEP "\n"
-
-
-/* Affiche un commentaire sur une ligne de tampon donnée. */
-bool g_code_buffer_update_inlined_comment(GCodeBuffer *, GBufferLine *, const char *, GObject *);
-
-/* Affiche un commentaire sur une ligne de tampon dédiée. */
-bool g_code_buffer_update_comment_area(GCodeBuffer *, GBufferLine *, const char *, bool, GObject *);
-
-/* Retrouve le créateur d'un commentaire existant. */
-GObject *g_code_buffer_get_comment_creator(const GCodeBuffer *, const GBufferLine *);
-
-/* Récupère le contenu d'un commentaire existant. */
-char *g_code_buffer_get_lines_comment(const GCodeBuffer *, const GBufferLine *);
-
-/* Supprime un commentaire existant. */
-bool g_code_buffer_delete_lines_comment(GCodeBuffer *, GBufferLine *);
-
-
-
-/* ------------------------- SIGNAUX IMMEDIATS POUR UNE VUE ------------------------- */
-
-
-/* Accompagne une variation de la quantité de lignes du tampon. */
-typedef void (* buffer_size_changed_cb) (const GCodeBuffer *, bool, size_t, size_t, GObject *);
-
-
-/* Enregistre l'adresse d'une fonction de mise à jour de vue. */
-void g_code_buffer_register_view_callback(GCodeBuffer *, buffer_size_changed_cb, GObject *);
-
-/* Supprime un élément des vues à contacter pour mises à jour. */
-void g_code_buffer_unregister_view_callback(GCodeBuffer *, GObject *);
-
-
-
-#endif /* _GLIBEXT_GCODEBUFFER_H */
diff --git a/src/glibext/generator-int.h b/src/glibext/generator-int.h
new file mode 100644
index 0000000..d284d87
--- /dev/null
+++ b/src/glibext/generator-int.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * generator-int.h - prototypes internes pour la génération de lignes à la volée
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_GENERATOR_INT_H
+#define _GLIBEXT_GENERATOR_INT_H
+
+
+#include "generator.h"
+
+
+
+
+
+/* Accès à un contenu binaire quelconque (interface) */
+struct _GBinContentIface
+{
+ GTypeInterface base_iface; /* A laisser en premier */
+
+
+
+
+
+
+};
+
+
+/* Redéfinition */
+typedef GBinContentIface GBinContentInterface;
+
+
+
+#endif /* _GLIBEXT_GENERATOR_INT_H */
diff --git a/src/glibext/generators/Makefile.am b/src/glibext/generators/Makefile.am
new file mode 100644
index 0000000..5dd7133
--- /dev/null
+++ b/src/glibext/generators/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libglibextgenerators.la
+
+libglibextgenerators_la_SOURCES = \
+ prologue.h prologue.c \
+ rborder.h rborder.c
+
+libglibextgenerators_la_LDFLAGS =
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS =
diff --git a/src/glibext/generators/prologue.c b/src/glibext/generators/prologue.c
new file mode 100644
index 0000000..7a4fea5
--- /dev/null
+++ b/src/glibext/generators/prologue.c
@@ -0,0 +1,359 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.c - génération à la volée de lignes d'introduction
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "prologue.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include "../gbufferline.h"
+#include "../linegen-int.h"
+#include "../linesegment.h"
+
+
+
+/* Tampon pour générateur de lignes en prologue (instance) */
+struct _GIntroGenerator
+{
+ GObject parent; /* A laisser en premier */
+
+ char **text; /* Lignes brutes à représenter */
+ size_t count; /* Quantité de ces lignes */
+
+};
+
+/* Tampon pour générateur de lignes en prologue (classe) */
+struct _GIntroGeneratorClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Procède à l'initialisation d'une classe de générateur. */
+static void g_intro_generator_class_init(GIntroGeneratorClass *);
+
+/* Procède à l'initialisation d'un générateur de lignes d'intro. */
+static void g_intro_generator_init(GIntroGenerator *);
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_intro_generator_interface_init(GLineGeneratorInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_intro_generator_dispose(GIntroGenerator *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_intro_generator_finalize(GIntroGenerator *);
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_intro_generator_count_lines(const GIntroGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_intro_generator_compute_addr(const GIntroGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_intro_generator_contains_addr(const GIntroGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_intro_generator_get_flags(const GIntroGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_intro_generator_print(GIntroGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+/* Détermine le type du générateur de lignes d'introduction à la volée. */
+G_DEFINE_TYPE_WITH_CODE(GIntroGenerator, g_intro_generator, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_intro_generator_interface_init));
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de générateur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_class_init(GIntroGeneratorClass *class)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_intro_generator_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_intro_generator_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un générateur de lignes d'intro.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_init(GIntroGenerator *generator)
+{
+ generator->text = NULL;
+ generator->count = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_intro_generator_count_lines;
+ iface->compute = (linegen_compute_fc)g_intro_generator_compute_addr;
+ iface->contains = (linegen_contains_fc)g_intro_generator_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_intro_generator_get_flags;
+ iface->print = (linegen_print_fc)g_intro_generator_print;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_dispose(GIntroGenerator *generator)
+{
+ G_OBJECT_CLASS(g_intro_generator_parent_class)->dispose(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_finalize(GIntroGenerator *generator)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < generator->count; i++)
+ free(generator->text[i]);
+
+ if (generator->text != NULL)
+ free(generator->text);
+
+ G_OBJECT_CLASS(g_intro_generator_parent_class)->finalize(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = trauducteur pour l'impression finale. *
+* text = tableau de lignes à conserver. *
+* count = taille du tableau fourni. *
+* *
+* Description : Crée un nouveau générateur de lignes d'introduction. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GIntroGenerator *g_intro_generator_new(const GCodingLanguage *lang, char **text, size_t count)
+{
+ GIntroGenerator *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_INTRO_GENERATOR, NULL);
+
+ result->text = text;
+ result->count = count;
+
+ g_coding_language_encapsulate_comments(lang, &result->text, &result->count);
+
+ result->text = (char **)realloc(result->text, ++result->count * sizeof(char *));
+
+ result->text[result->count - 1] = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_intro_generator_count_lines(const GIntroGenerator *generator)
+{
+ return generator->count;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_compute_addr(const GIntroGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ init_vmpa(addr, 0, 0);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_intro_generator_contains_addr(const GIntroGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ /**
+ * Les lignes générées sont purement artificielles et sans attache.
+ * Elles n'existent donc pas.
+ */
+
+ return 1;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Renseigne sur les propriétés liées à un générateur. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_intro_generator_get_flags(const GIntroGenerator *generator, size_t index, size_t repeat)
+{
+ return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_intro_generator_print(GIntroGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+ assert(repeat < generator->count);
+
+ if ((repeat + 1) != generator->count)
+ {
+ g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
+
+ g_buffer_line_append_text(line, BLC_PHYSICAL, SL(generator->text[repeat]), RTT_COMMENT, NULL);
+
+ if (repeat == 0)
+ g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
+
+ }
+
+}
diff --git a/src/glibext/generators/prologue.h b/src/glibext/generators/prologue.h
new file mode 100644
index 0000000..40cdce3
--- /dev/null
+++ b/src/glibext/generators/prologue.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.h - prototypes pour la génération à la volée de lignes d'introduction
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_GENERATORS_PROLOGUE_H
+#define _GLIBEXT_GENERATORS_PROLOGUE_H
+
+
+#include <glib-object.h>
+
+
+#include "../../analysis/human/lang.h"
+
+
+
+#define G_TYPE_INTRO_GENERATOR (g_intro_generator_get_type())
+#define G_INTRO_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GIntroGenerator))
+#define G_INTRO_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GIntroGeneratorClass))
+#define G_IS_INTRO_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_INTRO_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_INTRO_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GIntroGeneratorClass))
+
+
+/* Tampon pour générateur de lignes en prologue (instance) */
+typedef struct _GIntroGenerator GIntroGenerator;
+
+/* Tampon pour générateur de lignes en prologue (classe) */
+typedef struct _GIntroGeneratorClass GIntroGeneratorClass;
+
+
+/* Détermine le type du générateur de lignes d'introduction à la volée. */
+GType g_intro_generator_get_type(void);
+
+/* Crée un nouveau générateur de lignes d'introduction. */
+GIntroGenerator *g_intro_generator_new(const GCodingLanguage *, char **, size_t);
+
+
+
+#endif /* _GLIBEXT_GENERATORS_PROLOGUE_H */
diff --git a/src/glibext/generators/rborder.c b/src/glibext/generators/rborder.c
new file mode 100644
index 0000000..ff34dfb
--- /dev/null
+++ b/src/glibext/generators/rborder.c
@@ -0,0 +1,361 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.c - génération à la volée de délimitations de routines
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "rborder.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../gbufferline.h"
+#include "../linegen-int.h"
+#include "../linesegment.h"
+
+
+
+/* Tampon pour générateur de délimitations de routines (instance) */
+struct _GBorderGenerator
+{
+ GObject parent; /* A laisser en premier */
+
+ GCodingLanguage *lang; /* Traduction de la sortie */
+
+ vmpa2t addr; /* Position de la limite */
+ bool start; /* Début ou fin de routine ? */
+
+ MemoryDataSize msize; /* Taille du bus d'adresses */
+
+};
+
+/* Tampon pour générateur de délimitations de routines (classe) */
+struct _GBorderGeneratorClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+#define ROUTINE_INTRO_MSG "--------------- BEGIN OF PROCEDURE ---------------"
+
+#define ROUTINE_OUTRO_MSG "---------------- END OF PROCEDURE ----------------"
+
+
+/* Procède à l'initialisation d'une classe de générateur. */
+static void g_border_generator_class_init(GBorderGeneratorClass *);
+
+/* Procède à l'initialisation d'un générateur de délimitations. */
+static void g_border_generator_init(GBorderGenerator *);
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_border_generator_interface_init(GLineGeneratorInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_border_generator_dispose(GBorderGenerator *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_border_generator_finalize(GBorderGenerator *);
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_border_generator_count_lines(const GBorderGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_border_generator_compute_addr(const GBorderGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_border_generator_contains_addr(const GBorderGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_border_generator_print(GBorderGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+/* Détermine le type du générateur de délimitations de routines à la volée. */
+G_DEFINE_TYPE_WITH_CODE(GBorderGenerator, g_border_generator, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_border_generator_interface_init));
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de générateur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_class_init(GBorderGeneratorClass *class)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_border_generator_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_border_generator_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un générateur de délimitations. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_init(GBorderGenerator *generator)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_interface_init(GLineGeneratorInterface *iface)
+{
+ iface->count = (linegen_count_lines_fc)g_border_generator_count_lines;
+ iface->compute = (linegen_compute_fc)g_border_generator_compute_addr;
+ iface->contains = (linegen_contains_fc)g_border_generator_contains_addr;
+ iface->get_flags = (linegen_get_flags_fc)g_border_generator_get_flags;
+ iface->print = (linegen_print_fc)g_border_generator_print;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_dispose(GBorderGenerator *generator)
+{
+ g_object_unref(G_OBJECT(generator->lang));
+
+ G_OBJECT_CLASS(g_border_generator_parent_class)->dispose(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_finalize(GBorderGenerator *generator)
+{
+ G_OBJECT_CLASS(g_border_generator_parent_class)->finalize(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lang = trauducteur pour l'impression finale. *
+* addr = position correspondant à la délimitation à marquer. *
+* start = indique le type de délimitation observée. *
+* msize = taille des adresses représentées. *
+* *
+* Description : Crée un nouveau générateur de délimitations de routines. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBorderGenerator *g_border_generator_new(GCodingLanguage *lang, const vmpa2t *addr, bool start, MemoryDataSize msize)
+{
+ GBorderGenerator *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_BORDER_GENERATOR, NULL);
+
+ result->lang = lang;
+ g_object_ref(G_OBJECT(lang));
+
+ copy_vmpa(&result->addr, addr);
+ result->start = start;
+
+ result->msize = msize;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_border_generator_count_lines(const GBorderGenerator *generator)
+{
+ return 3;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ copy_vmpa(addr, &generator->addr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_border_generator_contains_addr(const GBorderGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ return cmp_vmpa(addr, &generator->addr);
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Renseigne sur les propriétés liées à un générateur. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *generator, size_t index, size_t repeat)
+{
+ return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_border_generator_print(GBorderGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+ char *text; /* Texte principal à insérer */
+
+ assert(repeat < 3);
+
+ g_buffer_line_fill_vmpa(line, &generator->addr, generator->msize, generator->msize);
+
+ if (repeat == 1)
+ {
+ text = strdup(generator->start ? ROUTINE_INTRO_MSG : ROUTINE_OUTRO_MSG);
+ g_coding_language_encapsulate_comment(generator->lang, &text);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(text), RTT_COMMENT, NULL);
+
+ free(text);
+
+ }
+
+}
diff --git a/src/glibext/generators/rborder.h b/src/glibext/generators/rborder.h
new file mode 100644
index 0000000..fa12734
--- /dev/null
+++ b/src/glibext/generators/rborder.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rborder.h - prototypes pour la génération à la volée de délimitations de routines
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_GENERATORS_RBORDER_H
+#define _GLIBEXT_GENERATORS_RBORDER_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../../analysis/human/lang.h"
+#include "../../arch/vmpa.h"
+
+
+
+#define G_TYPE_BORDER_GENERATOR (g_border_generator_get_type())
+#define G_BORDER_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GBorderGenerator))
+#define G_BORDER_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GBorderGeneratorClass))
+#define G_IS_BORDER_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_BORDER_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_BORDER_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GBorderGeneratorClass))
+
+
+/* Tampon pour générateur de délimitations de routines (instance) */
+typedef struct _GBorderGenerator GBorderGenerator;
+
+/* Tampon pour générateur de délimitations de routines (classe) */
+typedef struct _GBorderGeneratorClass GBorderGeneratorClass;
+
+
+/* Détermine le type du générateur de délimitations de routines à la volée. */
+GType g_border_generator_get_type(void);
+
+/* Crée un nouveau générateur de délimitations de routines. */
+GBorderGenerator *g_border_generator_new(GCodingLanguage *, const vmpa2t *, bool, MemoryDataSize);
+
+
+
+#endif /* _GLIBEXT_GENERATORS_RBORDER_H */
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index 3a1863e..cd452bc 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -30,7 +30,7 @@
#include <string.h>
-#include "gcodebuffer.h"
+#include "gbuffercache.h"
@@ -51,7 +51,7 @@ struct _GWidthTracker
{
GObject parent; /* A laisser en premier */
- GCodeBuffer *buffer; /* Ensemble complet de lignes */
+ GBufferCache *cache; /* Ensemble complet de lignes */
common_metrics *portions; /* Portions représentées */
size_t count; /* Quantité de ces portions */
@@ -163,7 +163,7 @@ static void g_width_tracker_init(GWidthTracker *tracker)
static void g_width_tracker_dispose(GWidthTracker *tracker)
{
- g_object_unref(G_OBJECT(tracker->buffer));
+ g_object_unref(G_OBJECT(tracker->cache));
G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker));
@@ -203,14 +203,14 @@ static void g_width_tracker_finalize(GWidthTracker *tracker)
* *
******************************************************************************/
-GWidthTracker *g_width_tracker_new(GCodeBuffer *buffer)
+GWidthTracker *g_width_tracker_new(GBufferCache *cache)
{
GWidthTracker *result; /* Composant à retourner */
result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL);
- g_object_ref(G_OBJECT(buffer));
- result->buffer = buffer;
+ g_object_ref(G_OBJECT(cache));
+ result->cache = cache;
return result;
@@ -240,8 +240,8 @@ GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *template, siz
result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL);
- g_object_ref(G_OBJECT(template->buffer));
- result->buffer = template->buffer;
+ g_object_ref(G_OBJECT(template->cache));
+ result->cache = template->cache;
start = g_width_tracker_find_metrics(template, first);
assert(start < template->count);
@@ -404,7 +404,6 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
{
common_metrics *portion; /* Portion à actualiser */
size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à manipuler */
assert(index < tracker->count);
@@ -419,12 +418,7 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
/* Collecte */
for (i = portion->first; i <= portion->last; i++)
- {
- line = g_code_buffer_find_line_by_index(tracker->buffer, i);
-
- g_buffer_line_collect_widths(line, &portion->summary);
-
- }
+ g_buffer_cache_collect_widths(tracker->cache, i, &portion->summary);
/* Marquage pour mémoire */
@@ -441,6 +435,30 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
* *
* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. *
* index = position de la première des lignes à ajouter. *
+* *
+* Description : Prend acte d'un changement sur une ligne pour les largeurs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_width_tracker_update(GWidthTracker *tracker, size_t index)
+{
+ size_t current; /* Indice de portion visée */
+
+ current = g_width_tracker_find_metrics(tracker, index);
+
+ g_width_tracker_reset_widths(tracker, current);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. *
+* index = position de la première des lignes à ajouter. *
* count = quantité de lignes devant être ajoutées. *
* *
* Description : Prend acte de l'ajout de lignes pour les largeurs. *
@@ -457,7 +475,6 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
common_metrics *portion; /* Portion sélectionnée */
size_t next; /* Prochaine portion à décaller*/
size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à manipuler */
size_t dest; /* Destination d'une recopie */
size_t src; /* Source d'une recopie */
@@ -502,9 +519,7 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
for (i = index + count - 1; i >= index; i--)
{
- line = g_code_buffer_find_line_by_index(tracker->buffer, i);
-
- if (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER)
+ if (g_buffer_cache_get_line_flags(tracker->cache, i) & BLF_WIDTH_MANAGER)
{
/* Insertion d'une nouvelle place */
@@ -602,11 +617,11 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
/* Suppression de portions inutiles ? */
- keep_first = (tracker->portions[first].first > start || end < tracker->portions[first].last);
+ keep_first = (tracker->portions[first].first < start || end < tracker->portions[first].last);
dest = (keep_first ? first + 1 : first);
- keep_last = (tracker->portions[last].first > start || end < tracker->portions[last].last);
+ keep_last = (tracker->portions[last].first < start || end < tracker->portions[last].last);
src = (keep_last ? last : last + 1);
@@ -647,7 +662,7 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
if (end < tracker->portions[first].last)
tracker->portions[first].last -= diff;
else
- tracker->portions[first].last = start;
+ tracker->portions[first].last = start - 1;
}
if (keep_last && last != first)
diff --git a/src/glibext/gwidthtracker.h b/src/glibext/gwidthtracker.h
index fe22088..b9d22ed 100644
--- a/src/glibext/gwidthtracker.h
+++ b/src/glibext/gwidthtracker.h
@@ -33,9 +33,8 @@
-/* gcodebuffer.h : Tampon pour code désassemblé (instance) */
-typedef struct _GCodeBuffer GCodeBuffer;
-
+/* gbuffercache.h : Tampon pour gestion de lignes optimisée (instance) */
+typedef struct _GBufferCache GBufferCache;
#define G_TYPE_WIDTH_TRACKER (g_width_tracker_get_type())
@@ -57,11 +56,14 @@ typedef struct _GWidthTrackerClass GWidthTrackerClass;
GType g_width_tracker_get_type(void);
/* Crée un nouveau suivi de largeurs au sein de lignes. */
-GWidthTracker *g_width_tracker_new(GCodeBuffer *);
+GWidthTracker *g_width_tracker_new(GBufferCache *);
/* Crée un nouveau suivi de largeurs au sein de lignes. */
GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, size_t);
+/* Prend acte d'un changement sur une ligne pour les largeurs. */
+void g_width_tracker_update(GWidthTracker *, size_t);
+
/* Prend acte de l'ajout de lignes pour les largeurs. */
void g_width_tracker_update_added(GWidthTracker *, size_t, size_t);
diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c
index 83413cf..5cce969 100644
--- a/src/glibext/linecolumn.c
+++ b/src/glibext/linecolumn.c
@@ -389,7 +389,7 @@ line_segment *get_line_column_content_from_index(const line_column *column, size
{
line_segment *result; /* Trouvaille à retourner */
- assert(index < column->count);
+ assert(index != -1 && index < column->count);
result = column->segments[index];
diff --git a/src/glibext/linegen-int.h b/src/glibext/linegen-int.h
new file mode 100644
index 0000000..f43b2f3
--- /dev/null
+++ b/src/glibext/linegen-int.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen-int.h - définitions internes propres aux intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_LINEGEN_INT_H
+#define _GLIBEXT_LINEGEN_INT_H
+
+
+#include "linegen.h"
+
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+typedef size_t (* linegen_count_lines_fc) (const GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+typedef void (* linegen_compute_fc) (const GLineGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+typedef int (* linegen_contains_fc) (const GLineGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+typedef BufferLineFlags (* linegen_get_flags_fc) (const GLineGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+typedef void (* linegen_print_fc) (GLineGenerator *, GBufferLine *, size_t, size_t);
+
+
+/* Intermédiaire pour la génération de lignes (interface) */
+struct _GLineGeneratorIface
+{
+ GTypeInterface base_iface; /* A laisser en premier */
+
+ linegen_count_lines_fc count; /* Décompte des lignes */
+ linegen_compute_fc compute; /* Calcul d'emplacement */
+ linegen_contains_fc contains; /* Inclusion de positions */
+ linegen_get_flags_fc get_flags; /* Récupération des drapeaux */
+ linegen_print_fc print; /* Impression d'une ligne */
+
+};
+
+
+/* Redéfinition */
+typedef GLineGeneratorIface GLineGeneratorInterface;
+
+
+
+#endif /* _GLIBEXT_LINEGEN_INT_H */
diff --git a/src/glibext/linegen.c b/src/glibext/linegen.c
new file mode 100644
index 0000000..fc0e01e
--- /dev/null
+++ b/src/glibext/linegen.c
@@ -0,0 +1,208 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.c - intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "linegen.h"
+
+
+#include <assert.h>
+
+
+#include "linegen-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_line_generator_default_init(GLineGeneratorInterface *);
+
+
+
+/* Détermine le type d'une interface pour la mise en place de lignes. */
+G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_line_generator_default_init(GLineGeneratorInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* *
+* Description : Indique le nombre de ligne prêtes à être générées. *
+* *
+* Retour : Nombre de lignes devant apparaître au final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_line_generator_count_lines(const GLineGenerator *generator)
+{
+ size_t result; /* Décompte à retourner */
+ GLineGeneratorIface *iface; /* Interface utilisée */
+
+ iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+ result = iface->count(generator);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* addr = position en mémoire à analyser. *
+* 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. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+ GLineGeneratorIface *iface; /* Interface utilisée */
+
+ iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+ if (iface->count != NULL)
+ assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+ iface->compute(generator, x, addr, index, repeat);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* addr = position en mémoire à analyser. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int g_line_generator_contains_addr(const GLineGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+ GLineGeneratorIface *iface; /* Interface utilisée */
+
+ iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+ if (iface->count != NULL)
+ assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+ return iface->contains(generator, addr, index, repeat);
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Renseigne sur les propriétés liées à un générateur. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size_t index, size_t repeat)
+{
+ GLineGeneratorIface *iface; /* Interface utilisée */
+
+ iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+ if (iface->count != NULL)
+ assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+ return iface->get_flags(generator, index, repeat);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_line_generator_print(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+ GLineGeneratorIface *iface; /* Interface utilisée */
+
+ iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+ if (iface->count != NULL)
+ assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+ return iface->print(generator, line, index, repeat);
+
+}
diff --git a/src/glibext/linegen.h b/src/glibext/linegen.h
new file mode 100644
index 0000000..c64baaa
--- /dev/null
+++ b/src/glibext/linegen.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.h - prototypes pour les intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_LINEGEN_H
+#define _GLIBEXT_LINEGEN_H
+
+
+
+#include "gbufferline.h"
+
+
+
+#define G_TYPE_LINE_GENERATOR (g_line_generator_get_type())
+#define G_LINE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LINE_GENERATOR, GLineGenerator))
+#define G_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LINE_GENERATOR, GLineGeneratorIface))
+#define GTK_IS_LINE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LINE_GENERATOR))
+#define GTK_IS_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LINE_GENERATOR))
+#define G_LINE_GENERATOR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LINE_GENERATOR, GLineGeneratorIface))
+
+
+/* Intermédiaire pour la génération de lignes (coquille vide) */
+typedef struct _GLineGenerator GLineGenerator;
+
+/* Intermédiaire pour la génération de lignes (interface) */
+typedef struct _GLineGeneratorIface GLineGeneratorIface;
+
+
+/* Détermine le type d'une interface pour la mise en place de lignes. */
+GType g_line_generator_get_type(void) G_GNUC_CONST;
+
+/* Indique le nombre de ligne prêtes à être générées. */
+size_t g_line_generator_count_lines(const GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+void g_line_generator_compute_addr(const GLineGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+int g_line_generator_contains_addr(const GLineGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+BufferLineFlags g_line_generator_get_flags(const GLineGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+void g_line_generator_print(GLineGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+#endif /* _GLIBEXT_LINEGEN_H */
diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c
index 8306320..5208db6 100644
--- a/src/glibext/linesegment.c
+++ b/src/glibext/linesegment.c
@@ -47,7 +47,11 @@
static const char *_segment_names[RTT_COUNT] = {
+ [RTT_NONE] = SEGMENT_NAME("none"),
[RTT_RAW] = SEGMENT_NAME("raw"),
+ [RTT_RAW_NULL] = SEGMENT_NAME("raw-null"),
+ [RTT_PRINTABLE] = SEGMENT_NAME("printable"),
+ [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"),
[RTT_COMMENT] = SEGMENT_NAME("comment"),
[RTT_INDICATION] = SEGMENT_NAME("indication"),
[RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"),
@@ -55,6 +59,7 @@ static const char *_segment_names[RTT_COUNT] = {
[RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"),
[RTT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"),
[RTT_RAW_CODE] = SEGMENT_NAME("raw-code"),
+ [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"),
[RTT_LABEL] = SEGMENT_NAME("label"),
[RTT_INSTRUCTION] = SEGMENT_NAME("instruction"),
[RTT_IMMEDIATE] = SEGMENT_NAME("immediate"),
@@ -162,6 +167,10 @@ struct _segcnt_list
};
+/* Indique si le contenu d'un segment est notable ou non. */
+bool selection_list_has_segment_content(const segcnt_list *, const line_segment *);
+
+
/* ---------------------------------------------------------------------------------- */
/* NATURE POUR UN FRAGMENT DE TEXTE */
diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h
index da43e7e..892dce2 100644
--- a/src/glibext/linesegment.h
+++ b/src/glibext/linesegment.h
@@ -66,7 +66,12 @@ void exit_segment_content_hash_table(void);
/* Types de partie de rendu */
typedef enum _RenderingTagType
{
+ RTT_NONE, /* Espace ou tabulation */
+
RTT_RAW, /* Contenu brut */
+ RTT_RAW_NULL, /* Contenu brut et nul */
+ RTT_PRINTABLE, /* Caractère imprimable */
+ RTT_NOT_PRINTABLE, /* Caractère non imprimable */
RTT_COMMENT, /* Commentaire */
RTT_INDICATION, /* Aide à la lecture */
@@ -76,6 +81,7 @@ typedef enum _RenderingTagType
RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */
RTT_VIRT_ADDR, /* Adresse virtuelle */
RTT_RAW_CODE, /* Code binaire brut */
+ RTT_RAW_CODE_NULL, /* Code binaire brut et nul */
RTT_LABEL, /* Etiquette sur une adresse */
@@ -188,9 +194,6 @@ bool reset_segment_content_list(segcnt_list *);
/* Marque le contenu d'un segment comme remarquable. */
bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *);
-/* Indique si le contenu d'un segment est notable ou non. */
-bool selection_list_has_segment_content(const segcnt_list *, const line_segment *);
-
#endif /* _GLIBEXT_LINESEGMENT_H */
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 45ce4ad..d874ac1 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -1,21 +1,20 @@
noinst_LTLIBRARIES = libgtkext.la
-libgtkext_la_SOURCES = \
- easygtk.h easygtk.c \
- gtkbinarystrip.h gtkbinarystrip.c \
- gtkextstatusbar.h gtkextstatusbar.c \
- gtkblockview.h gtkblockview.c \
- gtkbufferview-int.h \
- gtkbufferview.h gtkbufferview.c \
- gtkdisplaypanel-int.h \
- gtkdisplaypanel.h gtkdisplaypanel.c \
- gtkdockable-int.h \
- gtkdockable.h gtkdockable.c \
- gtkdockstation.h gtkdockstation.c \
- gtkgraphview.h gtkgraphview.c \
- gtksourceview.h gtksourceview.c \
- gtkstatusstack.h gtkstatusstack.c \
+libgtkext_la_SOURCES = \
+ easygtk.h easygtk.c \
+ gtkbinarystrip.h gtkbinarystrip.c \
+ gtkextstatusbar.h gtkextstatusbar.c \
+ gtkblockdisplay.h gtkblockdisplay.c \
+ gtkbufferdisplay-int.h \
+ gtkbufferdisplay.h gtkbufferdisplay.c \
+ gtkdisplaypanel-int.h \
+ gtkdisplaypanel.h gtkdisplaypanel.c \
+ gtkdockable-int.h \
+ gtkdockable.h gtkdockable.c \
+ gtkdockstation.h gtkdockstation.c \
+ gtkgraphdisplay.h gtkgraphdisplay.c \
+ gtkstatusstack.h gtkstatusstack.c \
support.h support.c
libgtkext_la_LIBADD = \
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 06e06c2..558e3cd 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -30,8 +30,8 @@
#include <string.h>
-#include "../gtkblockview.h"
-#include "../gtkbufferview.h"
+#include "../gtkblockdisplay.h"
+#include "../gtkbufferdisplay.h"
#include "../gtkdisplaypanel.h"
#include "../../common/sort.h"
@@ -104,7 +104,7 @@ struct _GGraphCluster
size_t ta_count; /* Quantité de ces accroches */
GBasicBlock *block; /* Bloc d'origine représenté */
- GtkWidget *view; /* Vue graphique associée */
+ GtkWidget *display; /* Vue graphique associée */
GtkAllocation alloc; /* Emplacement final du bloc */
leaving_edge **bottom_anchors; /* Accroches inférieures */
@@ -255,7 +255,7 @@ static void g_graph_cluster_init(GGraphCluster *cluster)
static void g_graph_cluster_dispose(GGraphCluster *cluster)
{
g_object_unref(G_OBJECT(cluster->block));
- g_object_unref(G_OBJECT(cluster->view));
+ g_object_unref(G_OBJECT(cluster->display));
G_OBJECT_CLASS(g_graph_cluster_parent_class)->dispose(G_OBJECT(cluster));
@@ -301,7 +301,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
GGraphCluster *result; /* Structure à retourner */
vmpa2t first; /* Début d'un groupe de lignes */
vmpa2t last; /* Fin d'un groupe de lignes */
- GCodeBuffer *buffer; /* Tampon brut à découper */
+ GBufferCache *cache; /* Tampon brut à découper */
GBufferView *view; /* Partie affichée du tampon */
GtkRequisition requisition; /* Taille à l'écran actuelle */
@@ -312,26 +312,26 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
result->block = g_block_list_get_block(list, index);
g_object_ref(G_OBJECT(result->block));
- result->view = gtk_block_view_new();
+ result->display = gtk_block_display_new();
- gtk_widget_show(result->view);
- gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->view), binary, BVW_GRAPH);
+ gtk_widget_show(result->display);
+ gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->display), binary, BVW_GRAPH);
- gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->view), true);
+ gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true);
/* Restriction au bloc basique */
g_basic_block_get_boundary_addresses(result->block, &first, &last);
- buffer = g_loaded_binary_get_disassembled_buffer(binary);
+ cache = g_loaded_binary_get_disassembled_cache(binary);
- view = g_buffer_view_new(buffer, highlighted);
+ view = g_buffer_view_new(cache, highlighted);
g_buffer_view_restrict(view, &first, &last);
- gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result->view), view);
+ gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(result->display), view);
/* Détermination d'une position initiale centrée */
- gtk_widget_get_preferred_size(result->view, NULL, &requisition);
+ gtk_widget_get_preferred_size(result->display, NULL, &requisition);
result->alloc.x = -requisition.width / 2;
result->alloc.y = 0;
@@ -741,7 +741,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
if (needed.x < alloc->x)
{
- alloc->width += (alloc->x + needed.x);
+ alloc->width += (alloc->x - needed.x);
alloc->x = needed.x;
}
@@ -765,7 +765,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
if (needed.x < alloc->x)
{
- alloc->width += (alloc->x + needed.x);
+ alloc->width += (alloc->x - needed.x);
alloc->x = needed.x;
}
@@ -800,7 +800,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
/******************************************************************************
* *
* Paramètres : cluster = encapsulation à traiter. *
-* view = support de destination finale. *
+* display = support de destination finale. *
* *
* Description : Dispose chaque noeud sur la surface de destination donnée. *
* *
@@ -810,23 +810,23 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
* *
******************************************************************************/
-void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphView *view)
+void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphDisplay *display)
{
size_t i; /* Boucle de parcours #1 */
size_t j; /* Boucle de parcours #2 */
- g_object_ref(G_OBJECT(cluster->view));
- gtk_graph_view_put(view, cluster->view, &cluster->alloc);
+ g_object_ref(G_OBJECT(cluster->display));
+ gtk_graph_display_put(display, cluster->display, &cluster->alloc);
for (i = 0; i < cluster->ta_count; i++)
{
g_object_ref(G_OBJECT(cluster->top_anchors[i]->edge));
- gtk_graph_view_add_edge(view, cluster->top_anchors[i]->edge);
+ gtk_graph_display_add_edge(display, cluster->top_anchors[i]->edge);
}
for (i = 0; i < cluster->ranks_count; i++)
for (j = 0; j < cluster->ranks[i].count; j++)
- g_graph_cluster_place(cluster->ranks[i].clusters[j], view);
+ g_graph_cluster_place(cluster->ranks[i].clusters[j], display);
}
@@ -1671,9 +1671,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
/******************************************************************************
* *
-* Paramètres : blocks = ensemble des blocs basiques déjà découpés. *
-* views = morceaux de code à afficher de façon organisée. *
-* count = quantité de ces morceaux de code. *
+* Paramètres : blocXXXXXXXXXXXXXXXXXXXXks = ensemble des blocs basiques déjà découpés. *
+* views = morceaux de codXXXXXXXXXXXXXXXXXxe à afficher de façon organisée. *
+* count = quantité de ces morceaux de code.XXXXXXXXXXXXXXXXXX *
* *
* Description : Construit un graphique à partir de blocs basiques. *
* *
diff --git a/src/gtkext/graph/cluster.h b/src/gtkext/graph/cluster.h
index d43622b..9c375d3 100644
--- a/src/gtkext/graph/cluster.h
+++ b/src/gtkext/graph/cluster.h
@@ -26,7 +26,7 @@
-#include "../gtkgraphview.h"
+#include "../gtkgraphdisplay.h"
#include "../../analysis/binary.h"
#include "../../analysis/disass/block.h"
@@ -57,7 +57,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *, const GBlockList *, size_t,
void g_graph_cluster_compute_needed_alloc(const GGraphCluster *, GtkAllocation *);
/* Dispose chaque noeud sur la surface de destination donnée. */
-void g_graph_cluster_place(GGraphCluster *, GtkGraphView *);
+void g_graph_cluster_place(GGraphCluster *, GtkGraphDisplay *);
diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c
index 561b9f3..27400a6 100644
--- a/src/gtkext/graph/edge.c
+++ b/src/gtkext/graph/edge.c
@@ -267,6 +267,33 @@ void g_graph_edge_resolve(GGraphEdge *edge)
/******************************************************************************
* *
+* Paramètres : edge = ligne de rendu à modifier dans ses positions. *
+* dx = déplacement à effectuer sur l'axe des abscisses. *
+* dy = déplacement à effectuer sur l'axe des ordonnées. *
+* *
+* Description : Opère un décallage du lien dans une direction donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_graph_edge_offset(GGraphEdge *edge, gint dx, gint dy)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < edge->count; i++)
+ {
+ edge->points[i].x += dx;
+ edge->points[i].y += dy;
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : edge = ligne de rendu à manipuler. *
* cairo = assistant pour le rendu graphique. *
* arrow = indique le besoin en flèche à l'arrivée. *
diff --git a/src/gtkext/graph/edge.h b/src/gtkext/graph/edge.h
index f60954c..4c43edb 100644
--- a/src/gtkext/graph/edge.h
+++ b/src/gtkext/graph/edge.h
@@ -81,6 +81,9 @@ void g_graph_edge_get_x_borders(const GGraphEdge *, gint *, gint *);
/* Détermine les positions finales d'un lien graphique. */
void g_graph_edge_resolve(GGraphEdge *);
+/* Opère un décallage du lien dans une direction donnée. */
+void g_graph_edge_offset(GGraphEdge *, gint, gint);
+
/* Dessine les liens graphiques enregistrés dans le moteur. */
void g_graph_edge_draw(const GGraphEdge *, cairo_t *, bool);
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockdisplay.c
index 82743b0..d53d766 100644
--- a/src/gtkext/gtkblockview.c
+++ b/src/gtkext/gtkblockdisplay.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkblockview.c - affichage d'un fragment de code d'assemblage
+ * gtkblockdisplay.c - affichage d'un fragment de code d'assemblage
*
* Copyright (C) 2008-2012 Cyrille Bagard
*
@@ -21,62 +21,60 @@
*/
-#include "gtkblockview.h"
+#include "gtkblockdisplay.h"
-#include "gtkbufferview-int.h"
+#include "gtkbufferdisplay-int.h"
-/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
-
-
/* Composant d'affichage de bloc d'assembleur (instance) */
-struct _GtkBlockView
+struct _GtkBlockDisplay
{
- GtkBufferView parent; /* A laisser en premier */
+ GtkBufferDisplay parent; /* A laisser en premier */
};
/* Composant d'affichage de code d'assembleur (classe) */
-struct _GtkBlockViewClass
+struct _GtkBlockDisplayClass
{
- GtkBufferViewClass parent; /* A laisser en premier */
+ GtkBufferDisplayClass parent; /* A laisser en premier */
/* Signaux */
- void (* highlight_changed) (GtkBlockView *);
+ void (* highlight_changed) (GtkBlockDisplay *);
};
/* Procède à l'initialisation des afficheurs de bloc assembleur. */
-static void gtk_block_view_class_init(GtkBlockViewClass *);
+static void gtk_block_display_class_init(GtkBlockDisplayClass *);
/* Procède à l'initialisation de l'afficheur de bloc assembleur. */
-static void gtk_block_view_init(GtkBlockView *);
+static void gtk_block_display_init(GtkBlockDisplay *);
-/* Réagit à un déplacement de curseur. */
-static bool gtk_block_view_notify_caret_relocation(GtkBlockView *, const GdkRectangle *, const vmpa2t *);
+/* Supprime toutes les références externes. */
+static void gtk_block_display_dispose(GtkBlockDisplay *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_block_display_finalize(GtkBlockDisplay *);
/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_block_view_button_press_event(GtkBlockView *, GdkEventButton *, gpointer);
+static gboolean gtk_block_display_button_press(GtkWidget *, GdkEventButton *);
/* Redessine l'affichage suite à un changement visuel. */
-static gboolean gtk_block_view_need_redraw(GBufferView *, GtkBlockView *);
+static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *, GBufferView *);
/* Prend acte de l'association d'un binaire chargé. */
-static void gtk_block_view_attach_binary(GtkBlockView *, GLoadedBinary *);
-
+static void gtk_block_display_attach_binary(GtkBlockDisplay *, GLoadedBinary *);
+/* Réagit à un déplacement de curseur. */
+static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *, const GdkRectangle *, const vmpa2t *);
-/* ---------------------------------------------------------------------------------- */
-/* INTERACTION DIRECTE AVEC GTK */
-/* ---------------------------------------------------------------------------------- */
/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
-G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BUFFER_VIEW)
+G_DEFINE_TYPE(GtkBlockDisplay, gtk_block_display, GTK_TYPE_BUFFER_DISPLAY)
/******************************************************************************
@@ -91,22 +89,36 @@ G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BUFFER_VIEW)
* *
******************************************************************************/
-static void gtk_block_view_class_init(GtkBlockViewClass *class)
+static void gtk_block_display_class_init(GtkBlockDisplayClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+ GtkWidgetClass *widget_class; /* Classe version Widget */
GtkDisplayPanelClass *panel_class; /* Classe parente */
- GtkBufferViewClass *buffer_class; /* Classe supérieure */
+ GtkBufferDisplayClass *buffer_class; /* Classe supérieure */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_block_display_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_block_display_finalize;
+
+ widget_class = GTK_WIDGET_CLASS(class);
+
+ widget_class->button_press_event = gtk_block_display_button_press;
panel_class = GTK_DISPLAY_PANEL_CLASS(class);
- buffer_class = GTK_BUFFER_VIEW_CLASS(class);
- panel_class->attach = (attach_binary_fc)gtk_block_view_attach_binary;
+ panel_class->attach = (attach_binary_fc)gtk_block_display_attach_binary;
+
+ buffer_class = GTK_BUFFER_DISPLAY_CLASS(class);
- buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_view_notify_caret_relocation;
+ buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_display_notify_caret_relocation;
+
+ /* Signaux */
g_signal_new("highlight-changed",
- GTK_TYPE_BLOCK_VIEW,
+ GTK_TYPE_BLOCK_DISPLAY,
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GtkBlockViewClass, highlight_changed),
+ G_STRUCT_OFFSET(GtkBlockDisplayClass, highlight_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -126,44 +138,46 @@ static void gtk_block_view_class_init(GtkBlockViewClass *class)
* *
******************************************************************************/
-static void gtk_block_view_init(GtkBlockView *view)
+static void gtk_block_display_init(GtkBlockDisplay *view)
{
-
- /*
- g_signal_connect(G_OBJECT(view), "button_press_event",
- G_CALLBACK(gtk_block_view_button_press_event), NULL);
- */
-
-
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* area = emplacement pour le dessin d'un curseur. *
-* addr = position dans la mémoire représentée du curseur. *
+* Paramètres : display = instance d'objet GLib à traiter. *
* *
-* Description : Réagit à un déplacement de curseur. *
+* Description : Supprime toutes les références externes. *
* *
-* Retour : true si un changement a été opéré. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const GdkRectangle *area, const vmpa2t *addr)
+static void gtk_block_display_dispose(GtkBlockDisplay *display)
{
- bool result; /* Bilan à retourner */
+ G_OBJECT_CLASS(gtk_block_display_parent_class)->dispose(G_OBJECT(display));
- result = g_buffer_view_highlight_segments(GTK_BUFFER_VIEW(view)->buffer_view, area->x, area->y,
- GTK_DISPLAY_PANEL(view)->display);
+}
- if (result)
- g_signal_emit_by_name(view, "highlight-changed");
- return result;
+/******************************************************************************
+* *
+* Paramètres : display = instance d'objet Gtk à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_block_display_finalize(GtkBlockDisplay *display)
+{
+ G_OBJECT_CLASS(gtk_block_display_parent_class)->finalize(G_OBJECT(display));
}
@@ -180,11 +194,11 @@ static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const Gdk
* *
******************************************************************************/
-GtkWidget *gtk_block_view_new(void)
+GtkWidget *gtk_block_display_new(void)
{
- GtkBlockView *result; /* Composant à retourner */
+ GtkBlockDisplay *result; /* Composant à retourner */
- result = g_object_new(GTK_TYPE_BLOCK_VIEW, NULL);
+ result = g_object_new(GTK_TYPE_BLOCK_DISPLAY, NULL);
return GTK_WIDGET(result);
@@ -193,9 +207,8 @@ GtkWidget *gtk_block_view_new(void)
/******************************************************************************
* *
-* Paramètres : view = composant GTK visé par l'opération. *
-* event = informations liées à l'événement. *
-* data = donnée non utilisée ici. *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
* *
* Description : Assure la gestion des clics de souris sur le composant. *
* *
@@ -205,31 +218,33 @@ GtkWidget *gtk_block_view_new(void)
* *
******************************************************************************/
-static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventButton *event, gpointer data)
+static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton *event)
{
- GtkBufferView *bview; /* Autre vision du composant */
+ GtkBlockDisplay *display; /* Autre version du composant */
gint real_x; /* Abscisse absolue réelle */
gint real_y; /* Ordonnée absolue réelle */
+ GBufferView *view; /* Vue du tampon représenté */
+ bool changed; /* Suivi des changements */
- if (event->type == GDK_2BUTTON_PRESS)
- {
-
-
+ GTK_WIDGET_CLASS(gtk_block_display_parent_class)->button_press_event(widget, event);
- printf("I feel %s clicked with button %d\n",
- event->type == GDK_2BUTTON_PRESS ? "double" : "triple",
- event->button);
-
- bview = GTK_BUFFER_VIEW(view);
+ display = GTK_BLOCK_DISPLAY(widget);
+ if (event->type == GDK_2BUTTON_PRESS)
+ {
real_x = event->x;
real_y = event->y;
- gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(bview), &real_x, &real_y);
+ gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y);
+
+ view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
- g_buffer_view_highlight_segments(gtk_buffer_view_get_buffer(bview), real_x, real_y, NULL);
+ changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display);
+ g_object_unref(G_OBJECT(view));
+ if (changed)
+ g_signal_emit_by_name(display, "highlight-changed");
}
@@ -240,8 +255,8 @@ static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventBu
/******************************************************************************
* *
-* Paramètres : view = composant GLib interne. *
-* block = composant GTK d'affichage. *
+* Paramètres : display = composant GTK d'affichage. *
+* view = composant GLib interne. *
* *
* Description : Redessine l'affichage suite à un changement visuel. *
* *
@@ -251,9 +266,9 @@ static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventBu
* *
******************************************************************************/
-static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *block)
+static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *display, GBufferView *view)
{
- gtk_widget_queue_draw(GTK_WIDGET(block));
+ gtk_widget_queue_draw(GTK_WIDGET(display));
return FALSE;
@@ -262,8 +277,8 @@ static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *bloc
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* binary = binaire associé à intégrer. *
+* Paramètres : display = composant GTK à mettre à jour. *
+* binary = binaire associé à intégrer. *
* *
* Description : Prend acte de l'association d'un binaire chargé. *
* *
@@ -273,17 +288,50 @@ static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *bloc
* *
******************************************************************************/
-static void gtk_block_view_attach_binary(GtkBlockView *view, GLoadedBinary *binary)
+static void gtk_block_display_attach_binary(GtkBlockDisplay *display, GLoadedBinary *binary)
{
- GCodeBuffer *buffer; /* Tampon par défaut */
- GBufferView *bview; /* Vue sur ce même tampon */
+ GBufferCache *cache; /* Tampon par défaut */
+ GBufferView *view; /* Vue sur ce même tampon */
- buffer = g_loaded_binary_get_disassembled_buffer(binary);
- bview = g_buffer_view_new(buffer, NULL);
+ cache = g_loaded_binary_get_disassembled_cache(binary);
+ view = g_buffer_view_new(cache, NULL);
- gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), bview);
+ gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(display), view);
- g_signal_connect(G_OBJECT(bview), "need-redraw",
- G_CALLBACK(gtk_block_view_need_redraw), view);
+ g_signal_connect_swapped(G_OBJECT(view), "need-redraw",
+ G_CALLBACK(gtk_block_display_need_redraw), display);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : display = composant GTK à manipuler. *
+* area = emplacement pour le dessin d'un curseur. *
+* addr = position dans la mémoire représentée du curseur. *
+* *
+* Description : Réagit à un déplacement de curseur. *
+* *
+* Retour : true si un changement a été opéré. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display, const GdkRectangle *area, const vmpa2t *addr)
+{
+ bool result; /* Bilan à retourner */
+ GBufferView *view; /* Vue du tampon représenté */
+
+ view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
+
+ result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display);
+
+ g_object_unref(G_OBJECT(view));
+
+ if (result)
+ g_signal_emit_by_name(display, "highlight-changed");
+
+ return result;
}
diff --git a/src/gtkext/gtkblockview.h b/src/gtkext/gtkblockdisplay.h
index 735d128..caef762 100644
--- a/src/gtkext/gtkblockview.h
+++ b/src/gtkext/gtkblockdisplay.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkblockview.h - prototypes pour l'affichage d'un fragment de code d'assemblage
+ * gtkblockdisplay.h - prototypes pour l'affichage d'un fragment de code d'assemblage
*
* Copyright (C) 2008-2014 Cyrille Bagard
*
@@ -21,8 +21,8 @@
*/
-#ifndef _GTKEXT_GTKBLOCKVIEW_H
-#define _GTKEXT_GTKBLOCKVIEW_H
+#ifndef _GTKEXT_GTKBLOCKDISPLAY_H
+#define _GTKEXT_GTKBLOCKDISPLAY_H
#include <glib-object.h>
@@ -30,27 +30,27 @@
-#define GTK_TYPE_BLOCK_VIEW (gtk_block_view_get_type())
-#define GTK_BLOCK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockView))
-#define GTK_BLOCK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass))
-#define GTK_IS_BLOCK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_VIEW))
-#define GTK_IS_BLOCK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_VIEW))
-#define GTK_BLOCK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass))
+#define GTK_TYPE_BLOCK_DISPLAY (gtk_block_display_get_type())
+#define GTK_BLOCK_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplay))
+#define GTK_BLOCK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass))
+#define GTK_IS_BLOCK_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_DISPLAY))
+#define GTK_IS_BLOCK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_DISPLAY))
+#define GTK_BLOCK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass))
/* Composant d'affichage de code d'assembleur (instance) */
-typedef struct _GtkBlockView GtkBlockView;
+typedef struct _GtkBlockDisplay GtkBlockDisplay;
/* Composant d'affichage de code d'assembleur (classe) */
-typedef struct _GtkBlockViewClass GtkBlockViewClass;
+typedef struct _GtkBlockDisplayClass GtkBlockDisplayClass;
/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
-GType gtk_block_view_get_type(void);
+GType gtk_block_display_get_type(void);
/* Crée un nouveau composant pour l'affichage de bloc en ASM. */
-GtkWidget *gtk_block_view_new(void);
+GtkWidget *gtk_block_display_new(void);
-#endif /* _GTKEXT_GTKBLOCKVIEW_H */
+#endif /* _GTKEXT_GTKBLOCKDISPLAY_H */
diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferdisplay-int.h
index a7da69d..4406361 100644
--- a/src/gtkext/gtkbufferview-int.h
+++ b/src/gtkext/gtkbufferdisplay-int.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes
+ * gtkbufferdisplay-int.h - prototypes internes pour l'affichage de tampons de lignes
*
- * Copyright (C) 2010-2013 Cyrille Bagard
+ * Copyright (C) 2016 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -21,11 +21,11 @@
*/
-#ifndef _GTK_BUFFERVIEW_INT_H
-#define _GTK_BUFFERVIEW_INT_H
+#ifndef _GTK_BUFFERDISPLAY_INT_H
+#define _GTK_BUFFERDISPLAY_INT_H
-#include "gtkbufferview.h"
+#include "gtkbufferdisplay.h"
#include "gtkdisplaypanel-int.h"
@@ -33,30 +33,25 @@
/* Réagit à un déplacement de curseur. */
-typedef bool (* notify_caret_relocation_fc) (GtkBufferView *, const GdkRectangle *, const vmpa2t *);
+typedef bool (* notify_caret_relocation_fc) (GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *);
/* Composant d'affichage de tampon de lignes (instance) */
-struct _GtkBufferView
+struct _GtkBufferDisplay
{
GtkDisplayPanel parent; /* A laisser en premier */
- //GCodeBuffer *buffer; /* Code sous forme de texte */
- GBufferView *buffer_view; /* Affichage de cette forme */
-
- gint line_height; /* Hauteur maximale des lignes */
- gint left_margin; /* Marge gauche + espace */
- gint left_text; /* Début d'impression du code */
+ GBufferView *view; /* Vue sur le contenu affiché */
GdkRectangle caret; /* Emplacement du curseur */
- const vmpa2t *caret_addr; /* Position mémoire du curseur */ /* FIXME : REMME */
+ vmpa2t caret_addr; /* Position mémoire du curseur */
guint caret_timer; /* Identifiant du chronomètre */
bool show_caret; /* Bascule entre les affichages*/
};
/* Composant d'affichage de tampon de lignes (classe) */
-struct _GtkBufferViewClass
+struct _GtkBufferDisplayClass
{
GtkDisplayPanelClass parent; /* A laisser en premier */
@@ -64,10 +59,10 @@ struct _GtkBufferViewClass
/* Signaux */
- void (* reach_limit) (GtkBufferView *, GdkScrollDirection);
+ void (* reach_limit) (GtkBufferDisplay *, GdkScrollDirection);
};
-#endif /* _GTK_BUFFERVIEW_INT_H */
+#endif /* _GTK_BUFFERDISPLAY_INT_H */
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferdisplay.c
index bafb15d..b510c8f 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.c - affichage de tampons de lignes
+ * gtkbufferdisplay.c - affichage de tampons de lignes
*
- * Copyright (C) 2010-2014 Cyrille Bagard
+ * Copyright (C) 2016 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -21,16 +21,13 @@
*/
-#include "gtkbufferview-int.h"
+#include "gtkbufferdisplay.h"
-#include <gdk/gdkkeysyms.h>
+#include "gtkbufferdisplay-int.h"
-#include "../arch/target.h"
-#include "../common/extstr.h"
#include "../core/params.h"
-#include "../glibext/chrysamarshal.h"
@@ -38,52 +35,46 @@
/* Procède à l'initialisation de l'afficheur de tampons. */
-static void gtk_buffer_view_class_init(GtkBufferViewClass *);
+static void gtk_buffer_display_class_init(GtkBufferDisplayClass *);
/* Procède à l'initialisation de l'afficheur de tampons. */
-static void gtk_buffer_view_init(GtkBufferView *);
+static void gtk_buffer_display_init(GtkBufferDisplay *);
/* Supprime toutes les références externes. */
-static void gtk_buffer_view_dispose(GtkBufferView *);
+static void gtk_buffer_display_dispose(GtkBufferDisplay *);
/* Procède à la libération totale de la mémoire. */
-static void gtk_buffer_view_finalize(GtkBufferView *);
+static void gtk_buffer_display_finalize(GtkBufferDisplay *);
/* Intègre le focus dans le rendu du composant. */
-static gboolean gtk_buffer_view_focus(GtkWidget *, GdkEventFocus *);
+static gboolean gtk_buffer_display_focus(GtkWidget *, GdkEventFocus *);
/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *);
+static gboolean gtk_buffer_display_button_press(GtkWidget *, GdkEventButton *);
/* Met à jour l'affichage de la visualisation de code buffer. */
-static gboolean gtk_buffer_view_draw(GtkWidget *, cairo_t *);
+static gboolean gtk_buffer_display_draw(GtkWidget *, cairo_t *);
/* Prend en compte une frappe de touche sur le composant. */
-static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);
-
-/* Prépare l'affichage d'une astuce. */
-static gboolean gtk_buffer_view_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *);
+static gboolean gtk_buffer_display_key_press(GtkWidget *, GdkEventKey *);
/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *);
+static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *, gint *, gint *);
/* Détermine la taille des bonds lors de défilements. */
-static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *);
+static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *, gint, GtkOrientation, gdouble *, gdouble *);
/* Réagit à un défilement chez une barre associée au composant. */
-static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkAdjustment *, GtkOrientation);
+static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *, GtkAdjustment *, GtkOrientation);
/* Indique la position courante du curseur. */
-static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *);
+static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *);
/* Indique la position d'affichage d'une adresse donnée. */
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
-
-/* Fournit des éléments liés à la position courante dans la vue. */
-static bool gtk_buffer_view_get_position(const GtkBufferView *, GBufferLine **, GObject **);
+static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
-static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAllocation *, double);
+static void gtk_buffer_display_cache_glance(GtkBufferDisplay *, cairo_t *, const GtkAllocation *, double);
@@ -91,16 +82,16 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl
/* Déplace le curseur à un emplacement défini. */
-static bool _gtk_buffer_view_move_caret_to(GtkBufferView *, gint, gint);
+static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *, gint, gint);
/* Déplace le curseur en effaçant son éventuelle position. */
-static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *);
+static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *);
/* Redémarre l'affichage du curseur à l'emplacement courant. */
-static void restart_caret_blinking(GtkBufferView *);
+static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *);
/* Bascule et relance l'affichage du curseur. */
-static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *);
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *);
@@ -110,7 +101,7 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *);
/* Détermine le type du composant d'affichage de tampon de lignes. */
-G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_DISPLAY_PANEL)
+G_DEFINE_TYPE(GtkBufferDisplay, gtk_buffer_display, GTK_TYPE_DISPLAY_PANEL)
/******************************************************************************
@@ -125,40 +116,41 @@ G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_DISPLAY_PANEL)
* *
******************************************************************************/
-static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
+static void gtk_buffer_display_class_init(GtkBufferDisplayClass *class)
{
GObjectClass *object; /* Autre version de la classe */
GtkWidgetClass *widget_class; /* Classe version Widget */
GtkDisplayPanelClass *panel_class; /* Classe parente */
object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_display_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_buffer_display_finalize;
+
widget_class = GTK_WIDGET_CLASS(class);
- panel_class = GTK_DISPLAY_PANEL_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_view_dispose;
- object->finalize = (GObjectFinalizeFunc)gtk_buffer_view_finalize;
+ widget_class->focus_in_event = gtk_buffer_display_focus;
+ widget_class->focus_out_event = gtk_buffer_display_focus;
+ widget_class->button_press_event = gtk_buffer_display_button_press;
+ widget_class->draw = gtk_buffer_display_draw;
+ widget_class->key_press_event = gtk_buffer_display_key_press;
- widget_class->focus_in_event = gtk_buffer_view_focus;
- widget_class->focus_out_event = gtk_buffer_view_focus;
- widget_class->button_press_event = gtk_buffer_view_button_press;
- widget_class->draw = gtk_buffer_view_draw;
- widget_class->key_press_event = gtk_buffer_view_key_press;
- widget_class->query_tooltip = gtk_buffer_view_query_tooltip;
+ panel_class = GTK_DISPLAY_PANEL_CLASS(class);
- panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size;
- panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc;
- panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value;
+ panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_display_compute_requested_size;
+ panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_display_compute_scroll_inc;
+ panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_display_adjust_scroll_value;
+ panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_display_get_caret_location;
+ panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_display_get_address_coordinates;
+ panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_display_move_caret_to;
+ panel_class->cache_glance = (cache_glance_fc)gtk_buffer_display_cache_glance;
- panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_view_get_caret_location;
- panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates;
- panel_class->get_position = (get_view_position_fc)gtk_buffer_view_get_position;
- panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_view_move_caret_to;
- panel_class->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance;
+ /* Signaux */
g_signal_new("reach-limit",
- GTK_TYPE_BUFFER_VIEW,
+ GTK_TYPE_BUFFER_DISPLAY,
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GtkBufferViewClass, reach_limit),
+ G_STRUCT_OFFSET(GtkBufferDisplayClass, reach_limit),
NULL, NULL,
g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE);
@@ -168,7 +160,7 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à initialiser. *
+* Paramètres : display = composant GTK à initialiser. *
* *
* Description : Procède à l'initialisation de l'afficheur de tampons. *
* *
@@ -178,25 +170,16 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
* *
******************************************************************************/
-static void gtk_buffer_view_init(GtkBufferView *view)
+static void gtk_buffer_display_init(GtkBufferDisplay *display)
{
- GObject *object; /* Autre version de l'instance */
-
- object = G_OBJECT(view);
-
- g_object_set(object, "has-tooltip", TRUE, NULL);
-
- view->caret.x = 10;
- view->caret.y = 10;
- view->caret.width = 100;
- view->caret.height = 100;
+ init_vmpa(&display->caret_addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
}
/******************************************************************************
* *
-* Paramètres : view = instance d'objet GLib à traiter. *
+* Paramètres : display = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -206,16 +189,19 @@ static void gtk_buffer_view_init(GtkBufferView *view)
* *
******************************************************************************/
-static void gtk_buffer_view_dispose(GtkBufferView *view)
+static void gtk_buffer_display_dispose(GtkBufferDisplay *display)
{
- G_OBJECT_CLASS(gtk_buffer_view_parent_class)->dispose(G_OBJECT(view));
+ if (display->view != NULL)
+ g_object_unref(G_OBJECT(display->view));
+
+ G_OBJECT_CLASS(gtk_buffer_display_parent_class)->dispose(G_OBJECT(display));
}
/******************************************************************************
* *
-* Paramètres : view = instance d'objet GLib à traiter. *
+* Paramètres : display = instance d'objet Gtk à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -225,9 +211,9 @@ static void gtk_buffer_view_dispose(GtkBufferView *view)
* *
******************************************************************************/
-static void gtk_buffer_view_finalize(GtkBufferView *view)
+static void gtk_buffer_display_finalize(GtkBufferDisplay *display)
{
- G_OBJECT_CLASS(gtk_buffer_view_parent_class)->finalize(G_OBJECT(view));
+ G_OBJECT_CLASS(gtk_buffer_display_parent_class)->finalize(G_OBJECT(display));
}
@@ -245,24 +231,24 @@ static void gtk_buffer_view_finalize(GtkBufferView *view)
* *
******************************************************************************/
-static gboolean gtk_buffer_view_focus(GtkWidget *widget, GdkEventFocus *event)
+static gboolean gtk_buffer_display_focus(GtkWidget *widget, GdkEventFocus *event)
{
- GtkBufferView *view; /* Autre version du composant */
+ GtkBufferDisplay *display; /* Autre version du composant */
gboolean has_focus; /* Etat courant */
- view = GTK_BUFFER_VIEW(widget);
+ display = GTK_BUFFER_DISPLAY(widget);
has_focus = event->in;
if (has_focus)
- restart_caret_blinking(view);
+ gtk_buffer_display_restart_caret_blinking(display);
- else if (view->caret_timer != 0)
+ else if (display->caret_timer != 0)
{
- g_source_remove(view->caret_timer);
- view->caret_timer = 0;
+ g_source_remove(display->caret_timer);
+ display->caret_timer = 0;
- view->show_caret = true;
- gtk_buffer_view_refresh_caret(view);
+ display->show_caret = true;
+ gtk_buffer_display_refresh_caret(display);
}
@@ -284,35 +270,32 @@ static gboolean gtk_buffer_view_focus(GtkWidget *widget, GdkEventFocus *event)
* *
******************************************************************************/
-static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event)
+static gboolean gtk_buffer_display_button_press(GtkWidget *widget, GdkEventButton *event)
{
- GtkBufferView *view; /* Autre version du composant */
+ GtkBufferDisplay *display; /* Autre version du composant */
+ GBufferCache *cache; /* Contenu représenté */
+ gint left_margin; /* Limite entre zones réactives*/
gint real_x; /* Abscisse absolue réelle */
gint real_y; /* Ordonnée absolue réelle */
- GBufferLine *line; /* Ligne à la position courante*/
- view = GTK_BUFFER_VIEW(widget);
+ display = GTK_BUFFER_DISPLAY(widget);
real_x = event->x;
real_y = event->y;
- gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y);
+ gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y);
- printf(" !mouse! :: (%g ; %g) -> (%d ; %d)\n",
- event->x, event->y,
- real_x, real_y);
+ cache = g_buffer_view_get_cache(display->view);
+ left_margin = g_buffer_cache_get_left_margin(cache);
- if (real_x < view->left_margin)
- {
- line = g_buffer_view_find_line_at(view->buffer_view, real_y, NULL);
- if (line == NULL) return FALSE;
+ g_object_unref(G_OBJECT(cache));
+ if (real_x < left_margin)
+ {
/* TODO */
- printf("Border Line :: %p\n", line);
-
}
else
- _gtk_buffer_view_move_caret_to(view, real_x, real_y);
+ _gtk_buffer_display_move_caret_to(display, real_x, real_y);
gtk_widget_grab_focus(widget);
@@ -334,22 +317,60 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
* *
******************************************************************************/
-static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
+static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
{
- GtkBufferView *view; /* Autre version du composant */
- GtkDisplayPanel *panel; /* Autre version du composant */
+ GtkBufferDisplay *display; /* Autre version du composant */
+ GtkDisplayPanel *parent; /* Autre version du composant */
GdkWindow *window; /* Fenêtre à redessiner */
cairo_region_t *region; /* Région visible à redessiner */
cairo_rectangle_int_t area; /* Surface correspondante */
GtkStyleContext *context; /* Contexte du thème actuel */
+ gint virt_x; /* Abscisse virtuelle */
+ gint virt_y; /* Ordonnée virtuelle */
+ GBufferCache *cache; /* Contenu représenté */
+ gint left_margin; /* Marge gauche + espace */
GdkRGBA color; /* Couleur de thème récupérée */
- gint fake_x; /* Abscisse virtuelle */
- gint fake_y; /* Ordonnée virtuelle */
bool sel_line; /* Souslignage de la sélection */
gint *selected; /* Ordonnée d'une sélection */
- view = GTK_BUFFER_VIEW(widget);
- panel = GTK_DISPLAY_PANEL(widget);
+
+ //gboolean status;
+
+
+ GtkStyleContext *other;
+ GtkWidgetPath *path;
+
+
+ other = gtk_style_context_new();
+
+
+ path = gtk_widget_path_new ();
+ gtk_widget_path_append_type (path, GTK_TYPE_SCALE);
+ //gtk_widget_path_iter_add_class (path, 0, "slider");
+ //gtk_widget_path_iter_add_class (path, 0, "scale");
+ gtk_style_context_set_path (other, path);
+ gtk_widget_path_free (path);
+
+
+
+
+ //context = gtk_widget_get_style_context(widget);
+
+
+ //gtk_render_background(context, cr, 0, 0, 1000, 1000);
+
+
+ //status = GTK_WIDGET_CLASS(gtk_buffer_display_parent_class)->draw(widget, cr);
+
+ //printf("status: %d\n", status);
+
+ //return TRUE;
+
+
+
+
+ display = GTK_BUFFER_DISPLAY(widget);
+ parent = GTK_DISPLAY_PANEL(widget);
window = gtk_widget_get_window(widget);
@@ -362,29 +383,56 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
context = gtk_widget_get_style_context(widget);
- if (panel->show_border)
+ if (parent->show_border)
{
- gtk_display_panel_define_border_path(panel, cr, 0, 0);
+ gtk_display_panel_define_border_path(parent, cr, 0, 0);
cairo_clip(cr);
}
+
+
+ gtk_render_background(context, cr, area.x, area.y, area.width, area.height);
+
+
+
+ /* Décallage pour le défilement horizontal */
+
+ virt_x = 0;
+ virt_y = 0;
+ gtk_display_panel_compute_fake_coord(parent, &virt_x, &virt_y);
+
+ cairo_save(cr);
+
+ cairo_translate(cr, virt_x, 0);
+
+ /* Récupération de la limite utile */
+
+ cache = g_buffer_view_get_cache(display->view);
+
+ left_margin = g_buffer_cache_get_left_margin(cache);
+
+ g_object_unref(G_OBJECT(cache));
+
+
/* Dessin de la marge gauche */
gtk_style_context_save(context);
- gtk_style_context_add_class(context, GTK_STYLE_CLASS_TOOLBAR);
+ gtk_style_context_add_class(other, GTK_STYLE_CLASS_TOOLBAR);
- gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color);
+ gtk_style_context_get_background_color(other, GTK_STATE_FLAG_ACTIVE, &color);
cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
+ //cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
- cairo_rectangle(cr, 0, area.y, view->left_margin, area.height);
+ cairo_rectangle(cr, 0, area.y, left_margin, area.height);
cairo_fill(cr);
gtk_style_context_restore(context);
/* Fond de la zone de texte */
+#if 1
gtk_style_context_save(context);
gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW);
@@ -393,10 +441,11 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.7);
- cairo_rectangle(cr, view->left_margin, area.y, area.width, area.height);
+ cairo_rectangle(cr, left_margin, area.y, area.width, area.height);
cairo_fill(cr);
gtk_style_context_restore(context);
+#endif
/* Ligne de séparation */
@@ -410,44 +459,50 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
cairo_set_line_width(cr, 1.0);
- cairo_move_to(cr, view->left_margin + 0.5, area.y - 0.5);
- cairo_line_to(cr, view->left_margin + 0.5, area.y + area.height + 0.5);
+ cairo_move_to(cr, left_margin + 0.5, area.y - 0.5);
+ cairo_line_to(cr, left_margin + 0.5, area.y + area.height + 0.5);
cairo_stroke(cr);
gtk_style_context_restore(context);
/* Eventuelle bordure globale */
- if (panel->show_border)
- gtk_display_panel_draw_border(panel, cr);
+ if (parent->show_border)
+ gtk_display_panel_draw_border(parent, cr);
/* Impression du désassemblage */
- if (view->buffer_view != NULL)
+ if (display->view != NULL)
{
- fake_x = 0;
- fake_y = 0;
- gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y);
-
g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line);
sel_line &= gtk_widget_has_focus(widget);
- if (!sel_line || view->caret_addr == NULL)
+ if (!sel_line || is_invalid_vmpa(&display->caret_addr))
selected = NULL;
else
- selected = &view->caret.y;
+ {
+ selected = (gint []) { display->caret.y };
+ gtk_display_panel_compute_relative_coords(parent, NULL, selected);
+ }
+
+ area.x -= virt_x;
+ virt_y += area.y;
- g_buffer_view_draw(view->buffer_view, cr, fake_x, fake_y, &area, panel->display, selected);
+ g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display, selected);
}
+ cairo_restore(cr);
+
/* Curseur clignotant ? */
+ /*
if (gtk_widget_is_focus(widget))
{
view->show_caret = !view->show_caret;
gtk_buffer_view_refresh_caret(view);
}
+ */
cairo_restore(cr);
@@ -469,20 +524,16 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
* *
******************************************************************************/
-static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
+static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *event)
{
gboolean result; /* Suites à renvoyer */
- GtkBufferView *view; /* Autre version du composant */
+ GdkScrollDirection dir; /* Direction du déplacement */
+ GtkBufferDisplay *display; /* Autre version du composant */
GtkDisplayPanel *panel; /* Autre version du composant */
bool ctrl; /* Statut de la touche Contrôle*/
- GdkScrollDirection dir; /* Direction du déplacement */
GdkRectangle area; /* Emplacement de curseur */
- const vmpa2t *addr; /* Adresse du nouveau curseur */
-
- result = FALSE;
-
- view = GTK_BUFFER_VIEW(widget);
- panel = GTK_DISPLAY_PANEL(widget);
+ vmpa2t addr; /* Adresse du nouveau curseur */
+ bool status; /* Validité d'un déplacement */
switch (event->keyval)
{
@@ -507,30 +558,28 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
break;
default:
+ result = FALSE;
break;
}
if (result)
{
- area = view->caret;
+ display = GTK_BUFFER_DISPLAY(widget);
+ panel = GTK_DISPLAY_PANEL(widget);
+
ctrl = (event->state & GDK_CONTROL_MASK);
+ area = display->caret;
- addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, dir, panel->display);
+ status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display, &area, &addr);
- if (addr != NULL)
+ if (status)
{
- gtk_buffer_view_relocate_caret(view, &area, addr);
- _gtk_display_panel_scroll_to_address(panel, addr, SPT_RAW, false);
+ gtk_buffer_display_relocate_caret(display, &area, &addr);
+ _gtk_display_panel_scroll_to_address(panel, &addr, SPT_RAW, false);
}
else
- g_signal_emit_by_name(view, "reach-limit", dir);
-
-
-
- //if (addr == NULL) return FALSE;
-
-
+ g_signal_emit_by_name(display, "reach-limit", dir);
}
@@ -541,172 +590,9 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
/******************************************************************************
* *
-* Paramètres : widget = composant GTK visé par l'opération. *
-* x = abscisse de la position du message. *
-* y = ordonnée de la position du message. *
-* keyboard = indique une demande suite à obtiention du focus. *
-* tooltip = astuce à compléter. [OUT] *
-* *
-* Description : Prépare l'affichage d'une astuce. *
-* *
-* Retour : TRUE pour un affichage validé, FALSE sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip)
-{
- gboolean result; /* Bilan à retourner */
- GBinFormat *format; /* Format du fichier binaire */
- GtkBufferView *view; /* Autre version du composant */
- gint real_x; /* Abscisse absolue réelle */
- gint real_y; /* Ordonnée absolue réelle */
- GBufferLine *line; /* Ligne en cours de survol */
- GObject *creator; /* Créateur à l'orgine du seg. */
- virt_t virt; /* Adresse virtuelle */
- vmpa2t addr; /* Adresse de destination */
- GBinSymbol *target_sym; /* Symbole présent à l'adresse */
- GBinSymbol *next_sym; /* Symbole suivant l'adresse */
- GCodeBuffer *buffer; /* Tampon où lire les lignes */
- const vmpa2t *stop_addr; /* Adresse associée, pour fin */
- const mrange_t *lrange; /* Couverture d'une ligne */
- size_t count; /* Nbre de lignes max à traiter*/
- char *markup; /* Description à construire */
- size_t i; /* Boucle de parcours */
- size_t index; /* Indice d'une ligne imprimée */
- char *text; /* Contenu à ajouter */
-
- if (keyboard) return FALSE;
-
- result = FALSE;
-
- format = NULL;
-
- view = GTK_BUFFER_VIEW(widget);
-
- /* Récupération de la destination pointée */
-
- real_x = x;
- real_y = y;
- gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y);
-
- line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
- &real_x, real_y, NULL,
- GTK_DISPLAY_PANEL(view)->display, &creator);
-
- if (line == NULL || creator == NULL) goto no_tooltip;
-
- /**
- * On fait le pari de reposer uniquement sur des adresses virtuelles !
- * A changer dans un futur ?
- */
-
- virt = VMPA_NO_VIRTUAL;
-
- if (G_IS_TARGET_OPERAND(creator))
- virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator));
-
- else if (G_IS_IMM_OPERAND(creator))
- {
- if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt))
- virt = VMPA_NO_VIRTUAL;
- }
-
- if (virt == VMPA_NO_VIRTUAL) goto no_tooltip;
-
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
-
- /* Construction du contenu textuel */
-
- format = G_BIN_FORMAT(g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary));
-
- if (!g_binary_format_find_symbol_at(format, &addr, &target_sym))
- goto no_tooltip;
-
- g_object_unref(G_OBJECT(target_sym));
-
- /* Construction du contenu textuel */
-
- /**
- * Dans le cas des vues de blocs basiques, il est impératif
- * de chercher les lignes dans le tampon global, et non uniquement dans
- * celui propre au bloc basique courant.
- */
-
- buffer = g_loaded_binary_get_disassembled_buffer(GTK_DISPLAY_PANEL(view)->binary);
-
- if (g_binary_format_find_next_symbol_at(format, &addr, &next_sym))
- stop_addr = get_mrange_addr(g_binary_symbol_get_range(next_sym));
- else
- stop_addr = NULL; /* Pour GCC */
-
- g_generic_config_get_value(get_main_configuration(), MPK_TOOLTIP_SIZE, &count);
-
- markup = NULL;
-
- for (i = 0, line = g_code_buffer_find_line_by_addr(buffer, &addr, BLF_NONE, &index);
- i < count && line != NULL;
- i++, line = g_code_buffer_find_line_by_index(buffer, index + i))
- {
- /* Si on commence à marcher sur les plates-bandes du symbole suivant... */
- if (next_sym != NULL)
- {
- lrange = g_buffer_line_get_range(line);
-
- if (mrange_contains_addr(lrange, stop_addr))
- break;
-
- }
-
- text = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
-
- if (markup != NULL)
- markup = stradd(markup, "\n");
-
- if (text != NULL)
- markup = stradd(markup, text);
-
- free(text);
-
- }
-
- if (next_sym != NULL)
- g_object_unref(G_OBJECT(next_sym));
-
- if (markup == NULL) goto no_tooltip;
-
- /* Impression finale */
-
- result = TRUE;
-
- gtk_tooltip_set_markup(tooltip, markup);
- free(markup);
-
- no_tooltip:
-
- if (creator != NULL)
- g_object_unref(creator);
-
- /*
- FIXME : ref() !
- if (line != NULL)
- g_object_unref(G_OBJECT(line));
- */
-
- if (format != NULL)
- g_object_unref(G_OBJECT(format));
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : view = composant GTK à consulter. *
-* width = largeur requise à renseigner ou NULL. [OUT] *
-* height = hauteur requise à renseigner ou NULL. [OUT] *
+* Paramètres : display = composant GTK à consulter. *
+* width = largeur requise à renseigner ou NULL. [OUT] *
+* height = hauteur requise à renseigner ou NULL. [OUT] *
* *
* Description : Indique les dimensions de travail du composant d'affichage. *
* *
@@ -716,20 +602,20 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y,
* *
******************************************************************************/
-static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *width, gint *height)
+static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *display, gint *width, gint *height)
{
if (width != NULL)
{
- if (view->buffer_view != NULL)
- *width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
+ if (display->view != NULL)
+ *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display);
else
*width = 0;
}
if (height != NULL)
{
- if (view->buffer_view != NULL)
- *height = g_buffer_view_get_height(view->buffer_view);
+ if (display->view != NULL)
+ *height = g_buffer_view_get_height(display->view);
else
*height = 0;
}
@@ -739,7 +625,7 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi
/******************************************************************************
* *
-* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* Paramètres : display = composant GTK d'affichage à consulter. *
* size = taille de l'espace dans la direction donnée. *
* orientation = indication sur le défilement à traiter. *
* step = valeur d'un petit pas de défilement. [OUT] *
@@ -753,24 +639,31 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi
* *
******************************************************************************/
-static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
+static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *display, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
{
- if (orientation == GTK_ORIENTATION_VERTICAL)
+ GBufferCache *cache; /* Gestionnaire de lignes */
+
+ if (orientation == GTK_ORIENTATION_VERTICAL && display->view != NULL)
{
- *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view);
+ cache = g_buffer_view_get_cache(display->view);
+
+ *step = g_buffer_cache_get_line_height(cache);
*page = *step * 10;
+
+ g_object_unref(G_OBJECT(cache));
+
}
else
- GTK_DISPLAY_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_DISPLAY_PANEL(view),
- size, orientation, step, page);
+ GTK_DISPLAY_PANEL_CLASS(gtk_buffer_display_parent_class)->compute_inc(GTK_DISPLAY_PANEL(display),
+ size, orientation, step, page);
}
/******************************************************************************
* *
-* Paramètres : view = panneau d'affichage concerné. *
+* Paramètres : display = panneau d'affichage concerné. *
* adj = défilement dont une valeur a changé. *
* orientation = indication sur le défilement à traiter. *
* *
@@ -782,21 +675,21 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G
* *
******************************************************************************/
-static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustment *adj, GtkOrientation orientation)
+static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *display, GtkAdjustment *adj, GtkOrientation orientation)
{
GtkWidget *widget; /* Autre vision du composant */
- widget = GTK_WIDGET(view);
+ widget = GTK_WIDGET(display);
if (gtk_widget_get_realized(widget))
- gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false);
+ gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, FALSE);
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
+* Paramètres : display = composant GTK à manipuler. *
* *
* Description : Indique la position courante du curseur. *
* *
@@ -806,20 +699,20 @@ static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustme
* *
******************************************************************************/
-static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *view)
+static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *display)
{
- return view->caret_addr;
+ return &display->caret_addr;
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à consulter. *
-* addr = adresse à présenter à l'écran. *
-* x = position horizontale au sein du composant. [OUT] *
-* y = position verticale au sein du composant. [OUT] *
-* tweak = adaptation finale à effectuer. *
+* Paramètres : display = composant GTK à consulter. *
+* addr = adresse à présenter à l'écran. *
+* x = position horizontale au sein du composant. [OUT] *
+* y = position verticale au sein du composant. [OUT] *
+* tweak = adaptation finale à effectuer. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -829,21 +722,24 @@ static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *vie
* *
******************************************************************************/
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
+static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
{
bool result; /* Bilan à remonter */
bool need_code; /* Recherche plus raffinée */
+ GBufferCache *cache; /* Gestionnaire de lignes */
int height; /* Hauteur allouée */
need_code = (tweak == SPT_BOTTOM);
- result = g_buffer_view_get_address_coordinates(view->buffer_view, addr, x, y, need_code);
+ cache = g_buffer_view_get_cache(display->view);
+
+ result = g_buffer_view_get_address_coordinates(display->view, addr, need_code, x, y);
if (result)
{
- *x += g_buffer_view_get_margin(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
+ *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display);
- height = gtk_widget_get_allocated_height(GTK_WIDGET(view));
+ height = gtk_widget_get_allocated_height(GTK_WIDGET(display));
switch (tweak)
{
@@ -859,58 +755,26 @@ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, c
case SPT_BOTTOM:
*y -= height;
- *y += g_buffer_view_get_line_height(view->buffer_view);
+ *y += g_buffer_cache_get_line_height(cache);
break;
}
}
- return result;
+ g_object_unref(G_OBJECT(cache));
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : view = composant GTK à consulter. *
-* line = ligne de tampon où se trouve le curseur. [OUT] *
-* creator = instance à l'origine de la représentation. [OUT] *
-* *
-* Description : Fournit des éléments liés à la position courante dans la vue.*
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine **line, GObject **creator)
-{
- GObject *obj; /* Elément à récupérer */
-
- /* Si aucune position n'est définie... */
- if (view->caret_addr == NULL)
- return false;
-
- *line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
- (gint []){ view->caret.x }, view->caret.y, NULL,
- GTK_DISPLAY_PANEL(view)->display, &obj);
-
- if (creator != NULL)
- *creator = obj;
-
- return (line != NULL);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* cairo = assistant pour la création de rendus. *
-* area = taille de la surface réduite à disposition. *
-* scale = échelle vis à vis de la taille réelle. *
+* Paramètres : display = composant GTK à manipuler. *
+* cairo = assistant pour la création de rendus. *
+* area = taille de la surface réduite à disposition. *
+* scale = échelle vis à vis de la taille réelle. *
* *
* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
* *
@@ -920,7 +784,7 @@ static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine
* *
******************************************************************************/
-static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, const GtkAllocation *area, double scale)
+static void gtk_buffer_display_cache_glance(GtkBufferDisplay *display, cairo_t *cairo, const GtkAllocation *area, double scale)
{
cairo_set_line_width(cairo, 1);
cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4);
@@ -934,10 +798,10 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* buffer = tampon de lignes à encadrer. *
+* Paramètres : display = instance d'objet Gtk à actualiser. *
+* view = nouvelle vue à associer au composant. *
* *
-* Description : Prend acte de l'association d'un tampon de lignes. *
+* Description : Lie une vue au composant d'affichage de tampon. *
* *
* Retour : - *
* *
@@ -945,46 +809,19 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co
* *
******************************************************************************/
-void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer)
+void gtk_buffer_display_set_view(GtkBufferDisplay *display, GBufferView *view)
{
- gint width; /* Largeur de l'objet actuelle */
- gint height; /* Hauteur de l'objet actuelle */
-
- if (view->buffer_view != NULL)
- {
- //g_object_unref(G_OBJECT(view->buffer));
- g_object_unref(G_OBJECT(view->buffer_view));
- }
-
- //view->buffer = g_buffer_view_get_buffer(buffer);
- //g_object_ref(G_OBJECT(view->buffer));
-
- view->buffer_view = buffer;
-
- /* Taille des marges */
-
- view->line_height = g_buffer_view_get_line_height(view->buffer_view);
- view->left_margin = 2 * view->line_height;
- view->left_text = -2.5 * view->line_height;
-
- /* Validation finale */
+ if (display->view != NULL)
+ g_object_unref(G_OBJECT(display->view));
- width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
- height = g_buffer_view_get_height(view->buffer_view);
-
- width += -view->left_text + 1;
- height += 1;
-
- //gtk_widget_set_size_request(GTK_WIDGET(view), width, height);
-
- gtk_widget_queue_draw(GTK_WIDGET(view));
+ display->view = view;
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à consulter. *
+* Paramètres : display = composant GTK à consulter. *
* *
* Description : Fournit la vue associée au tampon de lignes courant. *
* *
@@ -994,11 +831,15 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer)
* *
******************************************************************************/
-GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
+GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *display)
{
- /* TODO : ref... */
+ GBufferView *result; /* Instance à retourner */
- return view->buffer_view;
+ result = display->view;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
}
@@ -1011,9 +852,9 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* x = abscisse proposée pour le nouvel emplacement. *
-* y = ordonnée proposée pour le nouvel emplacement. *
+* Paramètres : display = composant GTK à manipuler. *
+* x = abscisse proposée pour le nouvel emplacement. *
+* y = ordonnée proposée pour le nouvel emplacement. *
* *
* Description : Déplace le curseur à un emplacement défini. *
* *
@@ -1023,34 +864,28 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
* *
******************************************************************************/
-static bool _gtk_buffer_view_move_caret_to(GtkBufferView *view, gint x, gint y)
+static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x, gint y)
{
- size_t index; /* Indice de ligne de tampon */
- GBufferLine *line; /* Ligne à la position courante*/
+ bool result; /* Bilan à retourner */
GtkDisplayPanel *panel; /* Autre version du composant */
- const vmpa2t *addr; /* Position mémoire associée */
+ vmpa2t addr; /* Position mémoire associée */
GdkRectangle new; /* Nouvel emplacement calculé */
- if (x < view->left_margin) return false;
+ panel = GTK_DISPLAY_PANEL(display);
- line = g_buffer_view_find_line_at(view->buffer_view, y, &index);
- if (line == NULL) return false;
+ result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display, &new, &addr);
- panel = GTK_DISPLAY_PANEL(view);
-
- addr = g_buffer_view_compute_caret_full(view->buffer_view, line, index, x, panel->display, &new);
-
- if (addr != NULL)
- gtk_buffer_view_relocate_caret(view, &new, addr);
+ if (result)
+ gtk_buffer_display_relocate_caret(display, &new, &addr);
- return (addr != NULL);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
+* Paramètres : display = composant GTK à manipuler. *
* beginning = précise le coin où se retrouvera le curseur. *
* same_x = tente de conserver une même abscisse ou NULL ? *
* *
@@ -1062,25 +897,39 @@ static bool _gtk_buffer_view_move_caret_to(GtkBufferView *view, gint x, gint y)
* *
******************************************************************************/
-bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *same_x)
+bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, bool beginning, gint *same_x)
{
bool result; /* Bilan à remonter */
+ GBufferCache *cache; /* Contenu représenté */
+ gint left_margin; /* Limite entre zones réactives*/
gint x; /* Abscisse d'emplacement */
gint y; /* Ordonnée d'emplacement */
if (beginning)
{
- x = same_x != NULL ? *same_x : view->left_margin * 2;
+ cache = g_buffer_view_get_cache(display->view);
+
+ left_margin = g_buffer_cache_get_left_margin(cache);
+
+ g_object_unref(G_OBJECT(cache));
+
+ x = same_x != NULL ? *same_x : left_margin * 2;
y = 0;
+
}
else
{
- if (same_x != NULL) x = *same_x;
- gtk_buffer_view_compute_requested_size(view, same_x != NULL ? NULL : &x, &y);
+ if (same_x != NULL)
+ x = *same_x;
+ else
+ gtk_widget_get_preferred_width(GTK_WIDGET(display), NULL, &x);
+
+ gtk_widget_get_preferred_height(GTK_WIDGET(display), NULL, &y);
y--;
+
}
- result = _gtk_buffer_view_move_caret_to(view, x, y);
+ result = _gtk_buffer_display_move_caret_to(display, x, y);
return result;
@@ -1089,9 +938,9 @@ bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *sa
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* area = emplacement pour le dessin d'un curseur. *
-* addr = position dans la mémoire représentée du curseur. *
+* Paramètres : display = composant GTK à manipuler. *
+* area = emplacement pour le dessin d'un curseur. *
+* addr = position dans la mémoire représentée du curseur. *
* *
* Description : Déplace le curseur en effaçant son éventuelle position. *
* *
@@ -1101,48 +950,48 @@ bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *sa
* *
******************************************************************************/
-static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr)
+static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *display, const GdkRectangle *area, const vmpa2t *addr)
{
bool clear_old; /* Effacement chirurgical */
GdkRectangle old_area; /* Mémorisation de l'ancien */
bool need_redraw; /* Besoin de rafraîchissement ?*/
- if (view->caret_addr != NULL)
+ if (!is_invalid_vmpa(&display->caret_addr))
{
clear_old = true;
- old_area = view->caret;
+ old_area = display->caret;
}
else
clear_old = false;
- view->caret = *area;
- view->caret_addr = addr;
+ display->caret = *area;
+ copy_vmpa(&display->caret_addr, addr);
- if (GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret != NULL)
- need_redraw = GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret(view, area, addr);
+ if (GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret != NULL)
+ need_redraw = GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret(display, area, addr);
else
need_redraw = false;
if (need_redraw)
- gtk_widget_queue_draw(GTK_WIDGET(view));
+ gtk_widget_queue_draw(GTK_WIDGET(display));
else if (clear_old)
{
- gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &old_area.x, &old_area.y);
+ gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &old_area.x, &old_area.y);
- gtk_widget_queue_draw_area(GTK_WIDGET(view), old_area.x, old_area.y,
+ gtk_widget_queue_draw_area(GTK_WIDGET(display), old_area.x, old_area.y,
old_area.width, old_area.height);
}
- restart_caret_blinking(view);
+ gtk_buffer_display_restart_caret_blinking(display);
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
+* Paramètres : display = composant GTK à manipuler. *
* *
* Description : Redémarre l'affichage du curseur à l'emplacement courant. *
* *
@@ -1152,31 +1001,43 @@ static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectang
* *
******************************************************************************/
-static void restart_caret_blinking(GtkBufferView *view)
+static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *display)
{
- if (view->caret_timer != 0)
+
+ GtkSettings *settings; /* Propriétés du système */
+ guint interval; /* Fréquence d'actualisation */
+
+ if (display->caret_timer != 0)
{
- g_source_remove(view->caret_timer);
- view->caret_timer = 0;
+ g_source_remove(display->caret_timer);
+ display->caret_timer = 0;
}
- if (view->caret_addr != NULL)
+ if (!is_invalid_vmpa(&display->caret_addr))
{
- view->show_caret = false;
- gtk_buffer_view_refresh_caret(view);
+ display->show_caret = false;
+ gtk_buffer_display_refresh_caret(display);
+
+ settings = gtk_settings_get_default();
- view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view);
+ g_object_get(settings, "gtk-cursor-blink-time", &interval, NULL);
+
+ g_object_ref(G_OBJECT(display));
+
+ display->caret_timer = g_timeout_add_full(G_PRIORITY_DEFAULT, interval,
+ (GSourceFunc)gtk_buffer_display_refresh_caret,
+ display, g_object_unref);
}
- g_signal_emit_by_name(view, "caret-moved", view->caret_addr);
+ g_signal_emit_by_name(display, "caret-moved", &display->caret_addr);
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
+* Paramètres : display = composant GTK à manipuler. *
* *
* Description : Bascule et relance l'affichage du curseur. *
* *
@@ -1186,7 +1047,7 @@ static void restart_caret_blinking(GtkBufferView *view)
* *
******************************************************************************/
-static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view)
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display)
{
GtkWidget *widget; /* Autre version du composant */
GdkWindow *window; /* Fenêtre de support associée */
@@ -1194,7 +1055,7 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view)
cairo_t *cr; /* Contexte graphique */
GdkRGBA *color; /* Couleur du curseur */
- widget = GTK_WIDGET(view);
+ widget = GTK_WIDGET(display);
window = gtk_widget_get_window(widget);
/**
@@ -1204,24 +1065,24 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view)
*/
if (window == NULL)
{
- view->show_caret = !view->show_caret;
+ display->show_caret = !display->show_caret;
return TRUE;
}
- area = view->caret;
- gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &area.x, &area.y);
+ area = display->caret;
+ gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &area.x, &area.y);
/* Réinitialisation de la surface */
- if (view->show_caret)
+ if (display->show_caret)
{
- view->show_caret = false;
+ display->show_caret = false;
gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height);
}
/* Dessin */
else
{
- view->show_caret = true;
+ display->show_caret = true;
cr = gdk_cairo_create(gtk_widget_get_window(widget));
diff --git a/src/gtkext/gtkbufferdisplay.h b/src/gtkext/gtkbufferdisplay.h
new file mode 100644
index 0000000..ea06b94
--- /dev/null
+++ b/src/gtkext/gtkbufferdisplay.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkbufferdisplay.h - prototypes pour l'affichage de tampons de lignes
+ *
+ * Copyright (C) 2016 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GTKEXT_GTKBUFFER_DISPLAY_H
+#define _GTKEXT_GTKBUFFER_DISPLAY_H
+
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+#include "../glibext/gbufferview.h"
+
+
+
+#define GTK_TYPE_BUFFER_DISPLAY (gtk_buffer_display_get_type())
+#define GTK_BUFFER_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplay))
+#define GTK_BUFFER_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplayClass))
+#define GTK_IS_BUFFER_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_DISPLAY))
+#define GTK_IS_BUFFER_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_DISPLAY))
+#define GTK_BUFFER_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferDisplayClass))
+
+
+/* Composant d'affichage de tampon de lignes (instance) */
+typedef struct _GtkBufferDisplay GtkBufferDisplay;
+
+/* Composant d'affichage de tampon de lignes (classe) */
+typedef struct _GtkBufferDisplayClass GtkBufferDisplayClass;
+
+
+/* Détermine le type du composant d'affichage de tampon de lignes. */
+GType gtk_buffer_display_get_type(void);
+
+/* Lie une vue au composant d'affichage de tampon. */
+void gtk_buffer_display_set_view(GtkBufferDisplay *, GBufferView *);
+
+/* Fournit la vue associée au tampon de lignes courant. */
+GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *);
+
+
+
+/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
+
+
+/* Déplace le curseur à un emplacement en extrémité. */
+bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *, bool, gint *);
+
+
+
+#endif /* _GTKEXT_GTKBUFFER_DISPLAY_H */
diff --git a/src/gtkext/gtkbufferview.h b/src/gtkext/gtkbufferview.h
deleted file mode 100644
index 1b13ab0..0000000
--- a/src/gtkext/gtkbufferview.h
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes
- *
- * Copyright (C) 2010-2014 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _GTK_BUFFERVIEW_H
-#define _GTK_BUFFERVIEW_H
-
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-
-#include "../glibext/gbufferview.h"
-
-
-
-#define GTK_TYPE_BUFFER_VIEW (gtk_buffer_view_get_type())
-#define GTK_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferView))
-#define GTK_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass))
-#define GTK_IS_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_VIEW))
-#define GTK_IS_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_VIEW))
-#define GTK_BUFFER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass))
-
-
-/* Composant d'affichage de tampon de lignes (instance) */
-typedef struct _GtkBufferView GtkBufferView;
-
-/* Composant d'affichage de tampon de lignes (classe) */
-typedef struct _GtkBufferViewClass GtkBufferViewClass;
-
-
-/* Détermine le type du composant d'affichage de tampon de lignes. */
-GType gtk_buffer_view_get_type(void);
-
-/* Prend acte de l'association d'un tampon de lignes. */
-void gtk_buffer_view_attach_buffer(GtkBufferView *, GBufferView *);
-
-/* Fournit la vue associée au tampon de lignes courant. */
-GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *);
-
-
-
-/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
-
-
-/* Déplace le curseur à un emplacement en extrémité. */
-bool gtk_buffer_view_move_caret_to(GtkBufferView *, bool, gint *);
-
-
-
-#endif /* _GTK_BUFFERVIEW_H */
diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index bc0e229..f6221d5 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -48,9 +48,6 @@ typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, Gtk
/* Réagit à la sélection externe d'une adresse. */
typedef void (* define_address_fc) (GtkDisplayPanel *, const vmpa2t *);
-/* Actualise les besoins internes avant un redimensionnement. */
-typedef void (* prepare_resize_fc) (GtkDisplayPanel *);
-
/* Indique la position courante du curseur. */
typedef const vmpa2t * (* get_caret_location_fc) (const GtkDisplayPanel *);
@@ -84,9 +81,6 @@ struct _GtkDisplayPanel
GLoadedBinary *binary; /* Binaire à visualiser */
- //define_address_fc define; /* Centrage sur une partie */
- prepare_resize_fc resize; /* Prépare une nouvelle taille */
-
};
/* Composant d'affichage générique (classe) */
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 6793d4e..66ec909 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -641,7 +641,8 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi
orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
- GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation);
+ if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust != NULL)
+ GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation);
}
@@ -832,9 +833,6 @@ static void on_view_panel_binary_display_change(GLoadedBinary *binary, BinaryVie
{
if (panel->content == view)
{
- if (panel->resize != NULL)
- panel->resize(panel);
-
gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel)));
gtk_widget_queue_resize(GTK_WIDGET(panel));
gtk_widget_queue_draw(GTK_WIDGET(panel));
@@ -924,23 +922,15 @@ void _gtk_display_panel_scroll_to_address(GtkDisplayPanel *panel, const vmpa2t *
double value; /* Valeur courante */
/**
- * Si une vue partielle se déplacer via cette fonction, il faut potentiellement
+ * Si une vue partielle se déplace via cette fonction, il faut potentiellement
* rediriger l'appel vers la vue en graphiques parente.
*/
parent = gtk_widget_get_parent(GTK_WIDGET(panel));
parent = gtk_widget_get_parent(GTK_WIDGET(parent));
- printf(" Widgets : %s -> %s\n",
- G_OBJECT_TYPE_NAME(parent), G_OBJECT_TYPE_NAME(panel));
-
if (GTK_IS_DISPLAY_PANEL(parent))
- {
- printf("reparent !\n");
panel = GTK_DISPLAY_PANEL(parent);
- }
- else
- printf("no need reparent !\n");
if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->define != NULL)
GTK_DISPLAY_PANEL_GET_CLASS(panel)->define(panel, addr);
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphdisplay.c
index 57bbec0..1d4f831 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphdisplay.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkgraphview.c - affichage de morceaux de code sous forme graphique
+ * gtkgraphdisplay.c - affichage de morceaux de code sous forme graphique
*
- * Copyright (C) 2009-2014 Cyrille Bagard
+ * Copyright (C) 2009-2016 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -21,14 +21,14 @@
*/
-#include "gtkgraphview.h"
+#include "gtkgraphdisplay.h"
#include <assert.h>
-#include "gtkblockview.h"
-#include "gtkbufferview.h"
+#include "gtkblockdisplay.h"
+#include "gtkbufferdisplay.h"
#include "gtkdisplaypanel-int.h"
#include "graph/cluster.h"
#include "../analysis/blocks/flow.h"
@@ -38,7 +38,7 @@
/* Composant d'affichage sous forme graphique (instance) */
-struct _GtkGraphView
+struct _GtkGraphDisplay
{
GtkDisplayPanel parent; /* A laisser en premier */
GtkWidget *support; /* Support des vues en bloc */
@@ -47,11 +47,7 @@ struct _GtkGraphView
GBinRoutine *routine; /* Routine en cours d'affichage*/
segcnt_list *highlighted; /* Segments mis en évidence */
- GtkBufferView **children; /* Liste des sous-blocs */
- GtkAllocation *allocs; /* Emplacements prévisibles */
- size_t children_count; /* Taille de cette liste */
- //GGraphLayout *layout; /* Disposition en graphique */
GGraphCluster *cluster; /* Disposition en graphique */
GGraphEdge **edges; /* Liens entre les noeuds */
@@ -66,7 +62,7 @@ struct _GtkGraphView
};
/* Composant d'affichage sous forme graphique (classe) */
-struct _GtkGraphViewClass
+struct _GtkGraphDisplayClass
{
GtkDisplayPanelClass parent; /* A laisser en premier */
@@ -76,77 +72,74 @@ struct _GtkGraphViewClass
/* Profondeur de l'ombre */
#define SHADOW_SIZE 4
+/* Marges en bordure de graphique */
+#define GRAPH_MARGIN 23
+
/* Initialise la classe générique des graphiques de code. */
-static void gtk_graph_view_class_init(GtkGraphViewClass *);
+static void gtk_graph_display_class_init(GtkGraphDisplayClass *);
/* Initialise une instance d'afficheur de code en graphique. */
-static void gtk_graph_view_init(GtkGraphView *);
+static void gtk_graph_display_init(GtkGraphDisplay *);
/* Supprime toutes les références externes. */
-static void gtk_graph_view_dispose(GtkGraphView *);
+static void gtk_graph_display_dispose(GtkGraphDisplay *);
/* Procède à la libération totale de la mémoire. */
-static void gtk_graph_view_finalize(GtkGraphView *);
+static void gtk_graph_display_finalize(GtkGraphDisplay *);
/* S'adapte à la surface concédée par le composant parent. */
-static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
+static void gtk_graph_display_size_allocate(GtkWidget *, GtkAllocation *);
/* Centre si possible le contenu du panneau d'affichage. */
-static void gtk_graph_view_update_support_margins(GtkGraphView *, const GtkAllocation *);
+static void gtk_graph_display_update_support_margins(GtkGraphDisplay *, const GtkAllocation *);
/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *);
+static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *, gint *, gint *);
/* Réagit à un défilement chez une barre associée au composant. */
-static void gtk_graph_view_adjust_scroll_value(GtkGraphView *, GtkAdjustment *, GtkOrientation);
+static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *, GtkAdjustment *, GtkOrientation);
/* Met à jour l'affichage de la vue sous forme graphique. */
-static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *);
+static gboolean gtk_graph_display_draw(GtkWidget *, cairo_t *, GtkGraphDisplay *);
/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_graph_view_button_press(GtkWidget *, GdkEventButton *, GtkGraphView *);
+static gboolean gtk_graph_display_button_press(GtkWidget *, GdkEventButton *, GtkGraphDisplay *);
/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_graph_view_button_release(GtkWidget *, GdkEventButton *, GtkGraphView *);
+static gboolean gtk_graph_display_button_release(GtkWidget *, GdkEventButton *, GtkGraphDisplay *);
/* Assure la suivi des déplacements de souris sur le composant. */
-static gboolean gtk_graph_view_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphView *);
-
-/* Actualise les besoins internes avant un redimensionnement. */
-static void gtk_graph_view_prepare_resize(GtkGraphView *);
+static gboolean gtk_graph_display_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphDisplay *);
/* Réagit à la sélection externe d'une adresse. */
-static void gtk_graph_view_define_main_address(GtkGraphView *, const vmpa2t *);
+static void gtk_graph_display_define_main_address(GtkGraphDisplay *, const vmpa2t *);
/* Indique la position courante du curseur. */
-static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *);
+static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *);
/* Indique la position d'affichage d'une adresse donnée. */
-static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak);
+static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak);
/* Déplace le curseur à un emplacement défini. */
-static bool gtk_graph_view_move_caret_to(GtkGraphView *, gint, gint);
+static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *, gint, gint);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
-static void gtk_graph_view_cache_glance(GtkGraphView *, cairo_t *, const GtkAllocation *, double);
+static void gtk_graph_display_cache_glance(GtkGraphDisplay *, cairo_t *, const GtkAllocation *, double);
/* Supprime tout contenu de l'afficheur de code en graphique. */
-static void gtk_graph_view_reset(GtkGraphView *);
-
-/* Définit la liste complète des éléments du futur graphique. */
-static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *, GLoadedBinary *, const GBinRoutine *);
+static void gtk_graph_display_reset(GtkGraphDisplay *);
/* Notifie un changement de surbrillance au sein d'un noeud. */
-static void gtk_graph_view_changed_highlights(GtkBlockView *, GtkGraphView *);
+static void gtk_graph_display_changed_highlights(GtkBlockDisplay *, GtkGraphDisplay *);
/* Notifie une incapacité de déplacement au sein d'un noeud. */
-static void gtk_graph_view_reach_caret_limit(GtkBufferView *, GdkScrollDirection, GtkGraphView *);
+static void gtk_graph_display_reach_caret_limit(GtkBufferDisplay *, GdkScrollDirection, GtkGraphDisplay *);
/* Détermine le type du composant d'affichage en graphique. */
-G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_DISPLAY_PANEL)
+G_DEFINE_TYPE(GtkGraphDisplay, gtk_graph_display, GTK_TYPE_DISPLAY_PANEL)
/******************************************************************************
@@ -161,7 +154,7 @@ G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_DISPLAY_PANEL)
* *
******************************************************************************/
-static void gtk_graph_view_class_init(GtkGraphViewClass *class)
+static void gtk_graph_display_class_init(GtkGraphDisplayClass *class)
{
GObjectClass *object; /* Autre version de la classe */
GtkWidgetClass *widget_class; /* Classe de haut niveau */
@@ -169,30 +162,30 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class)
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_view_dispose;
- object->finalize = (GObjectFinalizeFunc)gtk_graph_view_finalize;
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_display_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_graph_display_finalize;
widget_class = GTK_WIDGET_CLASS(class);
- widget_class->size_allocate = gtk_graph_view_size_allocate;
+ widget_class->size_allocate = gtk_graph_display_size_allocate;
panel_class = GTK_DISPLAY_PANEL_CLASS(class);
- panel_class->compute_size = (compute_requested_size_fc)gtk_graph_view_compute_requested_size;
- panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_view_adjust_scroll_value;
- panel_class->define = (define_address_fc)gtk_graph_view_define_main_address;
+ panel_class->compute_size = (compute_requested_size_fc)gtk_graph_display_compute_requested_size;
+ panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_display_adjust_scroll_value;
+ panel_class->define = (define_address_fc)gtk_graph_display_define_main_address;
- panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_view_get_caret_location;
- panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
- panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_view_move_caret_to;
- panel_class->cache_glance = (cache_glance_fc)gtk_graph_view_cache_glance;
+ panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_display_get_caret_location;
+ panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_display_get_address_coordinates;
+ panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_display_move_caret_to;
+ panel_class->cache_glance = (cache_glance_fc)gtk_graph_display_cache_glance;
}
/******************************************************************************
* *
-* Paramètres : view = instance GTK à initialiser. *
+* Paramètres : display = instance GTK à initialiser. *
* *
* Description : Initialise une instance d'afficheur de code en graphique. *
* *
@@ -202,64 +195,42 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class)
* *
******************************************************************************/
-static void gtk_graph_view_init(GtkGraphView *view)
+static void gtk_graph_display_init(GtkGraphDisplay *display)
{
- GtkDisplayPanel *panel; /* Instance parente #1 */
- //GtkBinView *binview; /* Instance parente #2 */
-
- panel = GTK_DISPLAY_PANEL(view);
-
- panel->resize = (prepare_resize_fc)gtk_graph_view_prepare_resize;
- ////////viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
-
- //binview = GTK_BIN_VIEW(view);
-
- //binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines;
- //binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address;
- //binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
-
- view->support = gtk_fixed_new();
- gtk_widget_set_has_window(view->support, TRUE);
- gtk_widget_set_can_focus(view->support, TRUE);
+ display->support = gtk_fixed_new();
+ gtk_widget_set_has_window(display->support, TRUE);
+ gtk_widget_set_can_focus(display->support, TRUE);
- g_signal_connect(G_OBJECT(view->support), "draw",
- G_CALLBACK(gtk_graph_view_draw), view);
+ g_signal_connect(G_OBJECT(display->support), "draw",
+ G_CALLBACK(gtk_graph_display_draw), display);
- g_signal_connect(G_OBJECT(view->support), "button-press-event",
- G_CALLBACK(gtk_graph_view_button_press), view);
- g_signal_connect(G_OBJECT(view->support), "button-release-event",
- G_CALLBACK(gtk_graph_view_button_release), view);
- g_signal_connect(G_OBJECT(view->support), "motion-notify-event",
- G_CALLBACK(gtk_graph_view_motion_notify), view);
+ g_signal_connect(G_OBJECT(display->support), "button-press-event",
+ G_CALLBACK(gtk_graph_display_button_press), display);
+ g_signal_connect(G_OBJECT(display->support), "button-release-event",
+ G_CALLBACK(gtk_graph_display_button_release), display);
+ g_signal_connect(G_OBJECT(display->support), "motion-notify-event",
+ G_CALLBACK(gtk_graph_display_motion_notify), display);
- gtk_widget_add_events(view->support,
+ gtk_widget_add_events(display->support,
GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
- gtk_widget_show(view->support);
+ gtk_widget_show(display->support);
- gtk_fixed_put(GTK_FIXED(view), view->support, 0, 0);
+ gtk_fixed_put(GTK_FIXED(display), display->support, 0, 0);
- //view->mutex = g_mutex_new();
- //view->cond = g_cond_new();
+ display->extender = gtk_fixed_new();
+ gtk_widget_set_margin_end(display->extender, 1);
+ gtk_widget_set_margin_top(display->extender, 1);
- view->extender = gtk_fixed_new();
-
- gtk_widget_set_margin_end(view->extender, 1);
- gtk_widget_set_margin_top(view->extender, 1);
-
- gtk_widget_show(view->extender);
-
-
- view->cluster = NULL;
-
+ gtk_widget_show(display->extender);
}
/******************************************************************************
* *
-* Paramètres : view = instance d'objet GLib à traiter. *
+* Paramètres : display = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -269,24 +240,20 @@ static void gtk_graph_view_init(GtkGraphView *view)
* *
******************************************************************************/
-static void gtk_graph_view_dispose(GtkGraphView *view)
+static void gtk_graph_display_dispose(GtkGraphDisplay *display)
{
- g_object_unref(G_OBJECT(view->extender));
+ g_object_unref(G_OBJECT(display->extender));
- if (view->cluster != NULL)
- {
- g_object_unref(G_OBJECT(view->cluster));
- view->cluster = NULL;
- }
+ gtk_graph_display_reset(display);
- G_OBJECT_CLASS(gtk_graph_view_parent_class)->dispose(G_OBJECT(view));
+ G_OBJECT_CLASS(gtk_graph_display_parent_class)->dispose(G_OBJECT(display));
}
/******************************************************************************
* *
-* Paramètres : view = instance d'objet GLib à traiter. *
+* Paramètres : display = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -296,9 +263,9 @@ static void gtk_graph_view_dispose(GtkGraphView *view)
* *
******************************************************************************/
-static void gtk_graph_view_finalize(GtkGraphView *view)
+static void gtk_graph_display_finalize(GtkGraphDisplay *display)
{
- G_OBJECT_CLASS(gtk_graph_view_parent_class)->finalize(G_OBJECT(view));
+ G_OBJECT_CLASS(gtk_graph_display_parent_class)->finalize(G_OBJECT(display));
}
@@ -316,21 +283,22 @@ static void gtk_graph_view_finalize(GtkGraphView *view)
* *
******************************************************************************/
-static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+static void gtk_graph_display_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
{
- GtkGraphView *view; /* Autre version du composant */
+ GtkGraphDisplay *display; /* Autre version du composant */
- GTK_WIDGET_CLASS(gtk_graph_view_parent_class)->size_allocate(widget, allocation);
+ GTK_WIDGET_CLASS(gtk_graph_display_parent_class)->size_allocate(widget, allocation);
- view = GTK_GRAPH_VIEW(widget);
+ display = GTK_GRAPH_DISPLAY(widget);
- gtk_graph_view_update_support_margins(view, allocation);
+ gtk_graph_display_update_support_margins(display, allocation);
}
+
/******************************************************************************
* *
-* Paramètres : view = panneau dont le contenu est à déplacer. *
+* Paramètres : display = panneau dont le contenu est à déplacer. *
* allocation = étendue accordée à la vue. *
* *
* Description : Centre si possible le contenu du panneau d'affichage. *
@@ -341,14 +309,14 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
* *
******************************************************************************/
-static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkAllocation *allocation)
+static void gtk_graph_display_update_support_margins(GtkGraphDisplay *display, const GtkAllocation *allocation)
{
gint width; /* Largeur totale du support */
gint height; /* Hauteur totale du support */
gint start; /* Bordure horizontale */
gint top; /* Bordure verticale */
- gtk_graph_view_compute_requested_size(view, &width, &height);
+ gtk_graph_display_compute_requested_size(display, &width, &height);
if (width > allocation->width)
start = 0;
@@ -360,17 +328,17 @@ static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkA
else
top = (allocation->height - height) / 2;
- gtk_widget_set_margin_start(view->support, start);
- gtk_widget_set_margin_top(view->support, top);
+ gtk_widget_set_margin_start(display->support, start);
+ gtk_widget_set_margin_top(display->support, top);
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à consulter. *
-* width = largeur requise à renseigner ou NULL. [OUT] *
-* height = hauteur requise à renseigner ou NULL. [OUT] *
+* Paramètres : display = composant GTK à consulter. *
+* width = largeur requise à renseigner ou NULL. [OUT] *
+* height = hauteur requise à renseigner ou NULL. [OUT] *
* *
* Description : Indique les dimensions de travail du composant d'affichage. *
* *
@@ -380,18 +348,17 @@ static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkA
* *
******************************************************************************/
-static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *width, gint *height)
+static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *display, gint *width, gint *height)
{
GtkAllocation needed; /* Taille requise */
- gint rwidth; /* Largeur demandée */
- gint rheight; /* Hauteur demandée */
- if (view->cluster != NULL)
+ if (display->cluster != NULL)
{
- g_graph_cluster_compute_needed_alloc(view->cluster, &needed);
+ g_graph_cluster_compute_needed_alloc(display->cluster, &needed);
assert(needed.x == 0 && needed.y == 0);
- /* TODO : marges ou centrage */
+ needed.width += 2 * GRAPH_MARGIN;
+ needed.height += 2 * GRAPH_MARGIN;
}
else
@@ -400,15 +367,15 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt
needed.height = 0;
}
- if (width != NULL) *width = needed.width + SHADOW_SIZE;
- if (height != NULL) *height = needed.height + SHADOW_SIZE;
+ if (width != NULL) *width = needed.width;
+ if (height != NULL) *height = needed.height;
}
/******************************************************************************
* *
-* Paramètres : view = panneau d'affichage concerné. *
+* Paramètres : display = panneau d'affichage concerné. *
* adj = défilement dont une valeur a changé. *
* orientation = indication sur le défilement à traiter. *
* *
@@ -420,25 +387,25 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt
* *
******************************************************************************/
-static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment *adj, GtkOrientation orientation)
+static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *display, GtkAdjustment *adj, GtkOrientation orientation)
{
gint fake_x; /* Abscisse virtuelle */
gint fake_y; /* Ordonnée virtuelle */
fake_x = 0;
fake_y = 0;
- gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y);
+ gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(display), &fake_x, &fake_y);
- gtk_fixed_move(GTK_FIXED(view), view->support, fake_x, -fake_y);
+ gtk_fixed_move(GTK_FIXED(display), display->support, fake_x, -fake_y);
}
/******************************************************************************
* *
-* Paramètres : widget = composant GTK à redessiner. *
-* cr = contexte graphique associé à l'événement. *
-* view = support maître à consulter. *
+* Paramètres : widget = composant GTK à redessiner. *
+* cr = contexte graphique associé à l'événement. *
+* display = support maître à consulter. *
* *
* Description : Met à jour l'affichage de la vue sous forme graphique. *
* *
@@ -448,7 +415,7 @@ static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment
* *
******************************************************************************/
-static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView *view)
+static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphDisplay *display)
{
size_t i; /* Boucle de parcours */
@@ -458,6 +425,10 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView
gint j; /* Boucle de parcours */
cairo_pattern_t *pattern; /* Zones d'application */
+ /* On évite l'extenseur de support... */
+ if (!GTK_IS_DISPLAY_PANEL(child))
+ return;
+
gtk_widget_get_allocation(child, &alloc);
for (j = 1; j < SHADOW_SIZE; j++)
@@ -486,17 +457,10 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView
}
- gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)draw_shadow, NULL);
-
-
- for (i = 0; i < view->edges_count; i++)
- g_graph_edge_draw(view->edges[i], cr, true);
-
+ gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_shadow, NULL);
- /*
- if (view->layout != NULL)
- g_graph_layout_draw(view->layout, cr, true);
- */
+ for (i = 0; i < display->edges_count; i++)
+ g_graph_edge_draw(display->edges[i], cr, true);
return FALSE;
@@ -505,9 +469,9 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView
/******************************************************************************
* *
-* Paramètres : widget = composant GTK visé par l'opération. *
-* event = informations liées à l'événement. *
-* view = support maître à consulter. *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* display = support maître à consulter. *
* *
* Description : Assure la gestion des clics de souris sur le composant. *
* *
@@ -517,7 +481,7 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView
* *
******************************************************************************/
-static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
+static gboolean gtk_graph_display_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display)
{
gboolean result; /* Poursuite à faire suivre */
GtkScrolledWindow *support; /* Support défilant associé */
@@ -529,21 +493,21 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e
if (event->button == 1)
{
- support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
+ support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display)));
hadj = gtk_scrolled_window_get_hadjustment(support);
vadj = gtk_scrolled_window_get_vadjustment(support);
- view->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj)
+ display->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj)
|| gtk_adjustment_get_upper(vadj) > gtk_adjustment_get_page_size(vadj));
- if (view->big_enough)
+ if (display->big_enough)
{
- view->start_x = event->x_root;
- view->start_y = event->y_root;
+ display->start_x = event->x_root;
+ display->start_y = event->y_root;
- view->ref_h = gtk_adjustment_get_value(hadj);
- view->ref_v = gtk_adjustment_get_value(vadj);
+ display->ref_h = gtk_adjustment_get_value(hadj);
+ display->ref_v = gtk_adjustment_get_value(vadj);
cursor = gdk_cursor_new(GDK_FLEUR);
gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
@@ -562,9 +526,9 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e
/******************************************************************************
* *
-* Paramètres : widget = composant GTK visé par l'opération. *
-* event = informations liées à l'événement. *
-* view = support maître à consulter. *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* display = support maître à consulter. *
* *
* Description : Assure la gestion des clics de souris sur le composant. *
* *
@@ -574,9 +538,9 @@ static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *e
* *
******************************************************************************/
-static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
+static gboolean gtk_graph_display_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display)
{
- if (event->button == 1 && view->big_enough)
+ if (event->button == 1 && display->big_enough)
gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
return FALSE;
@@ -586,9 +550,9 @@ static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton
/******************************************************************************
* *
-* Paramètres : widget = composant GTK visé par l'opération. *
-* event = informations liées à l'événement. *
-* view = support maître à consulter. *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* display = support maître à consulter. *
* *
* Description : Assure la suivi des déplacements de souris sur le composant. *
* *
@@ -598,7 +562,7 @@ static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton
* *
******************************************************************************/
-static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphView *view)
+static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphDisplay *display)
{
gdouble diff_x; /* Evolution sur les abscisses */
gdouble diff_y; /* Evolution sur les ordonnées */
@@ -607,21 +571,21 @@ static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *
GtkAdjustment *vadj; /* Gestionnaire du défilement */
gdouble value; /* Nouvelle valeur bornée */
- if (event->state & GDK_BUTTON1_MASK && view->big_enough)
+ if (event->state & GDK_BUTTON1_MASK && display->big_enough)
{
- diff_x = view->start_x - event->x_root;
- diff_y = view->start_y - event->y_root;
+ diff_x = display->start_x - event->x_root;
+ diff_y = display->start_y - event->y_root;
- support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
+ support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display)));
hadj = gtk_scrolled_window_get_hadjustment(support);
vadj = gtk_scrolled_window_get_vadjustment(support);
- value = CLAMP(view->ref_h + diff_x, gtk_adjustment_get_lower(hadj),
+ value = CLAMP(display->ref_h + diff_x, gtk_adjustment_get_lower(hadj),
gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj));
gtk_adjustment_set_value(hadj, value);
- value = CLAMP(view->ref_v + diff_y, gtk_adjustment_get_lower(vadj),
+ value = CLAMP(display->ref_v + diff_y, gtk_adjustment_get_lower(vadj),
gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj));
gtk_adjustment_set_value(vadj, value);
@@ -634,41 +598,8 @@ static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* *
-* Description : Actualise les besoins internes avant un redimensionnement. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void gtk_graph_view_prepare_resize(GtkGraphView *view)
-{
- size_t i; /* Boucle de parcours */
-
- if (view->children_count > 0)
- {
- for (i = 0; i < view->children_count; i++)
- gtk_widget_queue_resize(GTK_WIDGET(view->children[i]));
-
- /*
- g_graph_layout_refresh(view->layout);
- g_graph_layout_place(view->layout, view);
- */
-
- change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view));
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* addr = adresse sélectionnée de manière externe. *
+* Paramètres : display = composant GTK à mettre à jour. *
+* addr = adresse sélectionnée de manière externe. *
* *
* Description : Réagit à la sélection externe d'une adresse. *
* *
@@ -678,7 +609,7 @@ static void gtk_graph_view_prepare_resize(GtkGraphView *view)
* *
******************************************************************************/
-static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t *addr)
+static void gtk_graph_display_define_main_address(GtkGraphDisplay *display, const vmpa2t *addr)
{
bool need_update; /* Mise à jour du contenu ? */
const mrange_t *range; /* Couverture courante */
@@ -690,19 +621,19 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
gint bottom; /* Ordonnée du coin inférieur */
GtkAllocation allocation; /* Espace alloué au panneau */
- if (view->routine == NULL)
+ if (display->routine == NULL)
need_update = true;
else
{
- range = g_binary_routine_get_range(view->routine);
+ range = g_binary_routine_get_range(display->routine);
need_update = !mrange_contains_addr(range, addr);
}
if (need_update)
{
- gtk_graph_view_reset(view);
+ gtk_graph_display_reset(display);
- format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary);
+ format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(display)->binary);
routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
for (i = 0; i < routines_count; i++)
@@ -711,22 +642,22 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
if (mrange_contains_addr(range, addr))
{
- view->routine = routines[i];
- g_object_ref(G_OBJECT(view->routine));
+ display->routine = routines[i];
+ g_object_ref(G_OBJECT(display->routine));
- view->highlighted = init_segment_content_list();
+ display->highlighted = init_segment_content_list();
/*
- view->children = gtk_graph_view_load_nodes(view, GTK_DISPLAY_PANEL(view)->binary,
+ display->children = gtk_graph_display_load_nodes(display, GTK_DISPLAY_PANEL(display)->binary,
routines[i]);
- view->allocs = (GtkAllocation *)calloc(view->children_count,
+ display->allocs = (GtkAllocation *)calloc(display->children_count,
sizeof(GtkAllocation));
- view->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(view->routine),
- view->children, view->children_count);
+ display->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(display->routine),
+ display->children, display->children_count);
- g_graph_layout_place(view->layout, view);
+ g_graph_layout_place(display->layout, display);
*/
do
@@ -737,17 +668,17 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
list = g_binary_routine_get_basic_blocks(routines[i]);
#if 0
- view->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(view)->binary,
- list, 0/* FIXME */, view->highlighted);
+ display->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(display)->binary,
+ list, 0/* FIXME */, display->highlighted);
#endif
- view->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(view)->binary,
- list, view->highlighted);
+ display->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(display)->binary,
+ list, display->highlighted);
- g_graph_cluster_place(view->cluster, view);
+ g_graph_cluster_place(display->cluster, display);
/**
* Comme la taille du support ne peut pas être forcée et
@@ -755,18 +686,18 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
* minuscule à l'extrémité de ce support.
*/
- gtk_graph_view_compute_requested_size(view, &right, &bottom);
+ gtk_graph_display_compute_requested_size(display, &right, &bottom);
- g_object_ref(G_OBJECT(view->extender));
- gtk_fixed_put(GTK_FIXED(view->support), view->extender, right, bottom);
+ g_object_ref(G_OBJECT(display->extender));
+ gtk_fixed_put(GTK_FIXED(display->support), display->extender, right - 1, bottom - 1);
/**
* Si possible, on centre le contenu obtenu.
*/
- gtk_widget_get_allocation(GTK_WIDGET(view), &allocation);
+ gtk_widget_get_allocation(GTK_WIDGET(display), &allocation);
- gtk_graph_view_update_support_margins(view, &allocation);
+ gtk_graph_display_update_support_margins(display, &allocation);
@@ -781,7 +712,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
}
- change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view));
+ change_editor_items_current_view_content(GTK_DISPLAY_PANEL(display));
g_object_unref(G_OBJECT(format));
@@ -792,7 +723,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
+* Paramètres : display = composant GTK à manipuler. *
* *
* Description : Indique la position courante du curseur. *
* *
@@ -802,7 +733,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
* *
******************************************************************************/
-static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view)
+static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *display)
{
return NULL; /* FIXME */
@@ -811,11 +742,11 @@ static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à consulter. *
-* addr = adresse à présenter à l'écran. *
-* x = position horizontale au sein du composant. [OUT] *
-* y = position verticale au sein du composant. [OUT] *
-* tweak = adaptation finale à effectuer. *
+* Paramètres : display = composant GTK à consulter. *
+* addr = adresse à présenter à l'écran. *
+* x = position horizontale au sein du composant. [OUT] *
+* y = position verticale au sein du composant. [OUT] *
+* tweak = adaptation finale à effectuer. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -825,7 +756,7 @@ static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view)
* *
******************************************************************************/
-static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
+static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
{
/* TODO */
@@ -836,9 +767,9 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, con
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* x = abscisse proposée pour le nouvel emplacement. *
-* y = ordonnée proposée pour le nouvel emplacement. *
+* Paramètres : display = composant GTK à manipuler. *
+* x = abscisse proposée pour le nouvel emplacement. *
+* y = ordonnée proposée pour le nouvel emplacement. *
* *
* Description : Déplace le curseur à un emplacement défini. *
* *
@@ -848,31 +779,41 @@ static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, con
* *
******************************************************************************/
-static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y)
+static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *display, gint x, gint y)
{
bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- GtkDisplayPanel *panel; /* Autre vision d'enfance */
- gint sub_x; /* Abscisse relative à l'enfant*/
- gint sub_y; /* Ordonnée relative à l'enfant*/
result = false;
- for (i = 0; i < view->children_count; i++)
+ void move_caret_to_sub_block(GtkWidget *child, gpointer unused)
{
- if (x < view->allocs[i].x || x >= (view->allocs[i].x + view->allocs[i].width)) continue;
- if (y < view->allocs[i].y || y >= (view->allocs[i].y + view->allocs[i].height)) continue;
+ GtkAllocation alloc; /* Emplacement réservé */
+ GtkDisplayPanel *panel; /* Autre vision d'enfance */
+ gint sub_x; /* Abscisse relative à l'enfant*/
+ gint sub_y; /* Ordonnée relative à l'enfant*/
+
+ if (result)
+ return;
+
+ if (!GTK_IS_BUFFER_DISPLAY(child))
+ return;
+
+ gtk_widget_get_allocation(child, &alloc);
+
+ if (x < alloc.x || x >= (alloc.x + alloc.width)) return;
+ if (y < alloc.y || y >= (alloc.y + alloc.height)) return;
- panel = GTK_DISPLAY_PANEL(view->children[i]);
+ panel = GTK_DISPLAY_PANEL(child);
- sub_x = x - view->allocs[i].x;
- sub_y = y - view->allocs[i].y;
+ sub_x = x - alloc.x;
+ sub_y = y - alloc.y;
result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->move_caret_to(panel, sub_x, sub_y);
- break;
}
+ gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)move_caret_to_sub_block, NULL);
+
return result;
}
@@ -880,10 +821,10 @@ static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à manipuler. *
-* cairo = assistant pour la création de rendus. *
-* area = taille de la surface réduite à disposition. *
-* scale = échelle vis à vis de la taille réelle. *
+* Paramètres : display = composant GTK à manipuler. *
+* cr = assistant pour la création de rendus. *
+* area = taille de la surface réduite à disposition. *
+* scale = échelle vis à vis de la taille réelle. *
* *
* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
* *
@@ -893,28 +834,34 @@ static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y)
* *
******************************************************************************/
-static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo, const GtkAllocation *area, double scale)
+static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr, const GtkAllocation *area, double scale)
{
size_t i; /* Boucle de parcours */
- GtkAllocation sub_area; /* Emplacement réservé */
- for (i = 0; i < view->children_count; i++)
+ void draw_child_glance(GtkWidget *child, gpointer unused)
{
- sub_area.x = view->allocs[i].x * scale;
- sub_area.y = view->allocs[i].y * scale;
- sub_area.width = view->allocs[i].width * scale + 1;
- sub_area.height = view->allocs[i].height * scale + 1;
+ GtkAllocation sub_area; /* Emplacement réservé */
+
+ if (!GTK_IS_BUFFER_DISPLAY(child))
+ return;
- gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(view->children[i]), cairo, &sub_area, scale);
+ gtk_widget_get_allocation(child, &sub_area);
+
+ sub_area.x *= scale;
+ sub_area.y *= scale;
+ sub_area.width = sub_area.width * scale + 1;
+ sub_area.height = sub_area.height * scale + 1;
+
+ gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(child), cr, &sub_area, scale);
}
- cairo_scale(cairo, scale, scale);
+ gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_child_glance, NULL);
- /*
- if (view->layout != NULL)
- g_graph_layout_draw(view->layout, cairo, false);
- */
+ cairo_scale(cr, scale, scale);
+
+ for (i = 0; i < display->edges_count; i++)
+ g_graph_edge_draw(display->edges[i], cr, false);
}
@@ -931,19 +878,19 @@ static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo, cons
* *
******************************************************************************/
-GtkWidget *gtk_graph_view_new(void)
+GtkWidget *gtk_graph_display_new(void)
{
- return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL);
+ return g_object_new(GTK_TYPE_GRAPH_DISPLAY, NULL);
}
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* widget = composant GTK à insérer. *
-* x = abscisse du point d'insertion. *
-* y = ordonnée du point d'insertion. *
+* Paramètres : display = composant GTK à mettre à jour. *
+* widget = composant GTK à insérer. *
+* x = abscisse du point d'insertion. *
+* y = ordonnée du point d'insertion. *
* *
* Description : Place une vue sous forme de bloc dans le graphique. *
*