From dcd5e0b104143b110997029aa0728731f4087ad8 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 2 Jan 2021 00:20:42 +0100
Subject: Managed GObject references each time a configuration parameter is
 accessed.

---
 plugins/pychrysalide/glibext/configuration.c | 42 ++++++------
 src/analysis/cattribs.c                      |  4 ++
 src/core/params.c                            | 98 ++++++++++++++--------------
 src/glibext/configuration.c                  | 78 +++++++++++++++-------
 src/glibext/configuration.h                  | 44 +++++++++----
 src/gui/panel.c                              | 19 ++----
 tests/glibext/configuration.py               | 37 ++++++++++-
 7 files changed, 201 insertions(+), 121 deletions(-)

diff --git a/plugins/pychrysalide/glibext/configuration.c b/plugins/pychrysalide/glibext/configuration.c
index 235662d..b0586af 100644
--- a/plugins/pychrysalide/glibext/configuration.c
+++ b/plugins/pychrysalide/glibext/configuration.c
@@ -856,10 +856,8 @@ static PyObject *py_config_param_iterator_next(PyObject *self)
     iterator->last = item;
 
     if (item != NULL)
-    {
         result = pygobject_new(G_OBJECT(item->data));
-        Py_INCREF(result);
-    }
+
     else
     {
         PyErr_SetNone(PyExc_StopIteration);
@@ -1098,7 +1096,7 @@ static int py_generic_config_init(PyObject *self, PyObject *args, PyObject *kwds
 
     name = NULL;
 
-    ret = PyArg_ParseTuple(args, "s", &name);
+    ret = PyArg_ParseTuple(args, "|s", &name);
     if (!ret) return -1;
 
     /* Initialisation d'un objet GLib */
@@ -1110,7 +1108,8 @@ static int py_generic_config_init(PyObject *self, PyObject *args, PyObject *kwds
 
     config = G_GEN_CONFIG(pygobject_get(self));
 
-    g_generic_config_build(config, name);
+    if (name != NULL)
+        g_generic_config_build(config, name);
 
     return 0;
 
@@ -1305,7 +1304,7 @@ static PyObject *py_generic_config_search(PyObject *self, PyObject *args)
     else
     {
         result = pygobject_new(G_OBJECT(param));
-        //g_object_unref(G_OBJECT(param));
+        g_object_unref(G_OBJECT(param));
     }
 
     return result;
@@ -1333,7 +1332,7 @@ static PyObject *py_generic_config_add(PyObject *self, PyObject *args)
     GCfgParam *param;                       /* Paramètre GLib transmis     */
     int ret;                                /* Bilan de lecture des args.  */
     GGenConfig *config;                     /* Version GLib de la config.  */
-    GCfgParam *added;                       /* Elément ajouté ou NULL      */
+    bool status;                            /* Bilan de l'opération        */
 
 #define GENERIC_CONFIG_ADD_METHOD PYTHON_METHOD_DEF                         \
 (                                                                           \
@@ -1361,19 +1360,10 @@ static PyObject *py_generic_config_add(PyObject *self, PyObject *args)
 
     config = G_GEN_CONFIG(pygobject_get(self));
 
-    g_object_ref(G_OBJECT(param));
-    added = _g_generic_config_add_param(config, param, lock);
+    status = _g_generic_config_add_param(config, param, lock);
 
-    if (added == NULL)
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-    else
-    {
-        result = pygobject_new(G_OBJECT(added));
-        //g_object_unref(G_OBJECT(added));
-    }
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
     return result;
 
@@ -1436,6 +1426,7 @@ static PyObject *py_generic_config_delete(PyObject *self, PyObject *args)
 
 static PyObject *py_generic_config_get_filename(PyObject *self, void *closure)
 {
+    PyObject *result;                       /* Chemin à retourner          */
     GGenConfig *config;                     /* Version GLib de la config.  */
     const char *filename;                   /* Chemin d'accès au fichier   */
 
@@ -1446,14 +1437,23 @@ static PyObject *py_generic_config_get_filename(PyObject *self, void *closure)
     " configuration.\n"                                         \
     "\n"                                                        \
     "The result is a string pointing to a file which may not"   \
-    " (yet) exist."                                             \
+    " (yet) exist or None if not defined."                      \
 )
 
     config = G_GEN_CONFIG(pygobject_get(self));
 
     filename = g_generic_config_get_filename(config);
 
-    return PyUnicode_FromString(filename);
+    if (filename == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    else
+        result = PyUnicode_FromString(filename);
+
+    return result;
 
 }
 
diff --git a/src/analysis/cattribs.c b/src/analysis/cattribs.c
index ebebb83..704e665 100644
--- a/src/analysis/cattribs.c
+++ b/src/analysis/cattribs.c
@@ -297,6 +297,8 @@ const char **g_content_attributes_get_keys(const GContentAttributes *attribs, si
     result = NULL;
     *count = 0;
 
+    g_generic_config_rlock(attribs->configs[0]);
+
     list = g_generic_config_list_params(attribs->configs[0]);
 
     for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter))
@@ -311,6 +313,8 @@ const char **g_content_attributes_get_keys(const GContentAttributes *attribs, si
 
     }
 
+    g_generic_config_runlock(attribs->configs[0]);
+
     return result;
 
 }
diff --git a/src/core/params.c b/src/core/params.c
index 25f8991..c05ce68 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -38,87 +38,89 @@
 
 bool load_main_config_parameters(void)
 {
+    bool result;                            /* Bilan à retourner           */
     GGenConfig *config;                     /* Configuration à charger     */
-    GCfgParam *param;                       /* Paramètre chargé            */
 
     config = g_generic_config_new_from_file("main");
     set_main_configuration(config);
 
-    param = g_generic_config_create_param(config, MPK_FORMAT_NO_NAME, CPT_BOOLEAN, false);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_FORMAT_NO_NAME, CPT_BOOLEAN, false);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_INTERNAL_THEME, CPT_STRING, "Adwaita");
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_INTERNAL_THEME, CPT_STRING, "Adwaita");
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_TITLE_BAR, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_TITLE_BAR, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_SKIP_EXIT_MSG, CPT_BOOLEAN, false);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_SKIP_EXIT_MSG, CPT_BOOLEAN, false);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_MAXIMIZED, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_MAXIMIZED, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_ELLIPSIS_HEADER, CPT_INTEGER, 54);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_ELLIPSIS_HEADER, CPT_INTEGER, 54);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_ELLIPSIS_TAB, CPT_INTEGER, 35);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_ELLIPSIS_TAB, CPT_INTEGER, 35);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_WELCOME_STARTUP, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_WELCOME_STARTUP, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_WELCOME_CHECK, CPT_BOOLEAN, false);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_WELCOME_CHECK, CPT_BOOLEAN, false);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LABEL_OFFSET, CPT_INTEGER, 10);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LABEL_OFFSET, CPT_INTEGER, 10);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_HEX_PADDING, CPT_INTEGER, 10);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_HEX_PADDING, CPT_INTEGER, 10);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_SELECTION_LINE, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_SELECTION_LINE, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_TOOLTIP_MAX_CALLS, CPT_INTEGER, 5);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_TOOLTIP_MAX_CALLS, CPT_INTEGER, 5);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_TOOLTIP_MAX_STRINGS, CPT_INTEGER, 5);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_TOOLTIP_MAX_STRINGS, CPT_INTEGER, 5);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_HEX_UPPER_CASE, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_HEX_UPPER_CASE, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LINK_DEFAULT, CPT_COLOR, ((GdkRGBA []) { { 0, 0, 0, 1.0 } }));
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LINK_DEFAULT, CPT_COLOR, ((GdkRGBA []) { { 0, 0, 0, 1.0 } }));
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LINK_BRANCH_TRUE, CPT_COLOR, ((GdkRGBA []) { { 0, 0.6, 0, 1.0 } }));
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LINK_BRANCH_TRUE, CPT_COLOR, ((GdkRGBA []) { { 0, 0.6, 0, 1.0 } }));
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LINK_BRANCH_FALSE, CPT_COLOR, ((GdkRGBA []) { { 0.8, 0, 0, 1.0 } }));
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LINK_BRANCH_FALSE, CPT_COLOR, ((GdkRGBA []) { { 0.8, 0, 0, 1.0 } }));
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_LINK_LOOP, CPT_COLOR, ((GdkRGBA []) { { 0, 0, 0.8, 1.0 } }));
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_LINK_LOOP, CPT_COLOR, ((GdkRGBA []) { { 0, 0, 0.8, 1.0 } }));
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "<Shift>F2");
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "<Shift>F2");
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_TMPDIR, CPT_STRING, "/tmp/chrysalide");
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_TMPDIR, CPT_STRING, "/tmp/chrysalide");
+    if (!result) goto exit;
 
