From 8d8e5c02096f59a7227308a591fc5050ea5d92ff Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 14 Mar 2016 00:59:29 +0100 Subject: Given more flexibility to the field names of locations in XML databases. --- ChangeLog | 23 +++++++++++++++++++++++ src/analysis/db/collection.c | 40 ++++++++++++++++++++++++++-------------- src/analysis/db/items/bookmark.c | 8 ++++---- src/analysis/db/items/comment.c | 26 ++++++++++++++++---------- src/analysis/db/items/switcher.c | 20 ++++++++++++-------- src/analysis/db/misc/rlestr.c | 6 ++++-- src/analysis/db/misc/timestamp.c | 6 ++++-- src/arch/vmpa.c | 36 +++++++++++++++++++++++++++--------- src/arch/vmpa.h | 10 +++++----- src/common/sqlite.c | 36 ++++++++++++++++++++++++++++++++++++ src/common/sqlite.h | 12 +++++++++++- src/gtkext/gtkextstatusbar.c | 6 ++++++ 12 files changed, 174 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3628c4..d098f3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +16-03-14 Cyrille Bagard + + * src/analysis/db/collection.c: + Update code and fix some memory leaks. + + * src/analysis/db/items/bookmark.c: + * src/analysis/db/items/comment.c: + * src/analysis/db/items/switcher.c: + * src/analysis/db/misc/rlestr.c: + * src/analysis/db/misc/timestamp.c: + Update code. + + * src/arch/vmpa.c: + * src/arch/vmpa.h: + Give more flexibility to the field names of locations in XML databases. + + * src/common/sqlite.c: + * src/common/sqlite.h: + Provide a way to delete a list of bound values. + + * src/gtkext/gtkextstatusbar.c: + Disable some functions of the old status bar. + 16-03-13 Cyrille Bagard * configure.ac: diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index aa7591e..09d9c90 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -949,11 +949,11 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) int native_type; /* Type de valeur dans la base */ GDbItem *new; /* Nouvel élément à insérer */ - if (!g_db_collection_setup_load(collec, &values, &count)) - return false; - result = false; + if (!g_db_collection_setup_load(collec, &values, &count)) + goto gdclai_building_values; + /* Préparation de la requête */ sql = strdup("SELECT "); @@ -1074,6 +1074,10 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) free(sql); + gdclai_building_values: + + free_all_bound_values(values, count); + return result; } @@ -1104,11 +1108,11 @@ static bool g_db_collection_store_item(const GDbCollection *collec, const GDbIte int ret; /* Bilan d'un appel à SQLite */ int index; /* Indice de valeur attachée */ - if (!g_db_item_prepare_db_statement(item, &values, &count)) - return false; - result = false; + if (!g_db_item_prepare_db_statement(item, &values, &count)) + goto gdcsi_building_values; + /* Préparation de la requête */ sql = strdup("INSERT INTO "); @@ -1212,6 +1216,10 @@ static bool g_db_collection_store_item(const GDbCollection *collec, const GDbIte free(sql); + gdcsi_building_values: + + free_all_bound_values(values, count); + return result; } @@ -1244,11 +1252,11 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons int index; /* Indice de valeur attachée */ const bound_value *timestamp; /* Valeur de l'horodatage */ - if (!g_db_item_prepare_db_statement(item, &values, &count)) - return false; - result = false; + if (!g_db_item_prepare_db_statement(item, &values, &count)) + goto gdcsui_building_values; + /* Préparation de la requête */ sql = strdup("UPDATE "); @@ -1290,7 +1298,7 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons if (ret != SQLITE_OK) { fprintf(stderr, "Can't prepare UPDATE statment '%s' (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); - goto gdcsi_exit; + goto gdcsui_exit; } /* Attribution des valeurs */ @@ -1307,7 +1315,7 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons { fprintf(stderr, "Can't bind value for parameter nb %d in '%s' (ret=%d): %s\n", index - 1, sql, ret, sqlite3_errmsg(db)); - goto gdcsi_exit; + goto gdcsui_exit; } for (i = 0; i < count; i++) @@ -1353,7 +1361,7 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons { fprintf(stderr, "Can't bind value for parameter nb %d in '%s' (ret=%d): %s\n", index - 1, sql, ret, sqlite3_errmsg(db)); - goto gdcsi_exit; + goto gdcsui_exit; } } @@ -1365,17 +1373,21 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons if (ret != SQLITE_DONE) { fprintf(stderr, "UPDATE statement '%s' didn't return DONE (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); - goto gdcsi_exit; + goto gdcsui_exit; } sqlite3_finalize(stmt); result = true; - gdcsi_exit: + gdcsui_exit: free(sql); + gdcsui_building_values: + + free_all_bound_values(values, count); + return result; } diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 4c93faf..c8da383 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -510,7 +510,7 @@ static bool g_db_bookmark_prepare_db_statement(const GDbBookmark *bookmark, boun status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->prepare_stmt(G_DB_ITEM(bookmark), values, count); if (!status) return false; - status = prepare_vmpa_db_statement(&bookmark->addr, values, count); + status = prepare_vmpa_db_statement(&bookmark->addr, NULL, values, count); if (!status) return false; status &= prepare_db_statement_for_rle_string(&bookmark->comment, "comment", values, count); @@ -541,7 +541,7 @@ static bool g_db_bookmark_load(GDbBookmark *bookmark, const bound_value *values, result = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->load(G_DB_ITEM(bookmark), values, count); - result &= load_vmpa(&bookmark->addr, values, count); + result &= load_vmpa(&bookmark->addr, NULL, values, count); result &= load_rle_string(&bookmark->comment, "comment", values, count); @@ -752,7 +752,7 @@ static bool g_bookmark_collection_create_db_table(const GBookmarkCollection *col sql = "CREATE TABLE Bookmarks (" \ SQLITE_DB_ITEM_CREATE ", " \ - SQLITE_VMPA_CREATE ", " \ + SQLITE_SIMPLE_VMPA_CREATE ", " \ SQLITE_RLESTR_CREATE("comment") \ ");"; @@ -790,7 +790,7 @@ static bool g_bookmark_collection_setup_load(GBookmarkCollection *collec, bound_ values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!setup_load_for_vmpa(NULL, NULL, values, count)) return false; if (!setup_load_of_rle_string(NULL, "comment", values, count)) diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index b4a1dc0..8b9c25f 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -728,7 +728,7 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->prepare_stmt(G_DB_ITEM(comment), values, count); if (!status) return false; - status = prepare_vmpa_db_statement(&comment->addr, values, count); + status = prepare_vmpa_db_statement(&comment->addr, NULL, values, count); if (!status) return false; *count += 1; @@ -736,7 +736,8 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v value = &(*values)[*count - 1]; - value->name = "flags"; + value->cname = "flags"; + value->built_name = false; value->type = SQLITE_INTEGER; value->integer = comment->flags; value->delete = NULL; @@ -749,14 +750,16 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v value = &(*values)[*count - 2]; - value->name = "inlined"; + value->cname = "inlined"; + value->built_name = false; value->type = SQLITE_BOOLEAN; value->boolean = comment->inlined; value->delete = NULL; value = &(*values)[*count - 1]; - value->name = "repeatable"; + value->cname = "repeatable"; + value->built_name = false; value->type = SQLITE_BOOLEAN; value->boolean = comment->repeatable; value->delete = NULL; @@ -787,7 +790,7 @@ 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, values, count); + result &= load_vmpa(&comment->addr, NULL, values, count); if (result) { @@ -1028,7 +1031,7 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle sql = "CREATE TABLE Comments (" \ SQLITE_DB_ITEM_CREATE ", " \ - SQLITE_VMPA_CREATE ", " \ + SQLITE_SIMPLE_VMPA_CREATE ", " \ "flags INTEGER, " \ SQLITE_RLESTR_CREATE("text") ", " \ "inlined INTEGER, " \ @@ -1070,7 +1073,7 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!setup_load_for_vmpa(NULL, NULL, values, count)) return false; *count += 1; @@ -1078,7 +1081,8 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va value = &(*values)[*count - 1]; - value->name = "flags"; + value->cname = "flags"; + value->built_name = false; value->type = SQLITE_INTEGER; if (!setup_load_of_rle_string(NULL, "text", values, count)) @@ -1089,12 +1093,14 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va value = &(*values)[*count - 2]; - value->name = "inlined"; + value->cname = "inlined"; + value->built_name = false; value->type = SQLITE_BOOLEAN; value = &(*values)[*count - 1]; - value->name = "repeatable"; + value->cname = "repeatable"; + value->built_name = false; value->type = SQLITE_BOOLEAN; return true; diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 6497e41..de5fd36 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -648,7 +648,7 @@ static bool g_db_switcher_prepare_db_statement(const GDbSwitcher *switcher, boun status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->prepare_stmt(G_DB_ITEM(switcher), values, count); if (!status) return false; - status = prepare_vmpa_db_statement(&switcher->addr, values, count); + status = prepare_vmpa_db_statement(&switcher->addr, NULL, values, count); if (!status) return false; *count += 2; @@ -656,14 +656,16 @@ static bool g_db_switcher_prepare_db_statement(const GDbSwitcher *switcher, boun value = &(*values)[*count - 2]; - value->name = "op_index"; + value->cname = "op_index"; + value->built_name = false; value->type = SQLITE_INTEGER; value->integer = switcher->index; value->delete = NULL; value = &(*values)[*count - 1]; - value->name = "type"; + value->cname = "type"; + value->built_name = false; value->type = SQLITE_INTEGER; value->integer = switcher->display; value->delete = NULL; @@ -694,7 +696,7 @@ static bool g_db_switcher_load(GDbSwitcher *switcher, const bound_value *values, result = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->load(G_DB_ITEM(switcher), values, count); - result &= load_vmpa(&switcher->addr, values, count); + result &= load_vmpa(&switcher->addr, NULL, values, count); if (result) { @@ -865,7 +867,7 @@ static bool g_switcher_collection_create_db_table(const GSwitcherCollection *col sql = "CREATE TABLE Switchers (" \ SQLITE_DB_ITEM_CREATE ", " \ - SQLITE_VMPA_CREATE ", " \ + SQLITE_SIMPLE_VMPA_CREATE ", " \ "op_index INTEGER, " \ "type INTEGER" \ ");"; @@ -905,7 +907,7 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_ values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!setup_load_for_vmpa(NULL, NULL, values, count)) return false; *count += 2; @@ -913,12 +915,14 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_ value = &(*values)[*count - 2]; - value->name = "op_index"; + value->cname = "op_index"; + value->built_name = false; value->type = SQLITE_INTEGER; value = &(*values)[*count - 1]; - value->name = "type"; + value->cname = "type"; + value->built_name = false; value->type = SQLITE_INTEGER; return true; diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c index 3f45df6..a4647c1 100644 --- a/src/analysis/db/misc/rlestr.c +++ b/src/analysis/db/misc/rlestr.c @@ -267,7 +267,8 @@ bool prepare_db_statement_for_rle_string(const rle_string *str, const char *name *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = name; + value->cname = name; + value->built_name = false; value->type = (get_rle_string(str) != NULL ? SQLITE_TEXT : SQLITE_NULL); value->cstring = get_rle_string(str); value->delete = SQLITE_STATIC; @@ -299,7 +300,8 @@ bool setup_load_of_rle_string(const rle_string *str, const char *name, bound_val *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = name; + value->cname = name; + value->built_name = false; value->type = SQLITE_NATIVE; return true; diff --git a/src/analysis/db/misc/timestamp.c b/src/analysis/db/misc/timestamp.c index d3ff474..3772a70 100644 --- a/src/analysis/db/misc/timestamp.c +++ b/src/analysis/db/misc/timestamp.c @@ -197,7 +197,8 @@ bool prepare_db_statement_for_timestamp(const timestamp_t *timestamp, const char *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = name; + value->cname = name; + value->built_name = false; value->type = SQLITE_INT64; value->integer64 = *timestamp; @@ -228,7 +229,8 @@ bool setup_load_of_timestamp(const timestamp_t *timestamp, const char *name, bou *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = name; + value->cname = name; + value->built_name = false; value->type = SQLITE_INT64; return true; diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index 3b1bcec..7231c2c 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -553,6 +553,7 @@ vmpa2t *string_to_vmpa_virt(const char *buffer) /****************************************************************************** * * * Paramètres : addr = localisation dont la définition est à consulter. * +* base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à compléter. [OUT] * * count = nombre de descriptions renseignées. [OUT] * * * @@ -564,7 +565,7 @@ vmpa2t *string_to_vmpa_virt(const char *buffer) * * ******************************************************************************/ -bool setup_load_for_vmpa(const vmpa2t *addr, bound_value **values, size_t *count) +bool setup_load_for_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ @@ -573,12 +574,14 @@ bool setup_load_for_vmpa(const vmpa2t *addr, bound_value **values, size_t *count value = &(*values)[*count - 2]; - value->name = "phys"; + asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); + value->built_name = true; value->type = SQLITE_NATIVE; value = &(*values)[*count - 1]; - value->name = "virt"; + asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); + value->built_name = true; value->type = SQLITE_NATIVE; return true; @@ -589,6 +592,7 @@ bool setup_load_for_vmpa(const vmpa2t *addr, bound_value **values, size_t *count /****************************************************************************** * * * Paramètres : addr = localisation dont la définition est à définir. * +* base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à consulter. * * count = nombre de descriptions renseignées. * * * @@ -600,11 +604,17 @@ bool setup_load_for_vmpa(const vmpa2t *addr, bound_value **values, size_t *count * * ******************************************************************************/ -bool load_vmpa(vmpa2t *addr, const bound_value *values, size_t count) +bool load_vmpa(vmpa2t *addr, const char *base, const bound_value *values, size_t count) { + char *name; /* Désignation complète */ const bound_value *value; /* Valeur à intégrer */ - value = find_bound_value(values, count, "phys"); + asprintf(&name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); + + value = find_bound_value(values, count, name); + + free(name); + if (value == NULL) return false; switch (value->type) @@ -623,7 +633,12 @@ bool load_vmpa(vmpa2t *addr, const bound_value *values, size_t count) } - value = find_bound_value(values, count, "virt"); + asprintf(&name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); + + value = find_bound_value(values, count, name); + + free(name); + if (value == NULL) return false; switch (value->type) @@ -650,6 +665,7 @@ bool load_vmpa(vmpa2t *addr, const bound_value *values, size_t count) /****************************************************************************** * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * +* base = tronc commun pour les champs de la base de données. * * values = couples de champs et de valeurs à lier. [OUT] * * count = nombre de ces couples. [OUT] * * * @@ -661,14 +677,15 @@ bool load_vmpa(vmpa2t *addr, const bound_value *values, size_t count) * * ******************************************************************************/ -bool prepare_vmpa_db_statement(const vmpa2t *addr, bound_value **values, size_t *count) +bool prepare_vmpa_db_statement(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = "phys"; + asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); + value->built_name = true; if (addr->physical != VMPA_NO_PHYSICAL) { @@ -683,7 +700,8 @@ bool prepare_vmpa_db_statement(const vmpa2t *addr, bound_value **values, size_t *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; - value->name = "virt"; + asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); + value->built_name = true; if (addr->virtual != VMPA_NO_VIRTUAL) { diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index cfb9ab5..9905241 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -135,18 +135,18 @@ vmpa2t *string_to_vmpa_phy(const char *); vmpa2t *string_to_vmpa_virt(const char *); /* Définition du tronc commun pour les créations SQLite */ -#define SQLITE_VMPA_CREATE \ - "phys INTEGER, " \ +#define SQLITE_SIMPLE_VMPA_CREATE \ + "phys INTEGER, " \ "virt INTEGER" /* Décrit les colonnes utiles à un chargement de données. */ -bool setup_load_for_vmpa(const vmpa2t *, bound_value **, size_t *); +bool setup_load_for_vmpa(const vmpa2t *, const char *, bound_value **, size_t *); /* Charge les valeurs utiles pour une localisation. */ -bool load_vmpa(vmpa2t *, const bound_value *, size_t); +bool load_vmpa(vmpa2t *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ -bool prepare_vmpa_db_statement(const vmpa2t *, bound_value **, size_t *); +bool prepare_vmpa_db_statement(const vmpa2t *, const char *, bound_value **, size_t *); diff --git a/src/common/sqlite.c b/src/common/sqlite.c index ec3c280..2fe1096 100644 --- a/src/common/sqlite.c +++ b/src/common/sqlite.c @@ -24,6 +24,7 @@ #include "sqlite.h" +#include #include @@ -32,6 +33,41 @@ * * * Paramètres : values = tableau d'éléments à consulter. * * count = nombre de descriptions renseignées. * +* * +* Description : Libère de la mémoire un ensemble de valeurs en fin de vie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void free_all_bound_values(bound_value *values, size_t count) +{ + size_t i; /* Boucle de parcours */ + bound_value *value; /* Valeur à traiter */ + + return; + + for (i = 0; i < count; i++) + { + value = values + i; + + if (value->built_name) + free(value->name); + + } + + if (values != NULL) + free(values); + +} + + +/****************************************************************************** +* * +* Paramètres : values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * name = désignation de la valeur recherchée. * * * * Description : Effectue une recherche au sein d'un ensemble de valeurs. * diff --git a/src/common/sqlite.h b/src/common/sqlite.h index 064972b..e4f05a2 100644 --- a/src/common/sqlite.h +++ b/src/common/sqlite.h @@ -41,7 +41,14 @@ /* Description des champs et de leur valeur associée */ typedef struct _bound_value { - const char *name; /* Nom du champ à manipuler */ + union + { + char *name; /* Nom du champ à manipuler #1 */ + const char *cname; /* Nom du champ à manipuler #2 */ + + }; + bool built_name; /* Nom à libérer après usage */ + unsigned int type; /* Type de valeur à associer */ union @@ -59,6 +66,9 @@ typedef struct _bound_value } bound_value; +/* Libère de la mémoire un ensemble de valeurs en fin de vie. */ +void free_all_bound_values(bound_value *, size_t); + /* Effectue une recherche au sein d'un ensemble de valeurs. */ const bound_value *find_bound_value(const bound_value *, size_t, const char *); diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c index e936866..c195959 100644 --- a/src/gtkext/gtkextstatusbar.c +++ b/src/gtkext/gtkextstatusbar.c @@ -223,6 +223,8 @@ bstatus_id_t gtk_extended_status_bar_push(GtkExtStatusBar *bar, const char *mess size_t index; /* Indice du nouvel élément */ bar_update_info *info; /* Informations à mémoriser */ + return 0; + if (bar == NULL) return 0; /* Mise à jour de la pile */ @@ -276,6 +278,8 @@ void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, bstatus_id_t { bar_update_info *info; /* Informations à mémoriser */ + return; + if (bar == NULL) return; /* Mise à jour de la pile */ @@ -319,6 +323,8 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, bstatus_id_t id) size_t i; /* Boucle de parcours */ bar_update_info *info; /* Informations à mémoriser */ + return; + if (bar == NULL) return; /* Mise à jour de la pile */ -- cgit v0.11.2-87-g4458