summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/arm/v7/fetch.c25
-rw-r--r--plugins/dalvik/link.c2
-rw-r--r--plugins/fmtp/parser.c34
-rw-r--r--plugins/lnxsyscalls/writer.c48
-rw-r--r--plugins/pychrysalide/analysis/db/items/Makefile.am1
-rw-r--r--plugins/pychrysalide/analysis/db/items/comment.c550
-rw-r--r--plugins/pychrysalide/analysis/db/items/comment.h20
-rw-r--r--plugins/pychrysalide/analysis/db/items/constants.c129
-rw-r--r--plugins/pychrysalide/analysis/db/items/constants.h42
-rw-r--r--plugins/pychrysalide/analysis/db/items/module.c1
-rw-r--r--src/analysis/db/items/comment.c793
-rw-r--r--src/analysis/db/items/comment.h60
-rw-r--r--src/core/collections.c2
-rw-r--r--src/format/preload.c77
-rw-r--r--src/format/preload.h6
15 files changed, 1191 insertions, 599 deletions
diff --git a/plugins/arm/v7/fetch.c b/plugins/arm/v7/fetch.c
index 876ad51..2d38cbf 100644
--- a/plugins/arm/v7/fetch.c
+++ b/plugins/arm/v7/fetch.c
@@ -33,6 +33,7 @@
#include <arch/instructions/raw.h>
#include <arch/operands/immediate.h>
#include <arch/operands/register.h>
+#include <common/extstr.h>
#include <format/known.h>
#include <format/format.h>
#include <format/preload.h>
@@ -389,6 +390,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
GArchInstruction *loaded; /* Instruction de valeur */
bool inserted; /* Bilan d'une insertion */
char *desc; /* Description d'accompagnement*/
+ size_t index; /* Indice d'un existant ? */
GDbComment *comment; /* Définition de commentaire */
GArchOperand *new; /* Instruction de ciblage */
@@ -494,30 +496,35 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
g_preload_info_lock_comments(info);
- comment = _g_preload_info_find_comment_at(info, &loaded_addr);
+ comment = g_preload_info_find_comment_at(info, &loaded_addr, &index);
- if (comment != NULL)
+ if (comment == NULL)
{
- g_db_comment_add_static_text(comment, "\n");
- g_db_comment_add_dynamic_text(comment, desc);
+ comment = g_db_comment_new(&loaded_addr, CET_INLINED, BLF_HAS_CODE, desc);
+ g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
- g_object_unref(G_OBJECT(comment));
+ _g_preload_info_add_comment(info, comment);
}
else
{
- comment = g_db_comment_new_inlined(&loaded_addr, BLF_HAS_CODE, false);
- g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+ desc = strprep(desc, "\n");
+ desc = strprep(desc, g_db_comment_get_text(comment));
- g_db_comment_add_dynamic_text(comment, desc);
+ g_object_unref(G_OBJECT(comment));
- _g_preload_info_add_comment(info, comment);
+ comment = g_db_comment_new(&loaded_addr, CET_INLINED, BLF_HAS_CODE, desc);
+ g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+ g_preload_info_replace_comment_at(info, index, comment);
}
g_preload_info_unlock_comments(info);
+ free(desc);
+
}
/* Mise à jour de l'affichage et conclusion */
diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c
index d412511..9fb1992 100644
--- a/plugins/dalvik/link.c
+++ b/plugins/dalvik/link.c
@@ -358,7 +358,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
}
- item = g_db_comment_new_area(&comment->handler, BLF_NONE, msg, true);
+ item = g_db_comment_new(&comment->handler, CET_BEFORE, BLF_NONE, msg);
g_db_item_add_flag(G_DB_ITEM(item), DIF_VOLATILE);
g_proc_context_add_db_item(context, G_DB_ITEM(item));
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index 4a8749d..84bb86f 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -25,10 +25,12 @@
#include <assert.h>
+#include <string.h>
#include <i18n.h>
#include <arch/instructions/raw.h>
+#include <common/extstr.h>
#include <format/known.h>
@@ -63,6 +65,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
GArchInstruction *instr; /* Instruction décodée */
GImmOperand *imm; /* Opérande à transformer */
size_t i; /* Boucle de parcours */
+ char *text; /* Texte du commentaire complet*/
const vmpa2t *addr; /* Emplacement d'instruction */
GDbComment *comment; /* Définition de commentaire */
uint64_t raw; /* Valeur brute à étudier */
@@ -125,15 +128,12 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
/* Commentaire */
- addr = get_mrange_addr(g_arch_instruction_get_range(instr));
-
- comment = g_db_comment_new_inlined(addr, BLF_HAS_CODE, false);
- g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+ text = NULL;
switch (def->ctype)
{
case FCT_PLAIN:
- g_db_comment_add_static_text(comment, _(def->comment.plain));
+ text = strdup(_(def->comment.plain));
break;
case FCT_SWITCH:
@@ -155,13 +155,16 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
else if (raw != def->comment.choices[i].fixed)
continue;
- g_db_comment_add_static_text(comment, _(def->comment.choices[i].desc));
+ text = strnadd(text, _(def->comment.choices[i].desc), strlen(_(def->comment.choices[i].desc)));
break;
}
- if (i == def->comment.ccount)
- g_db_comment_add_static_text(comment, _(def->comment.def_choice));
+ if (text == NULL)
+ {
+ assert(i == def->comment.ccount);
+ text = strdup(_(def->comment.def_choice));
+ }
break;
@@ -174,16 +177,16 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
if (part->is_static)
{
if (part->avoid_i18n)
- g_db_comment_add_static_text(comment, part->static_text);
+ text = strnadd(text, part->static_text, strlen(part->static_text));
else
- g_db_comment_add_static_text(comment, _(part->static_text));
+ text = strnadd(text, _(part->static_text), strlen(_(part->static_text)));
}
else
{
if (part->avoid_i18n)
- g_db_comment_add_dynamic_text(comment, part->dynamic_text);
+ text = strnadd(text, part->dynamic_text, strlen(part->dynamic_text));
else
- g_db_comment_add_dynamic_text(comment, _(part->dynamic_text));
+ text = strnadd(text, _(part->dynamic_text), strlen(_(part->dynamic_text)));
}
}
@@ -192,6 +195,13 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
}
+ addr = get_mrange_addr(g_arch_instruction_get_range(instr));
+
+ comment = g_db_comment_new(addr, CET_INLINED, BLF_HAS_CODE, text);
+ g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+ free(text);
+
/* Insertions */
inserted = g_preload_info_add_instruction(info, instr);
diff --git a/plugins/lnxsyscalls/writer.c b/plugins/lnxsyscalls/writer.c
index 743e5c6..0b90d68 100644
--- a/plugins/lnxsyscalls/writer.c
+++ b/plugins/lnxsyscalls/writer.c
@@ -29,6 +29,7 @@
#include <analysis/db/items/comment.h>
+#include <common/extstr.h>
@@ -196,43 +197,60 @@ void write_all_comments(comment_writer *writer, GPreloadInfo *preload)
{
size_t i; /* Boucle de parcours #1 */
comment_data *target; /* Commentaire à éditer */
- GDbComment *comment; /* Commentaire final à intégrer*/
- bool new; /* Nature du commentaire */
+ char *text; /* Texte du commentaire complet*/
size_t k; /* Boucle de parcours #2 */
+ size_t index; /* Indice d'un existant ? */
+ GDbComment *comment; /* Commentaire final à intégrer*/
for (i = 0; i < writer->count; i++)
{
target = &writer->comments[i];
- g_preload_info_lock_comments(preload);
+ /* Construction de la nouveauté */
- comment = _g_preload_info_find_comment_at(preload, &target->addr);
+ text = NULL;
+
+ for (k = 0; k < target->count; k++)
+ {
+ if (k > 0)
+ text = stradd(text, " / ");
- new = (comment == NULL);
+ text = stradd(text, target->text[k]);
+
+ }
+
+ /* Inclusion de l'existant */
+
+ g_preload_info_lock_comments(preload);
+
+ comment = g_preload_info_find_comment_at(preload, &target->addr, &index);
if (comment == NULL)
{
- comment = g_db_comment_new_inlined(&target->addr, BLF_HAS_CODE, false);
+ comment = g_db_comment_new(&target->addr, CET_INLINED, BLF_HAS_CODE, text);
g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
- g_object_ref(G_OBJECT(comment));
-
_g_preload_info_add_comment(preload, comment);
}
- g_preload_info_unlock_comments(preload);
-
- for (k = 0; k < target->count; k++)
+ else
{
- if (k > 0 || !new)
- g_db_comment_add_static_text(comment, " / ");
+ text = strprep(text, " / ");
+ text = strprep(text, g_db_comment_get_text(comment));
- g_db_comment_add_dynamic_text(comment, strdup(target->text[k]));
+ g_object_unref(G_OBJECT(comment));
+
+ comment = g_db_comment_new(&target->addr, CET_INLINED, BLF_HAS_CODE, text);
+ g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+ g_preload_info_replace_comment_at(preload, index, comment);
}
- g_object_unref(G_OBJECT(comment));
+ g_preload_info_unlock_comments(preload);
+
+ free(text);
}
diff --git a/plugins/pychrysalide/analysis/db/items/Makefile.am b/plugins/pychrysalide/analysis/db/items/Makefile.am
index 07593f8..35f4ee6 100644
--- a/plugins/pychrysalide/analysis/db/items/Makefile.am
+++ b/plugins/pychrysalide/analysis/db/items/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libpychrysaanalysisdbitems.la
libpychrysaanalysisdbitems_la_SOURCES = \
bookmark.h bookmark.c \
comment.h comment.c \
+ constants.h constants.c \
module.h module.c \
switcher.h switcher.c
diff --git a/plugins/pychrysalide/analysis/db/items/comment.c b/plugins/pychrysalide/analysis/db/items/comment.c
index 845a118..78d4902 100644
--- a/plugins/pychrysalide/analysis/db/items/comment.c
+++ b/plugins/pychrysalide/analysis/db/items/comment.c
@@ -29,28 +29,57 @@
#include <pygobject.h>
-#include <i18n.h>
#include <analysis/db/items/comment.h>
+#include <plugins/dt.h>
+#include "constants.h"
+#include "../collection.h"
#include "../item.h"
#include "../../../access.h"
#include "../../../helpers.h"
#include "../../../arch/vmpa.h"
+#include "../../../glibext/constants.h"
+#include "../../../glibext/bufferline.h"
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
/* Crée un nouvel objet Python de type 'DbComment'. */
static PyObject *py_db_comment_new(PyTypeObject *, PyObject *, PyObject *);
-/* Associe un contenu statique supplémentaire à un commentaire. */
-static PyObject *py_db_comment_add_text(PyObject *, PyObject *);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_db_comment_init(PyObject *, PyObject *, PyObject *);
+
+/* Fournit l'adresse associée à un commentaire. */
+static PyObject *py_db_comment_get_address(PyObject *, void *);
+
+/* Indique le type d'incrustation prévue pour un commentaire. */
+static PyObject *py_db_comment_get_embedding_type(PyObject *, void *);
+
+/* Fournit les particularités d'accroche liées à un commentaire. */
+static PyObject *py_db_comment_get_flags(PyObject *, void *);
/* Fournit le commentaire associé à un commentaire. */
static PyObject *py_db_comment_get_text(PyObject *, void *);
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Crée un nouvel objet Python de type 'CommentCollection'. */
+static PyObject *py_comment_collection_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ELABORATION D'UN ELEMENT DE COLLECTION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : type = type de l'objet à instancier. *
@@ -67,58 +96,170 @@ static PyObject *py_db_comment_get_text(PyObject *, void *);
static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
- int repeatable; /* Note une répétition demandée*/
- const char *text; /* Eventuel premier commentaire*/
- int before; /* Indication sur l'emplacement*/
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
+
+ /* Validations diverses */
+
+ base = get_python_db_comment_type();
+
+ if (type == base)
+ goto simple_way;
+
+ /* Mise en place d'un type dédié */
+
+ first_time = (g_type_from_name(type->tp_name) == 0);
+
+ gtype = build_dynamic_type(G_TYPE_DB_COMMENT, type->tp_name, NULL, NULL, NULL);
+
+ if (first_time)
+ {
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0 en cas de succès, -1 sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_db_comment_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int result; /* Bilan à renvoyer */
vmpa2t *addr; /* Emplacement ciblé */
- unsigned long flags; /* Identifiants de ligne visée */
+ CommentEmbeddingType type; /* Type d'incrustation */
+ BufferLineFlags flags; /* Particularités de l'accroche*/
+ const char *text; /* Eventuel contenu textuel */
int ret; /* Bilan de lecture des args. */
- GDbComment *comment; /* Version GLib du commentaire */
-
- static char *kwlist[] = { "addr", "flags", "repeatable", "text", "before", NULL };
+ GDbComment *comment; /* Version GLib du signet */
+ bool status; /* Bilan de l'initialisation */
+
+#define DB_COMMENT_DOC \
+ "DbComment provides support for comments to embed into the disassembled" \
+ " code.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " DbComment(addr, addr, type, flags, text=None)\n" \
+ "\n" \
+ "Where *addr* is a location of type pychrysalide.arch.vmpa, *type* defines" \
+ " the kind of embedding as a" \
+ " pychrysalide.analysis.db.items.DbComment.CommentEmbeddingType value," \
+ " *flags* states for the pychrysalide.glibext.BufferLine.BufferLineFlags" \
+ " property of the line to attach and *text* is an optional string for the" \
+ " comment.\n" \
+ "\n" \
+ "An empty comment is not enough to delete a comment for a given address;" \
+ " the *ERASER* flag from the pychrysalide.analysis.db.DbItem.DbItemFlags" \
+ " enumeration must be explicitly add to the item by a call to the" \
+ " pychrysalide.analysis.db.DbItem.add_flag() function."
+
+ result = -1;
/* Récupération des paramètres */
- repeatable = -1;
text = NULL;
- before = -1;
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&k|$psp", kwlist,
- convert_any_to_vmpa, &addr, &flags, &repeatable, &text, &before);
- if (!ret) return NULL;
+ ret = PyArg_ParseTuple(args, "O&O&O&|s",
+ convert_any_to_vmpa, &addr,
+ convert_to_comment_embedding_type, &type,
+ convert_to_buffer_line_flags, &flags,
+ &text);
+ if (!ret) goto exit;
- /* Vérifications diverses */
+ /* Initialisation d'un objet GLib */
- if (flags > BLF_ALL)
+ ret = forward_pygobjet_init(self);
+ if (ret == -1)
{
clean_vmpa_arg(addr);
+ goto exit;
+ }
- PyErr_SetString(PyExc_ValueError, _("Invalid flag combination"));
- return NULL;
+ /* Eléments de base */
- }
+ comment = G_DB_COMMENT(pygobject_get(self));
- if ((repeatable == -1 && before == -1) || (repeatable != -1 && before != -1))
+ status = g_db_comment_fill(comment, addr, type, flags, text);
+ if (!status)
{
clean_vmpa_arg(addr);
+ goto exit;
+ }
- PyErr_SetString(PyExc_ValueError, _("repeatable or before has to be defined"));
- return NULL;
+ clean_vmpa_arg(addr);
- }
+ result = 0;
- /* Construction */
+ exit:
- if (repeatable)
- comment = g_db_comment_new_inlined(addr, flags, repeatable);
- else
- comment = g_db_comment_new_area(addr, flags, text, before);
+ return result;
- result = pygobject_new(G_OBJECT(comment));
- g_object_unref(comment);
+}
- clean_vmpa_arg(addr);
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit l'adresse associée à un commentaire. *
+* *
+* Retour : Adresse mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_db_comment_get_address(PyObject *self, void *closure)
+{
+ PyObject *result; /* Résultat à retourner */
+ GDbComment *comment; /* Commentaire à consulter */
+ const vmpa2t *addr; /* Localisation du commentaire */
+
+#define DB_COMMENT_ADDRESS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ address, py_db_comment, \
+ "Location of the comment, provided as a" \
+ " pychrysalide.arch.vmpa instance." \
+)
+
+ comment = G_DB_COMMENT(pygobject_get(self));
+
+ addr = g_db_comment_get_address(comment);
+
+ result = build_from_internal_vmpa(addr);
return result;
@@ -127,31 +268,74 @@ static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject
/******************************************************************************
* *
-* Paramètres : self = classe représentant un commentaire. *
-* args = arguments fournis à l'appel. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Associe un contenu statique supplémentaire à un commentaire. *
+* Description : Indique le type d'incrustation prévue pour un commentaire. *
* *
-* Retour : None. *
+* Retour : Incrustation associée au commentaire. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_db_comment_add_text(PyObject *self, PyObject *args)
+static PyObject *py_db_comment_get_embedding_type(PyObject *self, void *closure)
{
- const char *text; /* Commentaire complémentaire */
- int ret; /* Bilan de lecture des args. */
+ PyObject *result; /* Résultat à retourner */
GDbComment *comment; /* Commentaire à consulter */
+ CommentEmbeddingType type; /* Type d'incrustation */
- ret = PyArg_ParseTuple(args, "s", &text);
- if (!ret) return NULL;
+#define DB_COMMENT_EMBEDDING_TYPE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ embedding_type, py_db_comment, \
+ "Type of embedding required for the comment, as a" \
+ " pychrysalide.analysis.db.items.DbComment.CommentEmbeddingType value." \
+)
comment = G_DB_COMMENT(pygobject_get(self));
- g_db_comment_add_static_text(comment, text);
+ type = g_db_comment_get_embedding_type(comment);
+
+ result = cast_with_constants_group_from_type(get_python_db_comment_type(), "CommentEmbeddingType", type);
- Py_RETURN_NONE;
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit les particularités d'accroche liées à un commentaire.*
+* *
+* Retour : Particularités éventuelles pour l'accroche. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_db_comment_get_flags(PyObject *self, void *closure)
+{
+ PyObject *result; /* Résultat à retourner */
+ GDbComment *comment; /* Commentaire à consulter */
+ BufferLineFlags flags; /* Fanions à rechercher */
+
+#define DB_COMMENT_FLAGS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ flags, py_db_comment, \
+ "Flags of the line where to attach the comment, as a" \
+ " pychrysalide.glibext.BufferLine.BufferLineFlags value." \
+)
+
+ comment = G_DB_COMMENT(pygobject_get(self));
+
+ flags = g_db_comment_get_flags(comment);
+
+ result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
+
+ return result;
}
@@ -175,6 +359,13 @@ static PyObject *py_db_comment_get_text(PyObject *self, void *closure)
GDbComment *comment; /* Commentaire à consulter */
char *text; /* Contenu textuel associé */
+#define DB_COMMENT_TEXT_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ text, py_db_comment, \
+ "Content of the comment, as a string which may contain several lines," \
+ " or None of no text is linked to the comment." \
+)
+
comment = G_DB_COMMENT(pygobject_get(self));
text = g_db_comment_get_text(comment);
@@ -209,19 +400,14 @@ static PyObject *py_db_comment_get_text(PyObject *self, void *closure)
PyTypeObject *get_python_db_comment_type(void)
{
static PyMethodDef py_db_comment_methods[] = {
- {
- "add_text", py_db_comment_add_text,
- METH_VARARGS,
- "add_text($self, text, /)\n--\n\nAppend extra text to a given comment."
- },
{ NULL }
};
static PyGetSetDef py_db_comment_getseters[] = {
- {
- "text", py_db_comment_get_text, NULL,
- "Give access to the content of a given comment.", NULL
- },
+ DB_COMMENT_ADDRESS_ATTRIB,
+ DB_COMMENT_EMBEDDING_TYPE_ATTRIB,
+ DB_COMMENT_FLAGS_ATTRIB,
+ DB_COMMENT_TEXT_ATTRIB,
{ NULL }
};
@@ -234,11 +420,13 @@ PyTypeObject *get_python_db_comment_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "PyChrysalide comment for edited binary",
+ .tp_doc = DB_COMMENT_DOC,
.tp_methods = py_db_comment_methods,
.tp_getset = py_db_comment_getseters,
- .tp_new = py_db_comment_new
+
+ .tp_init = py_db_comment_init,
+ .tp_new = py_db_comment_new,
};
@@ -279,8 +467,260 @@ bool ensure_python_db_comment_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_DB_COMMENT, type, get_python_db_item_type()))
return false;
+ if (!define_db_comment_constants(type))
+ return false;
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en commentaire de base. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_db_comment(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_db_comment_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to database comment");
+ break;
+
+ case 1:
+ *((GDbComment **)dst) = G_DB_COMMENT(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION DE LA COLLECTION ASSOCIEE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'CommentCollection'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_comment_collection_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
+
+#define COMMENT_COLLECTION_DOC \
+ "CommentCollection remembers all comment definitions.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " CommentCollection()\n" \
+ "\n" \
+ "There should be no need for creating such instances manually."
+
+ /* Validations diverses */
+
+ base = get_python_db_comment_type();
+
+ if (type == base)
+ goto simple_way;
+
+ /* Mise en place d'un type dédié */
+
+ first_time = (g_type_from_name(type->tp_name) == 0);
+
+ gtype = build_dynamic_type(G_TYPE_DB_COMMENT, type->tp_name, NULL, NULL, NULL);
+
+ if (first_time)
+ {
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_comment_collection_type(void)
+{
+ static PyMethodDef py_comment_collection_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_comment_collection_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_comment_collection_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.db.items.CommentCollection",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = COMMENT_COLLECTION_DOC,
+
+ .tp_methods = py_comment_collection_methods,
+ .tp_getset = py_comment_collection_getseters,
+
+ .tp_new = py_comment_collection_new,
+
+ };
+
+ return &py_comment_collection_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....CommentCollection'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_comment_collection_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'DbComment' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_comment_collection_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.analysis.db.items");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_db_collection_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_COMMENT_COLLECTION, type, get_python_db_collection_type()))
+ return false;
+
}
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en collection de commentaires. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_comment_collection(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_comment_collection_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to comment collection");
+ break;
+
+ case 1:
+ *((GCommentCollection **)dst) = G_COMMENT_COLLECTION(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/db/items/comment.h b/plugins/pychrysalide/analysis/db/items/comment.h
index df02cc6..4e5af64 100644
--- a/plugins/pychrysalide/analysis/db/items/comment.h
+++ b/plugins/pychrysalide/analysis/db/items/comment.h
@@ -31,12 +31,32 @@
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_db_comment_type(void);
/* Prend en charge l'objet 'pychrysalide.analysis.db.items.DbComment'. */
bool ensure_python_db_comment_is_registered(void);
+/* Tente de convertir en commentaire de base. */
+int convert_to_db_comment(PyObject *, void *);
+
+
+
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_comment_collection_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.items.CommentCollection'. */
+bool ensure_python_comment_collection_is_registered(void);
+
+/* Tente de convertir en collection de commentaires. */
+int convert_to_comment_collection(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_COMMENT_H */
diff --git a/plugins/pychrysalide/analysis/db/items/constants.c b/plugins/pychrysalide/analysis/db/items/constants.c
new file mode 100644
index 0000000..e3ef99e
--- /dev/null
+++ b/plugins/pychrysalide/analysis/db/items/constants.c
@@ -0,0 +1,129 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes liées aux éléments de base
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "constants.h"
+
+
+#include <i18n.h>
+#include <analysis/db/items/comment.h>
+
+
+#include "../../../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux commentaires de base. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_db_comment_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "INLINED", CET_INLINED);
+ if (result) result = add_const_to_group(values, "REPEATED", CET_REPEATED);
+ if (result) result = add_const_to_group(values, "BEFORE", CET_BEFORE);
+ if (result) result = add_const_to_group(values, "AFTER", CET_AFTER);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "CommentEmbeddingType", values,
+ "Kinds of insertion for comments.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en constante CommentEmbeddingType. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_comment_embedding_type(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur récupérée */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type);
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to CommentEmbeddingType");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if (value >= CET_COUNT)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value to convert to CommentEmbeddingType");
+ result = 0;
+ }
+
+ else
+ *((CommentEmbeddingType *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/db/items/constants.h b/plugins/pychrysalide/analysis/db/items/constants.h
new file mode 100644
index 0000000..80210d9
--- /dev/null
+++ b/plugins/pychrysalide/analysis/db/items/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes liées aux éléments de base
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux commentaires de base. */
+bool define_db_comment_constants(PyTypeObject *);
+
+/* Tente de convertir en constante CommentEmbeddingType. */
+int convert_to_comment_embedding_type(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/db/items/module.c b/plugins/pychrysalide/analysis/db/items/module.c
index c963354..cbc367d 100644
--- a/plugins/pychrysalide/analysis/db/items/module.c
+++ b/plugins/pychrysalide/analysis/db/items/module.c
@@ -91,6 +91,7 @@ bool populate_analysis_db_items_module(void)
result = true;
if (result) result = ensure_python_bookmark_collection_is_registered();
+ if (result) result = ensure_python_comment_collection_is_registered();
if (result) result = ensure_python_switcher_collection_is_registered();
if (result) result = ensure_python_db_bookmark_is_registered();
if (result) result = ensure_python_db_comment_is_registered();
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 4b22502..136b62b 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -27,6 +27,7 @@
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
+#include <string.h>
#include <sys/socket.h>
@@ -53,23 +54,10 @@ struct _GDbComment
GDbItem parent; /* A laisser en premier */
vmpa2t addr; /* Adresse du commentaire */
+ CommentEmbeddingType type; /* Type d'incrustation */
BufferLineFlags flags; /* Identification de l'accroche*/
flat_array_t *text; /* Contenu du commentaire */
- size_t count; /* Quantité de lignes affichées*/
-
- bool inlined; /* Intégration dans une ligne ?*/
-
- union
- {
- bool repeatable; /* Répétition aux lignes liées */
- bool before; /* Zone dédiée au dessus ? */
- };
-
- GLineGenerator *previous; /* Commentaire remplacé */
-
- GLineGenerator **old_inlined; /* Commentaires d'origine ? */
- size_t old_count; /* Nombre de places à restaurer*/
};
@@ -93,6 +81,15 @@ static void g_db_comment_dispose(GDbComment *);
/* Procède à la libération totale de la mémoire. */
static void g_db_comment_finalize(GDbComment *);
+/* Constitue un ensemble de lignes pour un commentaire. */
+static void g_db_comment_define_text_lines(GDbComment *, const char *);
+
+/* Calcule le condensat associé à l'élément vu comme clef. */
+static guint g_db_comment_hash_key(const GDbComment *);
+
+/* Compare deux éléments en tant que clefs. */
+static gboolean g_db_comment_cmp_key(const GDbComment *, const GDbComment *);
+
/* Effectue la comparaison entre deux commentaires enregistrés. */
static gint g_db_comment_cmp(const GDbComment *, const GDbComment *);
@@ -120,19 +117,13 @@ static bool g_db_comment_load(GDbComment *, const bound_value *, size_t);
/* Constitue les champs destinés à une insertion / modification. */
static bool g_db_comment_store(GDbComment *, bound_value **, size_t *);
-/* Associe un contenu formaté supplémentaire à un commentaire. */
-static void g_db_comment_add_rle_string(GDbComment *, const rle_string *);
-
/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
-/* Calcule le nombre de lignes suite à un changement de contenu. */
-static void g_db_comment_update_count_lines(GDbComment *);
-
/* Indique le nombre de ligne prêtes à être générées. */
-static size_t g_db_comment_count_lines(const GDbComment *);
+static size_t g_db_comment_count_lines(GDbComment *);
/* Retrouve l'emplacement correspondant à une position donnée. */
static void g_db_comment_compute_cursor(const GDbComment *, gint, size_t, size_t, GLineCursor **);
@@ -141,7 +132,7 @@ static void g_db_comment_compute_cursor(const GDbComment *, gint, size_t, size_t
static int g_db_comment_contain_cursor(const GDbComment *, size_t, size_t, const GLineCursor *);
/* 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);
+static BufferLineFlags g_db_comment_get_generator_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, const GBinContent *);
@@ -222,6 +213,8 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
item->feature = DBF_COMMENTS;
+ item->hash_key = (hash_db_item_key_fc)g_db_comment_hash_key;
+ item->cmp_key = (cmp_db_item_key_fc)g_db_comment_cmp_key;
item->cmp = (cmp_db_item_fc)g_db_comment_cmp;
item->unpack = (unpack_db_item_fc)g_db_comment_unpack;
@@ -251,8 +244,12 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
static void g_db_comment_init(GDbComment *comment)
{
+ init_vmpa(&comment->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+ comment->type = CET_COUNT;
+ comment->flags = BLF_NONE;
+
comment->text = NULL;
- comment->count = 0;
}
@@ -274,7 +271,7 @@ 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_cursor;
iface->contain = (linegen_contain_fc)g_db_comment_contain_cursor;
- iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags;
+ iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_generator_flags;
iface->print = (linegen_print_fc)g_db_comment_print;
}
@@ -294,13 +291,6 @@ static void g_db_comment_interface_init(GLineGeneratorInterface *iface)
static void g_db_comment_dispose(GDbComment *comment)
{
- size_t i; /* Boucle de parcours */
-
- g_clear_object(&comment->previous);
-
- for (i = 0; i < comment->old_count; i++)
- g_clear_object(&comment->old_inlined[i]);
-
G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
}
@@ -340,9 +330,6 @@ static void g_db_comment_finalize(GDbComment *comment)
unlock_flat_array(&comment->text);
- if (comment->old_inlined != NULL)
- free(comment->old_inlined);
-
G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment));
}
@@ -350,11 +337,12 @@ static void g_db_comment_finalize(GDbComment *comment)
/******************************************************************************
* *
-* Paramètres : addr = adresse inamovible localisant une position. *
-* flags = indentifiants supplémentaires de ligne visée. *
-* repeatable = repétition aux instructions liées ? *
+* Paramètres : addr = adresse inamovible localisant une position. *
+* type = type d'incrustation à respecter pour l'insertion. *
+* flags = indentifiants supplémentaires de ligne visée. *
+* text = contenu textuel associé au commentaire ou NULL. *
* *
-* Description : Crée une définition de commentaire dans une zone de texte. *
+* Description : Crée une définition de commentaire textuel. *
* *
* Retour : Commentaire mis en place ou NULL en cas d'erreur. *
* *
@@ -362,19 +350,59 @@ static void g_db_comment_finalize(GDbComment *comment)
* *
******************************************************************************/
-GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, bool repeatable)
+GDbComment *g_db_comment_new(const vmpa2t *addr, CommentEmbeddingType type, BufferLineFlags flags, const char *text)
{
- GDbComment *result; /* Instance à retourner */
+ GDbComment *result; /* Instance à retourner */
+ bool status; /* Bilan de l'initialisation */
result = g_object_new(G_TYPE_DB_COMMENT, NULL);
- copy_vmpa(&result->addr, addr);
+ status = g_db_comment_fill(result, addr, type, flags, text);
+ if (!status) goto error;
+
+ return result;
+
+ error:
+
+ g_object_unref(G_OBJECT(result));
+
+ return NULL;
+
+}
+
- result->flags = flags;
+/******************************************************************************
+* *
+* Paramètres : addr = adresse inamovible localisant une position. *
+* type = type d'incrustation à respecter pour l'insertion. *
+* flags = indentifiants supplémentaires de ligne visée. *
+* text = contenu textuel associé au commentaire ou NULL. *
+* *
+* Description : Initialise la définition d'un commentaire à incruster. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- result->inlined = true;
+bool g_db_comment_fill(GDbComment *comment, const vmpa2t *addr, CommentEmbeddingType type, BufferLineFlags flags, const char *text)
+{
+ bool result; /* Bilan à retourner */
- result->repeatable = repeatable;
+ /**
+ * Cette fonction est principalement destinée aux initialisations
+ * depuis l'extension Python.
+ */
+
+ result = true;
+
+ copy_vmpa(&comment->addr, addr);
+
+ comment->type = type;
+ comment->flags = flags;
+
+ g_db_comment_define_text_lines(comment, text);
return result;
@@ -383,34 +411,98 @@ GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags,
/******************************************************************************
* *
-* Paramètres : addr = adresse inamovible localisant une position. *
-* flags = indentifiants supplémentaires de ligne visée. *
-* text = commentaire construit ou NULL. *
-* before = précision quant à la position de la zone à définir. *
+* Paramètres : comment = commentaire dont les lignes sont à constituer. *
+* text = contenu textuel associé au commentaire ou NULL. *
* *
-* Description : Crée une définition de commentaire dans une zone de texte. *
+* Description : Constitue un ensemble de lignes pour un commentaire. *
* *
-* Retour : Commentaire mis en place ou NULL en cas d'erreur. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool before)
+static void g_db_comment_define_text_lines(GDbComment *comment, const char *text)
{
- GDbComment *result; /* Instance à retourner */
+ char *tmp; /* Zone de travail modifiable */
+ char **lines; /* Lignes du texte découpé */
+ size_t count; /* Quantité de ces lignes */
+ size_t i; /* Boucle de parcours */
+ rle_string string; /* Fragment de texte à ajouter */
- result = g_object_new(G_TYPE_DB_COMMENT, NULL);
+ if (text != NULL)
+ {
+ tmp = strdup(text);
+
+ tmp = strrpl(tmp, "\r", "");
+
+ lines = strtoka(tmp, "\n", &count);
+
+ lock_flat_array(&comment->text);
+
+ for (i = 0; i < count; i++)
+ {
+ init_dynamic_rle_string(&string, lines[i]);
+
+ add_item_to_flat_array(&comment->text, &string, sizeof(rle_string));
+
+ }
+
+ unlock_flat_array(&comment->text);
+
+ free(lines);
+
+ free(tmp);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = élément de collection à consulter. *
+* *
+* Description : Calcule le condensat associé à l'élément vu comme clef. *
+* *
+* Retour : Condensat associé à l'élément. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- copy_vmpa(&result->addr, addr);
+static guint g_db_comment_hash_key(const GDbComment *comment)
+{
+ guint result; /* Valeur "unique" à renvoyer */
- result->flags = flags;
+ result = hash_vmpa(&comment->addr);
- g_db_comment_add_dynamic_text(result, strdup(text));
+ return result;
- result->inlined = false;
+}
- result->before = before;
+
+/******************************************************************************
+* *
+* Paramètres : a = premier élément de collection à consulter. *
+* b = second élément de collection à consulter. *
+* *
+* Description : Compare deux éléments en tant que clefs. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean g_db_comment_cmp_key(const GDbComment *a, const GDbComment *b)
+{
+ gboolean result; /* Bilan à retourner */
+ int ret; /* Bilan intermédiaire */
+
+ ret = cmp_vmpa(&a->addr, &b->addr);
+
+ result = (ret == 0);
return result;
@@ -440,8 +532,8 @@ static gint g_db_comment_cmp(const GDbComment *a, const GDbComment *b)
if (result == 0)
{
- string_a = g_db_comment_get_text(a);
- string_b = g_db_comment_get_text(b);
+ string_a = g_db_comment_get_text((GDbComment *)a);
+ string_b = g_db_comment_get_text((GDbComment *)b);
if (string_a == NULL && string_b == NULL)
result = 0;
@@ -481,9 +573,9 @@ static gint g_db_comment_cmp(const GDbComment *a, const GDbComment *b)
static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
{
bool result; /* Bilan à retourner */
- uint32_t tmp32; /* Valeur sur 32 bits */
- rle_string string; /* Texte brut récupéré */
uint8_t tmp8; /* Valeur sur 8 bits */
+ uint32_t tmp32; /* Valeur sur 32 bits */
+ rle_string text; /* Texte brut récupéré */
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->unpack(G_DB_ITEM(comment), pbuf);
@@ -492,29 +584,25 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
if (result)
{
- result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true);
- comment->flags = tmp32;
+ result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
+ comment->type = tmp8;
}
if (result)
{
- result = unpack_rle_string(&string, pbuf);
-
- if (!is_rle_string_empty(&string) > 0)
- g_db_comment_add_rle_string(comment, &string);
-
+ result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true);
+ comment->flags = tmp32;
}
if (result)
{
- result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
- comment->inlined = tmp8;
- }
+ setup_empty_rle_string(&text);
+ result = unpack_rle_string(&text, pbuf);
+
+ g_db_comment_define_text_lines(comment, get_rle_string(&text));
+
+ exit_rle_string(&text);
- if (result)
- {
- result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
- comment->repeatable = tmp8;
}
return result;
@@ -546,6 +634,9 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
result = pack_vmpa(&comment->addr, pbuf);
if (result)
+ result = extend_packed_buffer(pbuf, (uint8_t []) { comment->type }, sizeof(uint8_t), true);
+
+ if (result)
result = extend_packed_buffer(pbuf, (uint32_t []) { comment->flags }, sizeof(uint32_t), true);
if (result)
@@ -555,12 +646,6 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
exit_rle_string(&text);
}
- if (result)
- result = extend_packed_buffer(pbuf, (uint8_t []) { comment->inlined }, sizeof(uint8_t), true);
-
- if (result)
- result = extend_packed_buffer(pbuf, (uint8_t []) { comment->repeatable }, sizeof(uint8_t), true);
-
return result;
}
@@ -580,28 +665,40 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
static char *g_db_comment_build_label(GDbComment *comment)
{
-#if 0
- VMPA_BUFFER(loc); /* Indication de position */
- size_t count; /* Nombre d'éléments textuels */
+ char *result; /* Description à retourner */
+ DbItemFlags flags; /* Propriétés de l'élément */
+ const char *text; /* Commentaire associé */
+ const char *prefix; /* Préfixe à ajouter */
- vmpa2_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL);
+ flags = g_db_item_get_flags(G_DB_ITEM(comment));
- lock_flat_array(&comment->text);
- count = count_flat_array_items(comment->text);
- unlock_flat_array(&comment->text);
+ if (flags & DIF_ERASER)
+ asprintf(&result, _("Removed comment"));
+
+ else if (flags & DIF_UPDATED)
+ {
+ text = "...";//get_rle_string(&comment->text);
- if (count == 0)
- asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc);
+ if (text != NULL)
+ asprintf(&result, _("Updated comment: \"%s\""), text);
+ else
+ asprintf(&result, _("Reset comment"));
+ }
else
{
- if (comment->inlined)
- asprintf(&G_DB_ITEM(comment)->label, _("Enter inlined comment at %s"), loc);
+ prefix = _("Created");
+
+ text = "...";//get_rle_string(&comment->text);
+
+ if (text != NULL)
+ asprintf(&result, _("%s comment \"%s\""), prefix, text);
else
- asprintf(&G_DB_ITEM(comment)->label, _("Enter comment area at %s"), loc);
+ asprintf(&result, _("%s empty comment"), prefix);
+
}
-#endif
- return NULL;
+
+ return result;
}
@@ -638,46 +735,30 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
cache = g_loaded_binary_get_disassembly_cache(binary);
- cursor = g_binary_cursor_new();
- g_binary_cursor_update(G_BINARY_CURSOR(cursor), &comment->addr);
+ g_buffer_cache_lock(cache);
- index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
+ switch (comment->type)
+ {
+ case CET_INLINED:
- g_object_unref(G_OBJECT(cursor));
+ cursor = g_binary_cursor_new();
+ g_binary_cursor_update(G_BINARY_CURSOR(cursor), &comment->addr);
- index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+ index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
- if (comment->inlined)
- {
+ g_object_unref(G_OBJECT(cursor));
-#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), BLF_NONE, 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, BLF_NONE, false, false); \
- g_object_unref(G_OBJECT(old)); \
- } \
- \
- }
+ index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
- /* Commentaire principal */
+ g_buffer_cache_delete_type_at(cache, index, G_TYPE_DB_COMMENT, false, false);
- RUN_INLINED_COMMENT(index, comment, comment->previous);
+ if (apply)
+ g_buffer_cache_insert_at(cache, index, G_LINE_GENERATOR(comment), BLF_NONE, false, false);
- /* Renvois répétés */
+ break;
+
+ case CET_REPEATED:
- if (comment->repeatable)
- {
proc = g_loaded_binary_get_processor(binary);
instr = g_arch_processor_find_instr_by_address(proc, &comment->addr);
@@ -685,12 +766,6 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
scount = g_arch_instruction_count_sources(instr);
- if (apply)
- {
- comment->old_count = scount;
- comment->old_inlined = realloc(comment->old_inlined, comment->old_count * sizeof(GLineGenerator *));
- }
-
for (i = 0; i < scount && result; i++)
{
source = g_arch_instruction_get_source(instr, i);
@@ -713,202 +788,37 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
linked = g_buffer_cache_look_for_flag(cache, linked, BLF_HAS_CODE | BLF_IS_LABEL);
- RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]);
-
- unref_instr_link(source);
-
- }
+ g_buffer_cache_delete_type_at(cache, linked, G_TYPE_DB_COMMENT, false, false);
- if (!apply)
- {
- free(comment->old_inlined);
+ if (apply)
+ g_buffer_cache_insert_at(cache, linked, G_LINE_GENERATOR(comment), BLF_NONE, false, false);
- comment->old_inlined = NULL;
- comment->old_count = 0;
+ unref_instr_link(source);
}
g_object_unref(G_OBJECT(proc));
+ break;
- }
-
-
-
- }
-
- else
- {
-
-
-
-
-
-
+ case CET_BEFORE:
+ break;
+ case CET_AFTER:
+ break;
+ case CET_COUNT:
+ assert(false);
+ result = false;
+ break;
}
-
- //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_buffer_cache_unlock(cache);
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 */
- 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 */
- GBufferLine *linked; /* Ligne liée à traiter */
- GDbComment *old; /* Ancien élément à restaurer */
-
- result = true;
-
- /* Recherche de la ligne visée */
-
- buffer = g_loaded_binary_get_disassembled_buffer(binary);
-
- line = g_code_buffer_find_line_by_addr(buffer, &comment->addr, comment->flags, NULL);
- if (line == NULL)
- {
- result = false;
- goto exit_gui;
- }
-
- /* Détermination de l'imprimeur précédent */
-
- if (apply)
- {
- assert(comment->old_count == 0);
-
- comment->old_count = 1;
- comment->oldies = calloc(comment->old_count, sizeof(GDbComment *));
-
- }
-
- /* Applications globales finales */
-
-#define g_code_buffer_update_inlined_comment_dummy(b, l, c, d, o) \
- g_code_buffer_update_inlined_comment(b, l, c, o)
-
- /**
- * Note : on part du principe qu'un commentaire intégré ne peut remplacer qu'un
- * commentaire intégré. Et pareil pour les commentaires en blocs.
- */
-
-#define RUN_COMMENT_ON(ln, idx, func) \
- if (apply) \
- { \
- comment->oldies[idx] = (GDbComment *)g_code_buffer_get_comment_creator(buffer, ln); \
- assert(comment->oldies[idx] == NULL || G_IS_DB_COMMENT(comment->oldies[idx])); \
- assert(comment->oldies[idx] == NULL || comment->oldies[idx]->inlined == comment->inlined); \
- \
- if (is_rle_string_empty(&comment->text)) \
- result = g_code_buffer_delete_lines_comment(buffer, ln); \
- else \
- result = func(buffer, ln, get_rle_string(&comment->text), \
- comment->before, G_OBJECT(comment)); \
- } \
- else \
- { \
- old = comment->oldies[idx]; \
- \
- if (old == NULL) \
- { \
- if (!is_rle_string_empty(&comment->text)) \
- result = g_code_buffer_delete_lines_comment(buffer, ln); \
- else \
- result = true; \
- } \
- else \
- { \
- if (is_rle_string_empty(&old->text)) \
- result = g_code_buffer_delete_lines_comment(buffer, ln); \
- else \
- result = func(buffer, ln, get_rle_string(&old->text), \
- old->before, G_OBJECT(old)); \
- } \
- \
- }
-
- if (comment->inlined)
- {
- /* Traitement d'un commentaire inscrusté */
-
- RUN_COMMENT_ON(line, 0, g_code_buffer_update_inlined_comment_dummy);
-
- /* Traitement des répétitions ? */
-
- if (comment->repeatable/* && result*/)
- {
- proc = g_loaded_binary_get_processor(binary);
-
- range = g_buffer_line_get_range(line);
-
- instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
- assert(instr != NULL);
-
- scount = g_arch_instruction_get_sources(instr, &sources);
-
- if (apply)
- {
- comment->old_count += scount;
- comment->oldies = realloc(comment->oldies, comment->old_count * sizeof(GDbComment *));
- }
-
- 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_code_buffer_find_line_by_addr(buffer, get_mrange_addr(range), BLF_NONE, NULL);
- assert(linked != NULL);
-
- RUN_COMMENT_ON(linked, 1 + i, g_code_buffer_update_inlined_comment_dummy);
-
- }
-
- g_object_unref(G_OBJECT(instr));
-
- g_object_unref(G_OBJECT(proc));
-
- }
-
- }
-
- else
- {
- RUN_COMMENT_ON(line, 0, g_code_buffer_update_comment_area);
- }
-
- g_object_unref(G_OBJECT(line));
-
- exit_gui:
-
- /* TODO g_object_unref(G_OBJECT(buffer));*/
-
- return result;
-#endif
}
@@ -982,40 +892,38 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count);
- result &= load_vmpa(&comment->addr, NULL, values, count);
+ if (result)
+ result = load_vmpa(&comment->addr, NULL, values, count);
if (result)
{
- value = find_bound_value(values, count, "lflags");
+ value = find_bound_value(values, count, "type");
result = (value != NULL && value->type == SQLITE_INTEGER);
if (result)
- comment->flags = value->integer;
+ comment->type = value->integer;
}
- result &= load_rle_string(&string, "text", values, count);
-
- if (result)
- g_db_comment_add_rle_string(comment, &string);
-
if (result)
{
- value = find_bound_value(values, count, "inlined");
- result = (value != NULL && value->type == SQLITE_BOOLEAN);
+ value = find_bound_value(values, count, "line_flags");
+ result = (value != NULL && value->type == SQLITE_INTEGER);
if (result)
- comment->inlined = value->boolean;
+ comment->flags = value->integer;
}
if (result)
{
- value = find_bound_value(values, count, "repeatable");
- result = (value != NULL && value->type == SQLITE_BOOLEAN);
+ result = load_rle_string(&string, "text", values, count);
if (result)
- comment->repeatable = value->boolean;
+ {
+ g_db_comment_define_text_lines(comment, get_rle_string(&string));
+ exit_rle_string(&string);
+ }
}
@@ -1063,7 +971,7 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
value = &(*values)[*count - 1];
- value->cname = "lflags";
+ value->cname = "type";
value->built_name = false;
value->type = SQLITE_INTEGER;
@@ -1071,50 +979,39 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
if (value->has_value)
{
- value->integer = comment->flags;
+ value->integer = comment->type;
value->delete = NULL;
}
- if (value->has_value)
- {
- init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
- status = store_rle_string(&text, "text", values, count);
- exit_rle_string(&text);
- }
-
- if (!status) return false;
-
- *count += 2;
+ *count += 1;
*values = realloc(*values, *count * sizeof(bound_value));
- value = &(*values)[*count - 2];
+ value = &(*values)[*count - 1];
- value->cname = "inlined";
+ value->cname = "line_flags";
value->built_name = false;
- value->type = SQLITE_BOOLEAN;
+ value->type = SQLITE_INTEGER;
value->has_value = (comment != NULL);
if (value->has_value)
{
- value->boolean = comment->inlined;
+ value->integer = comment->flags;
value->delete = NULL;
}
- value = &(*values)[*count - 1];
-
- value->cname = "repeatable";
- value->built_name = false;
- value->type = SQLITE_BOOLEAN;
-
- value->has_value = (comment != NULL);
+ if (comment == NULL)
+ status = store_rle_string(NULL, "text", values, count);
- if (value->has_value)
+ else
{
- value->boolean = comment->repeatable;
- value->delete = NULL;
+ init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
+ status = store_rle_string(&text, "text", values, count);
+ exit_rle_string(&text);
}
+ if (!status) return false;
+
return true;
}
@@ -1122,19 +1019,27 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
/******************************************************************************
* *
-* Paramètres : comment = informations à consulter. *
+* Paramètres : key = clef de comparaison sous forme de localisation. *
+* comment = informations de commentaire à consulter. *
* *
-* Description : Fournit l'adresse associée à un commentaire. *
+* Description : Etablit la comparaison d'une adresse avec un commentaire. *
* *
-* Retour : Adresse mémoire. *
+* Retour : Bilan de la comparaison. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
+int compare_comment_by_addr(const vmpa2t *key, const GDbComment * const *comment)
{
- return &comment->addr;
+ int result; /* Bilan à retourner */
+ const vmpa2t *addr; /* Position du commentaire */
+
+ addr = g_db_comment_get_address(*comment);
+
+ result = cmp_vmpa(key, addr);
+
+ return result;
}
@@ -1143,38 +1048,19 @@ const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
* *
* Paramètres : comment = informations à consulter. *
* *
-* Description : Fournit le commentaire associé à un commentaire. *
+* Description : Fournit l'adresse associée à un commentaire. *
* *
-* Retour : Commentaire existant à libérer après usage ou NULL. *
+* Retour : Adresse mémoire. *
* *
* Remarques : - *
* *
******************************************************************************/
-char *g_db_comment_get_text(GDbComment *comment)
+const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
{
- char *result; /* Chaîne constituée à renvoyer*/
- size_t count; /* Nombre d'éléments textuels */
- size_t i; /* Boucle de parcours */
- rle_string *string; /* Chaîne à consulter */
+ const vmpa2t *result; /* Localisation à retourner */
- result = NULL;
-
- lock_flat_array(&comment->text);
-
- count = count_flat_array_items(comment->text);
-
- for (i = 0; i < count; i++)
- {
- string = get_flat_array_item(comment->text, i, sizeof(rle_string));
-
- assert(!is_rle_string_empty(string));
-
- result = stradd(result, get_rle_string(string));
-
- }
-
- unlock_flat_array(&comment->text);
+ result = &comment->addr;
return result;
@@ -1184,30 +1070,22 @@ char *g_db_comment_get_text(GDbComment *comment)
/******************************************************************************
* *
* Paramètres : comment = informations à consulter. *
-* text = commentaire construit ou NULL. *
* *
-* Description : Associe un contenu supplémentaire à un commentaire. *
+* Description : Indique le type d'incrustation prévue pour un commentaire. *
* *
-* Retour : - *
+* Retour : Incrustation associée au commentaire. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_db_comment_add_dynamic_text(GDbComment *comment, char *text)
+CommentEmbeddingType g_db_comment_get_embedding_type(const GDbComment *comment)
{
- rle_string string; /* Fragment de texte à ajouter */
-
- if (text != NULL)
- {
- init_dynamic_rle_string(&string, text);
+ CommentEmbeddingType result; /* Type à renvoyer */
- g_db_comment_add_rle_string(comment, &string);
+ result = comment->type;
- }
-
- else
- g_db_comment_update_count_lines(comment);
+ return result;
}
@@ -1215,30 +1093,22 @@ void g_db_comment_add_dynamic_text(GDbComment *comment, char *text)
/******************************************************************************
* *
* Paramètres : comment = informations à consulter. *
-* text = commentaire construit ou NULL. *
* *
-* Description : Associe un contenu statique supplémentaire à un commentaire. *
+* Description : Fournit les particularités d'accroche liées à un commentaire.*
* *
-* Retour : - *
+* Retour : Particularités éventuelles pour l'accroche. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_db_comment_add_static_text(GDbComment *comment, const char *text)
+BufferLineFlags g_db_comment_get_flags(const GDbComment *comment)
{
- rle_string string; /* Fragment de texte à ajouter */
+ BufferLineFlags result; /* Type à renvoyer */
- if (text != NULL)
- {
- init_static_rle_string(&string, text);
+ result = comment->flags;
- g_db_comment_add_rle_string(comment, &string);
-
- }
-
- else
- g_db_comment_update_count_lines(comment);
+ return result;
}
@@ -1246,29 +1116,41 @@ void g_db_comment_add_static_text(GDbComment *comment, const char *text)
/******************************************************************************
* *
* Paramètres : comment = informations à consulter. *
-* string = commentaire établi à inétgrer. *
* *
-* Description : Associe un contenu formaté supplémentaire à un commentaire. *
+* Description : Fournit le commentaire associé à un commentaire. *
* *
-* Retour : - *
+* Retour : Commentaire existant à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *string)
+char *g_db_comment_get_text(GDbComment *comment)
{
- /* Extension du contenu */
+ char *result; /* Chaîne constituée à renvoyer*/
+ size_t count; /* Nombre d'éléments textuels */
+ size_t i; /* Boucle de parcours */
+ rle_string *string; /* Chaîne à consulter */
+
+ result = NULL;
lock_flat_array(&comment->text);
- add_item_to_flat_array(&comment->text, string, sizeof(rle_string));
+ count = count_flat_array_items(comment->text);
- unlock_flat_array(&comment->text);
+ for (i = 0; i < count; i++)
+ {
+ string = get_flat_array_item(comment->text, i, sizeof(rle_string));
- /* Mise à jour de la taille de rendu */
+ assert(!is_rle_string_empty(string));
- g_db_comment_update_count_lines(comment);
+ result = stradd(result, get_rle_string(string));
+
+ }
+
+ unlock_flat_array(&comment->text);
+
+ return result;
}
@@ -1281,64 +1163,27 @@ static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *s
/******************************************************************************
* *
-* Paramètres : comment = informations à réactualiser. *
+* Paramètres : comment = générateur à consulter. *
* *
-* Description : Calcule le nombre de lignes suite à un changement de contenu.*
+* Description : Indique le nombre de ligne prêtes à être générées. *
* *
-* Retour : - *
+* Retour : Nombre de lignes devant apparaître au final. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_db_comment_update_count_lines(GDbComment *comment)
+static size_t g_db_comment_count_lines(GDbComment *comment)
{
- char *full; /* Contenu textuel complet */
- char **lines; /* Lignes brutes à représenter */
- GCodingLanguage *lang; /* Langage de sortie préféré */
- size_t i; /* Boucle de parcours */
+ size_t result; /* Quantité à retourner */
- full = g_db_comment_get_text(comment);
-
- if (full == NULL)
- comment->count = 0;
-
- else
- {
- lines = strtoka(full, "\n", &comment->count);
-
- lang = g_asm_language_new();
- g_coding_language_encapsulate_comments(lang, &lines, &comment->count);
- g_object_unref(G_OBJECT(lang));
-
- for (i = 0; i < comment->count; i++)
- free(lines[i]);
-
- if (lines != NULL)
- free(lines);
-
- free(full);
-
- }
-
-}
+ lock_flat_array(&comment->text);
+ result = count_flat_array_items(comment->text);
-/******************************************************************************
-* *
-* 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 : - *
-* *
-******************************************************************************/
+ unlock_flat_array(&comment->text);
-static size_t g_db_comment_count_lines(const GDbComment *comment)
-{
- return comment->count;
+ return result;
}
@@ -1413,7 +1258,7 @@ static int g_db_comment_contain_cursor(const GDbComment *comment, size_t index,
* *
******************************************************************************/
-static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t index, size_t repeat)
+static BufferLineFlags g_db_comment_get_generator_flags(const GDbComment *comment, size_t index, size_t repeat)
{
return BLF_NONE;
@@ -1454,11 +1299,6 @@ static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t in
g_coding_language_encapsulate_comments(lang, &lines, &count);
g_object_unref(G_OBJECT(lang));
- if (count != comment->count)
- printf("full=%s\n", full);
-
- assert(count == comment->count);
-
g_buffer_line_append_text(line, DLC_COMMENTS, SL(lines[repeat]), RTT_COMMENT, NULL);
for (i = 0; i < count; i++)
@@ -1616,13 +1456,12 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
char *msg; /* Message d'erreur */
int ret; /* Bilan de la création */
- sql = "CREATE TABLE Comments (" \
- SQLITE_DB_ITEM_CREATE ", " \
- "%s, " \
- "lflags INTEGER, " \
- SQLITE_RLESTR_CREATE("text") ", " \
- "inlined INTEGER, " \
- "repeatable INTEGER" \
+ sql = "CREATE TABLE Comments (" \
+ SQLITE_DB_ITEM_CREATE ", " \
+ "%s, " \
+ "type INTEGER, " \
+ "line_flags INTEGER, " \
+ SQLITE_RLESTR_CREATE("text") \
");";
addr_fields = create_vmpa_db_table(NULL);
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index 7049b28..fa1644f 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -37,12 +37,25 @@
/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
-#define G_TYPE_DB_COMMENT g_db_comment_get_type()
-#define G_DB_COMMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_comment_get_type(), GDbComment))
-#define G_IS_DB_COMMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_comment_get_type()))
-#define G_DB_COMMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COMMENT, GDbCommentClass))
-#define G_IS_DB_COMMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COMMENT))
-#define G_DB_COMMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COMMENT, GDbCommentClass))
+/* Incrustations possibles pour un commentaire */
+typedef enum _CommentEmbeddingType
+{
+ CET_INLINED, /* En bout de ligne */
+ CET_REPEATED, /* Reproduit à chaque référence*/
+ CET_BEFORE, /* Placé sur une ligne avant */
+ CET_AFTER, /* Placé sur une ligne après */
+
+ CET_COUNT
+
+} CommentEmbeddingType;
+
+
+#define G_TYPE_DB_COMMENT g_db_comment_get_type()
+#define G_DB_COMMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DB_COMMENT, GDbComment))
+#define G_IS_DB_COMMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DB_COMMENT))
+#define G_DB_COMMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COMMENT, GDbCommentClass))
+#define G_IS_DB_COMMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COMMENT))
+#define G_DB_COMMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COMMENT, GDbCommentClass))
/* Commentaire à placer dans du texte quelconque (instance) */
@@ -55,35 +68,38 @@ typedef struct _GDbCommentClass GDbCommentClass;
/* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
GType g_db_comment_get_type(void);
-/* Crée une définition de commentaire dans une zone de texte. */
-GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, bool);
+/* Crée une définition de commentaire textuel. */
+GDbComment *g_db_comment_new(const vmpa2t *, CommentEmbeddingType, BufferLineFlags, const char *);
+
+/* Initialise la définition d'un commentaire à incruster. */
+bool g_db_comment_fill(GDbComment *, const vmpa2t *, CommentEmbeddingType, BufferLineFlags, const char *);
-/* Crée une définition de commentaire dans une zone de texte. */
-GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool);
+/* Etablit la comparaison d'une adresse avec un commentaire. */
+int compare_comment_by_addr(const vmpa2t *, const GDbComment * const *);
/* Fournit l'adresse associée à un commentaire. */
const vmpa2t *g_db_comment_get_address(const GDbComment *);
-/* Fournit le commentaire associé à un commentaire. */
-char *g_db_comment_get_text(GDbComment *);
+/* Indique le type d'incrustation prévue pour un commentaire. */
+CommentEmbeddingType g_db_comment_get_embedding_type(const GDbComment *);
-/* Associe un contenu supplémentaire à un commentaire. */
-void g_db_comment_add_dynamic_text(GDbComment *, char *);
+/* Fournit les particularités d'accroche liées à un commentaire. */
+BufferLineFlags g_db_comment_get_flags(const GDbComment *);
-/* Associe un contenu statique supplémentaire à un commentaire. */
-void g_db_comment_add_static_text(GDbComment *, const char *);
+/* Fournit le commentaire associé à un commentaire. */
+char *g_db_comment_get_text(GDbComment *);
/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
-#define G_TYPE_COMMENT_COLLECTION g_comment_collection_get_type()
-#define G_COMMENT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_comment_collection_get_type(), GCommentCollection))
-#define G_IS_COMMENT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_comment_collection_get_type()))
-#define G_COMMENT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
-#define G_IS_COMMENT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMMENT_COLLECTION))
-#define G_COMMENT_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
+#define G_TYPE_COMMENT_COLLECTION g_comment_collection_get_type()
+#define G_COMMENT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollection))
+#define G_IS_COMMENT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_COMMENT_COLLECTION))
+#define G_COMMENT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
+#define G_IS_COMMENT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMMENT_COLLECTION))
+#define G_COMMENT_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
/* Collection dédiée aux commentaires textuels (instance) */
diff --git a/src/core/collections.c b/src/core/collections.c
index f5bccd7..660c981 100644
--- a/src/core/collections.c
+++ b/src/core/collections.c
@@ -114,7 +114,7 @@ bool load_hard_coded_collection_definitions(void)
REGISTER_COLLECTION(G_TYPE_BM_COLLECTION, DBF_BOOKMARKS);
- //REGISTER_COLLECTION(G_TYPE_COMMENT_COLLECTION, DBF_COMMENTS);
+ REGISTER_COLLECTION(G_TYPE_COMMENT_COLLECTION, DBF_COMMENTS);
//REGISTER_COLLECTION(G_TYPE_MOVE_COLLECTION, DBF_MOVES);
diff --git a/src/format/preload.c b/src/format/preload.c
index dc254b2..c36db93 100644
--- a/src/format/preload.c
+++ b/src/format/preload.c
@@ -24,6 +24,9 @@
#include "preload.h"
+#include <assert.h>
+
+
#include "preload-int.h"
@@ -629,7 +632,7 @@ void _g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
* *
* Description : Recherche un commentaire dans des préchargements. *
* *
-* Retour : Eventuel commenaire retrouvé ou NULL. *
+* Retour : Eventuel commentaire retrouvé ou NULL. *
* *
* Remarques : - *
* *
@@ -640,23 +643,52 @@ GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *ad
GDbComment *result; /* Trouvaille à retourner */
GDbComment **ptr; /* Adresse dans le tableau */
- int cmp_comment_by_addr(const vmpa2t *key, const GDbComment * const *comment)
+ ptr = find_item_in_flat_array(info->comments, sizeof(GDbComment *),
+ (__compar_fn_t)compare_comment_by_addr, addr);
+
+ if (ptr != NULL)
{
- const vmpa2t *caddr; /* Position du commentaire */
+ result = *ptr;
+ g_object_ref(G_OBJECT(result));
+ }
+ else
+ result = NULL;
- caddr = g_db_comment_get_address(*comment);
+ return result;
- return cmp_vmpa(key, caddr);
+}
- }
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à consulter. *
+* addr = localisation du commentaire recherché. *
+* index = indice du commentaire retrouvé ou NULL. [OUT] *
+* *
+* Description : Recherche un commentaire dans des préchargements. *
+* *
+* Retour : Eventuel commentaire retrouvé ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *addr, size_t *index)
+{
+ GDbComment *result; /* Trouvaille à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
ptr = find_item_in_flat_array(info->comments, sizeof(GDbComment *),
- (__compar_fn_t)cmp_comment_by_addr, addr);
+ (__compar_fn_t)compare_comment_by_addr, addr);
if (ptr != NULL)
{
result = *ptr;
g_object_ref(G_OBJECT(result));
+
+ if (index != NULL)
+ *index = ((void **)ptr - info->comments);
+
}
else
result = NULL;
@@ -668,6 +700,37 @@ GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *ad
/******************************************************************************
* *
+* Paramètres : info = instance à mettre à jour. *
+* index = indice du commentaire à remplacer. *
+* comment = commentaire à venir associer. *
+* *
+* Description : Remplace un commentaire par un autre à un emplacement donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_replace_comment_at(GPreloadInfo *info, size_t index, GDbComment *comment)
+{
+#ifndef NDEBUG
+ GDbComment **current; /* Commentaire à remplacer */
+#endif
+
+#ifndef NDEBUG
+ current = get_flat_array_item(info->comments, index, sizeof(GDbComment *));
+
+ assert(cmp_vmpa(g_db_comment_get_address(*current), g_db_comment_get_address(comment)));
+#endif
+
+ rpl_item_in_flat_array(info->comments, index, &comment, sizeof(GDbComment *));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : info = instance à consulter. *
* *
* Description : Indique la quantité de commentaires préchargés disponibles. *
diff --git a/src/format/preload.h b/src/format/preload.h
index 5557253..587c35d 100644
--- a/src/format/preload.h
+++ b/src/format/preload.h
@@ -102,6 +102,12 @@ void _g_preload_info_add_comment(GPreloadInfo *, GDbComment *);
/* Recherche un commentaire dans des préchargements. */
GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *, const vmpa2t *);
+/* Recherche un commentaire dans des préchargements. */
+GDbComment *g_preload_info_find_comment_at(GPreloadInfo *, const vmpa2t *, size_t *);
+
+/* Remplace un commentaire par un autre à un emplacement donné. */
+void g_preload_info_replace_comment_at(GPreloadInfo *, size_t, GDbComment *);
+
/* Indique la quantité de commentaires préchargés disponibles. */
size_t _g_preload_info_count_comments(const GPreloadInfo *);