summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-01-01 23:20:42 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-01-01 23:20:42 (GMT)
commitdcd5e0b104143b110997029aa0728731f4087ad8 (patch)
tree141a79ade5eae6e469ba9e5255882039e9c29a3e
parent7b320516abf871eefe009ff6fe4fb86ed921fed9 (diff)
Managed GObject references each time a configuration parameter is accessed.
-rw-r--r--plugins/pychrysalide/glibext/configuration.c42
-rw-r--r--src/analysis/cattribs.c4
-rw-r--r--src/core/params.c98
-rw-r--r--src/glibext/configuration.c78
-rw-r--r--src/glibext/configuration.h44
-rw-r--r--src/gui/panel.c19
-rw-r--r--tests/glibext/configuration.py37
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) ]))