-/* Copyright (c) 2004-2014,2016. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2004-2017. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <stdio.h>
+#include <cstdio>
#include <algorithm>
#include <cerrno>
#include <climits>
#include <functional>
+#include <map>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <typeinfo>
-#include <unordered_map>
#include <vector>
#include <xbt/ex.hpp>
static bool parseBool(const char* value)
{
- for (const char* true_value : true_values)
+ for (const char* const& true_value : true_values)
if (std::strcmp(true_value, value) == 0)
return true;
- for (const char* false_value : false_values)
+ for (const char* const& false_value : false_values)
if (std::strcmp(false_value, value) == 0)
return false;
throw std::range_error("not a boolean");
bool isdefault = true;
public:
-
/* Callback */
xbt_cfg_cb_t old_callback = nullptr;
TypedConfigurationElement(const char* key, const char* desc, T value = T())
: ConfigurationElement(key, desc), content(std::move(value))
{}
- TypedConfigurationElement(const char* key, const char* desc, T value,
- xbt_cfg_cb_t cb)
- : ConfigurationElement(key, desc, cb), content(std::move(value))
+ TypedConfigurationElement(const char* key, const char* desc, T value, xbt_cfg_cb_t cb)
+ : ConfigurationElement(key, desc, cb), content(std::move(value))
{}
- TypedConfigurationElement(const char* key, const char* desc, T value,
- std::function<void(T&)> callback)
- : ConfigurationElement(key, desc), content(std::move(value)),
- callback(std::move(callback))
+ TypedConfigurationElement(const char* key, const char* desc, T value, std::function<void(T&)> callback)
+ : ConfigurationElement(key, desc), content(std::move(value)), callback(std::move(callback))
{}
- ~TypedConfigurationElement()=default;
+ ~TypedConfigurationElement() = default;
std::string getStringValue() override;
const char* getTypeName() override;
this->content = std::move(value);
this->update();
} else {
- XBT_DEBUG("Do not override configuration variable '%s' with value '%s'"
- " because it was already set.", key.c_str(), to_string(value).c_str());
+ XBT_DEBUG("Do not override configuration variable '%s' with value '%s' because it was already set.", key.c_str(),
+ to_string(value).c_str());
}
}
};
class Config {
private:
// name -> ConfigElement:
- std::unordered_map<std::string, simgrid::config::ConfigurationElement*> options;
+ std::map<std::string, simgrid::config::ConfigurationElement*> options;
// alias -> xbt_dict_elm_t from options:
- std::unordered_map<std::string, simgrid::config::ConfigurationElement*> aliases;
+ std::map<std::string, simgrid::config::ConfigurationElement*> aliases;
+ bool warn_for_aliases = true;
public:
Config() = default;
Config::~Config()
{
XBT_DEBUG("Frees cfg set %p", this);
- for (auto elm : options)
+ for (auto const& elm : options)
delete elm.second;
}
inline ConfigurationElement* Config::getDictElement(const char* name)
{
- try {
- return options.at(name);
- } catch (std::out_of_range& unfound) {
- try {
- ConfigurationElement* res = aliases.at(name);
- XBT_INFO("Option %s has been renamed to %s. Consider switching.", name, res->getKey().c_str());
+ auto opt = options.find(name);
+ if (opt != options.end()) {
+ return opt->second;
+ } else {
+ auto als = aliases.find(name);
+ if (als != aliases.end()) {
+ ConfigurationElement* res = als->second;
+ if (warn_for_aliases)
+ XBT_INFO("Option %s has been renamed to %s. Consider switching.", name, res->getKey().c_str());
return res;
- } catch (std::out_of_range& missing_key) {
+ } else {
throw simgrid::config::missing_key_error(std::string("Bad config key: ") + name);
}
}
if (name)
printf("%s>> Dumping of the config set '%s':\n", indent, name);
- for (auto elm : options)
+ for (auto const& elm : options)
printf("%s %s: ()%s) %s", indent, elm.first.c_str(), elm.second->getTypeName(),
elm.second->getStringValue().c_str());
/** @brief Displays the declared aliases and their description */
void Config::showAliases()
{
- std::vector<std::string> names;
-
- for (auto elm : aliases)
- names.push_back(elm.first);
- std::sort(names.begin(), names.end());
-
- for (auto name : names)
- printf(" %s: %s\n", name.c_str(), (*this)[name.c_str()].getDescription().c_str());
+ bool old_warn_for_aliases = false;
+ std::swap(warn_for_aliases, old_warn_for_aliases);
+ for (auto const& elm : aliases)
+ printf(" %s: %s\n", elm.first.c_str(), (*this)[elm.first.c_str()].getDescription().c_str());
+ std::swap(warn_for_aliases, old_warn_for_aliases);
}
/** @brief Displays the declared options and their description */
void Config::help()
{
- std::vector<std::string> names;
-
- for (auto elm : options)
- names.push_back(elm.first);
- std::sort(names.begin(), names.end());
-
- for (auto name : names) {
- simgrid::config::ConfigurationElement* variable = this->options.at(name);
- printf(" %s: %s\n", name.c_str(), variable->getDescription().c_str());
+ for (auto const& elm : options) {
+ simgrid::config::ConfigurationElement* variable = this->options.at(elm.first);
+ printf(" %s: %s\n", elm.first.c_str(), variable->getDescription().c_str());
printf(" Type: %s; ", variable->getTypeName());
printf("Current value: %s\n", variable->getStringValue().c_str());
}
}
// Horrible mess to translate C++ exceptions to C exceptions:
-// Exit from the catch blog (and do the correct exceptio cleaning)
-// before attempting to THROWF.
+// Exit from the catch block (and do the correct exception cleaning) before attempting to THROWF.
#define TRANSLATE_EXCEPTIONS(...) \
catch(simgrid::config::missing_key_error& e) { THROWF(not_found_error, 0, __VA_ARGS__); abort(); } \
catch(...) { THROWF(not_found_error, 0, __VA_ARGS__); abort(); }
(*simgrid_config)[key].setDefaultValue<int>(value);
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to default integer %i",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to default integer %i", key, value);
}
/** @brief Set an integer value to \a name within \a cfg if it wasn't changed yet
(*simgrid_config)[key].setDefaultValue<double>(value);
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to default double %f",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to default double %f", key, value);
}
/** @brief Set a string value to \a name within \a cfg if it wasn't changed yet
(*simgrid_config)[key].setDefaultValue<std::string>(value ? value : "");
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to default string %s",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to default string %s", key, value);
}
/** @brief Set an boolean value to \a name within \a cfg if it wasn't changed yet
(*simgrid_config)[key].setDefaultValue<bool>(simgrid::config::parseBool(value));
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to default boolean %s",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to default boolean %s", key, value);
}
/** @brief Set an integer value to \a name within \a cfg
(*simgrid_config)[key].setValue<int>(value);
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to integer %i",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to integer %i", key, value);
}
/** @brief Set or add a double value to \a name within \a cfg
(*simgrid_config)[key].setValue<double>(value);
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to double %f",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to double %f", key, value);
}
/** @brief Set or add a string value to \a name within \a cfg
(*simgrid_config)[key].setValue<std::string>(value ? value : "");
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to string %s",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to string %s", key, value);
}
/** @brief Set or add a boolean value to \a name within \a cfg
(*simgrid_config)[key].setValue<bool>(simgrid::config::parseBool(value));
return;
}
- TRANSLATE_EXCEPTIONS("Could not set variable %s to boolean %s",
- key, value);
+ TRANSLATE_EXCEPTIONS("Could not set variable %s to boolean %s", key, value);
}
xbt_test_add("Get a single value");
{
/* get_single_value */
- int ival;
-
xbt_cfg_set_parse("peername:toto:42 speed:42");
- ival = xbt_cfg_get_int("speed");
+ int ival = xbt_cfg_get_int("speed");
if (ival != 42)
xbt_test_fail("Speed value = %d, I expected 42", ival);
}