-    param = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true);
-    if (param == NULL) return false;
+    result = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true);
+    if (!result) goto exit;
 
     g_generic_config_create_group(config, "gui.panels.positions", CPT_INTEGER);
 
     g_generic_config_create_group(config, "gui.panels.dock_at_startup", CPT_BOOLEAN);
     g_generic_config_create_group(config, "gui.panels.path", CPT_STRING);
 
-    return true;
+ exit:
+
+    return result;
 
 }
 
diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c
index b4eb784..5bc94a7 100644
--- a/src/glibext/configuration.c
+++ b/src/glibext/configuration.c
@@ -942,7 +942,7 @@ void g_config_param_set_value(GCfgParam *param, ...)
 *                                                                             *
 ******************************************************************************/
 
-void g_config_param_get_value(GCfgParam *param, ...)
+void g_config_param_get_value(const GCfgParam *param, ...)
 {
     va_list ap;                             /* Liste d'arguments           */
 
@@ -1135,6 +1135,7 @@ static void g_config_group_load(GCfgGroup *group, GGenConfig *config, xmlXPathCo
 
         param = g_config_param_new_empty(key, group->type);
         _g_generic_config_add_param(config, param, false);
+        g_object_unref(G_OBJECT(param));
 
         free(key);
 
@@ -1358,7 +1359,11 @@ void g_generic_config_build(GGenConfig *config, const char *name)
 
 const char *g_generic_config_get_filename(const GGenConfig *config)
 {
-    return config->filename;
+    char *result;                           /* Chemin à retourner          */
+
+    result = config->filename;
+
+    return result;
 
 }
 
@@ -1463,24 +1468,33 @@ bool g_generic_config_write(GGenConfig *config)
     xmlXPathContextPtr context;             /* Contexte de recherche XPath */
     GList *iter;                            /* Boucle de parcours          */
 
-    if (!create_new_xml_file(&xdoc, &context))
-        return false;
-
-    g_generic_config_rlock(config);
+    if (config->filename == NULL)
+        result = false;
 
-    for (result = true, iter = g_list_first(config->params);
-         result && iter != NULL;
-         iter = g_list_next(iter))
+    else
     {
-        result = g_config_param_write(G_CFG_PARAM(iter->data), xdoc, context);
-    }
+        result = create_new_xml_file(&xdoc, &context);
+        if (!result) goto exit;
 
-    g_generic_config_runlock(config);
+        g_generic_config_rlock(config);
 
-    if (result)
-        result = save_xml_file(xdoc, config->filename);
+        for (iter = g_list_first(config->params);
+             result && iter != NULL;
+             iter = g_list_next(iter))
+        {
+            result = g_config_param_write(G_CFG_PARAM(iter->data), xdoc, context);
+        }
 
-    close_xml_file(xdoc, context);
+        g_generic_config_runlock(config);
+
+        if (result)
+            result = save_xml_file(xdoc, config->filename);
+
+        close_xml_file(xdoc, context);
+
+    }
+
+ exit:
 
     return result;
 
@@ -1504,6 +1518,8 @@ void g_generic_config_add_group(GGenConfig *config, GCfgGroup *group)
 {
     g_generic_config_wlock(config);
 
+    g_object_ref(G_OBJECT(group));
+
     config->groups = g_list_append(config->groups, group);
 
     g_generic_config_wunlock(config);
@@ -1527,6 +1543,7 @@ void g_generic_config_add_group(GGenConfig *config, GCfgGroup *group)
 
 GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool lock)
 {
+    GCfgParam *result;                      /* Instance à retourner        */
     GList *item;                            /* Elément générique de liste  */
     GCfgParam fake;                         /* Faux élément partiel        */
 
@@ -1538,10 +1555,15 @@ GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool l
 
     item = g_list_find_custom(config->params, &fake, (GCompareFunc)g_config_param_compare);
 
+    result = item ? item->data : NULL;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
     if (lock)
         g_generic_config_runlock(config);
 
-    return item ? item->data : NULL;
+    return result;
 
 }
 
@@ -1554,14 +1576,15 @@ GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool l
 *                                                                             *
 *  Description : Ajoute un paramètre à une configuration.                     *
 *                                                                             *
-*  Retour      : Elément mis en place ou NULL en cas d'erreur.                *
+*  Retour      : Validation de l'ajout : true ou false.                       *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GCfgParam *_g_generic_config_add_param(GGenConfig *config, GCfgParam *param, bool lock)
+bool _g_generic_config_add_param(GGenConfig *config, GCfgParam *param, bool lock)
 {
+    bool result;                            /* Bilan à retourner           */
     const char *path;                       /* Chemin d'accès unique       */
     GCfgParam *old;                         /* Test de présence            */
 
@@ -1573,20 +1596,25 @@ GCfgParam *_g_generic_config_add_param(GGenConfig *config, GCfgParam *param, boo
     old = _g_generic_config_search(config, path, false);
     if (old != NULL)
     {
-        g_clear_object(&param);
+        g_object_unref(G_OBJECT(old));
+        result = false;
         goto exit;
     }
 
+    g_object_ref(G_OBJECT(param));
+
     config->params = g_list_append(config->params, param);
 
     g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), config);
 
+    result = true;
+
  exit:
 
     if (lock)
         g_generic_config_wunlock(config);
 
-    return param;
+    return result;
 
 }
 
