From 83faef9c8f78b20cb031af686f763cfb215cf9d7 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 11 Sep 2019 23:25:13 +0200
Subject: Reactivated bookmarks for disassembled code.

---
 plugins/pychrysalide/analysis/db/constants.c      |  38 ++++++
 plugins/pychrysalide/analysis/db/constants.h      |   3 +
 plugins/pychrysalide/analysis/db/item.c           | 137 +++++++++++++++++++++-
 plugins/pychrysalide/analysis/db/items/bookmark.c |   7 +-
 src/analysis/db/collection.c                      |  10 +-
 src/analysis/db/item-int.h                        |   9 ++
 src/analysis/db/item.c                            |  68 +++++++++++
 src/analysis/db/item.h                            |  18 +++
 src/analysis/db/items/bookmark.c                  |  71 ++++++++---
 src/analysis/db/misc/rlestr.c                     |  13 ++
 src/arch/vmpa.c                                   |  24 +---
 src/glibext/gbuffercache.h                        |   5 +
 12 files changed, 356 insertions(+), 47 deletions(-)

diff --git a/plugins/pychrysalide/analysis/db/constants.c b/plugins/pychrysalide/analysis/db/constants.c
index 9685ba6..fb30c7e 100644
--- a/plugins/pychrysalide/analysis/db/constants.c
+++ b/plugins/pychrysalide/analysis/db/constants.c
@@ -25,6 +25,7 @@
 #include "constants.h"
 
 
+#include <analysis/db/item.h>
 #include <analysis/db/server.h>
 
 
@@ -36,6 +37,43 @@
 *                                                                             *
 *  Paramètres  : type = type dont le dictionnaire est à compléter.            *
 *                                                                             *
+*  Description : Définit les constantes pour les éléments de base de données. *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_db_item_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "NONE", DIF_NONE);
+    if (result) result = add_const_to_group(values, "ERASER", DIF_ERASER);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group(type, true, "DbItemFlags", values, "Properties of a database item.");
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
 *  Description : Définit les constantes pour les serveurs de données.         *
 *                                                                             *
 *  Retour      : true en cas de succès de l'opération, false sinon.           *
diff --git a/plugins/pychrysalide/analysis/db/constants.h b/plugins/pychrysalide/analysis/db/constants.h
index a2fc49e..cb7edf4 100644
--- a/plugins/pychrysalide/analysis/db/constants.h
+++ b/plugins/pychrysalide/analysis/db/constants.h
@@ -31,6 +31,9 @@
 
 
 
+/* Définit les constantes pour les éléments de base de données. */
+bool define_db_item_constants(PyTypeObject *);
+
 /* Définit les constantes pour les serveurs de données. */
 bool define_hub_server_constants(PyTypeObject *);
 
diff --git a/plugins/pychrysalide/analysis/db/item.c b/plugins/pychrysalide/analysis/db/item.c
index 981e0c0..bbaa21b 100644
--- a/plugins/pychrysalide/analysis/db/item.c
+++ b/plugins/pychrysalide/analysis/db/item.c
@@ -32,17 +32,109 @@
 #include <analysis/db/item.h>
 
 
+#include "constants.h"
 #include "../../access.h"
 #include "../../helpers.h"
 
 
 
+/* Ajoute une propriété à un élément de base de données. */
+static PyObject *py_db_item_add_flag(PyObject *, PyObject *);
+
+/* Retire une propriété à un élément de base de données. */
+static PyObject *py_db_item_remove_flag(PyObject *, PyObject *);
+
 /* Indique si l'élément contient des données à oublier ou non. */
 static PyObject *py_db_item_get_volatile(PyObject *, void *);
 
 /* Définit si l'élément contient des données à oublier ou non. */
 static int py_db_item_set_volatile(PyObject *, PyObject *, void *);
 
