/src/

pan> while(parseConfigObject(is)); return true; } /* Reads a configuration object from stream (usually a single line) and adds it to dst. Preserves comments and empty lines. Settings that were added to dst are also added to updated. key of updated is setting name, value of updated is dummy. Returns false on EOF */ bool getUpdatedConfigObject(std::istream &is, core::list<std::string> &dst, core::map<std::string, bool> &updated) { JMutexAutoLock lock(m_mutex); 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) { infostream<<"Changing value of \""<<name<<"\" = \"" <<value<<"\" -> \""<<newvalue<<"\"" <<std::endl; } dst.push_back(name + " = " + newvalue + line_end); updated[name] = true; } return true; } /* Updates configuration file Returns true on success */ bool updateConfigFile(const char *filename) { infostream<<"Updating configuration file: \"" <<filename<<"\""<<std::endl; core::list<std::string> objects; core::map<std::string, bool> updated; // Read and modify stuff { std::ifstream is(filename); if(is.good() == false) { infostream<<"updateConfigFile():" " Error opening configuration file" " for reading: \"" <<filename<<"\""<<std::endl; } else { while(getUpdatedConfigObject(is, objects, updated)); } } JMutexAutoLock lock(m_mutex); // Write stuff back { std::ofstream os(filename); if(os.good() == false) { errorstream<<"Error opening configuration file" " for writing: \"" <<filename<<"\""<<std::endl; return false; } /* Write updated stuff */ for(core::list<std::string>::Iterator i = objects.begin(); i != objects.end(); i++) { os<<(*i); } /* Write stuff that was not already in the file */ for(core::map<std::string, std::string>::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(); infostream<<"Adding \""<<name<<"\" = \""<<value<<"\"" <<std::endl; os<<name<<" = "<<value<<"\n"; } } return true; } /* NOTE: Types of allowed_options are ignored returns true on success */ bool parseCommandLine(int argc, char *argv[], core::map<std::string, ValueSpec> &allowed_options) { int i=1; for(;;) { if(i >= argc) break; std::string argname = argv[i]; if(argname.substr(0, 2) != "--") { errorstream<<"Invalid command-line parameter \"" <<argname<<"\": --<option> expected."<<std::endl; return false; } i++; std::string name = argname.substr(2); core::map<std::string, ValueSpec>::Node *n; n = allowed_options.find(name); if(n == NULL) { errorstream<<"Unknown command-line parameter \"" <<argname<<"\""<<std::endl; return false; } ValueType type = n->getValue().type; std::string value = ""; if(type == VALUETYPE_FLAG) { value = "true"; } else { if(i >= argc) { errorstream<<"Invalid command-line parameter \"" <<name<<"\": missing value"<<std::endl; return false; } value = argv[i]; i++; } infostream<<"Valid command-line parameter: \"" <<name<<"\" = \""<<value<<"\"" <<std::endl; set(name, value); } return true; }