- bool &value_changed)
- {
- 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 empty lines and comments
- if(trimmedline.size() == 0 || 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) != m_settings.end())
- {
- std::string newvalue = m_settings[name];
-
- if(newvalue != value)
- {
- infostream<<"Changing value of \""<<name<<"\" = \""
- <<value<<"\" -> \""<<newvalue<<"\""
- <<std::endl;
- value_changed = true;
- }
-
- dst.push_back(name + " = " + newvalue + line_end);
-
- updated.insert(name);
- }
- else //file contains a setting which is not in m_settings
- value_changed=true;
-
- return true;
- }
-
- /*
- Updates configuration file
-
- Returns true on success
- */
- bool updateConfigFile(const char *filename)
- {
- infostream<<"Updating configuration file: \""
- <<filename<<"\""<<std::endl;
-
- std::list<std::string> objects;
- std::set<std::string> updated;
- bool something_actually_changed = false;
-
- // 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,
- something_actually_changed));
- }
- }
-
- JMutexAutoLock lock(m_mutex);
-
- // If something not yet determined to have been changed, check if
- // any new stuff was added
- if(!something_actually_changed){
- for(std::map<std::string, std::string>::iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- if(updated.find(i->first) != updated.end())
- continue;
- something_actually_changed = true;
- break;
- }
- }
-
- // If nothing was actually changed, skip writing the file
- if(!something_actually_changed){
- infostream<<"Skipping writing of "<<filename
- <<" because content wouldn't be modified"<<std::endl;
- return true;
- }
-
- // 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(std::list<std::string>::iterator
- i = objects.begin();
- i != objects.end(); ++i)
- {
- os<<(*i);
- }
-
- /*
- Write stuff that was not already in the file
- */
- for(std::map<std::string, std::string>::iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- if(updated.find(i->first) != updated.end())
- continue;
- std::string name = i->first;
- std::string value = i->second;
- 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[],
- std::map<std::string, ValueSpec> &allowed_options)
- {
- int nonopt_index = 0;
- int i=1;
- for(;;)
- {
- if(i >= argc)
- break;
- std::string argname = argv[i];
- if(argname.substr(0, 2) != "--")
- {
- // If option doesn't start with -, read it in as nonoptX
- if(argname[0] != '-'){
- std::string name = "nonopt";
- name += itos(nonopt_index);
- set(name, argname);
- nonopt_index++;
- i++;
- continue;
- }
- errorstream<<"Invalid command-line parameter \""
- <<argname<<"\": --<option> expected."<<std::endl;
- return false;
- }
- i++;
-
- std::string name = argname.substr(2);
-
- std::map<std::string, ValueSpec>::iterator n;
- n = allowed_options.find(name);
- if(n == allowed_options.end())
- {
- errorstream<<"Unknown command-line parameter \""
- <<argname<<"\""<<std::endl;
- return false;
- }
-
- ValueType type = n->second.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;
- }
-
- void set(std::string name, std::string value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_settings[name] = value;
- }
-
- void set(std::string name, const char *value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_settings[name] = value;
- }
-
-
- void setDefault(std::string name, std::string value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_defaults[name] = value;
- }
-
- bool exists(std::string name)
- {
- JMutexAutoLock lock(m_mutex);
-
- return (m_settings.find(name) != m_settings.end() || m_defaults.find(name) != m_defaults.end());
- }
-
- std::string get(std::string name)
- {
- JMutexAutoLock lock(m_mutex);
-
- std::map<std::string, std::string>::iterator n;
- n = m_settings.find(name);
- if(n == m_settings.end())
- {
- n = m_defaults.find(name);
- if(n == m_defaults.end())
- {
- throw SettingNotFoundException("Setting not found");
- }
- }
-
- return n->second;
- }
-
- bool getBool(std::string name)
- {
- 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)
- {
- // If it is in settings
- if(exists(name))
- return getBool(name);
-
- std::string s;
- char templine[10];
- std::cout<<question<<" [y/N]: ";
- std::cin.getline(templine, 10);
- s = templine;
-
- if(s == "")
- return def;
-
- return is_yes(s);
- }
-
- float getFloat(std::string name)
- {
- return stof(get(name));
- }
-
- u16 getU16(std::string name)
- {
- return stoi(get(name), 0, 65535);
- }
-
- u16 getU16Ask(std::string name, std::string question, u16 def)
- {
- // If it is in settings
- if(exists(name))
- return getU16(name);
-
- std::string s;
- char templine[10];
- std::cout<<question<<" ["<<def<<"]: ";
- std::cin.getline(templine, 10);
- s = templine;
-
- if(s == "")
- return def;
-
- return stoi(s, 0, 65535);
- }
-
- s16 getS16(std::string name)
- {
- return stoi(get(name), -32768, 32767);
- }
-
- s32 getS32(std::string name)
- {
- return stoi(get(name));
- }
-
- v3f getV3F(std::string name)
- {
- v3f value;
- Strfnd f(get(name));
- f.next("(");
- value.X = stof(f.next(","));
- value.Y = stof(f.next(","));
- value.Z = stof(f.next(")"));
- return value;
- }