summaryrefslogtreecommitdiff
path: root/src/analysis/db/items/comment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/items/comment.c')
-rw-r--r--src/analysis/db/items/comment.c300
1 files changed, 259 insertions, 41 deletions
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index b43c1e6..beec629 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -36,6 +36,7 @@
#include "../collection-int.h"
#include "../item-int.h"
#include "../../human/asm/lang.h"
+#include "../../../common/array.h"
#include "../../../common/extstr.h"
#include "../../../glibext/linegen-int.h"
@@ -52,10 +53,8 @@ struct _GDbComment
vmpa2t addr; /* Adresse du commentaire */
BufferLineFlags flags; /* Identification de l'accroche*/
- rle_string text; /* Contenu du commentaire */
-
- char **lines; /* Lignes brutes à représenter */
- size_t count; /* Quantité de ces lignes */
+ flat_array_t *text; /* Contenu du commentaire */
+ size_t count; /* Quantité de lignes affichées*/
bool inlined; /* Intégration dans une ligne ?*/
@@ -99,7 +98,7 @@ static gint g_db_comment_cmp(GDbComment *, GDbComment *, bool);
static bool g_db_comment_unpack(GDbComment *, packed_buffer *);
/* Exporte la définition d'un commentaire dans un flux réseau. */
-static bool g_db_comment_pack(const GDbComment *, packed_buffer *);
+static bool g_db_comment_pack(GDbComment *, packed_buffer *);
/* Construit la description humaine d'un commentaire. */
static void g_db_comment_build_label(GDbComment *);
@@ -114,19 +113,22 @@ static bool g_db_comment_apply(GDbComment *, GLoadedBinary *);
static bool g_db_comment_cancel(GDbComment *, GLoadedBinary *);
/* Constitue les champs destinés à une insertion / modification. */
-static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **, size_t *);
+static bool g_db_comment_prepare_db_statement(GDbComment *, bound_value **, size_t *);
/* Charge les valeurs utiles pour un commentaire. */
static bool g_db_comment_load(GDbComment *, const bound_value *, size_t);
-/* Définit le commentaire associé à un commentaire. */
-static void g_db_comment_set_text(GDbComment *, const char *);
+/* 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 *);
@@ -253,7 +255,7 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
static void g_db_comment_init(GDbComment *comment)
{
- comment->lines = NULL;
+ comment->text = NULL;
comment->count = 0;
}
@@ -298,12 +300,6 @@ static void g_db_comment_dispose(GDbComment *comment)
{
size_t i; /* Boucle de parcours */
- for (i = 0; i < comment->count; i++)
- free(comment->lines[i]);
-
- if (comment->lines != NULL)
- free(comment->lines);
-
for (i = 0; i < comment->old_count; i++)
g_object_unref(G_OBJECT(comment->old_inlined[i]));
@@ -329,7 +325,25 @@ static void g_db_comment_dispose(GDbComment *comment)
static void g_db_comment_finalize(GDbComment *comment)
{
- exit_rle_string(&comment->text);
+ size_t count; /* Nombre d'éléments textuels */
+ size_t i; /* Boucle de parcours */
+ rle_string *string; /* Chaîne à traiter */
+
+ 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, 0, sizeof(rle_string));
+
+ exit_rle_string(string);
+
+ rem_item_from_flat_array(&comment->text, 0, sizeof(rle_string));
+
+ }
+
+ unlock_flat_array(&comment->text);
G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment));
@@ -340,7 +354,6 @@ static void g_db_comment_finalize(GDbComment *comment)
* *
* Paramètres : addr = adresse inamovible localisant une position. *
* flags = indentifiants supplémentaires de ligne visée. *
-* text = commentaire construit ou NULL. *
* repeatable = repétition aux instructions liées ? *
* *
* Description : Crée une définition de commentaire dans une zone de texte. *
@@ -351,7 +364,7 @@ static void g_db_comment_finalize(GDbComment *comment)
* *
******************************************************************************/
-GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool repeatable)
+GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, bool repeatable)
{
GDbComment *result; /* Instance à retourner */
@@ -361,8 +374,6 @@ GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags,
result->flags = flags;
- g_db_comment_set_text(result, text);
-
result->inlined = true;
result->repeatable = repeatable;
@@ -397,7 +408,7 @@ GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, con
result->flags = flags;
- g_db_comment_set_text(result, text);
+ g_db_comment_add_dynamic_text(result, strdup(text));
result->inlined = false;
@@ -425,11 +436,32 @@ GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, con
static gint g_db_comment_cmp(GDbComment *a, GDbComment *b, bool with)
{
gint result; /* Bilan de la comparaison */
+ char *string_a; /* Texte du commentaire A */
+ char *string_b; /* Texte du commentaire B */
result = cmp_vmpa_by_phy(&a->addr, &b->addr);
if (result == 0)
- result = cmp_rle_string(&a->text, &b->text);
+ {
+ string_a = g_db_comment_get_text(a);
+ string_b = g_db_comment_get_text(b);
+
+ if (string_a == NULL && string_b == NULL)
+ result = 0;
+
+ else if (string_a != NULL && string_b == NULL)
+ result = 1;
+
+ else if (string_a == NULL && string_b != NULL)
+ result = -1;
+
+ else
+ result = strcmp(string_a, string_b);
+
+ if (string_a != NULL) free(string_a);
+ if (string_b != NULL) free(string_b);
+
+ }
if (result == 0)
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->cmp(G_DB_ITEM(a), G_DB_ITEM(b), with);
@@ -456,6 +488,7 @@ 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 */
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->unpack(G_DB_ITEM(comment), pbuf);
@@ -470,7 +503,13 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
}
if (result)
- result = unpack_rle_string(&comment->text, pbuf);
+ {
+ result = unpack_rle_string(&string, pbuf);
+
+ if (!is_rle_string_empty(&string) > 0)
+ g_db_comment_add_rle_string(comment, &string);
+
+ }
if (result)
{
@@ -502,9 +541,10 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
* *
******************************************************************************/
-static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf)
+static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
{
bool result; /* Bilan à retourner */
+ rle_string text; /* Texte brut récupéré */
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->pack(G_DB_ITEM(comment), pbuf);
@@ -515,7 +555,11 @@ static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf)
result = extend_packed_buffer(pbuf, (uint32_t []) { comment->flags }, sizeof(uint32_t), true);
if (result)
- result = pack_rle_string(&comment->text, pbuf);
+ {
+ init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
+ result = pack_rle_string(&text, pbuf);
+ exit_rle_string(&text);
+ }
if (result)
result = extend_packed_buffer(pbuf, (uint8_t []) { comment->inlined }, sizeof(uint8_t), true);
@@ -543,10 +587,15 @@ static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf)
static void g_db_comment_build_label(GDbComment *comment)
{
VMPA_BUFFER(loc); /* Indication de position */
+ size_t count; /* Nombre d'éléments textuels */
vmpa2_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL);
- if (is_rle_string_empty(&comment->text))
+ lock_flat_array(&comment->text);
+ count = count_flat_array_items(comment->text);
+ unlock_flat_array(&comment->text);
+
+ if (count == 0)
asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc);
else
@@ -917,10 +966,11 @@ static bool g_db_comment_cancel(GDbComment *comment, GLoadedBinary *binary)
* *
******************************************************************************/
-static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_value **values, size_t *count)
+static bool g_db_comment_prepare_db_statement(GDbComment *comment, bound_value **values, size_t *count)
{
bool status; /* Bilan d'opération initiale */
bound_value *value; /* Valeur à éditer / définir */
+ rle_string text; /* Texte brut récupéré */
status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->prepare_stmt(G_DB_ITEM(comment), values, count);
if (!status) return false;
@@ -939,7 +989,10 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v
value->integer = comment->flags;
value->delete = NULL;
- status &= prepare_db_statement_for_rle_string(&comment->text, "text", values, count);
+ init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
+ status &= prepare_db_statement_for_rle_string(&text, "text", values, count);
+ exit_rle_string(&text);
+
if (!status) return false;
*count += 2;
@@ -984,6 +1037,7 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
{
bool result; /* Bilan à faire remonter */
const bound_value *value; /* Valeur à éditer / définir */
+ rle_string string; /* Texte brut récupéré */
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count);
@@ -999,7 +1053,10 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
}
- result &= load_rle_string(&comment->text, "text", values, count);
+ result &= load_rle_string(&string, "text", values, count);
+
+ if (result)
+ g_db_comment_add_rle_string(comment, &string);
if (result)
{
@@ -1051,15 +1108,38 @@ const vmpa2t *g_db_comment_get_address(GDbComment *comment)
* *
* Description : Fournit le commentaire associé à un commentaire. *
* *
-* Retour : Commentaire existant ou NULL. *
+* Retour : Commentaire existant à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_db_comment_get_text(const GDbComment *comment)
+char *g_db_comment_get_text(GDbComment *comment)
{
- return get_rle_string(&comment->text);
+ 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);
+
+ count = count_flat_array_items(comment->text);
+
+ for (i = 0; i < count; i++)
+ {
+ string = get_flat_array_item(comment->text, 0, sizeof(rle_string));
+
+ assert(!is_rle_string_empty(string));
+
+ result = stradd(result, get_rle_string(string));
+
+ }
+
+ unlock_flat_array(&comment->text);
+
+ return result;
}
@@ -1069,7 +1149,7 @@ const char *g_db_comment_get_text(const GDbComment *comment)
* Paramètres : comment = informations à consulter. *
* text = commentaire construit ou NULL. *
* *
-* Description : Définit le commentaire associé à un commentaire. *
+* Description : Associe un contenu supplémentaire à un commentaire. *
* *
* Retour : - *
* *
@@ -1077,19 +1157,81 @@ const char *g_db_comment_get_text(const GDbComment *comment)
* *
******************************************************************************/
-static void g_db_comment_set_text(GDbComment *comment, const char *text)
+void g_db_comment_add_dynamic_text(GDbComment *comment, char *text)
{
- GCodingLanguage *lang; /* Langage de sortie préféré */
+ rle_string string; /* Fragment de texte à ajouter */
+
+ if (text != NULL)
+ {
+ init_dynamic_rle_string(&string, text);
+
+ g_db_comment_add_rle_string(comment, &string);
- set_rle_string(&comment->text, text);
+ }
+
+ else
+ g_db_comment_update_count_lines(comment);
+
+}
- lang = g_asm_language_new();
- comment->lines = strtoka(text, "\n", &comment->count);
+/******************************************************************************
+* *
+* Paramètres : comment = informations à consulter. *
+* text = commentaire construit ou NULL. *
+* *
+* Description : Associe un contenu statique supplémentaire à un commentaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- g_coding_language_encapsulate_comments(lang, &comment->lines, &comment->count);
+void g_db_comment_add_static_text(GDbComment *comment, const char *text)
+{
+ rle_string string; /* Fragment de texte à ajouter */
- g_object_unref(G_OBJECT(lang));
+ if (text != NULL)
+ {
+ init_static_rle_string(&string, text);
+
+ g_db_comment_add_rle_string(comment, &string);
+
+ }
+
+ else
+ g_db_comment_update_count_lines(comment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = informations à consulter. *
+* string = commentaire établi à inétgrer. *
+* *
+* Description : Associe un contenu formaté supplémentaire à un commentaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *string)
+{
+ /* Extension du contenu */
+
+ lock_flat_array(&comment->text);
+
+ add_item_to_flat_array(&comment->text, string, sizeof(rle_string));
+
+ unlock_flat_array(&comment->text);
+
+ /* Mise à jour de la taille de rendu */
+
+ g_db_comment_update_count_lines(comment);
}
@@ -1102,6 +1244,51 @@ static void g_db_comment_set_text(GDbComment *comment, const char *text)
/******************************************************************************
* *
+* Paramètres : comment = informations à réactualiser. *
+* *
+* Description : Calcule le nombre de lignes suite à un changement de contenu.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_update_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 */
+
+ 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);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : comment = générateur à consulter. *
* *
* Description : Indique le nombre de ligne prêtes à être générées. *
@@ -1206,7 +1393,38 @@ static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t
static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t index, size_t repeat)
{
- g_buffer_line_append_text(line, BLC_COMMENTS, SL(comment->lines[repeat]), RTT_COMMENT, NULL);
+ char *full; /* Contenu textuel complet */
+ size_t count; /* Quantité de ces lignes */
+ char **lines; /* Lignes brutes à représenter */
+ GCodingLanguage *lang; /* Langage de sortie préféré */
+ size_t i; /* Boucle de parcours */
+
+ full = g_db_comment_get_text(comment);
+
+ if (full != NULL)
+ {
+ lines = strtoka(full, "\n", &count);
+
+ lang = g_asm_language_new();
+ 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, BLC_COMMENTS, SL(lines[repeat]), RTT_COMMENT, NULL);
+
+ for (i = 0; i < count; i++)
+ free(lines[i]);
+
+ if (lines != NULL)
+ free(lines);
+
+ free(full);
+
+ }
}