Homepage Demos Overview Downloads Tutorials Reference
Credits

config.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003-2004  Etienne Lachance
00003 
00004 This library is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as
00006 published by the Free Software Foundation; either version 2.1 of the
00007 License, or (at your option) any later version.
00008 
00009 This library is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public
00015 License along with this library; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 Report problems and direct all questions to:
00020 
00021 email: etienne.lachance@polytml.ca or richard.gourdeau@polymtl.ca
00022 
00023 -------------------------------------------------------------------------------
00024 Revision_history:
00025 
00026 2004/06/10: Etienne Lachance
00027     -Added doxygen documentation.
00028 
00029 2004/07/01: Ethan Tira-Thompson
00030     -Added support for newmat's use_namespace #define, using ROBOOP namespace
00031 
00032 2004/07/13: Ethan Tira-Thompson
00033     -Added a select_real and add_real function for type indepence of Real
00034     -Added functions to test for sections and parameters existance
00035 
00036 2004/07/23: Ethan Tira-Thompson
00037     -Fixed potentially uninitialized variables and some other warnings
00038 
00039 2004/09/01: Ethan Tira-Thompson
00040     -Added optional parameter to constructor so you can automatically read_conf
00041     -select_* functions are now const
00042 -------------------------------------------------------------------------------
00043 */
00044 
00045 /*! 
00046   @file config.cpp
00047   @brief Configuration class functions.
00048 */
00049 
00050 //! @brief RCS/CVS version.
00051 static const char rcsid[] = "$Id: config.cpp,v 1.9 2004/09/01 19:51:04 ejt Exp $";
00052 
00053 
00054 #include "config.h"
00055 
00056 #ifdef use_namespace
00057 namespace ROBOOP {
00058   using namespace NEWMAT;
00059 #endif
00060 
00061 Config::Config(const string & filename_, bool doRead/*=false*/)
00062 //! @brief Constructor.
00063   : conf(), filename(filename_)
00064 {
00065    if(doRead)
00066       read_conf();
00067 }
00068 
00069 Config::Config(const Config & x)
00070 //! @brief Constructor.
00071   : conf(x.conf), filename(x.filename)
00072 {
00073 }
00074 
00075 Config & Config::operator=(const Config & x)
00076 //! @brief Overload = operator.
00077 {
00078    conf = x.conf;
00079    filename = x.filename;
00080    return *this;
00081 }
00082 
00083 short Config::read_conf()
00084 /*!
00085   @brief Read a configuration file.
00086 
00087   This function reads the configuration file specified in 
00088   the constructor parameter. The information is stored in the
00089   variable conf.
00090 
00091   A configuration file contains section(s) (between [ ]), and the 
00092   section(s) contains parameter(s) with there respective value(s). 
00093   The section and the parameter are always access via a string. Below 
00094   is an exemple: one section named PUMA560_mDH, and two parameters.
00095 
00096   [PUMA560_mDH]
00097   DH:         0
00098   dof:        6
00099 */
00100 {
00101    const char *ptr_filename = filename.c_str(); //transform string to *char
00102 
00103    std::ifstream inconffile(ptr_filename, std::ios::in);
00104 
00105    if(inconffile)
00106    {
00107       string temp;
00108       int tmpPos;
00109       Data data;
00110 #ifdef __WATCOMC__
00111       char tempo[256], tempo2[256];
00112       string section, parameter, value;
00113       inconffile.getline(tempo,sizeof(tempo));
00114       temp = tempo;
00115 #else
00116       getline(inconffile, temp);
00117 #endif
00118 
00119       while( !inconffile.eof() )
00120       {
00121    // Is-it comment line?
00122          if(temp.substr(0,1) != "#")
00123          {
00124       // Is-it a section name?
00125             if(temp.substr(0,1) == "[") // [section]
00126             {
00127          // Search for the end of the section name and ignore the rest of the line.
00128          tmpPos = temp.find("]");
00129          if (tmpPos != (int)string::npos)
00130      {
00131        data.section = temp.substr(1, tmpPos-1); // remove []
00132        // Read the next line, it's should be a parameter.
00133 #ifdef __WATCOMC__
00134        inconffile.getline(tempo,sizeof(tempo));
00135        temp = tempo;
00136 #else
00137        getline(inconffile, temp);
00138 #endif
00139        // Be sure that is not another section name.
00140        while( (temp.substr(0,1) != "[") &&
00141         (!inconffile.eof()) )
00142          {
00143            if(temp.substr(0,1) != "#") // ignore comments
00144        {
00145          if(temp.find(":") != string::npos)
00146            {
00147 #ifdef __WATCOMC__
00148              istrstream inputString(tempo);
00149              inputString >> tempo2;
00150              data.parameter = tempo2;
00151              inputString >> tempo2;
00152              data.value = tempo2;
00153 #else
00154              istringstream inputString(temp);
00155              inputString >> data.parameter >> data.value;
00156 #endif
00157              // Find ":" in parameter.
00158              tmpPos = data.parameter.find(":");
00159              if (tmpPos != (int)string::npos)
00160          // remove ":" a the end of parameter
00161          data.parameter = data.parameter.substr(0, tmpPos);
00162              else
00163          {
00164 #ifdef __WATCOMC__
00165            inputString >> tempo2;
00166            data.value = tempo2;
00167 #else
00168            inputString >> data.value;
00169 #endif
00170          }
00171 
00172              // Add data to the config vector
00173              conf.push_back(data);
00174            }
00175 
00176          // Read the next line.
00177 #ifdef __WATCOMC__
00178          inconffile.getline(tempo,sizeof(tempo));
00179          temp = tempo;
00180 #else
00181          getline(inconffile, temp);
00182 #endif
00183        }
00184            else
00185        {
00186          // Ignore comments and read the next line.
00187 #ifdef __WATCOMC__
00188          inconffile.getline(tempo,sizeof(tempo));
00189          temp = tempo;
00190 #else
00191          getline(inconffile, temp);
00192 #endif
00193        }
00194          }
00195      }
00196             }
00197          }
00198          if(temp.substr(0,1) != "[") {
00199 #ifdef __WATCOMC__
00200             inconffile.getline(tempo,sizeof(tempo));
00201             temp = tempo;
00202 #else
00203             getline(inconffile, temp);
00204 #endif
00205          }
00206       }
00207    }
00208    else
00209    {
00210       cerr << "Config::read_conf: can not open file " << filename.c_str() << endl;
00211       return CAN_NOT_OPEN_FILE;
00212    }
00213    return 0;
00214 }
00215 
00216 void Config::print()
00217 //! @brief Print the configuration data.
00218 {
00219   string tmpSection;
00220   for(Conf_data::iterator iter = conf.begin(); iter != conf.end(); ++iter)
00221     {
00222       if (tmpSection != iter->section)
00223   {
00224     //Beginning of a section
00225     tmpSection = iter->section;
00226     cout << "\n[" << tmpSection << "]" << endl;
00227   }
00228       else
00229     cout << setw(15-iter->parameter.size()) << iter->parameter+":" << " " 
00230          << iter->value << endl;
00231     }
00232 }
00233 
00234 bool Config::section_exists(const string& section) const
00235 /*!
00236   @brief Test to see if a section exists
00237   @return true if @a section is found
00238 */
00239 {
00240   for(Conf_data::const_iterator iter = conf.begin(); iter != conf.end(); ++iter)
00241     if(iter->section == section)
00242       return true;
00243   return false;
00244 }
00245 
00246 bool Config::parameter_exists(const string& section, const string& parameter) const
00247 /*!
00248   @brief Test to see if a parameter exists within a section
00249   @return true if @a parameter is found within @a section
00250 */
00251 {
00252   for(Conf_data::const_iterator iter = conf.begin(); iter != conf.end(); ++iter)
00253     if( (iter->section == section) && (iter->parameter == parameter) )
00254       return true;
00255   return false;
00256 }
00257 
00258 short Config::select_string(const string section, const string parameter, string & value) const
00259 /*!
00260   @brief Get a parameter data, of a certain section, into the string value.
00261   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00262 */
00263 {
00264    for(Conf_data::const_iterator iter = conf.begin(); iter != conf.end(); ++iter)
00265    {
00266       if( (iter->section == section) && (iter->parameter == parameter) )
00267       {
00268          value = iter->value;
00269          return 0;
00270       }
00271    }
00272    value = "";
00273    cerr << "Config::select_string: section " << section.c_str() << " or parameter "
00274    << parameter.c_str() << " does not exist." << endl;
00275    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00276 }
00277 
00278 short Config::select_bool(const string section, const string parameter, bool & value) const
00279 /*!
00280   @brief Get a parameter data, of a certain section, into the bool value.
00281   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00282 */
00283 {
00284    string value_string;
00285    if(!select_string(section, parameter, value_string))
00286    {
00287 #ifdef __WATCOMC__
00288       char temp[256];
00289       strcpy(temp,value_string.c_str());
00290       istrstream istr(temp);
00291       value = istr;
00292 #else
00293       istringstream istr(value_string);
00294       istr >> value;
00295 #endif
00296       return 0;
00297    }
00298    cerr << "Config::select_bool: section " << section.c_str() << " or parameter "
00299    << parameter.c_str() << " does not exist" << endl;
00300    value = false;
00301    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00302 }
00303 
00304 short Config::select_int(const string section, const string parameter, int & value) const
00305 /*!
00306   @brief Get a parameter data, of a certain section, into the int value.
00307   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00308 */
00309 {
00310    string value_string;
00311    if(!select_string(section, parameter, value_string))
00312    {
00313 #ifdef __WATCOMC__
00314       char temp[256];
00315       strcpy(temp,value_string.c_str());
00316       istrstream istr(temp);
00317       istr >> value;
00318 #else
00319       istringstream istr(value_string);
00320       istr >> value;
00321 #endif
00322       return 0;
00323    }
00324    cerr << "Config::select_int: section " << section.c_str() << " or parameter "
00325    << parameter.c_str() << " does not exist" << endl;
00326    value = 0;
00327    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00328 }
00329 
00330 short Config::select_short(const string section, const string parameter, short & value) const
00331 /*!
00332   @brief Get a parameter data, of a certain section, into the short value.
00333   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00334 */
00335 {
00336    string value_string;
00337    if(!select_string(section, parameter, value_string))
00338    {
00339 #ifdef __WATCOMC__
00340       char temp[256];
00341       strcpy(temp,value_string.c_str());
00342       istrstream istr(temp);
00343       istr >> value;
00344 #else
00345       istringstream istr(value_string);
00346       istr >> value;
00347 #endif
00348       return 0;
00349    }
00350    cerr << "Config::select_short: section " << section.c_str() << " or parameter "
00351    << parameter.c_str() << " does not exist" << endl;
00352    value = 0;
00353    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00354 }
00355 
00356 short Config::select_float(const string section, const string parameter, float & value) const
00357 /*!
00358   @brief Get a parameter data, of a certain section, into the float value.
00359   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00360 */
00361 {
00362    string value_string;
00363    if(!select_string(section, parameter, value_string))
00364    {
00365 #ifdef __WATCOMC__
00366       char temp[256];
00367       strcpy(temp,value_string.c_str());
00368       istrstream istr(temp);
00369       istr >> value;
00370 #else
00371       istringstream istr(value_string);
00372       istr >> value;
00373 #endif
00374       return 0;
00375    }
00376    cerr << "Config::select_float: section " << section.c_str() << " or parameter "
00377    << parameter.c_str() << " does not exist" << endl;
00378    value = 0.0;
00379    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00380 }
00381 
00382 short Config::select_double(const string section, const string parameter, double & value) const
00383 /*!
00384   @brief Get a parameter data, of a certain section, into the double value.
00385   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00386 */
00387 {
00388    string value_string;
00389    if(!select_string(section, parameter, value_string))
00390    {
00391 #ifdef __WATCOMC__
00392       char temp[256];
00393       strcpy(temp,value_string.c_str());
00394       istrstream istr(temp);
00395       istr >> value;
00396 #else
00397       istringstream istr(value_string);
00398       istr >> value;
00399 #endif
00400       return 0;
00401    }
00402    cerr << "Config::select_double: section " << section.c_str() << " or parameter "
00403    << parameter.c_str() << " does not exist" << endl;
00404    value = 0.0;
00405    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00406 }
00407 
00408 short Config::select_real(const string section, const string parameter, Real & value) const
00409 /*!
00410   @brief Get a parameter data, of a certain section, into the Real value.
00411   @return 0 or SECTION_OR_PARAMETER_DOES_NOT_EXIST if the data can not be found.
00412 */
00413 {
00414    string value_string;
00415    if(!select_string(section, parameter, value_string))
00416    {
00417 #ifdef __WATCOMC__
00418       char temp[256];
00419       strcpy(temp,value_string.c_str());
00420       istrstream istr(temp);
00421       istr >> value;
00422 #else
00423       istringstream istr(value_string);
00424       istr >> value;
00425 #endif
00426       return 0;
00427    }
00428    cerr << "Config::select_real: section " << section.c_str() << " or parameter "
00429    << parameter.c_str() << " does not exist" << endl;
00430    value = 0.0;
00431    return SECTION_OR_PARAMETER_DOES_NOT_EXIST;
00432 }
00433 
00434 short Config::write_conf(const string name, const string file_title,
00435                          const int space_between_column)
00436 /*!
00437   @brief Write the configuration information, contained in conf, on disk.
00438   @param name: Configuration file name.
00439   @param file_title: Title in the configuration file header.
00440   @param space_between_column: Number of blanks between : (of a parameter) and it's value.
00441 */
00442 {
00443    const char *ptr_filename = name.c_str(); //transform string to *char
00444    std::ofstream outconffile(ptr_filename, std::ios::out);
00445 
00446    if(outconffile)
00447    {                     // file header
00448       outconffile << "# ---------------------------------------------------" << endl;
00449       outconffile << "# " << file_title << endl;
00450       outconffile << "# ---------------------------------------------------" << endl;
00451       outconffile << endl;
00452 
00453       string section = "";
00454 
00455       for(Conf_data::iterator iterConf = conf.begin(); iterConf != conf.end(); ++iterConf)
00456       {
00457          if(section != iterConf->section)
00458          {
00459             section = iterConf->section;
00460             outconffile << "\n[" << section << "]\n" << endl;
00461          }
00462    outconffile << setw(space_between_column-iterConf->parameter.size()) 
00463          << iterConf->parameter + ":" << " " << iterConf->value << endl;
00464       }
00465       return 0;
00466    }
00467    else
00468    {
00469       cerr << "Config::write_conf: can not create file " << name.c_str() << endl;
00470       return CAN_NOT_CREATE_FILE;
00471    }
00472 }
00473 
00474 void Config::add_string(const string section, const string parameter, const string value)
00475 /*!
00476   @brief Added the value(string) of the parameter in the section in the configuration data.
00477 
00478   The functions will added the parameter and the section if it does not already exist.
00479 */
00480 {
00481    Data dataSet;
00482    dataSet.section = section;
00483    dataSet.parameter = parameter;
00484    dataSet.value = value;
00485    for(Conf_data::iterator iterConf = conf.begin(); iterConf != conf.end(); ++iterConf)
00486    {
00487       if(section == iterConf->section) // section already exist
00488       {
00489          if(parameter == iterConf->parameter) // parameter already exist
00490          {
00491             iterConf->value = value;
00492             return;
00493          }
00494          // parameter does not exist
00495          for(Conf_data::iterator iterConf2 = iterConf; iterConf2 != conf.end(); ++iterConf2)
00496          {
00497             if(section != iterConf2->section)
00498             {
00499                conf.insert(iterConf2, dataSet);
00500                return;
00501             }
00502          }
00503       }
00504    }
00505    // section and parameter does not exist.
00506    conf.push_back(dataSet);
00507 }
00508 
00509 void Config::add_bool(const string section, const string parameter,
00510                       const bool value)
00511 /*!
00512   @brief Added the value (bool) of the parameter in the section in the configuration data.
00513 
00514   The functions use add_string by first converting the value (bool) in value (string) 
00515 */
00516 {
00517    string value_tmp;
00518 #ifdef __WATCOMC__
00519    ostrstream ostr;
00520 #else
00521    ostringstream ostr;
00522 #endif
00523    ostr << value;
00524    value_tmp = ostr.str();
00525 
00526    add_string(section, parameter, value_tmp);
00527 }
00528 
00529 void Config::add_int(const string section, const string parameter,
00530                      const int value)
00531 /*!
00532   @brief Added the value (int) of the parameter in the section in the configuration data.
00533 
00534   The functions use add_string by first converting the value (int) in value (string) 
00535 */
00536 {
00537    string value_tmp;
00538 #ifdef __WATCOMC__
00539    ostrstream ostr;
00540 #else
00541    ostringstream ostr;
00542 #endif
00543    ostr << value;
00544    value_tmp = ostr.str();
00545 
00546    add_string(section, parameter, value_tmp);
00547 }
00548 
00549 void Config::add_float(const string section, const string parameter,
00550            const float value)
00551 /*!
00552   @brief Added the value (float) of the parameter in the section in the configuration data.
00553 
00554   The functions use add_string by first converting the value (float) in value (string) 
00555 */
00556 {
00557    string value_tmp;
00558 #ifdef __WATCOMC__
00559    ostrstream ostr;
00560 #else
00561    ostringstream ostr;
00562 #endif
00563 #ifdef _MSC_VER  
00564    ostr << value; // need to be fixed !
00565 #else
00566    ostr << setprecision(13) << value;
00567 #endif
00568    value_tmp = ostr.str();
00569 
00570    add_string(section, parameter, value_tmp);
00571 }
00572 
00573 void Config::add_double(const string section, const string parameter,
00574                         const double value)
00575 /*!
00576   @brief Added the value (double) of the parameter in the section in the configuration data.
00577 
00578   The functions use add_string by first converting the value (double) in value (string) 
00579 */
00580 {
00581    string value_tmp;
00582 #ifdef __WATCOMC__
00583    ostrstream ostr;
00584 #else
00585    ostringstream ostr;
00586 #endif
00587 #ifdef _MSC_VER  
00588    ostr << value; // need to be fixed !
00589 #else
00590    ostr << setprecision(13) << value;
00591 #endif
00592    value_tmp = ostr.str();
00593 
00594    add_string(section, parameter, value_tmp);
00595 }
00596 
00597 void Config::add_real(const string section, const string parameter,
00598                         const Real value)
00599 /*!
00600   @brief Added the value (Real) of the parameter in the section in the configuration data.
00601 
00602   The functions use add_string by first converting the value (Real) in value (string) 
00603 */
00604 {
00605    string value_tmp;
00606 #ifdef __WATCOMC__
00607    ostrstream ostr;
00608 #else
00609    ostringstream ostr;
00610 #endif
00611 #ifdef _MSC_VER  
00612    ostr << value; // need to be fixed !
00613 #else
00614    ostr << setprecision(13) << value;
00615 #endif
00616    value_tmp = ostr.str();
00617 
00618    add_string(section, parameter, value_tmp);
00619 }
00620 
00621 
00622 #ifdef use_namespace
00623 }
00624 #endif
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 

ROBOOP v1.21a
Generated Tue Jan 4 15:42:24 2005 by Doxygen 1.4.0