1 /* Copyright (c) 2004-2014,2016. The SimGrid Team.
2 * All rights reserved. */
12 #include <type_traits>
14 #include <xbt/config.h>
15 #include <xbt/config.hpp>
17 #include "xbt/sysdep.h"
20 #include "xbt/dynar.h"
25 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_cfg, xbt, "configuration support");
27 XBT_EXPORT_NO_IMPORT(xbt_cfg_t) simgrid_config = NULL;
29 /** @brief possible content of each configuration cell */
31 xbt_cfgelm_int = 0, /**< int */
32 xbt_cfgelm_double, /**< double */
33 xbt_cfgelm_string, /**< char* */
34 xbt_cfgelm_boolean, /**< int */
36 xbt_cfgelm_any, /* not shown to users to prevent errors */
39 } e_xbt_cfgelm_type_t;
45 void increment(e_xbt_cfgelm_type_t& type)
47 typedef std::underlying_type<e_xbt_cfgelm_type_t>::type underlying_type;
48 type = (e_xbt_cfgelm_type_t) ((underlying_type) type + 1);
53 static const char *xbt_cfgelm_type_name[xbt_cfgelm_type_count] = {
54 "int", "double", "string", "boolean", "any"
57 /** Boolean possible values **/
58 struct xbt_boolean_couple {
60 const char *false_val;
63 const struct xbt_boolean_couple xbt_cfgelm_boolean_values[] = {
73 struct ConfigurationElement ;
78 /* Retrieve the variable we'll modify */
79 static simgrid::config::ConfigurationElement* xbt_cfgelm_get(xbt_cfg_t cfg, const char *name, e_xbt_cfgelm_type_t type);
84 // A configuration variable:
85 struct ConfigurationElement {
89 /* Allowed type of the variable */
90 e_xbt_cfgelm_type_t type;
91 bool isdefault = true;
94 xbt_cfg_cb_t cb_set = nullptr;
96 /* Advanced callback (for xbt_cfgelm_string only) */
97 std::function<void(const char* value)> callback;
101 double double_content;
102 char* string_content;
103 bool boolean_content;
106 ~ConfigurationElement()
108 XBT_DEBUG("Frees cfgelm %p", this);
111 case xbt_cfgelm_double:
112 case xbt_cfgelm_boolean:
114 case xbt_cfgelm_string:
115 free(string_content);
118 xbt_die("Unexpected config type");
125 // name -> ConfigElement:
127 // alias -> xbt_dict_elm_t from options:
135 Config(Config const&) = delete;
136 Config& operator=(Config const&) = delete;
138 xbt_dictelm_t getElement(const char* name);
139 ConfigurationElement* operator[](const char* name);
140 void alias(const char* realname, const char* aliasname);
142 simgrid::config::ConfigurationElement* registerOption(
143 const char *name, const char *desc, e_xbt_cfgelm_type_t type,
144 xbt_cfg_cb_t cb_set);
147 void dump(const char *name, const char *indent);
152 /* Internal stuff used in cache to free a variable */
153 static void xbt_cfgelm_free(void *data)
156 delete (simgrid::config::ConfigurationElement*) data;
160 options(xbt_dict_new_homogeneous(xbt_cfgelm_free)),
161 aliases(xbt_dict_new_homogeneous(NULL))
166 XBT_DEBUG("Frees cfg set %p", this);
167 xbt_dict_free(&this->options);
168 xbt_dict_free(&this->aliases);
172 xbt_dictelm_t Config::getElement(const char* name)
174 // We are interested in the options dictelm:
175 xbt_dictelm_t res = xbt_dict_get_elm_or_null(options, name);
178 // The aliases dict stores pointers to the options dictelm:
179 res = (xbt_dictelm_t) xbt_dict_get_or_null(aliases, name);
181 XBT_INFO("Option %s has been renamed to %s. Consider switching.", name, res->key);
186 ConfigurationElement* Config::operator[](const char* name)
188 xbt_dictelm_t elm = getElement(name);
190 return (ConfigurationElement*) elm->content;
195 void Config::alias(const char* realname, const char* aliasname)
197 xbt_assert(this->getElement(aliasname) == nullptr, "Alias '%s' already.", aliasname);
198 xbt_dictelm_t element = this->getElement(realname);
199 xbt_assert(element, "Cannot define an alias to the non-existing option '%s'.", realname);
200 xbt_dict_set(this->aliases, aliasname, element, NULL);
203 /** @brief Dump a config set for debuging purpose
205 * @param name The name to give to this config set
206 * @param indent what to write at the beginning of each line (right number of spaces)
208 void Config::dump(const char *name, const char *indent)
210 xbt_dict_t dict = this->options;
211 xbt_dict_cursor_t cursor = NULL;
212 simgrid::config::ConfigurationElement* variable = NULL;
216 printf("%s>> Dumping of the config set '%s':\n", indent, name);
218 xbt_dict_foreach(dict, cursor, key, variable) {
219 const char* type_name = xbt_cfgelm_type_name[variable->type];
220 switch (variable->type) {
222 printf("%s %s: ()%s) %i", indent, key, type_name, variable->int_content);
224 case xbt_cfgelm_double:
225 printf("%s %s: ()%s) %f", indent, key, type_name, variable->double_content);
227 case xbt_cfgelm_string:
228 printf("%s %s: ()%s) %s", indent, key, type_name, variable->string_content);
230 case xbt_cfgelm_boolean:
231 printf("%s %s: ()%s) %s", indent, key, type_name,
232 variable->boolean_content ? "true" : "false");
235 printf("%s Invalid type!!\n", indent);
241 printf("%s<< End of the config set '%s'\n", indent, name);
244 xbt_dict_cursor_free(&cursor);
247 simgrid::config::ConfigurationElement* Config::registerOption(
248 const char *name, const char *desc, e_xbt_cfgelm_type_t type, xbt_cfg_cb_t cb_set)
250 xbt_assert(type >= xbt_cfgelm_int && type <= xbt_cfgelm_boolean,
251 "type of %s not valid (%d should be between %d and %d)",
252 name, (int)type, xbt_cfgelm_int, xbt_cfgelm_boolean);
254 simgrid::config::ConfigurationElement* res = (simgrid::config::ConfigurationElement*) xbt_dict_get_or_null(this->options, name);
255 xbt_assert(NULL == res, "Refusing to register the config element '%s' twice.", name);
257 res = new simgrid::config::ConfigurationElement();
258 XBT_DEBUG("Register cfg elm %s (%s) (%s (=%d) @%p in set %p)",
259 name, desc, xbt_cfgelm_type_name[type], (int)type, res, this);
261 res->cb_set = cb_set;
265 // Set a default default value:
268 res->int_content = 0;
270 case xbt_cfgelm_double:
271 res->double_content = 0.0;
273 case xbt_cfgelm_string:
274 res->string_content = nullptr;
276 case xbt_cfgelm_boolean:
277 res->boolean_content = false;
280 XBT_ERROR("%d is an invalid type code", (int)type);
284 xbt_dict_set(this->options, name, res, NULL);
288 /** @brief Displays the declared aliases and their description */
289 void Config::showAliases()
291 xbt_dict_cursor_t dict_cursor;
292 unsigned int dynar_cursor;
293 xbt_dictelm_t dictel;
295 xbt_dynar_t names = xbt_dynar_new(sizeof(char *), NULL);
297 xbt_dict_foreach(this->aliases, dict_cursor, name, dictel)
298 xbt_dynar_push(names, &name);
299 xbt_dynar_sort_strings(names);
301 xbt_dynar_foreach(names, dynar_cursor, name) {
302 simgrid::config::ConfigurationElement* variable = (*this)[name];
304 printf(" %s: %s\n", name, variable->desc.c_str());
308 /** @brief Displays the declared options and their description */
311 xbt_dict_cursor_t dict_cursor;
312 unsigned int dynar_cursor;
313 simgrid::config::ConfigurationElement* variable;
315 xbt_dynar_t names = xbt_dynar_new(sizeof(char *), NULL);
317 xbt_dict_foreach(this->options, dict_cursor, name, variable)
318 xbt_dynar_push(names, &name);
319 xbt_dynar_sort_strings(names);
321 xbt_dynar_foreach(names, dynar_cursor, name) {
322 variable = (simgrid::config::ConfigurationElement*) xbt_dict_get(this->options, name);
324 printf(" %s: %s\n", name, variable->desc.c_str());
325 printf(" Type: %s; ", xbt_cfgelm_type_name[variable->type]);
326 printf("Current value: ");
328 switch (variable->type) {
330 printf("%d\n", variable->int_content);
332 case xbt_cfgelm_double:
333 printf("%f\n", variable->double_content);
335 case xbt_cfgelm_string:
336 printf("'%s'\n", variable->string_content);
338 case xbt_cfgelm_boolean:
339 printf("'%s'\n", variable->boolean_content ? "true" : "false");
342 printf("Invalid type!!\n");
347 xbt_dynar_free(&names);
355 /** @brief Constructor */
356 xbt_cfg_t xbt_cfg_new(void) { return new simgrid::config::Config(); }
357 /** @brief Destructor */
358 void xbt_cfg_free(xbt_cfg_t * cfg) { delete *cfg; }
360 void xbt_cfg_dump(const char *name, const char *indent, xbt_cfg_t cfg)
362 cfg->dump(name, indent);
365 /*----[ Registering stuff ]-----------------------------------------------*/
366 /** @brief Register an element within a config set
368 * @param cfg the config set
369 * @param name the name of the config element
370 * @param desc a description for this item (used by xbt_cfg_help())
371 * @param type the type of the config element
372 * @param cb_set callback function called when a value is set
374 static simgrid::config::ConfigurationElement* xbt_cfg_register(
375 xbt_cfg_t * cfg, const char *name, const char *desc, e_xbt_cfgelm_type_t type, xbt_cfg_cb_t cb_set)
378 *cfg = xbt_cfg_new();
379 return (*cfg)->registerOption(name, desc, type, cb_set);
382 void xbt_cfg_register_double(const char *name, double default_value,xbt_cfg_cb_t cb_set, const char *desc)
384 xbt_cfg_register(&simgrid_config, name, desc, xbt_cfgelm_double, cb_set);
385 xbt_cfg_setdefault_double(name, default_value);
387 void xbt_cfg_register_int(const char *name, int default_value,xbt_cfg_cb_t cb_set, const char *desc)
389 xbt_cfg_register(&simgrid_config, name, desc, xbt_cfgelm_int, cb_set);
390 xbt_cfg_setdefault_int(name, default_value);
392 void xbt_cfg_register_string(const char *name, const char *default_value, xbt_cfg_cb_t cb_set, const char *desc)
394 xbt_cfg_register(&simgrid_config,name,desc,xbt_cfgelm_string,cb_set);
395 xbt_cfg_setdefault_string(name, default_value);
397 void xbt_cfg_register_boolean(const char *name, const char*default_value,xbt_cfg_cb_t cb_set, const char *desc)
399 xbt_cfg_register(&simgrid_config,name,desc,xbt_cfgelm_boolean,cb_set);
400 xbt_cfg_setdefault_boolean(name, default_value);
403 void xbt_cfg_register_alias(const char *realname, const char *aliasname)
405 if (simgrid_config == NULL)
406 simgrid_config = xbt_cfg_new();
407 simgrid_config->alias(realname, aliasname);
411 * @brief Parse a string and register the stuff described.
413 * @param cfg the config set
414 * @param entry a string describing the element to register
416 * The string may consist in several variable descriptions separated by a space.
417 * Each of them must use the following syntax: \<name\>:\<type\>
418 * with type being one of 'string','int','bool' or 'double'.
420 * Note that this does not allow to set the description, so you should prefer the other interface
422 void xbt_cfg_register_str(xbt_cfg_t * cfg, const char *entry)
424 char *entrycpy = xbt_strdup(entry);
427 e_xbt_cfgelm_type_t type;
428 XBT_DEBUG("Register string '%s'", entry);
430 tok = strchr(entrycpy, ':');
431 xbt_assert(tok, "Invalid config element descriptor: %s; Should be <name>:<type>", entry);
434 for (type = (e_xbt_cfgelm_type_t)0; type < xbt_cfgelm_type_count && strcmp(tok, xbt_cfgelm_type_name[type]); increment(type));
435 xbt_assert(type < xbt_cfgelm_type_count,
436 "Invalid type in config element descriptor: %s; Should be one of 'string', 'int' or 'double'.", entry);
438 xbt_cfg_register(cfg, entrycpy, NULL, type, NULL);
440 free(entrycpy); /* strdup'ed by dict mechanism, but cannot be const */
443 void xbt_cfg_aliases(void) { simgrid_config->showAliases(); }
444 void xbt_cfg_help(void) { simgrid_config->help(); }
446 static simgrid::config::ConfigurationElement* xbt_cfgelm_get(xbt_cfg_t cfg, const char *name, e_xbt_cfgelm_type_t type)
448 simgrid::config::ConfigurationElement* res = (*cfg)[name];
453 THROWF(not_found_error, 0, "No registered variable '%s' in this config set.", name);
456 xbt_assert(type == xbt_cfgelm_any || res->type == type,
457 "You tried to access to the config element %s as an %s, but its type is %s.",
458 name, xbt_cfgelm_type_name[type], xbt_cfgelm_type_name[res->type]);
462 /*----[ Setting ]---------------------------------------------------------*/
464 /** @brief Add values parsed from a string into a config set
466 * @param options a string containing the content to add to the config set. This is a '\\t',' ' or '\\n' or ','
467 * separated list of variables. Each individual variable is like "[name]:[value]" where [name] is the name of an
468 * already registered variable, and [value] conforms to the data type under which this variable was registered.
470 * @todo This is a crude manual parser, it should be a proper lexer.
472 void xbt_cfg_set_parse(const char *options)
474 if (!options || !strlen(options)) { /* nothing to do */
477 char *optionlist_cpy = xbt_strdup(options);
479 XBT_DEBUG("List to parse and set:'%s'", options);
480 char *option = optionlist_cpy;
481 while (1) { /* breaks in the code */
485 int len = strlen(name);
486 XBT_DEBUG("Still to parse and set: '%s'. len=%d; option-name=%ld", name, len, (long) (option - name));
489 while (option - name <= (len - 1) && *option != ' ' && *option != '\n' && *option != '\t' && *option != ',') {
490 XBT_DEBUG("Take %c.", *option);
493 if (option - name == len) {
494 XBT_DEBUG("Boundary=EOL");
495 option = NULL; /* don't do next iteration */
497 XBT_DEBUG("Boundary on '%c'. len=%d;option-name=%ld", *option, len, (long) (option - name));
498 /* Pass the following blank chars */
500 while (option - name < (len - 1) && (*option == ' ' || *option == '\n' || *option == '\t')) {
501 /* fprintf(stderr,"Ignore a blank char.\n"); */
504 if (option - name == len - 1)
505 option = NULL; /* don't do next iteration */
507 XBT_DEBUG("parse now:'%s'; parse later:'%s'", name, option);
509 if (name[0] == ' ' || name[0] == '\n' || name[0] == '\t')
514 char *val = strchr(name, ':');
515 xbt_assert(val, "Option '%s' badly formatted. Should be of the form 'name:value'", name);
516 /* don't free(optionlist_cpy) if the assert fails, 'name' points inside it */
519 if (strncmp(name, "contexts/", strlen("contexts/")) && strncmp(name, "path", strlen("path")))
520 XBT_INFO("Configuration change: Set '%s' to '%s'", name, val);
523 xbt_cfg_set_as_string(name,val);
525 free(optionlist_cpy);
529 free(optionlist_cpy);
532 /** @brief Set the value of a variable, using the string representation of that value
534 * @param key name of the variable to modify
535 * @param value string representation of the value to set
538 void xbt_cfg_set_as_string(const char *key, const char *value)
540 simgrid::config::ConfigurationElement* variable = (*simgrid_config)[key];
541 if (variable == nullptr)
542 THROWF(not_found_error, 0, "No registered variable corresponding to '%s'.", key);
548 switch (variable->type) {
549 case xbt_cfgelm_string:
550 xbt_cfg_set_string(key, value); /* throws */
553 i = strtol(value, &ret, 0);
554 if (ret == value || *ret != '\0')
555 xbt_die("Value of option %s not valid. Should be an integer", key);
556 xbt_cfg_set_int(key, i); /* throws */
558 case xbt_cfgelm_double:
559 d = strtod(value, &ret);
560 if (ret == value || *ret != '\0')
561 xbt_die("Value of option %s not valid. Should be a double", key);
562 xbt_cfg_set_double(key, d); /* throws */
564 case xbt_cfgelm_boolean:
565 xbt_cfg_set_boolean(key, value); /* throws */
568 THROWF(unknown_error, 0, "Type of config element %s is not valid.", key);
573 /** @brief Set an integer value to \a name within \a cfg if it wasn't changed yet
575 * This is useful to change the default value of a variable while allowing
576 * users to override it with command line arguments
578 void xbt_cfg_setdefault_int(const char *name, int val)
580 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_int);
582 if (variable->isdefault){
583 xbt_cfg_set_int(name, val);
584 variable->isdefault = true;
586 XBT_DEBUG("Do not override configuration variable '%s' with value '%d' because it was already set.", name, val);
589 /** @brief Set an integer value to \a name within \a cfg if it wasn't changed yet
591 * This is useful to change the default value of a variable while allowing
592 * users to override it with command line arguments
594 void xbt_cfg_setdefault_double(const char *name, double val)
596 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_double);
598 if (variable->isdefault) {
599 xbt_cfg_set_double(name, val);
600 variable->isdefault = true;
602 XBT_DEBUG("Do not override configuration variable '%s' with value '%f' because it was already set.", name, val);
605 /** @brief Set a string value to \a name within \a cfg if it wasn't changed yet
607 * This is useful to change the default value of a variable while allowing
608 * users to override it with command line arguments
610 void xbt_cfg_setdefault_string(const char *name, const char *val)
612 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_string);
614 if (variable->isdefault){
615 xbt_cfg_set_string(name, val);
616 variable->isdefault = true;
618 XBT_DEBUG("Do not override configuration variable '%s' with value '%s' because it was already set.", name, val);
621 /** @brief Set an boolean value to \a name within \a cfg if it wasn't changed yet
623 * This is useful to change the default value of a variable while allowing
624 * users to override it with command line arguments
626 void xbt_cfg_setdefault_boolean(const char *name, const char *val)
628 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_boolean);
630 if (variable->isdefault){
631 xbt_cfg_set_boolean(name, val);
632 variable->isdefault = true;
635 XBT_DEBUG("Do not override configuration variable '%s' with value '%s' because it was already set.", name, val);
638 /** @brief Set an integer value to \a name within \a cfg
640 * @param name the name of the variable
641 * @param val the value of the variable
643 void xbt_cfg_set_int(const char *name, int val)
645 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_int);
646 variable->int_content = val;
647 if (variable->cb_set)
648 variable->cb_set(name);
649 variable->isdefault = false;
652 /** @brief Set or add a double value to \a name within \a cfg
654 * @param name the name of the variable
655 * @param val the double to set
657 void xbt_cfg_set_double(const char *name, double val)
659 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_double);
660 variable->double_content = val;
661 if (variable->cb_set)
662 variable->cb_set(name);
663 variable->isdefault = false;
666 /** @brief Set or add a string value to \a name within \a cfg
668 * @param cfg the config set
669 * @param name the name of the variable
670 * @param val the value to be added
673 void xbt_cfg_set_string(const char *name, const char *val)
675 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_string);
676 free(variable->string_content);
677 variable->string_content = xbt_strdup(val);
678 if (variable->cb_set)
679 variable->cb_set(name);
680 variable->isdefault = false;
682 if (variable->callback) {
684 variable->callback(val);
686 catch(std::range_error& e) {
687 xbt_die("Invalid flag %s=%s: %s", val, name, e.what());
689 catch(std::exception& e) {
690 xbt_die("Error for flag %s=%s: %s", val, name, e.what());
693 xbt_die("Error for flag %s=%s", val, name);
698 /** @brief Set or add a boolean value to \a name within \a cfg
700 * @param name the name of the variable
701 * @param val the value of the variable
703 void xbt_cfg_set_boolean(const char *name, const char *val)
706 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_boolean);
708 for (int i = 0; xbt_cfgelm_boolean_values[i].true_val != NULL; i++) {
709 if (strcmp(val, xbt_cfgelm_boolean_values[i].true_val) == 0){
713 if (strcmp(val, xbt_cfgelm_boolean_values[i].false_val) == 0){
718 xbt_assert(bval != -1, "Value of option '%s' not valid. Should be a boolean (yes,no,on,off,true,false,0,1)", val);
719 variable->boolean_content = bval;
720 if (variable->cb_set)
721 variable->cb_set(name);
722 variable->isdefault = false;
726 /* Say if the value is the default value */
727 int xbt_cfg_is_default_value(const char *name)
729 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_any);
730 return variable->isdefault;
733 /*----[ Getting ]---------------------------------------------------------*/
734 /** @brief Retrieve an integer value of a variable (get a warning if not uniq)
736 * @param name the name of the variable
738 * Returns the first value from the config set under the given name.
740 int xbt_cfg_get_int(const char *name)
742 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_int);
743 return variable->int_content;
746 /** @brief Retrieve a double value of a variable (get a warning if not uniq)
748 * @param cfg the config set
749 * @param name the name of the variable
751 * Returns the first value from the config set under the given name.
753 double xbt_cfg_get_double(const char *name)
755 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_double);
756 return variable->double_content;
759 /** @brief Retrieve a string value of a variable (get a warning if not uniq)
761 * @param cfg the config set
762 * @param name the name of the variable
764 * Returns the first value from the config set under the given name.
765 * If there is more than one value, it will issue a warning.
766 * Returns NULL if there is no value.
768 * \warning the returned value is the actual content of the config set
770 char *xbt_cfg_get_string(const char *name)
772 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_string);
773 return variable->string_content;
776 /** @brief Retrieve a boolean value of a variable (get a warning if not uniq)
778 * @param cfg the config set
779 * @param name the name of the variable
781 * Returns the first value from the config set under the given name.
782 * If there is more than one value, it will issue a warning.
784 int xbt_cfg_get_boolean(const char *name)
786 simgrid::config::ConfigurationElement* variable = xbt_cfgelm_get(simgrid_config, name, xbt_cfgelm_boolean);
787 return variable->boolean_content;
793 bool parseBool(const char* value)
795 for (int i = 0; xbt_cfgelm_boolean_values[i].true_val != NULL; i++) {
796 if (std::strcmp(value, xbt_cfgelm_boolean_values[i].true_val) == 0)
798 if (std::strcmp(value, xbt_cfgelm_boolean_values[i].false_val) == 0)
801 throw std::range_error("not a boolean");
804 double parseDouble(const char* value)
808 double res = std::strtod(value, &end);
810 throw std::range_error("out of range");
812 xbt_die("Unexpected errno");
813 if (end == value || *end != '\0')
814 throw std::range_error("invalid double");
819 long int parseLong(const char* value)
823 long int res = std::strtol(value, &end, 0);
825 if (res == LONG_MIN && errno == ERANGE)
826 throw std::range_error("underflow");
827 else if (res == LONG_MAX && errno == ERANGE)
828 throw std::range_error("overflow");
829 xbt_die("Unexpected errno");
831 if (end == value || *end != '\0')
832 throw std::range_error("invalid integer");
837 void declareFlag(const char* name, const char* description,
838 std::function<void(const char* value)> callback)
840 simgrid::config::ConfigurationElement* e = xbt_cfg_register(
841 &simgrid_config, name, description, xbt_cfgelm_string, NULL);
842 e->callback = std::move(callback);
855 #include <xbt/config.hpp>
857 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(xbt_cfg);
859 XBT_TEST_SUITE("config", "Configuration support");
861 static xbt_cfg_t make_set()
863 xbt_cfg_t set = NULL;
865 xbt_log_threshold_set(&_XBT_LOGV(xbt_cfg), xbt_log_priority_critical);
866 xbt_cfg_register_str(&set, "speed:int");
867 xbt_cfg_register_str(&set, "peername:string");
868 xbt_cfg_register_str(&set, "user:string");
871 } /* end_of_make_set */
873 XBT_PUBLIC_DATA(xbt_cfg_t) simgrid_config;
875 XBT_TEST_UNIT("memuse", test_config_memuse, "Alloc and free a config set")
877 simgrid_config = make_set();
878 xbt_test_add("Alloc and free a config set");
879 xbt_cfg_set_parse("peername:veloce user:bidule");
880 xbt_cfg_free(&simgrid_config);
883 XBT_TEST_UNIT("use", test_config_use, "Data retrieving tests")
885 simgrid_config = make_set();
886 xbt_test_add("Get a single value");
888 /* get_single_value */
891 xbt_cfg_set_parse("peername:toto:42 speed:42");
892 ival = xbt_cfg_get_int("speed");
894 xbt_test_fail("Speed value = %d, I expected 42", ival);
897 xbt_test_add("Access to a non-existant entry");
902 xbt_cfg_set_parse("color:blue");
904 if (e.category != not_found_error)
905 xbt_test_exception(e);
909 xbt_cfg_free(&simgrid_config);
912 XBT_TEST_UNIT("c++flags", test_config_cxx_flags, "C++ flags")
914 simgrid_config = make_set();
915 xbt_test_add("C++ declaration of flags");
917 simgrid::config::Flag<int> int_flag("int", "", 0);
918 simgrid::config::Flag<std::string> string_flag("string", "", "foo");
919 simgrid::config::Flag<double> double_flag("double", "", 0.32);
920 simgrid::config::Flag<bool> bool_flag1("bool1", "", false);
921 simgrid::config::Flag<bool> bool_flag2("bool2", "", true);
923 xbt_test_add("Parse values");
924 xbt_cfg_set_parse("int:42 string:bar double:8.0 bool1:true bool2:false");
925 xbt_test_assert(int_flag == 42, "Check int flag");
926 xbt_test_assert(string_flag == "bar", "Check string flag");
927 xbt_test_assert(double_flag == 8.0, "Check double flag");
928 xbt_test_assert(bool_flag1, "Check bool1 flag");
929 xbt_test_assert(!bool_flag2, "Check bool2 flag");
931 xbt_cfg_free(&simgrid_config);
934 #endif /* SIMGRID_TEST */