@@ -1632,12 +1660,16 @@ void g_generic_config_delete_param(GGenConfig *config, const char *path)
 
     old = _g_generic_config_search(config, path, false);
 
-    g_signal_handlers_disconnect_by_func(old, G_CALLBACK(on_config_param_modified), config);
-
     if (old != NULL)
+    {
+        g_signal_handlers_disconnect_by_func(old, G_CALLBACK(on_config_param_modified), config);
+
         config->params = g_list_remove(config->params, old);
 
-    g_object_unref(G_OBJECT(old));
+        g_object_unref(G_OBJECT(old));
+        g_object_unref(G_OBJECT(old));
+
+    }
 
     g_generic_config_wunlock(config);
 
diff --git a/src/glibext/configuration.h b/src/glibext/configuration.h
index afefed1..aac6dc7 100644
--- a/src/glibext/configuration.h
+++ b/src/glibext/configuration.h
@@ -105,7 +105,7 @@ void g_config_param_reset(GCfgParam *);
 void g_config_param_set_value(GCfgParam *, ...);
 
 /* Indique la valeur courante d'un paramètre de configuration. */
-void g_config_param_get_value(GCfgParam *, ...);
+void g_config_param_get_value(const GCfgParam *, ...);
 
 
 
@@ -191,6 +191,7 @@ void g_generic_config_add_group(GGenConfig *, GCfgGroup *);
         GCfgGroup *__group;                                     \
         __group = g_config_group_new(p, t);                     \
         g_generic_config_add_group(c, __group);                 \
