From 4ce370996ff8db309df820b203b461a79aed993d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20B=C3=A9daride?= Date: Fri, 10 May 2013 17:00:58 +0200 Subject: [PATCH] Add new boolean type for configuration --- ChangeLog | 3 + include/xbt/config.h | 18 ++++ src/include/simgrid/sg_config.h | 1 + src/mc/mc_global.c | 4 +- src/simgrid/sg_config.c | 71 +++++++------ src/smpi/smpi_global.c | 2 +- src/surf/cpu_cas01.c | 2 +- src/surf/network.c | 2 +- src/surf/workstation.c | 2 +- src/xbt/config.c | 172 +++++++++++++++++++++++++++++++- 10 files changed, 237 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f30967188..24a2358418 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ SimGrid (3.10) NOT RELEASED; urgency=low * Our own implementation of getline is renamed xbt_getline, and gets used even if the OS provide a getline(). This should reduce the configuration complexity by using the same code on all platforms. + * new xbt_cfg_elm_boolean type Java: * Reintegrate Java to the main archive as desynchronizing these @@ -23,6 +24,8 @@ SimGrid (3.10) NOT RELEASED; urgency=low version of MPE. - Bug Fix: the compute part of the reduce action is now taken into account. + PLATFORM: + * Handle units for values (10ms, 10kiloflops, 10Bps, …) -- $date Da SimGrid team SimGrid (3.9) stable; urgency=low diff --git a/include/xbt/config.h b/include/xbt/config.h index 67c25bc85f..bc1b68093f 100644 --- a/include/xbt/config.h +++ b/include/xbt/config.h @@ -103,6 +103,7 @@ XBT_PUBLIC(void) xbt_cfg_set_double(xbt_cfg_t cfg, const char *name, double val); XBT_PUBLIC(void) xbt_cfg_set_string(xbt_cfg_t cfg, const char *name, const char *val); +XBT_PUBLIC(void) xbt_cfg_set_boolean(xbt_cfg_t cfg, const char *name, const char *val); XBT_PUBLIC(void) xbt_cfg_set_peer(xbt_cfg_t cfg, const char *name, const char *peer, int port); XBT_PUBLIC(void*) xbt_cfg_set_as_string(xbt_cfg_t cfg, const char *name, const char *val); @@ -117,6 +118,8 @@ XBT_PUBLIC(void) xbt_cfg_setdefault_double(xbt_cfg_t cfg, const char *name, double val); XBT_PUBLIC(void) xbt_cfg_setdefault_string(xbt_cfg_t cfg, const char *name, const char *val); +XBT_PUBLIC(void) xbt_cfg_setdefault_boolean(xbt_cfg_t cfg, const char *name, + const char *val); XBT_PUBLIC(void) xbt_cfg_setdefault_peer(xbt_cfg_t cfg, const char *name, const char *host, int port); @@ -129,6 +132,7 @@ XBT_PUBLIC(void) xbt_cfg_rm_double(xbt_cfg_t cfg, const char *name, double val); XBT_PUBLIC(void) xbt_cfg_rm_string(xbt_cfg_t cfg, const char *name, const char *val); +XBT_PUBLIC(void) xbt_cfg_rm_boolean(xbt_cfg_t cfg, const char *name, int val); XBT_PUBLIC(void) xbt_cfg_rm_peer(xbt_cfg_t cfg, const char *name, const char *peer, int port); @@ -159,12 +163,23 @@ typedef enum { /**< double */ xbt_cfgelm_string, /**< char* */ + xbt_cfgelm_boolean, /**< int */ xbt_cfgelm_peer, /**< both a char* (representing the peername) and an integer (representing the port) */ xbt_cfgelm_any, /* not shown to users to prevent errors */ xbt_cfgelm_type_count } e_xbt_cfgelm_type_t; +/** Boolean possible values **/ + +struct xbt_boolean_couple { + const char *true_val; + const char *false_val; +}; + + + + /** \brief Callback types. They get the name of the modified entry, and the position of the changed value */ typedef void (*xbt_cfg_cb_t) (const char *, int); @@ -215,6 +230,7 @@ XBT_PUBLIC(e_xbt_cfgelm_type_t) xbt_cfg_get_type(xbt_cfg_t cfg, XBT_PUBLIC(int) xbt_cfg_get_int(xbt_cfg_t cfg, const char *name); XBT_PUBLIC(double) xbt_cfg_get_double(xbt_cfg_t cfg, const char *name); XBT_PUBLIC(char *) xbt_cfg_get_string(xbt_cfg_t cfg, const char *name); +XBT_PUBLIC(int) xbt_cfg_get_boolean(xbt_cfg_t cfg, const char *name); XBT_PUBLIC(void) xbt_cfg_get_peer(xbt_cfg_t cfg, const char *name, char **peer, int *port); XBT_PUBLIC(xbt_dynar_t) xbt_cfg_get_dynar(xbt_cfg_t cfg, const char *name); @@ -225,6 +241,8 @@ XBT_PUBLIC(double) xbt_cfg_get_double_at(xbt_cfg_t cfg, const char *name, int pos); XBT_PUBLIC(char *) xbt_cfg_get_string_at(xbt_cfg_t cfg, const char *name, int pos); +XBT_PUBLIC(int) xbt_cfg_get_boolean_at(xbt_cfg_t cfg, const char *name, + int pos); XBT_PUBLIC(void) xbt_cfg_get_peer_at(xbt_cfg_t cfg, const char *name, int pos, char **peer, int *port); diff --git a/src/include/simgrid/sg_config.h b/src/include/simgrid/sg_config.h index fdda707180..9952bfca13 100644 --- a/src/include/simgrid/sg_config.h +++ b/src/include/simgrid/sg_config.h @@ -7,6 +7,7 @@ XBT_PUBLIC_DATA(xbt_cfg_t) _sg_cfg_set; XBT_PUBLIC(int) sg_cfg_get_int(const char* name); XBT_PUBLIC(double) sg_cfg_get_double(const char* name); XBT_PUBLIC(char*) sg_cfg_get_string(const char* name); +XBT_PUBLIC(int) sg_cfg_get_boolean(const char* name); XBT_PUBLIC(void) sg_cfg_get_peer(const char *name, char **peer, int *port); XBT_PUBLIC(xbt_dynar_t) sg_cfg_get_dynar(const char* name); diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index 430da06f13..bb5f9424d2 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -51,7 +51,7 @@ void _mc_cfg_cb_checkpoint(const char *name, int pos) { if (_sg_init_status && !_sg_do_model_check) { xbt_die("You are specifying a checkpointing value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry."); } - _sg_mc_checkpoint = xbt_cfg_get_int(_sg_cfg_set, name); + _sg_mc_checkpoint = xbt_cfg_get_boolean(_sg_cfg_set, name); } void _mc_cfg_cb_property(const char *name, int pos) { if (_sg_init_status && !_sg_do_model_check) { @@ -64,7 +64,7 @@ void _mc_cfg_cb_timeout(const char *name, int pos) { if (_sg_init_status && !_sg_do_model_check) { xbt_die("You are specifying a value to enable/disable timeout for wait requests after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry."); } - _sg_mc_timeout= xbt_cfg_get_int(_sg_cfg_set, name); + _sg_mc_timeout= xbt_cfg_get_boolean(_sg_cfg_set, name); } void _mc_cfg_cb_max_depth(const char *name, int pos) { diff --git a/src/simgrid/sg_config.c b/src/simgrid/sg_config.c index 34baf68fae..420f381182 100644 --- a/src/simgrid/sg_config.c +++ b/src/simgrid/sg_config.c @@ -291,9 +291,9 @@ extern int _sg_do_model_check; /* this variable lives in xbt_main until I find static void _sg_cfg_cb_model_check(const char *name, int pos) { #ifdef HAVE_MC - _sg_do_model_check = xbt_cfg_get_int(_sg_cfg_set, name); + _sg_do_model_check = xbt_cfg_get_boolean(_sg_cfg_set, name); #else - if (xbt_cfg_get_int(_sg_cfg_set, name)) { + if (xbt_cfg_get_boolean(_sg_cfg_set, name)) { xbt_die("You tried to activate the model-checking from the command line, but it was not compiled in. Change your settings in cmake, recompile and try again"); } #endif @@ -303,7 +303,7 @@ extern int _sg_do_verbose_exit; static void _sg_cfg_cb_verbose_exit(const char *name, int pos) { - _sg_do_verbose_exit = xbt_cfg_get_int(_sg_cfg_set, name); + _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name); } @@ -348,18 +348,15 @@ static void _sg_cfg_cb_contexts_parallel_mode(const char *name, int pos) static void _sg_cfg_cb__surf_network_coordinates(const char *name, int pos) { - char *val = xbt_cfg_get_string(_sg_cfg_set, name); - if (!strcmp(val, "yes")) { + int val = xbt_cfg_get_boolean(_sg_cfg_set, name); + if (val) { if (!COORD_HOST_LEVEL) { COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp); COORD_ASR_LEVEL = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp); } - } else if (!strcmp(val, "no")) { + } else if (COORD_HOST_LEVEL) xbt_die("Setting of whether to use coordinate cannot be disabled once set."); - } else { - xbt_die("Command line setting of whether to use coordinates must be either \"yes\" or \"no\""); - } } static void _sg_cfg_cb_surf_nthreads(const char *name, int pos) @@ -370,7 +367,7 @@ static void _sg_cfg_cb_surf_nthreads(const char *name, int pos) static void _sg_cfg_cb__surf_network_crosstraffic(const char *name, int pos) { - sg_network_crosstraffic = xbt_cfg_get_int(_sg_cfg_set, name); + sg_network_crosstraffic = xbt_cfg_get_boolean(_sg_cfg_set, name); } #ifdef HAVE_GTNETS @@ -536,32 +533,34 @@ void sg_config_init(int *argc, char **argv) xbt_cfgelm_string, NULL, 0, 0, _sg_cfg_cb__surf_path, NULL); - default_value_int = 0; + default_value = xbt_strdup("off"); xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update", - "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)", - xbt_cfgelm_int, &default_value_int, 0, 1, + "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)", + xbt_cfgelm_boolean, &default_value, 0, 1, NULL, NULL); - default_value_int = 0; + default_value = xbt_strdup("off"); xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update", - "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)", - xbt_cfgelm_int, &default_value_int, 0, 1, + "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)", + xbt_cfgelm_boolean, &default_value, 0, 1, NULL, NULL); #ifdef HAVE_MC /* do model-checking */ + default_value = xbt_strdup("off"); xbt_cfg_register(&_sg_cfg_set, "model-check", "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)", - xbt_cfgelm_int, NULL, 0, 1, + xbt_cfgelm_boolean, NULL, 0, 1, _sg_cfg_cb_model_check, NULL); - xbt_cfg_setdefault_int(_sg_cfg_set, "model-check", 0); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", default_value); /* do stateful model-checking */ + default_value = xbt_strdup("off"); xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint", - "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). " - "If value=1, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.", - xbt_cfgelm_int, NULL, 0, 1, + "Specify the amount of steps between checkpoints during stateful model-checking (default: off => stateless verification). " + "If value=on, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.", + xbt_cfgelm_boolean, NULL, 0, 1, _mc_cfg_cb_checkpoint, NULL); - xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/checkpoint", default_value); /* do liveness model-checking */ xbt_cfg_register(&_sg_cfg_set, "model-check/property", @@ -578,11 +577,12 @@ void sg_config_init(int *argc, char **argv) xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor"); /* Enable/disable timeout for wait requests with model-checking */ + default_value = xbt_strdup("off"); xbt_cfg_register(&_sg_cfg_set, "model-check/timeout", "Enable/Disable timeout for wait requests", - xbt_cfgelm_int, NULL, 0, 1, + xbt_cfgelm_boolean, NULL, 0, 1, _mc_cfg_cb_timeout, NULL); - xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/timeout", 0); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", default_value); /* Set max depth exploration */ xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth", @@ -607,10 +607,10 @@ void sg_config_init(int *argc, char **argv) #endif /* do verbose-exit */ - default_value_int = 1; + default_value = xbt_strdup("on"); xbt_cfg_register(&_sg_cfg_set, "verbose-exit", "Activate the \"do nothing\" mode in Ctrl-C", - xbt_cfgelm_int, &default_value_int, 0, 1, + xbt_cfgelm_boolean, &default_value, 0, 1, _sg_cfg_cb_verbose_exit, NULL); @@ -662,16 +662,16 @@ void sg_config_init(int *argc, char **argv) default_value = xbt_strdup("no"); xbt_cfg_register(&_sg_cfg_set, "network/coordinates", "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)", - xbt_cfgelm_string, &default_value, 1, 1, + xbt_cfgelm_boolean, &default_value, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL); - xbt_cfg_setdefault_string(_sg_cfg_set, "network/coordinates", default_value); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", default_value); - default_value_int = 0; + default_value = xbt_strdup("no"); xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic", "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)", - xbt_cfgelm_int, &default_value_int, 0, 1, + xbt_cfgelm_boolean, &default_value, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL); - xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", default_value_int); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", default_value); #ifdef HAVE_GTNETS xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter", @@ -701,11 +701,12 @@ void sg_config_init(int *argc, char **argv) xbt_cfgelm_double, &default_reference_speed, 1, 1, NULL, NULL); - int default_display_timing = 0; + default_value = xbt_strdup("no"); xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing", "Boolean indicating whether we should display the timing after simulation.", - xbt_cfgelm_int, &default_display_timing, 1, 1, NULL, + xbt_cfgelm_boolean, &default_value, 1, 1, NULL, NULL); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", default_value); double default_threshold = 1e-6; xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold", @@ -924,6 +925,10 @@ char* sg_cfg_get_string(const char* name) { return xbt_cfg_get_string(_sg_cfg_set,name); } +int sg_cfg_get_boolean(const char* name) +{ + return xbt_cfg_get_boolean(_sg_cfg_set,name); +} void sg_cfg_get_peer(const char *name, char **peer, int *port) { xbt_cfg_get_peer(_sg_cfg_set,name, peer, port); diff --git a/src/smpi/smpi_global.c b/src/smpi/smpi_global.c index 88549955a9..7fca6d7bf9 100644 --- a/src/smpi/smpi_global.c +++ b/src/smpi/smpi_global.c @@ -413,7 +413,7 @@ int smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[]) else SIMIX_run(); - if (sg_cfg_get_int("smpi/display_timing")) + if (sg_cfg_get_boolean("smpi/display_timing")) XBT_INFO("Simulation time: %g seconds.", SIMIX_get_clock()); smpi_global_destroy(); diff --git a/src/surf/cpu_cas01.c b/src/surf/cpu_cas01.c index b492ee1106..43bb124c96 100644 --- a/src/surf/cpu_cas01.c +++ b/src/surf/cpu_cas01.c @@ -327,7 +327,7 @@ static void surf_cpu_model_init_internal() char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim"); int select = - xbt_cfg_get_int(_sg_cfg_set, "cpu/maxmin_selective_update"); + xbt_cfg_get_boolean(_sg_cfg_set, "cpu/maxmin_selective_update"); surf_cpu_model = surf_model_init(); diff --git a/src/surf/network.c b/src/surf/network.c index 2eee39ca3d..04c576314d 100644 --- a/src/surf/network.c +++ b/src/surf/network.c @@ -736,7 +736,7 @@ static void set_update_mechanism(void) { char *optim = xbt_cfg_get_string(_sg_cfg_set, "network/optim"); int select = - xbt_cfg_get_int(_sg_cfg_set, "network/maxmin_selective_update"); + xbt_cfg_get_boolean(_sg_cfg_set, "network/maxmin_selective_update"); if (!strcmp(optim, "Full")) { surf_network_model->model_private->update_mechanism = UM_FULL; diff --git a/src/surf/workstation.c b/src/surf/workstation.c index b938ed0d7a..9399b42ad1 100644 --- a/src/surf/workstation.c +++ b/src/surf/workstation.c @@ -446,7 +446,7 @@ static void surf_workstation_model_init_internal(void) void surf_workstation_model_init_current_default(void) { surf_workstation_model_init_internal(); - xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", 1); + xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes")); surf_cpu_model_init_Cas01(); surf_network_model_init_LegrandVelho(); diff --git a/src/xbt/config.c b/src/xbt/config.c index 2b352b1569..2eee32a906 100644 --- a/src/xbt/config.c +++ b/src/xbt/config.c @@ -45,7 +45,15 @@ typedef struct { } s_xbt_cfgelm_t, *xbt_cfgelm_t; static const char *xbt_cfgelm_type_name[xbt_cfgelm_type_count] = - { "int", "double", "string", "peer", "any" }; + { "int", "double", "string", "boolean", "peer", "any" }; + +const struct xbt_boolean_couple xbt_cfgelm_boolean_values[] = { + { "yes", "no"}, + { "on", "off"}, + {"true", "false"}, + { "1", "0"}, + { NULL, NULL} +}; /* Internal stuff used in cache to free a variable */ static void xbt_cfgelm_free(void *data); @@ -154,6 +162,13 @@ void xbt_cfg_dump(const char *name, const char *indent, xbt_cfg_t cfg) } break; + case xbt_cfgelm_boolean: + for (i = 0; i < size; i++) { + ival = xbt_dynar_get_as(variable->content, i, int); + printf("%s %d\n", indent, ival); + } + break; + case xbt_cfgelm_peer: for (i = 0; i < size; i++) { hval = xbt_dynar_get_as(variable->content, i, xbt_peer_t); @@ -253,6 +268,12 @@ xbt_cfg_register(xbt_cfg_t * cfg, xbt_dynar_push(res->content, default_value); break; + case xbt_cfgelm_boolean: + res->content = xbt_dynar_new(sizeof(int), NULL); + if (default_value) + xbt_dynar_push(res->content, default_value); + break; + case xbt_cfgelm_peer: res->content = xbt_dynar_new(sizeof(xbt_peer_t), xbt_peer_free_voidp); if (default_value) @@ -391,6 +412,10 @@ void xbt_cfg_help(xbt_cfg_t cfg) printf("'%s'%s", xbt_dynar_get_as(variable->content, i, char *), sep); break; + case xbt_cfgelm_boolean: + printf("'%d'%s", xbt_dynar_get_as(variable->content, i, int), sep); + break; + case xbt_cfgelm_peer: { xbt_peer_t hval = xbt_dynar_get_as(variable->content, i, xbt_peer_t); printf("%s:%d%s", hval->name, hval->port, sep); @@ -537,6 +562,11 @@ void xbt_cfg_set_vargs(xbt_cfg_t cfg, const char *name, va_list pa) xbt_cfg_set_double(cfg, name, d); break; + case xbt_cfgelm_boolean: + str = va_arg(pa, char *); + xbt_cfg_set_boolean(cfg, name, str); + break; + default: xbt_die("Config element variable %s not valid (type=%d)", name, (int)type); } @@ -700,6 +730,10 @@ void *xbt_cfg_set_as_string(xbt_cfg_t cfg, const char *key, const char *value) { xbt_cfg_set_double(cfg, key, d); /* throws */ break; + case xbt_cfgelm_boolean: + xbt_cfg_set_boolean(cfg, key, value); /* throws */ + break; + case xbt_cfgelm_peer: val = xbt_strdup(value); str = val; @@ -784,6 +818,26 @@ void xbt_cfg_setdefault_string(xbt_cfg_t cfg, const char *name, name, val); } + +/** @brief Set an boolean value to \a name within \a cfg if it wasn't changed yet + * + * This is useful to change the default value of a variable while allowing + * users to override it with command line arguments + */ +void xbt_cfg_setdefault_boolean(xbt_cfg_t cfg, const char *name, const char *val) +{ + xbt_cfgelm_t variable = xbt_cfgelm_get(cfg, name, xbt_cfgelm_boolean); + + if (variable->isdefault){ + xbt_cfg_set_boolean(cfg, name, val); + variable->isdefault = 1; + } + else + XBT_DEBUG + ("Do not override configuration variable '%s' with value '%s' because it was already set.", + name, val); +} + /** @brief Set a peer value to \a name within \a cfg if it wasn't changed yet * * This is useful to change the default value of a variable while allowing @@ -917,6 +971,55 @@ void xbt_cfg_set_string(xbt_cfg_t cfg, const char *name, const char *val) variable->isdefault = 0; } +/** @brief Set or add a boolean value to \a name within \a cfg + * + * \arg cfg the config set + * \arg name the name of the variable + * \arg val the value of the variable + */ +void xbt_cfg_set_boolean(xbt_cfg_t cfg, const char *name, const char *val) +{ + xbt_cfgelm_t variable; + int i, bval; + + XBT_VERB("Configuration setting: %s=%s", name, val); + variable = xbt_cfgelm_get(cfg, name, xbt_cfgelm_boolean); + + for (i = 0; xbt_cfgelm_boolean_values[i].true_val != NULL; i++) { + if (strcmp(val, xbt_cfgelm_boolean_values[i].true_val) == 0){ + bval = 1; + break; + } + if (strcmp(val, xbt_cfgelm_boolean_values[i].false_val) == 0){ + bval = 0; + break; + } + } + if (xbt_cfgelm_boolean_values[i].true_val == NULL) { + xbt_die("Value of option '%s' not valid. Should be a boolean (yes,no,on,off,true,false,0,1)", val); + } + + if (variable->max == 1) { + if (variable->cb_rm && !xbt_dynar_is_empty(variable->content)) + variable->cb_rm(name, 0); + + xbt_dynar_set(variable->content, 0, &bval); + } else { + if (variable->max + && xbt_dynar_length(variable->content) == + (unsigned long) variable->max) + THROWF(mismatch_error, 0, + "Cannot add value %s to the config element %s since it's already full (size=%d)", + val, name, variable->max); + + xbt_dynar_push(variable->content, &bval); + } + + if (variable->cb_set) + variable->cb_set(name, xbt_dynar_length(variable->content) - 1); + variable->isdefault = 0; +} + /** @brief Set or add an peer value to \a name within \a cfg * * \arg cfg the config set @@ -1061,6 +1164,40 @@ void xbt_cfg_rm_string(xbt_cfg_t cfg, const char *name, const char *val) val, name); } +/** @brief Remove the provided \e val boolean value from a variable + * + * \arg cfg the config set + * \arg name the name of the variable + * \arg val the value to be removed + */ +void xbt_cfg_rm_boolean(xbt_cfg_t cfg, const char *name, int val) +{ + + xbt_cfgelm_t variable; + unsigned int cpt; + int seen; + + variable = xbt_cfgelm_get(cfg, name, xbt_cfgelm_boolean); + + if (xbt_dynar_length(variable->content) == variable->min) + THROWF(mismatch_error, 0, + "Cannot remove value %d from the config element %s since it's already at its minimal size (=%d)", + val, name, variable->min); + + xbt_dynar_foreach(variable->content, cpt, seen) { + if (seen == val) { + if (variable->cb_rm) + variable->cb_rm(name, cpt); + xbt_dynar_cursor_rm(variable->content, &cpt); + return; + } + } + + THROWF(not_found_error, 0, + "Can't remove the value %d of config element %s: value not found.", + val, name); +} + /** @brief Remove the provided \e val peer value from a variable * * \arg cfg the config set @@ -1242,6 +1379,31 @@ char *xbt_cfg_get_string(xbt_cfg_t cfg, const char *name) return xbt_dynar_get_as(variable->content, 0, char *); } +/** @brief Retrieve a boolean value of a variable (get a warning if not uniq) + * + * \arg cfg the config set + * \arg name the name of the variable + * \arg val the wanted value + * + * Returns the first value from the config set under the given name. + * If there is more than one value, it will issue a warning. Consider using + * xbt_cfg_get_dynar() instead. + * + * \warning the returned value is the actual content of the config set + */ +int xbt_cfg_get_boolean(xbt_cfg_t cfg, const char *name) +{ + xbt_cfgelm_t variable = xbt_cfgelm_get(cfg, name, xbt_cfgelm_boolean); + + if (xbt_dynar_length(variable->content) > 1) { + XBT_WARN + ("You asked for the first value of the config element '%s', but there is %lu values", + name, xbt_dynar_length(variable->content)); + } + + return xbt_dynar_get_as(variable->content, 0, int); +} + /** @brief Retrieve an peer value of a variable (get a warning if not uniq) * * \arg cfg the config set @@ -1331,6 +1493,14 @@ char *xbt_cfg_get_string_at(xbt_cfg_t cfg, const char *name, int pos) return xbt_dynar_get_as(variable->content, pos, char *); } +/** @brief Retrieve one of the boolean value of a variable */ +int xbt_cfg_get_boolean_at(xbt_cfg_t cfg, const char *name, int pos) +{ + + xbt_cfgelm_t variable = xbt_cfgelm_get(cfg, name, xbt_cfgelm_boolean); + return xbt_dynar_get_as(variable->content, pos, int); +} + /** @brief Retrieve one of the peer value of a variable */ void xbt_cfg_get_peer_at(xbt_cfg_t cfg, const char *name, int pos, -- 2.20.1