source: CMT/v1r10p20011126/src/cmt_awk.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 12.7 KB
Line 
1
2#ifdef WIN32
3#include <direct.h>
4#define popen _popen
5#define pclose _pclose
6#endif
7
8#include "cmt_awk.h"
9#include "cmt_system.h"
10
11class Parser
12{
13public:
14  Parser (Awk* awk, const cmt_string pattern, const cmt_regexp* expression) :
15          m_awk(awk), m_pattern (pattern), m_expression (expression)
16      {
17      }
18
19  Awk::condition parse (const cmt_string& text)
20      {
21        Awk::condition result = Awk::ok;
22
23        cmt_string line;
24        int pos;
25        int max_pos;
26
27        pos = 0;
28        max_pos = text.size ();
29
30        m_accumulator.erase (0);
31
32        for (pos = 0; pos < max_pos;)
33          {
34            int cr = text.find (pos, "\r\n");
35            int nl = text.find (pos, '\n');
36            int first = nl;
37            int length = 1;
38           
39            if (cr != cmt_string::npos)
40              {
41                if (nl == cmt_string::npos)
42                  {
43                    first = cr;
44                    length = 2;
45                  }
46                else
47                  {
48                    first = (nl < cr) ? nl : cr;
49                    length = (nl < cr) ? 1 : 2;
50                  }
51              }
52           
53            if (first == cmt_string::npos)
54              {
55                text.substr (pos, line);
56                pos = max_pos;
57              }
58            else if (first > pos)
59              {
60                text.substr (pos, first - pos, line);
61                pos = first + length;
62              }
63            else
64              {
65                line.erase (0);
66                pos += length;
67              }
68
69              //cout << "parse> line=[" << line << "]" << endl;
70
71            result = parse_line (line);
72            if (result != Awk::ok) break;
73          }
74
75        return (result);
76      }
77
78  Awk::condition parse_line (const cmt_string& line)
79      {
80        Awk::condition result = Awk::ok;
81        int length;
82        int nl;
83        int back_slash;
84        cmt_string temp_line = line;
85
86        if (temp_line.size () == 0) return (result);
87
88        nl = temp_line.find_last_of ('\n');
89        if (nl != cmt_string::npos) temp_line.erase (nl);
90       
91        length = temp_line.size ();
92        if (length == 0) return (result);
93       
94          //
95          // We scan the line for handling backslashes.
96          //
97          // o Really terminating backslashes (ie those only followed by spaces/tabs
98          // mean continued line
99          //
100          //
101
102        bool finished = true;
103
104        length = temp_line.size ();
105
106        back_slash = temp_line.find_last_of ('\\');
107       
108        if (back_slash != cmt_string::npos)
109          {
110              //
111              // This is the last backslash
112              // check if there are only space chars after it
113              //
114           
115            bool at_end = true;
116           
117            for (int i = (back_slash + 1); i < length; i++)
118              {
119                char c = temp_line[i];
120                if ((c != ' ') && (c != '\t'))
121                  {
122                    at_end = false;
123                    break;
124                  }
125              }
126           
127            if (at_end)
128              {
129                temp_line.erase (back_slash);
130                finished = false;
131              }
132            else
133              {
134                  // This was not a trailing backslash.
135                finished = true;
136              }
137          }
138       
139        m_accumulator += temp_line;
140       
141          //cout << "parse_line1> accumulator=[" << m_accumulator << "]" << endl;
142          //cout << "parse_line1> finished=[" << finished << "]" << endl;
143
144        if (!finished)
145          {
146              // We still need to accumulate forthcoming lines
147              // before parsing the resulting text.
148            return (result);
149          }
150
151          // now filter the accumulated line
152
153        if (m_accumulator != "")
154          {
155            bool ok = false;
156           
157            if (m_expression != 0)
158              {
159                if (m_expression->match (m_accumulator))
160                  {
161                    ok = true;
162                  }
163              }
164            else
165              {
166                if ((m_pattern == "") ||
167                    (m_accumulator.find (m_pattern) != cmt_string::npos))
168                  {
169                    ok = true;
170                  }
171              }
172           
173            if (ok && (m_awk != 0))
174              {
175                  //cout << "parse_line> accumulator=[" << m_accumulator << "]" << endl;
176
177                m_awk->filter (m_accumulator);
178                result = m_awk->get_last_condition ();
179              }
180          }
181       
182        m_accumulator.erase (0);
183
184        return (result);
185      }
186
187private:
188
189  cmt_string m_accumulator;
190  cmt_string m_pattern;
191  const cmt_regexp* m_expression;
192  Awk* m_awk;
193};
194
195//------------------------------------------------
196Awk::Awk ()
197{
198  m_condition = ok;
199}
200
201//------------------------------------------------
202Awk::~Awk ()
203{
204}
205
206//------------------------------------------------
207Awk::condition Awk::run (const cmt_string& text,
208                         const cmt_string& pattern)
209{
210  m_line_number = 0;
211  m_condition = ok;
212
213  begin ();
214  if (m_condition != ok) return (m_condition);
215
216  if (CmtSystem::testenv ("CMTTESTAWK"))
217    {
218      Parser p (this, pattern, 0);
219
220      m_condition = p.parse (text);
221      if (m_condition != ok) return (m_condition);
222    }
223  else
224    {
225      cmt_string line;
226      int pos = 0;
227      int max_pos;
228
229      max_pos = text.size ();
230
231      for (pos = 0; pos < max_pos;)
232        {
233          int cr = text.find (pos, "\r\n");
234          int nl = text.find (pos, '\n');
235         
236            // Get the first end-of-line (either lf or cr-lf)
237         
238          int first = nl;
239         
240          if (cr != cmt_string::npos)
241            {
242              if (nl == cmt_string::npos)
243                {
244                  first = cr;
245                }
246              else
247                {
248                  first = (nl < cr) ? nl : cr;
249                }
250            }
251         
252          if (first == cmt_string::npos)
253            {
254                // This is likely the last line since there is no end-of-line
255              text.substr (pos, line);
256              pos = max_pos;
257            }
258          else if (first > pos)
259            {
260                // The eol was found beyond the current position
261                // (ie. this is a non empty line)
262              text.substr (pos, first - pos, line);
263              pos = first + 1;
264            }
265          else
266            {
267                // an empty line
268              line = "";
269              pos++;
270            }
271         
272          m_line_number++;
273         
274          if (line != "")
275            {
276              if ((pattern == "") ||
277                  (line.find (pattern) != cmt_string::npos))
278                {
279                  filter (line);
280                  if (m_condition != ok) return (m_condition);
281                }
282            }
283        }
284    }
285
286  end ();
287
288  return (m_condition);
289}
290
291//------------------------------------------------
292Awk::condition Awk::run (const cmt_string& text,
293                         const cmt_regexp& expression)
294{
295  m_line_number = 0;
296  m_condition = ok;
297
298  begin ();
299  if (m_condition != ok) return (m_condition);
300
301  if (CmtSystem::testenv ("CMTTESTAWK"))
302    {
303      Parser p (this, "", &expression);
304
305      m_condition = p.parse (text);
306      if (m_condition != ok) return (m_condition);
307    }
308  else
309    {
310      cmt_string line;
311      int pos = 0;
312      int max_pos;
313
314      max_pos = text.size ();
315
316      for (pos = 0; pos < max_pos;)
317        {
318          int cr = text.find (pos, "\r\n");
319          int nl = text.find (pos, '\n');
320         
321            // Get the first end-of-line (either lf or cr-lf)
322         
323          int first = nl;
324         
325          if (cr != cmt_string::npos)
326            {
327              if (nl == cmt_string::npos)
328                {
329                  first = cr;
330                }
331              else
332                {
333                  first = (nl < cr) ? nl : cr;
334                }
335            }
336         
337          if (first == cmt_string::npos)
338            {
339                // This is likely the last line since there is no end-of-line
340              text.substr (pos, line);
341              pos = max_pos;
342            }
343          else if (first > pos)
344            {
345                // The eol was found beyond the current position
346                // (ie. this is a non empty line)
347              text.substr (pos, first - pos, line);
348              pos = first + 1;
349            }
350          else
351            {
352                // an empty line
353              line = "";
354              pos++;
355            }
356         
357          m_line_number++;
358         
359          if (line != "")
360            {
361              if (expression.match (line))
362                {
363                  filter (line);
364                  if (m_condition != ok) return (m_condition);
365                }
366            }
367        }
368    }
369
370  end ();
371
372  return (m_condition);
373}
374
375//------------------------------------------------
376void Awk::stop ()
377{
378  m_condition = stopped;
379}
380
381//------------------------------------------------
382void Awk::abort ()
383{
384  m_condition = failed;
385}
386
387//------------------------------------------------
388void Awk::allow_continuation ()
389{
390  m_continuation_allowed = true;
391}
392
393//------------------------------------------------
394Awk::condition Awk::get_last_condition () const
395{
396  return (m_condition);
397}
398
399//------------------------------------------------
400void Awk::begin ()
401{
402}
403
404//------------------------------------------------
405void Awk::filter (const cmt_string& line)
406{
407    //cout << "awk> " << line << endl;
408}
409
410//------------------------------------------------
411void Awk::end ()
412{
413}
414
415//------------------------------------------------
416Awk::condition FAwk::run (const cmt_string& file_name,
417                          const cmt_string& pattern)
418{
419  if (!CmtSystem::test_file (file_name)) return (failed);
420
421  CmtSystem::basename (file_name, m_file_name);
422  CmtSystem::dirname (file_name, m_dir_name);
423
424  cmt_string text;
425
426  text.read (file_name);
427
428  return (Awk::run (text, pattern));
429}
430
431//------------------------------------------------
432Awk::condition FAwk::run (const cmt_string& file_name,
433                          const cmt_regexp& expression)
434{
435  if (!CmtSystem::test_file (file_name)) return (failed);
436
437  CmtSystem::basename (file_name, m_file_name);
438  CmtSystem::dirname (file_name, m_dir_name);
439
440  cmt_string text;
441
442  text.read (file_name);
443
444  return (Awk::run (text, expression));
445}
446
447//------------------------------------------------
448Awk::condition PAwk::run (const cmt_string& command, 
449                          const cmt_string& pattern)
450{
451  cmt_string line;
452
453  m_line_number = 0;
454  m_condition = ok;
455
456  begin ();
457  if (m_condition != ok) return (m_condition);
458
459  FILE* f = popen (command.c_str (), "r"); 
460 
461  if (f == 0) return (failed);
462
463  char buffer[8192]; 
464  char* ptr;
465
466  while ((ptr = fgets (buffer, sizeof (buffer), f)) != NULL) 
467    {
468      line = ptr;
469
470      if (line.find ("\n") == cmt_string::npos)
471        {
472          cerr << "#CMT> Warning : Line too long and truncated in PAwk::run for command " << command << endl;
473        }
474
475      line.replace ("\n", "");
476
477      m_line_number++;
478
479      if (line != "")
480        {
481          if ((pattern == "") ||
482              (line.find (pattern) != cmt_string::npos))
483            {
484              filter (line);
485              if (m_condition != ok) return (m_condition);
486            }
487        }
488    }
489
490  pclose (f);
491
492  end ();
493
494  return (m_condition);
495}
496
497//------------------------------------------------
498Awk::condition PAwk::run (const cmt_string& command, 
499                          const cmt_regexp& expression)
500{
501  cmt_string line;
502
503  m_line_number = 0;
504  m_condition = ok;
505
506  begin ();
507  if (m_condition != ok) return (m_condition);
508
509  FILE* f = popen (command.c_str (), "r"); 
510 
511  if (f == 0) return (failed);
512
513  char buffer[256]; 
514  char* ptr;
515
516  while ((ptr = fgets (buffer, sizeof (buffer), f)) != NULL) 
517    {
518      line = ptr;
519
520      line.replace ("\n", "");
521
522      m_line_number++;
523
524      if (line != "")
525        {
526          if (expression.match (line))
527            {
528              filter (line);
529              if (m_condition != ok) return (m_condition);
530            }
531        }
532    }
533
534  pclose (f);
535
536  end ();
537
538  return (m_condition);
539}
540
Note: See TracBrowser for help on using the repository browser.