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

cmt_fragment.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_fragment.h"
00013 #include "cmt_use.h"
00014 #include "cmt_symbol.h"
00015 #include "cmt_system.h"
00016 #include "cmt_database.h"
00017 
00018 /*----------------------------------------------------------*/
00019 /*                                                          */
00020 /*  Operations on Variables                                 */
00021 /*                                                          */
00022 /*----------------------------------------------------------*/
00023 
00024 //----------------------------------------------------------
00025 Variable* Variable::find (VariableVector& vector, 
00026                           const cmt_string& name)
00027 {
00028   for (int i = 0; i < vector.size (); i++)
00029     {
00030       Variable& v = vector[i];
00031 
00032       if (v.name == name) return (&v);
00033     }
00034 
00035   return (0);
00036 }
00037 
00038 //----------------------------------------------------------
00039 Variable::Variable ()
00040 {
00041 }
00042 
00043 //----------------------------------------------------------
00044 Variable::Variable (const cmt_string& n) : name (n)
00045 {
00046   m_macro_braces = "${";
00047   m_macro_braces += name;
00048   m_macro_braces += "}";
00049 
00050   m_macro_pars = "$(";
00051   m_macro_pars += name;
00052   m_macro_pars += ")";
00053 }
00054 
00055 //----------------------------------------------------------
00056 const cmt_string& Variable::macro_braces () const
00057 {
00058   return (m_macro_braces);
00059 }
00060 
00061 //----------------------------------------------------------
00062 const cmt_string& Variable::macro_pars () const
00063 {
00064   return (m_macro_pars);
00065 }
00066 
00067 //----------------------------------------------------------
00068 void Variable::set (const cmt_string& new_name,
00069                     const cmt_string& new_value)
00070 {
00071   name = new_name;
00072   value = new_value;
00073 
00074   m_macro_braces = "${";
00075   m_macro_braces += name;
00076   m_macro_braces += "}";
00077 
00078   m_macro_pars = "$(";
00079   m_macro_pars += name;
00080   m_macro_pars += ")";
00081 }
00082 
00083 //----------------------------------------------------------
00084 Variable& Variable::operator = (const Variable& other)
00085 {
00086   value = other.value;
00087   return (*this);
00088 }
00089 
00090 //----------------------------------------------------------
00091 Variable& Variable::operator = (const cmt_string& v)
00092 {
00093   value = v;
00094   return (*this);
00095 }
00096 
00097 //----------------------------------------------------------
00098 void Variable::operator += (const cmt_string& v)
00099 {
00100   value += v;
00101 }
00102 
00103 //----------------------------------------------------------
00104 cmt_string Variable::operator + (const cmt_string& v) const
00105 {
00106   return (value + v);
00107 }
00108 
00109 //----------------------------------------------------------
00110 Variable::operator const cmt_string& () const
00111 {
00112   return (value);
00113 }
00114 
00115 //----------------------------------------------------------
00116 bool Variable::operator == (const cmt_string& v) const
00117 {
00118   return ((value == v));
00119 }
00120 
00121 //----------------------------------------------------------
00122 bool Variable::operator != (const cmt_string& v) const
00123 {
00124   return ((value != v));
00125 }
00126 
00127 /*----------------------------------------------------------*/
00128 /*                                                          */
00129 /*  Operations on Fragments                                 */
00130 /*                                                          */
00131 /*----------------------------------------------------------*/
00132 
00133 /*----------------------------------------------------------*/
00134 void Fragment::show (const cmt_string& name)
00135 {
00136   Fragment* fragment = Fragment::find (name);
00137   if (fragment == 0)
00138     {
00139       cout << "Fragment " << name << " not found" << endl;
00140     }
00141   else
00142     {
00143       fragment->print ();
00144     }
00145 }
00146 
00147 /*----------------------------------------------------------*/
00148 void Fragment::show_all ()
00149 {
00150   static FragmentVector& Fragments = fragments ();
00151 
00152   int number;
00153 
00154   for (number = 0; number < Fragments.size (); number++)
00155     {
00156       Fragment& fragment = Fragments[number];
00157 
00158       fragment.print ();
00159     }
00160 }
00161 
00162 class fragment_action_iterator
00163 {
00164 public:
00165 
00166   fragment_action_iterator (Use* use) :
00167     m_need_dependencies (false),
00168     m_state (need_name),
00169     m_use (use)
00170   {
00171   }
00172 
00173   void add_word (const cmt_string& w)
00174   {
00175     switch (m_state)
00176       {
00177       case need_name:
00178         m_name = w;
00179         m_state = need_options;
00180         break;
00181       case need_options:
00182         if (w.find ("-suffix=") != cmt_string::npos)
00183           {
00184             m_suffix = w;
00185             m_suffix.replace ("-suffix=", "");
00186           }
00187         else if (w.find ("-dependencies") != cmt_string::npos)
00188           {
00189             m_need_dependencies = true;
00190           }
00191         else if (w.find ("-header=") != cmt_string::npos)
00192           {
00193             m_header = w;
00194             m_header.replace ("-header=", "");
00195 
00196             if (Fragment::find (m_header) == 0)
00197               {
00198                 Fragment::add (m_header, "", "", "", false, m_use);
00199               }
00200           }
00201         else if (w.find ("-trailer=") != cmt_string::npos)
00202           {
00203             m_trailer = w;
00204             m_trailer.replace ("-trailer=", "");
00205             
00206             if (Fragment::find (m_trailer) == 0)
00207               {
00208                 Fragment::add (m_trailer, "", "", "", false, m_use);
00209               }
00210           }
00211         break;
00212       }
00213   }
00214 
00215   void commit ()
00216   {
00217     Fragment::add (m_name, m_suffix, m_header, m_trailer, m_need_dependencies, m_use);
00218   }
00219 
00220 private:
00221 
00222   enum
00223     {
00224       need_name,
00225       need_options
00226     } m_state;
00227 
00228   cmt_string m_name;
00229   cmt_string m_suffix;
00230   cmt_string m_header;
00231   cmt_string m_trailer;
00232   bool m_need_dependencies;
00233   Use* m_use;
00234 };
00235 
00236 
00237 /*----------------------------------------------------------*/
00238 void Fragment::action (const CmtSystem::cmt_string_vector& words,
00239                        Use* use)
00240 {
00241   if ((Cmt::get_current_access () == UserMode) &&
00242       (use->get_current_scope () == ScopePrivate)) return;
00243 
00244   if (words.size () <= 1) return;
00245 
00246   fragment_action_iterator it (use);
00247 
00248   for (int i = 1; i < words.size (); i++)
00249     {
00250       const cmt_string& w = words[i];
00251       cmt_string ew = w;
00252 
00253       Symbol::expand (ew);
00254       if (ew != w)
00255         {
00256           CmtSystem::cmt_string_vector ws;
00257 
00258           CmtSystem::split (ew, " ", ws);
00259 
00260           for (int j = 0; j < ws.size (); ++j)
00261             {
00262               const cmt_string& ww = ws[j];
00263               it.add_word (ww);
00264             }
00265         }
00266       else
00267         {
00268           it.add_word (ew);
00269         }
00270     }
00271 
00272   it.commit ();
00273 }
00274 
00275 /*----------------------------------------------------------*/
00276 Fragment* Fragment::find (const cmt_string& name)
00277 {
00278   static FragmentVector& Fragments = fragments ();
00279 
00280   int fragment_index;
00281 
00282   if (Fragments.size () == 0) return (0);
00283 
00284   for (fragment_index = 0;
00285        fragment_index < Fragments.size ();
00286        fragment_index++)
00287     {
00288       Fragment& fragment = Fragments[fragment_index];
00289 
00290       if (fragment.name == name)
00291         {
00292           return (&fragment);
00293         }
00294     }
00295 
00296   return (0);
00297 }
00298 
00299 /*----------------------------------------------------------*/
00300 void Fragment::add (const cmt_string& name,
00301                     const cmt_string& suffix,
00302                     const cmt_string& header,
00303                     const cmt_string& trailer,
00304                     bool need_dependencies,
00305                     Use* use)
00306 {
00307   static FragmentVector& Fragments = fragments ();
00308 
00309   {
00310     Fragment* fragment;
00311 
00312     if (name == "") return;
00313 
00314     fragment = find (name);
00315     if (fragment != 0)
00316       {
00317         if (suffix != "")
00318           {
00319             fragment->suffix = suffix;
00320           }
00321 
00322         if (header != "")
00323           {
00324             fragment->header = header;
00325           }
00326 
00327         if (trailer != "")
00328           {
00329             fragment->trailer = trailer;
00330           }
00331 
00332         fragment->need_dependencies = need_dependencies;
00333 
00334         fragment->use = use;
00335         return;
00336       }
00337   }
00338 
00339   Fragment& fragment = Fragments.add ();
00340 
00341   fragment.name              = name;
00342   fragment.suffix            = suffix;
00343   fragment.header            = header;
00344   fragment.trailer           = trailer;
00345   fragment.need_dependencies = need_dependencies;
00346   fragment.use               = use;
00347 }
00348 
00349 /*----------------------------------------------------------*/
00350 void Fragment::clear_all ()
00351 {
00352   static FragmentVector& Fragments = fragments ();
00353 
00354   for (int i = 0; i < Fragments.size (); i++)
00355     {
00356       Fragment& f = Fragments[i];
00357       f.clear ();
00358     }
00359 
00360   Fragments.clear ();
00361 }
00362 
00363 /*----------------------------------------------------------*/
00364 Fragment::FragmentVector& Fragment::fragments ()
00365 {
00366   static Database& db = Database::instance ();
00367   static FragmentVector& Fragments = db.fragments ();
00368 
00369   return (Fragments);
00370 }
00371 
00372 /*----------------------------------------------------------*/
00373 Fragment::Fragment ()
00374 {
00375   use = 0;
00376 }
00377 
00378 /*----------------------------------------------------------*/
00379 Fragment::Fragment (const cmt_string& fragment_name)
00380 {
00381   name = fragment_name;
00382   use = 0;
00383   path = "";
00384 }
00385 
00386 /*----------------------------------------------------------*/
00387 Fragment::~Fragment ()
00388 {
00389   use = 0;
00390 }
00391 
00392 /*----------------------------------------------------------*/
00393 void Fragment::clear ()
00394 {
00395   name    = "";
00396   suffix  = "";
00397   header  = "";
00398   trailer = "";
00399   need_dependencies = false;
00400   path = "";
00401   use  = 0;
00402 }
00403 
00404 /*----------------------------------------------------------*/
00405 int Fragment::print ()
00406 {
00407   int result = 1;
00408 
00409   if (name == "") return (0);
00410   
00411   locate ();
00412 
00413   if (use == 0)
00414     {
00415       Use& u = Use::current();
00416       use = &u;
00417     }
00418   
00419   cmt_string the_path = path;
00420 
00421   use->reduce_path (the_path);
00422 
00423   cout << the_path;
00424 
00425   if (suffix != "")
00426     {
00427       cout << "->" << suffix;
00428     }
00429 
00430   cout << endl;
00431 
00432   return (result);
00433 }
00434 
00435 /*----------------------------------------------------------*/
00436 bool Fragment::locate ()
00437 {
00438   cmt_string root_path;
00439 
00440   if (use == 0)
00441     {
00442       // Assume CMT
00443       use = Use::find ("CMT");
00444     }
00445 
00446   use->get_full_path (root_path);
00447 
00448   if (path != "") return (true);
00449 
00450   // First try /fragments/ or /fragments/nmake/
00451 
00452   path = root_path;
00453   path += CmtSystem::file_separator ();
00454   path += "fragments";
00455   path += CmtSystem::file_separator ();
00456   
00457   if (Cmt::build_nmake ())
00458     {
00459       path += "nmake";
00460       path += CmtSystem::file_separator ();
00461     }
00462   
00463   path += name;
00464 
00465   if (CmtSystem::test_file (path)) return (true);
00466 
00467   // Then try /fragments/ for both Win and Unix
00468 
00469   path = root_path;
00470   path += CmtSystem::file_separator ();
00471   path += "fragments";
00472   path += CmtSystem::file_separator ();
00473   path += name;
00474 
00475   if (CmtSystem::test_file (path)) return (true);
00476 
00477   // Then try /cmt/fragments/ or /cmt/fragments/nmake/
00478 
00479   root_path += CmtSystem::file_separator ();
00480 
00481   if (use->style == mgr_style) root_path += "mgr";
00482   else root_path += "cmt";
00483   
00484   root_path += CmtSystem::file_separator ();
00485   root_path += "fragments";
00486   root_path += CmtSystem::file_separator ();
00487   
00488   path = root_path;
00489   
00490   if (Cmt::build_nmake ())
00491     {
00492       path += "nmake";
00493       path += CmtSystem::file_separator ();
00494     }
00495   
00496   path += name;
00497   
00498   if (CmtSystem::test_file (path)) return (true);
00499 
00500   // Then try /cmt/fragments/ for both Win and Unix
00501 
00502   path = root_path;
00503   
00504   path += name;
00505 
00506   if (CmtSystem::test_file (path)) return (true);
00507 
00508   return (false);
00509 }
00510 
00511 //--------------------------------------------------
00512 bool Fragment::copy (FILE* out,
00513                      const cmt_string& name,
00514                      int variables, ...)
00515 {
00516   va_list ids;
00517 
00518   Fragment* fragment = Fragment::find (name);
00519   if (fragment == 0) return (false);
00520 
00521   va_start (ids, variables);
00522   bool result = fragment->copy (out, variables, ids);
00523   va_end (ids);
00524 
00525   return (result);
00526 }
00527 
00528 //--------------------------------------------------
00529 bool Fragment::copy (cmt_string& out,
00530                      const cmt_string& name,
00531                      int variables, ...)
00532 {
00533   va_list ids;
00534 
00535   Fragment* fragment = Fragment::find (name);
00536   if (fragment == 0) return (false);
00537 
00538   va_start (ids, variables);
00539   bool result = fragment->copy (out, variables, ids);
00540   va_end (ids);
00541 
00542   return (result);
00543 }
00544 
00545 //--------------------------------------------------
00546 bool Fragment::copy (FILE* out, int variables, ...)
00547 {
00548   va_list ids;
00549 
00550   va_start (ids, variables);
00551   bool result = copy (out, variables, ids);
00552   va_end (ids);
00553 
00554   return (result);
00555 }
00556 
00557 //--------------------------------------------------
00558 bool Fragment::copy (cmt_string& out, int variables, ...)
00559 {
00560   va_list ids;
00561 
00562   va_start (ids, variables);
00563   bool result = copy (out, variables, ids);
00564   va_end (ids);
00565 
00566   return (result);
00567 }
00568 
00569 //--------------------------------------------------
00570 bool Fragment::copy (FILE* out, int variables, va_list ids)
00571 {
00572   static cmt_string cline;
00573 
00574   bool result = copy (cline, variables, ids);
00575   if (result)
00576     {
00577       cline.write (out);
00578       return (true);
00579     }
00580   else
00581     {
00582       return (false);
00583     }
00584 }
00585 
00586 //--------------------------------------------------
00587 bool Fragment::copy (cmt_string& out, int variables, va_list ids)
00588 {
00589   int i;
00590 
00591   if (!locate ()) return (false);
00592 
00593   out.read (path);
00594 
00595   Variable* var = 0;
00596   for (i = 0; i < variables; i++)
00597     {
00598       var = va_arg (ids, Variable*);
00599       out.replace_all (var->macro_braces (), var->value);
00600       out.replace_all (var->macro_pars (), var->value);
00601     }
00602 
00603   return (true);
00604 }
00605 
00606 //--------------------------------------------------
00607 bool Fragment::wincopy (FILE* out, int variables, va_list ids)
00608 {
00609   static cmt_string cline;
00610 
00611   bool result = wincopy (cline, variables, ids);
00612 
00613   if (result)
00614     {
00615       cline.write (out);
00616       return (true);
00617     }
00618   else
00619     {
00620       return (false);
00621     }
00622 }
00623 
00624 //--------------------------------------------------
00625 bool Fragment::wincopy (cmt_string& out, int variables, va_list ids)
00626 {
00627   int i;
00628 
00629   if (!locate ()) return (false);
00630 
00631   out.read (path);
00632 
00633   Variable* var = 0;
00634   for (i = 0; i < variables; i++)
00635     {
00636       var = va_arg (ids, Variable*);
00637       out.replace_all (var->macro_braces (), var->value);
00638       out.replace_all (var->macro_pars (), var->value);
00639     }
00640 
00641   cmt_string pattern;
00642   cmt_string macro_name;
00643   char end_pattern;
00644 
00645   int start = 0;
00646 
00647   for (;;)
00648     {
00649       //
00650       // Try and substitute all ${xxx} or $(xxx) patterns
00651       // using symbol values.
00652       //
00653       int par;
00654       int brace;
00655       int begin;
00656 
00657       par = out.find (start, "$(");
00658       brace = out.find (start, "${");
00659 
00660       if (par == cmt_string::npos)
00661         {
00662           // No parentheses. Look for brace
00663           if (brace == cmt_string::npos)
00664             {
00665               // No pattern, finish the scan.
00666               break;
00667             }
00668 
00669           // Brace found
00670           end_pattern = '}';
00671           begin = brace;
00672         }
00673       else
00674         {
00675           // Parenthese found. Look for closest from {par, brace}
00676           if ((brace == cmt_string::npos) ||
00677               (brace > par))
00678             {
00679               end_pattern = ')';
00680               begin = par;
00681             }
00682           else
00683             {
00684               end_pattern = '}';
00685               begin = brace;
00686             }
00687         }
00688 
00689       // Skip the pattern intro.
00690       start = begin + 2;
00691 
00692       int end;
00693       end = out.find (start, end_pattern);
00694       if (end == cmt_string::npos)
00695         {
00696           // The pattern is a fake one (no ending!)
00697           break;
00698         }
00699 
00700       // This should never happen...
00701       if (end < begin) break;
00702 
00703       // Extract the complete pattern
00704       out.substr (begin, end - begin + 1, pattern);
00705 
00706       // Then only the macro name
00707       out.substr (begin + 2, end - begin - 2, macro_name);
00708 
00709       if (macro_name == "CFG")
00710         {
00711           // This is a Windows reserved keyword...
00712           start = end + 1;
00713         }
00714       else
00715         {
00716           Symbol* macro = Symbol::find (macro_name);
00717           if (macro != 0)
00718             {
00719               // Macro found
00720               cmt_string value = macro->resolve_macro_value ();
00721               //cout << "resolve_macro_value2> value=" << value << endl;
00722               out.replace_all (pattern, value);
00723 
00724               // The substitution will restart from the same place
00725               // allowing for recursive replacements
00726               start = begin;
00727             }
00728           else
00729             {
00730               // Macro not found. Look for env. variable
00731               cmt_string value = CmtSystem::getenv (macro_name);
00732               //cout << "resolve_macro_value3> " << macro_name << "=" << value << endl;
00733               out.replace_all (pattern, value);
00734 
00735               // The substitution will restart from the same place
00736               // allowing for recursive replacements
00737               start = begin;
00738             }
00739         }
00740     }
00741 
00742   // Uniformly install CR-LF doublets.
00743 
00744   out.replace_all ("\r\n", "\n");
00745   out.replace_all ("\n", "\r\n");
00746 
00747   return (true);
00748 }
00749 
00750 
00751 
00752 
00753 
00754 
00755 
00756 
00757 //--------------------------------------------------
00758 bool Fragment::copy (FILE* out,
00759                      const cmt_string& name,
00760                      const Variable::VariableVector& vector, 
00761                      int variables, ...)
00762 {
00763   va_list ids;
00764 
00765   Fragment* fragment = Fragment::find (name);
00766   if (fragment == 0) return (false);
00767 
00768   va_start (ids, variables);
00769   bool result = fragment->copy (out, vector, variables, ids);
00770   va_end (ids);
00771 
00772   return (result);
00773 }
00774 
00775 //--------------------------------------------------
00776 bool Fragment::copy (cmt_string& out,
00777                      const cmt_string& name,
00778                      const Variable::VariableVector& vector, 
00779                      int variables, ...)
00780 {
00781   va_list ids;
00782 
00783   Fragment* fragment = Fragment::find (name);
00784   if (fragment == 0) return (false);
00785 
00786   va_start (ids, variables);
00787   bool result = fragment->copy (out, vector, variables, ids);
00788   va_end (ids);
00789 
00790   return (result);
00791 }
00792 
00793 //--------------------------------------------------
00794 bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
00795 {
00796   va_list ids;
00797 
00798   va_start (ids, variables);
00799   bool result = copy (out, vector, variables, ids);
00800   va_end (ids);
00801 
00802   return (result);
00803 }
00804 
00805 //--------------------------------------------------
00806 bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
00807 {
00808   va_list ids;
00809 
00810   va_start (ids, variables);
00811   bool result = copy (out, vector, variables, ids);
00812   va_end (ids);
00813 
00814   return (result);
00815 }
00816 
00817 //--------------------------------------------------
00818 bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
00819 {
00820   static cmt_string cline;
00821 
00822   bool result = copy (cline, vector, variables, ids);
00823   if (result)
00824     {
00825       cline.write (out);
00826       return (true);
00827     }
00828   else
00829     {
00830       return (false);
00831     }
00832 }
00833 
00834 //--------------------------------------------------
00835 bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, va_list ids)
00836 {
00837   int i;
00838 
00839   if (!locate ()) return (false);
00840 
00841   out.read (path);
00842 
00843   Variable* var = 0;
00844 
00845   for (i = 0; i < vector.size (); i++)
00846     {
00847       var = &(vector[i]);
00848       out.replace_all (var->macro_braces (), var->value);
00849       out.replace_all (var->macro_pars (), var->value);
00850     }
00851 
00852   for (i = 0; i < variables; i++)
00853     {
00854       var = va_arg (ids, Variable*);
00855       out.replace_all (var->macro_braces (), var->value);
00856       out.replace_all (var->macro_pars (), var->value);
00857     }
00858 
00859   return (true);
00860 }
00861 
00862 //--------------------------------------------------
00863 bool Fragment::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
00864 {
00865   static cmt_string cline;
00866 
00867   bool result = wincopy (cline, vector, variables, ids);
00868   if (result)
00869     {
00870       cline.write (out);
00871       return (true);
00872     }
00873   else
00874     {
00875       return (false);
00876     }
00877 }
00878 
00879 //--------------------------------------------------
00880 bool Fragment::wincopy (cmt_string& out, const Variable::VariableVector& vector, 
00881                         int variables, va_list ids)
00882 {
00883   int i;
00884 
00885   if (!locate ()) return (false);
00886 
00887   out.read (path);
00888 
00889   Variable* var = 0;
00890 
00891   for (i = 0; i < vector.size (); i++)
00892     {
00893       var = &(vector[i]);
00894       out.replace_all (var->macro_braces (), var->value);
00895       out.replace_all (var->macro_pars (), var->value);
00896     }
00897 
00898   for (i = 0; i < variables; i++)
00899     {
00900       var = va_arg (ids, Variable*);
00901       out.replace_all (var->macro_braces (), var->value);
00902       out.replace_all (var->macro_pars (), var->value);
00903     }
00904 
00905   cmt_string pattern;
00906   cmt_string macro_name;
00907   char end_pattern;
00908 
00909   int start = 0;
00910 
00911   for (;;)
00912     {
00913       //
00914       // Try and substitute all ${xxx} or $(xxx) patterns
00915       // using symbol values.
00916       //
00917       int par;
00918       int brace;
00919       int begin;
00920 
00921       par = out.find (start, "$(");
00922       brace = out.find (start, "${");
00923 
00924       if (par == cmt_string::npos)
00925         {
00926           // No parentheses. Look for brace
00927           if (brace == cmt_string::npos)
00928             {
00929               // No pattern, finish the scan.
00930               break;
00931             }
00932 
00933           // Brace found
00934           end_pattern = '}';
00935           begin = brace;
00936         }
00937       else
00938         {
00939           // Parenthese found. Look for closest from {par, brace}
00940           if ((brace == cmt_string::npos) ||
00941               (brace > par))
00942             {
00943               end_pattern = ')';
00944               begin = par;
00945             }
00946           else
00947             {
00948               end_pattern = '}';
00949               begin = brace;
00950             }
00951         }
00952 
00953       // Skip the pattern intro.
00954       start = begin + 2;
00955 
00956       int end;
00957       end = out.find (start, end_pattern);
00958       if (end == cmt_string::npos)
00959         {
00960           // The pattern is a fake one (no ending!)
00961           break;
00962         }
00963 
00964       // This should never happen...
00965       if (end < begin) break;
00966 
00967       // Extract the complete pattern
00968       out.substr (begin, end - begin + 1, pattern);
00969 
00970       // Then only the macro name
00971       out.substr (begin + 2, end - begin - 2, macro_name);
00972 
00973       if (macro_name == "CFG")
00974         {
00975           // This is a Windows reserved keyword...
00976           start = end + 1;
00977         }
00978       else
00979         {
00980           Symbol* macro = Symbol::find (macro_name);
00981           if (macro != 0)
00982             {
00983               // Macro found
00984               cmt_string value = macro->resolve_macro_value ();
00985               //cout << "resolve_macro_value2> value=" << value << endl;
00986               out.replace_all (pattern, value);
00987 
00988               // The substitution will restart from the same place
00989               // allowing for recursive replacements
00990               start = begin;
00991             }
00992           else
00993             {
00994               // Macro not found. Look for env. variable
00995               cmt_string value = CmtSystem::getenv (macro_name);
00996               //cout << "resolve_macro_value3> " << macro_name << "=" << value << endl;
00997               out.replace_all (pattern, value);
00998 
00999               // The substitution will restart from the same place
01000               // allowing for recursive replacements
01001               start = begin;
01002             }
01003         }
01004     }
01005 
01006   // Uniformly install CR-LF doublets.
01007 
01008   out.replace_all ("\r\n", "\n");
01009   out.replace_all ("\n", "\r\n");
01010 
01011   return (true);
01012 }
01013 
01014 //--------------------------------------------------
01015 FragmentHandle::FragmentHandle ()
01016 {
01017   _fragment = 0;
01018   _initialized = false;
01019 }
01020 
01021 //--------------------------------------------------
01022 FragmentHandle::FragmentHandle (const cmt_string name) : _name(name)
01023 {
01024   _fragment = 0;
01025   _initialized = false;
01026 }
01027 
01028 //--------------------------------------------------
01029 FragmentHandle& FragmentHandle::operator = (const FragmentHandle& other)
01030 {
01031   _name = other._name;
01032   _fragment = 0;
01033   _initialized = false;
01034 
01035   return (*this);
01036 }
01037 
01038 //--------------------------------------------------
01039 void FragmentHandle::reset ()
01040 {
01041   _fragment = 0;
01042   _initialized = false;
01043 }
01044 
01045 //--------------------------------------------------
01046 void FragmentHandle::set (const cmt_string name)
01047 {
01048   _name = name;
01049   _fragment = 0;
01050   _initialized = false;
01051 }
01052 
01053 //--------------------------------------------------
01054 cmt_string& FragmentHandle::name ()
01055 {
01056   static cmt_string null_string;
01057 
01058   if (!setup ()) return (null_string);
01059 
01060   return (_fragment->name);
01061 }
01062 
01063 //--------------------------------------------------
01064 cmt_string& FragmentHandle::suffix ()
01065 {
01066   static cmt_string null_string;
01067 
01068   if (!setup ()) return (null_string);
01069 
01070   return (_fragment->suffix);
01071 }
01072 
01073 //--------------------------------------------------
01074 cmt_string& FragmentHandle::header ()
01075 {
01076   static cmt_string null_string;
01077 
01078   if (!setup ()) return (null_string);
01079 
01080   return (_fragment->header);
01081 }
01082 
01083 //--------------------------------------------------
01084 cmt_string& FragmentHandle::trailer ()
01085 {
01086   static cmt_string null_string;
01087 
01088   if (!setup ()) return (null_string);
01089 
01090   return (_fragment->trailer);
01091 }
01092 
01093 //--------------------------------------------------
01094 bool FragmentHandle::need_dependencies ()
01095 {
01096   if (!setup ()) return (false);
01097 
01098   return (_fragment->need_dependencies);
01099 }
01100 
01101 //--------------------------------------------------
01102 bool FragmentHandle::copy (FILE* out, int variables, ...)
01103 {
01104   if (!setup ()) return (false);
01105 
01106   va_list ids;
01107 
01108   va_start (ids, variables);
01109   bool result = _fragment->copy (out, variables, ids);
01110   va_end (ids);
01111 
01112   if (!result)
01113     {
01114       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01115       _fragment = 0;
01116     }
01117 
01118   return (result);
01119 }
01120 
01121 //--------------------------------------------------
01122 bool FragmentHandle::copy (cmt_string& out, int variables, ...)
01123 {
01124   if (!setup ()) return (false);
01125 
01126   va_list ids;
01127 
01128   va_start (ids, variables);
01129   bool result = _fragment->copy (out, variables, ids);
01130   va_end (ids);
01131 
01132   if (!result)
01133     {
01134       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01135       _fragment = 0;
01136     }
01137 
01138   return (result);
01139 }
01140 
01141 //--------------------------------------------------
01142 bool FragmentHandle::wincopy (FILE* out, int variables, ...)
01143 {
01144   if (!setup ()) return (false);
01145 
01146   va_list ids;
01147 
01148   va_start (ids, variables);
01149   bool result = _fragment->wincopy (out, variables, ids);
01150   va_end (ids);
01151 
01152   if (!result)
01153     {
01154       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01155       _fragment = 0;
01156     }
01157 
01158   return (result);
01159 }
01160 
01161 //--------------------------------------------------
01162 bool FragmentHandle::wincopy (cmt_string& out, int variables, ...)
01163 {
01164   if (!setup ()) return (false);
01165 
01166   va_list ids;
01167 
01168   va_start (ids, variables);
01169   bool result = _fragment->wincopy (out, variables, ids);
01170   va_end (ids);
01171 
01172   if (!result)
01173     {
01174       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01175       _fragment = 0;
01176     }
01177 
01178   return (result);
01179 }
01180 
01181 
01182 
01183 
01184 //--------------------------------------------------
01185 bool FragmentHandle::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
01186 {
01187   if (!setup ()) return (false);
01188 
01189   va_list ids;
01190 
01191   va_start (ids, variables);
01192   bool result = _fragment->copy (out, vector, variables, ids);
01193   va_end (ids);
01194 
01195   if (!result)
01196     {
01197       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01198       _fragment = 0;
01199     }
01200 
01201   return (result);
01202 }
01203 
01204 //--------------------------------------------------
01205 bool FragmentHandle::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
01206 {
01207   if (!setup ()) return (false);
01208 
01209   va_list ids;
01210 
01211   va_start (ids, variables);
01212   bool result = _fragment->copy (out, vector, variables, ids);
01213   va_end (ids);
01214 
01215   if (!result)
01216     {
01217       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01218       _fragment = 0;
01219     }
01220 
01221   return (result);
01222 }
01223 
01224 //--------------------------------------------------
01225 bool FragmentHandle::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
01226 {
01227   if (!setup ()) return (false);
01228 
01229   va_list ids;
01230 
01231   va_start (ids, variables);
01232   bool result = _fragment->wincopy (out, vector, variables, ids);
01233   va_end (ids);
01234 
01235   if (!result)
01236     {
01237       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01238       _fragment = 0;
01239     }
01240 
01241   return (result);
01242 }
01243 
01244 //--------------------------------------------------
01245 bool FragmentHandle::wincopy (cmt_string& out, 
01246                               const Variable::VariableVector& vector, 
01247                               int variables, ...)
01248 {
01249   if (!setup ()) return (false);
01250 
01251   va_list ids;
01252 
01253   va_start (ids, variables);
01254   bool result = _fragment->wincopy (out, vector, variables, ids);
01255   va_end (ids);
01256 
01257   if (!result)
01258     {
01259       cerr << "#CMT> Fragment " << _name << " not found" << endl;
01260       _fragment = 0;
01261     }
01262 
01263   return (result);
01264 }
01265 
01266 //--------------------------------------------------
01267 bool FragmentHandle::setup ()
01268 {
01269   if (!_initialized)
01270     {
01271       _initialized = true;
01272 
01273       _fragment = Fragment::find (_name);
01274       if (_fragment == 0)
01275         {
01276           cerr << "#CMT> Fragment " << _name << " not found" << endl;
01277         }
01278     }
01279 
01280   if (_fragment == 0)
01281     {
01282       return (false);
01283     }
01284   else
01285     {
01286       return (true);
01287     }
01288 }

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