Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

ConfigFileParser - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: ConfigFileParser.cc,v 1.7 2005/05/06 18:29:37 thea Exp $
// Daniel De Marco created Jan, 28 2002

#include "ConfigFileParser.hh"
#include <stdlib.h>
#include <time.h>
#include <math.h>

ClassImp(ConfigFileParser)

string ConfigFileParser::fCfgDir = "./config";

//______________________________________________________________________________
 ConfigFileParser::ConfigFileParser(const string &type, const string &s, const string &fn) 
    : fBasicType(type), fBasicName(s) {
    
    // 
    // Constructor
    //

    if(fn.empty()) fPath=type+"/"+s+".cfg";
    else fPath=fn;

    ParseConfigFile();
}

//______________________________________________________________________________
 void ConfigFileParser::CheckId(const string &s) {

    if(fNumbers.count(s)!=0 || fChars.count(s)!=0) {
            cout<<"warning: multiple definition of "<<s<<endl;
    }
}


//______________________________________________________________________________
 void ConfigFileParser::ParseConfigFile() {
    //
    // Parse the config file
    //

    // open config file
    string fname = fCfgDir+"/"+fPath;
    ifstream in(fname.c_str());
    if(!in) Msg(EsafMsg::Panic) << "can't open file "+fPath << MsgDispatch;
    
    string dummy;
    while(getline(in, dummy)) {
        ParseLine(dummy);
    } 

}

//______________________________________________________________________________
 void ConfigFileParser::ParseLine( string line) {
        size_t pos;

        // erase comments
        pos=line.find('#');
        if(pos!=string::npos) line.erase(pos);

        // swallow spaces
        line=swallow_spaces(line);

        // skip blank lines
        if(line.empty()) return;

        // we expect something like that:
        // identifier=number
        // identifier=string

        // get identifier
        string identifier=line.substr(0,line.find('='));
        identifier=r_swallow_spaces(identifier);
        if(identifier.find_first_of("t ")!=string::npos) 
            Msg(EsafMsg::Panic) << "wrong assignment: "+line << MsgDispatch;

        // get value
        string value=line.substr(line.find('=')+1, string::npos);
        value=swallow_spaces(value);
        value=r_swallow_spaces(value);
        // trying for a double
        char *p;
        double d=strtod(value.c_str(), &p);
        if(d==0 && value.c_str()==p || isinf(d) || isnan(d) )  {
            // not a double, inf and nan are not considered numbers
            CheckId(identifier);
            fChars[identifier]=value; 
        } else { 
            // a double
            CheckId(identifier);
            fNumbers[identifier]=d; 
        }

}

//______________________________________________________________________________
 void ConfigFileParser::ReplaceStr(const string &s, const string& val) {
    // 
    // Replace a string value in the Config
    //

    string s1 = s;
    s1 = swallow_spaces(s1);
    if (s1.empty()) 
        Msg(EsafMsg::Panic) << "invalid key: "+s << MsgDispatch;
    fChars[s] = val;
}

//______________________________________________________________________________
 void ConfigFileParser::ReplaceNum(const string &s, const double val) {
    // 
    // Replace a numerical value in the Config
    // 

    string s1 = s;
    s1 = swallow_spaces(s1);
    if (s1.empty()) 
        Msg(EsafMsg::Panic) << "invalid key: "+s << MsgDispatch;
    fNumbers[s1] = val;
}

//______________________________________________________________________________
 void ConfigFileParser::Replace(const string &s, Bool_t add) {
    //
    // Replace a string or a number value in the Config
    // 

    string s1 = s;
    s1 = swallow_spaces(s1);
    if (s1.empty()) 
        Msg(EsafMsg::Panic) << "invalid expr: "+s << MsgDispatch;

    string identifier=s1.substr(0,s1.find('='));

    identifier=r_swallow_spaces(identifier);
    if(identifier.find_first_of("t ")!=string::npos) 
        Msg(EsafMsg::Panic) << "wrong assignment: "+s1 << MsgDispatch;

    if (!add && fChars.count(identifier) == 0 && fNumbers.count(identifier) == 0)
        Msg(EsafMsg::Panic) << identifier+" does not exists in class "+fBasicName << MsgDispatch;

    // get value
    string value=s1.substr(s1.find('=')+1, string::npos);
    value=swallow_spaces(value);
    value=r_swallow_spaces(value);
    // trying for a double
    char *p;
    double d=strtod(value.c_str(), &p);
    if(d==0 && value.c_str()==p) { // not a double
        fChars[identifier]=value; 
    } else { // a double
        fNumbers[identifier]=d; 
    }
}


//______________________________________________________________________________
 void ConfigFileParser::Write(const string &name) const {
    //
    // Write the content of this to file
    //

    // open file
    ofstream out(name.c_str());
    if(!out) Msg(EsafMsg::Panic) << "can't open file "+fPath << MsgDispatch;

    char datestr[100];
    time_t timet=time(0);
    strftime(datestr, 100, "%Y-%m-%d %H:%M", localtime(&timet));
    // write header
    out<<"# "<<name<<"n"
        <<"# original filename: "<<fPath<<"n"
        <<"# "<<datestr<<endl;

    // write fNumbers
    map<string, double>::const_iterator i=fNumbers.begin();
    for(; i!=fNumbers.end(); i++) {
        out<<i->first<<" = "<<i->second<<endl;
    }

    // write strings
    map<string, string>::const_iterator p=fChars.begin();
    for(; p!=fChars.end(); p++) {
        out<<p->first<<" = "<<p->second<<endl;
    }
}
About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update Wed Nov 16 16:57:39 2005 Wed Nov 16 16:29:22 2005