Browse Source

Implemented support of lists in configuration files

master
Artyom Beilis 16 years ago
parent
commit
3dc4b6c460
2 changed files with 122 additions and 51 deletions
  1. +55
    -10
      global_config.cpp
  2. +67
    -41
      global_config.h

+ 55
- 10
global_config.cpp View File

@@ -14,6 +14,14 @@ bool cppcms_config::get_tocken(FILE *f,tocken_t &T)
T.first='.';
return true;
}
else if(c=='{') {
T.first='{';
return true;
}
else if(c=='}') {
T.first='}';
return true;
}
else if(c=='=') {
T.first='=';
return true;
@@ -119,22 +127,22 @@ void cppcms_config::load(char const *fname)
string key;
int state=0;
try{
while(get_tocken(f,T) && state != 5) {
while(get_tocken(f,T) && state != -1) {
switch(state) {
case 0: if(T.first != WORD) {
state=5;
state=-1;
}else{
key=T.second;
state=1;
}
break;
case 1: if(T.first != '.')
state=5;
state=-1;
else
state=2;
break;
case 2: if(T.first!=WORD){
state=5;
state=-1;
}else{
state=3;
key+='.';
@@ -142,27 +150,64 @@ void cppcms_config::load(char const *fname)
}
break;
case 3: if(T.first!= '=')
state=5;
state=-1;
else
state=4;
break;
case 4: if(T.first==INT) {
case 4: if(T.first=='{') {
state=5;
break;
}
if(T.first==INT) {
long val=atol(T.second.c_str());
long_map.insert(pair<string,long>(key,val));
data[key]=val;
}
else if(T.first==DOUBLE) {
double val=atof(T.second.c_str());
double_map.insert(pair<string,double>(key,val));
data[key]=val;
}
else if(T.first==STR){
string_map.insert(pair<string,string>(key,T.second));
data[key]=T.second;
}
else {
state=5;
state=-1;
break;
}
state=0;
break;
case 5:
if(T.first==INT || T.first==DOUBLE || T.first==STR) {
int fp=T.first;
vector<long> vl;
vector<double> vd;
vector<string> vs;
do {
if(T.first=='}') {
state=0;
}
else if(T.first==fp){
switch(T.first) {
case INT: vl.push_back(atol(T.second.c_str())); break;
case DOUBLE: vd.push_back(atof(T.second.c_str())); break;
case STR: vs.push_back(T.second); break;
}
}
else {
state=-1;
}
}while(state==5 && get_tocken(f,T));

if(state==0) {
switch(fp) {
case INT: data[key]=vl; break;
case DOUBLE: data[key]=vd; break;
case STR: data[key]=vs; break;
};
}
}
else
state=-1;
break;
}
}
if(state!=0) {


+ 67
- 41
global_config.h View File

@@ -3,7 +3,9 @@

#include <string>
#include <map>
#include <vector>
#include "cppcms_error.h"
#include <boost/any.hpp>

namespace cppcms {

@@ -12,68 +14,92 @@ using namespace std;
class cppcms_config {

enum { WORD, INT, DOUBLE, STR };
typedef std::pair<int,string> tocken_t;

typedef std::pair<string,string> key_t;

std::map<string,long> long_map;
std::map<string,double> double_map;
std::map<string,string> string_map;
map<string,boost::any> data;

string filename;

int line_counter;

bool loaded;

bool get_tocken(FILE *,tocken_t &T);

template<typename T>
T const *get(string const &name) const {
map<string,boost::any>::const_iterator it;
if((it=data.find(name))==data.end()) {
return NULL;
}
T const *res=boost::any_cast<T>(&it->second);
if(!res) {
throw cppcms_error("Type mistmach for field "+name);
}
return res;
};

template<typename T>
T const &get(string const &name,T const &def) const
{
T const *p=get<T>(name);
if(!p) return def;
return *p;
};
template<typename T>
T const &get_throw(string const &name) const
{
T const *p=get<T>(name);
if(!p) throw cppcms_error("Configuration parameter "+name+" not found");
return *p;
};
template<typename T>
T const &get_nothrow(string const &name) const
{
T const *p=get<T>(name);
static const T v;
if(!p) return v;
return *p;
};


public:

size_t size() const { return data.size(); };
void load(char const *filename);
void load(int argc,char *argv[],char const *def=NULL);

cppcms_config() { loaded = false;};
long lval(string major) const {
std::map<string,long>::const_iterator it;
if((it=long_map.find(major))!=long_map.end()) {
return it->second;
}
throw cppcms_error("Undefined configuration "+major);

long lval(string m) const {
return get_throw<long>(m);
};
long lval(string major,long def) const {
std::map<string,long>::const_iterator it;
if((it=long_map.find(major))!=long_map.end()) {
return it->second;
}
return def;
long lval(string m,long def) const {
return get<long>(m,def);
};
double dval(string major) const {
std::map<string,double>::const_iterator it;
if((it=double_map.find(major))!=double_map.end()) {
return it->second;
}
throw cppcms_error("Undefined configuration "+major);
double dval(string m) const {
return get_throw<double>(m);
};
double dval(string major,double def) const {
std::map<string,double>::const_iterator it;
if((it=double_map.find(major))!=double_map.end()) {
return it->second;
}
return def;
double dval(string m,double def) const {
return get<double>(m,def);
};
string const &sval(string major) const {
std::map<string,string>::const_iterator it;
if((it=string_map.find(major))!=string_map.end()) {
return it->second;
}
throw cppcms_error("Undefined configuration "+major);
string const &sval(string m) const {
return get_throw<string>(m);
};
string sval(string major,string def) const {
std::map<string,string>::const_iterator it;
if((it=string_map.find(major))!=string_map.end()) {
return it->second;
}
return def;
string sval(string m,string def) const {
return get<string>(m,def);
};
vector<long> const &llist(string m) const {
return get_nothrow<vector<long> >(m);
}
vector<double> const &dlist(string m) const{
return get_nothrow<vector<double> >(m);
};

vector<string> const &slist(string m) const {
return get_nothrow<vector<string> >(m);
};

};


Loading…
Cancel
Save