source: CMT/v1r20p20080222/source/cmt_pattern.cxx

Last change on this file was 400, checked in by arnault, 17 years ago

Text formatting
Sending warnings & errors to stderr
Using internally PWD for every cd/pwd
CL 327

  • Property svn:eol-style set to native
File size: 23.3 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      cerr << "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
496      apply_pattern.show ();
497
498      cout << endl;
499    }
500}
501
502//----------------------------------------------------------
503void Pattern::show_all_names ()
504{
505  PatternList::show_all_pattern_names ();
506}
507
508/**
509 *  This is the cmt show pattern <name> command
510 * It shows both the pattern definition(s) and the places
511 * where it is explicitly applied.
512 */
513void Pattern::show (const cmt_string& name)
514{
515  static PatternVector& Patterns = patterns ();
516
517  int i;
518  int j;
519
520  bool found = false;
521
522  // First show the definitions.
523
524  Pattern* p = Pattern::find (name);
525
526  if (p == 0)
527    {
528      CmtError::set (CmtError::pattern_not_found, name);
529      return;
530    }
531
532  p->show ();
533
534  //
535  // Then show the packages which explicitly apply the pattern.
536  //
537  Use* use;
538  ApplyPattern* apply_pattern = 0;
539
540  Use::UsePtrVector& uses = Use::get_ordered_uses ();
541
542  for (i = 0; i < uses.size (); i++)
543    {
544      use = uses[i];
545      for (j = 0; j < use->apply_patterns.size (); j++)
546        {
547          apply_pattern = &(use->apply_patterns[j]);
548           
549          if (apply_pattern->name == name)
550            {
551              cout << "# applied by " << use->get_package_name () << " => " << endl;
552              apply_pattern->show ();
553              cout << endl;
554            }
555        }
556    }
557
558  use = &(Use::current ());
559  for (j = 0; j < use->apply_patterns.size (); j++)
560    {
561      apply_pattern = &(use->apply_patterns[j]);
562       
563      if (apply_pattern->name == name)
564        {
565          cout << "# " << use->get_package_name () << " " << use->version << " applies pattern " << name;
566          cout << " => " << endl;
567          apply_pattern->show ();
568          cout << endl;
569        }
570    }
571}
572
573//----------------------------------------------------------
574Pattern::Pattern ()
575{
576}
577
578//----------------------------------------------------------
579Pattern::~Pattern ()
580
581{
582}
583
584//----------------------------------------------------------
585void Pattern::clear ()
586{
587  global = false;
588  name = "";
589  use = 0;
590  line = "";
591}
592
593//----------------------------------------------------------
594void Pattern::show () const
595{
596  if (use != 0) cout << "# " << use->get_package_name () << " " << use->version;
597  else cout << "# ?? ";
598
599  cout  << " defines ";
600
601  if (global) cout << "global ";
602 
603  cout << "pattern " << name << " as" << endl;
604  cout << "  " << line << endl;
605}
606
607//----------------------------------------------------------
608class PatternCache
609{
610public:
611  static PatternCache& instance ()
612  {
613    static PatternCache me;
614
615    return (me);
616  }
617
618  static bool update (Use* c, Use* t)
619  {
620    static PatternCache& me = instance ();
621
622    return (me.do_update (c, t));
623  }
624
625  static Use::UsePtrVector& get_list ()
626  {
627    static PatternCache& me = instance ();
628
629    return (me.list);
630  }
631
632private:
633
634  PatternCache () : current(0), target(0)
635  {
636    current_name = "";
637    target_name = "";
638  }
639
640  bool do_update (Use* c, Use* t)
641  {
642    cmt_string c_name = c->get_package_name ();
643    cmt_string t_name = t->get_package_name ();
644
645    if ((current_name != c_name) || (target_name != t_name))
646      {
647        if (CmtSystem::getenv ("TESTCACHE") != "")
648          {
649            cerr << "update cache " << c->get_package_name () << "(" << c << ") " << t->get_package_name () << "(" << t << ")" << endl;
650          }
651       
652        current = c;
653        current_name = c_name;
654
655        target = t;
656        target_name = t_name;
657
658        list.clear ();
659         
660        if (current != target)
661          {
662            if (!current->get_paths (target, list)) return (false);
663          }
664        else
665          {
666            list.push_back (current);
667          }
668      }
669    else
670      {
671        if (CmtSystem::getenv ("TESTCACHE") != "")
672          {
673            cerr << "keep cache" << endl;
674          }
675      }
676    return (true);
677  }
678 
679  Use* current;
680  cmt_string current_name;
681  Use* target;
682  cmt_string target_name;
683  Use::UsePtrVector list;
684};
685
686/**
687 *   Applies a pattern to all uses (except CMT itself) between
688 *   current and the use that declared the pattern.
689 */
690void Pattern::apply () const
691{
692  Use::UsePtrVector& uses = Use::get_ordered_uses ();
693
694  Use* current = &(Use::current());
695
696  if (Cmt::get_debug ())
697    {
698      cout << "Pattern(" << name << "::apply> " << " defined in " << use->get_package_name () << endl;
699    }
700
701  if (!PatternCache::update (current, use)) return;
702
703  Use::UsePtrVector& list = PatternCache::get_list ();
704
705  for (int i = 0; i < list.size (); i++)
706    {
707      Use* u = list[i];
708
709      if (Cmt::get_debug ())
710        {
711          cout << "Pattern(" << name << "::apply> " << " to package " << u->get_package_name () << endl;
712        }
713
714      if ((u->get_package_name () != "CMT") && 
715          (IgnorePattern::find (name, u) == 0)) apply (u);
716    }
717}
718
719//----------------------------------------------------------
720void Pattern::apply (Use* context_use) const
721{
722  static Template::TemplateVector dummy_templates;
723
724  apply (context_use, dummy_templates);
725}
726
727/**
728 *  Applies a pattern to one particular use.
729 */
730void Pattern::apply (Use* context_use, 
731                     const Template::TemplateVector& templates) const
732{
733  cmt_string replacement;
734
735  expand (context_use, templates, replacement);
736
737  if (CmtSystem::testenv ("CMTTESTPATTERN"))
738    {
739      cerr << "Pattern::apply> replacement=[" << replacement << "]" << endl;
740    }
741
742  if (replacement != "")
743    {
744      SyntaxParser::parse_requirements_text (replacement, "", context_use);
745    }
746}
747
748//----------------------------------------------------------
749void Pattern::expand (Use* context_use, 
750                      const Template::TemplateVector& templates, 
751                      cmt_string& replacement) const
752{
753  if (context_use == 0) context_use = &(Use::current ());
754
755  if (CmtSystem::testenv ("CMTTESTPATTERN"))
756    {
757      cerr << "Pattern::expand1> line=[" << line << "]" << endl;
758    }
759
760  replacement = line;
761
762  if (replacement != "")
763    {
764      // Substitute templates from the cmt statement
765      replacement.replace_all ("<package>", context_use->get_package_name ().c_str ());
766      replacement.replace_all ("<PACKAGE>", context_use->prefix.c_str ());
767      replacement.replace_all ("<version>", context_use->version.c_str ());
768      replacement.replace_all ("<path>",    context_use->real_path.c_str ());
769
770      cmt_string cmtpath = "";
771      cmt_string offset = "";
772
773      context_use->get_cmtpath_and_offset (cmtpath, offset);
774
775      Project* p = Project::find_by_cmtpath (cmtpath);
776      if (p != 0)
777        {
778          const cmt_string& n = p->get_name ();
779          replacement.replace_all ("<project>", n.c_str ());
780        }
781
782      for (int j = 0; j < templates.size (); j++)
783        {
784          Template& t = templates[j];
785          cmt_string s;
786          s = "<";
787          s += t.name;
788          s += ">";
789          replacement.replace_all (s, t.value);
790        }
791
792      for (;;)
793        {
794          int begin = replacement.find ("<");
795          if (begin == cmt_string::npos) break;
796          int end = replacement.find (begin, ">");
797          if (end == cmt_string::npos) break;
798          // Do not erase XML constructs
799          if (replacement[end-1] == '/') break;
800          replacement.erase (begin, end - begin + 1);
801        }
802
803      if (CmtSystem::testenv ("CMTTESTPATTERN"))
804        {
805          cerr << "Pattern::expand2> repl=[" << replacement << "]" << endl;
806        }
807
808    }
809}
810
811//----------------------------------------------------------
812//
813//  Operations on ApplyPatterns
814//
815//----------------------------------------------------------
816
817//----------------------------------------------------------
818void ApplyPattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
819{
820  //
821  // Expected syntax is
822  //
823  // apply_pattern <pattern-name> [ <template>=<value> ... ]
824  //   or just
825  // <pattern-name> [ <template>=<value> ... ]
826  //
827
828  int first_word = 0;
829
830  if (words[0] == "apply_pattern") first_word = 1;
831  else first_word = 0;
832
833  if (words.size () < (first_word + 1)) return;
834
835  if (use == 0) use = &(Use::current());
836
837  cmt_string name = words[first_word];
838  Symbol::expand (name);
839
840  if (name == "") return;
841
842  Pattern* p = Pattern::find (name);
843  if (p == 0) 
844    {
845      CmtError::set (CmtError::pattern_not_found, name);
846      return;
847    }
848
849  ApplyPattern* apply_pattern = add (name, use);
850
851  /*
852    We then look for all <name>=<value> pairs
853  */
854  enum
855    {
856      need_template,
857      need_equal,
858      need_value,
859      can_add,
860      in_error
861    } state = need_template;
862
863  cmt_string tname;
864  cmt_string tvalue;
865
866  for (int i = (first_word + 1); i < words.size (); i++)
867    {
868      cmt_string s = words[i];
869
870      if (CmtSystem::testenv ("CMTTESTPATTERN"))
871        {
872          cerr << "ApplyPattern::action> " << name << " s=[" << s << "] state=" << state << endl;
873        }
874
875      int pos = cmt_string::npos;
876
877      switch (state)
878        {
879        case need_template:
880          pos = s.find ("=");
881
882          tname = s;
883          tvalue = "";
884
885          if (pos == cmt_string::npos)
886            {
887              state = need_equal;
888            }
889          else
890            {
891              s.substr (0, pos, tname);
892              s.substr (pos + 1, tvalue);
893
894              if (CmtSystem::testenv ("CMTTESTPATTERN"))
895                {
896                  cerr << "ApplyPattern::action-1> n=[" << tname << "] v=[" << tvalue << "]" << endl;
897                }
898             
899              if (tvalue == "")
900                {
901                  state = need_value;
902                }
903              else
904                {                 
905                  state = can_add;
906                }
907            }
908          break;
909        case need_equal:
910          pos = s.find ("=");
911
912          tvalue = "";
913
914          if (pos != 0)
915            {
916              state = in_error;
917              if (!Cmt::get_quiet ())
918                {
919                  cerr << "#CMT> Warning: bad syntax in apply_pattern " << name
920                       << " (missing '=' separator)";
921
922                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
923
924                  cerr << endl;
925                }
926              break;
927            }
928          else
929            {
930              s.substr (pos + 1, tvalue);
931
932              if (tvalue == "")
933                {
934                  state = need_value;
935                }
936              else
937                {                 
938                  state = can_add;
939                }
940            }
941          break;
942        case need_value:
943
944          pos = s.find ("=");
945
946          if (pos == cmt_string::npos)
947            {
948              tvalue = s;
949              state = can_add;
950            }
951          else
952            {
953              tname = s;
954              tvalue = "";
955
956              s.substr (0, pos, tname);
957              s.substr (pos + 1, tvalue);
958
959              if (CmtSystem::testenv ("CMTTESTPATTERN"))
960                {
961                  cerr << "ApplyPattern::action-2> n=[" << tname << "] v=[" << tvalue << "]" << endl;
962                }
963             
964              if (tvalue == "")
965                {
966                  state = need_value;
967                }
968              else
969                {                 
970                  state = can_add;
971                }
972            }
973
974          break;
975        }
976
977      if (state == can_add)
978        {
979          state = need_template;
980
981          if (CmtSystem::testenv ("CMTTESTPATTERN"))
982            {
983              cerr << "ApplyPattern::action-3> n=[" << tname << "] v=[" << tvalue << "]" << endl;
984            }
985
986          cmt_string tsearch = "<";
987          tsearch += tname;
988          tsearch += ">";
989
990          if (p->line.find (tsearch) == cmt_string::npos)
991            {
992              if (!Cmt::get_quiet ())
993                {
994                  cerr << "#CMT> Warning: template <" << tname << "> not expected in pattern " << name;
995                  if (use != 0) cerr << " (from " << use->get_package_name () << ")";
996                  cerr << endl;
997                }
998            }
999
1000          Template& t = apply_pattern->replacements.add ();
1001
1002          t.name = tname;
1003          t.value = tvalue;
1004
1005          int size = t.value.size ();
1006
1007          if (size >= 2)
1008            {
1009              if (((t.value[0] == '"') && (t.value[size - 1] == '"')) ||
1010                  ((t.value[0] == '\'') && (t.value[size - 1] == '\'')))
1011                {
1012                  t.value.erase (size - 1);
1013                  t.value.erase (0, 1);
1014                }
1015            }
1016        }
1017    }
1018
1019  apply_pattern->apply ();
1020}
1021
1022//----------------------------------------------------------
1023ApplyPattern* ApplyPattern::add (const cmt_string& name, Use* use)
1024{
1025  ApplyPattern& a = use->apply_patterns.add ();
1026
1027  a.name = name;
1028  a.use  = use;
1029
1030  return (&a);
1031}
1032
1033//----------------------------------------------------------
1034ApplyPattern::ApplyPattern ()
1035{
1036}
1037
1038//----------------------------------------------------------
1039ApplyPattern::~ApplyPattern ()
1040{
1041}
1042
1043//----------------------------------------------------------
1044void ApplyPattern::show () const
1045{
1046  cmt_string replacement = "";
1047
1048  Pattern* p = Pattern::find (name);
1049  if (p == 0) return;
1050
1051  Use* u = use;
1052  if (u == 0) u = &(Use::current ());
1053
1054  p->expand (u, replacements, replacement);
1055
1056  if (replacement != "")
1057    {
1058      replacement.replace_all ("\"", "");
1059      cout << replacement;
1060    }
1061}
1062
1063//----------------------------------------------------------
1064void ApplyPattern::apply () const
1065{
1066  if (CmtSystem::testenv ("CMTTESTPATTERN"))
1067    {
1068      cerr << "ApplyPattern::apply> " << name << endl;
1069    }
1070
1071  Pattern* p = Pattern::find (name);
1072  if (p == 0) 
1073    {
1074      if (CmtSystem::testenv ("CMTTESTPATTERN"))
1075        {
1076          cerr << "ApplyPattern::apply> " << name << " not found" << endl;
1077        }
1078
1079      return;
1080    }
1081
1082  if (p->global) return;
1083 
1084  Use* u = use;
1085  if (u == 0) u = &(Use::current ());
1086
1087  p->apply (u, replacements);
1088}
1089
1090
1091
1092//----------------------------------------------------------
1093/*                                                          */
1094/*  Operations on IgnorePatterns                            */
1095/*                                                          */
1096//----------------------------------------------------------
1097
1098//----------------------------------------------------------
1099void IgnorePattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
1100{
1101  //
1102  // Expected syntax is
1103  //
1104  // ignore_pattern <pattern-name>
1105  //
1106
1107  if (words.size () < 2) return;
1108
1109  if (use == 0) use = &(Use::current());
1110
1111  cmt_string& name = words[1];
1112
1113  add (name, use);
1114}
1115
1116//----------------------------------------------------------
1117IgnorePattern* IgnorePattern::find (const cmt_string& name, Use* use)
1118{
1119  int ignore_pattern_index;
1120
1121  if (use == 0) use = &(Use::current());
1122
1123  if (use->ignore_patterns.size () == 0) return (0);
1124
1125  for (ignore_pattern_index = 0;
1126       ignore_pattern_index < use->ignore_patterns.size ();
1127       ignore_pattern_index++)
1128    {
1129      IgnorePattern& ignore_pattern = use->ignore_patterns[ignore_pattern_index];
1130
1131      if (ignore_pattern.name == name)
1132        {
1133          return (&ignore_pattern);
1134        }
1135    }
1136
1137  return (0);
1138}
1139
1140//----------------------------------------------------------
1141void IgnorePattern::add (const cmt_string& name, Use* use)
1142{
1143  IgnorePattern* ignore_pattern;
1144
1145  ignore_pattern = find (name, use);
1146
1147  if (ignore_pattern == 0)
1148    {
1149      IgnorePattern& a = use->ignore_patterns.add ();
1150
1151      a.name = name;
1152      a.use  = use;
1153    }
1154}
1155
1156//----------------------------------------------------------
1157IgnorePattern::IgnorePattern ()
1158{
1159}
1160
1161//----------------------------------------------------------
1162IgnorePattern::~IgnorePattern ()
1163{
1164}
1165
1166//----------------------------------------------------------
1167void IgnorePattern::show () const
1168{
1169}
Note: See TracBrowser for help on using the repository browser.