openModeller  Version 1.4.0
my_file_parser.cpp
Go to the documentation of this file.
00001 
00027 #include <file_parser.hh>
00028 #include <string.h>
00029 #include <stdio.h>
00030 
00031 #if 0
00032 // Need an ostream inserter for the special icstring type.
00033 inline std::ostream& operator<<( std::ostream& strm, const FileParser::icstring& s )
00034 {
00035   return strm << std::string(s.data(),s.length() );
00036 }
00037 #endif
00038 
00039 /****************************************************************/
00040 /**************************** File Parser ***********************/
00041 
00042 static char error[256];
00043 
00044 /******************/
00045 /*** constructor ***/
00046 
00047 FileParser::FileParser( std::string const file )
00048 {
00049   if ( ! load( file ) )
00050     {
00051       sprintf( error, "File '%s' was not found.\n", file.c_str() );
00052       fprintf( stderr, "%s", error );
00053       throw error;
00054     }
00055 }
00056 
00057 
00058 /******************/
00059 /*** destructor ***/
00060 
00061 FileParser::~FileParser()
00062 {
00063 }
00064 
00065 /************/
00066 /*** load ***/
00067 int
00068 FileParser::load( std::string const file )
00069 {
00070   FILE *fd = fopen( file.c_str(), "r" );
00071   if ( ! fd )
00072     return 0;
00073 
00074   f_lst.clear();
00075   f_seclst.clear();
00076 
00077   char *sec = NULL;
00078   SectionList::iterator secit;
00079 
00080   const int size = 1024;
00081   char line[size];
00082 
00083   while ( fgets( line, size, fd ) ) {
00084     // Find the first # which indicates the start of comment.
00085     char *sep = strchr( line,'#' );
00086     // If it's at the beginning of the line
00087     // loop.
00088     if ( sep == line )
00089       continue;
00090 
00091     // If it's not at the beginning of the line,
00092     // assign it to "null", terminating the string,
00093     // and effectively commenting to end of line.
00094     if ( sep )
00095       *sep = '\0';
00096 
00097     // Find the start of the key.
00098     // Trim the whitespace from the front of the line.
00099     char *start_key = line;
00100     while ( isspace( *start_key ) && (*start_key != '\0') ) {
00101       start_key++;
00102     }
00103 
00104     // Nothing but whitespace.  Loop.
00105     if ( *start_key == '\0' )
00106       continue;
00107 
00108     // Are we inside a section [section_name]?
00109     char *sec_ini = strchr( line, '[' );
00110     char *sec_end = strchr( line, ']' );
00111     if ( sec_ini && sec_end ) {
00112 
00113       sec = sec_ini+1;
00114       // Left trim the whitespace.
00115       while ( isspace( *sec ) && ( *sec != '\0' ) ) {
00116   sec++;
00117       }
00118       // Right trim the value.
00119       char *tmp = sec + strlen( sec ) - 1;
00120       while ( isspace( *tmp ) || ( *tmp != ']' ) )
00121   *tmp-- = '\0';
00122       ItemList lst;
00123       f_seclst.push_back( std::make_pair( sec, lst ) );
00124       secit = f_seclst.end() -1;
00125       continue;
00126     }
00127 
00128     // Separate key and value
00129     sep = strchr( line, '=' );
00130     if ( sep ) {
00131       // Find the start of the value.
00132       char *start_val = sep+1;
00133       // Left trim the whitespace.
00134       while ( isspace( *start_val ) && ( *start_val != '\0' ) ) {
00135   start_val++;
00136       }
00137       // No value?  loop.
00138       if ( *start_val == '\0' )
00139   continue;
00140 
00141       // Null terminate the key.
00142       *sep-- = '\0';
00143       // and right trim it.
00144       while( isspace( *sep ) )
00145   *sep-- = '\0';
00146 
00147       // Right trim the value.
00148       sep = start_val + strlen( start_val ) - 1;
00149       // Remember the \0 we substitued for the '='?
00150       // use that to terminate the loop.
00151       while ( isspace( *sep ) && ( *sep != '\0' ) )
00152   *sep-- = '\0';
00153       
00154       if ( *sep == '\0' )
00155   continue;
00156       
00157       if ( sec != NULL ) {
00158 
00159         (*secit).second.push_back( std::make_pair( start_key, start_val ) );
00160       }
00161       else {
00162 
00163         f_lst.push_back( std::make_pair( start_key, start_val ) );
00164       }
00165     }
00166   }
00167   
00168   fclose( fd );
00169   return 1;
00170 }
00171 
00172 
00173 /************/
00174 /*** _get ***/
00175 std::string
00176 FileParser::_get( std::string const key, ItemList lst ) const
00177 {
00178   ItemList::const_iterator it = lst.begin();
00179 
00180   while ( it != lst.end() ) {
00181 
00182     if ( it->first == key.c_str() ) {
00183 
00184       return it->second;
00185     }
00186 
00187     ++it;
00188   }
00189 
00190   return "";
00191 }
00192 
00193 
00194 /***********/
00195 /*** get ***/
00196 std::string
00197 FileParser::get( std::string const key ) const
00198 {
00199   return _get( key, f_lst );
00200 }
00201 
00202 
00203 /***********/
00204 /*** get ***/
00205 std::string
00206 FileParser::get( std::string const section, std::string const key ) const
00207 {
00208   SectionList::const_iterator it = f_seclst.begin();
00209 
00210   while ( it != f_seclst.end() ) {
00211 
00212     if ( it->first == section.c_str() ) {
00213 
00214       return _get( key, it->second );
00215     }
00216 
00217     ++it;
00218   }
00219 
00220   return "";
00221 }
00222 
00223 
00224 /**************/
00225 /*** _count ***/
00226 int 
00227 FileParser::_count( std::string const key, ItemList lst ) const
00228 {
00229   int n = 0;
00230 
00231   ItemList::const_iterator it = lst.begin();
00232 
00233   while ( it != lst.end() ) {
00234 
00235     if ( it->first == key.c_str() ) {
00236 
00237       ++n;
00238     }
00239 
00240     ++it;
00241   }
00242 
00243   return n;
00244 }
00245 
00246 
00247 /*************/
00248 /*** count ***/
00249 int
00250 FileParser::count( std::string const key ) const
00251 {
00252   return _count( key, f_lst );
00253 }
00254 
00255 
00256 /*************/
00257 /*** count ***/
00258 int
00259 FileParser::count( std::string const section, std::string const key ) const
00260 {
00261   SectionList::const_iterator it = f_seclst.begin();
00262 
00263   while ( it != f_seclst.end() ) {
00264 
00265     if (  it->first == section.c_str() ) {
00266 
00267       return _count( key, it->second );
00268     }
00269 
00270     ++it;
00271   }
00272 
00273   return 0;
00274 }
00275 
00276 
00277 /****************/
00278 /*** _get All ***/
00279 std::vector<std::string>
00280 FileParser::_getAll( std::string const key, ItemList lst ) const
00281 {
00282   std::vector<std::string> values;
00283   ItemList::const_iterator it = lst.begin();
00284 
00285   while ( it != lst.end() ) {
00286 
00287     if ( it->first == key.c_str() ) {
00288 
00289       values.push_back( it->second );
00290     }
00291 
00292     ++it;
00293   }
00294   return values;
00295 }
00296 
00297 
00298 /***************/
00299 /*** get All ***/
00300 std::vector<std::string>
00301 FileParser::getAll( std::string const key ) const
00302 {
00303   return _getAll( key, f_lst );
00304 }
00305 
00306 
00307 /***************/
00308 /*** get All ***/
00309 std::vector<std::string>
00310 FileParser::getAll( std::string const section, std::string const key ) const
00311 {
00312   SectionList::const_iterator it = f_seclst.begin();
00313 
00314   while ( it != f_seclst.end() ) {
00315 
00316     if (  it->first == section.c_str() ) {
00317 
00318       return _getAll( key, it->second );
00319     }
00320 
00321     ++it;
00322   }
00323 
00324   std::vector<std::string> values;
00325   return values;
00326 }