Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cmt_awk.cxx

Go to the documentation of this file.
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                   // Last line, since there is no eol at all
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                       // this is an empty line
00063                     line = "";
00064                     pos += length;
00065                   }
00066                 else
00067                   {
00068                       // The eol was found beyond the current position
00069                       // (ie. this is a non empty line)
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               //cout << "parse> line=[" << line << "]" << endl;
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           // We scan the line for handling backslashes.
00101           //
00102           // Really terminating backslashes (ie those only followed by spaces/tabs
00103           // mean continued line
00104           //
00105           //
00106 
00107         bool finished = true;
00108 
00109         length = temp_line.size ();
00110 
00111         if (length == 0)
00112           {
00113               // An empty line following a backslash terminates the continuation.
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               // This is the last backslash
00124               // check if there are only space chars after it
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                       // This was not a trailing backslash.
00147                     finished = true;
00148                   }
00149               }
00150         
00151             m_accumulator += temp_line;
00152           }
00153 
00154           //cout << "parse_line1> accumulator=[" << m_accumulator << "]" << endl;
00155           //cout << "parse_line1> finished=[" << finished << "]" << endl;
00156 
00157         if (!finished)
00158           {
00159               // We still need to accumulate forthcoming lines
00160               // before parsing the resulting text.
00161             return (Awk::ok);
00162           }
00163 
00164           // now filter the complete accumulated line (if non empty)
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                   //cout << "parse_line> accumulator=[" << m_accumulator << "]" << endl;
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             // Get the first end-of-line (either lf or cr-lf)
00250 
00251             //--------------------
00252             //
00253             //     cr    1    0
00254             //   nl
00255             //
00256             //    1      a    b
00257             //
00258             //    0      c    d
00259             //
00260             //--------------------
00261           
00262           int first = nl;
00263           
00264           if (cr != cmt_string::npos)
00265             {
00266                 // cases a or c
00267 
00268               if (nl == cmt_string::npos)
00269                 {
00270                     // case a
00271                   first = cr;
00272                 }
00273               else
00274                 {
00275                     // case c
00276                   first = (nl < cr) ? nl : cr;
00277                 }
00278             }
00279           
00280           if (first == cmt_string::npos)
00281             {
00282                 // This is likely the last line since there is no end-of-line
00283               text.substr (pos, line);
00284               pos = max_pos;
00285             }
00286           else if (first > pos)
00287             {
00288                 // The eol was found beyond the current position
00289                 // (ie. this is a non empty line)
00290               text.substr (pos, first - pos, line);
00291               pos = first + 1;
00292             }
00293           else
00294             {
00295                 // an empty line
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   if (CmtSystem::testenv ("CMTTESTAWK"))
00336     {
00337     }
00338   else
00339     {
00340       cmt_string line;
00341       int pos = 0;
00342       int max_pos;
00343 
00344       max_pos = text.size ();
00345 
00346       for (pos = 0; pos < max_pos;)
00347         {
00348           int cr = text.find (pos, "\r\n");
00349           int nl = text.find (pos, '\n');
00350           
00351             // Get the first end-of-line (either lf or cr-lf)
00352           
00353           int first = nl;
00354           
00355           if (cr != cmt_string::npos)
00356             {
00357               if (nl == cmt_string::npos)
00358                 {
00359                   first = cr;
00360                 }
00361               else
00362                 {
00363                   first = (nl < cr) ? nl : cr;
00364                 }
00365             }
00366           
00367           if (first == cmt_string::npos)
00368             {
00369                 // This is likely the last line since there is no end-of-line
00370               text.substr (pos, line);
00371               pos = max_pos;
00372             }
00373           else if (first > pos)
00374             {
00375                 // The eol was found beyond the current position
00376                 // (ie. this is a non empty line)
00377               text.substr (pos, first - pos, line);
00378               pos = first + 1;
00379             }
00380           else
00381             {
00382                 // an empty line
00383               line = "";
00384               pos++;
00385             }
00386           
00387           m_line_number++;
00388           
00389           if (line != "")
00390             {
00391               if (expression.match (line))
00392                 {
00393                   filter (line);
00394                   if (m_condition != ok) return (m_condition);
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& /*line*/)
00437 {
00438     //cout << "awk> " << line << endl;
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 

Generated at Mon Jun 10 17:57:45 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000