openModeller
Version 1.4.0
|
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 }