6 #ifndef OPENMPCD_CONFIGURATION_HPP
7 #define OPENMPCD_CONFIGURATION_HPP
15 #include <boost/algorithm/string.hpp>
16 #include <libconfig.h++>
46 Setting(
const libconfig::Setting& s) : setting(&s)
55 return setting->getName() != NULL;
71 return setting->getName();
82 bool has(
const std::string& settingName)
const
84 const std::string::size_type dot = settingName.find(
".");
86 if(dot != std::string::npos)
88 if(dot == 0 || dot + 1 >= settingName.size())
92 settingName +
" is not a legal setting name.");
95 const std::string first = settingName.substr(0, dot);
97 if(!setting->exists(first))
100 const Setting subsetting(setting->lookup(first));
102 const std::string second = settingName.substr(dot + 1);
103 return subsetting.
has(second);
106 return setting->exists(settingName);
130 template<
typename ValueType>
131 void read(
const std::string& name, ValueType*
const value)
134 #ifdef OPENMPCD_DEBUG
139 const std::string::size_type dot = name.find(
".");
141 if(dot != std::string::npos)
143 if(dot == 0 || dot + 1 >= name.size())
147 name +
" is not a legal setting name.");
150 const std::string first = name.substr(0, dot);
152 if(!setting->exists(first))
156 name +
" does not exist.");
159 const Setting subsetting(setting->lookup(first));
161 const std::string second = name.substr(dot + 1);
162 return subsetting.
read(second, value);
165 if(!setting->lookupValue(name, *value))
167 if(!setting->exists(name))
170 name+
" does not exist.");
172 const libconfig::Setting::Type type =
173 setting->lookup(name).getType();
174 const std::string typeString =
180 name +
" has an unexpected type: " + typeString);
203 void read(
const std::string& name, std::size_t*
const value)
222 template<
typename ValueType>
223 ValueType
read(
const std::string& name)
const
237 return static_cast<std::size_t
>(setting->getLength());
252 typedef libconfig::Setting::const_iterator It;
254 std::size_t current = 0;
255 for(It it = setting->begin(); it != setting->end(); ++it)
257 if(current == childIndex)
281 name +
" does not exist.");
284 return Setting(setting->lookup(name));
313 const std::set<std::string>& names,
314 std::string*
const offender = NULL)
const;
317 const libconfig::Setting* setting;
334 List(
const libconfig::Setting& s) : setting(&s)
336 #ifdef OPENMPCD_DEBUG
337 if(!setting->isArray() && !setting->isList())
348 return setting->getLength();
367 return Setting((*setting)[index]);
381 const libconfig::Setting& child = (*setting)[index];
383 if(!child.isArray() && !child.isList())
399 template<
typename ValueType>
400 void read(
const unsigned int index, ValueType*
const value)
const
402 #ifdef OPENMPCD_DEBUG
409 *value=
static_cast<ValueType
>((*setting)[index]);
415 "Setting has an unexpected type or does not exist.");
435 const unsigned int index, std::string*
const value)
438 #ifdef OPENMPCD_DEBUG
445 *value = (*setting)[index].operator std::string();
451 "Setting has an unexpected type or does not "
463 template<
typename ValueType>
464 ValueType
read(
const unsigned int index)
const
472 const libconfig::Setting* setting;
509 bool has(
const std::string& setting)
const
511 return config.exists(setting);
522 template<
typename ValueType,
unsigned int settingsCount>
523 void read(
const std::pair<const char*, ValueType*> (&settingsAndValues)[settingsCount])
const
525 for(
unsigned int i=0; i<settingsCount; ++i)
526 read(settingsAndValues[i].first, settingsAndValues[i].second);
537 template<
typename ValueType>
538 void read(
const std::string& setting, ValueType*
const value)
const
540 #ifdef OPENMPCD_DEBUG
545 if(!config.lookupValue(setting, *value))
547 if(!config.exists(setting))
550 const libconfig::Setting::Type type = config.lookup(setting).getType();
563 template<
typename ValueType>
564 ValueType
read(
const std::string& setting)
const
567 read(setting, &value);
587 return Setting(config.lookup(name));
601 const libconfig::Setting& child = config.lookup(name);
603 if(!child.isArray() && !child.isList())
616 template <
typename ValueType>
617 void assertValue(
const std::string& setting,
const ValueType& value)
const
619 ValueType configValue;
620 if(!config.lookupValue(setting, configValue))
623 if(configValue!=value)
625 std::stringstream message;
626 message<<setting<<
": value is \""<<configValue<<
"\", expected \""<<value<<
"\"";
639 void assertValue(
const std::string& setting,
const char (&value)[N])
const
641 std::string configValue;
642 if(!config.lookupValue(setting, configValue))
645 if(configValue!=value)
647 std::stringstream message;
648 message<<setting<<
": value is \""<<configValue<<
"\", expected \""<<value<<
"\"";
660 template<
typename ValueType>
661 void set(
const std::string& setting,
const ValueType value)
663 std::vector<std::string> pathComponents;
664 boost::algorithm::split(pathComponents, setting, boost::algorithm::is_any_of(
"."));
666 libconfig::Setting* currentSetting = &config.getRoot();
667 for(
unsigned int level=0; level < pathComponents.size(); ++level)
669 const bool isLastLevel = level + 1 == pathComponents.size();
670 const std::string currentName = pathComponents[level];
674 if(currentSetting->exists(currentName))
678 (*currentSetting)[currentName.c_str()] = value;
680 catch(
const libconfig::SettingTypeException&)
692 if(currentSetting->exists(currentName))
694 std::string lookupPath = currentSetting->getPath();
695 if(!lookupPath.empty())
697 lookupPath += currentName;
699 currentSetting = &config.lookup(lookupPath);
700 #ifdef OPENMPCD_DEBUG
701 if(!currentSetting->isAggregate())
707 currentSetting = ¤tSetting->add(currentName, libconfig::Setting::TypeGroup);
721 createAggregateSetting(name, libconfig::Setting::TypeGroup);
732 createAggregateSetting(name, libconfig::Setting::TypeList);
741 config.writeFile(path.c_str());
767 void createAggregateSetting(
const std::string& name,
const libconfig::Setting::Type type)
773 type != libconfig::Setting::TypeGroup &&
774 type != libconfig::Setting::TypeArray &&
775 type != libconfig::Setting::TypeList)
780 std::vector<std::string> pathComponents;
781 boost::algorithm::split(pathComponents, name, boost::algorithm::is_any_of(
"."));
783 libconfig::Setting* currentSetting = &config.getRoot();
784 for(
unsigned int level=0; level < pathComponents.size(); ++level)
786 const std::string currentName = pathComponents[level];
788 if(currentSetting->exists(currentName))
790 std::string lookupPath = currentSetting->getPath();
791 if(!lookupPath.empty())
793 lookupPath += currentName;
795 currentSetting = &config.lookup(lookupPath);
799 const bool isLastLevel = level + 1 == pathComponents.size();
800 const libconfig::Setting::Type typeToCreate = isLastLevel ? type : libconfig::Setting::TypeGroup;
801 currentSetting = ¤tSetting->add(currentName, typeToCreate);
807 mutable libconfig::Config config;
811 const Configuration::List
818 name +
" does not exist.");
821 return List(setting->lookup(name));
824 #ifdef OPENMPCD_COMPILER_GCC
825 #pragma GCC diagnostic push
826 #pragma GCC diagnostic ignored "-Wsign-compare"
841 if(
static_cast<int>(value) == value)
843 set(setting,
static_cast<int>(value));
847 #ifdef OPENMPCD_DEBUG
848 if(
static_cast<long long int>(value) != value)
852 set(setting,
static_cast<long long int>(value));
855 #ifdef OPENMPCD_COMPILER_GCC
856 #pragma GCC diagnostic pop