+        g_object_unref(G_OBJECT(__group));                      \
     })
 
 
@@ -205,7 +206,10 @@ GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool);
         GCfgParam *__param;                                     \
         __param = g_generic_config_search(c, p);                \
         if (__param != NULL)                                    \
+        {                                                       \
             g_config_param_set_value(__param, v);               \
+            g_object_unref(G_OBJECT(__param));                  \
+        }                                                       \
         __param != NULL ? true : false;                         \
     })
 
@@ -214,51 +218,63 @@ GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool);
         GCfgParam *__param;                                     \
         __param = g_generic_config_search(c, p);                \
         if (__param != NULL)                                    \
+        {                                                       \
             g_config_param_get_value(__param, v);               \
+            g_object_unref(G_OBJECT(__param));                  \
+        }                                                       \
         __param != NULL ? true : false;                         \
     })
 
 
 /* Ajoute un paramètre à une configuration. */
-GCfgParam *_g_generic_config_add_param(GGenConfig *, GCfgParam *, bool);
+bool _g_generic_config_add_param(GGenConfig *, GCfgParam *, bool);
 
 
 #define g_generic_config_add_param(c, p) _g_generic_config_add_param(c, p, true)
 
 #define g_generic_config_create_param(c, p, t, d)               \
     ({                                                          \
-        GCfgParam *__result;                                    \
-        __result = g_config_param_new(p, t, d);                 \
-        __result = g_generic_config_add_param(c, __result);     \
+        bool __result;                                          \
+        GCfgParam *__param;                                     \
+        __param = g_config_param_new(p, t, d);                  \
+        __result = g_generic_config_add_param(c, __param);      \
+        g_object_unref(G_OBJECT(__param));                      \
         __result;                                               \
     })
 
 
 #define g_generic_config_create_param_if_not_exist(c, p, t, d)  \
     ({                                                          \
-        GCfgParam *__result;                                    \
-        __result = g_generic_config_search(c, p);               \
-        if (__result == NULL)                                   \
+        bool __result;                                          \
+        GCfgParam *__param;                                     \
+        __param = g_generic_config_search(c, p);                \
+        if (__param == NULL)                                    \
         {                                                       \
-            __result = g_config_param_new(p, t, d);             \
-            __result = g_generic_config_add_param(c, __result); \
+            __param = g_config_param_new(p, t, d);              \
+            __result = g_generic_config_add_param(c, __param);  \
         }                                                       \
+        else                                                    \
+            __result = true;                                    \
+        g_object_unref(G_OBJECT(__param));                      \
         __result;                                               \
     })
 
 
 #define g_generic_config_create_or_udpdate_param(c, p, t, d, v) \
     ({                                                          \
+        bool __result;                                          \
         GCfgParam *__param;                                     \
         __param = g_generic_config_search(c, p);                \
         if (__param == NULL)                                    \
         {                                                       \
             __param = g_config_param_new(p, t, d);              \
-            __param = g_generic_config_add_param(c, __param);   \
+            __result = g_generic_config_add_param(c, __param);  \
         }                                                       \
-        if (__param != NULL)                                    \
-            g_config_param_set_value(__param, v);               \
-        __param != NULL ? true : false;                         \
+        else                                                    \
+            __result = true;                                    \
+        g_config_param_set_value(__param, v);                   \
+        g_object_unref(G_OBJECT(__param));                      \
+        __result;                                               \
     })
 
 
