simple_file_parser.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 #include "simple_file_parser.h"
00031 using namespace std;
00032
00033 #define MYDEBUG(msg) cout << "DEBUG:" << __FILE__ << ":" << __LINE__ << ": " << msg << endl
00034
00035 simple_file_parser::simple_file_parser(const simple_file_parser& obj)
00036 {
00037 }
00038
00039 simple_file_parser& simple_file_parser::operator=(const simple_file_parser& obj)
00040 {
00041 return *this;
00042 }
00043
00044 simple_file_parser::simple_file_parser()
00045 : m_ifs(0),
00046 m_lineno(0),
00047 m_bufsz(65536),
00048 m_in_comment(false)
00049 {
00050 m_buf = new char[m_bufsz];
00051 size_t sz = sizeof(m_single_char_tokens)/sizeof(bool);
00052 for(size_t i=0;i<sz;++i)
00053 m_single_char_tokens[i] = false;
00054 }
00055
00056 simple_file_parser::~simple_file_parser()
00057 {
00058 close();
00059 delete [] m_buf;
00060 m_bufsz = 0;
00061 }
00062
00063 bool simple_file_parser::file_exists(const char* fn)
00064 {
00065 ifstream ifs(fn);
00066 if (!ifs || ifs.bad())
00067 return false;
00068 return true;
00069 }
00070
00071 bool simple_file_parser::file_exists(const string& fn) {
00072 return file_exists(fn.c_str());
00073 }
00074
00075 bool simple_file_parser::open(const string& fn)
00076 {
00077 if (!file_exists(fn))
00078 return false;
00079 close();
00080 m_ifs = new ifstream(fn.c_str());
00081 if (!*m_ifs || m_ifs->bad()) {
00082 close();
00083 return false;
00084 }
00085 m_fn = fn;
00086 return true;
00087 }
00088
00089 void simple_file_parser::close()
00090 {
00091 if (m_ifs) {
00092 m_lineno = 0;
00093 delete m_ifs;
00094 m_ifs = 0;
00095 m_tokens.clear();
00096 m_fn = "";
00097 }
00098 }
00099
00100 bool simple_file_parser::eof() const
00101 {
00102 return m_ifs ? m_ifs->eof() : true;
00103 }
00104
00105 void simple_file_parser::rewind()
00106 {
00107 if (m_ifs) {
00108 m_ifs->seekg(0);
00109 m_lineno = 0;
00110 m_tokens.clear();
00111 }
00112 }
00113
00114 void simple_file_parser::set_single_char_tokens(const char* tokens)
00115 {
00116 size_t sz = sizeof(m_single_char_tokens)/sizeof(bool);
00117 for(size_t i=0;i<sz;++i)
00118 m_single_char_tokens[i] = false;
00119 if (tokens) {
00120 for(const char* p = tokens;*p;++p) {
00121 size_t i = size_t(*p);
00122 m_single_char_tokens[i] = true;
00123 }
00124 }
00125 }
00126
00127 const char* simple_file_parser::get_single_char_tokens() const
00128 {
00129 const size_t cache_size = sizeof(m_single_char_tokens)/sizeof(bool);
00130 static char cache[cache_size];
00131 char* p = cache;
00132 for(size_t i=0;i<cache_size;++i) {
00133 if (m_single_char_tokens[i]) {
00134 char ch = char(i);
00135 *p++ = ch;
00136 }
00137 }
00138 *p = 0;
00139 return cache;
00140 }
00141
00142 char* simple_file_parser::skip_to_end_of_comment(char* p)
00143 {
00144 for(;*p;++p) {
00145 if (*p == '*' && p[1] == '/') {
00146 p++;
00147 p++;
00148 m_in_comment=false;
00149 break;
00150 }
00151 }
00152 return p;
00153 }
00154
00155 char* simple_file_parser::skip_comments(char* p)
00156 {
00157 if (!*p) {
00158 return p;
00159 }
00160
00161 if (m_in_comment) {
00162 p = skip_to_end_of_comment(p);
00163 if (m_in_comment) {
00164
00165 return p;
00166 }
00167 }
00168
00169 if (*p != '/') {
00170
00171 return p;
00172 }
00173
00174 if (p[1] == '/') {
00175
00176 for(;*p;++p);
00177 }
00178 else if (p[1] == '*') {
00179
00180
00181 p++;
00182 p++;
00183 m_in_comment=true;
00184 p = skip_to_end_of_comment(p);
00185 }
00186 return p;
00187 }
00188
00189 char* simple_file_parser::skip_whitespace(char* p)
00190 {
00191 if (!*p)
00192 return p;
00193 for(;*p!=0 && (*p<=' ' || *p>=127);++p);
00194 p = skip_comments(p);
00195 if (*p && (*p<=' ' || *p>=127)) {
00196 p = skip_whitespace(p);
00197 }
00198 return p;
00199 }
00200
00201 char* simple_file_parser::skip_to_whitespace(char* p)
00202 {
00203 for(;*p!=0 && *p>' ' && *p<127;++p);
00204 return p;
00205 }
00206
00207 char* simple_file_parser::is_continuation_line(char* line) const
00208 {
00209 char* p = line;
00210 for(;*p;++p);
00211 if ((p-line)<2) {
00212 return 0;
00213 }
00214 if (p[-2] <= ' ' && p[-1] == '\\') {
00215 return p;
00216 }
00217 return 0;
00218 }
00219
00220 void simple_file_parser::add_token(char* token)
00221 {
00222
00223 char* cur = token;
00224 char* beg = token;
00225 for(;*cur;++cur) {
00226 size_t i = size_t(*cur);
00227 if (m_single_char_tokens[i]) {
00228 char single_char_token[2] = {*cur,0};
00229 single_char_token[0] = *cur;
00230 *cur = 0;
00231
00232
00233 if (*beg)
00234 m_tokens.push_back(beg);
00235 m_tokens.push_back(single_char_token);
00236 beg = cur+1;
00237 *cur = single_char_token[0];
00238 }
00239 }
00240 if (!*cur && *beg) {
00241
00242 m_tokens.push_back(beg);
00243 }
00244 }
00245
00246 size_t simple_file_parser::get_next_line()
00247 {
00248
00249 m_buf[0] = 0;
00250 m_tokens.clear();
00251 char *p = m_buf;
00252 while (!m_ifs->eof() && m_ifs->getline(m_buf,m_bufsz)) {
00253 m_lineno++;
00254
00255
00256
00257
00258
00259 p = m_buf;
00260 char* eol = is_continuation_line(p);
00261 size_t sz = m_ifs->gcount();
00262 while (eol && !m_ifs->eof()) {
00263
00264
00265 --sz;
00266 p = eol-1;
00267 if (sz>=m_bufsz) {
00268 break;
00269 }
00270 m_ifs->getline(p,m_bufsz-sz);
00271 m_lineno++;
00272 sz += m_ifs->gcount();
00273 eol = is_continuation_line(p);
00274 }
00275 if (sz>=m_bufsz) {
00276
00277
00278
00279
00280
00281 cerr << endl
00282 << "ERROR:" << __FILE__ << ":" << __LINE__ << ": "
00283 << "Internal buffer overflow, maximum of characters per line is "
00284 << (m_bufsz-1) << ", found " << sz
00285 << " at line " << m_lineno << " in " << get_file_name()
00286 << endl;
00287 exit(1);
00288 }
00289
00290
00291
00292 p = skip_whitespace(m_buf);
00293 if (*p) {
00294 while (*p) {
00295 char* end = p;
00296 if (*end=='"') {
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 p++;
00310 for(end++;*end!=0 && *end!='"' ;++end);
00311 }
00312 else if (*p=='\'') {
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 p++;
00326 for(end++;*end!=0 && *end!='\'' ;++end);
00327 }
00328 else {
00329
00330 end = skip_to_whitespace(p);
00331 }
00332 char ec = *end;
00333 *end = 0;
00334 add_token(p);
00335 if (ec) {
00336 p = skip_whitespace(end+1);
00337 }
00338 else {
00339 *p = 0;
00340 }
00341 }
00342 break;
00343 }
00344 }
00345 return get_num_tokens();
00346 }
00347
00348 bool simple_file_parser::get_next_line(size_t num_tokens,
00349 const string& tok1,
00350 const string& tok2,
00351 const string& tok3,
00352 const string& tok4,
00353 const string& tok5,
00354 const string& tok6,
00355 const string& tok7,
00356 const string& tok8)
00357 {
00358 size_t n = get_next_line();
00359 if (num_tokens>0 && num_tokens!=n)
00360 return false;
00361 if (num_tokens>=1 && tok1!="" && tok1!=m_tokens[0])
00362 return false;
00363 if (num_tokens>=2 && tok2!="" && tok2!=m_tokens[1])
00364 return false;
00365 if (num_tokens>=3 && tok3!="" && tok3!=m_tokens[2])
00366 return false;
00367 if (num_tokens>=4 && tok4!="" && tok4!=m_tokens[3])
00368 return false;
00369 if (num_tokens>=5 && tok5!="" && tok5!=m_tokens[4])
00370 return false;
00371 if (num_tokens>=6 && tok6!="" && tok6!=m_tokens[5])
00372 return false;
00373 if (num_tokens>=7 && tok7!="" && tok7!=m_tokens[6])
00374 return false;
00375 if (num_tokens>=8 && tok8!="" && tok8!=m_tokens[7])
00376 return false;
00377 return true;
00378 }
00379
00380 bool simple_file_parser::is_token_uint(size_t i) const
00381 {
00382 const char* p = m_tokens[i].c_str();
00383 for(;*p;p++) {
00384 if (*p<'0' || *p>'9')
00385 return false;
00386 }
00387
00388 return true;
00389 }
00390
00391 bool simple_file_parser::is_token_int(size_t i) const
00392 {
00393 const char* p = m_tokens[i].c_str();
00394
00395
00396 if (*p!='-' && (*p<'0' || *p>'9'))
00397 return false;
00398
00399 for(++p;*p;p++) {
00400 if (*p<'0' || *p>'9')
00401 return false;
00402 }
00403
00404 return true;
00405 }