configuration.cpp

Go to the documentation of this file.
00001 //======================================================================
00002 // File:        configuration.cpp
00003 // Author:      Matthias Toussaint
00004 // Created:     Sun Dec  3 10:31:50 CET 2006
00005 // Project:     QtDMM
00006 // Description: Commandline parsing and configuration file reading
00007 //----------------------------------------------------------------------
00008 // This file  may  be used under  the terms of  the GNU  General Public
00009 // License  version 2.0 as published   by the Free Software  Foundation
00010 // and appearing  in the file LICENSE.GPL included  in the packaging of
00011 // this file.
00012 // 
00013 // This file is provided AS IS with  NO WARRANTY OF ANY KIND, INCLUDING 
00014 // THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00015 // PURPOSE.
00016 //----------------------------------------------------------------------
00017 // Copyright 2006 Matthias Toussaint
00018 //======================================================================
00019 
00020 #include <configuration.h>
00021 #include <util.h>
00022 #include <fstream>
00023 #include <iostream>
00024 
00025 Configuration::Configuration()
00026 {
00027 }
00028 
00029 Configuration::~Configuration()
00030 {
00031 }
00032 
00033 void Configuration::addOption( const Option & option )
00034 {
00035   m_option.push_back( option );
00036 }
00037 
00038 bool Configuration::setCommandLine( int argc, char **argv )
00039 {
00040   if (argc<2) return false;
00041   
00042   int argIndex=1;
00043   bool waitForParameter=false;
00044   std::string key;
00045   
00046   do 
00047   {
00048     if (waitForParameter)
00049     {
00050       insertEntry( key, argv[argIndex] );
00051       waitForParameter = false;
00052     }
00053     else
00054     {
00055       TokenList tokenList = Util::tokenize( argv[argIndex], "=" );
00056       
00057       if (tokenList.size() == 1)
00058       {
00059         int index = findOption( tokenList[0] );
00060         
00061         if (-1 != index)
00062         {
00063           if (m_option[index].hasParameter) 
00064           {
00065             key = m_option[index].longOption;
00066             waitForParameter = true;
00067           }
00068           else
00069           {
00070             insertEntry( m_option[index].longOption, "" );
00071           }
00072         }
00073         else
00074         {
00075           std::cout << "Unknown parameter: " << tokenList[0] 
00076                     << std::endl;
00077           
00078           return false;
00079         }
00080       }
00081       else if (tokenList.size() == 2)
00082       {
00083         if (tokenList[0].substr( 0, 2 ) != "--")
00084         {
00085           std::cout << "Error processing commandline: " << tokenList[0] 
00086                     << std::endl;
00087           
00088           return false;
00089         }
00090         
00091         insertEntry( tokenList[0].substr( 2, tokenList[0].size()-2 ), tokenList[1] );
00092       }
00093       else 
00094       {
00095         std::cout << "Error processing commandline: " << tokenList[0] 
00096                   << std::endl;
00097         
00098         return false;
00099       }
00100     }
00101     
00102     ++argIndex;
00103     
00104   } while (argIndex<argc);
00105   
00106   return true;
00107 }
00108 
00109 void Configuration::insertEntry( const std::string & key, 
00110                                  const std::string & value )
00111 {
00112   int index = findEntry( key );
00113   if (-1 == index)
00114   {
00115     m_entry.push_back( OptionEntry( key, value ));
00116   }
00117   else
00118   {
00119     m_entry[index] = OptionEntry( key, value );
00120   }
00121 }
00122 
00123 int Configuration::findOption( const std::string & optionText ) const
00124 {
00125   int index = findShort( optionText );
00126   if (-1 == index) index = findLong( optionText );
00127   
00128   return index;
00129 }
00130 
00131 int Configuration::findShort( const std::string & tst ) const
00132 {
00133   int i=0;
00134   while (tst[i] == '-') ++i;
00135   std::string shortOption = tst.substr( i, tst.size()-i );
00136   
00137   i=0;
00138   
00139   for (OptionList::const_iterator it = m_option.begin(); 
00140        it != m_option.end(); ++it, ++i)
00141   {
00142     if ((*it).shortOption == shortOption) return i;
00143   }
00144   
00145   return -1;
00146 }
00147 
00148 int Configuration::findLong( const std::string & tst ) const
00149 {
00150   int i=0;
00151   while (tst[i] == '-') ++i;
00152   std::string longOption = tst.substr( i, tst.size()-i );
00153   
00154   i=0;
00155   
00156   for (OptionList::const_iterator it = m_option.begin(); 
00157        it != m_option.end(); ++it, ++i)
00158   {
00159     if ((*it).longOption == longOption) return i;
00160   }
00161   
00162   return -1;
00163 }
00164 
00165 int Configuration::findEntry( const std::string & key ) const
00166 {
00167   int index=0;
00168   for (EntryList::const_iterator it = m_entry.begin(); 
00169        it != m_entry.end(); ++it, ++index)
00170   {
00171     if ((*it).key == key) return index;
00172   }
00173   
00174   return -1;
00175 }
00176 
00177 bool Configuration::hasKey( const std::string & key ) const
00178 {
00179   for (EntryList::const_iterator it = m_entry.begin(); 
00180        it != m_entry.end(); ++it)
00181   {
00182     if ((*it).key == key) return true;
00183   }
00184   
00185   return false;
00186 }
00187 
00188 std::string Configuration::value( const std::string & key ) const
00189 {
00190   for (EntryList::const_iterator it = m_entry.begin(); 
00191        it != m_entry.end(); ++it)
00192   {
00193     if ((*it).key == key)
00194     {
00195       return (*it).value;
00196     }
00197   }
00198   
00199   return std::string();
00200 }
00201 
00202 int Configuration::intValue( const std::string & key ) const
00203 {
00204   std::string str = value( key );
00205   int intValue;
00206   Util::fromString( &intValue, str );
00207   
00208   return intValue;
00209 }
00210 
00211 bool Configuration::loadFile( const std::string & filename )
00212 {
00213   // dear c++ gurus. why the heck do I need c_str here?
00214   std::ifstream is( filename.c_str(), std::ios_base::in );
00215   
00216   if (!is)
00217   {
00218     std::cerr << "Couldn't open file: " << filename << std::endl;
00219     return false;
00220   }
00221   std::string line;
00222   
00223   while (!is.eof())
00224   {
00225     std::getline( is, line );
00226     line = Util::strip_whitespace( line );
00227     
00228     if (line.size())
00229     {
00230       if (line[0] != '#')
00231       {
00232         TokenList tokenList = Util::tokenize( line, "=" );
00233         
00234         int index = findOption( Util::strip_whitespace( tokenList[0] ));
00235         
00236         if (-1 != index)
00237         {
00238           if (m_option[index].hasParameter)
00239           {
00240             if (tokenList.size() == 2)
00241             {
00242               insertEntry( m_option[index].longOption, 
00243                            Util::strip_whitespace( tokenList[1] ));
00244             }
00245             else if (tokenList.size() > 2)
00246             {
00247               std::cerr << "Too many values in line: " << line << std::endl;
00248               return false;
00249             }
00250             else 
00251             {
00252               std::cerr << "Missing value in line: " << line << std::endl;
00253               return false;
00254             }
00255           }
00256           else
00257           {
00258             insertEntry( m_option[index].longOption, "" );
00259           }
00260         }
00261       }
00262     }
00263   }
00264     
00265   return true;
00266 }
00267 
00268 void Configuration::printEntries() const
00269 {
00270   for (EntryList::const_iterator it = m_entry.begin(); 
00271        it != m_entry.end(); ++it)
00272   {
00273     std::cout << (*it).key << " = " 
00274         << (*it).value << std::endl;
00275   }
00276 }
00277 
00278 std::string Configuration::helpText() const
00279 {
00280   std::string help;
00281   help = "Syntax: -s[ value] or --long[=value]\n";
00282   help += "The following commandline options can be used\n";
00283   
00284   for (OptionList::const_iterator it = m_option.begin(); 
00285        it != m_option.end(); ++it)
00286   {
00287     if ((*it).shortOption.size())
00288     {
00289       help += "-";
00290       help += (*it).shortOption;
00291     }
00292     if ((*it).longOption.size())
00293     {
00294       if ((*it).shortOption.size()) help += "|";
00295       help += "--";
00296       help += (*it).longOption;
00297     }
00298     help += "\n    ";
00299     if (!(*it).hasParameter)
00300     {
00301       help += "Flag: ";
00302     }
00303     help += (*it).description;
00304     help += "\n";
00305   }
00306   
00307   help += m_helpText;
00308   
00309   return help;
00310 }

Generated on Mon Jan 22 23:24:18 2007 for cdmm by  doxygen 1.4.6