diff --git a/src/gui/panel.c b/src/gui/panel.c
index 976a2d7..5b21620 100644
--- a/src/gui/panel.c
+++ b/src/gui/panel.c
@@ -516,40 +516,31 @@ bool gtk_panel_item_class_setup_configuration(const GPanelItemClass *class, GGen
     bool result;                            /* Bilan à retourner           */
     char *key;                              /* Clef d'accès à un paramètre */
     bool dock_at_startup;                   /* Affichage dès le départ ?   */
-    GCfgParam *param;                       /* Paramètre chargé            */
     char *path;                             /* Localisation du panneau     */
 
-    result = true;
-
     key = gtk_panel_item_class_build_configuration_key(class, "dock_at_startup");
 
     dock_at_startup = class->dock_at_startup(class);
 
-    param = g_generic_config_create_param_if_not_exist(config, key, CPT_BOOLEAN, dock_at_startup);
+    result = g_generic_config_create_param_if_not_exist(config, key, CPT_BOOLEAN, dock_at_startup);
 
     free(key);
 
-    if (param == NULL)
-    {
-        result = false;
+    if (!result)
         goto exit;
-    }
 
     key = gtk_panel_item_class_build_configuration_key(class, "path");
 
     path = class->get_path(class);
 
-    param = g_generic_config_create_param_if_not_exist(config, key, CPT_STRING, path);
-
-    if (param == NULL)
-        result = false;
+    result = g_generic_config_create_param_if_not_exist(config, key, CPT_STRING, path);
 
     free(path);
 
- exit:
-
     free(key);
 
+ exit:
+
     return result;
 
 }
diff --git a/tests/glibext/configuration.py b/tests/glibext/configuration.py
index 786fc9e..880b445 100644
--- a/tests/glibext/configuration.py
+++ b/tests/glibext/configuration.py
@@ -4,7 +4,7 @@ gi.require_version('Gdk', '3.0')
 from gi.repository import Gdk
 
 from chrysacase import ChrysalideTestCase
-from pychrysalide.glibext import ConfigParam
+from pychrysalide.glibext import ConfigParam, GenConfig
 
 
 class TestConfiguration(ChrysalideTestCase):
@@ -69,3 +69,38 @@ class TestConfiguration(ChrysalideTestCase):
         self.assertTrue('|' in str(param.state))
 
         self.assertTrue('.' in str(param.type))
+
+
+    def testConfiguration(self):
+        """Feed and browse a basic configuration."""
+
+        config = GenConfig()
+        self.assertIsNotNone(config)
+        self.assertIsNone(config.filename)
+
+        for i in range(5):
+            param = ConfigParam('config.int.%u' % i, ConfigParam.ConfigParamType.INTEGER, i)
+            config.add(param)
+
+        chain = ''
+
+        for p in config.params:
+            chain += '%u' % p.value
+
+        self.assertTrue(chain == ''.join([ '%u' % i for i in range(5) ]))
+
+        found = config.search('config.int.3')
+        self.assertTrue(found.value == 3)
+
+        found = config.search('config.int.33')
+        self.assertIsNone(found)
+
+        for p in config.params:
+            p.value *= 10
+
+        chain = ''
+
+        for p in config.params:
+            chain += '%u' % p.value
+
+        self.assertTrue(chain == ''.join([ '%u' % (i * 10) for i in range(5) ]))
-- 
cgit v0.11.2-87-g4458