+/* Indique les propriétés particulières appliquées à l'élément. */
+static PyObject *py_db_item_get_flags(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = serveur à manipuler.                                  *
+*                args = arguments d'appel non utilisés ici.                   *
+*                                                                             *
+*  Description : Ajoute une propriété à un élément de base de données.        *
+*                                                                             *
+*  Retour      : None.                                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_add_flag(PyObject *self, PyObject *args)
+{
+    unsigned int flag;                      /* Propriété à traiter         */
+    int ret;                                /* Bilan de lecture des args.  */
+    GDbItem *item;                          /* Elément à manipuler         */
+
+#define DB_ITEM_ADD_FLAG_METHOD PYTHON_METHOD_DEF                   \
+(                                                                   \
+    add_flag, "$self, flag, /",                                     \
+    METH_VARARGS, py_db_item,                                       \
+    "Add a property to a database item."                            \
+    "\n"                                                            \
+    "This property is one of the values listed in the"              \
+    " of pychrysalide.analysis.db.DbItem.DbItemFlags enumeration."  \
+)
+
+    ret = PyArg_ParseTuple(args, "I", &flag);
+    if (!ret) return NULL;
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    g_db_item_add_flag(item, flag);
+
+    Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = serveur à manipuler.                                  *
+*                args = arguments d'appel non utilisés ici.                   *
+*                                                                             *
+*  Description : Retire une propriété à un élément de base de données.        *
+*                                                                             *
+*  Retour      : None.                                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_remove_flag(PyObject *self, PyObject *args)
+{
+    unsigned int flag;                      /* Propriété à traiter         */
+    int ret;                                /* Bilan de lecture des args.  */
+    GDbItem *item;                          /* Elément à manipuler         */
+
+#define DB_ITEM_REMOVE_FLAG_METHOD PYTHON_METHOD_DEF                \
+(                                                                   \
+    remove_flag, "$self, flag, /",                                  \
+    METH_VARARGS, py_db_item,                                       \
+    "Remove a property from a database item."                       \
+    "\n"                                                            \
+    "This property is one of the values listed in the"              \
+    " of pychrysalide.analysis.db.DbItem.DbItemFlags enumeration."  \
+)
+
+    ret = PyArg_ParseTuple(args, "I", &flag);
+    if (!ret) return NULL;
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    g_db_item_remove_flag(item, flag);
+
+    Py_RETURN_NONE;
+
+}
 
 
 /******************************************************************************
@@ -107,6 +199,43 @@ static int py_db_item_set_volatile(PyObject *self, PyObject *value, void *closur
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Indique les propriétés particulières appliquées à l'élément. *
+*                                                                             *
+*  Retour      : Propriétés actives de l'élément.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_get_flags(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GDbItem *item;                          /* Elément à consulter         */
+    DbItemFlags flags;                      /* Propriétés de l'élément     */
+
+#define DB_ITEM_FLAGS_ATTRIB PYTHON_GET_DEF_FULL                \
+(                                                               \
+    flags, py_db_item,                                          \
+    "Properties of the database item, provided as a mask"       \
+    " of pychrysalide.analysis.db.DbItem.DbItemFlags values."   \
+)
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    flags = g_db_item_get_flags(item);
+
+    result = cast_with_constants_group(get_python_db_item_type(), "DbItemFlags", flags);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Fournit un accès à une définition de type à diffuser.        *
@@ -120,17 +249,18 @@ static int py_db_item_set_volatile(PyObject *self, PyObject *value, void *closur
 PyTypeObject *get_python_db_item_type(void)
 {
     static PyMethodDef py_db_item_methods[] = {
+        DB_ITEM_ADD_FLAG_METHOD,
+        DB_ITEM_REMOVE_FLAG_METHOD,
         { NULL }
     };
 
     static PyGetSetDef py_db_item_getseters[] = {
-
         {
             "volatile", py_db_item_get_volatile, py_db_item_set_volatile,
             "Define if a Database item can be forgotten.", NULL
         },
+        DB_ITEM_FLAGS_ATTRIB,
         { NULL }
-
     };
 
     static PyTypeObject py_db_item_type = {
@@ -183,6 +313,9 @@ bool ensure_python_db_item_is_registered(void)
         if (!register_class_for_pygobject(dict, G_TYPE_DB_ITEM, type, &PyGObject_Type))
             return false;
 
+        if (!define_db_item_constants(type))
+            return false;
+
     }
 
     return true;
diff --git a/plugins/pychrysalide/analysis/db/items/bookmark.c b/plugins/pychrysalide/analysis/db/items/bookmark.c
index 8a33357..783efa6 100644
--- a/plugins/pychrysalide/analysis/db/items/bookmark.c
+++ b/plugins/pychrysalide/analysis/db/items/bookmark.c
@@ -147,7 +147,12 @@ static int py_db_bookmark_init(PyObject *self, PyObject *args, PyObject *kwds)
     "    DbBookmark(addr, comment=None)"                                        \
     "\n"                                                                        \
     "Where addr is a location of type pychrysalide.arch.vmpa and"               \
-    " comment is a string or None."
+    " comment is a string or None.\n"                                           \
+    "\n"                                                                        \
+    "An empty comment is not enough to delete a bookmark for a given address;"  \
+    " the *ERASER* flag from the pychrysalide.analysis.db.DbItem.DbItemFlags"   \
+    " enumeration must be explicitly add to the item by a call to the"          \
+    " pychrysalide.analysis.db.DbItem.add_flag() function."
 
     result = -1;
 
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index cdc91aa..0f4e771 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -375,14 +375,10 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
             if (result)
             {
                 if (collec->binary != NULL && g_db_item_is_active(item))
-                    result = g_db_item_apply(item, collec->binary);
+                    g_db_item_apply(item, collec->binary);
 
-                if (result && db != NULL)
-                    result = g_db_collection_store_item(collec, item, db);
-
-                /* En cas d'erreur, il faut retirer l'élément */
-                if (!result)
-                    _g_db_collection_remove_item(collec, item, true, false);
+                if (db != NULL)
+                    g_db_collection_store_item(collec, item, db);
 
             }
 
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 3a5f47d..923ea3a 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -71,8 +71,17 @@ struct _GDbItem
 
     char *label;                            /* Représentation humaine      */
 
+    union
+    {
+        DbItemFlags flags;                  /* Propriétés de l'élément     */
+        gint atomic_flags;                  /* Accès atomique              */
+
+    };
+
     bool is_volatile;                       /* Pas besoin de sauvegarde ?  */
 
+    bool broken;                            /* Changement applicable ?     */
+
 };
 
 /* Base d'un élément pour collection générique (classe) */
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index 2bbc683..c59ef64 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -596,6 +596,74 @@ bool g_db_item_is_volatile(const GDbItem *item)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = base d'éléments à mettre à jour.                      *
+*                flag = type de propriété à traiter.                          *
+*                                                                             *
+*  Description : Ajoute une propriété à un élément de base de données.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_item_add_flag(GDbItem *item, DbItemFlags flag)
+{
+    g_atomic_int_add(&item->atomic_flags, flag);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = base d'éléments à mettre à jour.                      *
+*                flag = type de propriété à traiter.                          *
+*                                                                             *
+*  Description : Retire une propriété à un élément de base de données.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_item_remove_flag(GDbItem *item, DbItemFlags flag)
+{
+    gint mask;                              /* Masque à appliquer          */
+
+    mask = flag;
+    mask = ~mask;
+
+    g_atomic_int_and(&item->atomic_flags, mask);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = base d'éléments à consulter.                          *
+*                                                                             *
+*  Description : Indique les propriétés particulières appliquées à l'élément. *
+*                                                                             *
+*  Retour      : Propriétés actives de l'élément.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+DbItemFlags g_db_item_get_flags(const GDbItem *item)
+{
+    DbItemFlags result;                     /* Fanions à retourner         */
+
+    result = g_atomic_int_get(&item->atomic_flags);
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                       MANIPULATIONS AVEC UNE BASE DE DONNEES                       */
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
index 6644507..3444b73 100644
--- a/src/analysis/db/item.h
+++ b/src/analysis/db/item.h
@@ -40,6 +40,15 @@
 typedef struct _GLoadedBinary GLoadedBinary;
 
 
+/* Propriétés particulières pour un élément */
+typedef enum _DbItemFlags
+{
+    DIF_NONE    = (0 << 0),                 /* Propriétés par défaut       */
+    DIF_ERASER  = (1 << 0),                 /* Suppression de l'effet      */
+
+} DbItemFlags;
+
+
 #define G_TYPE_DB_ITEM               g_db_item_get_type()
 #define G_DB_ITEM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_item_get_type(), GDbItem))
 #define G_IS_DB_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_item_get_type()))
@@ -103,6 +112,15 @@ void g_db_item_set_volatile(GDbItem *, bool);
 /* Indique si l'élément contient des données à oublier ou non. */
 bool g_db_item_is_volatile(const GDbItem *);
 
+/* Ajoute une propriété à un élément de base de données. */
+void g_db_item_add_flag(GDbItem *, DbItemFlags);
+
+/* Retire une propriété à un élément de base de données. */
+void g_db_item_remove_flag(GDbItem *, DbItemFlags);
+
+/* Indique les propriétés particulières appliquées à l'élément. */
+DbItemFlags g_db_item_get_flags(const GDbItem *);
+
 
 
 /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 266b04c..819528d 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -34,6 +34,7 @@
 
 #include "../collection-int.h"
 #include "../item-int.h"
+#include "../../../glibext/gbinarycursor.h"
 
 
 
@@ -206,6 +207,9 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass)
 
 static void g_db_bookmark_init(GDbBookmark *bookmark)
 {
+    init_vmpa(&bookmark->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+    init_dynamic_rle_string(&bookmark->comment, NULL);
 
 }
 
@@ -440,37 +444,60 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark)
 
 static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool *prev, bool set)
 {
-    return false;
-#if 0
     bool result;                            /* Bilan à faire remonter      */
-    GCodeBuffer *buffer;                    /* Tampon de lignes à traiter  */
+    GBufferCache *cache;                    /* Tampon d'impression colorée */
+    GLineCursor *cursor;                    /* Emplacement dans un tampon  */
+    size_t index;                           /* Indice de ligne à traiter   */
     GBufferLine *line;                      /* Ligne de tampon à marquer   */
 
-    result = true;
+    result = false;
+
+    cache = g_loaded_binary_get_disassembled_cache(binary);
+    if (cache == NULL) goto exit;
+
+    g_buffer_cache_lock(cache);
+
+    /* Recherche de la ligne concernée */
+
+    cursor = g_binary_cursor_new();
+    g_binary_cursor_update(G_BINARY_CURSOR(cursor), &bookmark->addr);
 
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
+    index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
 
-    line = g_code_buffer_find_line_by_addr(buffer, &bookmark->addr, BLF_HAS_CODE, NULL);
-    if (line == NULL)
+    g_object_unref(G_OBJECT(cursor));
+
+    line = g_buffer_cache_find_line_by_index(cache, index);
+
+    /* Application du changement */
+
+    result = (line != NULL);
+
+    if (result)
     {
-        result = false;
-        goto exit;
-    }
+        *prev = g_buffer_line_get_flags(line) & BLF_BOOKMARK;
 
-    *prev = g_buffer_line_get_flags(line) & BLF_BOOKMARK;
+        if (set)
+            g_buffer_line_add_flag(line, BLF_BOOKMARK);
 
-    if (set)
-        g_buffer_line_add_flag(line, BLF_BOOKMARK);
+        else
+            g_buffer_line_remove_flag(line, BLF_BOOKMARK);
 
-    else
-        g_buffer_line_remove_flag(line, BLF_BOOKMARK);
+        g_object_unref(G_OBJECT(line));
+
+        g_buffer_cache_throw_update_at_index(cache, index);
+
+    }
 
-    g_object_unref(G_OBJECT(line));
+    /* Sortie */
+
+    g_buffer_cache_unlock(cache);
+
+    g_object_unref(G_OBJECT(cache));
 
  exit:
 
     return result;
-#endif
+
 }
 
 
@@ -490,8 +517,11 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool
 static bool g_db_bookmark_apply(GDbBookmark *bookmark, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
+    DbItemFlags flags;                      /* Propriétés de l'élément     */
 
-    result = g_db_bookmark_run(bookmark, binary, &bookmark->prev_state, true);
+    flags = g_db_item_get_flags(G_DB_ITEM(bookmark));
+
+    result = g_db_bookmark_run(bookmark, binary, &bookmark->prev_state, (flags & DIF_ERASER) == 0);
 
     return result;
 
@@ -514,9 +544,12 @@ static bool g_db_bookmark_apply(GDbBookmark *bookmark, GLoadedBinary *binary)
 static bool g_db_bookmark_cancel(GDbBookmark *bookmark, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
+    DbItemFlags flags;                      /* Propriétés de l'élément     */
+
+    flags = g_db_item_get_flags(G_DB_ITEM(bookmark));
 
     if (!bookmark->prev_state)
-        result = g_db_bookmark_run(bookmark, binary, (bool []) { 0 }, false);
+        result = g_db_bookmark_run(bookmark, binary, (bool []) { 0 }, (flags & DIF_ERASER) != 0);
     else
         result = true;
 
diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c
index f26c146..0fe182b 100644
--- a/src/analysis/db/misc/rlestr.c
+++ b/src/analysis/db/misc/rlestr.c
@@ -105,6 +105,9 @@ void init_static_rle_string(rle_string *str, const char *data)
 
 void dup_into_rle_string(rle_string *str, const char *data)
 {
+    if (str->data != NULL)
+        unset_rle_string(str);
+
     if (data != NULL)
     {
         str->data = strdup(data);
@@ -144,6 +147,11 @@ void set_dynamic_rle_string(rle_string *str, char *data)
         str->length = strlen(data);
         str->dynamic = true;
     }
+    else
+    {
+        str->data = NULL;
+        str->length = 0;
+    }
 
 }
 
@@ -172,6 +180,11 @@ void set_static_rle_string(rle_string *str, const char *data)
         str->length = strlen(data);
         str->dynamic = false;
     }
+    else
+    {
+        str->data = NULL;
+        str->length = 0;
+    }
 
 }
 
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index a2a3ba5..70ea52b 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -813,36 +813,24 @@ bool store_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size
     asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : "");
     value->built_name = true;
 
+    value->type = SQLITE_INT64;
+
     value->has_value = (addr != NULL);
 
     if (value->has_value)
-    {
-        if (addr->physical != VMPA_NO_PHYSICAL)
-        {
-            value->type = SQLITE_INT64;
-            value->integer64 = addr->physical;
-        }
-        else
-            value->type = SQLITE_NULL;
-    }
+        value->integer64 = addr->physical;
 
     value = &(*values)[*count - 1];
 
     asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : "");
     value->built_name = true;
 
+    value->type = SQLITE_INT64;
+
     value->has_value = (addr != NULL);
 
     if (value->has_value)
-    {
-        if (addr->virtual != VMPA_NO_VIRTUAL)
-        {
-            value->type = SQLITE_INT64;
-            value->integer64 = addr->virtual;
-        }
-        else
-            value->type = SQLITE_NULL;
-    }
+        value->integer64 = addr->virtual;
 
     return true;
 
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
index 8059357..0086b38 100644
--- a/src/glibext/gbuffercache.h
+++ b/src/glibext/gbuffercache.h
@@ -99,6 +99,11 @@ void g_buffer_cache_get_line_cursor(const GBufferCache *, size_t, gint, GLineCur
 /* Détermine l'ensemble des propriétés attachées à une ligne. */
 BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t);
 
+#define g_buffer_cache_lock(c)
+#define g_buffer_cache_unlock(c)
+
+#define g_buffer_cache_throw_update_at_index(c, i) // check locked
+
 /* Retrouve une ligne au sein d'un tampon avec un indice. */
 GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *, size_t);
 
-- 
cgit v0.11.2-87-g4458