diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/db/items/comment.c | 793 | ||||
| -rw-r--r-- | src/analysis/db/items/comment.h | 60 | ||||
| -rw-r--r-- | src/core/collections.c | 2 | ||||
| -rw-r--r-- | src/format/preload.c | 77 | ||||
| -rw-r--r-- | src/format/preload.h | 6 | 
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 *);  | 
