diff options
| -rw-r--r-- | plugins/pychrysalide/glibext/configuration.c | 42 | ||||
| -rw-r--r-- | src/analysis/cattribs.c | 4 | ||||
| -rw-r--r-- | src/core/params.c | 98 | ||||
| -rw-r--r-- | src/glibext/configuration.c | 78 | ||||
| -rw-r--r-- | src/glibext/configuration.h | 44 | ||||
| -rw-r--r-- | src/gui/panel.c | 19 | ||||
| -rw-r--r-- | 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(¶m); +        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) ])) | 
