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 
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               //cout << "parse> line=[" << line << "]" << endl;
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           // We scan the line for handling backslashes.
00096           //
00097           // o Really terminating backslashes (ie those only followed by spaces/tabs
00098           // mean continued line
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               // This is the last backslash
00112               // check if there are only space chars after it
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                   // This was not a trailing backslash.
00135                 finished = true;
00136               }
00137           }
00138         
00139         m_accumulator += temp_line;
00140         
00141           //cout << "parse_line1> accumulator=[" << m_accumulator << "]" << endl;
00142           //cout << "parse_line1> finished=[" << finished << "]" << endl;
00143 
00144         if (!finished)
00145           {
00146               // We still need to accumulate forthcoming lines
00147               // before parsing the resulting text.
00148             return (result);
00149           }
00150 
00151           // now filter the accumulated line
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                   //cout << "parse_line> accumulator=[" << m_accumulator << "]" << endl;
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             // Get the first end-of-line (either lf or cr-lf)
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                 // This is likely the last line since there is no end-of-line
00255               text.substr (pos, line);
00256               pos = max_pos;
00257             }
00258           else if (first > pos)
00259             {
00260                 // The eol was found beyond the current position
00261                 // (ie. this is a non empty line)
00262               text.substr (pos, first - pos, line);
00263               pos = first + 1;
00264             }
00265           else
00266             {
00267                 // an empty line
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             // Get the first end-of-line (either lf or cr-lf)
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                 // This is likely the last line since there is no end-of-line
00340               text.substr (pos, line);
00341               pos = max_pos;
00342             }
00343           else if (first > pos)
00344             {
00345                 // The eol was found beyond the current position
00346                 // (ie. this is a non empty line)
00347               text.substr (pos, first - pos, line);
00348               pos = first + 1;
00349             }
00350           else
00351             {
00352                 // an empty line
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& /*line*/)
00406 {
00407     //cout << "awk> " << line << endl;
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 

Generated at Thu May 16 16:27:05 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000