Main?Page | Class?Hierarchy | Class?List | File?List | Class?Members | File?Members

cmt_pattern.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------
00002 // Copyright Christian Arnault LAL-Orsay CNRS
00003 // 
00004 // See the complete license in cmt_license.txt "http://www.cecill.info". 
00005 //-----------------------------------------------------------
00006 
00007 #include 
00008 #include 
00009 #include 
00010 #include 
00011 
00012 #include "cmt.h"
00013 #include "cmt_pattern.h"
00014 #include "cmt_use.h"
00015 #include "cmt_database.h"
00016 #include "cmt_error.h"
00017 #include "cmt_syntax.h"
00018 
00019 
00020 //----------------------------------------------------------
00021 
00022 PatternList* PatternList::find (const cmt_string& name)
00023 {
00024   static PatternListMap& map = pattern_list_map ();
00025 
00026   return (map.find (name));
00027 }
00028 
00029 
00030 Pattern* PatternList::find_pattern (const cmt_string& name)
00031 {
00032   PatternList* list = find (name);
00033   if (list == 0) return (0);
00034 
00035   Pattern::PatternPtrVector& vector = list->get_patterns ();
00036 
00037   if (vector.size () == 0) return (0);
00038 
00039   Pattern* p = vector[vector.size () - 1];
00040 
00041   return (p);
00042 }
00043 
00044 Pattern* PatternList::find (const cmt_string& name, Use* use)
00045 {
00046   PatternList* list = find (name);
00047   if (list == 0) return (0);
00048 
00049   Pattern::PatternPtrVector& vector = list->get_patterns ();
00050 
00051   for (int i = 0; i < vector.size (); i++)
00052     {
00053       Pattern* p = vector[i];
00054 
00055       if (p->use == use) return (p);
00056     }
00057 
00058   return (0);
00059 }
00060 
00061 PatternList* PatternList::add (const cmt_string& name)
00062 {
00063   PatternList* list = find (name);
00064   if (list != 0) return (list);
00065 
00066   static PatternListVector& vector = pattern_lists ();
00067 
00068   PatternList& pl = vector.add ();
00069   pl.m_name = name;
00070 
00071   static PatternListMap& map = pattern_list_map ();
00072   map.add (name, pl);
00073 
00074   return (&pl);
00075 }
00076 
00077 void PatternList::clear_all ()
00078 {
00079   static PatternListVector& vector = pattern_lists ();
00080   static PatternListMap& map = pattern_list_map ();
00081 
00082   for (int i = 0; i < vector.size (); i++)
00083     {
00084       PatternList& p = vector[i];
00085       p.clear ();
00086     }
00087 
00088   vector.clear ();
00089   map.clear ();
00090 }
00091 
00092 PatternList::PatternListMap& PatternList::pattern_list_map ()
00093 {
00094   static Database& db = Database::instance ();
00095   static PatternListMap& map = db.pattern_list_map ();
00096 
00097   return (map);
00098 }
00099 
00100 PatternList::PatternListVector& PatternList::pattern_lists ()
00101 {
00102   static Database& db = Database::instance ();
00103   static PatternListVector& vector = db.pattern_lists ();
00104 
00105   return (vector);
00106 }
00107 
00108 PatternList::PatternList ()
00109 {
00110 }
00111 
00112 PatternList::PatternList (const cmt_string& name) : m_name (name)
00113 {
00114 }
00115 
00116 PatternList::~PatternList ()
00117 {
00118   clear ();
00119 }
00120 
00121 Pattern::PatternPtrVector& PatternList::get_patterns ()
00122 {
00123   return (m_patterns);
00124 }
00125 
00126 void PatternList::add_pattern (Pattern* pattern)
00127 {
00128   for (int i = 0; i < m_patterns.size (); i++)
00129     {
00130       Pattern* p = m_patterns[i];
00131       if (p->use == pattern->use)
00132         {
00133           m_patterns[i] = pattern;
00134           return;
00135         }
00136     }
00137 
00138   m_patterns.push_back (pattern);
00139 }
00140 
00141 void PatternList::clear ()
00142 {
00143   m_name = "";
00144   m_patterns.clear ();
00145 }
00146 
00147 
00148 //----------------------------------------------------------
00149 //
00150 //  Operations on Patterns
00151 //
00152 //----------------------------------------------------------
00153 
00154 //----------------------------------------------------------
00155 void Pattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
00156 {
00157   bool global = false;
00158   int start_index;
00159 
00160   if (words.size () < 2) return;
00161 
00162     //
00163     // expected syntax is:
00164     //
00165     //  pattern [-global] pattern-name any-cmt-statement
00166     //
00167     // where any-cmt-statement may contain "templates"
00168     //
00169     //      
00170     //      
00171     //      
00172     //      
00173     //
00174 
00175   cmt_string& option = words[1];
00176 
00177   if (option == "-global")
00178     {
00179       global = true;
00180       start_index = 2;
00181     }
00182   else
00183     {
00184       start_index = 1;
00185     }
00186 
00187   cmt_string& name = words[start_index];
00188 
00189   start_index++;
00190 
00191   add (name, words, start_index, global, use);
00192 
00193   if (CmtSystem::testenv ("CMTTESTPATTERN"))
00194     {
00195       cout << "Pattern::action> add " << name << endl;
00196     }
00197 }
00198 
00206 Pattern* Pattern::find (const cmt_string& name)
00207 {
00208   Pattern* p = PatternList::find_pattern (name);
00209 
00210   return (p);
00211 }
00212 
00213 //----------------------------------------------------------
00214 Pattern* Pattern::find (const cmt_string& name, Use* use)
00215 {
00216   Pattern* p = PatternList::find (name, use);
00217 
00218   return (p);
00219 }
00220 
00221 //----------------------------------------------------------
00222 void Pattern::add (const cmt_string& name,
00223                    const CmtSystem::cmt_string_vector& words,
00224                    int start_index,
00225                    bool global,
00226                    Use* use)
00227 {
00228   static PatternVector& Patterns = patterns ();
00229 
00230   Pattern* pattern;
00231 
00232   pattern = find (name, use);
00233 
00234   if (pattern == 0)
00235     {
00236         // No pattern for the pair  exist yet.
00237         // create one.
00238       Pattern& p = Patterns.add ();
00239 
00240       p.clear ();
00241 
00242       p.name = name;
00243       p.use  = use;
00244 
00245       PatternList* pl = PatternList::add (name);
00246       pl->add_pattern (&p);
00247 
00248       pattern = &p;
00249     }
00250   else
00251     {
00252       Pattern& p = *pattern;
00253 
00254       p.clear ();
00255 
00256       p.name = name;
00257       p.use  = use;
00258     }
00259 
00260   pattern->line = "";
00261 
00262   int first_word = start_index;
00263 
00264     //
00265     // Install the cmt-statement both as a vector of words and as a single line
00266     //
00267   for (int i = start_index; i < words.size (); i++)
00268     {
00269       bool need_quotes = (i > (first_word + 1));
00270       //bool need_quotes = true;
00271 
00272       cmt_string& s = words[i];
00273 
00274       if (i > start_index) pattern->line += " ";
00275 
00276       if (s == ";") first_word = i+1;
00277 
00278       if ((s == "\n") | (s == ";"))
00279         {
00280           pattern->line += "\n  ";
00281         }
00282       else
00283         {
00284           cmt_string sep = "\"";
00285 
00286           if (s.find (sep) != cmt_string::npos)
00287             {
00288               sep = "\'";
00289             }
00290 
00291           if (!need_quotes) sep = "";
00292 
00293           pattern->line += sep;
00294           pattern->line += s;
00295           pattern->line += sep;
00296         }
00297     }
00298 
00299   pattern->global = global;
00300 }
00301 
00305 int Pattern::pattern_number ()
00306 {
00307   static PatternVector& Patterns = patterns ();
00308 
00309   return (Patterns.size ());
00310 }
00311 
00315 Pattern& Pattern::pattern (int index)
00316 {
00317   static PatternVector& Patterns = patterns ();
00318 
00319   return (Patterns[index]);
00320 }
00321 
00322 //----------------------------------------------------------
00323 void Pattern::clear_all ()
00324 {
00325   static PatternVector& Patterns = patterns ();
00326 
00327   for (int i = 0; i < Patterns.size (); i++)
00328     {
00329       Pattern& p = Patterns[i];
00330       p.clear ();
00331     }
00332 
00333   Patterns.clear ();
00334 }
00335 
00336 //----------------------------------------------------------
00337 Pattern::PatternVector& Pattern::patterns ()
00338 {
00339   static Database& db = Database::instance ();
00340   static PatternVector& Patterns = db.patterns ();
00341 
00342   return (Patterns);
00343 }
00344 
00348 void PatternList::apply_all_globals ()
00349 {
00350   static PatternListVector& PatternLists = pattern_lists ();
00351 
00352   int i;
00353 
00354   for (i = 0; i < PatternLists.size (); i++)
00355     {
00356       PatternList& pl = PatternLists[i];
00357 
00358       int n = pl.m_patterns.size ();
00359 
00360       if (n > 0)
00361         {
00362           Pattern* p = pl.m_patterns[n-1];
00363 
00364           if ((p != 0) && (p->global)) p->apply ();
00365         }
00366     }
00367 }
00368 
00372 void PatternList::apply_all_globals (Use* use)
00373 {
00374   if (use->get_package_name () == "CMT") return;
00375 
00376   static PatternListVector& PatternLists = pattern_lists ();
00377 
00378   int i;
00379 
00380   for (i = 0; i < PatternLists.size (); i++)
00381     {
00382       PatternList& pl = PatternLists[i];
00383 
00384       int n = pl.m_patterns.size ();
00385 
00386       if (n > 0)
00387         {
00388           Pattern* p = pl.m_patterns[n-1];
00389 
00390           if ((p != 0) && (p->global)) 
00391             {
00392               if (p->global)
00393                 {
00394                   if (IgnorePattern::find (p->name, use) == 0) p->apply (use);
00395                 }
00396             }
00397         }
00398     }
00399 }
00400 
00404 void PatternList::show_all_patterns ()
00405 {
00406   static PatternListVector& PatternLists = pattern_lists ();
00407 
00408   int i;
00409 
00410   for (i = 0; i < PatternLists.size (); i++)
00411     {
00412       PatternList& pl = PatternLists[i];
00413 
00414       int n = pl.m_patterns.size ();
00415 
00416       if (n > 0)
00417         {
00418           Pattern* p = pl.m_patterns[n-1];
00419 
00420           if (p != 0) p->show ();
00421         }
00422     }
00423 }
00427 void PatternList::show_all_pattern_names ()
00428 {
00429   bool empty = true;
00430 
00431   static PatternListVector& PatternLists = pattern_lists ();
00432 
00433   int i;
00434 
00435   for (i = 0; i < PatternLists.size (); i++)
00436     {
00437       PatternList& pl = PatternLists[i];
00438 
00439       int n = pl.m_patterns.size ();
00440 
00441       if (n > 0)
00442         {
00443           Pattern* p = pl.m_patterns[n-1];
00444 
00445           if (p != 0)
00446             {
00447               cout << p->name << " ";
00448               empty = false;
00449             }
00450         }
00451     }
00452   if (!empty) cout << endl;
00453 }
00454 
00458 void Pattern::apply_all_globals ()
00459 {
00460   PatternList::apply_all_globals ();
00461 }
00462 
00466 void Pattern::apply_all_globals (Use* use)
00467 {
00468   PatternList::apply_all_globals ();
00469 }
00470 
00475 void Pattern::show_all ()
00476 {
00477   PatternList::show_all_patterns ();
00478 
00479   show_all_applied_patterns ();
00480 }
00481 
00486 void Pattern::show_all_applied_patterns ()
00487 {
00488   Use* use = &(Use::current ());
00489   for (int i = 0; i < use->apply_patterns.size (); i++)
00490     {
00491       const ApplyPattern& apply_pattern = use->apply_patterns[i];
00492 
00493       cout << "# " << use->get_package_name ()
00494            << " applies pattern " << apply_pattern.name << " => " << endl;
00495       apply_pattern.show ();
00496       cout << endl;
00497     }
00498 }
00499 
00500 //----------------------------------------------------------
00501 void Pattern::show_all_names ()
00502 {
00503   PatternList::show_all_pattern_names ();
00504 }
00505 
00511 void Pattern::show (const cmt_string& name)
00512 {
00513   static PatternVector& Patterns = patterns ();
00514 
00515   int i;
00516   int j;
00517 
00518   bool found = false;
00519 
00520     // First show the definitions.
00521 
00522   Pattern* p = Pattern::find (name);
00523 
00524   if (p == 0)
00525     {
00526       CmtError::set (CmtError::pattern_not_found, name);
00527       return;
00528     }
00529 
00530   p->show ();
00531 
00532     //
00533     // Then show the packages which explicitly apply the pattern.
00534     //
00535   Use* use;
00536   ApplyPattern* apply_pattern = 0;
00537 
00538   Use::UsePtrVector& uses = Use::get_ordered_uses ();
00539 
00540   for (i = 0; i < uses.size (); i++)
00541     {
00542       use = uses[i];
00543       for (j = 0; j < use->apply_patterns.size (); j++)
00544         {
00545           apply_pattern = &(use->apply_patterns[j]);
00546             
00547           if (apply_pattern->name == name)
00548             {
00549               cout << "# applied by " << use->get_package_name () << " => " << endl;
00550               apply_pattern->show ();
00551               cout << endl;
00552             }
00553         }
00554     }
00555 
00556   use = &(Use::current ());
00557   for (j = 0; j < use->apply_patterns.size (); j++)
00558     {
00559       apply_pattern = &(use->apply_patterns[j]);
00560         
00561       if (apply_pattern->name == name)
00562         {
00563           cout << "# " << use->get_package_name () << " " << use->version << " applies pattern " << name;
00564           cout << " => " << endl;
00565           apply_pattern->show ();
00566           cout << endl;
00567         }
00568     }
00569 }
00570 
00571 //----------------------------------------------------------
00572 Pattern::Pattern ()
00573 {
00574 }
00575 
00576 //----------------------------------------------------------
00577 Pattern::~Pattern ()
00578 
00579 {
00580 }
00581 
00582 //----------------------------------------------------------
00583 void Pattern::clear ()
00584 {
00585   global = false;
00586   name = "";
00587   use = 0;
00588   line = "";
00589 }
00590 
00591 //----------------------------------------------------------
00592 void Pattern::show () const
00593 {
00594   if (use != 0) cout << "# " << use->get_package_name () << " " << use->version;
00595   else cout << "# ?? ";
00596 
00597   cout  << " defines ";
00598 
00599   if (global) cout << "global ";
00600   
00601   cout << "pattern " << name << " as" << endl;
00602   cout << "  " << line << endl;
00603 }
00604 
00605 //----------------------------------------------------------
00606 class PatternCache
00607 {
00608 public:
00609   static PatternCache& instance ()
00610   {
00611     static PatternCache me;
00612 
00613     return (me);
00614   }
00615 
00616   static bool update (Use* c, Use* t)
00617   {
00618     static PatternCache& me = instance ();
00619 
00620     return (me.do_update (c, t));
00621   }
00622 
00623   static Use::UsePtrVector& get_list ()
00624   {
00625     static PatternCache& me = instance ();
00626 
00627     return (me.list);
00628   }
00629 
00630 private:
00631 
00632   PatternCache () : current(0), target(0)
00633   {
00634     current_name = "";
00635     target_name = "";
00636   }
00637 
00638   bool do_update (Use* c, Use* t)
00639   {
00640     cmt_string c_name = c->get_package_name ();
00641     cmt_string t_name = t->get_package_name ();
00642 
00643     if ((current_name != c_name) || (target_name != t_name))
00644       {
00645         if (CmtSystem::getenv ("TESTCACHE") != "")
00646           {
00647             cout << "update cache " << c->get_package_name () << "(" << c << ") " << t->get_package_name () << "(" << t << ")" << endl;
00648           }
00649         
00650         current = c;
00651         current_name = c_name;
00652 
00653         target = t;
00654         target_name = t_name;
00655 
00656         list.clear ();
00657           
00658         if (current != target)
00659           {
00660             if (!current->get_paths (target, list)) return (false);
00661           }
00662         else
00663           {
00664             list.push_back (current);
00665           }
00666       }
00667     else
00668       {
00669         if (CmtSystem::getenv ("TESTCACHE") != "")
00670           {
00671             cout << "keep cache" << endl;
00672           }
00673       }
00674     return (true);
00675   }
00676   
00677   Use* current;
00678   cmt_string current_name;
00679   Use* target;
00680   cmt_string target_name;
00681   Use::UsePtrVector list;
00682 };
00683 
00688 void Pattern::apply () const
00689 {
00690   Use::UsePtrVector& uses = Use::get_ordered_uses ();
00691 
00692   Use* current = &(Use::current());
00693 
00694   if (Cmt::get_debug ())
00695     {
00696       cout << "Pattern(" << name << "::apply> " << " defined in " << use->get_package_name () << endl;
00697     }
00698 
00699   if (!PatternCache::update (current, use)) return;
00700 
00701   Use::UsePtrVector& list = PatternCache::get_list ();
00702 
00703   for (int i = 0; i < list.size (); i++)
00704     {
00705       Use* u = list[i];
00706 
00707       if (Cmt::get_debug ())
00708         {
00709           cout << "Pattern(" << name << "::apply> " << " to package " << u->get_package_name () << endl;
00710         }
00711 
00712       if ((u->get_package_name () != "CMT") && 
00713           (IgnorePattern::find (name, u) == 0)) apply (u);
00714     }
00715 }
00716 
00717 //----------------------------------------------------------
00718 void Pattern::apply (Use* context_use) const
00719 {
00720   static Template::TemplateVector dummy_templates;
00721 
00722   apply (context_use, dummy_templates);
00723 }
00724 
00728 void Pattern::apply (Use* context_use, 
00729                      const Template::TemplateVector& templates) const
00730 {
00731   cmt_string replacement;
00732 
00733   expand (context_use, templates, replacement);
00734 
00735   if (CmtSystem::testenv ("CMTTESTPATTERN"))
00736     {
00737       cout << "Pattern::apply> replacement=[" << replacement << "]" << endl;
00738     }
00739 
00740   if (replacement != "")
00741     {
00742       SyntaxParser::parse_requirements_text (replacement, "", context_use);
00743     }
00744 }
00745 
00746 //----------------------------------------------------------
00747 void Pattern::expand (Use* context_use, 
00748                       const Template::TemplateVector& templates, 
00749                       cmt_string& replacement) const
00750 {
00751   if (context_use == 0) context_use = &(Use::current ());
00752 
00753   if (CmtSystem::testenv ("CMTTESTPATTERN"))
00754     {
00755       cout << "Pattern::expand1> line=[" << line << "]" << endl;
00756     }
00757 
00758   replacement = line;
00759 
00760   if (replacement != "")
00761     {
00762         // Substitute templates from the cmt statement
00763       replacement.replace_all ("", context_use->get_package_name ().c_str ());
00764       replacement.replace_all ("", context_use->prefix.c_str ());
00765       replacement.replace_all ("", context_use->version.c_str ());
00766       replacement.replace_all ("",    context_use->real_path.c_str ());
00767 
00768       for (int j = 0; j < templates.size (); j++)
00769         {
00770           Template& t = templates[j];
00771           cmt_string s;
00772           s = "<";
00773           s += t.name;
00774           s += ">";
00775           replacement.replace_all (s, t.value);
00776         }
00777 
00778       for (;;)
00779         {
00780           int begin = replacement.find ("<");
00781           if (begin == cmt_string::npos) break;
00782           int end = replacement.find (begin, ">");
00783           if (end == cmt_string::npos) break;
00784           // Do not erase XML constructs
00785           if (replacement[end-1] == '/') break;
00786           replacement.erase (begin, end - begin + 1);
00787         }
00788 
00789       if (CmtSystem::testenv ("CMTTESTPATTERN"))
00790         {
00791           cout << "Pattern::expand2> repl=[" << replacement << "]" << endl;
00792         }
00793 
00794     }
00795 }
00796 
00797 //----------------------------------------------------------
00798 //
00799 //  Operations on ApplyPatterns
00800 //
00801 //----------------------------------------------------------
00802 
00803 //----------------------------------------------------------
00804 void ApplyPattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
00805 {
00806     //
00807     // Expected syntax is
00808     //
00809     // apply_pattern  [ 
00810     //   or just
00811     //  [ 
00812     //
00813 
00814   int first_word = 0;
00815 
00816   if (words[0] == "apply_pattern") first_word = 1;
00817   else first_word = 0;
00818 
00819   if (words.size () < (first_word + 1)) return;
00820 
00821   if (use == 0) use = &(Use::current());
00822 
00823   cmt_string name = words[first_word];
00824   Symbol::expand (name);
00825 
00826   if (name == "") return;
00827 
00828   Pattern* p = Pattern::find (name);
00829   if (p == 0) 
00830     {
00831       CmtError::set (CmtError::pattern_not_found, name);
00832       return;
00833     }
00834 
00835   ApplyPattern* apply_pattern = add (name, use);
00836 
00837   /*
00838     We then look for all = pairs
00839    */
00840   enum
00841     {
00842       need_template,
00843       need_equal,
00844       need_value,
00845       can_add,
00846       in_error
00847     } state = need_template;
00848 
00849   cmt_string tname;
00850   cmt_string tvalue;
00851 
00852   for (int i = (first_word + 1); i < words.size (); i++)
00853     {
00854       cmt_string s = words[i];
00855 
00856       if (CmtSystem::testenv ("CMTTESTPATTERN"))
00857         {
00858           cout << "ApplyPattern::action> " << name << " s=[" << s << "] state=" << state << endl;
00859         }
00860 
00861       int pos = cmt_string::npos;
00862 
00863       switch (state)
00864         {
00865         case need_template:
00866           pos = s.find ("=");
00867 
00868           tname = s;
00869           tvalue = "";
00870 
00871           if (pos == cmt_string::npos)
00872             {
00873               state = need_equal;
00874             }
00875           else
00876             {
00877               s.substr (0, pos, tname);
00878               s.substr (pos + 1, tvalue);
00879 
00880               if (CmtSystem::testenv ("CMTTESTPATTERN"))
00881                 {
00882                   cout << "ApplyPattern::action-1> n=[" << tname << "] v=[" << tvalue << "]" << endl;
00883                 }
00884               
00885               if (tvalue == "")
00886                 {
00887                   state = need_value;
00888                 }
00889               else
00890                 {                 
00891                   state = can_add;
00892                 }
00893             }
00894           break;
00895         case need_equal:
00896           pos = s.find ("=");
00897 
00898           tvalue = "";
00899 
00900           if (pos != 0)
00901             {
00902               state = in_error;
00903               if (!Cmt::get_quiet ())
00904                 {
00905                   cerr << "#CMT> Warning: bad syntax in apply_pattern " << name
00906                        << " (missing '=' separator)";
00907 
00908                   if (use != 0) cerr << " (from " << use->get_package_name () << ")";
00909 
00910                   cerr << endl;
00911                 }
00912               break;
00913             }
00914           else
00915             {
00916               s.substr (pos + 1, tvalue);
00917 
00918               if (tvalue == "")
00919                 {
00920                   state = need_value;
00921                 }
00922               else
00923                 {                 
00924                   state = can_add;
00925                 }
00926             }
00927           break;
00928         case need_value:
00929 
00930           pos = s.find ("=");
00931 
00932           if (pos == cmt_string::npos)
00933             {
00934               tvalue = s;
00935               state = can_add;
00936             }
00937           else
00938             {
00939               tname = s;
00940               tvalue = "";
00941 
00942               s.substr (0, pos, tname);
00943               s.substr (pos + 1, tvalue);
00944 
00945               if (CmtSystem::testenv ("CMTTESTPATTERN"))
00946                 {
00947                   cout << "ApplyPattern::action-2> n=[" << tname << "] v=[" << tvalue << "]" << endl;
00948                 }
00949               
00950               if (tvalue == "")
00951                 {
00952                   state = need_value;
00953                 }
00954               else
00955                 {                 
00956                   state = can_add;
00957                 }
00958             }
00959 
00960           break;
00961         }
00962 
00963       if (state == can_add)
00964         {
00965           state = need_template;
00966 
00967               if (CmtSystem::testenv ("CMTTESTPATTERN"))
00968                 {
00969                   cout << "ApplyPattern::action-3> n=[" << tname << "] v=[" << tvalue << "]" << endl;
00970                 }
00971 
00972           cmt_string tsearch = "<";
00973           tsearch += tname;
00974           tsearch += ">";
00975 
00976           if (p->line.find (tsearch) == cmt_string::npos)
00977             {
00978               if (!Cmt::get_quiet ())
00979                 {
00980                   cerr << "#CMT> Warning: template <" << tname << "> not expected in pattern " << name;
00981                   if (use != 0) cerr << " (from " << use->get_package_name () << ")";
00982                   cerr << endl;
00983                 }
00984             }
00985 
00986           Template& t = apply_pattern->replacements.add ();
00987 
00988           t.name = tname;
00989           t.value = tvalue;
00990 
00991           int size = t.value.size ();
00992 
00993           if (size >= 2)
00994             {
00995               if (((t.value[0] == '"') && (t.value[size - 1] == '"')) ||
00996                   ((t.value[0] == '\'') && (t.value[size - 1] == '\'')))
00997                 {
00998                   t.value.erase (size - 1);
00999                   t.value.erase (0, 1);
01000                 }
01001             }
01002         }
01003     }
01004 
01005   apply_pattern->apply ();
01006 }
01007 
01008 //----------------------------------------------------------
01009 ApplyPattern* ApplyPattern::add (const cmt_string& name, Use* use)
01010 {
01011   ApplyPattern& a = use->apply_patterns.add ();
01012 
01013   a.name = name;
01014   a.use  = use;
01015 
01016   return (&a);
01017 }
01018 
01019 //----------------------------------------------------------
01020 ApplyPattern::ApplyPattern ()
01021 {
01022 }
01023 
01024 //----------------------------------------------------------
01025 ApplyPattern::~ApplyPattern ()
01026 {
01027 }
01028 
01029 //----------------------------------------------------------
01030 void ApplyPattern::show () const
01031 {
01032   cmt_string replacement = "";
01033 
01034   Pattern* p = Pattern::find (name);
01035   if (p == 0) return;
01036 
01037   Use* u = use;
01038   if (u == 0) u = &(Use::current ());
01039 
01040   p->expand (u, replacements, replacement);
01041 
01042   if (replacement != "")
01043     {
01044       replacement.replace_all ("\"", "");
01045       cout << replacement;
01046     }
01047 }
01048 
01049 //----------------------------------------------------------
01050 void ApplyPattern::apply () const
01051 {
01052   if (CmtSystem::testenv ("CMTTESTPATTERN"))
01053     {
01054       cout << "ApplyPattern::apply> " << name << endl;
01055     }
01056 
01057   Pattern* p = Pattern::find (name);
01058   if (p == 0) 
01059     {
01060       if (CmtSystem::testenv ("CMTTESTPATTERN"))
01061         {
01062           cout << "ApplyPattern::apply> " << name << " not found" << endl;
01063         }
01064 
01065       return;
01066     }
01067 
01068   if (p->global) return;
01069   
01070   Use* u = use;
01071   if (u == 0) u = &(Use::current ());
01072 
01073   p->apply (u, replacements);
01074 }
01075 
01076 
01077 
01078 //----------------------------------------------------------
01079 /*                                                          */
01080 /*  Operations on IgnorePatterns                            */
01081 /*                                                          */
01082 //----------------------------------------------------------
01083 
01084 //----------------------------------------------------------
01085 void IgnorePattern::action (const CmtSystem::cmt_string_vector& words, Use* use)
01086 {
01087     //
01088     // Expected syntax is
01089     //
01090     // ignore_pattern 
01091     //
01092 
01093   if (words.size () < 2) return;
01094 
01095   if (use == 0) use = &(Use::current());
01096 
01097   cmt_string& name = words[1];
01098 
01099   add (name, use);
01100 }
01101 
01102 //----------------------------------------------------------
01103 IgnorePattern* IgnorePattern::find (const cmt_string& name, Use* use)
01104 {
01105   int ignore_pattern_index;
01106 
01107   if (use == 0) use = &(Use::current());
01108 
01109   if (use->ignore_patterns.size () == 0) return (0);
01110 
01111   for (ignore_pattern_index = 0;
01112        ignore_pattern_index < use->ignore_patterns.size ();
01113        ignore_pattern_index++)
01114     {
01115       IgnorePattern& ignore_pattern = use->ignore_patterns[ignore_pattern_index];
01116 
01117       if (ignore_pattern.name == name)
01118         {
01119           return (&ignore_pattern);
01120         }
01121     }
01122 
01123   return (0);
01124 }
01125 
01126 //----------------------------------------------------------
01127 void IgnorePattern::add (const cmt_string& name, Use* use)
01128 {
01129   IgnorePattern* ignore_pattern;
01130 
01131   ignore_pattern = find (name, use);
01132 
01133   if (ignore_pattern == 0)
01134     {
01135       IgnorePattern& a = use->ignore_patterns.add ();
01136 
01137       a.name = name;
01138       a.use  = use;
01139     }
01140 }
01141 
01142 //----------------------------------------------------------
01143 IgnorePattern::IgnorePattern ()
01144 {
01145 }
01146 
01147 //----------------------------------------------------------
01148 IgnorePattern::~IgnorePattern ()
01149 {
01150 }
01151 
01152 //----------------------------------------------------------
01153 void IgnorePattern::show () const
01154 {
01155 }

Generated on Mon May 2 10:25:05 2005 for CMT by 1.3.5