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