source: CMT/v1r19/source/cmt_pattern.cxx @ 1

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

Import all tags

File size: 24.1 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// See the complete license in cmt_license.txt "http://www.cecill.info".
5//-----------------------------------------------------------
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <ctype.h>
11
12#include "cmt.h"
13#include "cmt_pattern.h"
14#include "cmt_use.h"
15#include "cmt_database.h"
16#include "cmt_error.h"
17#include "cmt_syntax.h"
18
19
20//----------------------------------------------------------
21
22PatternList* PatternList::find (const cmt_string& name)
23{
24  static PatternListMap& map = pattern_list_map ();
25
26  return (map.find (name));
27}
28
29
30Pattern* PatternList::find_pattern (const cmt_string& name)
31{
32  PatternList* list = find (name);
33  if (list == 0) return (0);
34
35  Pattern::PatternPtrVector& vector = list->get_patterns ();
36
37  if (vector.size () == 0) return (0);
38
39  Pattern* p = vector[vector.size () - 1];
40
41  return (p);
42}
43
44Pattern* PatternList::find (const cmt_string& name, Use* use)
45{
46  PatternList* list = find (name);
47  if (list == 0) return (0);
48
49  Pattern::PatternPtrVector& vector = list->get_patterns ();
50
51  for (int i = 0; i < vector.size (); i++)
52    {
53      Pattern* p = vector[i];
54
55      if (p->use == use) return (p);
56    }
57
58  return (0);
59}
60
61PatternList* PatternList::add (const cmt_string& name)
62{
63  PatternList* list = find (name);
64  if (list != 0) return (list);
65
66  static PatternListVector& vector = pattern_lists ();
67
68  PatternList& pl = vector.add ();
69  pl.m_name = name;
70
71  static PatternListMap& map = pattern_list_map ();
72  map.add (name, pl);
73
74  return (&pl);
75}
76
77void PatternList::clear_all ()
78{
79  static PatternListVector& vector = pattern_lists ();
80  static PatternListMap& map = pattern_list_map ();
81
82  for (int i = 0; i < vector.size (); i++)
83    {
84      PatternList& p = vector[i];
85      p.clear ();
86    }
87
88  vector.clear ();
89  map.clear ();
90}
91
92PatternList::PatternListMap& PatternList::pattern_list_map ()
93{
94  static Database& db = Database::instance ();
95  static PatternListMap& map = db.pattern_list_map ();
96
97  return (map);
98}
99
100PatternList::PatternListVector& PatternList::pattern_lists ()
101{
102  static Database& db = Database::instance ();
103  static PatternListVector& vector = db.pattern_lists ();
104
105  return (vector);
106}
107
108PatternList::PatternList ()
109{
110}
111
112PatternList::PatternList (const cmt_string& name) : m_name (name)
113{
114}
115
116PatternList::~PatternList ()
117{
118  clear ();
119}
120
121Pattern::PatternPtrVector& PatternList::get_patterns ()
122{
123  return (m_patterns);
124}
125
126void PatternList::add_pattern (Pattern* pattern)
127{
128  for (int i = 0; i < m_patterns.size (); i++)
129    {
130      Pattern* p = m_patterns[i];
131      if (p->use == pattern->use)
132        {
133          m_patterns[i] = pattern;
134          return;
135        }
136    }
137
138  m_patterns.push_back (pattern);
139}
140
141void PatternList::clear ()
142{
143  m_name = "";
144  m_patterns.clear ();
145}
146
147
148//----------------------------------------------------------
149//
150//  Operations on Patterns
151//
152//----------------------------------------------------------
153
154//----------------------------------------------------------
155void Pattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
156{
157  bool global = false;
158  int start_index;
159
160  if (words.size () < 2) return;
161
162    //
163    // expected syntax is:
164    //
165    //  pattern [-global] pattern-name any-cmt-statement
166    //
167    // where any-cmt-statement may contain "templates"
168    //
169    //      <package>
170    //      <PACKAGE>
171    //      <version>
172    //      <path>
173    //
174
175  cmt_string& option = words[1];
176
177  if (option == "-global")
178    {
179      global = true;
180      start_index = 2;
181    }
182  else
183    {
184      start_index = 1;
185    }
186
187  cmt_string& name = words[start_index];
188
189  start_index++;
190
191  add (name, words, start_index, global, use);
192
193  if (CmtSystem::testenv ("CMTTESTPATTERN"))
194    {
195      cout << "Pattern::action> add " << name << endl;
196    }
197}
198
199/**
200 *
201 *  Patterns are stored with two keys : <name> and <use>
202 *
203 *  thus search must done against these two keys.
204 *
205 */
206Pattern* Pattern::find (const cmt_string& name)
207{
208  Pattern* p = PatternList::find_pattern (name);
209
210  return (p);
211}
212
213//----------------------------------------------------------
214Pattern* Pattern::find (const cmt_string& name, Use* use)
215{
216  Pattern* p = PatternList::find (name, use);
217
218  return (p);
219}
220
221//----------------------------------------------------------
222void Pattern::add (const cmt_string& name,
223                   const CmtSystem::cmt_string_vector& words,
224                   int start_index,
225                   bool global,
226                   Use* use)
227{
228  static PatternVector& Patterns = patterns ();
229
230  Pattern* pattern;
231
232  pattern = find (name, use);
233
234  if (pattern == 0)
235    {
236        // No pattern for the pair <name, use> exist yet.
237        // create one.
238      Pattern& p = Patterns.add ();
239
240      p.clear ();
241
242      p.name = name;
243      p.use  = use;
244
245      PatternList* pl = PatternList::add (name);
246      pl->add_pattern (&p);
247
248      pattern = &p;
249    }
250  else
251    {
252      Pattern& p = *pattern;
253
254      p.clear ();
255
256      p.name = name;
257      p.use  = use;
258    }
259
260  pattern->line = "";
261
262  int first_word = start_index;
263
264    //
265    // Install the cmt-statement both as a vector of words and as a single line
266    //
267  for (int i = start_index; i < words.size (); i++)
268    {
269      bool need_quotes = (i > (first_word + 1));
270      //bool need_quotes = true;
271
272      cmt_string& s = words[i];
273
274      if (i > start_index) pattern->line += " ";
275
276      if (s == ";") first_word = i+1;
277
278      if ((s == "\n") | (s == ";"))
279        {
280          pattern->line += "\n  ";
281        }
282      else
283        {
284          cmt_string sep = "\"";
285
286          if (s.find (sep) != cmt_string::npos)
287            {
288              sep = "\'";
289            }
290
291          if (!need_quotes) sep = "";
292
293          pattern->line += sep;
294          pattern->line += s;
295          pattern->line += sep;
296        }
297    }
298
299  pattern->global = global;
300}
301
302/**
303 * Get the number of registered patterns
304 */
305int Pattern::pattern_number ()
306{
307  static PatternVector& Patterns = patterns ();
308
309  return (Patterns.size ());
310}
311
312/**
313 * Get the index'th pattern in the database
314 */
315Pattern& Pattern::pattern (int index)
316{
317  static PatternVector& Patterns = patterns ();
318
319  return (Patterns[index]);
320}
321
322//----------------------------------------------------------
323void Pattern::clear_all ()
324{
325  static PatternVector& Patterns = patterns ();
326
327  for (int i = 0; i < Patterns.size (); i++)
328    {
329      Pattern& p = Patterns[i];
330      p.clear ();
331    }
332
333  Patterns.clear ();
334}
335
336//----------------------------------------------------------
337Pattern::PatternVector& Pattern::patterns ()
338{
339  static Database& db = Database::instance ();
340  static PatternVector& Patterns = db.patterns ();
341
342  return (Patterns);
343}
344
345/**
346 * Applies all global patterns to all uses
347 */
348void PatternList::apply_all_globals ()
349{
350  static PatternListVector& PatternLists = pattern_lists ();
351
352  int i;
353
354  for (i = 0; i < PatternLists.size (); i++)
355    {
356      PatternList& pl = PatternLists[i];
357
358      int n = pl.m_patterns.size ();
359
360      if (n > 0)
361        {
362          Pattern* p = pl.m_patterns[n-1];
363
364          if ((p != 0) && (p->global)) p->apply ();
365        }
366    }
367}
368
369/**
370 * Applies all global patterns to a given Use
371 */
372void PatternList::apply_all_globals (Use* use)
373{
374  if (use->get_package_name () == "CMT") return;
375
376  static PatternListVector& PatternLists = pattern_lists ();
377
378  int i;
379
380  for (i = 0; i < PatternLists.size (); i++)
381    {
382      PatternList& pl = PatternLists[i];
383
384      int n = pl.m_patterns.size ();
385
386      if (n > 0)
387        {
388          Pattern* p = pl.m_patterns[n-1];
389
390          if ((p != 0) && (p->global)) 
391            {
392              if (p->global)
393                {
394                  if (IgnorePattern::find (p->name, use) == 0) p->apply (use);
395                }
396            }
397        }
398    }
399}
400
401/**
402 * Show all patterns
403 */
404void PatternList::show_all_patterns ()
405{
406  static PatternListVector& PatternLists = pattern_lists ();
407
408  int i;
409
410  for (i = 0; i < PatternLists.size (); i++)
411    {
412      PatternList& pl = PatternLists[i];
413
414      int n = pl.m_patterns.size ();
415
416      if (n > 0)
417        {
418          Pattern* p = pl.m_patterns[n-1];
419
420          if (p != 0) p->show ();
421        }
422    }
423}
424/**
425 * Show all pattern names
426 */
427void PatternList::show_all_pattern_names ()
428{
429  bool empty = true;
430
431  static PatternListVector& PatternLists = pattern_lists ();
432
433  int i;
434
435  for (i = 0; i < PatternLists.size (); i++)
436    {
437      PatternList& pl = PatternLists[i];
438
439      int n = pl.m_patterns.size ();
440
441      if (n > 0)
442        {
443          Pattern* p = pl.m_patterns[n-1];
444
445          if (p != 0)
446            {
447              cout << p->name << " ";
448              empty = false;
449            }
450        }
451    }
452  if (!empty) cout << endl;
453}
454
455/**
456 * Applies all global patterns to all uses
457 */
458void Pattern::apply_all_globals ()
459{
460  PatternList::apply_all_globals ();
461}
462
463/**
464 * Applies all global patterns to a given Use
465 */
466void Pattern::apply_all_globals (Use* use)
467{
468  PatternList::apply_all_globals ();
469}
470
471/**
472 * this is the cmt show patterns command
473 * It just shows the pattern declarations.
474 */
475void Pattern::show_all ()
476{
477  PatternList::show_all_patterns ();
478
479  show_all_applied_patterns ();
480}
481
482/**
483 * this is the cmt show applied_patterns command
484 * It just shows the pattern applications.
485 */
486void Pattern::show_all_applied_patterns ()
487{
488  Use* use = &(Use::current ());
489  for (int i = 0; i < use->apply_patterns.size (); i++)
490    {
491      const ApplyPattern& apply_pattern = use->apply_patterns[i];
492
493      cout << "# " << use->get_package_name ()
494           << " applies pattern " << apply_pattern.name << " => " << endl;
495      apply_pattern.show ();
496      cout << endl;
497    }
498}
499
500//----------------------------------------------------------
501void Pattern::show_all_names ()
502{
503  PatternList::show_all_pattern_names ();
504}
505
506/**
507 *  This is the cmt show pattern <name> command
508 * It shows both the pattern definition(s) and the places
509 * where it is explicitly applied.
510 */
511void Pattern::show (const cmt_string& name)
512{
513  static PatternVector& Patterns = patterns ();
514
515  int i;
516  int j;
517
518  bool found = false;
519
520    // First show the definitions.
521
522  Pattern* p = Pattern::find (name);
523
524  if (p == 0)
525    {
526      CmtError::set (CmtError::pattern_not_found, name);
527      return;
528    }
529
530  p->show ();
531
532    //
533    // Then show the packages which explicitly apply the pattern.
534    //
535  Use* use;
536  ApplyPattern* apply_pattern = 0;
537
538  Use::UsePtrVector& uses = Use::get_ordered_uses ();
539
540  for (i = 0; i < uses.size (); i++)
541    {
542      use = uses[i];
543      for (j = 0; j < use->apply_patterns.size (); j++)
544        {
545          apply_pattern = &(use->apply_patterns[j]);
546           
547          if (apply_pattern->name == name)
548            {
549              cout << "# applied by " << use->get_package_name () << " => " << endl;
550              apply_pattern->show ();
551              cout << endl;
552            }
553        }
554    }
555
556  use = &(Use::current ());
557  for (j = 0; j < use->apply_patterns.size (); j++)
558    {
559      apply_pattern = &(use->apply_patterns[j]);
560       
561      if (apply_pattern->name == name)
562        {
563          cout << "# " << use->get_package_name () << " " << use->version << " applies pattern " << name;
564          cout << " => " << endl;
565          apply_pattern->show ();
566          cout << endl;
567        }
568    }
569}
570
571//----------------------------------------------------------
572Pattern::Pattern ()
573{
574}
575
576//----------------------------------------------------------
577Pattern::~Pattern ()
578
579{
580}
581
582//----------------------------------------------------------
583void Pattern::clear ()
584{
585  global = false;
586  name = "";
587  use = 0;
588  line = "";
589}
590
591//----------------------------------------------------------
592void Pattern::show () const
593{
594  if (use != 0) cout << "# " << use->get_package_name () << " " << use->version;
595  else cout << "# ?? ";
596
597  cout  << " defines ";
598
599  if (global) cout << "global ";
600 
601  cout << "pattern " << name << " as" << endl;
602  cout << "  " << line << endl;
603}
604
605//----------------------------------------------------------
606class PatternCache
607{
608public:
609  static PatternCache& instance ()
610  {
611    static PatternCache me;
612
613    return (me);
614  }
615
616  static bool update (Use* c, Use* t)
617  {
618    static PatternCache& me = instance ();
619
620    return (me.do_update (c, t));
621  }
622
623  static Use::UsePtrVector& get_list ()
624  {
625    static PatternCache& me = instance ();
626
627    return (me.list);
628  }
629
630private:
631
632  PatternCache () : current(0), target(0)
633  {
634    current_name = "";
635    target_name = "";
636  }
637
638  bool do_update (Use* c, Use* t)
639  {
640    cmt_string c_name = c->get_package_name ();
641    cmt_string t_name = t->get_package_name ();
642
643    if ((current_name != c_name) || (target_name != t_name))
644      {
645        if (CmtSystem::getenv ("TESTCACHE") != "")
646          {
647            cout << "update cache " << c->get_package_name () << "(" << c << ") " << t->get_package_name () << "(" << t << ")" << endl;
648          }
649       
650        current = c;
651        current_name = c_name;
652
653        target = t;
654        target_name = t_name;
655
656        list.clear ();
657         
658        if (current != target)
659          {
660            if (!current->get_paths (target, list)) return (false);
661          }
662        else
663          {
664            list.push_back (current);
665          }
666      }
667    else
668      {
669        if (CmtSystem::getenv ("TESTCACHE") != "")
670          {
671            cout << "keep cache" << endl;
672          }
673      }
674    return (true);
675  }
676 
677  Use* current;
678  cmt_string current_name;
679  Use* target;
680  cmt_string target_name;
681  Use::UsePtrVector list;
682};
683
684/**
685 *   Applies a pattern to all uses (except CMT itself) between
686 *   current and the use that declared the pattern.
687 */
688void Pattern::apply () const
689{
690  Use::UsePtrVector& uses = Use::get_ordered_uses ();
691
692  Use* current = &(Use::current());
693
694  if (Cmt::get_debug ())
695    {
696      cout << "Pattern(" << name << "::apply> " << " defined in " << use->get_package_name () << endl;
697    }
698
699  if (!PatternCache::update (current, use)) return;
700
701  Use::UsePtrVector& list = PatternCache::get_list ();
702
703  for (int i = 0; i < list.size (); i++)
704    {
705      Use* u = list[i];
706
707      if (Cmt::get_debug ())
708        {
709          cout << "Pattern(" << name << "::apply> " << " to package " << u->get_package_name () << endl;
710        }
711
712      if ((u->get_package_name () != "CMT") && 
713          (IgnorePattern::find (name, u) == 0)) apply (u);
714    }
715}
716
717//----------------------------------------------------------
718void Pattern::apply (Use* context_use) const
719{
720  static Template::TemplateVector dummy_templates;
721
722  apply (context_use, dummy_templates);
723}
724
725/**
726 *  Applies a pattern to one particular use.
727 */
728void Pattern::apply (Use* context_use, 
729                     const Template::TemplateVector& templates) const
730{
731  cmt_string replacement;
732
733  expand (context_use, templates, replacement);
734
735  if (CmtSystem::testenv ("CMTTESTPATTERN"))
736    {
737      cout << "Pattern::apply> replacement=[" << replacement << "]" << endl;
738    }
739
740  if (replacement != "")
741    {
742      SyntaxParser::parse_requirements_text (replacement, "", context_use);
743    }
744}
745
746//----------------------------------------------------------
747void Pattern::expand (Use* context_use, 
748                      const Template::TemplateVector& templates, 
749                      cmt_string& replacement) const
750{
751  if (context_use == 0) context_use = &(Use::current ());
752
753  if (CmtSystem::testenv ("CMTTESTPATTERN"))
754    {
755      cout << "Pattern::expand1> line=[" << line << "]" << endl;
756    }
757
758  replacement = line;
759
760  if (replacement != "")
761    {
762        // Substitute templates from the cmt statement
763      replacement.replace_all ("<package>", context_use->get_package_name ().c_str ());
764      replacement.replace_all ("<PACKAGE>", context_use->prefix.c_str ());
765      replacement.replace_all ("<version>", context_use->version.c_str ());
766      replacement.replace_all ("<path>",    context_use->real_path.c_str ());
767
768      for (int j = 0; j < templates.size (); j++)
769        {
770          Template& t = templates[j];
771          cmt_string s;
772          s = "<";
773          s += t.name;
774          s += ">";
775          replacement.replace_all (s, t.value);
776        }
777
778      for (;;)
779        {
780          int begin = replacement.find ("<");
781          if (begin == cmt_string::npos) break;
782          int end = replacement.find (begin, ">");
783          if (end == cmt_string::npos) break;
784          // Do not erase XML constructs
785          if (replacement[end-1] == '/') break;
786          replacement.erase (begin, end - begin + 1);
787        }
788
789      if (CmtSystem::testenv ("CMTTESTPATTERN"))
790        {
791          cout << "Pattern::expand2> repl=[" << replacement << "]" << endl;
792        }
793
794    }
795}
796
797//----------------------------------------------------------
798//
799//  Operations on ApplyPatterns
800//
801//----------------------------------------------------------
802
803//----------------------------------------------------------
804void ApplyPattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
805{
806    //
807    // Expected syntax is
808    //
809    // apply_pattern <pattern-name> [ <template>=<value> ... ]
810    //   or just
811    // <pattern-name> [ <template>=<value> ... ]
812    //
813
814  int first_word = 0;
815
816  if (words[0] == "apply_pattern") first_word = 1;
817  else first_word = 0;
818
819  if (words.size () < (first_word + 1)) return;
820
821  if (use == 0) use = &(Use::current());
822
823  cmt_string name = words[first_word];
824  Symbol::expand (name);
825
826  if (name == "") return;
827
828  Pattern* p = Pattern::find (name);
829  if (p == 0) 
830    {
831      CmtError::set (CmtError::pattern_not_found, name);
832      return;
833    }
834
835  ApplyPattern* apply_pattern = add (name, use);
836
837  /*
838    We then look for all <name>=<value> pairs
839   */
840  enum
841    {
842      need_template,
843      need_equal,
844      need_value,
845      can_add,
846      in_error
847    } state = need_template;
848
849  cmt_string tname;
850  cmt_string tvalue;
851
852  for (int i = (first_word + 1); i < words.size (); i++)
853    {
854      cmt_string s = words[i];
855
856      if (CmtSystem::testenv ("CMTTESTPATTERN"))
857        {
858          cout << "ApplyPattern::action> " << name << " s=[" << s << "] state=" << state << endl;
859        }
860
861      int pos = cmt_string::npos;
862
863      switch (state)
864        {
865        case need_template:
866          pos = s.find ("=");
867
868          tname = s;
869          tvalue = "";
870
871          if (pos == cmt_string::npos)
872            {
873              state = need_equal;
874            }
875          else
876            {
877              s.substr (0, pos, tname);
878              s.substr (pos + 1, tvalue);
879
880              if (CmtSystem::testenv ("CMTTESTPATTERN"))
881                {
882                  cout << "ApplyPattern::action-1> n=[" << tname << "] v=[" << tvalue << "]" << endl;
883                }
884             
885              if (tvalue == "")
886                {
887                  state = need_value;
888                }
889              else
890                {                 
891                  state = can_add;
892                }
893            }
894          break;
895        case need_equal:
896          pos = s.find ("=");
897
898          tvalue = "";
899
900          if (pos != 0)
901            {
902              state = in_error;
903              if (!Cmt::get_quiet ())
904                {
905                  cerr << "#CMT> Warning: bad syntax in apply_pattern " << name
906                       << " (missing '=' separator)";
907
908                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
909
910                  cerr << endl;
911                }
912              break;
913            }
914          else
915            {
916              s.substr (pos + 1, tvalue);
917
918              if (tvalue == "")
919                {
920                  state = need_value;
921                }
922              else
923                {                 
924                  state = can_add;
925                }
926            }
927          break;
928        case need_value:
929
930          pos = s.find ("=");
931
932          if (pos == cmt_string::npos)
933            {
934              tvalue = s;
935              state = can_add;
936            }
937          else
938            {
939              tname = s;
940              tvalue = "";
941
942              s.substr (0, pos, tname);
943              s.substr (pos + 1, tvalue);
944
945              if (CmtSystem::testenv ("CMTTESTPATTERN"))
946                {
947                  cout << "ApplyPattern::action-2> n=[" << tname << "] v=[" << tvalue << "]" << endl;
948                }
949             
950              if (tvalue == "")
951                {
952                  state = need_value;
953                }
954              else
955                {                 
956                  state = can_add;
957                }
958            }
959
960          break;
961        }
962
963      if (state == can_add)
964        {
965          state = need_template;
966
967              if (CmtSystem::testenv ("CMTTESTPATTERN"))
968                {
969                  cout << "ApplyPattern::action-3> n=[" << tname << "] v=[" << tvalue << "]" << endl;
970                }
971
972          cmt_string tsearch = "<";
973          tsearch += tname;
974          tsearch += ">";
975
976          if (p->line.find (tsearch) == cmt_string::npos)
977            {
978              if (!Cmt::get_quiet ())
979                {
980                  cerr << "#CMT> Warning: template <" << tname << "> not expected in pattern " << name;
981                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
982                  cerr << endl;
983                }
984            }
985
986          Template& t = apply_pattern->replacements.add ();
987
988          t.name = tname;
989          t.value = tvalue;
990
991          int size = t.value.size ();
992
993          if (size >= 2)
994            {
995              if (((t.value[0] == '"') && (t.value[size - 1] == '"')) ||
996                  ((t.value[0] == '\'') && (t.value[size - 1] == '\'')))
997                {
998                  t.value.erase (size - 1);
999                  t.value.erase (0, 1);
1000                }
1001            }
1002        }
1003    }
1004
1005  apply_pattern->apply ();
1006}
1007
1008//----------------------------------------------------------
1009ApplyPattern* ApplyPattern::add (const cmt_string& name, Use* use)
1010{
1011  ApplyPattern& a = use->apply_patterns.add ();
1012
1013  a.name = name;
1014  a.use  = use;
1015
1016  return (&a);
1017}
1018
1019//----------------------------------------------------------
1020ApplyPattern::ApplyPattern ()
1021{
1022}
1023
1024//----------------------------------------------------------
1025ApplyPattern::~ApplyPattern ()
1026{
1027}
1028
1029//----------------------------------------------------------
1030void ApplyPattern::show () const
1031{
1032  cmt_string replacement = "";
1033
1034  Pattern* p = Pattern::find (name);
1035  if (p == 0) return;
1036
1037  Use* u = use;
1038  if (u == 0) u = &(Use::current ());
1039
1040  p->expand (u, replacements, replacement);
1041
1042  if (replacement != "")
1043    {
1044      replacement.replace_all ("\"", "");
1045      cout << replacement;
1046    }
1047}
1048
1049//----------------------------------------------------------
1050void ApplyPattern::apply () const
1051{
1052  if (CmtSystem::testenv ("CMTTESTPATTERN"))
1053    {
1054      cout << "ApplyPattern::apply> " << name << endl;
1055    }
1056
1057  Pattern* p = Pattern::find (name);
1058  if (p == 0) 
1059    {
1060      if (CmtSystem::testenv ("CMTTESTPATTERN"))
1061        {
1062          cout << "ApplyPattern::apply> " << name << " not found" << endl;
1063        }
1064
1065      return;
1066    }
1067
1068  if (p->global) return;
1069 
1070  Use* u = use;
1071  if (u == 0) u = &(Use::current ());
1072
1073  p->apply (u, replacements);
1074}
1075
1076
1077
1078//----------------------------------------------------------
1079/*                                                          */
1080/*  Operations on IgnorePatterns                            */
1081/*                                                          */
1082//----------------------------------------------------------
1083
1084//----------------------------------------------------------
1085void IgnorePattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
1086{
1087    //
1088    // Expected syntax is
1089    //
1090    // ignore_pattern <pattern-name>
1091    //
1092
1093  if (words.size () < 2) return;
1094
1095  if (use == 0) use = &(Use::current());
1096
1097  cmt_string& name = words[1];
1098
1099  add (name, use);
1100}
1101
1102//----------------------------------------------------------
1103IgnorePattern* IgnorePattern::find (const cmt_string& name, Use* use)
1104{
1105  int ignore_pattern_index;
1106
1107  if (use == 0) use = &(Use::current());
1108
1109  if (use->ignore_patterns.size () == 0) return (0);
1110
1111  for (ignore_pattern_index = 0;
1112       ignore_pattern_index < use->ignore_patterns.size ();
1113       ignore_pattern_index++)
1114    {
1115      IgnorePattern& ignore_pattern = use->ignore_patterns[ignore_pattern_index];
1116
1117      if (ignore_pattern.name == name)
1118        {
1119          return (&ignore_pattern);
1120        }
1121    }
1122
1123  return (0);
1124}
1125
1126//----------------------------------------------------------
1127void IgnorePattern::add (const cmt_string& name, Use* use)
1128{
1129  IgnorePattern* ignore_pattern;
1130
1131  ignore_pattern = find (name, use);
1132
1133  if (ignore_pattern == 0)
1134    {
1135      IgnorePattern& a = use->ignore_patterns.add ();
1136
1137      a.name = name;
1138      a.use  = use;
1139    }
1140}
1141
1142//----------------------------------------------------------
1143IgnorePattern::IgnorePattern ()
1144{
1145}
1146
1147//----------------------------------------------------------
1148IgnorePattern::~IgnorePattern ()
1149{
1150}
1151
1152//----------------------------------------------------------
1153void IgnorePattern::show () const
1154{
1155}
Note: See TracBrowser for help on using the repository browser.