From b612acf7efecfcf54481db931f9474a59142a569 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Thu, 17 Mar 2016 22:41:32 -0400 Subject: [PATCH] Rules: Added settings accessors --- src/Rules.cpp | 147 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/Rules.h | 19 ++++++- 2 files changed, 160 insertions(+), 6 deletions(-) diff --git a/src/Rules.cpp b/src/Rules.cpp index c1ed29bd..ddbb2f9c 100644 --- a/src/Rules.cpp +++ b/src/Rules.cpp @@ -27,7 +27,12 @@ #include #include #include +#include +#include #include +#include // TODO Remove +#include +#include //////////////////////////////////////////////////////////////////////////////// // Nested files are supported, with the following construct: @@ -51,11 +56,87 @@ void Rules::load (const std::string& file, int nest /* = 1 */) } //////////////////////////////////////////////////////////////////////////////// -// define r: -// name value -std::string Rules::get (const std::string& rule, const std::string& name) const +bool Rules::has (const std::string& key) const { - return ""; // TODO Replace + return _settings.find (key) != _settings.end (); +} + +//////////////////////////////////////////////////////////////////////////////// +// Return the configuration value given the specified key. +std::string Rules::get (const std::string& key) const +{ + auto found = _settings.find (key); + if (found != _settings.end ()) + return found->second; + + return ""; +} + +//////////////////////////////////////////////////////////////////////////////// +int Rules::getInteger (const std::string& key) const +{ + auto found = _settings.find (key); + if (found != _settings.end ()) + return strtoimax (found->second.c_str (), nullptr, 10); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +double Rules::getReal (const std::string& key) const +{ + auto found = _settings.find (key); + if (found != _settings.end ()) + return strtod (found->second.c_str (), nullptr); + + return 0.0; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Rules::getBoolean (const std::string& key) const +{ + auto found = _settings.find (key); + if (found != _settings.end ()) + { + auto value = lowerCase (found->second); + if (value == "true" || + value == "1" || + value == "y" || + value == "yes" || + value == "on") + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +void Rules::set (const std::string& key, const int value) +{ + _settings[key] = format (value); +} + +//////////////////////////////////////////////////////////////////////////////// +void Rules::set (const std::string& key, const double value) +{ + _settings[key] = format (value, 1, 8); +} + +//////////////////////////////////////////////////////////////////////////////// +void Rules::set (const std::string& key, const std::string& value) +{ + _settings[key] = value; +} + +//////////////////////////////////////////////////////////////////////////////// +// Provide a vector of all configuration keys. +std::vector Rules::all () const +{ + std::vector items; + for (const auto& it : _settings) + items.push_back (it.first); + + return items; } //////////////////////////////////////////////////////////////////////////////// @@ -66,12 +147,70 @@ std::string Rules::dump () const << " _original_file " << _original_file << "\n"; + out << " Settings\n"; + for (const auto& item : _settings) + out << " " << item.first << " " << item.second << "\n"; + return out.str (); } //////////////////////////////////////////////////////////////////////////////// void Rules::parse (const std::string& input, int nest /* = 1 */) { + // Indentation stack. + std::stack indent; + indent.push (0); + + // Parse each line. + for (auto& line : split (input, '\n')) + { + // Remove comments. + auto comment = line.find ("#"); + if (comment != std::string::npos) + line = line.substr (0, comment); + + // Skip empty lines. + line = rtrim (line); + if (line.length () > 0) + { + std::cout << "# Rules::parse " << line << "\n"; + + // TODO Count spaces at SOL. + auto indentation = line.find_first_not_of (' '); + if (indentation && indentation != std::string::npos) + std::cout << "# indentation " << indentation << "\n"; + +/* + auto equal = line.find ("="); + if (equal != std::string::npos) + { + std::string key = trim (line.substr (0, equal)); + std::string value = trim (line.substr (equal+1, line.length () - equal)); + + (*this)[key] = jsonDecode (value); + } + else + { + auto include = line.find ("include"); + if (include != std::string::npos) + { + Path included (trim (line.substr (include + 7))); + if (included.is_absolute ()) + { + if (included.readable ()) + load (included, nest + 1); + else + throw format ("Could not read include file '{1}'.", included._data); + } + else + throw format ("Can only include files with absolute paths, not '{1}'", included._data); + } + else + throw format ("Malformed entry '{1}' in config file.", line); + } +*/ + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Rules.h b/src/Rules.h index 06effd65..d44e25cc 100644 --- a/src/Rules.h +++ b/src/Rules.h @@ -27,6 +27,8 @@ #ifndef INCLUDED_RULES #define INCLUDED_RULES +#include +#include #include class Rules @@ -34,14 +36,27 @@ class Rules public: Rules () = default; void load (const std::string&, int next = 1); - std::string get (const std::string&, const std::string&) const; + + bool has (const std::string&) const; + std::string get (const std::string&) const; + int getInteger (const std::string&) const; + double getReal (const std::string&) const; + bool getBoolean (const std::string&) const; + + void set (const std::string&, const int); + void set (const std::string&, const double); + void set (const std::string&, const std::string&); + + std::vector all () const; + std::string dump () const; private: void parse (const std::string&, int next = 1); private: - std::string _original_file {}; + std::string _original_file {}; + std::map _settings {}; }; #endif