diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-04-19 19:25:04 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-04-19 19:25:04 (GMT) |
commit | c177597d6da5dedb32aa176e8370db8ffb7f87aa (patch) | |
tree | 26f7eb2702ba4aa3dfd7267d74fe78ad79791a8c /src/analysis/db/items | |
parent | 35f37c72e9d81e478395914da6c10b3c546761a7 (diff) |
Handled static strings as well as dynamic strings in comments.
Diffstat (limited to 'src/analysis/db/items')
-rw-r--r-- | src/analysis/db/items/bookmark.c | 2 | ||||
-rw-r--r-- | src/analysis/db/items/comment.c | 300 | ||||
-rw-r--r-- | src/analysis/db/items/comment.h | 10 |
3 files changed, 268 insertions, 44 deletions
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 9d3b691..0db847b 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -604,7 +604,7 @@ const char *g_db_bookmark_get_comment(const GDbBookmark *bookmark) void g_db_bookmark_set_comment(GDbBookmark *bookmark, const char *comment) { - set_rle_string(&bookmark->comment, comment); + dup_into_rle_string(&bookmark->comment, comment); } 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); + + } } diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h index 03d1bff..ee68491 100644 --- a/src/analysis/db/items/comment.h +++ b/src/analysis/db/items/comment.h @@ -58,7 +58,7 @@ typedef struct _GDbCommentClass GDbCommentClass; 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, const char *, bool); +GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, bool); /* Crée une définition de commentaire dans une zone de texte. */ GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool); @@ -67,7 +67,13 @@ GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, const vmpa2t *g_db_comment_get_address(GDbComment *); /* Fournit le commentaire associé à un commentaire. */ -const char *g_db_comment_get_text(const GDbComment *); +char *g_db_comment_get_text(GDbComment *); + +/* Associe un contenu supplémentaire à un commentaire. */ +void g_db_comment_add_dynamic_text(GDbComment *, char *); + +/* Associe un contenu statique supplémentaire à un commentaire. */ +void g_db_comment_add_static_text(GDbComment *, const char *); |