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