From 4102348817525acc058732da5a5b9e9c4de16d65 Mon Sep 17 00:00:00 2001 From: gimmedonutnow Date: Thu, 10 Aug 2006 05:25:19 +0000 Subject: [PATCH] - added this configuration system for cross-platform testing --- src/drivers/common/SConscript | 1 + src/drivers/common/configSys.cpp | 409 +++++++++++++++++++++++++++++++ src/drivers/common/configSys.h | 62 +++++ 3 files changed, 472 insertions(+) create mode 100644 src/drivers/common/configSys.cpp create mode 100644 src/drivers/common/configSys.h diff --git a/src/drivers/common/SConscript b/src/drivers/common/SConscript index 94f47a8e..64fadbe7 100644 --- a/src/drivers/common/SConscript +++ b/src/drivers/common/SConscript @@ -8,6 +8,7 @@ scale2x.cpp scale3x.cpp scalebit.cpp vidblit.cpp +configSys.cpp """) for x in range(len(my_list)): diff --git a/src/drivers/common/configSys.cpp b/src/drivers/common/configSys.cpp new file mode 100644 index 00000000..a40f12b8 --- /dev/null +++ b/src/drivers/common/configSys.cpp @@ -0,0 +1,409 @@ +#include +#include +#include + +#include "configSys.h" + +/** + * Add a given option. The option is specified as a short command + * line (-f), long command line (--foo), option name (Foo), its type + * (integer or string). + */ +int +Config::_addOption(char shortArg, + const std::string &longArg, + const std::string &name, + int type) +{ + // make sure we have a valid type + if(type != INTEGER && type != STRING) { + return -1; + } + + // check if the option already exists + if(_shortArgMap.find(shortArg) != _shortArgMap.end() || + _longArgMap.find(longArg) != _longArgMap.end() || + (type == INTEGER && _intOptMap.find(name) != _intOptMap.end()) || + (type == STRING && _strOptMap.find(name) != _strOptMap.end())) { + return -1; + } + + // add the option + switch(type) { + case(INTEGER): + _intOptMap[name] = 0; + break; + case(STRING): + _strOptMap[name] = ""; + break; + default: + break; + } + _shortArgMap[shortArg] = name; + _longArgMap[longArg] = name; + + return 0; +} + +/** + * Add a given option and sets its default value. The option is + * specified as a short command line (-f), long command line (--foo), + * option name (Foo), its type (integer or string), and its default + * value. + */ +int +Config::addOption(char shortArg, + const std::string &longArg, + const std::string &name, + int type, + int defaultValue) +{ + int error; + + // add the option to the config system + error = _addOption(shortArg, longArg, name, type); + if(error) { + return error; + } + + // set the option to the default value + error = setOption(name, defaultValue); + if(error) { + return error; + } + + return 0; +} + +/** + * Add a given option and sets its default value. The option is + * specified as a short command line (-f), long command line (--foo), + * option name (Foo), its type (integer or string), and its default + * value. + */ +int +Config::addOption(char shortArg, + const std::string &longArg, + const std::string &name, + int type, + const std::string &defaultValue) +{ + int error; + + // add the option to the config system + error = _addOption(shortArg, longArg, name, type); + if(error) { + return error; + } + + // set the option to the default value + error = setOption(name, defaultValue); + if(error) { + return error; + } + + return 0; +} + +/** + * Sets the specified option to the given integer value. + */ +int +Config::setOption(const std::string &name, + int value) +{ + std::map::iterator opt_i; + + // confirm that the option exists + opt_i = _intOptMap.find(name); + if(opt_i == _intOptMap.end()) { + return -1; + } + + // set the option + opt_i->second = value; + return 0; +} + +/** + * Sets the specified option to the given string value. + */ +int +Config::setOption(const std::string &name, + const std::string &value) +{ + std::map::iterator opt_i; + + // confirm that the option exists + opt_i = _strOptMap.find(name); + if(opt_i == _strOptMap.end()) { + return -1; + } + + // set the option + opt_i->second = value; + return 0; +} + +int +Config::getOption(const std::string &name, + std::string *value) +{ + std::map::iterator opt_i; + + // confirm that the option exists + opt_i = _strOptMap.find(name); + if(opt_i == _strOptMap.end()) { + return -1; + } + + // get the option + (*value) = opt_i->second; + return 0; +} + +int +Config::getOption(const std::string &name, + const char **value) +{ + std::map::iterator opt_i; + + // confirm that the option exists + opt_i = _strOptMap.find(name); + if(opt_i == _strOptMap.end()) { + return -1; + } + + // get the option + (*value) = opt_i->second.c_str(); + return 0; +} + +int +Config::getOption(const std::string &name, + int *value) +{ + std::map::iterator opt_i; + + // confirm that the option exists + opt_i = _intOptMap.find(name); + if(opt_i == _intOptMap.end()) { + return -1; + } + + // get the option + (*value) = opt_i->second; + return 0; +} + + +/** + * Parses the command line arguments. Short args are of the form -f + * , long args are of the form --foo . Returns < 0 on error, + * or the index of the rom file in argv. + */ +int +Config::_parseArgs(int argc, + char **argv) +{ + int retval = 0; + std::map::iterator long_i, str_i; + std::map::iterator short_i; + std::map::iterator int_i; + std::string arg, opt, value; + + for(int i = 1; i < argc; i++) { + arg = argv[i]; + if(arg[0] != '-') { + // must be a rom name? + retval = i; + continue; + } + + if(arg.size() < 2) { + // XXX invalid argument + return -1; + } + + // parse the argument and get the option name + if(arg[1] == '-') { + // long arg + long_i = _longArgMap.find(arg.substr(2)); + if(long_i == _longArgMap.end()) { + // XXX invalid argument + return -1; + } + + opt = long_i->second; + } else { + // short arg + short_i = _shortArgMap.find(arg[1]); + if(short_i == _shortArgMap.end()) { + // XXX invalid argument + return -1; + } + + opt = short_i->second; + } + + // make sure we've got a value + if(i + 1 >= argc) { + // XXX missing value + return -1; + } + i++; + + // now, find the appropriate option entry, and update it + str_i = _strOptMap.find(opt); + int_i = _intOptMap.find(opt); + if(str_i != _strOptMap.end()) { + str_i->second = argv[i]; + } else if(int_i != _intOptMap.end()) { + int_i->second = atol(argv[i]); + } else { + // XXX invalid option? shouldn't happen + return -1; + } + } + + // if we didn't get a rom-name, return error + return (retval) ? retval : -1; +} + + +/** + * Parses first the configuration file, and then overrides with any + * command-line options that were specified. + */ +int +Config::parse(int argc, + char **argv) +{ + int error; + + // read the config file + error = _load(); + if(error) { + return error; + } + + // parse the arguments + error = _parseArgs(argc, argv); + if(error) { + return error; + } + + return 0; +} + + +/** + * Read each line of the config file and put the variables into the + * config maps. Valid configuration lines are of the form: + * + *