summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-08-06 17:38:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-08-06 17:38:09 (GMT)
commite59544bb61b0043d82946918ece144cae2749d53 (patch)
tree553447beaf577d573076a2bdf3f694f134c8d8e6
parentebfc6a8ebcef2b42beb6ef12e4946bb2f73f2723 (diff)
Fixed many bugs in the code cache and the width tracker objects.
-rw-r--r--src/analysis/db/items/comment.c36
-rw-r--r--src/glibext/gbuffercache.c102
-rw-r--r--src/glibext/gbuffercache.h5
-rw-r--r--src/glibext/gwidthtracker.c67
4 files changed, 138 insertions, 72 deletions
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 8155fc5..b879d08 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -654,24 +654,24 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
if (comment->inlined)
{
-#define RUN_INLINED_COMMENT(idx, new, old) \
- if (apply) \
- { \
- old = g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \
- \
- g_buffer_cache_insert_at(cache, idx, G_LINE_GENERATOR(new), false, false); \
- \
- } \
- else \
- { \
- g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \
- \
- if (old != NULL) \
- { \
- g_buffer_cache_insert_at(cache, idx, old, false, false); \
- g_object_unref(G_OBJECT(old)); \
- } \
- \
+#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)); \
+ } \
+ \
}
/* Commentaire principal */
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
index 7293e7c..866d696 100644
--- a/src/glibext/gbuffercache.c
+++ b/src/glibext/gbuffercache.c
@@ -72,7 +72,7 @@ static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFl
static void release_cache_info(cache_info *);
/* Ajoute un générateur aux informations sur une ligne. */
-static void extend_cache_info(cache_info *, GLineGenerator *);
+static void extend_cache_info(cache_info *, GLineGenerator *, BufferLineFlags);
/* Retire un générateur aux informations d'une ligne. */
static void remove_from_cache_info(cache_info *, GLineGenerator *);
@@ -217,6 +217,7 @@ static void release_cache_info(cache_info *info)
* *
* Paramètres : info = informations concernant une ligne à actualiser. *
* generator = générateur à associer à toutes les lignes. *
+* flags = propriétés supplémentaires à associer à la ligne.*
* *
* Description : Ajoute un générateur aux informations sur une ligne. *
* *
@@ -226,7 +227,7 @@ static void release_cache_info(cache_info *info)
* *
******************************************************************************/
-static void extend_cache_info(cache_info *info, GLineGenerator *generator)
+static void extend_cache_info(cache_info *info, GLineGenerator *generator, BufferLineFlags flags)
{
generator_link first; /* Générateur déjà en place */
generator_link *new; /* Nouveau générateur placé */
@@ -259,6 +260,17 @@ static void extend_cache_info(cache_info *info, GLineGenerator *generator)
reset_cache_info_line(info);
+ /**
+ * On peut rajouter des indications, mais, en cas de retrait d'un générateur,
+ * on ne saura pas forcément lesquelles retirer puisque qu'on ne trace pas
+ * leur origine.
+ *
+ * On considère donc que seul le premier générateur (le principal) a le
+ * droit de poser des fanions.
+ */
+
+ assert(flags == BLF_NONE);
+
}
@@ -319,6 +331,8 @@ static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
info->generators = (generator_link *)realloc(info->generators,
--info->count * sizeof(generator_link));
+ g_object_unref(G_OBJECT(generator));
+
break;
}
@@ -592,7 +606,7 @@ static void g_buffer_cache_init(GBufferCache *cache)
static void g_buffer_cache_dispose(GBufferCache *cache)
{
size_t i; /* Boucle de parcours #1 */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
size_t j; /* Boucle de parcours #2 */
if (cache->content != NULL)
@@ -636,7 +650,7 @@ static void g_buffer_cache_dispose(GBufferCache *cache)
static void g_buffer_cache_finalize(GBufferCache *cache)
{
size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
for (i = 0; i < cache->used; i++)
{
@@ -817,7 +831,7 @@ GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache)
static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator)
{
size_t result; /* Compteur à retourner */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
size_t i; /* Boucle de parcours */
result = 0;
@@ -853,6 +867,7 @@ static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t inde
* Paramètres : cache = instance GLib à modifier. *
* index = point d'insertion, puis de sauvegarde. *
* generator = générateur à insérer dans les lignes. *
+* flags = propriétés supplémentaires à associer à la ligne.*
* before = précise l'emplacement final des nouvelles lignes.*
* after = précise l'emplacement final des nouvelles lignes.*
* *
@@ -864,7 +879,7 @@ static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t inde
* *
******************************************************************************/
-void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
+void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, BufferLineFlags flags, bool before, bool after)
{
#ifndef NDEBUG
GLineCursor *gen_cursor; /* Position du générateur */
@@ -880,26 +895,27 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
#ifndef NDEBUG
- g_line_generator_compute_cursor(generator, 0, index, 0, &gen_cursor);
+ if (!before && !after)
+ {
+ g_line_generator_compute_cursor(generator, 0, index, 0, &gen_cursor);
- get_cache_info_cursor(&cache->lines[index], index, 0, &line_cursor);
+ get_cache_info_cursor(&cache->lines[index], index, 0, &line_cursor);
- ret = g_line_cursor_compare(gen_cursor, line_cursor);
+ ret = g_line_cursor_compare(gen_cursor, line_cursor);
- g_object_unref(G_OBJECT(gen_cursor));
- g_object_unref(G_OBJECT(line_cursor));
+ g_object_unref(G_OBJECT(gen_cursor));
+ g_object_unref(G_OBJECT(line_cursor));
- ///////////////////////////////////////
- if (ret != 0) return;
+ assert(ret == 0);
- assert(ret == 0);
+ }
#endif
/* Cas particulier d'ajout en fin de cache... */
if (after && (index + 1) == cache->used)
{
- g_buffer_cache_append(cache, generator, BLF_NONE);
+ g_buffer_cache_append(cache, generator, flags);
goto gbcia_done;
}
@@ -932,10 +948,10 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
if (before || after)
{
- memmove(&cache->lines[index], &cache->lines[index + needed], (cache->used - index) * sizeof(cache_info));
+ memmove(&cache->lines[index + needed], &cache->lines[index], (cache->used - index) * sizeof(cache_info));
for (i = 0; i < needed; i++)
- init_cache_info(&cache->lines[index + i], generator, i, BLF_NONE);
+ init_cache_info(&cache->lines[index + i], generator, i, flags);
cache->used += needed;
@@ -947,7 +963,7 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
else
{
- extend_cache_info(&cache->lines[index], generator);
+ extend_cache_info(&cache->lines[index], generator, flags);
g_width_tracker_update(cache->tracker, index);
@@ -980,6 +996,42 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
/******************************************************************************
* *
+* Paramètres : cache = instance GLib à modifier. *
+* index = point de suppression. *
+* *
+* Description : Retire une ligne du tampon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_cache_delete_at(GBufferCache *cache, size_t index)
+{
+ cache_info *info; /* Accès direct à une ligne */
+
+ assert(index < cache->used);
+
+ info = &cache->lines[index];
+
+ release_cache_info(info);
+
+ if ((index + 1) < cache->used)
+ memmove(&cache->lines[index], &cache->lines[index + 1],
+ (cache->used - index - 1) * sizeof(cache_info));
+
+ cache->used--;
+
+ g_width_tracker_update_deleted(cache->tracker, index, index);
+
+ g_signal_emit_by_name(cache, "size-changed", false, index, 1);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : cache = instance GLib à modifier. *
* index = point d'insertion, puis de sauvegarde. *
* type = type de générateurs à retirer des lignes visées. *
@@ -997,7 +1049,7 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
{
GLineGenerator *result; /* Prédécesseur à retourner */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
generator_link *link; /* Accès simplifié */
size_t i; /* Boucle de parcours */
size_t count; /* Emplacements occupés */
@@ -1122,7 +1174,7 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe
size_t count; /* Nombre de lignes générées */
size_t index; /* Point d'insertion */
size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
count = g_line_generator_count_lines(generator);
@@ -1157,8 +1209,6 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe
cache->used += count;
- g_object_unref(G_OBJECT(generator));
-
g_width_tracker_update_added(cache->tracker, index, count);
g_signal_emit_by_name(cache, "size-changed", true, index, count);
@@ -1184,7 +1234,7 @@ void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerato
{
size_t index; /* Point d'insertion */
size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
size_t added; /* Nombre d'ajouts effectués */
assert(count >= cache->used);
@@ -1245,7 +1295,7 @@ void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerato
void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
{
size_t i; /* Boucle de parcours #1 */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
size_t j; /* Boucle de parcours #2 */
size_t removed; /* Nombre de retraits effectués*/
@@ -1326,7 +1376,7 @@ void g_buffer_cache_get_line_cursor(const GBufferCache *cache, size_t index, gin
BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *cache, size_t index)
{
BufferLineFlags result; /* Somme à renvoyer */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
const generator_link *generator; /* Générateur retenu */
size_t i; /* Boucle de parcours */
@@ -1433,7 +1483,7 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s
gint y; /* Point de départ en ordonnée */
bool wait_selection; /* Sélection déjà passée ? */
size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès directe à une ligne */
+ cache_info *info; /* Accès direct à une ligne */
line_width_summary summary; /* Résumé concis des largeurs */
GBufferLine *line; /* Ligne à venir dessiner */
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
index 7a0d250..077c5f9 100644
--- a/src/glibext/gbuffercache.h
+++ b/src/glibext/gbuffercache.h
@@ -76,7 +76,10 @@ size_t g_buffer_cache_count_lines(const GBufferCache *);
GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *);
/* Insère un générateur dans des lignes à une position donnée. */
-void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, bool, bool);
+void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, BufferLineFlags, bool, bool);
+
+/* Retire une ligne du tampon. */
+void g_buffer_cache_delete_at(GBufferCache *, size_t);
/* Retire un type de générateur de lignes. */
GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *, size_t, GType, bool, bool);
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index 44a7ff0..e116a85 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -613,8 +613,14 @@ static void g_width_tracker_update_ranges(GWidthTracker *tracker, size_t start,
for (i = start; i < tracker->count; i++)
{
+#ifndef NDEBUG
+ if ((i + 1) < tracker->count)
+ assert((tracker->portions[i].last + 1) == tracker->portions[i + 1].first);
+#endif
+
tracker->portions[i].first += diff;
tracker->portions[i].last += diff;
+
}
}
@@ -746,7 +752,6 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
{
size_t current; /* Indice de portion visée */
common_metrics *portion; /* Portion sélectionnée */
- size_t next; /* Prochaine portion à décaller*/
size_t i; /* Boucle de parcours */
size_t dest; /* Destination d'une recopie */
size_t src; /* Source d'une recopie */
@@ -786,7 +791,9 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
g_width_tracker_reset_widths(tracker, current);
- next = current + 1;
+ /* Suite impérative : accroître les indices ! */
+
+ g_width_tracker_update_ranges(tracker, current + 1, count);
/* Un découpage s'impose-t-il quelque part ? */
@@ -810,14 +817,12 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
memmove(&tracker->portions[dest], &tracker->portions[src],
(tracker->count - src - 1) * sizeof(common_metrics));
- next++;
-
/* Insertion au début */
if (i == portion->first)
{
assert(i == index);
- tracker->portions[current + 1].first = portion->first + 1;
+ tracker->portions[current + 1].first = i + 1;
tracker->portions[current + 1].last = portion->last;
tracker->portions[current + 1].cached = false;
@@ -839,6 +844,8 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
}
+ assert((tracker->portions[current].last + 1) == tracker->portions[current + 1].first);
+
/* Mise à jour des largeurs */
g_width_tracker_reset_widths(tracker, current);
@@ -849,10 +856,6 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
}
- /* Suite impérative : accroître les indices ! */
-
- g_width_tracker_update_ranges(tracker, next, 1);
-
}
@@ -879,6 +882,7 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
size_t dest; /* Destination du transfert */
bool keep_last; /* Conservation de portion #2 */
size_t src; /* Source du transfert */
+ size_t update; /* Début de la série en rafale */
first = g_width_tracker_find_metrics(tracker, start);
assert(first < tracker->count);
@@ -890,18 +894,19 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
/* Suppression de portions inutiles ? */
- keep_first = (tracker->portions[first].first < start || end < tracker->portions[first].last);
+ keep_first = (tracker->portions[first].first < start);
dest = (keep_first ? first + 1 : first);
- keep_last = (tracker->portions[last].first < start || end < tracker->portions[last].last);
+ keep_last = (end < tracker->portions[last].last);
src = (keep_last ? last : last + 1);
if (src > dest)
{
- memmove(&tracker->portions[dest], &tracker->portions[src],
- (tracker->count - src) * sizeof(common_metrics));
+ if (src < tracker->count)
+ memmove(&tracker->portions[dest], &tracker->portions[src],
+ (tracker->count - src) * sizeof(common_metrics));
tracker->count -= (src - dest);
@@ -914,10 +919,11 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
if (keep_first && keep_last && last != first)
{
- tracker->portions[first].last = tracker->portions[dest].last;
+ tracker->portions[first].last = tracker->portions[first + 1].last;
- memmove(&tracker->portions[first + 1], &tracker->portions[first + 2],
- (tracker->count - first - 2) * sizeof(common_metrics));
+ if ((first - 2) < tracker->count)
+ memmove(&tracker->portions[first + 1], &tracker->portions[first + 2],
+ (tracker->count - first - 2) * sizeof(common_metrics));
tracker->count--;
@@ -930,29 +936,36 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
/* Avant toute chose : faire décroître les indices ! */
- if (keep_first)
+ if (keep_first && keep_last)
{
- if (end < tracker->portions[first].last)
- tracker->portions[first].last -= diff;
- else
- tracker->portions[first].last = start - 1;
+ tracker->portions[first].last -= diff;
+ update = first + 1;
}
- if (keep_last && last != first)
+ else
{
- tracker->portions[dest].first = end + 1;
- tracker->portions[dest].last -= diff;
+ if (keep_first)
+ {
+ tracker->portions[first].last = start - 1;
+ update = first + 1;
+ }
+ else
+ update = first;
+
+ if (keep_last)
+ tracker->portions[update].first = end + 1;
+
}
- g_width_tracker_update_ranges(tracker, keep_last ? dest + 1 : dest, -diff);
+ g_width_tracker_update_ranges(tracker, update, -diff);
/* Mise à jour des largeurs aux extrémités */
if (keep_first)
g_width_tracker_reset_widths(tracker, first);
- if (keep_last && last != first)
- g_width_tracker_reset_widths(tracker, dest);
+ if (keep_last && !keep_first)
+ g_width_tracker_reset_widths(tracker, update);
}