source: CMT/v1r18p20060505/source/cmt_pattern.cxx @ 654

Last change on this file since 654 was 177, checked in by arnault, 18 years ago

Add support for a <project> template in patterns - See CL 301

  • Property svn:eol-style set to native
File size: 23.2 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      Project* p = Project::find_by_cmtpath (context_use->real_path);
769      if (p != 0)
770        {
771          const cmt_string& n = p->get_name ();
772          replacement.replace_all ("<project>", n.c_str ());
773        }
774
775      for (int j = 0; j < templates.size (); j++)
776        {
777          Template& t = templates[j];
778          cmt_string s;
779          s = "<";
780          s += t.name;
781          s += ">";
782          replacement.replace_all (s, t.value);
783        }
784
785      for (;;)
786        {
787          int begin = replacement.find ("<");
788          if (begin == cmt_string::npos) break;
789          int end = replacement.find (begin, ">");
790          if (end == cmt_string::npos) break;
791          // Do not erase XML constructs
792          if (replacement[end-1] == '/') break;
793          replacement.erase (begin, end - begin + 1);
794        }
795
796      if (CmtSystem::testenv ("CMTTESTPATTERN"))
797        {
798          cout << "Pattern::expand2> repl=[" << replacement << "]" << endl;
799        }
800
801    }
802}
803
804//----------------------------------------------------------
805//
806//  Operations on ApplyPatterns
807//
808//----------------------------------------------------------
809
810//----------------------------------------------------------
811void ApplyPattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
812{
813    //
814    // Expected syntax is
815    //
816    // apply_pattern <pattern-name> [ <template>=<value> ... ]
817    //   or just
818    // <pattern-name> [ <template>=<value> ... ]
819    //
820
821  int first_word = 0;
822
823  if (words[0] == "apply_pattern") first_word = 1;
824  else first_word = 0;
825
826  if (words.size () < (first_word + 1)) return;
827
828  if (use == 0) use = &(Use::current());
829
830  cmt_string name = words[first_word];
831  Symbol::expand (name);
832
833  if (name == "") return;
834
835  Pattern* p = Pattern::find (name);
836  if (p == 0) 
837    {
838      CmtError::set (CmtError::pattern_not_found, name);
839      return;
840    }
841
842  ApplyPattern* apply_pattern = add (name, use);
843
844  /*
845    We then look for all <name>=<value> pairs
846   */
847  enum
848    {
849      need_template,
850      need_equal,
851      need_value,
852      can_add,
853      in_error
854    } state = need_template;
855
856  cmt_string tname;
857  cmt_string tvalue;
858
859  for (int i = (first_word + 1); i < words.size (); i++)
860    {
861      cmt_string s = words[i];
862
863      if (CmtSystem::testenv ("CMTTESTPATTERN"))
864        {
865          cout << "ApplyPattern::action> " << name << " s=[" << s << "] state=" << state << endl;
866        }
867
868      int pos = cmt_string::npos;
869
870      switch (state)
871        {
872        case need_template:
873          pos = s.find ("=");
874
875          tname = s;
876          tvalue = "";
877
878          if (pos == cmt_string::npos)
879            {
880              state = need_equal;
881            }
882          else
883            {
884              s.substr (0, pos, tname);
885              s.substr (pos + 1, tvalue);
886
887              if (CmtSystem::testenv ("CMTTESTPATTERN"))
888                {
889                  cout << "ApplyPattern::action-1> n=[" << tname << "] v=[" << tvalue << "]" << endl;
890                }
891             
892              if (tvalue == "")
893                {
894                  state = need_value;
895                }
896              else
897                {                 
898                  state = can_add;
899                }
900            }
901          break;
902        case need_equal:
903          pos = s.find ("=");
904
905          tvalue = "";
906
907          if (pos != 0)
908            {
909              state = in_error;
910              if (!Cmt::get_quiet ())
911                {
912                  cerr << "#CMT> Warning: bad syntax in apply_pattern " << name
913                       << " (missing '=' separator)";
914
915                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
916
917                  cerr << endl;
918                }
919              break;
920            }
921          else
922            {
923              s.substr (pos + 1, tvalue);
924
925              if (tvalue == "")
926                {
927                  state = need_value;
928                }
929              else
930                {                 
931                  state = can_add;
932                }
933            }
934          break;
935        case need_value:
936
937          pos = s.find ("=");
938
939          if (pos == cmt_string::npos)
940            {
941              tvalue = s;
942              state = can_add;
943            }
944          else
945            {
946              tname = s;
947              tvalue = "";
948
949              s.substr (0, pos, tname);
950              s.substr (pos + 1, tvalue);
951
952              if (CmtSystem::testenv ("CMTTESTPATTERN"))
953                {
954                  cout << "ApplyPattern::action-2> n=[" << tname << "] v=[" << tvalue << "]" << endl;
955                }
956             
957              if (tvalue == "")
958                {
959                  state = need_value;
960                }
961              else
962                {                 
963                  state = can_add;
964                }
965            }
966
967          break;
968        }
969
970      if (state == can_add)
971        {
972          state = need_template;
973
974              if (CmtSystem::testenv ("CMTTESTPATTERN"))
975                {
976                  cout << "ApplyPattern::action-3> n=[" << tname << "] v=[" << tvalue << "]" << endl;
977                }
978
979          cmt_string tsearch = "<";
980          tsearch += tname;
981          tsearch += ">";
982
983          if (p->line.find (tsearch) == cmt_string::npos)
984            {
985              if (!Cmt::get_quiet ())
986                {
987                  cerr << "#CMT> Warning: template <" << tname << "> not expected in pattern " << name;
988                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
989                  cerr << endl;
990                }
991            }
992
993          Template& t = apply_pattern->replacements.add ();
994
995          t.name = tname;
996          t.value = tvalue;
997
998          int size = t.value.size ();
999
1000          if (size >= 2)
1001            {
1002              if (((t.value[0] == '"') && (t.value[size - 1] == '"')) ||
1003                  ((t.value[0] == '\'') && (t.value[size - 1] == '\'')))
1004                {
1005                  t.value.erase (size - 1);
1006                  t.value.erase (0, 1);
1007                }
1008            }
1009        }
1010    }
1011
1012  apply_pattern->apply ();
1013}
1014
1015//----------------------------------------------------------
1016ApplyPattern* ApplyPattern::add (const cmt_string& name, Use* use)
1017{
1018  ApplyPattern& a = use->apply_patterns.add ();
1019
1020  a.name = name;
1021  a.use  = use;
1022
1023  return (&a);
1024}
1025
1026//----------------------------------------------------------
1027ApplyPattern::ApplyPattern ()
1028{
1029}
1030
1031//----------------------------------------------------------
1032ApplyPattern::~ApplyPattern ()
1033{
1034}
1035
1036//----------------------------------------------------------
1037void ApplyPattern::show () const
1038{
1039  cmt_string replacement = "";
1040
1041  Pattern* p = Pattern::find (name);
1042  if (p == 0) return;
1043
1044  Use* u = use;
1045  if (u == 0) u = &(Use::current ());
1046
1047  p->expand (u, replacements, replacement);
1048
1049  if (replacement != "")
1050    {
1051      replacement.replace_all ("\"", "");
1052      cout << replacement;
1053    }
1054}
1055
1056//----------------------------------------------------------
1057void ApplyPattern::apply () const
1058{
1059  if (CmtSystem::testenv ("CMTTESTPATTERN"))
1060    {
1061      cout << "ApplyPattern::apply> " << name << endl;
1062    }
1063
1064  Pattern* p = Pattern::find (name);
1065  if (p == 0) 
1066    {
1067      if (CmtSystem::testenv ("CMTTESTPATTERN"))
1068        {
1069          cout << "ApplyPattern::apply> " << name << " not found" << endl;
1070        }
1071
1072      return;
1073    }
1074
1075  if (p->global) return;
1076 
1077  Use* u = use;
1078  if (u == 0) u = &(Use::current ());
1079
1080  p->apply (u, replacements);
1081}
1082
1083
1084
1085//----------------------------------------------------------
1086/*                                                          */
1087/*  Operations on IgnorePatterns                            */
1088/*                                                          */
1089//----------------------------------------------------------
1090
1091//----------------------------------------------------------
1092void IgnorePattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
1093{
1094    //
1095    // Expected syntax is
1096    //
1097    // ignore_pattern <pattern-name>
1098    //
1099
1100  if (words.size () < 2) return;
1101
1102  if (use == 0) use = &(Use::current());
1103
1104  cmt_string& name = words[1];
1105
1106  add (name, use);
1107}
1108
1109//----------------------------------------------------------
1110IgnorePattern* IgnorePattern::find (const cmt_string& name, Use* use)
1111{
1112  int ignore_pattern_index;
1113
1114  if (use == 0) use = &(Use::current());
1115
1116  if (use->ignore_patterns.size () == 0) return (0);
1117
1118  for (ignore_pattern_index = 0;
1119       ignore_pattern_index < use->ignore_patterns.size ();
1120       ignore_pattern_index++)
1121    {
1122      IgnorePattern& ignore_pattern = use->ignore_patterns[ignore_pattern_index];
1123
1124      if (ignore_pattern.name == name)
1125        {
1126          return (&ignore_pattern);
1127        }
1128    }
1129
1130  return (0);
1131}
1132
1133//----------------------------------------------------------
1134void IgnorePattern::add (const cmt_string& name, Use* use)
1135{
1136  IgnorePattern* ignore_pattern;
1137
1138  ignore_pattern = find (name, use);
1139
1140  if (ignore_pattern == 0)
1141    {
1142      IgnorePattern& a = use->ignore_patterns.add ();
1143
1144      a.name = name;
1145      a.use  = use;
1146    }
1147}
1148
1149//----------------------------------------------------------
1150IgnorePattern::IgnorePattern ()
1151{
1152}
1153
1154//----------------------------------------------------------
1155IgnorePattern::~IgnorePattern ()
1156{
1157}
1158
1159//----------------------------------------------------------
1160void IgnorePattern::show () const
1161{
1162}
Note: See TracBrowser for help on using the repository browser.