Files
retrobsd/tools/configsys/config.cpp
Matt Jenkins 07b6681eef Improve configsys option parsing
Up until now all the options in the config system have only been
able to take one word (or one string with no spaces) as a parameter.
This update improves it so it takes everything after the = up until
the end of the line (or the first #) as the parameter.
2014-04-29 13:37:09 +01:00

186 lines
4.1 KiB
C++

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <string>
#include <sstream>
#include "util.h"
#include "mapping.h"
#include "device.h"
#include "instance.h"
#include "config.h"
using namespace std;
extern map <string,device> devices;
extern map <string,device> cores;
extern map <string,mapping> mappings;
config::config(string path)
{
this->configpath = path;
}
string get_parsed_line(ifstream &f)
{
stringstream line;
char in[1024];
string token;
stringstream s;
s.str("");
if(f.getline(in,1023))
{
line.str(in);
while(line >> token)
{
if(token == "\\")
{
f.getline(in,1023);
line.str(in);
continue;
}
s << token << " ";
}
}
return s.str();
}
bool config::load(const char *filename)
{
ifstream f;
string temp;
size_t pos;
string devid = "";
map <string,device>::iterator it;
f.open(filename,ios::in);
if(!f.is_open())
{
cout << "Unable to open " << filename << endl;
return false;
}
while(!f.eof())
{
string command;
temp = get_parsed_line(f);
stringstream in(temp);
in >> command;
uc(command);
if(command.substr(0,1)=="#")
{
continue;
}
if(command == "MAPPING")
{
in >> this->pinmapping;
uc(this->pinmapping);
continue;
}
if(command == "DEVICE")
{
string devname;
int devnum;
string devid;
in >> devid;
uc(devid);
pos = devid.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUFWXYZ");
if(pos == devid.npos)
{
devname = devid;
devnum = 0;
} else {
devname = devid.substr(0,pos);
devnum = atoi(devid.substr(pos,devid.size()).c_str());
}
this->instances[devid].unit = devnum;
this->instances[devid].device = devname;
while(in >> temp)
{
pos = temp.find("=");
if(pos>0)
{
string l,r;
l = temp.substr(0,pos);
uc(l);
r = temp.substr(pos+1,temp.size());
this->instances[devid].settings[l] = r;
}
}
continue;
}
if(command == "CORE")
{
string devname;
in >> devname;
uc(devname);
if(cores.find(devname) == cores.end())
{
cout << "Unknown core: " << devname << endl;
f.close();
return false;
}
this->core.device = devname;
this->core.unit = 0;
while(in >> temp)
{
pos = temp.find("=");
if(pos>0)
{
this->core.settings[temp.substr(0,pos)] = temp.substr(pos,temp.size());
}
}
continue;
}
if(command == "LINKER")
{
in >> this->linker;
continue;
}
if(command == "OPTION")
{
in >> temp;
pos = temp.find("=");
if(pos>0)
{
stringstream data;
string l,r;
l = temp.substr(0,pos);
uc(l);
r = temp.substr(pos+1,temp.size());
data << r;
while (in >> temp) {
if (temp[0] == '#') {
break;
}
data << " " << temp;
}
this->instances["GLOBAL"].settings[l] = data.str();
this->instances["GLOBAL"].device="GLOBAL";
this->instances["GLOBAL"].unit=0;
}
continue;
}
}
f.close();
return true;
}