00001
00002 #ifdef WIN32
00003 #include <direct.h>
00004 #define popen _popen
00005 #define pclose _pclose
00006 #endif
00007
00008 #include "cmt_awk.h"
00009 #include "cmt_system.h"
00010
00011 class Parser
00012 {
00013 public:
00014 Parser (Awk* awk, const cmt_string pattern, const cmt_regexp* expression) :
00015 m_pattern (pattern), m_expression (expression), m_awk(awk)
00016 {
00017 }
00018
00025 Awk::condition parse (const cmt_string& text)
00026 {
00027 Awk::condition result = Awk::ok;
00028
00029 cmt_string line;
00030 int pos;
00031 int max_pos;
00032
00033 pos = 0;
00034 max_pos = text.size ();
00035
00036 m_accumulator.erase (0);
00037
00038 for (pos = 0; pos < max_pos;)
00039 {
00040 int eol = text.find (pos, '\n');
00041
00042 if (eol == cmt_string::npos)
00043 {
00044
00045 text.substr (pos, line);
00046 pos = max_pos;
00047 }
00048 else
00049 {
00050 int length = 1;
00051
00052 int cr = text.find (pos, "\r\n");
00053
00054 if (cr == (eol-1))
00055 {
00056 eol = cr;
00057 length = 2;
00058 }
00059
00060 if (eol == pos)
00061 {
00062
00063 line = "";
00064 pos += length;
00065 }
00066 else
00067 {
00068
00069
00070 text.substr (pos, eol - pos, line);
00071 pos = eol + length;
00072 }
00073 }
00074
00075 if (m_awk != 0) m_awk->inc_line_number ();
00076
00077
00078
00079 result = parse_line (line);
00080 if (result != Awk::ok) break;
00081 }
00082
00083 return (result);
00084 }
00085
00093 Awk::condition parse_line (const cmt_string& line)
00094 {
00095 Awk::condition result = Awk::ok;
00096 int length;
00097 cmt_string temp_line = line;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 bool finished = true;
00108
00109 length = temp_line.size ();
00110
00111 if (length == 0)
00112 {
00113
00114 finished = true;
00115 }
00116 else
00117 {
00118 int back_slash = temp_line.find_last_of ('\\');
00119
00120 if (back_slash != cmt_string::npos)
00121 {
00122
00123
00124
00125
00126
00127 bool at_end = true;
00128
00129 for (int i = (back_slash + 1); i < length; i++)
00130 {
00131 char c = temp_line[i];
00132 if ((c != ' ') && (c != '\t'))
00133 {
00134 at_end = false;
00135 break;
00136 }
00137 }
00138
00139 if (at_end)
00140 {
00141 temp_line.erase (back_slash);
00142 finished = false;
00143 }
00144 else
00145 {
00146
00147 finished = true;
00148 }
00149 }
00150
00151 m_accumulator += temp_line;
00152 }
00153
00154
00155
00156
00157 if (!finished)
00158 {
00159
00160
00161 return (Awk::ok);
00162 }
00163
00164
00165
00166 if (m_accumulator != "")
00167 {
00168 bool ok = false;
00169
00170 if (m_expression != 0)
00171 {
00172 if (m_expression->match (m_accumulator))
00173 {
00174 ok = true;
00175 }
00176 }
00177 else
00178 {
00179 if ((m_pattern == "") ||
00180 (m_accumulator.find (m_pattern) != cmt_string::npos))
00181 {
00182 ok = true;
00183 }
00184 }
00185
00186 if (ok && (m_awk != 0))
00187 {
00188
00189
00190 m_awk->filter (m_accumulator);
00191 result = m_awk->get_last_condition ();
00192 }
00193
00194 m_accumulator.erase (0);
00195 }
00196
00197 return (result);
00198 }
00199
00200 private:
00201
00202 cmt_string m_accumulator;
00203 cmt_string m_pattern;
00204 const cmt_regexp* m_expression;
00205 Awk* m_awk;
00206 };
00207
00208
00209 Awk::Awk ()
00210 {
00211 m_condition = ok;
00212 }
00213
00214
00215 Awk::~Awk ()
00216 {
00217 }
00218
00219
00220 Awk::condition Awk::run (const cmt_string& text,
00221 const cmt_string& pattern)
00222 {
00223 m_line_number = 0;
00224 m_condition = ok;
00225
00226 begin ();
00227 if (m_condition != ok) return (m_condition);
00228
00229 if (CmtSystem::testenv ("CMTTESTAWK"))
00230 {
00231 Parser p (this, pattern, 0);
00232
00233 m_condition = p.parse (text);
00234 if (m_condition != ok) return (m_condition);
00235 }
00236 else
00237 {
00238 cmt_string line;
00239 int pos = 0;
00240 int max_pos;
00241
00242 max_pos = text.size ();
00243
00244 for (pos = 0; pos < max_pos;)
00245 {
00246 int cr = text.find (pos, "\r\n");
00247 int nl = text.find (pos, '\n');
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 int first = nl;
00263
00264 if (cr != cmt_string::npos)
00265 {
00266
00267
00268 if (nl == cmt_string::npos)
00269 {
00270
00271 first = cr;
00272 }
00273 else
00274 {
00275
00276 first = (nl < cr) ? nl : cr;
00277 }
00278 }
00279
00280 if (first == cmt_string::npos)
00281 {
00282
00283 text.substr (pos, line);
00284 pos = max_pos;
00285 }
00286 else if (first > pos)
00287 {
00288
00289
00290 text.substr (pos, first - pos, line);
00291 pos = first + 1;
00292 }
00293 else
00294 {
00295
00296 line = "";
00297 pos++;
00298 }
00299
00300 m_line_number++;
00301
00302 if (line != "")
00303 {
00304 if ((pattern == "") ||
00305 (line.find (pattern) != cmt_string::npos))
00306 {
00307 filter (line);
00308 if (m_condition != ok) return (m_condition);
00309 }
00310 }
00311 }
00312 }
00313
00314 end ();
00315
00316 return (m_condition);
00317 }
00318
00319
00320 Awk::condition Awk::run (const cmt_string& text,
00321 const cmt_regexp& expression)
00322 {
00323 m_line_number = 0;
00324 m_condition = ok;
00325
00326 begin ();
00327 if (m_condition != ok) return (m_condition);
00328
00329 Parser p (this, "", &expression);
00330
00331 m_condition = p.parse (text);
00332 if (m_condition != ok) return (m_condition);
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 end ();
00402
00403 return (m_condition);
00404 }
00405
00406
00407 void Awk::stop ()
00408 {
00409 m_condition = stopped;
00410 }
00411
00412
00413 void Awk::abort ()
00414 {
00415 m_condition = failed;
00416 }
00417
00418
00419 void Awk::allow_continuation ()
00420 {
00421 m_continuation_allowed = true;
00422 }
00423
00424
00425 Awk::condition Awk::get_last_condition () const
00426 {
00427 return (m_condition);
00428 }
00429
00430
00431 void Awk::begin ()
00432 {
00433 }
00434
00435
00436 void Awk::filter (const cmt_string& )
00437 {
00438
00439 }
00440
00441
00442 void Awk::end ()
00443 {
00444 }
00445
00446
00447 void Awk::inc_line_number ()
00448 {
00449 m_line_number++;
00450 }
00451
00452
00453 Awk::condition FAwk::run (const cmt_string& file_name,
00454 const cmt_string& pattern)
00455 {
00456 if (!CmtSystem::test_file (file_name)) return (failed);
00457
00458 CmtSystem::basename (file_name, m_file_name);
00459 CmtSystem::dirname (file_name, m_dir_name);
00460
00461 cmt_string text;
00462
00463 text.read (file_name);
00464
00465 return (Awk::run (text, pattern));
00466 }
00467
00468
00469 Awk::condition FAwk::run (const cmt_string& file_name,
00470 const cmt_regexp& expression)
00471 {
00472 if (!CmtSystem::test_file (file_name)) return (failed);
00473
00474 CmtSystem::basename (file_name, m_file_name);
00475 CmtSystem::dirname (file_name, m_dir_name);
00476
00477 cmt_string text;
00478
00479 text.read (file_name);
00480
00481 return (Awk::run (text, expression));
00482 }
00483
00484
00485 Awk::condition PAwk::run (const cmt_string& command,
00486 const cmt_string& pattern)
00487 {
00488 cmt_string line;
00489
00490 m_line_number = 0;
00491 m_condition = ok;
00492
00493 begin ();
00494 if (m_condition != ok) return (m_condition);
00495
00496 FILE* f = popen (command.c_str (), "r");
00497
00498 if (f == 0) return (failed);
00499
00500 char buffer[8192];
00501 char* ptr;
00502
00503 while ((ptr = fgets (buffer, sizeof (buffer), f)) != NULL)
00504 {
00505 line = ptr;
00506
00507 if (line.find ("\n") == cmt_string::npos)
00508 {
00509 cerr << "#CMT> Warning : Line too long and truncated in PAwk::run for command " << command << endl;
00510 }
00511
00512 line.replace ("\n", "");
00513
00514 m_line_number++;
00515
00516 if (line != "")
00517 {
00518 if ((pattern == "") ||
00519 (line.find (pattern) != cmt_string::npos))
00520 {
00521 filter (line);
00522 if (m_condition != ok) return (m_condition);
00523 }
00524 }
00525 }
00526
00527 pclose (f);
00528
00529 end ();
00530
00531 return (m_condition);
00532 }
00533
00534
00535 Awk::condition PAwk::run (const cmt_string& command,
00536 const cmt_regexp& expression)
00537 {
00538 cmt_string line;
00539
00540 m_line_number = 0;
00541 m_condition = ok;
00542
00543 begin ();
00544 if (m_condition != ok) return (m_condition);
00545
00546 FILE* f = popen (command.c_str (), "r");
00547
00548 if (f == 0) return (failed);
00549
00550 char buffer[256];
00551 char* ptr;
00552
00553 while ((ptr = fgets (buffer, sizeof (buffer), f)) != NULL)
00554 {
00555 line = ptr;
00556
00557 line.replace ("\n", "");
00558
00559 m_line_number++;
00560
00561 if (line != "")
00562 {
00563 if (expression.match (line))
00564 {
00565 filter (line);
00566 if (m_condition != ok) return (m_condition);
00567 }
00568 }
00569 }
00570
00571 pclose (f);
00572
00573 end ();
00574
00575 return (m_condition);
00576 }
00577