123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- // STL includes
- #include <assert.h>
- #include <fstream>
- #include <unistd.h> //for getpwd() under linux
- #include <sys/param.h> //for MAXPATHLEN - the maximal path length
- // nice-core includes
- #include "core/basics/Exception.h"
- #include "core/basics/Config.h"
- #include "core/basics/ossettings.h"
- #include "core/basics/StringTools.h"
- #include "core/basics/FileName.h"
- using namespace NICE;
-
- using namespace std;
- #undef DEBUGCONFIG
- #define DEBUGPRINT printf
- Config::Config ()
- {
- ioUntilEndOfFile = true;
- }
- Config::Config ( const std::string & configfn )
- {
- if ( configfn.size() >0 ) {
- read(configfn);
- }
- ioUntilEndOfFile = true;
- m_sConfigFilename = configfn;
- }
- Config::Config ( int argc,
- char **argv )
- {
- readFromArguments ( argc, argv );
- std::string configfile = gS("main", "config", "" );
- NICE::FileName t_ConfigFilename( configfile );
- // check for relative path correction:
- // if dataset is a relative path, then make it absolute using the
- // currend working directory
- if( t_ConfigFilename.isRelative() )
- {
- char sCWDPath[MAXPATHLEN];
- getcwd(sCWDPath, MAXPATHLEN);
- t_ConfigFilename.set( string(sCWDPath) + "/" + configfile );
- t_ConfigFilename.convertToRealPath();
- configfile = t_ConfigFilename.str();
- }
- m_sConfigFilename = configfile;
- std::cerr << "configfile: " << configfile << std::endl;
- ioUntilEndOfFile = gB("main", "ioUntilEndOfFile", true );
- if ( configfile.size() > 0 )
- readWithoutOverwrite ( configfile.c_str(), CONFIG_DO_NOT_OVERWRITE_VALUES /*do not overwrite values*/ );
- }
- Config::Config ( const Config & conf ) : Persistent()
- {
- ioUntilEndOfFile = true;
- m_sConfigFilename = conf.m_sConfigFilename;
- confB.copyFrom ( conf.confB );
- confD.copyFrom ( conf.confD );
- confI.copyFrom ( conf.confI );
- confS.copyFrom ( conf.confS );
- }
- Config::~Config()
- {
- }
- void Config::clear()
- {
- #if defined DEBUGCONFIG
- DEBUGPRINT( "Config: clear ...\n" );
- #endif
- confB.clear();
- confD.clear();
- confI.clear();
- confS.clear();
- }
- void Config::addKeyValuePair ( const std::string & block,
- const std::string & key,
- const std::string & value )
- {
- vector<string> submatches;
- #if defined DEBUGCONFIG
- DEBUGPRINT( "Config: analyzing value %s\n", value.c_str() );
- #endif
- if ( StringTools::regexMatch ( value, "^ *([-[:digit:]]+) *;?$", submatches ) &&
- (submatches.size() == 2) ) {
- #if defined DEBUGCONFIG
- DEBUGPRINT ( "Config: integer value\n");
- #endif
- int v;
- v = StringTools::convert<int> ( submatches[1] );
- confI.store ( block, key, v );
- } else if ( value.compare("true") == 0 ) {
- #if defined DEBUGCONFIG
- DEBUGPRINT( "Config: boolean value\n");
- #endif
- confB.store ( block, key, true );
- } else if ( value.compare("false") == 0 ) {
- #if defined DEBUGCONFIG
- DEBUGPRINT ( "Config: boolean value\n");
- #endif
- confB.store ( block, key, false );
- } else if ( StringTools::regexMatch ( value, "^ *([-e.[:digit:]]+) *;?$", submatches ) &&
- (submatches.size() == 2) )
- {
- double v;
- if ( ! StringTools::convert<double> ( submatches[1], v ) )
- {
- DEBUGPRINT ( "Config: please ask Erik to debug this part of Config.cpp\n");
- exit(-1);
- }
- #if defined DEBUGCONFIG
- DEBUGPRINT ( "Config: double value\n");
- #endif
- confD.store ( block, key, v );
- } else {
- #if defined DEBUGCONFIG
- DEBUGPRINT ( "Config: string value\n");
- #endif
- string trimValue = value;
- StringTools::trimbounds ( trimValue, '\"' );
- StringTools::trimbounds ( trimValue, '\'' );
- confS.store ( block, key, trimValue );
- }
- }
- void Config::readFromArguments ( int argc, char **argv )
- {
- std::string section;
- std::string key;
- std::string value;
- ioUntilEndOfFile = true;
- for ( int i = 1 ; i < argc ; i++ )
- {
- if ( argv[i] == NULL ) break;
- std::string arg ( argv[i] );
- vector<string> submatches;
- bool match = false;
- match = StringTools::regexMatch ( arg, "^--?([[:alpha:]][[:alpha:][:digit:]_-]*):([[:alpha:][:digit:]_-]+)", submatches );
- if ( (match) && (submatches.size() == 3) ) {
- if ( key.size() > 0 ) {
- addArgBoolean ( section, key );
- }
- section = submatches[1];
- key = submatches[2];
- continue;
- }
- match = StringTools::regexMatch ( arg, "^--?([[:alpha:]][[:alpha:][:digit:]_-]*)", submatches );
- if ( (match) && (submatches.size() == 2) ) {
- if ( key.size() > 0 )
- {
- addArgBoolean ( section, key );
- }
- section = "main";
- key = submatches[1];
- continue;
- }
- value = string(argv[i]);
- if ( key.size() <= 0 )
- {
- // add to more options
- moreOptions.push_back ( value );
- continue;
- }
- #if defined DEBUGCONFIG
- cout << "Config: add command line option: " << section << ":" << key << " = " << value << endl;
- #endif
- addKeyValuePair ( section, key, value );
- key = "";
- }
-
- if ( key.size() > 0 )
- addArgBoolean ( section, key );
- }
- // refactor-nice.pl: check this substitution
- // old: void Config::addArgBoolean ( const string & section, const string & key )
- void Config::addArgBoolean ( const std::string & section, const std::string & key )
- {
- vector<string> submatches;
- if ( StringTools::regexMatch ( key, "^no-(.*)$", submatches )
- && (submatches.size() == 2) )
- {
- confB.store ( section, submatches[1], false );
- } else {
- confB.store ( section, key, true );
- }
- }
- void Config::restore (istream & is, int format)
- {
- std::string block = "main";
- std::string key;
- std::string value;
- std::string line;
- int count = 0;
-
- //check for the first word
- //if this is "Config::store--PreciseTermination" then we do not read until eof
- //but bis the precise termination statement "Config::store--done" arises
- std::string firstWord;
- if (! is.eof() )
- {
- is >> firstWord;
- if ( firstWord.compare( "Config::store--PreciseTermination" ) == 0)
- {
- ioUntilEndOfFile = false;
- }
- else
- ioUntilEndOfFile = true;
- }
-
- //jump to the beginning of the file
- is.clear();
- is.seekg(0, ios::beg);
- //we keep the while-loop untached, but break out of ioUntilEndOfFile is false and we reached the termination-statement
- while (! is.eof())
- {
- size_t i=0;
- if ( !getline(is, line) )
- break;
-
- //do we have to check for the precise termination statement and reaches it yet?
- if ( (!ioUntilEndOfFile) && (line.compare("Config::store--done") == 0) )
- break;
- if ( line.size() <= 0 )
- continue;
- size_t len = line.size();
- count++;
- if ( (len < 1) || (line[0] == '#' ) )
- continue;
- line = StringTools::chomp ( line );
- len = line.size();
- #if defined DEBUGCONFIG
- DEBUGPRINT ("Config: (%d) '%s' (len = %d) / %s\n", (int)count, line.c_str(), (int)len,
- block.c_str());
- #endif
- while ( ( (line[i] == '\t') || (line[i]==' ') ) && (i<len)) i++;
- if ( i == len ) continue;
-
- if ( line[i] == '[' ) {
- size_t j = i+1;
- while ((line[j]!=']') && (j<len)) j++;
- if ( (j == len) || (i==j-1) ) continue;
- block = line.substr( i+1, j-i-1 );
- #if defined DEBUGCONFIG
- DEBUGPRINT ("Config: reading block %s\n", block.c_str());
- #endif
- StringTools::normalize_string(block);
- continue;
- }
- if ( line[i] == '%' ) {
- size_t j = i+1;
- while ((line[j]!='%') && (j<len)) j++;
- if ( (j == len) || (i==j-1) ) continue;
- std::string includefile = line.substr( i+1, j-i-1 );
- #if defined DEBUGCONFIG
- DEBUGPRINT ("Config: including config file %s\n", includefile.c_str());
- #endif
- StringTools::normalize_string ( includefile );
- readWithoutOverwrite ( includefile.c_str(), format );
- continue;
- }
-
- size_t p = i;
- while ( (line[p]!='=') && (p<len) ) p++;
- if ( (p >= len-1) || (p<=i) ) continue;
- key = line.substr( i, p-i );
- value = line.substr( p+1 ); // with only one argument, substr copies from the specified position until the end of the string
- StringTools::normalize_string(value);
- StringTools::normalize_string(key);
- // transform(key.begin(), key.end(), key.begin(), ::tolower);
- #if defined DEBUGCONFIG
- DEBUGPRINT ("Config: found key value pair (%s,%s) in section %s\n",
- key.c_str(), value.c_str(), block.c_str());
- #endif
- if ( (format == CONFIG_OVERWRITE_VALUES) || ( !keyExists(block, key) ) )
- addKeyValuePair ( block, key, value );
- }
- #if defined DEBUGCONFIG
- DEBUGPRINT ("Config: successfully loaded.\n" );
- DEBUGPRINT ("Config: %d double values\n", (int)confD.size() );
- DEBUGPRINT ("Config: %d integer values\n", (int)confI.size() );
- DEBUGPRINT ("Config: %d bool values\n", (int)confB.size() );
- // refactor-nice.pl: check this substitution
- // old: DEBUGPRINT ("Config: %d string values\n", (int)confS.size() );
- DEBUGPRINT ("Config: %d std::string values\n", (int)confS.size() );
- #endif
- }
-
- bool Config::keyExists ( const std::string & block, const std::string & key ) const
- {
- return ( confS.keyExists ( block, key ) ||
- confI.keyExists ( block, key ) ||
- confB.keyExists ( block, key ) ||
- confD.keyExists ( block, key ) );
- }
- void Config::addHelp ( const std::string & block, const std::string & key,
- const std::string & helpText )
- {
- helpTexts[ block + "::" + key ] = helpText;
- }
- std::string Config::help ( const std::string & block, const std::string & key ) const
- {
- std::string k = block + "::" + key;
- map<string, string>::const_iterator i = helpTexts.find(k);
- if ( i == helpTexts.end() )
- return "no helping information for this variable, sorry!";
- else
- return i->second;
- }
- std::string Config::gS(const std::string & key) const
- {
- return gS(key, "main");
- }
- std::string Config::gS(const std::string & block, const std::string & key) const
- {
- std::string v ("");
- if ( confS.find(block, key, v) )
- {
- return v;
- }
- else
- {
- std::string errorMessage = "Config: setting " + block + "::" + key + " not found !\n";
- errorMessage += "\n \n Config: " + help(block, key) + "\n";
- throw NICE::Exception( errorMessage );
- }
- }
- // refactor-nice.pl: check this substitution
- // old: string Config::gS(const string & block, const string & key, const string & defv) const
- std::string Config::gS(const std::string & block, const std::string & key, const std::string & defv) const
- {
- // refactor-nice.pl: check this substitution
- // old: string v ("");
- std::string v ("");
- if ( confS.find(block, key, v) ) {
- return v;
- } else {
- #if defined DEBUGCONFIG
- DEBUGPRINT("Config: Setting %s::%s not found using default value %s\n", block.c_str(), key.c_str(), defv.c_str() );
- #endif
- return defv;
- }
- }
- // refactor-nice.pl: check this substitution
- // old: double Config::gD(const string & key) const
- double Config::gD(const std::string & key) const
- {
- return gD(key, "main");
- }
- // refactor-nice.pl: check this substitution
- // old: double Config::gD(const string & block, const string & key) const
- double Config::gD(const std::string & block, const std::string & key) const
- {
- double v = 0.0;
- if ( confD.find(block, key, v) ) {
- return v;
- } else {
- int vi;
- if ( confI.find(block, key, vi) ) {
- DEBUGPRINT("Config: Setting %s::%s should be double (please change in the config)\n", block.c_str(), key.c_str() );
- return (int)vi;
- }
- fprintf (stderr, "Config: setting %s::%s not found !\n", block.c_str(), key.c_str() );
- fprintf (stderr, "Config: %s\n", help(block, key).c_str() );
- exit(-1);
- return -1.0; // never reached
- }
- }
- // refactor-nice.pl: check this substitution
- // old: double Config::gD(const string & block, const string & key, const double defv) const
- double Config::gD(const std::string & block, const std::string & key, const double defv) const
- {
- double v = 0.0;
- if ( confD.find(block, key, v) ) {
- return v;
- } else {
- int vi;
- if ( confI.find(block, key, vi) ) {
- DEBUGPRINT("Config: Setting %s::%s should be double (please change in the config)\n", block.c_str(), key.c_str() );
- return (int)vi;
- }
- #if defined DEBUGCONFIG
- DEBUGPRINT("Config: Setting %s::%s not found using default value %f\n", block.c_str(), key.c_str(), defv );
- #endif
- return defv;
- }
- }
- // refactor-nice.pl: check this substitution
- // old: int Config::gI(const string & key) const
- int Config::gI(const std::string & key) const
- {
- return gI(key, "main");
- }
- // refactor-nice.pl: check this substitution
- // old: int Config::gI(const string & block, const string & key) const
- int Config::gI(const std::string & block, const std::string & key) const
- {
- int v = 0;
- if ( confI.find(block, key, v) ) {
- return v;
- } else {
- fprintf (stderr, "Config: setting %s::%s not found !\n", block.c_str(), key.c_str() );
- fprintf (stderr, "Config: %s\n", help(block, key).c_str() );
- exit(-1);
- return 1; // never reached
- }
- }
- // refactor-nice.pl: check this substitution
- // old: int Config::gI(const string & block, const string & key, int defv) const
- int Config::gI(const std::string & block, const std::string & key, int defv) const
- {
- int v = 0;
- if ( confI.find(block, key, v) ) {
- return v;
- } else {
- #if defined DEBUGCONFIG
- DEBUGPRINT("Config: Setting %s::%s not found using default value %d\n", block.c_str(), key.c_str(), defv );
- #endif
- return defv;
- }
- }
- // refactor-nice.pl: check this substitution
- // old: bool Config::gB(const string & key) const
- bool Config::gB(const std::string & key) const
- {
- return gB(key, "main");
- }
- // refactor-nice.pl: check this substitution
- // old: bool Config::gB(const string & block, const string & key) const
- bool Config::gB(const std::string & block, const std::string & key) const
- {
- bool v = true;
- if ( confB.find(block, key, v) ) {
- return v;
- } else {
- fprintf (stderr, "Config: setting %s::%s not found !\n", block.c_str(), key.c_str() );
- fprintf (stderr, "Config: %s\n", help(block, key).c_str() );
- exit(-1);
- return true; // never reached
- }
- }
- // refactor-nice.pl: check this substitution
- // old: bool Config::gB(const string & block, const string & key, bool defv) const
- bool Config::gB(const std::string & block, const std::string & key, bool defv) const
- {
- bool v = true;
- if ( confB.find(block, key, v) ) {
- return v;
- } else {
- #if defined DEBUGCONFIG
- DEBUGPRINT("Config: Setting %s::%s not found using default value %d\n", block.c_str(), key.c_str(), defv );
- #endif
- return defv;
- }
- }
- // refactor-nice.pl: check this substitution
- // old: void Config::getAllS ( const std::string & block, std::map< string, string > & list ) const
- void Config::getAllS ( const std::string & block, std::map< string, std::string > & list ) const
- {
- confS.getAll ( block, list );
- }
- void Config::getAllD ( const std::string & block, std::map< string, double > & list ) const
- {
- confD.getAll ( block, list );
- }
- void Config::getAllI ( const std::string & block, std::map< string, int > & list ) const
- {
- confI.getAll ( block, list );
- }
- void Config::getAllB ( const std::string & block, std::map< string, bool > & list ) const
- {
- confB.getAll ( block, list );
- }
- void Config::sD(const std::string & block, const std::string & key, const double defv)
- {
- confD.store ( block, key, defv );
- }
- void Config::sI(const std::string & block, const std::string & key, const int defv)
- {
- confI.store ( block, key, defv );
- }
- void Config::sB(const std::string & block, const std::string & key, const bool defv)
- {
- confB.store ( block, key, defv );
- }
- void Config::sS(const std::string & block, const std::string & key, const std::string & defv)
- {
- confS.store ( block, key, defv );
- }
- void Config::store (ostream & os, int format) const
- {
- if (!ioUntilEndOfFile)
- {
- //let's give us a hint that we do not have to restore until end of file but until "Config::store--done"
- os << "Config::store--PreciseTermination" << std::endl;
- }
- os << "# -----------------------------------------" << endl;
- os << "# | Config |" << endl;
- os << "# -----------------------------------------" << endl;
- os << endl << "# ------------- double values" << endl;
- confD.store( os, format );
- os << endl << "# ------------- boolean values" << endl;
- confB.store( os, format );
- os << endl << "# ------------- integer values" << endl;
- confI.store( os, format );
- os << endl << "# ------------- string values" << endl;
- confS.store( os, format );
- os << "# -----------------------------------------" << endl;
- if (!ioUntilEndOfFile)
- {
- os << "Config::store--done" << std::endl;
- }
- }
- void Config::getAllBlocks ( std::set< std::string > & list ) const
- {
- list.clear();
- confB.getAllBlocks ( list );
- confD.getAllBlocks ( list );
- confS.getAllBlocks ( list );
- confI.getAllBlocks ( list );
- }
- string Config::getAbsoluteFilenameRelativeToThisConfig(const string &p_Filename) const
- {
- if( m_sConfigFilename.empty() )
- return p_Filename;
- NICE::FileName t_DatasetFilename( p_Filename );
- if( !t_DatasetFilename.isRelative() )
- {
- return p_Filename;
- }
- NICE::FileName t_ConfigFilename( this->m_sConfigFilename );
- return t_ConfigFilename.extractPath().str() + p_Filename;
- }
|