- added this configuration system for cross-platform testing

This commit is contained in:
gimmedonutnow 2006-08-10 05:25:19 +00:00
parent 1e7eeb0140
commit 4102348817
3 changed files with 472 additions and 0 deletions

View File

@ -8,6 +8,7 @@ scale2x.cpp
scale3x.cpp
scalebit.cpp
vidblit.cpp
configSys.cpp
""")
for x in range(len(my_list)):

View File

@ -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;
}

View File

@ -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