#include #include #include #include #include #include "../../types.h" #include "configSys.h" std::string cfgFile = "fceux.cfg"; /** * 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 && type != DOUBLE && type != FUNCTION) { 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()) || (type == DOUBLE && _dblOptMap.find(name) != _dblOptMap.end())) { return -1; } // add the option switch(type) { case(STRING): _strOptMap[name] = ""; break; case(INTEGER): _intOptMap[name] = 0; break; case(DOUBLE): _dblOptMap[name] = 0.0; break; case(FUNCTION): _fnOptMap[name] = NULL; break; default: break; } _shortArgMap[shortArg] = name; _longArgMap[longArg] = name; return 0; } int Config::_addOption(const std::string &longArg, const std::string &name, int type) { // make sure we have a valid type if(type != STRING && type != INTEGER && type != DOUBLE) { return -1; } // check if the option already exists if(_longArgMap.find(longArg) != _longArgMap.end() || (type == STRING && _strOptMap.find(name) != _strOptMap.end()) || (type == INTEGER && _intOptMap.find(name) != _intOptMap.end()) || (type == DOUBLE && _dblOptMap.find(name) != _dblOptMap.end())) { return -1; } // add the option switch(type) { case(STRING): _strOptMap[name] = ""; break; case(INTEGER): _intOptMap[name] = 0; break; case(DOUBLE): _dblOptMap[name] = 0.0; break; default: break; } _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 defaultValue) { int error; // add the option to the config system error = _addOption(shortArg, longArg, name, INTEGER); 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, double defaultValue) { int error; // add the option to the config system error = _addOption(shortArg, longArg, name, DOUBLE); 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, const std::string &defaultValue) { int error; // add the option to the config system error = _addOption(shortArg, longArg, name, STRING); if(error) { return error; } // set the option to the default value error = setOption(name, defaultValue); if(error) { return error; } return 0; } int Config::addOption(char shortArg, const std::string &longArg, const std::string &name, void (*defaultFn)(const std::string &)) { int error; // add the option to the config system error = _addOption(shortArg, longArg, name, FUNCTION); if(error) { return error; } // set the option to the default value error = setOption(name, defaultFn); if(error) { return error; } return 0; } int Config::addOption(const std::string &longArg, const std::string &name, const std::string &defaultValue) { int error; // add the option to the config system error = _addOption(longArg, name, STRING); if(error) { return error; } // set the option to the default value error = setOption(name, defaultValue); if(error) { return error; } return 0; } int Config::addOption(const std::string &longArg, const std::string &name, int defaultValue) { int error; // add the option to the config system error = _addOption(longArg, name, INTEGER); if(error) { return error; } // set the option to the default value error = setOption(name, defaultValue); if(error) { return error; } return 0; } int Config::addOption(const std::string &longArg, const std::string &name, double defaultValue) { int error; // add the option to the config system error = _addOption(longArg, name, DOUBLE); if(error) { return error; } // set the option to the default value error = setOption(name, defaultValue); if(error) { return error; } return 0; } int Config::addOption(const std::string &name, const std::string &defaultValue) { if(_strOptMap.find(name) != _strOptMap.end()) { return -1; } // add the option _strOptMap[name] = defaultValue; return 0; } int Config::addOption(const std::string &name, int defaultValue) { if(_intOptMap.find(name) != _intOptMap.end()) { return -1; } // add the option _intOptMap[name] = defaultValue; return 0; } int Config::addOption(const std::string &name, double defaultValue) { if(_dblOptMap.find(name) != _dblOptMap.end()) { return -1; } // add the option _dblOptMap[name] = defaultValue; 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 integer value. */ int Config::setOption(const std::string &name, double value) { std::map::iterator opt_i; // confirm that the option exists opt_i = _dblOptMap.find(name); if(opt_i == _dblOptMap.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; } /** * Sets the specified option to the given function. */ int Config::setOption(const std::string &name, void (*value)(const std::string &)) { std::map::iterator opt_i; // confirm that the option exists opt_i = _fnOptMap.find(name); if(opt_i == _fnOptMap.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; } int Config::getOption(const std::string &name, double *value) { std::map::iterator opt_i; // confirm that the option exists opt_i = _dblOptMap.find(name); if(opt_i == _dblOptMap.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::map::iterator dbl_i; std::map::iterator fn_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); dbl_i = _dblOptMap.find(opt); fn_i = _fnOptMap.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 if(dbl_i != _dblOptMap.end()) { dbl_i->second = atof(argv[i]); } else if(fn_i != _fnOptMap.end()) { (*(fn_i->second))(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 return _parseArgs(argc, argv); } /** * Read each line of the config file and put the variables into the * config maps. Valid configuration lines are of the form: * *