- added this configuration system for cross-platform testing
This commit is contained in:
parent
1e7eeb0140
commit
4102348817
|
@ -8,6 +8,7 @@ scale2x.cpp
|
|||
scale3x.cpp
|
||||
scalebit.cpp
|
||||
vidblit.cpp
|
||||
configSys.cpp
|
||||
""")
|
||||
|
||||
for x in range(len(my_list)):
|
||||
|
|
|
@ -0,0 +1,409 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
|
||||
#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<std::string, int>::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<std::string, std::string>::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<std::string, std::string>::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<std::string, std::string>::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<std::string, int>::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
|
||||
* <opt>, long args are of the form --foo <opt>. 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<std::string, std::string>::iterator long_i, str_i;
|
||||
std::map<char, std::string>::iterator short_i;
|
||||
std::map<std::string, int>::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:
|
||||
*
|
||||
* <option name> = <option value>
|
||||
*
|
||||
* Lines beginning with # are ignored.
|
||||
*/
|
||||
int
|
||||
Config::_load()
|
||||
{
|
||||
int error;
|
||||
unsigned int pos, eqPos;
|
||||
std::fstream config;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, std::string>::iterator str_i;
|
||||
std::string configFile = _dir + "/fceu.cfg";
|
||||
std::string line, name, value;
|
||||
char buf[1024];
|
||||
|
||||
// set the exception handling to catch i/o errors
|
||||
config.exceptions(std::fstream::badbit);
|
||||
|
||||
try {
|
||||
// open the file for reading (create if it doesn't exist)
|
||||
config.open(configFile.c_str(), std::ios::in | std::ios::out);
|
||||
|
||||
while(!config.eof()) {
|
||||
// read a line
|
||||
config.getline(buf, 1024);
|
||||
line = buf;
|
||||
|
||||
// check line validity
|
||||
eqPos = line.find("=");
|
||||
if(line[0] == '#' || eqPos == std::string::npos) {
|
||||
// skip this line
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the name and value for the option
|
||||
pos = line.find(" ");
|
||||
name = line.substr(0, (pos > eqPos) ? eqPos : pos);
|
||||
pos = line.find_first_not_of(" ", eqPos + 1);
|
||||
value = line.substr(pos);
|
||||
|
||||
// check if the option exists, and if so, set it appropriately
|
||||
str_i = _strOptMap.find(name);
|
||||
int_i = _intOptMap.find(name);
|
||||
if(str_i != _strOptMap.end()) {
|
||||
str_i->second = value;
|
||||
} else if(int_i != _intOptMap.end()) {
|
||||
int_i->second = atol(value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// close the file
|
||||
config.close();
|
||||
} catch(std::fstream::failure e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the configuration file with the current configuration settings.
|
||||
*/
|
||||
int
|
||||
Config::save()
|
||||
{
|
||||
int error;
|
||||
std::fstream config;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, std::string>::iterator str_i;
|
||||
std::string configFile = _dir + "/fceu.cfg";
|
||||
char buf[1024];
|
||||
|
||||
// set the exception handling to catch i/o errors
|
||||
config.exceptions(std::ios::failbit | std::ios::badbit);
|
||||
|
||||
try {
|
||||
// open the file, truncate and for write
|
||||
config.open(configFile.c_str(), std::ios::out | std::ios::trunc);
|
||||
|
||||
// write a warning
|
||||
strcpy(buf, "# Auto-generated\n");
|
||||
config.write(buf, strlen(buf));
|
||||
|
||||
// write each configuration setting
|
||||
for(int_i = _intOptMap.begin(); int_i != _intOptMap.end(); int_i++) {
|
||||
snprintf(buf, 1024, "%s = %d\n",
|
||||
int_i->first.c_str(), int_i->second);
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
for(str_i = _strOptMap.begin(); str_i != _strOptMap.end(); str_i++) {
|
||||
snprintf(buf, 1024, "%s = %s\n",
|
||||
str_i->first.c_str(), str_i->second.c_str());
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
|
||||
// close the file
|
||||
config.close();
|
||||
} catch(std::fstream::failure e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef __CONFIGSYS_H
|
||||
#define __CONFIGSYS_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class Config {
|
||||
private:
|
||||
std::string _dir;
|
||||
|
||||
std::map<std::string, std::string> _strOptMap;
|
||||
std::map<std::string, int> _intOptMap;
|
||||
|
||||
std::map<char, std::string> _shortArgMap;
|
||||
std::map<std::string, std::string> _longArgMap;
|
||||
|
||||
private:
|
||||
int _addOption(char, const std::string &, const std::string &, int);
|
||||
int _load(void);
|
||||
int _parseArgs(int, char **);
|
||||
|
||||
public:
|
||||
const static int STRING = 1;
|
||||
const static int INTEGER = 2;
|
||||
|
||||
public:
|
||||
Config(std::string d) : _dir(d) { }
|
||||
~Config() { }
|
||||
|
||||
/**
|
||||
* Adds a configuration option. All options must be added before
|
||||
* parse().
|
||||
*/
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, int, int);
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, int, const std::string &);
|
||||
|
||||
/**
|
||||
* Sets a configuration option. Can be called at any time.
|
||||
*/
|
||||
int setOption(const std::string &, int);
|
||||
int setOption(const std::string &, const std::string &);
|
||||
|
||||
int getOption(const std::string &, std::string *);
|
||||
int getOption(const std::string &, const char **);
|
||||
int getOption(const std::string &, int *);
|
||||
|
||||
/**
|
||||
* Parse the arguments. Also read in the configuration file and
|
||||
* set the variables accordingly.
|
||||
*/
|
||||
int parse(int, char **);
|
||||
|
||||
/**
|
||||
* Save all of the current configuration options to the
|
||||
* configuration file.
|
||||
*/
|
||||
int save();
|
||||
};
|
||||
|
||||
#endif // !__CONFIGSYS_H
|
Loading…
Reference in New Issue