summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-09-07 22:11:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-09-07 22:11:49 (GMT)
commitf663a08007095e58f60fcf9a815a8b3d31b87c83 (patch)
tree80da49384da78cb9f1b7f81e23e638e5d1dc054e /src
parent39ceed9ed4e4484919f9eecc35d0b51372e5a233 (diff)
Rewritten some code managing comments.
Diffstat (limited to 'src')
-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
5 files changed, 431 insertions, 507 deletions
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 *);