From 385dd9917fd4ced23a704f0566779d58f5a6b727 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 14 Dec 2010 15:16:49 +0200 Subject: settings manager: better default setting handling and updating config file and command line parsing --- src/utility.h | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 255 insertions(+), 6 deletions(-) (limited to 'src/utility.h') diff --git a/src/utility.h b/src/utility.h index afcb4e414..f7e726f87 100644 --- a/src/utility.h +++ b/src/utility.h @@ -668,6 +668,23 @@ inline s32 stoi(std::string s) Config stuff */ +enum ValueType +{ + VALUETYPE_STRING, + VALUETYPE_FLAG // Doesn't take any arguments +}; + +struct ValueSpec +{ + ValueSpec(ValueType a_type, const char *a_help=NULL) + { + type = a_type; + help = a_help; + } + ValueType type; + const char *help; +}; + class Settings { public: @@ -710,36 +727,255 @@ public: return true; } - // Returns true on success + /* + Read configuration file + + Returns true on success + */ bool readConfigFile(const char *filename) { std::ifstream is(filename); if(is.good() == false) { - dstream<<"Error opening configuration file: " - < &dst, + core::map &updated) + { + if(is.eof()) + return false; + + // NOTE: This function will be expanded to allow multi-line settings + std::string line; + std::getline(is, line); + + std::string trimmedline = trim(line); + + std::string line_end = ""; + if(is.eof() == false) + line_end = "\n"; + + // Ignore comments + if(trimmedline[0] == '#') + { + dst.push_back(line+line_end); + return true; + } + + Strfnd sf(trim(line)); + + std::string name = sf.next("="); + name = trim(name); + + if(name == "") + { + dst.push_back(line+line_end); + return true; + } + + std::string value = sf.next("\n"); + value = trim(value); + + if(m_settings.find(name)) + { + std::string newvalue = m_settings[name]; + + if(newvalue != value) + { + dstream<<"Changing value of \""< \""< objects; + core::map updated; + + // Read and modify stuff + { + std::ifstream is(filename); + if(is.good() == false) + { + dstream<<"Error opening configuration file" + " for reading: \"" + <::Iterator + i = objects.begin(); + i != objects.end(); i++) + { + os<<(*i); + } + + /* + Write stuff that was not already in the file + */ + for(core::map::Iterator + i = m_settings.getIterator(); + i.atEnd() == false; i++) + { + if(updated.find(i.getNode()->getKey())) + continue; + std::string name = i.getNode()->getKey(); + std::string value = i.getNode()->getValue(); + dstream<<"Adding \""< &allowed_options) + { + int i=1; + for(;;) + { + if(i >= argc) + break; + std::string argname = argv[i]; + if(argname.substr(0, 2) != "--") + { + dstream<<"Invalid command-line parameter \"" + < expected."<::Node *n; + n = allowed_options.find(name); + if(n == NULL) + { + dstream<<"Unknown command-line parameter \"" + <getValue().type; + + std::string value = ""; + + if(type == VALUETYPE_FLAG) + { + value = "true"; + } + else + { + if(i >= argc) + { + dstream<<"Invalid command-line parameter \"" + <::Node *n; n = m_settings.find(name); if(n == NULL) - throw SettingNotFoundException("Setting not found"); + { + n = m_defaults.find(name); + if(n == NULL) + { + throw SettingNotFoundException("Setting not found"); + } + } return n->getValue(); } @@ -749,6 +985,18 @@ public: return is_yes(get(name)); } + bool getFlag(std::string name) + { + try + { + return getBool(name); + } + catch(SettingNotFoundException &e) + { + return false; + } + } + // Asks if empty bool getBoolAsk(std::string name, std::string question, bool def) { @@ -809,6 +1057,7 @@ public: private: core::map m_settings; + core::map m_defaults; }; /* -- cgit v1.2.3