settings manager: better default setting handling and updating config file and command line parsing
parent
f501cfd799
commit
385dd9917f
|
@ -32,7 +32,8 @@ Controls:
|
||||||
|
|
||||||
Configuration file:
|
Configuration file:
|
||||||
- An optional configuration file can be used. See minetest.conf.example.
|
- An optional configuration file can be used. See minetest.conf.example.
|
||||||
- Path to file can be passed as a parameter to the executable.
|
- Path to file can be passed as a parameter to the executable:
|
||||||
|
--config <path-to-file>
|
||||||
- If not given as a parameter, these are checked, in order:
|
- If not given as a parameter, these are checked, in order:
|
||||||
../minetest.conf
|
../minetest.conf
|
||||||
../../minetest.conf
|
../../minetest.conf
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
# By default, all the settings are commented and not functional.
|
# By default, all the settings are commented and not functional.
|
||||||
# Uncomment settings by removing the preceding #.
|
# Uncomment settings by removing the preceding #.
|
||||||
|
|
||||||
#dedicated_server =
|
|
||||||
|
|
||||||
# Client side stuff
|
# Client side stuff
|
||||||
|
|
||||||
#wanted_fps = 30
|
#wanted_fps = 30
|
||||||
|
|
|
@ -124,6 +124,14 @@ public:
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CommandLineError : public BaseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandLineError(const char *s):
|
||||||
|
BaseException(s)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some "old-style" interrupts:
|
Some "old-style" interrupts:
|
||||||
*/
|
*/
|
||||||
|
|
152
src/main.cpp
152
src/main.cpp
|
@ -306,38 +306,36 @@ Settings g_settings;
|
||||||
// Sets default settings
|
// Sets default settings
|
||||||
void set_default_settings()
|
void set_default_settings()
|
||||||
{
|
{
|
||||||
g_settings.set("dedicated_server", "");
|
|
||||||
|
|
||||||
// Client stuff
|
// Client stuff
|
||||||
g_settings.set("wanted_fps", "30");
|
g_settings.setDefault("wanted_fps", "30");
|
||||||
g_settings.set("fps_max", "60");
|
g_settings.setDefault("fps_max", "60");
|
||||||
g_settings.set("viewing_range_nodes_max", "300");
|
g_settings.setDefault("viewing_range_nodes_max", "300");
|
||||||
g_settings.set("viewing_range_nodes_min", "35");
|
g_settings.setDefault("viewing_range_nodes_min", "35");
|
||||||
g_settings.set("screenW", "");
|
g_settings.setDefault("screenW", "");
|
||||||
g_settings.set("screenH", "");
|
g_settings.setDefault("screenH", "");
|
||||||
g_settings.set("host_game", "");
|
g_settings.setDefault("host_game", "");
|
||||||
g_settings.set("port", "");
|
g_settings.setDefault("port", "");
|
||||||
g_settings.set("address", "");
|
g_settings.setDefault("address", "");
|
||||||
g_settings.set("name", "");
|
g_settings.setDefault("name", "");
|
||||||
g_settings.set("random_input", "false");
|
g_settings.setDefault("random_input", "false");
|
||||||
g_settings.set("client_delete_unused_sectors_timeout", "1200");
|
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
|
||||||
g_settings.set("max_block_send_distance", "8");
|
g_settings.setDefault("max_block_send_distance", "8");
|
||||||
g_settings.set("max_block_generate_distance", "6");
|
g_settings.setDefault("max_block_generate_distance", "6");
|
||||||
|
|
||||||
// Server stuff
|
// Server stuff
|
||||||
g_settings.set("creative_mode", "false");
|
g_settings.setDefault("creative_mode", "false");
|
||||||
g_settings.set("heightmap_blocksize", "32");
|
g_settings.setDefault("heightmap_blocksize", "32");
|
||||||
g_settings.set("height_randmax", "constant 50.0");
|
g_settings.setDefault("height_randmax", "constant 50.0");
|
||||||
g_settings.set("height_randfactor", "constant 0.6");
|
g_settings.setDefault("height_randfactor", "constant 0.6");
|
||||||
g_settings.set("height_base", "linear 0 0 0");
|
g_settings.setDefault("height_base", "linear 0 0 0");
|
||||||
g_settings.set("plants_amount", "1.0");
|
g_settings.setDefault("plants_amount", "1.0");
|
||||||
g_settings.set("ravines_amount", "1.0");
|
g_settings.setDefault("ravines_amount", "1.0");
|
||||||
g_settings.set("objectdata_interval", "0.2");
|
g_settings.setDefault("objectdata_interval", "0.2");
|
||||||
g_settings.set("active_object_range", "2");
|
g_settings.setDefault("active_object_range", "2");
|
||||||
g_settings.set("max_simultaneous_block_sends_per_client", "1");
|
g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
|
||||||
g_settings.set("max_simultaneous_block_sends_server_total", "4");
|
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
|
||||||
g_settings.set("disable_water_climb", "true");
|
g_settings.setDefault("disable_water_climb", "true");
|
||||||
g_settings.set("endless_water", "true");
|
g_settings.setDefault("endless_water", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -962,6 +960,51 @@ int main(int argc, char *argv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse command line
|
||||||
|
TODO
|
||||||
|
*/
|
||||||
|
|
||||||
|
core::map<std::string, ValueSpec> allowed_options;
|
||||||
|
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
|
||||||
|
allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
|
||||||
|
"Run server directly"));
|
||||||
|
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
|
||||||
|
"Load configuration from specified file"));
|
||||||
|
allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
|
||||||
|
|
||||||
|
Settings cmd_args;
|
||||||
|
|
||||||
|
bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);
|
||||||
|
|
||||||
|
if(ret == false || cmd_args.getFlag("help"))
|
||||||
|
{
|
||||||
|
dstream<<"Allowed options:"<<std::endl;
|
||||||
|
for(core::map<std::string, ValueSpec>::Iterator
|
||||||
|
i = allowed_options.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
dstream<<" --"<<i.getNode()->getKey();
|
||||||
|
if(i.getNode()->getValue().type == VALUETYPE_FLAG)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstream<<" <value>";
|
||||||
|
}
|
||||||
|
dstream<<std::endl;
|
||||||
|
|
||||||
|
if(i.getNode()->getValue().help != NULL)
|
||||||
|
{
|
||||||
|
dstream<<" "<<i.getNode()->getValue().help
|
||||||
|
<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_args.getFlag("help") ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Basic initialization
|
Basic initialization
|
||||||
*/
|
*/
|
||||||
|
@ -999,11 +1042,23 @@ int main(int argc, char *argv[])
|
||||||
Initialization
|
Initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Read config file
|
/*
|
||||||
|
Read config file
|
||||||
|
*/
|
||||||
|
|
||||||
if(argc >= 2)
|
// Path of configuration file in use
|
||||||
|
std::string configpath = "";
|
||||||
|
|
||||||
|
if(cmd_args.exists("config"))
|
||||||
{
|
{
|
||||||
g_settings.readConfigFile(argv[1]);
|
bool r = g_settings.readConfigFile(cmd_args.get("config").c_str());
|
||||||
|
if(r == false)
|
||||||
|
{
|
||||||
|
dstream<<"Could not read configuration from \""
|
||||||
|
<<cmd_args.get("config")<<"\""<<std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
configpath = cmd_args.get("config");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1017,7 +1072,10 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
bool r = g_settings.readConfigFile(filenames[i]);
|
bool r = g_settings.readConfigFile(filenames[i]);
|
||||||
if(r)
|
if(r)
|
||||||
|
{
|
||||||
|
configpath = filenames[i];
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1059,16 +1117,19 @@ int main(int argc, char *argv[])
|
||||||
std::cout<<std::endl;
|
std::cout<<std::endl;
|
||||||
char templine[100];
|
char templine[100];
|
||||||
|
|
||||||
// Dedicated?
|
|
||||||
bool dedicated = g_settings.getBoolAsk
|
|
||||||
("dedicated_server", "Dedicated server?", false);
|
|
||||||
std::cout<<"dedicated = "<<dedicated<<std::endl;
|
|
||||||
|
|
||||||
// Port?
|
// Port?
|
||||||
u16 port = g_settings.getU16Ask("port", "Port", 30000);
|
u16 port = 30000;
|
||||||
std::cout<<"-> "<<port<<std::endl;
|
if(cmd_args.exists("port"))
|
||||||
|
{
|
||||||
|
port = cmd_args.getU16("port");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port = g_settings.getU16Ask("port", "Port", 30000);
|
||||||
|
std::cout<<"-> "<<port<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if(dedicated)
|
if(cmd_args.getFlag("server"))
|
||||||
{
|
{
|
||||||
DSTACK("Dedicated server branch");
|
DSTACK("Dedicated server branch");
|
||||||
|
|
||||||
|
@ -2208,7 +2269,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
{
|
{
|
||||||
TimeTaker timer("beginScene", device);
|
TimeTaker timer("beginScene", device);
|
||||||
driver->beginScene(true, true, bgcolor);
|
//driver->beginScene(true, true, bgcolor);
|
||||||
|
driver->beginScene(false, true, bgcolor);
|
||||||
beginscenetime = timer.stop(true);
|
beginscenetime = timer.stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2306,6 +2368,14 @@ int main(int argc, char *argv[])
|
||||||
In the end, delete the Irrlicht device.
|
In the end, delete the Irrlicht device.
|
||||||
*/
|
*/
|
||||||
device->drop();
|
device->drop();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update configuration file
|
||||||
|
*/
|
||||||
|
if(configpath != "")
|
||||||
|
{
|
||||||
|
g_settings.updateConfigFile(configpath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
} //try
|
} //try
|
||||||
catch(con::PeerNotFoundException &e)
|
catch(con::PeerNotFoundException &e)
|
||||||
|
|
|
@ -205,7 +205,7 @@ void UDPSocket::Send(const Address & destination, const void * data, int size)
|
||||||
destination.print();
|
destination.print();
|
||||||
dstream<<", size="<<size<<", data=";
|
dstream<<", size="<<size<<", data=";
|
||||||
for(int i=0; i<size && i<20; i++){
|
for(int i=0; i<size && i<20; i++){
|
||||||
if(i%2==0) printf(" ");
|
if(i%2==0) DEBUGPRINT(" ");
|
||||||
DEBUGPRINT("%.2X", ((int)((const char*)data)[i])&0xff);
|
DEBUGPRINT("%.2X", ((int)((const char*)data)[i])&0xff);
|
||||||
}
|
}
|
||||||
if(size>20)
|
if(size>20)
|
||||||
|
@ -267,7 +267,7 @@ int UDPSocket::Receive(Address & sender, void * data, int size)
|
||||||
//dstream<<", received="<<received<<std::endl;
|
//dstream<<", received="<<received<<std::endl;
|
||||||
dstream<<", size="<<received<<", data=";
|
dstream<<", size="<<received<<", data=";
|
||||||
for(int i=0; i<received && i<20; i++){
|
for(int i=0; i<received && i<20; i++){
|
||||||
if(i%2==0) printf(" ");
|
if(i%2==0) DEBUGPRINT(" ");
|
||||||
DEBUGPRINT("%.2X", ((int)((const char*)data)[i])&0xff);
|
DEBUGPRINT("%.2X", ((int)((const char*)data)[i])&0xff);
|
||||||
}
|
}
|
||||||
if(received>20)
|
if(received>20)
|
||||||
|
|
|
@ -1070,8 +1070,8 @@ struct TestConnection
|
||||||
|
|
||||||
dstream<<"Sending data (size="<<1100<<"):";
|
dstream<<"Sending data (size="<<1100<<"):";
|
||||||
for(int i=0; i<1100 && i<20; i++){
|
for(int i=0; i<1100 && i<20; i++){
|
||||||
if(i%2==0) printf(" ");
|
if(i%2==0) DEBUGPRINT(" ");
|
||||||
printf("%.2X", ((int)((const char*)*data1)[i])&0xff);
|
DEBUGPRINT("%.2X", ((int)((const char*)*data1)[i])&0xff);
|
||||||
}
|
}
|
||||||
if(1100>20)
|
if(1100>20)
|
||||||
dstream<<"...";
|
dstream<<"...";
|
||||||
|
@ -1091,8 +1091,8 @@ struct TestConnection
|
||||||
|
|
||||||
dstream<<"Received data (size="<<size<<"):";
|
dstream<<"Received data (size="<<size<<"):";
|
||||||
for(int i=0; i<size && i<20; i++){
|
for(int i=0; i<size && i<20; i++){
|
||||||
if(i%2==0) printf(" ");
|
if(i%2==0) DEBUGPRINT(" ");
|
||||||
printf("%.2X", ((int)((const char*)recvdata)[i])&0xff);
|
DEBUGPRINT("%.2X", ((int)((const char*)recvdata)[i])&0xff);
|
||||||
}
|
}
|
||||||
if(size>20)
|
if(size>20)
|
||||||
dstream<<"...";
|
dstream<<"...";
|
||||||
|
|
261
src/utility.h
261
src/utility.h
|
@ -668,6 +668,23 @@ inline s32 stoi(std::string s)
|
||||||
Config stuff
|
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
|
class Settings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -710,36 +727,255 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true on success
|
/*
|
||||||
|
Read configuration file
|
||||||
|
|
||||||
|
Returns true on success
|
||||||
|
*/
|
||||||
bool readConfigFile(const char *filename)
|
bool readConfigFile(const char *filename)
|
||||||
{
|
{
|
||||||
std::ifstream is(filename);
|
std::ifstream is(filename);
|
||||||
if(is.good() == false)
|
if(is.good() == false)
|
||||||
{
|
{
|
||||||
dstream<<"Error opening configuration file: "
|
dstream<<"Error opening configuration file \""
|
||||||
<<filename<<std::endl;
|
<<filename<<"\""<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dstream<<"Parsing configuration file: "
|
dstream<<"Parsing configuration file: \""
|
||||||
<<filename<<std::endl;
|
<<filename<<"\""<<std::endl;
|
||||||
|
|
||||||
while(parseConfigObject(is));
|
while(parseConfigObject(is));
|
||||||
|
|
||||||
return true;
|
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)
|
||||||
|
{
|
||||||
|
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 \""<<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)
|
||||||
|
{
|
||||||
|
dstream<<"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)
|
||||||
|
{
|
||||||
|
dstream<<"Error opening configuration file"
|
||||||
|
" for reading: \""
|
||||||
|
<<filename<<"\""<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(getUpdatedConfigObject(is, objects, updated));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write stuff back
|
||||||
|
{
|
||||||
|
std::ofstream os(filename);
|
||||||
|
if(os.good() == false)
|
||||||
|
{
|
||||||
|
dstream<<"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();
|
||||||
|
dstream<<"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) != "--")
|
||||||
|
{
|
||||||
|
dstream<<"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)
|
||||||
|
{
|
||||||
|
dstream<<"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)
|
||||||
|
{
|
||||||
|
dstream<<"Invalid command-line parameter \""
|
||||||
|
<<name<<"\": missing value"<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
value = argv[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dstream<<"Valid command-line parameter: \""
|
||||||
|
<<name<<"\" = \""<<value<<"\""
|
||||||
|
<<std::endl;
|
||||||
|
set(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void set(std::string name, std::string value)
|
void set(std::string name, std::string value)
|
||||||
{
|
{
|
||||||
m_settings[name] = value;
|
m_settings[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDefault(std::string name, std::string value)
|
||||||
|
{
|
||||||
|
m_defaults[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists(std::string name)
|
||||||
|
{
|
||||||
|
return (m_settings.find(name) || m_defaults.find(name));
|
||||||
|
}
|
||||||
|
|
||||||
std::string get(std::string name)
|
std::string get(std::string name)
|
||||||
{
|
{
|
||||||
core::map<std::string, std::string>::Node *n;
|
core::map<std::string, std::string>::Node *n;
|
||||||
n = m_settings.find(name);
|
n = m_settings.find(name);
|
||||||
if(n == NULL)
|
if(n == NULL)
|
||||||
throw SettingNotFoundException("Setting not found");
|
{
|
||||||
|
n = m_defaults.find(name);
|
||||||
|
if(n == NULL)
|
||||||
|
{
|
||||||
|
throw SettingNotFoundException("Setting not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return n->getValue();
|
return n->getValue();
|
||||||
}
|
}
|
||||||
|
@ -749,6 +985,18 @@ public:
|
||||||
return is_yes(get(name));
|
return is_yes(get(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getFlag(std::string name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getBool(name);
|
||||||
|
}
|
||||||
|
catch(SettingNotFoundException &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Asks if empty
|
// Asks if empty
|
||||||
bool getBoolAsk(std::string name, std::string question, bool def)
|
bool getBoolAsk(std::string name, std::string question, bool def)
|
||||||
{
|
{
|
||||||
|
@ -809,6 +1057,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::map<std::string, std::string> m_settings;
|
core::map<std::string, std::string> m_settings;
|
||||||
|
core::map<std::string, std::string> m_defaults;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue