Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cmt_parser.cxx

Go to the documentation of this file.
00001 
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <ctype.h>
00006 
00007 //----------------------------------------------------------
00008 
00009 #include "cmt_parser.h"
00010 #include "cmt_version.h"
00011 
00012 #include "cmt_database.h"
00013 #include "cmt_include.h"
00014 #include "cmt_script.h"
00015 #include "cmt_generator.h"
00016 #include "cmt_system.h"
00017 #include "cmt.h"
00018 #include "cmt_error.h"
00019 #include "cmt_cvs.h"
00020 #include "cmt_lock.h"
00021 #include "cmt_triggers.h"
00022 #include "cmt_model.h"
00023 #include "cmt_awk.h"
00024 
00025 //----------------------------------------------------------
00026 //
00027 //  Static object definitions for the Cmt class.
00028 //
00029 
00030 ActionType Cmt::m_action;
00031 bool Cmt::m_build_nmake;
00032 cmt_string Cmt::m_cmt_config;
00033 CmtSystem::cmt_string_vector Cmt::m_cmt_path;
00034 CmtSystem::cmt_string_vector Cmt::m_cmt_path_pwds;
00035 CmtSystem::cmt_string_vector Cmt::m_cmt_path_sources;
00036 cmt_string Cmt::m_cmt_root;
00037 cmt_string Cmt::m_cmt_home;
00038 cmt_string Cmt::m_cmt_user_context;
00039 cmt_string Cmt::m_cmt_site;
00040 cmt_string Cmt::m_cmt_version;
00041 int Cmt::m_current_build_strategy = DefaultBuildStrategy;
00042 
00043 cmt_string Cmt::m_current_dir;
00044 cmt_string Cmt::m_current_package;
00045 cmt_string Cmt::m_current_config;
00046 cmt_string Cmt::m_current_path;
00047 cmt_string Cmt::m_current_prefix;
00048 
00049 AccessMode Cmt::m_current_access = UserMode;
00050 VersionStrategy Cmt::m_current_strategy = BestFit;
00051 CmtDirStyle Cmt::m_current_style = cmt_style;
00052 
00053 cmt_string Cmt::m_current_tag;
00054 cmt_string Cmt::m_current_target;
00055 cmt_string Cmt::m_current_version;
00056 
00057 cmt_string Cmt::m_extra_tags;
00058 
00059 cmt_string Cmt::m_configure_error;
00060 
00061 bool Cmt::m_debug;
00062 
00063 cmt_string Cmt::m_default_path;
00064 cmt_string Cmt::m_filtered_text;
00065 bool Cmt::m_quiet;
00066 bool Cmt::m_recursive;
00067 ScopeType Cmt::m_scope;
00068 bool Cmt::m_simulation;
00069 bool Cmt::m_standard_macros_done;
00070 //----------------------------------------------------------
00071 
00072 
00073 //----------------------------------------------------------
00074 //
00075 //   Utility classes
00076 //
00077 //----------------------------------------------------------
00078 
00079 
00080 
00085 class FileScanner
00086 {
00087 public:
00088   class actor
00089   {
00090   public:
00091     virtual void run (const cmt_string& package,
00092                       const cmt_string& version,
00093                       const cmt_string& path)
00094     {
00095     }
00096   };
00097 
00098   FileScanner ();
00099   bool scan_path (const cmt_string& path, actor& a);
00100   bool scan_package (const cmt_string& path, const cmt_string& package);
00101 
00102 private:
00103   void scan_path (const cmt_string& path, int level, actor& a);
00104 
00105   bool _running;
00106   int _level;
00107 };
00108 
00109 
00113 class PackageViewer : public FileScanner::actor
00114 {
00115 public:
00116   void run (const cmt_string& package,
00117             const cmt_string& version,
00118             const cmt_string& path);
00119 };
00120 
00121 
00125 class PackageSelector : public FileScanner::actor
00126 {
00127 public:
00128   PackageSelector (CmtSystem::cmt_string_vector& uses);
00129   void run (const cmt_string& package,
00130             const cmt_string& version,
00131             const cmt_string& path);
00132 private:
00133   CmtSystem::cmt_string_vector& m_uses;
00134 };
00135 
00136 
00137 
00141 class PackageCollector : public FileScanner::actor
00142 {
00143 public:
00144   PackageCollector (const cmt_string& package,
00145                     const cmt_string& version);
00146   void run (const cmt_string& package,
00147             const cmt_string& version,
00148             const cmt_string& path);
00149   int count ();
00150 
00151 private:
00152   const cmt_string& m_package;
00153   const cmt_string& m_version;
00154   int m_count;
00155 };
00156 
00157 
00158 //----------------------------------------------------------
00159 FileScanner::FileScanner ()
00160 {
00161   _running = false;
00162   _level = 0;
00163 }
00164 
00165 //----------------------------------------------------------
00166 bool FileScanner::scan_path (const cmt_string& path, actor& a)
00167 {
00168   if (_running) return (false);
00169 
00170   _level = 0;
00171   _running = true;
00172   scan_path (path, 0, a);
00173   _running = false;
00174   _level = 0;
00175 
00176   return (true);
00177 }
00178 
00179 //----------------------------------------------------------
00180 void FileScanner::scan_path (const cmt_string& path, int level, actor& a)
00181 {
00182   //
00183   // Only do something if it is a directory.
00184   //
00185 
00186   if (!CmtSystem::test_directory (path)) return;
00187 
00188   CmtSystem::cmt_string_vector list;
00189 
00190   CmtSystem::scan_dir (path, list);
00191 
00192   if (list.size () == 0) return;
00193 
00194   _level++;
00195 
00196   // Will be set if at least one directory is a version directory
00197   bool has_package = false;
00198 
00199   cmt_string pack;
00200   CmtSystem::basename (path, pack);
00201 
00202   int i;
00203   for (i = 0; i < list.size (); i++)
00204     {
00205       const cmt_string& name = list[i];
00206 
00207       //cout << "scan> level=" << level << " name=" << name;
00208 
00209       cmt_string version;
00210       CmtSystem::basename (name, version);
00211 
00212       //
00213       //  All entries at this level may be "legal" version directories.
00214       //
00215       //  So we go down but no more then one level deep.
00216       //  The next level we request that the entry is a version
00217       //  and that there is a mgr/requirements file below.
00218       //
00219 
00220       if (level == 0)
00221         {
00222           //cout << " -> down" << endl;
00223           scan_path (name, level + 1, a);
00224         }
00225       else if (CmtSystem::is_version_directory (version))
00226         {
00227           cmt_string req;
00228 
00229           req = name;
00230           req += CmtSystem::file_separator ();
00231           req += "cmt";
00232           req += CmtSystem::file_separator ();
00233           req += "requirements";
00234 
00235           if (CmtSystem::test_file (req))
00236             {
00237               //cout << " -> cmt" << endl;
00238 
00239               a.run (pack, version, path);
00240 
00241               has_package = true;
00242             }
00243           else
00244             {
00245               //cout << " -> no cmt" << endl;
00246               req = name;
00247               req += CmtSystem::file_separator ();
00248               req += "mgr";
00249               req += CmtSystem::file_separator ();
00250               req += "requirements";
00251 
00252               if (CmtSystem::test_file (req))
00253                 {
00254                   //cout << " -> cmt" << endl;
00255 
00256                   a.run (pack, version, path);
00257 
00258                   has_package = true;
00259                 }
00260               else
00261                 {
00262                   //cout << " -> no mgr" << endl;
00263                 }
00264             }
00265         }
00266       else
00267         {
00268           //cout << " -> stop" << endl;
00269         }
00270     }
00271 
00272   if (has_package)
00273     {
00274       //
00275       // At least one version was found here.
00276       //
00277       scan_path (path, 0, a);
00278     }
00279 
00280   _level--;
00281 }
00282 
00283 
00284 //----------------------------------------------------------
00285 bool FileScanner::scan_package (const cmt_string& path,
00286                                 const cmt_string& package)
00287 {
00288   //
00289   // Only do something if it is a directory.
00290   //
00291 
00292   if (!CmtSystem::test_directory (path)) return (false);
00293 
00294   cmt_string pattern = path;
00295   pattern += CmtSystem::file_separator ();
00296   pattern += package;
00297 
00298   if (!CmtSystem::test_directory (pattern)) return (false);
00299 
00300   CmtSystem::cmt_string_vector list;
00301 
00302   CmtSystem::scan_dir (pattern, list);
00303 
00304   if (list.size () == 0) return (false);
00305 
00306   bool result = false;
00307 
00308   int i;
00309   for (i = 0; i < list.size (); i++)
00310     {
00311       const cmt_string& name = list[i];
00312 
00313       cmt_string version;
00314       CmtSystem::basename (name, version);
00315 
00316       if (CmtSystem::is_version_directory (version))
00317         {
00318           cmt_string req;
00319 
00320           req = name;
00321           req += CmtSystem::file_separator ();
00322           req += "cmt";
00323           req += CmtSystem::file_separator ();
00324           req += "requirements";
00325 
00326           if (CmtSystem::test_file (req))
00327             {
00328               //cout << " -> cmt" << endl;
00329 
00330               cout << package << " " << version << " " << path << endl;
00331 
00332               result = true;
00333             }
00334           else
00335             {
00336               //cout << " -> no cmt" << endl;
00337 
00338               req = name;
00339               req += CmtSystem::file_separator ();
00340               req += "mgr";
00341               req += CmtSystem::file_separator ();
00342               req += "requirements";
00343 
00344               if (CmtSystem::test_file (req))
00345                 {
00346                   //cout << " -> mgr" << endl;
00347 
00348                   cout << package << " " << version << " " << path << endl;
00349 
00350                   result = true;
00351                 }
00352               else
00353                 {
00354                   //cout << " -> no mgr" << endl;
00355                 }
00356             }
00357         }
00358       else
00359         {
00360           //cout << " -> stop" << endl;
00361         }
00362     }
00363 
00364   return (result);
00365 }
00366 
00367 //----------------------------------------------------------
00368 void PackageViewer::run (const cmt_string& package,
00369                          const cmt_string& version,
00370                          const cmt_string& path)
00371 {
00372   cout << package << " " << version << " " << path << endl;
00373 }
00374 
00375 //----------------------------------------------------------
00376 PackageSelector::PackageSelector (CmtSystem::cmt_string_vector& uses) : m_uses(uses)
00377 {
00378 }
00379 
00380 //----------------------------------------------------------
00381 void PackageSelector::run (const cmt_string& package,
00382                            const cmt_string& version,
00383                            const cmt_string& path)
00384 {
00385   cmt_string temp;
00386 
00387   temp = path;
00388   //temp += "/";
00389   //temp += package;
00390   temp += "/";
00391   temp += version;
00392   temp += "/cmt/requirements";
00393 
00394   if (!CmtSystem::test_file (temp))
00395     {
00396       temp.replace ("/cmt/", "/mgr/");
00397       if (!CmtSystem::test_file (temp))
00398         {
00399           return;
00400         }
00401     }
00402         
00403   temp.replace ("/requirements", "");
00404   cmt_string& use = m_uses.add ();
00405   use = temp;
00406 }
00407 
00408 //----------------------------------------------------------
00409 PackageCollector::PackageCollector (const cmt_string& package,
00410                                     const cmt_string& version) :
00411   m_package (package), m_version (version), m_count (0)
00412 {
00413 }
00414 
00415 //----------------------------------------------------------
00416 void PackageCollector::run (const cmt_string& package,
00417                             const cmt_string& version,
00418                             const cmt_string& path)
00419 {
00420   cmt_string dir = path;
00421   dir += CmtSystem::file_separator ();
00422   dir += version;
00423   dir += CmtSystem::file_separator ();
00424 
00425   cmt_string req;
00426 
00427   req = dir;
00428   req += "cmt";
00429   req += CmtSystem::file_separator ();
00430   req += "requirements";
00431 
00432   cmt_string requirements;
00433   cmt_string line;
00434   CmtSystem::cmt_string_vector words;
00435 
00436   if (CmtSystem::test_file (req))
00437     {
00438       requirements.read (req);
00439     }
00440   else
00441     {
00442       req = dir;
00443       req += "mgr";
00444       req += CmtSystem::file_separator ();
00445       req += "requirements";
00446       if (CmtSystem::test_file (req))
00447         {
00448           requirements.read (req);
00449         }
00450     }
00451 
00452   if (requirements != "")
00453     {
00454       int pos = 0;
00455       int max_pos = requirements.size ();
00456 
00457       while (pos < max_pos)
00458         {
00459           int cr = requirements.find (pos, "\r\n");
00460           int nl = requirements.find (pos, '\n');
00461           int first = nl;
00462           int length = 1;
00463                 
00464           if (cr != cmt_string::npos)
00465             {
00466               if (nl == cmt_string::npos)
00467                 {
00468                   first = cr;
00469                   length = 2;
00470                 }
00471               else
00472                 {
00473                   first = (nl < cr) ? nl : cr;
00474                   length = (nl < cr) ? 1 : 2;
00475                 }
00476             }
00477                 
00478           if (first == cmt_string::npos)
00479             {
00480               requirements.substr (pos, line);
00481               pos = max_pos;
00482             }
00483           else if (first > pos)
00484             {
00485               requirements.substr (pos, first - pos, line);
00486               pos = first + length;
00487             }
00488           else
00489             {
00490               line.erase (0);
00491               pos += length;
00492             }
00493 
00494           CmtSystem::split (line, " \t", words);
00495 
00496           if ((words.size () > 2) && (words[0] == "use")) 
00497             {
00498               if ((words[1] == m_package) && 
00499                   ((words[2] == m_version) || (m_version == "")))
00500                 {
00501                   cout << "# " << package << " " << version << " " << path;
00502                   if (m_version == "")
00503                     {
00504                       cout << " (use version " << words[2] << ")";
00505                     }
00506                   cout << endl;
00507                   m_count++;
00508                 }
00509             }
00510         }
00511     }
00512 }
00513 
00514 //----------------------------------------------------------
00515 int PackageCollector::count ()
00516 {
00517   return (m_count);
00518 }
00519 
00520 
00521 
00522 
00523 //----------------------------------------------------------
00524 //
00525 //   The Cmt methods
00526 //
00527 //----------------------------------------------------------
00528 
00529 
00530 
00534 void Cmt::build_config (const cmt_string& prefix,
00535                         cmt_string& config)
00536 {
00537   /*
00538     Building the config from <prefix> 
00539   */
00540 
00541   config = prefix;
00542   config += "CONFIG";
00543 }
00544 
00545 //----------------------------------------------------------
00546 void Cmt::build_makefile (const cmt_string& target)
00547 {
00548   Constituent* constituent = 0;
00549 
00550   if (target.size () > 0)
00551     {
00552       /*
00553         Do genmake for one specific target.
00554       */
00555       constituent = Constituent::find (target);
00556       if (constituent != 0)
00557         {
00558           constituent->build_makefile (m_simulation);
00559         }
00560     }
00561   else
00562     {
00563       /*
00564         Do genmake for all possible targets.
00565       */
00566       Constituent::build_all_makefiles (m_simulation);
00567     }
00568 }
00569 
00570 //----------------------------------------------------------
00571 void Cmt::build_msdev_file (const cmt_string& target)
00572 {
00573   Constituent* constituent = 0;
00574 
00575   set_standard_macros ();
00576 
00577   if (target != "")
00578     {
00579       /*
00580         Do genmsdev for one specific target.
00581       */
00582       constituent = Constituent::find (target);
00583       if (constituent != 0)
00584         {
00585           constituent->build_msdev_file (m_simulation);
00586         }
00587     }
00588   else
00589     {
00590       /*
00591         Do genmsdev for all possible targets.
00592       */
00593       Constituent::build_all_msdev_files (m_simulation);
00594     }
00595 }
00596 
00597 //----------------------------------------------------------
00598 bool Cmt::build_nmake ()
00599 {
00600   return (m_build_nmake);
00601 }
00602 
00603 //----------------------------------------------------------
00604 void Cmt::build_OS9_makefile (const cmt_string& target)
00605 {
00606   build_makefile (target);
00607 }
00608 
00612 void Cmt::build_prefix (const cmt_string& package, cmt_string& prefix)
00613 {
00614   int pos;
00615   char c;
00616 
00617   /*
00618     Building the prefix from <package> 
00619   */
00620 
00621   prefix = package;
00622 
00623   for (pos = 0; pos < package.size (); pos++)
00624     {
00625       c = package[pos];
00626       prefix[pos] = toupper (c);
00627     }
00628 }
00629 
00630 //----------------------------------------------------------
00631 void Cmt::clear ()
00632 {
00633   m_action         = action_none;
00634   m_build_nmake    = false;
00635   m_cmt_config     = "";
00636   m_cmt_path.clear ();
00637   m_cmt_path_pwds.clear ();
00638   m_cmt_path_sources.clear ();
00639   m_cmt_root       = "";
00640   m_cmt_version    = "";
00641   m_current_build_strategy = DefaultBuildStrategy;
00642   m_current_dir     = "";
00643   m_current_package = "";
00644   m_current_config  = "";
00645   m_current_path    = "";
00646   m_current_prefix  = "";
00647   m_current_access   = DeveloperMode;
00648   m_current_strategy = BestFit;
00649 
00650   m_current_tag      = "";
00651   m_current_target   = "";
00652   m_current_version  = "";
00653   m_default_path     = "";
00654   m_quiet            = false;
00655   m_recursive        = false;
00656 
00657   m_scope            = ScopePublic;
00658   m_simulation       = false;
00659 
00660   m_filtered_text    = "";
00661   m_standard_macros_done = false;
00662 
00663   Database::clear ();
00664   Include::clear_all ();
00665   Script::clear_all ();
00666   CmtError::clear ();
00667 }
00668 
00669 //----------------------------------------------------------
00670 void Cmt::configure ()
00671 {
00672   static bool configured = false;
00673 
00674   if (configured) return;
00675 
00676   m_cmt_version   = "";
00677   m_current_dir     = "";
00678   m_current_package = "";
00679   m_current_prefix  = "";
00680   m_current_config  = "";
00681   m_current_path    = "";
00682 
00683   m_current_tag     = "";
00684   m_current_version = "";
00685 
00686   m_configure_error = "";
00687 
00688   m_debug = false;
00689   if (getenv ("CMTDEBUG") != 0) m_debug = true;
00690 
00691   m_default_path    = "";
00692 
00693   configure_default_path ();
00694   configure_uname_tag ();
00695   configure_hosttype_tag ();
00696   configure_config_tag ();
00697   configure_site_tag (0);
00698   configure_cmt_path (0);
00699   configure_current_dir ();
00700   configure_current_package ();
00701   configure_home (0);
00702   configure_user_context (0);
00703 
00704   Use& use = Use::current();
00705 
00706   use.set (m_current_package,
00707            m_current_version,
00708            m_current_path,
00709            "",
00710            "");
00711 
00712   use.style = m_current_style;
00713 
00714   use.change_path (m_current_path);
00715 
00716   if (CmtError::has_pending_error ()) 
00717     {
00718       m_configure_error = CmtError::get_last_error ();
00719     }
00720 }
00721 
00722 //----------------------------------------------------------
00723 void Cmt::configure_cmt_path (Use* use)
00724 {
00725   cmt_string s;
00726 
00727   Symbol* symbol = Symbol::find ("CMTPATH");
00728   if (symbol != 0)
00729     {
00730       bool show_set_hidden = false;
00731 
00732       if (Cmt::m_action == action_show_set)
00733         {
00734           show_set_hidden = true;
00735           Cmt::m_action = action_none;
00736         }
00737 
00738       s = symbol->build_macro_value ();
00739       Symbol::expand (s);
00740 
00741       if (show_set_hidden)
00742         {
00743           show_set_hidden = false;
00744           Cmt::m_action = action_show_set;
00745         }
00746     }
00747 
00748   CmtSystem::get_cmt_paths (m_cmt_path, 
00749                             m_cmt_path_pwds, 
00750                             m_cmt_path_sources, s);
00751 }
00752 
00753 //----------------------------------------------------------
00754 void Cmt::configure_config_tag ()
00755 {
00756   m_cmt_config = CmtSystem::get_cmt_config ();
00757   if (m_cmt_config != "")
00758     {
00759       Tag* tag;
00760 
00761       tag = Tag::add (m_cmt_config, PriorityConfig, "CMTCONFIG", 0);
00762       tag->mark ();
00763     }
00764 }
00765 
00766 //----------------------------------------------------------
00767 void Cmt::configure_current_dir ()
00768 {
00769   cmt_string file_name;
00770 
00771   /*
00772     Building current_dir :
00773 
00774     o we first get the physical value (using getwd)
00775     o then this value is possibly filtered using the
00776     cmt_mount_filter file.
00777   */
00778 
00779   m_current_dir.erase (0);
00780 
00781   file_name = m_default_path;
00782   if (file_name != "")
00783     {
00784       file_name += CmtSystem::file_separator ();
00785       file_name += "CMT";
00786       file_name += CmtSystem::file_separator ();
00787       file_name += m_cmt_version;
00788       file_name += CmtSystem::file_separator ();
00789       file_name += "mgr";
00790       file_name += CmtSystem::file_separator ();
00791     }
00792 
00793   file_name += "cmt_mount_filter";
00794 
00795   m_current_dir = CmtSystem::pwd ();
00796 
00797   {
00798     cmt_string text;
00799     cmt_string line;
00800     CmtSystem::cmt_string_vector words;
00801 
00802     text.read (file_name);
00803 
00804     int pos = 0;
00805     int max_pos = text.size ();
00806 
00807     for (pos = 0; pos < max_pos; )
00808       {
00809         int cr = text.find (pos, "\r\n");
00810         int nl = text.find (pos, '\n');
00811         int first = nl;
00812         int length = 1;
00813 
00814         if (cr != cmt_string::npos)
00815           {
00816             if (nl == cmt_string::npos)
00817               {
00818                 first = cr;
00819                 length = 2;
00820               }
00821             else
00822               {
00823                 first = (nl < cr) ? nl : cr;
00824                 length = (nl < cr) ? 1 : 2;
00825               }
00826           }
00827         
00828         if (first == cmt_string::npos)
00829           {
00830             text.substr (pos, line);
00831             pos = max_pos;
00832           }
00833         else if (first > pos)
00834           {
00835             text.substr (pos, first - pos, line);
00836             pos = first + length;
00837           }
00838         else
00839           {
00840             line.erase (0);
00841             pos += length;
00842           }
00843 
00844         CmtSystem::split (line, " \t", words);
00845 
00846         if (words.size () >= 2)
00847           {
00848             cmt_string& path_name = words[0];
00849             cmt_string& replacement = words[1];
00850 
00851             if (m_current_dir.find (path_name) != cmt_string::npos)
00852               {
00853                 m_current_dir.replace (path_name, replacement);
00854                 break;
00855               }
00856           }
00857       }
00858   }
00859 }
00860 
00861 //----------------------------------------------------------
00862 void Cmt::configure_current_package ()
00863 {
00864   /*
00865     Build current_package and current_prefix.
00866 
00867     This is only possible if we are within the cmt/mgr branch of a
00868     standard directory tree (i.e. <package>/<version>/cmt or mgr)
00869   */
00870 
00871   if (CmtSystem::test_file ("../cmt/requirements"))
00872     {
00873       m_current_style = cmt_style;
00874     }
00875   else if (CmtSystem::test_file ("../mgr/requirements"))
00876     {
00877       m_current_style = mgr_style;
00878     }
00879   else
00880     {
00881       m_current_style = none_style;
00882     }
00883 
00884   if (m_current_style != none_style)
00885     {
00886       CmtSystem::dirname (m_current_dir, m_current_path);
00887       CmtSystem::basename (m_current_path, m_current_version);
00888       CmtSystem::dirname (m_current_path, m_current_path);
00889       CmtSystem::basename (m_current_path, m_current_package);
00890       CmtSystem::dirname (m_current_path, m_current_path);
00891       build_prefix (m_current_package, m_current_prefix);
00892       build_config (m_current_prefix, m_current_config);
00893     }
00894   else
00895     {
00896       m_current_package = "cmt_standalone";
00897       m_current_version = "";
00898       m_current_path = m_current_dir;
00899       build_prefix (m_current_package, m_current_prefix);
00900       build_config (m_current_prefix, m_current_config);
00901     }
00902 
00903   //cout << "configure_current_package> current style=" << m_current_style << endl;
00904 }
00905 
00906 //----------------------------------------------------------
00907 void Cmt::configure_default_path ()
00908 {
00909   m_default_path = CmtSystem::get_cmt_root ();
00910   CmtSystem::get_cmt_version (m_cmt_version);
00911   m_cmt_root = m_default_path;
00912   m_cmt_root += CmtSystem::file_separator ();
00913   m_cmt_root += "CMT";
00914   m_cmt_root += CmtSystem::file_separator ();
00915   m_cmt_root += m_cmt_version;
00916 }
00917 
00918 //----------------------------------------------------------
00919 void Cmt::configure_home (Use* use)
00920 {
00921   m_cmt_home = "";
00922 
00923   Symbol* symbol = Symbol::find ("CMTHOME");
00924   if (symbol != 0)
00925     {
00926       m_cmt_home = symbol->build_macro_value ();
00927     }
00928   else if (CmtSystem::testenv ("CMTHOME"))
00929     {
00930       m_cmt_home = CmtSystem::getenv ("CMTHOME");
00931     }
00932 
00933   if ((m_cmt_home != "") && !CmtSystem::test_directory (m_cmt_home))
00934     {
00935       m_cmt_home = "";
00936     }
00937 }
00938 
00939 //----------------------------------------------------------
00940 void Cmt::configure_user_context (Use* use)
00941 {
00942   m_cmt_user_context = "";
00943 
00944   Symbol* symbol = Symbol::find ("CMTUSERCONTEXT");
00945   if (symbol != 0)
00946     {
00947       m_cmt_user_context = symbol->build_macro_value ();
00948     }
00949   else if (CmtSystem::testenv ("CMTUSERCONTEXT"))
00950     {
00951       m_cmt_user_context = CmtSystem::getenv ("CMTUSERCONTEXT");
00952     }
00953 
00954   if ((m_cmt_user_context != "") && !CmtSystem::test_directory (m_cmt_user_context))
00955     {
00956       m_cmt_user_context = "";
00957     }
00958 }
00959 
00960 //----------------------------------------------------------
00961 void Cmt::configure_hosttype_tag ()
00962 {
00963   cmt_string hosttype;
00964 
00965   CmtSystem::get_hosttype (hosttype);
00966 
00967   if (hosttype != "")
00968     {
00969       Tag* tag;
00970 
00971       tag = Tag::add (hosttype, PriorityUname, "HOSTTYPE", 0);
00972       tag->mark ();
00973     }
00974 }
00975 
00976 //----------------------------------------------------------
00977 void Cmt::configure_site_tag (Use* use)
00978 {
00979   Symbol* symbol = Symbol::find ("CMTSITE");
00980   if (symbol != 0)
00981     {
00982       m_cmt_site = symbol->build_macro_value ();
00983     }
00984   else
00985     {
00986       m_cmt_site = CmtSystem::get_cmt_site ();
00987     }
00988 
00989   if (m_cmt_site != "")
00990     {
00991       cmt_string s = "CMTSITE";
00992 
00993       if (use != 0)
00994         {
00995           s += " in ";
00996         }
00997 
00998       Tag* tag;
00999 
01000       tag = Tag::add (m_cmt_site, PrioritySite, s, use);
01001       tag->mark ();
01002     }
01003 }
01004 
01005 //----------------------------------------------------------
01006 void Cmt::restore_all_tags (Use* use)
01007 {
01008     //cerr << "restore_all_tags" << endl;
01009 
01010   Cmt::configure_tags (use);
01011 
01012     /*
01013       Then get existing extra tags
01014      */
01015 
01016   if (CmtSystem::testenv ("CMTEXTRATAGS"))
01017     {
01018       cmt_string s = "CMTEXTRATAGS";
01019 
01020       if (use != 0)
01021         {
01022           s += " in ";
01023         }
01024 
01025       Tag* tag;
01026       CmtSystem::cmt_string_vector words;
01027       
01028       cmt_string tags = CmtSystem::getenv ("CMTEXTRATAGS");
01029       
01030       CmtSystem::split (tags, " \t,", words);
01031 
01032       Cmt::m_extra_tags = "";
01033       
01034       for (int i = 0; i < words.size (); i++)
01035         {
01036           const cmt_string& a = words[i];
01037 
01038           Cmt::m_extra_tags += a;
01039           Cmt::m_extra_tags += ",";
01040           
01041           tag = Tag::add (a, PriorityUserTag, s, use);
01042           
01043           tag->mark ();
01044         }
01045     }
01046 }
01047 
01048 //----------------------------------------------------------
01049 void Cmt::configure_tags (Use* use)
01050 {
01051   cmt_string config_tag;
01052   
01053   if (m_debug) cerr << "configure_tags0> current_tag=" << m_current_tag << endl;
01054 
01055   Symbol* symbol = Symbol::find ("CMTCONFIG");
01056   if (symbol != 0)
01057     {
01058       bool show_set_hidden = false;
01059 
01060       if (Cmt::m_action == action_show_set)
01061         {
01062           show_set_hidden = true;
01063           Cmt::m_action = action_none;
01064         }
01065 
01066       config_tag = symbol->build_macro_value ();
01067 
01068       if (show_set_hidden)
01069         {
01070           show_set_hidden = false;
01071           Cmt::m_action = action_show_set;
01072         }
01073     }
01074   else if (CmtSystem::testenv ("CMTCONFIG"))
01075     {
01076       config_tag = CmtSystem::getenv ("CMTCONFIG");
01077     }
01078   else if (CmtSystem::testenv ("CMTBIN"))
01079     {
01080       config_tag = CmtSystem::getenv ("CMTBIN");
01081     }
01082 
01083   if (config_tag == "")
01084     {
01085       CmtSystem::get_uname (config_tag);
01086     }
01087 
01088   if (m_debug) cerr << "configure_tags> current_tag=" << m_current_tag << endl;
01089 
01090   cmt_string s = "CMTCONFIG";
01091 
01092   if (use != 0)
01093     {
01094       s += " in ";
01095     }
01096 
01097   Tag* tag;
01098 
01099   tag = Tag::add (config_tag, PriorityConfig, s, use);
01100   tag->mark ();
01101 
01102     //m_current_tag = config_tag;
01103 }
01104 
01105 //----------------------------------------------------------
01106 void Cmt::configure_uname_tag ()
01107 {
01108   cmt_string uname;
01109 
01110   CmtSystem::get_uname (uname);
01111 
01112   if (uname != "")
01113     {
01114       Tag* tag;
01115 
01116       tag = Tag::add (uname, PriorityUname, "uname", 0);
01117       tag->mark ();
01118     }
01119 }
01120 
01121 //----------------------------------------------------------
01122 //
01123 //   Actions
01124 //
01125 //----------------------------------------------------------
01126 
01127 class AwkActor : public Awk
01128 {
01129 public:
01130 
01131   void filter (const cmt_string& line)
01132       {
01133         cout << line << endl;
01134       }
01135 };
01136 
01137 //----------------------------------------------------------
01138 void Cmt::do_awk (const CmtSystem::cmt_string_vector& arguments)
01139 {
01140   if (arguments.size () < 1)
01141     {
01142       cout << "> cmt broadcast <file> <pattern>" << endl;
01143       return;
01144     }
01145 
01146   const cmt_string& file = arguments[0];
01147   const cmt_string& pattern = arguments[1];
01148   cmt_string text;
01149 
01150   text.read (file);
01151 
01152   static AwkActor a;
01153 
01154   cmt_regexp exp (pattern);
01155 
01156   a.run (text, exp);
01157 }
01158 
01159 //----------------------------------------------------------
01160 void Cmt::do_broadcast (const CmtSystem::cmt_string_vector& arguments,
01161                         int argc,
01162                         char* argv[])
01163 {
01164   Use::UsePtrVector& Uses = Use::uses ();
01165 
01166   CmtSystem::cmt_string_vector uses;
01167   CmtSystem::cmt_string_vector path_selections;
01168   CmtSystem::cmt_string_vector selections;
01169   CmtSystem::cmt_string_vector exclusions;
01170   cmt_string begin;
01171   cmt_string command;
01172   bool is_cmt = false;
01173   int first = 0;
01174   int i;
01175   bool ignore_errors = false;
01176   bool all_packages = false;
01177 
01178   bool local = true;
01179 
01180   for (i = 0; i < arguments.size (); i++)
01181     {
01182       const cmt_string& w = arguments[i];
01183 
01184       if (command == "")
01185         {
01186           if (w.substr (0, 13) == "-all_packages")
01187             {
01188               local = false;
01189               all_packages = true;
01190             }
01191           else if (w.substr (0, 7) == "-depth=")
01192             {
01193               local = false;
01194 
01195               cmt_string depth_str;
01196               int depth_value = 0;
01197                           
01198               w.substr (7, depth_str);
01199               if ((sscanf (depth_str.c_str (), "%d", &depth_value) < 1) ||
01200                   (depth_value < 1))
01201                 {
01202                   // Syntax error
01203                   //  We shall restrict to packages found within 
01204                   // the <depth_value> first elements of CMTPATH.
01205                   //  If CMTPATH is empty, nothing is selected.
01206                   // depth=1 is equivalent to local
01207                 }
01208 
01209               int i = 0;
01210               while (i < m_cmt_path.size ())
01211                 {
01212                   cmt_string& p = m_cmt_path[i];
01213                   cmt_string& pwd = m_cmt_path_pwds[i];
01214                   cmt_string& src = m_cmt_path_sources[i];
01215 
01216                   if (src == "current package")
01217                     {
01218                       cmt_string& s1 = path_selections.add ();
01219                       s1 = p;
01220                       cmt_string& s2 = path_selections.add ();
01221                       s2 = pwd;
01222                     }
01223                   else if (src != "default path")
01224                     {
01225                       if (depth_value > 0)
01226                         {
01227                           cmt_string& s1 = path_selections.add ();
01228                           s1 = p;
01229                           cmt_string& s2 = path_selections.add ();
01230                           s2 = pwd;
01231                           depth_value--;
01232                         }
01233                     }
01234                   i++;
01235                 }
01236             }
01237           else if (w.substr (0, 9) == "-exclude=")
01238             {
01239               cmt_string exclusion;
01240 
01241               w.substr (9, exclusion);
01242 
01243               int size = exclusion.size ();
01244               
01245               if (size >= 2)
01246                 {
01247                   if (((exclusion[0] == '"') && (exclusion[size - 1] == '"')) ||
01248                       ((exclusion[0] == '\'') && (exclusion[size - 1] == '\'')))
01249                     {
01250                       exclusion.erase (size - 1);
01251                       exclusion.erase (0, 1);
01252                     }
01253 
01254                   CmtSystem::split (exclusion, " \t", exclusions);
01255                 }
01256             }
01257           else if (w.substr (0, 7) == "-global")
01258             {
01259               path_selections.clear ();
01260               local = false;
01261             }
01262           else if (w.substr (0, 6) == "-local")
01263             {
01264               local = true;
01265             }
01266           else if (w.substr (0, 8) == "-select=")
01267             {
01268               cmt_string selection;
01269 
01270               w.substr (8, selection);
01271 
01272               int size = selection.size ();
01273               
01274               if (size >= 2)
01275                 {
01276                   if (((selection[0] == '"') && (selection[size - 1] == '"')) ||
01277                       ((selection[0] == '\'') && (selection[size - 1] == '\'')))
01278                     {
01279                       selection.erase (size - 1);
01280                       selection.erase (0, 1);
01281                     }
01282 
01283                   CmtSystem::split (selection, " \t", selections);
01284                 }
01285             }
01286           else if (w.substr (0, 7) == "-begin=")
01287             {
01288               w.substr (7, begin);
01289             }
01290           else
01291             {
01292               command = w;
01293             }
01294         }
01295       else
01296         {
01297           command += " ";
01298           command += w;
01299         }
01300 
01301     }
01302 
01303   if (local)
01304     {
01305       int depth_value = 1;
01306 
01307       int i = 0;
01308       while (i < m_cmt_path.size ())
01309         {
01310           cmt_string& p = m_cmt_path[i];
01311           cmt_string& pwd = m_cmt_path_pwds[i];
01312           cmt_string& src = m_cmt_path_sources[i];
01313 
01314           if (src == "current package")
01315             {
01316               cmt_string& s1 = path_selections.add ();
01317               s1 = p;
01318               cmt_string& s2 = path_selections.add ();
01319               s2 = pwd;
01320             }
01321           else if (src != "default path")
01322             {
01323               if (depth_value > 0)
01324                 {
01325                   cmt_string& s1 = path_selections.add ();
01326                   s1 = p;
01327                   cmt_string& s2 = path_selections.add ();
01328                   s2 = pwd;
01329                   depth_value--;
01330                 }
01331             }
01332           i++;
01333         }
01334     }
01335 
01336   if (command[0] == '-')
01337     {
01338       ignore_errors = true;
01339       command.erase (0, 1);
01340     }
01341 
01342   //if (command.substr (0, 3) == "cmt") is_cmt = true;
01343 
01344   if (all_packages)
01345     {
01346       PackageSelector selector (uses);
01347       FileScanner scanner;
01348           
01349       for (i = 0; i < m_cmt_path.size (); i++)
01350         {
01351           cmt_string& p = m_cmt_path[i];
01352           scanner.scan_path (p, selector);
01353         }
01354     }
01355   else
01356     {
01357       for (i = Uses.size () - 1; i >= 0; i--)
01358         {
01359           Use* use = Uses[i];
01360                   
01361           if (use->discarded) continue;
01362 
01363           if (!use->located ())
01364             {
01365               if (!Cmt::m_quiet)
01366                 {
01367                   cout << "# package " << use->package <<
01368                       " " << use->version << " " << use->path <<
01369                       " not found" <<
01370                       endl;
01371                 }
01372             }
01373           else
01374             {
01375               if (use->package != "CMT")
01376                 {
01377                   cmt_string& s = uses.add ();
01378                                   
01379                   if (use->real_path == "") s = CmtSystem::pwd ();
01380                   else s = use->real_path;
01381                   s += CmtSystem::file_separator ();
01382                   s += use->package;
01383                   s += CmtSystem::file_separator ();
01384                   s += use->version;
01385                   s += CmtSystem::file_separator ();
01386                                   
01387                   if (use->style == mgr_style) s += "mgr";
01388                   else s += "cmt";
01389 
01390                   //cout << ">>> adding " << s << " to selection" << endl;
01391                 }
01392             }
01393         }
01394           
01395       {
01396         cmt_string& s = uses.add ();
01397                   
01398         Use* use = &(Use::current ());
01399 
01400         if (use->package.find ("cmt_standalone") != cmt_string::npos)
01401           {
01402             s = CmtSystem::pwd ();
01403           }
01404         else
01405           {
01406             if (use->real_path == "") s = CmtSystem::pwd ();
01407             else s = use->real_path;
01408             s += CmtSystem::file_separator ();
01409             s += use->package;
01410             s += CmtSystem::file_separator ();
01411             s += use->version;
01412             s += CmtSystem::file_separator ();
01413                   
01414             if (use->style == mgr_style) s += "mgr";
01415             else s += "cmt";
01416           }
01417 
01418         //cout << ">>> adding current " << s << " to selection" << endl;
01419       }
01420     }
01421 
01422   bool started = false;
01423 
01424   if (begin == "") started = true;
01425 
01426   for (i = 0; i < uses.size (); i++)
01427     {
01428       const cmt_string& s = uses[i];
01429       bool ok = true;
01430       bool selected = true;
01431       bool excluded = false;
01432 
01433       if (path_selections.size () > 0)
01434         {
01435           selected = false;
01436 
01437           for (int j = 0; j < path_selections.size (); j++)
01438             {
01439               const cmt_string& sel = path_selections[j];
01440               
01441               if (s.find (sel) != cmt_string::npos) 
01442                 {
01443                   selected = true;
01444                   break;
01445                 }
01446             }
01447 
01448           ok = selected;
01449         }
01450 
01451       if (ok)
01452         {
01453           if (selections.size () > 0)
01454             {
01455               selected = false;
01456               
01457               for (int j = 0; j < selections.size (); j++)
01458                 {
01459                   const cmt_string& sel = selections[j];
01460                   
01461                   if (s.find (sel) != cmt_string::npos) 
01462                     {
01463                       selected = true;
01464                       break;
01465                     }
01466                 }
01467               
01468               ok = selected;
01469             }
01470         }
01471 
01472       if (ok && !started)
01473         {
01474           if (s.find (begin) != cmt_string::npos)
01475             {
01476               started = true;
01477               ok = true;
01478             }
01479           else
01480             {
01481               ok = false;
01482             }
01483         }
01484 
01485 
01486       if (ok)
01487         {
01488           excluded = false;
01489 
01490           for (int j = 0; j < exclusions.size (); j++)
01491             {
01492               const cmt_string& exc = exclusions[j];
01493               
01494               if (s.find (exc) != cmt_string::npos) 
01495                 {
01496                   excluded = true;
01497                   break;
01498                 }
01499             }
01500 
01501           if (excluded) ok = false;
01502         }
01503 
01504       if (!ok) 
01505         {
01506           continue;
01507         }
01508 
01509 
01510 
01511       if (!CmtSystem::cd (s))
01512         {
01513           if (s.find ("cmt_standalone") != cmt_string::npos)
01514             {
01515               cout << "# Currently not in a CMT package" << endl;
01516             }
01517           else
01518             {
01519               cout << "# Cannot move to the package in " << s << " (" << i+1 << "/" 
01520                    << uses.size () << ")"<< endl;
01521             }
01522 
01523           if (!ignore_errors) break;
01524 
01525           continue;
01526         }
01527 
01528       if (CmtLock::check () == CmtLock::locked_by_another_user)
01529         {
01530           cout << "# Ignore locked package in " << s << " (" << i+1 << "/" 
01531                << uses.size () << ")" << endl;
01532           continue;
01533         }
01534 
01535       cout << "#--------------------------------------------------------------" << endl;
01536       cout << "# Now trying [" << command << "] in " << s << " (" << i+1 << "/" << uses.size () 
01537            << ")" << endl;
01538       cout << "#--------------------------------------------------------------" << endl;
01539 
01540       if (is_cmt)
01541         {
01542           //
01543           //  There is a bug in the recursive use of the parser. Macros are not set correctly.
01544           //  Thus the recursive optimization is now discarded.
01545           //
01546           if (parser (command) != 0)
01547             {
01548               CmtError::set (CmtError::execution_error, command);
01549               break;
01550             }
01551         }
01552       else
01553         {
01554           int status = CmtSystem::execute (command);
01555 
01556           //cerr << "do_broadcast> status=" << status << " ignore_errors=" << ignore_errors << endl;
01557 
01558           if (((status != 0) && !ignore_errors) || (status == 2))
01559               //if ((status != 0) && !ignore_errors)
01560             {
01561               if (status != 2) CmtError::set (CmtError::execution_error, command);
01562               break;
01563             }
01564         }
01565     }
01566 }
01567 
01568 //----------------------------------------------------------
01569 void Cmt::do_build_constituent_makefile (const CmtSystem::cmt_string_vector& arguments,
01570                                          int argc,
01571                                          char* argv[])
01572 {
01573   if (CmtLock::check () == CmtLock::locked_by_another_user)
01574     {
01575       CmtError::set (CmtError::conflicting_lock, "build_constituent_makefile>");
01576       return;
01577     }
01578   if (arguments.size () > 0) 
01579     {
01580       set_standard_macros ();
01581       Generator::build_constituent_makefile (arguments[0]);
01582     }
01583 }
01584 
01585 //----------------------------------------------------------
01586 void Cmt::do_build_constituents_makefile (const CmtSystem::cmt_string_vector& arguments,
01587                                           int argc,
01588                                           char* argv[])
01589 {
01590   if (CmtLock::check () == CmtLock::locked_by_another_user)
01591     {
01592       CmtError::set (CmtError::conflicting_lock, "build_constituents_makefile>");
01593       return;
01594     }
01595   set_standard_macros ();
01596   Generator::build_constituents_makefile (m_current_package);
01597 }
01598 
01599 //----------------------------------------------------------
01600 void Cmt::do_build_dependencies (const CmtSystem::cmt_string_vector& arguments,
01601                                  int argc,
01602                                  char* argv[])
01603 {
01604   if (CmtLock::check () == CmtLock::locked_by_another_user)
01605     {
01606       CmtError::set (CmtError::conflicting_lock, "build_dependencies>");
01607       return;
01608     }
01609   if (arguments.size () > 0)
01610     {
01611       set_standard_macros ();
01612 
01613       while (argc > 0)
01614         {
01615           if (strcmp (argv[0], "dependencies") != 0)
01616             {
01617               argc--;
01618               argv++;
01619             }
01620           else
01621             {
01622               argc--;
01623               argv++;
01624               argc--;
01625               argv++;
01626 
01627               Generator::build_dependencies (arguments[0], argc, argv);
01628 
01629               break;
01630             }
01631         }
01632     }
01633 }
01634 
01635 //----------------------------------------------------------
01636 void Cmt::do_build_library_links ()
01637 {
01638   if (CmtLock::check () == CmtLock::locked_by_another_user)
01639     {
01640       CmtError::set (CmtError::conflicting_lock, "build_library_links>");
01641       return;
01642     }
01643 
01644   set_standard_macros ();
01645 
01646   Use::UsePtrVector& Uses = Use::uses ();
01647   Use& current_use = Use::current ();
01648   int i;
01649   cmt_string shlibsuffix;
01650   cmt_string bin;
01651 
01652   {
01653     Symbol* macro = Symbol::find ("shlibsuffix");
01654     if (macro == 0) return;
01655     shlibsuffix = macro->build_macro_value ();
01656   }
01657 
01658   for (i = 0; i < Uses.size (); i++)
01659     {
01660       Use* use = Uses[i];
01661 
01662       if (use->discarded) continue;
01663 
01664       if (!use->located ())
01665         {
01666           if (!m_quiet)
01667             {
01668               cout << "# package " << use->package <<
01669                   " " << use->version << " " << use->path << 
01670                   " not found" <<
01671                   endl;
01672             }
01673         }
01674       else
01675         {
01676           if (use->package == "CMT") continue;
01677           if (use->package == current_use.package) continue;
01678 
01679           cmt_string s;
01680 
01681           s = use->package;
01682           s += "_libraries";
01683 
01684           Symbol* libraries_macro = Symbol::find (s);
01685 
01686           if (libraries_macro == 0) continue;
01687 
01688           cmt_string libraries = libraries_macro->build_macro_value ();
01689           static CmtSystem::cmt_string_vector values;
01690 
01691           CmtSystem::split (libraries, " \t", values);
01692 
01693           for (int j = 0; j < values.size (); j++)
01694             {
01695               const cmt_string& library = values[j];
01696 
01697               static cmt_string libname;
01698               static cmt_string name;
01699 
01700               // Is it a simple name or a complete path?
01701 
01702               libname = library;
01703               Symbol::expand (libname);
01704 
01705               if (CmtSystem::absolute_path (libname))
01706                 {
01712                   cmt_string suffix;
01713                   CmtSystem::basename (library, name);
01714                 }
01715               else
01716                 {
01723                   libname = "${";
01724                   libname += use->prefix;
01725                   libname += "ROOT}/${";
01726                   libname += use->package;
01727                   libname += "_tag}/lib";
01728                   libname += library;
01729                   libname += ".";
01730                   libname += shlibsuffix;
01731 
01732                   name = "lib";
01733                   name += library;
01734                   name += ".";
01735                   name += shlibsuffix;
01736                 }
01737 
01738               Symbol::expand (libname);
01739 
01740               s = "../$(";
01741               s += current_use.package;
01742               s += "_tag)/";
01743               s += name;
01744 
01745               Symbol::expand (s);
01746 
01747               if (!m_quiet) cout << "   Symlinking " << libname << " to " << s << endl;
01748 
01749               if (!CmtSystem::create_symlink (libname, s))
01750                 {
01751                   cout << "Cannot create a symbolic link to " << libname << endl;
01752 
01753                   break;
01754                 }
01755             }
01756         }
01757     }
01758 }
01759 
01760 //----------------------------------------------------------
01761 void Cmt::do_build_make_setup ()
01762 {
01763   if (CmtLock::check () == CmtLock::locked_by_another_user)
01764     {
01765       CmtError::set (CmtError::conflicting_lock, "build_make_setup>");
01766       return;
01767     }
01768   set_standard_macros ();
01769   Generator::build_make_setup (m_current_package);
01770 }
01771 
01772 //----------------------------------------------------------
01773 void Cmt::do_build_msdev (const CmtSystem::cmt_string_vector& arguments)
01774 {
01775   if (CmtLock::check () == CmtLock::locked_by_another_user)
01776     {
01777       CmtError::set (CmtError::conflicting_lock, "build_msdev>");
01778       return;
01779     }
01780 
01781   if (true)
01782     {
01783       set_standard_macros ();
01784       if (arguments.size () > 0) build_msdev_file (arguments[0]);
01785       else build_msdev_file ("");
01786     }
01787 }
01788 
01789 //----------------------------------------------------------
01790 void Cmt::do_build_os9_makefile (const CmtSystem::cmt_string_vector& arguments)
01791 {
01792   if (CmtLock::check () == CmtLock::locked_by_another_user)
01793     {
01794       CmtError::set (CmtError::conflicting_lock, "build_os9_makefile>");
01795       return;
01796     }
01797 
01798   if (arguments.size () > 0) 
01799     {
01800       set_standard_macros ();
01801       build_OS9_makefile (arguments[0]);
01802     }
01803 }
01804 
01805 //----------------------------------------------------------
01806 void Cmt::do_build_prototype (const CmtSystem::cmt_string_vector& arguments)
01807 {
01808   if (CmtLock::check () == CmtLock::locked_by_another_user)
01809     {
01810       CmtError::set (CmtError::conflicting_lock, "build_prototype>");
01811       return;
01812     }
01813 
01814   if (arguments.size () > 0) 
01815     {
01816       set_standard_macros ();
01817       Generator::build_prototype (arguments[0]);
01818     }
01819 }
01820 
01821 //----------------------------------------------------------
01822 void Cmt::do_build_readme (const CmtSystem::cmt_string_vector& arguments)
01823 {
01824   if (CmtLock::check () == CmtLock::locked_by_another_user)
01825     {
01826       CmtError::set (CmtError::conflicting_lock, "build_readme>");
01827       return;
01828     }
01829 
01830   set_standard_macros ();
01831   Generator::build_readme (arguments);
01832 }
01833 
01834 //----------------------------------------------------------
01835 void Cmt::do_build_tag_makefile ()
01836 {
01837   if (CmtLock::check () == CmtLock::locked_by_another_user)
01838     {
01839       CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
01840       return;
01841     }
01842 
01843   print_macros (Make);
01844 }
01845 
01846 //----------------------------------------------------------
01847 void Cmt::do_build_temporary_name ()
01848 {
01849   cmt_string name = CmtSystem::get_temporary_name ();
01850   cout << name << endl;
01851 }
01852 
01853 //----------------------------------------------------------
01854 void Cmt::do_build_triggers (const CmtSystem::cmt_string_vector& arguments)
01855 {
01856   if (CmtLock::check () == CmtLock::locked_by_another_user)
01857     {
01858       CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
01859       return;
01860     }
01861 
01862   if (arguments.size () > 0) 
01863     {
01864       set_standard_macros ();
01865       TriggerGenerator::run (arguments[0]);
01866     }
01867 }
01868 
01869 //----------------------------------------------------------
01870 void Cmt::do_build_windefs (const CmtSystem::cmt_string_vector& arguments)
01871 {
01872   if (CmtLock::check () == CmtLock::locked_by_another_user)
01873     {
01874       CmtError::set (CmtError::conflicting_lock, "build_windefs>");
01875       return;
01876     }
01877 
01878   if (arguments.size () > 0) 
01879     {
01880       set_standard_macros ();
01881       Generator::build_windefs (arguments[0]);
01882     }
01883 }
01884 
01885 //----------------------------------------------------------
01886 void Cmt::do_check_configuration ()
01887 {
01888 }
01889 
01890 //----------------------------------------------------------
01891 void Cmt::do_check_files (const CmtSystem::cmt_string_vector& arguments)
01892 {
01893   if (arguments.size () >= 2) 
01894     {
01895       cmt_string first_file = arguments[0];
01896       cmt_string second_file = arguments[1];
01897           
01898       if (first_file == "") return;
01899       if (second_file == "") return;
01900           
01901       CmtSystem::compare_and_update_files (first_file, second_file);
01902     }
01903 }
01904 
01905 //----------------------------------------------------------
01906 void Cmt::do_check_version (const CmtSystem::cmt_string_vector& arguments)
01907 {
01908   if (arguments.size () > 0)
01909     {
01910       cmt_string name = arguments[0];
01911           
01912       if (name == "") return;
01913       int v = 0;
01914       int r = 0;
01915       int p = 0;
01916           
01917       bool ok = CmtSystem::is_version_directory (name, v, r, p);
01918           
01919       if (ok)
01920         {
01921           cout << "# " << name << " is version " << v << " release " << r << " patch " << p << endl;
01922         }
01923       else
01924         {
01925           cout << "# " << name << " is not a version tag" << endl;
01926         }
01927     }
01928 }
01929 
01930 //----------------------------------------------------------
01931 void Cmt::do_checkout (const CmtSystem::cmt_string_vector& arguments)
01932 {
01933   Cvs::checkout (arguments);
01934 }
01935 
01936 //----------------------------------------------------------
01937 void Cmt::do_cleanup (PrintMode& mode)
01938 {
01939   print_clean (mode);
01940 }
01941 
01942 //----------------------------------------------------------
01943 void Cmt::do_config ()
01944 {
01945   if (CmtLock::check () == CmtLock::locked_by_another_user)
01946     {
01947       CmtError::set (CmtError::conflicting_lock, "config>");
01948       return;
01949     }
01950 
01951     //Use::UsePtrVector& Uses = Use::uses ();
01952 
01953   /*
01954     cout << "pwd " << CmtSystem::pwd () << endl;
01955     cout << "current_dir " << m_current_dir << endl;
01956     cout << "default_path " << m_default_path << endl;
01957     cout << "cmt config " <<
01958     m_current_package << " " <<
01959     m_current_version << " " <<
01960     m_current_path << endl;
01961   */
01962 
01963   if (m_current_package == "CMT") return;
01964   if (m_current_package == "methods") return;
01965 
01966   cmt_string branch;
01967 
01968   CmtSystem::basename (m_current_dir, branch);
01969 
01970   if ((branch != "mgr") && (branch != "cmt"))
01971     {
01972       if (CmtSystem::test_file ("requirements"))
01973         {
01974           cout << "------------------------------------------" << endl;
01975           cout << "Configuring environment for standalone package." << endl;
01976           cout << "CMT version " << m_cmt_version << "." << endl;
01977           cout << "System is " << m_cmt_config << endl;
01978           cout << "------------------------------------------" << endl;
01979 
01980           install_test_setup_scripts ();
01981           install_test_cleanup_scripts ();
01982 
01983           Generator::build_default_makefile ();
01984         }
01985       else
01986         {
01987           cout << "==============================================" << endl;
01988           cout << "cmt config must be operated either upon "
01989             "an existing package" << endl;
01990           cout << " (ie. when a requirements file already exists)" << endl;
01991           cout << "   > cd ..." << endl;
01992           cout << "   > cmt config" << endl;
01993           cout << "or to create a new package" << endl;
01994           cout << "   > cmt config <package> <version> [<path>]" << endl;
01995           cout << "==============================================" << endl;
01996         }
01997 
01998       return;
01999     }
02000 
02001   if (branch == "cmt") m_current_style = cmt_style;
02002   else if (branch == "mgr") m_current_style = mgr_style;
02003   else m_current_style = none_style;
02004 
02005   Generator::build_default_makefile ();
02006 
02007   CmtSystem::cmt_string_vector makes;
02008   cmt_regexp expression ("[.]n?make(sav)?$");
02009 
02010   CmtSystem::scan_dir (".", expression, makes);
02011 
02012   if (makes.size () > 0)
02013     {
02014       cout << "Removing all previous make fragments from " << branch << endl;
02015 
02016       for (int i = 0; i < makes.size (); i++)
02017         {
02018           const cmt_string& s = makes[i];
02019           CmtSystem::remove_file (s);
02020         }
02021     }
02022 
02023   CmtSystem::cd ("..");
02024 
02025   CmtSystem::scan_dir (m_cmt_config, expression, makes); 
02026     
02027   if (makes.size () > 0) 
02028     {
02029       cout << "Removing all previous make fragments from "
02030            << m_cmt_config << endl; 
02031 
02032       for (int i = 0; i < makes.size (); i++) 
02033         { 
02034           const cmt_string& s = makes[i]; 
02035           CmtSystem::remove_file (s); 
02036         }    
02037     } 
02038     
02039   CmtSystem::cd (branch); 
02040     
02041 
02042   /*
02043     if (!load (m_current_path, m_current_package, m_current_version))
02044     {
02045     cout << "Cannot read the requirements file" << endl;
02046     return;
02047     }
02048   */
02049 
02050   CmtSystem::dirname (m_current_dir, m_current_path);
02051   CmtSystem::basename (m_current_path, m_current_version);
02052   CmtSystem::dirname (m_current_path, m_current_path);
02053   CmtSystem::basename (m_current_path, m_current_package);
02054   CmtSystem::dirname (m_current_path, m_current_path);
02055 
02056   Use& use = Use::current ();
02057 
02058   use.set (m_current_package,
02059            m_current_version,
02060            m_current_path,
02061            "",
02062            "");
02063 
02064   use.change_path (m_current_path);
02065   use.style     = m_current_style;
02066 
02067   //cout << "do_config> current style=" << m_current_style << endl;
02068 
02069   if (!reach_current_package ())
02070     {
02071       cout << "Cannot read the requirements file" << endl;
02072       return;
02073     }
02074 
02075   install_setup_scripts ();
02076   install_cleanup_scripts ();
02077 
02078   CmtSystem::cd ("..");
02079 
02080   Branch::BranchVector& branches = Branch::branches ();
02081 
02082   int i;
02083 
02084   for (i = 0; i < branches.size (); i++)
02085     {
02086       const Branch& branch = branches[i];
02087       const cmt_string& branch_name = branch.name ();
02088 
02089       if (!CmtSystem::test_directory (branch_name))
02090         {
02091           if (!CmtSystem::mkdir (branch_name))
02092             {
02093               cout << "Cannot create the " << branch_name <<" branch" << endl;
02094             }
02095           else
02096             {
02097               cout << "Installing the " << branch_name << " directory" << endl;
02098             }
02099         }
02100       else
02101         {
02102           cout << branch_name << " directory already installed" << endl;
02103         }
02104     }
02105 }
02106 
02107 //----------------------------------------------------------
02108 void Cmt::do_create (const CmtSystem::cmt_string_vector& arguments)
02109 {
02110   if (arguments.size () < 2) return;
02111 
02112   const cmt_string& package = arguments[0];
02113   const cmt_string& version = arguments[1];
02114   cmt_string offset;
02115   if (arguments.size () >= 3) offset = arguments[2];
02116 
02117   if (m_debug)
02118     {
02119       cout << "do_create>m_current_package=" << m_current_package << endl;
02120       cout << "do_create>package=" << package << endl;
02121     }
02122 
02123     //if (m_current_package == "CMT") return;
02124     //if (m_current_package == "methods") return;
02125 
02126   cmt_string the_path;
02127 
02128   the_path = CmtSystem::pwd ();
02129 
02130   if (offset != "")
02131     {
02132       if (!CmtSystem::absolute_path (offset))
02133         {
02134           // offset is really a relative offset
02135           the_path += CmtSystem::file_separator ();
02136           the_path += offset;
02137         }
02138       else // absolute path
02139         {
02140           the_path = offset;
02141         }
02142     }
02143 
02144   CmtSystem::compress_path (the_path);
02145 
02146   // Now 'the_path' contains the complete path where the package will be created
02147 
02148   cout << "------------------------------------------" << endl;
02149   cout << "Configuring environment for package " << package <<
02150     " version " << version << "." << endl;
02151   cout << "CMT version " << m_cmt_version << "." << endl;
02152   cout << "Root set to " << the_path << "." << endl;
02153   cout << "System is " << m_cmt_config << endl;
02154   cout << "------------------------------------------" << endl;
02155 
02156   if (!CmtSystem::test_directory (the_path))
02157     {
02158       if (!CmtSystem::mkdir (the_path))
02159         {
02160           cout << "Cannot create the path directory" << endl;
02161           return;
02162         }
02163       else
02164         {
02165           cout << "Installing the path directory" << endl;
02166         }
02167     }
02168 
02169   CmtSystem::cd (the_path);
02170 
02171   if (!CmtSystem::test_directory (package))
02172     {
02173       if (!CmtSystem::mkdir (package))
02174         {
02175           cout << "Cannot create the package directory" << endl;
02176           return;
02177         }
02178       else
02179         {
02180           cout << "Installing the package directory" << endl;
02181         }
02182     }
02183   else
02184     {
02185       cout << "Package directory already installed" << endl;
02186     }
02187 
02188   CmtSystem::cd (package);
02189 
02190   if (!CmtSystem::test_directory (version))
02191     {
02192       if (!CmtSystem::mkdir (version))
02193         {
02194           cout << "Cannot create the version directory" << endl;
02195           return;
02196         }
02197       else
02198         {
02199           cout << "Installing the version directory" << endl;
02200         }
02201     }
02202   else
02203     {
02204       cout << "Version directory already installed" << endl;
02205     }
02206 
02207   CmtSystem::cd (version);
02208 
02209   if (!CmtSystem::test_directory ("cmt"))
02210     {
02211       if (!CmtSystem::test_directory ("mgr"))
02212         {
02213           if (!CmtSystem::mkdir ("cmt"))
02214             {
02215               cout << "Cannot create the cmt directory" << endl;
02216               return;
02217             }
02218           else
02219             {
02220               m_current_style = cmt_style;
02221               cout << "Installing the cmt directory" << endl;
02222             }
02223         }
02224       else
02225         {
02226           m_current_style = mgr_style;
02227           cout << "Mgr directory already installed" << endl;
02228         }
02229     }
02230   else
02231     {
02232       m_current_style = cmt_style;
02233       cout << "Cmt directory already installed" << endl;
02234     }
02235 
02236   if (!CmtSystem::test_directory ("src"))
02237     {
02238       if (!CmtSystem::mkdir ("src"))
02239         {
02240           cout << "Cannot create the src directory" << endl;
02241           return;
02242         }
02243       else
02244         {
02245           cout << "Installing the src directory" << endl;
02246         }
02247     }
02248   else
02249     {
02250       cout << "src directory already installed" << endl;
02251     }
02252 
02253   switch (m_current_style)
02254     {
02255     case cmt_style:
02256       CmtSystem::cd ("cmt");
02257       break;
02258     case mgr_style:
02259       CmtSystem::cd ("mgr");
02260       break;
02261     }
02262 
02263   Generator::build_default_makefile ();
02264 
02265   if (!CmtSystem::test_file ("requirements"))
02266     {
02267       // create an empty requirement file.
02268       ofstream f ("requirements");
02269       if (f)
02270         {
02271           f << "package " << package << endl;
02272           f << endl;
02273           f.close ();
02274         }
02275     }
02276 
02277   m_current_package = package;
02278   m_current_version = version;
02279   m_current_path    = the_path;
02280   m_current_dir     = CmtSystem::pwd ();
02281 
02282   do_config ();
02283 }
02284 
02285 //----------------------------------------------------------
02286 void Cmt::do_cvsbranches (const CmtSystem::cmt_string_vector& arguments)
02287 {
02288   Cvs::branches (arguments[0]);
02289 }
02290 
02291 //----------------------------------------------------------
02292 void Cmt::do_cvssubpackages (const CmtSystem::cmt_string_vector& arguments)
02293 {
02294   Cvs::subpackages (arguments[0]);
02295 }
02296 
02297 //----------------------------------------------------------
02298 void Cmt::do_cvstags (const CmtSystem::cmt_string_vector& arguments)
02299 {
02300   Cvs::tags (arguments);
02301 }
02302 
02303 //----------------------------------------------------------
02304 void Cmt::do_expand_model (const CmtSystem::cmt_string_vector& arguments)
02305 {
02306   set_standard_macros ();
02307   CmtModel::expand (arguments[0]);
02308 }
02309 
02320 void Cmt::do_filter (const CmtSystem::cmt_string_vector& arguments)
02321 {
02322   if (arguments.size () < 2) return;
02323 
02324   cmt_string& input = arguments[0];
02325   cmt_string& output = arguments[1];
02326 
02327   if (!CmtSystem::test_file (input))
02328     {
02329       cout << "#CMT> File " << input << " not found" << endl;
02330       return;
02331     }
02332 
02333   cmt_string text;
02334 
02335   text.read (input);
02336 
02337   set_standard_macros ();
02338 
02339   Symbol::expand (text);
02340 
02341   FILE* file = fopen (output, "wb");
02342   if (file == NULL)
02343     {
02344       cout << "#CMT> Cannot write filtered file " << output << endl;
02345     }
02346   else
02347     {
02348       text.write (file);
02349       fclose (file);
02350     }
02351 }
02352 
02353 //----------------------------------------------------------
02354 void Cmt::do_help ()
02355 {
02356   cout << "> cmt command [option...]" << endl;
02357   cout << " command :" << endl;
02358   cout << "   broadcast [-select=list] [-exclude=list] [-local] [-global] [-begin=pattern] [-depth=n] <command> : apply a command to [some of] the used packages" << endl;
02359   cout << "" << endl;
02360   cout << "   build <key>             : build various components :" << endl;
02361   cout << "         constituent_makefile <constituent>  : generate constituent Makefile fragment" << endl;
02362   cout << "         constituents_makefile : generate constituents.make" << endl;
02363   cout << "         dependencies      : generate dependencies" << endl;
02364   cout << "         library_links     : build symbolic links towards all imported libraries" << endl;
02365   cout << "         make_setup        : build a compiled version of setup scripts" << endl;
02366   cout << "         msdev             : generate MSDEV files" << endl;
02367   cout << "         os9_makefile      : generate Makefile for OS9" << endl;
02368   cout << "         prototype         : generate prototype file" << endl;
02369   cout << "         readme            : generate README.html" << endl;
02370   cout << "         tag_makefile      : generate tag specific Makefile" << endl;
02371   cout << "         triggers <constituent> : generate library trigger file" << endl;
02372   cout << "         windefs <library_name> : generate def file for Windows shared libraries" << endl;
02373   cout << "" << endl;
02374   cout << "   check <key>             : perform various checks" << endl;
02375   cout << "         configuration     : check configuration" << endl;
02376   cout << "         files <old> <new> : compare two files and overrides <old> by <new> if different" << endl;
02377   cout << "         version <name>    : check if a name follows a version tag syntax " << endl;
02378   cout << "   check_files <old> <new> : compare two files and overrides <old> by <new> if different" << endl;
02379   cout << "   checkout                : perform a cvs checkout over a CMT package" << endl;
02380   cout << "   co                      : perform a cvs checkout over a CMT package" << endl;
02381   cout << "   cleanup [-csh|-sh|-bat] : generate a cleanup script" << endl;
02382   cout << "   config                  : generate setup and cleanup scripts" << endl;
02383   cout << "   create <package> <version> [<path>] : create and configure a new package" << endl;
02384   cout << "   filter <in> <out>       : filter a file against CMT macros and env. variables" << endl;
02385   cout << "   help                    : display this help" << endl;
02386   cout << "   lock [<p> <v> [<path>]] : lock a package" << endl;
02387   cout << "   remove <package> <version> [<path>] : remove a package version" << endl;
02388   cout << "   remove library_links    : remove symbolic links towards all imported libraries" << endl;
02389   cout << "   run <command>           : apply a command" << endl;
02390   cout << "   setup [-csh|-sh|-bat]   : generate a setup script" << endl;
02391   cout << "   show <key>              : display various infos on :" << endl;
02392   cout << "         all_tags          :  all defined tags" << endl;
02393   cout << "         applied_patterns  :  all patterns actually applied" << endl;
02394   cout << "         author            :  package author" << endl;
02395   cout << "         branches          :  added branches" << endl;
02396   cout << "         clients           :  package clients" << endl;
02397   cout << "         constituent_names :  constituent names" << endl;
02398   cout << "         constituents      :  constituent definitions" << endl;
02399   cout << "         uses              :  the use tree" << endl;
02400   cout << "         fragment <name>   :  one fragment definition" << endl;
02401   cout << "         fragments         :  fragment definitions" << endl;
02402   cout << "         groups            :  group definitions" << endl;
02403   cout << "         languages         :  language definitions" << endl;
02404   cout << "         macro <name>      :  a formatted macro definition" << endl;
02405   cout << "         macro_value <name>  :  a raw macro definition" << endl;
02406   cout << "         macros            :  all macro definitions" << endl;
02407   cout << "         manager           :  package manager" << endl;
02408   cout << "         packages          :  packages reachable from the current context" << endl;
02409   cout << "         path              :  the package search list" << endl;
02410   cout << "         pattern <name>    :  the pattern definition and usages" << endl;
02411   cout << "         pattern_names     :  pattern names" << endl;
02412   cout << "         patterns          :  the pattern definitions" << endl;
02413   cout << "         pwd               :  filtered current directory" << endl;
02414   cout << "         set_value <name>  :  a raw set definition" << endl;
02415   cout << "         set <name>        :  a formatted set definition" << endl;
02416   cout << "         sets              :  set definitions" << endl;
02417   cout << "         strategies        :  all strategies (build & version)" << endl;
02418   cout << "         tags              :  all currently active tags" << endl;
02419   cout << "         uses              :  used packages" << endl;
02420   cout << "         version           :  version of the current package" << endl;
02421   cout << "         versions <name>   :  visible versions of the selected package" << endl;
02422   cout << "" << endl;
02423   cout << "   system                  : display the system tag" << endl;
02424   cout << "   unlock [<p> <v> [<path>]] : unlock a package" << endl;
02425   cout << "   version                 : version of CMT" << endl;
02426   cout << "" << endl;
02427   cout << "   cvstags <module>         : display the CVS tags for a module" << endl;
02428   cout << "   cvsbranches <module>     : display the subdirectories for a module" << endl;
02429   cout << "   cvssubpackagess <module> : display the subpackages for a module" << endl;
02430 
02431   cout << " global options :" << endl;
02432 
02433   cout << "   -quiet                  : don't print errors" << endl;
02434   cout << "   -use=<p>:<v>:<path>     : set package version path" << endl;
02435   cout << "   -pack=<package>         : set package" << endl;
02436   cout << "   -version=<version>      : set version" << endl;
02437   cout << "   -path=<path>            : set root path" << endl;
02438   cout << "   -f=<requirement-file>   : set input file" << endl;
02439   cout << "   -e=<statement>          : add a one line statement" << endl;
02440   cout << "   -tag=<tag-list>         : select a new tag-set" << endl;
02441   cout << "   -tag_add=<tag-list>     : add specific comma-separated tag(s)" << endl;
02442   cout << "   -tag_remove=<tag-list>  : remove specific comma-separated tag(s)" << endl;
02443 }
02444 
02445 //----------------------------------------------------------
02446 void Cmt::do_lock (const cmt_string& package,
02447                    const cmt_string& version,
02448                    const cmt_string& path)
02449 {
02450   //(unsused) Use& use = Use::current();
02451 
02452   cout << "try to lock package " << package << " in " << CmtSystem::pwd () << endl;
02453 
02454   set_standard_macros ();
02455 
02456   CmtLock::status status = CmtLock::lock ();
02457 }
02458 
02459 //----------------------------------------------------------
02460 void Cmt::do_remove (const cmt_string& package,
02461                      const cmt_string& version,
02462                      const cmt_string& path)
02463 {
02464     //Use::UsePtrVector& Uses = Use::uses ();
02465 
02466   if (m_current_package == "CMT") return;
02467   if (m_current_package == "methods") return;
02468 
02469   cmt_string the_path;
02470 
02471   //the_path = m_default_path;
02472   the_path = CmtSystem::pwd ();
02473 
02474   if (path != "")
02475     {
02476       if (!CmtSystem::absolute_path (path))
02477         {
02478           // path is just a suffix
02479           the_path += CmtSystem::file_separator ();
02480           the_path += path;
02481         }
02482       else // absolute path
02483         {
02484           the_path = path;
02485         }
02486     }
02487 
02488   CmtSystem::compress_path (the_path);
02489 
02490   cout << "------------------------------------------" << endl;
02491   cout << "Removing package " << package <<
02492     " version " << version << "." << endl;
02493   cout << "CMT version " << m_cmt_version << "." << endl;
02494   cout << "Root set to " << the_path << "." << endl;
02495   cout << "System is " << m_cmt_config << endl;
02496   cout << "------------------------------------------" << endl;
02497 
02498   the_path += CmtSystem::file_separator ();
02499   the_path += package;
02500 
02501   if (CmtSystem::cd (the_path) && 
02502       CmtSystem::test_directory (version))
02503     {
02504       if (CmtSystem::remove_directory (version))
02505         {
02506           cout << "Version " << version << " has been removed from " << the_path << endl;
02507           CmtSystem::cmt_string_vector contents;
02508           CmtSystem::scan_dir (".", contents);
02509           if (contents.size () == 0)
02510             {
02511               CmtSystem::cd ("..");
02512               if (CmtSystem::remove_directory (package))
02513                 {
02514                   cout << "Package " << package << " has no more versions. Thus it has been removed."<< endl;
02515                 }
02516             }
02517         }
02518       else
02519         {
02520           cout << "Impossible to remove version " << version << " from " << the_path << endl;
02521         }
02522     }
02523   else
02524     {
02525       cout << "Version " << version << " not found" << endl;
02526     }
02527 }
02528 
02529 //----------------------------------------------------------
02530 void Cmt::do_remove_library_links ()
02531 {
02532   if (CmtLock::check () == CmtLock::locked_by_another_user)
02533     {
02534       CmtError::set (CmtError::conflicting_lock, "remove_library_links>");
02535       return;
02536     }
02537 
02538   set_standard_macros ();
02539 
02540   Use::UsePtrVector& Uses = Use::uses ();
02541   Use& current_use = Use::current ();
02542   int i;
02543   cmt_string shlibsuffix;
02544   cmt_string symunlink;
02545 
02546   {
02547     Symbol* macro = Symbol::find ("shlibsuffix");
02548     if (macro == 0) return;
02549     shlibsuffix = macro->build_macro_value ();
02550   }
02551 
02552   {
02553     Symbol* macro = Symbol::find ("symunlink");
02554     if (macro == 0) return;
02555     symunlink = macro->build_macro_value ();
02556   }
02557 
02558   for (i = 0; i < Uses.size (); i++)
02559     {
02560       Use* use = Uses[i];
02561 
02562       if (use->discarded) continue;
02563 
02564       if (!use->located ())
02565         {
02566           if (!m_quiet)
02567             {
02568               cout << "# package " << use->package <<
02569                   " " << use->version << " " << use->path << 
02570                   " not found" <<
02571                   endl;
02572             }
02573         }
02574       else
02575         {
02576           if (use->package == "CMT") continue;
02577           if (use->package == current_use.package) continue;
02578 
02579           cmt_string s;
02580 
02581           s = use->package;
02582           s += "_libraries";
02583 
02584           Symbol* libraries_macro = Symbol::find (s);
02585 
02586           if (libraries_macro == 0) continue;
02587 
02588           cmt_string libraries = libraries_macro->build_macro_value ();
02589           static CmtSystem::cmt_string_vector values;
02590 
02591           CmtSystem::split (libraries, " \t", values);
02592 
02593           for (int j = 0; j < values.size (); j++)
02594             {
02595               const cmt_string& library = values[j];
02596 
02597               static cmt_string libname;
02598               static cmt_string name;
02599 
02600               // Is it a simple name or a complete path?
02601 
02602               libname = library;
02603               Symbol::expand (libname);
02604 
02605               if (CmtSystem::absolute_path (libname))
02606                 {
02612                   cmt_string suffix;
02613                   CmtSystem::basename (library, name);
02614                 }
02615               else
02616                 {
02624                   name = "lib";
02625                   name += libname;
02626                   name += ".";
02627                   name += shlibsuffix;
02628                 }
02629 
02630               s = symunlink;
02631               s += " ../$(";
02632               s += current_use.package;
02633               s += "_tag)/";
02634               s += name;
02635 
02636               Symbol::expand (s);
02637 
02638               if (!m_quiet) cout << s << endl;
02639               int status = CmtSystem::execute (s);
02640 
02641               if (status != 0)
02642                 {
02643                   if (status != 2) CmtError::set (CmtError::execution_error, s);
02644 
02645                   cout << "Cannot remove the symbolic link " << s << endl;
02646 
02647                   break;
02648                 }
02649             }
02650         }
02651     }
02652 }
02653 
02654 //----------------------------------------------------------
02655 void Cmt::do_run (const CmtSystem::cmt_string_vector& arguments)
02656 {
02657   if (arguments.size () > 0) CmtSystem::execute (arguments[0]);
02658 }
02659 
02709 class SequenceRunner : public FAwk
02710 {
02711 public:
02712 
02713   SequenceRunner ()
02714   {
02715   }
02716 
02717   void begin ()
02718   {
02719     started = false;
02720     running = false;
02721     if (style == CmtSystem::getenv ("CMTSTRUCTURINGSTYLE"))
02722       {
02723         vdir = CmtSystem::file_separator (); 
02724         vdir += "v1"; 
02725       } 
02726     else
02727       {
02728         vdir = ""; 
02729       }
02730     package = "";
02731     filename = "";
02732     buffer = "";
02733     pwd = "";
02734   }
02735 
02736   void filter (const cmt_string& line)
02737   {
02738     //cout << "line=[" << line << "]" << endl;
02739 
02740     CmtSystem::cmt_string_vector words;
02741 
02742     CmtSystem::split (line, " \t", words);
02743 
02744     cmt_string verb;
02745 
02746     if (words.size () > 0) verb = words[0];
02747 
02748     if (verb.substr (0, 2) == "%%")
02749       {
02750         if (verb.substr (0, 3) == "%%%") return;
02751 
02752         if (running)
02753           {
02754             buffer.write (filename);
02755             //cout << "%%Writing file " << filename << endl;
02756             //cout << buffer << endl;
02757             buffer = "";
02758 
02759             running = false;
02760           }
02761       }
02762 
02763     if (verb == "%%package")
02764       {
02765         package = words[1];
02766 
02767         cmt_string command = "cmt create ";
02768         command += package;
02769         command += " v1";
02770 
02771         CmtSystem::execute (command);
02772         //cout << "%% creating package " << package << " with command [" << command << "]" << endl;
02773 
02774         filename = package;
02775         filename += vdir;
02776         filename += CmtSystem::file_separator ();
02777         filename += "cmt";
02778         filename += CmtSystem::file_separator ();
02779         filename += "requirements";
02780 
02781         started = true;
02782       }
02783     else if (verb == "%%file") 
02784       {
02785         cmt_string file = words[1];
02786 
02787         cmt_string d = package;
02788         d += vdir;
02789         d += CmtSystem::file_separator ();
02790         d += file;
02791         CmtSystem::dirname (d, d);
02792         
02793         CmtSystem::mkdir (d);
02794         //cout << "%% creating directory " << d << endl;
02795 
02796         buffer = "";
02797 
02798         filename = package;
02799         filename += vdir;
02800         filename += CmtSystem::file_separator ();
02801         filename += file; 
02802         started = true;
02803       }
02804     else if (verb == "%%cdpackage") 
02805       {
02806         package = words[1];
02807 
02808         pwd = package;
02809         pwd += vdir;
02810         pwd += CmtSystem::file_separator ();
02811         pwd += "cmt";
02812       }
02813     else if (verb == "%%cmt") 
02814       {
02815         cmt_string command;
02816 
02817         if (pwd != "")
02818           {
02819             command = "cd ";
02820             command += pwd;
02821             command += " ";
02822             command += CmtSystem::command_separator ();
02823             command += " ";
02824           }
02825 
02826         command += line;
02827         command.replace ("%%", "");
02828 
02829         CmtSystem::execute (command);
02830       }
02831     else
02832       {
02833         buffer += line;
02834         buffer += "\n";
02835       }
02836 
02837     if (started)
02838       {
02839         started = false;
02840         running = true;
02841       }
02842   }
02843 
02844   void end ()
02845   {
02846     if (running)
02847       {
02848         if (buffer != "")
02849           {
02850             buffer.write (filename);
02851             //cout << "%%Writing file " << filename << endl;
02852             //cout << buffer << endl;
02853             buffer = "";
02854           }
02855         running = false;
02856       }
02857   }
02858 
02859 private:
02860   bool started;
02861   bool running;
02862   cmt_string style;
02863   cmt_string vdir;
02864   cmt_string package;
02865   cmt_string filename;
02866   cmt_string buffer;
02867   cmt_string pwd;
02868 };
02869 
02870 //----------------------------------------------------------
02871 void Cmt::do_run_sequence (const CmtSystem::cmt_string_vector& arguments)
02872 {
02873   if (arguments.size () == 0) cout << "# cmt run_sequence: no sequence specified" << endl;
02874 
02875   SequenceRunner runner;
02876 
02877   cout << "# cmt run_sequence: sequence " << arguments[0] << endl;
02878 
02879   runner.run (arguments[0]);
02880 }
02881 
02882 //----------------------------------------------------------
02883 void Cmt::do_setup (PrintMode& mode)
02884 {
02885   print (mode);
02886 }
02887 
02888 //----------------------------------------------------------
02889 void Cmt::do_show_all_tags ()
02890 {
02891   Tag::TagPtrVector tags = Tag::tags ();
02892   int index;
02893 
02894   set_standard_macros ();
02895 
02896   for (index = 0; index < tags.size (); index++)
02897     {
02898       const Tag* tag = tags[index];
02899       if (tag != 0)
02900         {
02901           tag->show_definition (true);
02902         }
02903     }
02904 }
02905 
02906 //----------------------------------------------------------
02907 void Cmt::do_show_applied_patterns ()
02908 {
02909   Pattern::show_all_applied_patterns ();
02910 }
02911 
02912 //----------------------------------------------------------
02913 void Cmt::do_show_author ()
02914 {
02915   Use& use = Use::current();
02916 
02917   cout << use.author << endl;
02918 }
02919 
02920 //----------------------------------------------------------
02921 void Cmt::do_show_branches (PrintMode& mode)
02922 {
02923   Branch::print_all (mode);
02924 }
02925 
02926 //----------------------------------------------------------
02927 void Cmt::do_show_clients (const CmtSystem::cmt_string_vector& arguments)
02928 {
02929   cmt_string package;
02930   cmt_string version;
02931   cmt_string path_name;
02932 
02933   if (arguments.size () >= 1) package = arguments[0];
02934   if (arguments.size () >= 2) version = arguments[1];
02935   if (arguments.size () >= 3) path_name = arguments[2];
02936 
02937   FileScanner scanner;
02938   PackageCollector collector (package, version);
02939 
02940   clear ();
02941   configure ();
02942 
02943   cout << "# ----------- Clients of " << package <<
02944     " " << version <<
02945     " " << path_name <<
02946     endl;
02947 
02948   if (path_name == "")
02949     {
02950       int path_index;
02951 
02952       for (path_index = 0; path_index < m_cmt_path.size (); path_index++)
02953         {
02954           const cmt_string& path = m_cmt_path[path_index];
02955 
02956           scanner.scan_path (path, collector);
02957         }
02958     }
02959   else
02960     {
02961       scanner.scan_path (path_name, collector);
02962     }
02963   cout << "# ----------- " << collector.count () << " clients found." << endl;
02964 }
02965 
02966 //----------------------------------------------------------
02967 void Cmt::do_show_constituent (const CmtSystem::cmt_string_vector& arguments)
02968 {
02969   if (arguments.size () > 0) 
02970     {
02971       set_standard_macros ();
02972       Constituent::show (arguments[0]);
02973     }
02974 }
02975 
02976 //----------------------------------------------------------
02977 void Cmt::do_show_constituent_names ()
02978 {
02979   set_standard_macros ();
02980   Constituent::show_names ();
02981 }
02982 
02983 //----------------------------------------------------------
02984 void Cmt::do_show_constituents ()
02985 {
02986   set_standard_macros ();
02987   Constituent::show_all ();
02988 }
02989 
02990 //----------------------------------------------------------
02991 void Cmt::do_show_fragment (const CmtSystem::cmt_string_vector& arguments)
02992 {
02993   if (arguments.size () > 0) Fragment::show (arguments[0]);
02994 }
02995 
02996 //----------------------------------------------------------
02997 void Cmt::do_show_fragments ()
02998 {
02999   Fragment::show_all ();
03000 }
03001 
03002 //----------------------------------------------------------
03003 void Cmt::do_show_groups ()
03004 {
03005   Group::show_all ();
03006 }
03007 
03008 //----------------------------------------------------------
03009 void Cmt::do_show_include_dirs ()
03010 {
03011   cmt_string temp;
03012 
03013   Use& use = Use::current();
03014 
03015   set_standard_macros ();
03016 
03017   if (use.include_path == "")
03018     {
03019       temp += "$(src) ";
03020     }
03021   else if (use.include_path != "none")
03022     {
03023       temp += use.include_path;
03024       temp += " ";
03025     }
03026 
03027   for (int include_number = 0;
03028        include_number < use.includes.size ();
03029        include_number++)
03030     {
03031       Include& incl = use.includes[include_number];
03032       
03033       temp += incl.name;
03034       temp += " ";
03035     }
03036 
03037   cout << temp << endl;
03038 }
03039 
03040 //----------------------------------------------------------
03041 void Cmt::do_show_language (const CmtSystem::cmt_string_vector& arguments)
03042 {
03043   if (arguments.size () > 0) 
03044     {
03045       set_standard_macros ();
03046       Language::show (arguments[0]);
03047     }
03048 }
03049 
03050 //----------------------------------------------------------
03051 void Cmt::do_show_languages ()
03052 {
03053   set_standard_macros ();
03054   Language::show_all ();
03055 }
03056 
03057 //----------------------------------------------------------
03058 void Cmt::do_show_macro (const CmtSystem::cmt_string_vector& arguments,
03059                          PrintMode& mode)
03060 {
03061   cmt_string target;
03062 
03063   if (arguments.size () > 0) target = arguments[0];
03064 
03065   Symbol* symbol;
03066 
03067   set_standard_macros ();
03068 
03069   symbol = Symbol::find (target);
03070 
03071   if (symbol == 0) 
03072     {
03073       cmt_string t = " ";
03074       t += target;
03075       t += " is not a ";
03076 
03077       if ((m_action == action_show_macro) ||
03078           (m_action == action_show_macro_value))
03079         {
03080           t += "macro";
03081         }
03082       else if ((m_action == action_show_set) ||
03083                (m_action == action_show_set_value))
03084         {
03085           t += "set";
03086         }
03087 
03088       CmtError::set (CmtError::symbol_not_found, t);
03089 
03090       return;
03091     }
03092   else
03093     {
03094       cmt_string t = " ";
03095       t += target;
03096       t += " is not a ";
03097 
03098       if ((m_action == action_show_macro) ||
03099           (m_action == action_show_macro_value))
03100         {
03101           if ((symbol->command != CommandMacro) &&
03102               (symbol->command != CommandMacroAppend) &&
03103               (symbol->command != CommandMacroPrepend) &&
03104               (symbol->command != CommandMacroRemove) &&
03105               (symbol->command != CommandMacroRemoveAll))
03106             {
03107               t += "macro";
03108 
03109               CmtError::set (CmtError::symbol_not_found, t);
03110 
03111               return;
03112             }
03113         }
03114       else if ((m_action == action_show_set) ||
03115                (m_action == action_show_set_value))
03116         {
03117           if ((symbol->command != CommandSet) &&
03118               (symbol->command != CommandSetAppend) &&
03119               (symbol->command != CommandSetPrepend) &&
03120               (symbol->command != CommandSetRemove) &&
03121               (symbol->command != CommandPath) &&
03122               (symbol->command != CommandPathAppend) &&
03123               (symbol->command != CommandPathPrepend) &&
03124               (symbol->command != CommandPathRemove))
03125             {
03126               t += "set";
03127 
03128               CmtError::set (CmtError::symbol_not_found, t);
03129 
03130               return;
03131             }
03132         }
03133     }
03134 
03135   if (symbol->value_lists.size () < 1) return;
03136 
03137   symbol->show_macro (mode);
03138 }
03139 
03140 //----------------------------------------------------------
03141 void Cmt::do_show_macro_names (const CmtSystem::cmt_string_vector& arguments,
03142                                PrintMode& mode)
03143 {
03144   if (arguments.size () > 0)
03145     {
03146       const cmt_string& pattern = arguments[0];
03147       print_symbol_names (mode, pattern);
03148     }
03149   else
03150     {
03151       print_symbol_names (mode);
03152     }
03153 }
03154 
03155 //----------------------------------------------------------
03156 void Cmt::do_show_macro_value (const CmtSystem::cmt_string_vector& arguments,
03157                                PrintMode& mode)
03158 {
03159   do_show_macro (arguments, mode);
03160 }
03161 
03162 //----------------------------------------------------------
03163 void Cmt::do_show_macros (const CmtSystem::cmt_string_vector& arguments,
03164                           PrintMode& mode)
03165 {
03166   if (arguments.size () > 0)
03167     {
03168       const cmt_string& pattern = arguments[0];
03169       print_macros (mode, pattern);
03170     }
03171   else
03172     {
03173       print_macros (mode);
03174     }
03175 }
03176 
03177 //----------------------------------------------------------
03178 void Cmt::do_show_manager ()
03179 {
03180   Use& use = Use::current();
03181 
03182   cout << use.manager << endl;
03183 }
03184 
03185 //----------------------------------------------------------
03186 void Cmt::do_show_packages (const CmtSystem::cmt_string_vector& arguments)
03187 {
03188   cmt_string path_name;
03189 
03190   if (arguments.size () > 0) path_name = arguments[0];
03191 
03192   FileScanner scanner;
03193   PackageViewer viewer;
03194 
03195   if (path_name == "")
03196     {
03197       int path_index;
03198 
03199       for (path_index = 0; path_index < m_cmt_path.size (); path_index++)
03200         {
03201           const cmt_string& path = m_cmt_path[path_index];
03202 
03203           scanner.scan_path (path, viewer);
03204         }
03205     }
03206   else
03207     {
03208       scanner.scan_path (path_name, viewer);
03209     }
03210 }
03211 
03212 //----------------------------------------------------------
03213 void Cmt::do_show_path ()
03214 {
03215   int path_index;
03216 
03217   if (!m_quiet)
03218     {
03219       for (path_index = 0; path_index < m_cmt_path.size (); path_index++)
03220         {
03221           const cmt_string& path   = m_cmt_path[path_index];
03222           const cmt_string& source = m_cmt_path_sources[path_index];
03223 
03224           cout << "# Add path " << path << " from " << source << endl;
03225         }
03226 
03227       cout << "#" << endl;
03228     }
03229 
03230   for (path_index = 0; path_index < m_cmt_path.size (); path_index++)
03231     {
03232       const cmt_string& path   = m_cmt_path[path_index];
03233       const cmt_string& source = m_cmt_path_sources[path_index];
03234 
03235       if (path_index > 0) cout << CmtSystem::path_separator ();
03236 
03237       cout << path;
03238     }
03239 
03240   cout << endl;
03241 }
03242 
03243 //----------------------------------------------------------
03244 void Cmt::do_show_pattern (const CmtSystem::cmt_string_vector& arguments)
03245 {
03246   cmt_string name;
03247   if (arguments.size () > 0) name = arguments[0];
03248   Pattern::show (name);
03249 }
03250 
03251 //----------------------------------------------------------
03252 void Cmt::do_show_pattern_names ()
03253 {
03254   Pattern::show_all_names ();
03255 }
03256 
03257 //----------------------------------------------------------
03258 void Cmt::do_show_patterns ()
03259 {
03260   Pattern::show_all ();
03261 }
03262 
03263 //----------------------------------------------------------
03264 void Cmt::do_show_pwd ()
03265 {
03266   cout << m_current_dir << endl;
03267 }
03268 
03269 //----------------------------------------------------------
03270 void Cmt::do_show_set (const CmtSystem::cmt_string_vector& arguments,
03271                        PrintMode& mode)
03272 {
03273   do_show_macro (arguments, mode);
03274 }
03275 
03276 //----------------------------------------------------------
03277 void Cmt::do_show_set_names (const CmtSystem::cmt_string_vector& arguments,
03278                              PrintMode& mode)
03279 {
03280   if (arguments.size () > 0)
03281     {
03282       const cmt_string& pattern = arguments[0];
03283       print_symbol_names (mode, pattern);
03284     }
03285   else
03286     {
03287       print_symbol_names (mode);
03288     }
03289 }
03290 
03291 //----------------------------------------------------------
03292 void Cmt::do_show_set_value (const CmtSystem::cmt_string_vector& arguments,
03293                              PrintMode& mode)
03294 {
03295   do_show_macro (arguments, mode);
03296 }
03297 
03298 //----------------------------------------------------------
03299 void Cmt::do_show_sets (const CmtSystem::cmt_string_vector& arguments,
03300                         PrintMode& mode)
03301 {
03302   if (arguments.size () > 0)
03303     {
03304       const cmt_string& pattern = arguments[0];
03305       print_macros (mode, pattern);
03306     }
03307   else
03308     {
03309       print_macros (mode);
03310     }
03311 }
03312 
03313 //----------------------------------------------------------
03314 void Cmt::do_show_strategies ()
03315 {
03316   cout << "Version strategy : ";
03317 
03318   switch (m_current_strategy)
03319     {
03320     case BestFit :
03321       cout << "BestFit";
03322       break;
03323     case BestFitNoCheck :
03324       cout << "BestFitNoCheck";
03325       break;
03326     case FirstChoice :
03327       cout << "FirstChoice";
03328       break;
03329     case LastChoice :
03330       cout << "LastChoice";
03331       break;
03332     case KeepAll :
03333       cout << "KeepAll";
03334       break;
03335     default :
03336       cout << "BestFit";
03337       break;
03338     }
03339   
03340   cout << endl;
03341   
03342   cout << "Build strategy   : ";
03343   
03344   if ((m_current_build_strategy & PrototypesMask) == Prototypes)
03345     {
03346       cout << "prototypes";
03347     }
03348   else
03349     {
03350       cout << "no_prototypes";
03351     }
03352   
03353   if ((m_current_build_strategy & KeepMakefilesMask) == KeepMakefiles)
03354     {
03355       cout << " keep_makefiles";
03356     }
03357   else
03358     {
03359       cout << " rebuild_makefiles";
03360     }
03361   
03362   cout << endl;
03363 }
03364 
03365 //----------------------------------------------------------
03366 void Cmt::do_show_tags ()
03367 {
03368   Tag::TagPtrVector tags = Tag::tags ();
03369   int index;
03370 
03371   set_standard_macros ();
03372 
03373   for (index = 0; index < tags.size (); index++)
03374     {
03375       const Tag* tag = tags[index];
03376       if (tag != 0)
03377         {
03378           tag->show (m_quiet);
03379         }
03380     }
03381 }
03382 
03383 //----------------------------------------------------------
03384 void Cmt::do_show_uses ()
03385 {
03386   Use::show_all ();
03387 
03388 /*
03389   {
03390     Use::UsePtrVector& Uses = Use::uses ();
03391 
03392     Use& cu = Use::current ();
03393 
03394     for (int i = 0; i < Uses.size (); i++)
03395       {
03396         Use* use = Uses[i];
03397         
03398         if (use == 0) continue;
03399         if (use->discarded) continue;
03400         
03401         Use::UsePtrVector list;
03402         
03403         cu.get_paths (use, list);
03404 
03405         cout << " to " << use->package << endl;
03406 
03407         for (int j = list.size (); j >= 0; j--)
03408           {
03409             Use* u = list[j];
03410             if (u == 0) continue;
03411             cout << "  " << u->package << endl;
03412           }
03413       }
03414   }
03415 */
03416 }
03417 
03418 //----------------------------------------------------------
03419 void Cmt::do_show_version ()
03420 {
03421   cout << m_current_version << endl;
03422 }
03423 
03424 //----------------------------------------------------------
03425 void Cmt::do_show_versions (const CmtSystem::cmt_string_vector& arguments)
03426 {
03427   cmt_string package_name;
03428 
03429   if (arguments.size () > 0) package_name = arguments[0];
03430 
03431   FileScanner scanner;
03432 
03433   int path_index;
03434 
03435   for (path_index = 0; path_index < m_cmt_path.size (); path_index++)
03436     {
03437       const cmt_string& path   = m_cmt_path[path_index];
03438 
03439       scanner.scan_package (path, package_name);
03440     }
03441 }
03442 
03443 //----------------------------------------------------------
03444 void Cmt::do_show_system ()
03445 {
03446   cout << CmtSystem::get_cmt_config () << endl;
03447 }
03448 
03449 //----------------------------------------------------------
03450 void Cmt::do_unlock (const cmt_string& package,
03451                      const cmt_string& version,
03452                      const cmt_string& path)
03453 {
03454   // (unused??) Use& use = Use::current();
03455 
03456   cout << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
03457 
03458   set_standard_macros ();
03459 
03460   CmtLock::status status = CmtLock::unlock ();
03461 }
03462 
03463 //----------------------------------------------------------
03464 void Cmt::do_version ()
03465 {
03466   cout << CMTVERSION << endl;
03467 }
03468 
03469 
03470 
03471 //----------------------------------------------------------
03472 ActionType Cmt::get_action ()
03473 {
03474   return (m_action);
03475 }
03476 
03477 const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
03478 {
03479   return (m_cmt_path);
03480 }
03481 
03482 const cmt_string& Cmt::get_cmt_home ()
03483 {
03484   return (m_cmt_home);
03485 }
03486 
03487 const cmt_string& Cmt::get_cmt_user_context ()
03488 {
03489   return (m_cmt_user_context);
03490 }
03491 
03492 const cmt_string& Cmt::get_current_dir ()
03493 {
03494   return (m_current_dir);
03495 }
03496 
03497 const cmt_string& Cmt::get_current_package ()
03498 {
03499   return (m_current_package);
03500 }
03501 
03502 AccessMode Cmt::get_current_access ()
03503 {
03504   return (m_current_access);
03505 }
03506 
03507 VersionStrategy Cmt::get_current_strategy ()
03508 {
03509   return (m_current_strategy);
03510 }
03511 
03512 const cmt_string& Cmt::get_current_version ()
03513 {
03514   return (m_current_version);
03515 }
03516 
03517 const cmt_string& Cmt::get_current_target ()
03518 {
03519   return (m_current_target);
03520 }
03521 
03522 bool Cmt::get_debug ()
03523 {
03524   return (m_debug);
03525 }
03526 
03527 bool Cmt::get_quiet ()
03528 {
03529   return (m_quiet);
03530 }
03531 
03532 bool Cmt::get_recursive ()
03533 {
03534   return (m_recursive);
03535 }
03536 
03537 ScopeType Cmt::get_scope ()
03538 {
03539   return (m_scope);
03540 }
03541 
03542 //----------------------------------------------------------
03543 const cmt_string& Cmt::filter_dir (const cmt_string& dir)
03544 {
03545   static cmt_string newdir;
03546 
03547   CmtSystem::compress_path (dir, newdir);
03548 
03549   return (newdir);
03550 }
03551 
03552 //----------------------------------------------------------
03553 void Cmt::install_cleanup_scripts ()
03554 {
03555 #ifdef WIN32
03556   static const int modes = 1;
03557   static const cmt_string suffix[1]   = {"bat"};
03558   static const PrintMode  mode[1]     = {Bat};
03559 #else
03560   static const int modes = 2;
03561   static const cmt_string suffix[2]   = {"csh", "sh"};
03562   static const PrintMode  mode[2]     = {Csh, Sh};
03563 #endif
03564 
03565   cout << "Creating cleanup scripts." << endl;
03566 
03567   cmt_string temp;
03568   int i;
03569 
03570   for (i = 0; i < modes; i++)
03571     {
03572       cmt_string file_name = "cleanup";
03573       file_name += ".";
03574       file_name += suffix[i];
03575       file_name += ".";
03576       file_name += "new";
03577 
03578       FILE* f = fopen (file_name.c_str (), "wb");
03579       if (f != NULL)
03580         {
03581           if (mode[i] == Csh)
03582             {
03583               fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03584               fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
03585               fprintf (f, "${CMTROOT}/mgr/cmt -quiet cleanup -%s "
03586                        "-pack=%s -version=%s -path=%s $* >${tempfile}; "
03587                        "source ${tempfile}\n",
03588                        suffix[i].c_str (),
03589                        m_current_package.c_str (),
03590                        m_current_version.c_str (),
03591                        m_current_path.c_str ());
03592               fprintf (f, "/bin/rm -f ${tempfile}\n");
03593             }
03594           else if (mode[i] == Sh)
03595             {
03596               fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03597               fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
03598               fprintf (f, "${CMTROOT}/mgr/cmt -quiet cleanup -%s "
03599                        "-pack=%s -version=%s -path=%s $* >${tempfile}; "
03600                        ". ${tempfile}\n",
03601                        suffix[i].c_str (),
03602                        m_current_package.c_str (),
03603                        m_current_version.c_str (),
03604                        m_current_path.c_str ());
03605               fprintf (f, "/bin/rm -f ${tempfile}\n");
03606             }
03607           else if (mode[i] == Bat)
03608             {
03609               fprintf (f, "set tempfile=%%HOMEDRIVE%%%%HOMEPATH%%tmpsetup.bat\n");
03610               fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe -quiet cleanup -%s "
03611                        "-path=%s "
03612                        "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%tempfile%%\n",
03613                        suffix[i].c_str (),
03614                        m_current_path.c_str ());
03615               fprintf (f, "if exist %%tempfile%% call %%tempfile%%\n");
03616               fprintf (f, "if exist %%tempfile%% del %%tempfile%%\n");
03617             }
03618 
03619           fprintf (f, "\n");
03620 
03621           fclose (f);
03622 
03623           cmt_string old_file_name = "cleanup";
03624           old_file_name += ".";
03625           old_file_name += suffix[i];
03626 
03627           CmtSystem::compare_and_update_files (file_name, old_file_name);
03628         }
03629     }
03630 }
03631 
03632 //----------------------------------------------------------
03633 void Cmt::install_setup_scripts ()
03634 {
03635 #ifdef WIN32
03636   static const int modes = 1;
03637   static const cmt_string suffix[1]   = {"bat"};
03638   static const PrintMode  mode[1]     = {Bat};
03639 #else
03640   static const int modes = 2;
03641   static const cmt_string suffix[2]   = {"csh", "sh"};
03642   static const PrintMode  mode[2]     = {Csh, Sh};
03643 #endif
03644 
03645   cout << "Creating setup scripts." << endl;
03646 
03647   cmt_string temp;
03648   int i;
03649 
03650   for (i = 0; i < modes; i++)
03651     {
03652       cmt_string file_name = "setup";
03653       file_name += ".";
03654       file_name += suffix[i];
03655       file_name += ".";
03656       file_name += "new";
03657 
03658       FILE* f = fopen (file_name.c_str (), "wb");
03659       if (f != NULL)
03660         {
03661           if (mode[i] == Csh)
03662             {
03663               fprintf (f, "# echo \"Setting %s %s in %s\"\n",
03664                        m_current_package.c_str (),
03665                        m_current_version.c_str (),
03666                        m_current_path.c_str ());
03667               fprintf (f, "\n");
03668 
03669               fprintf (f, "setenv CMTROOT %s\n", m_cmt_root.c_str ());
03670               fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
03671               fprintf (f, "\n");
03672               fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03673               fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
03674               fprintf (f, "${CMTROOT}/mgr/cmt -quiet setup -%s "
03675                        "-pack=%s -version=%s -path=%s $* >${tempfile}; "
03676                        "source ${tempfile}\n",
03677                        suffix[i].c_str (),
03678                        m_current_package.c_str (),
03679                        m_current_version.c_str (),
03680                        m_current_path.c_str ());
03681               fprintf (f, "/bin/rm -f ${tempfile}\n");
03682             }
03683           else if (mode[i] == Sh)
03684             {
03685               fprintf (f, "# echo \"Setting %s %s in %s\"\n",
03686                        m_current_package.c_str (),
03687                        m_current_version.c_str (),
03688                        m_current_path.c_str ());
03689               fprintf (f, "\n");
03690 
03691               fprintf (f, "CMTROOT=%s; export CMTROOT\n", m_cmt_root.c_str ());
03692               fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
03693               fprintf (f, "\n");
03694               fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03695               fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
03696               fprintf (f, "${CMTROOT}/mgr/cmt -quiet setup -%s "
03697                        "-pack=%s -version=%s -path=%s $* >${tempfile}; "
03698                        ". ${tempfile}\n",
03699                        suffix[i].c_str (),
03700                        m_current_package.c_str (),
03701                        m_current_version.c_str (),
03702                        m_current_path.c_str ());
03703               fprintf (f, "/bin/rm -f ${tempfile}\n");
03704             }
03705           else if (mode[i] == Bat)
03706             {
03707               fprintf (f, "rem Setting %s %s in %s\n",
03708                        m_current_package.c_str (),
03709                        m_current_version.c_str (),
03710                        m_current_path.c_str ());
03711               fprintf (f, "@echo off\n");
03712 
03713               fprintf (f, "set CMTROOT=%s\n", m_cmt_root.c_str ());
03714               fprintf (f, "call %%CMTROOT%%\\mgr\\setup.bat\n");
03715               fprintf (f, "\n");
03716               fprintf (f, "set tempfile=%%HOMEDRIVE%%%%HOMEPATH%%tmpsetup.bat\n");
03717               fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe -quiet setup -%s "
03718                        "-pack=%s -version=%s -path=%s "
03719                        "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%tempfile%%\n",
03720                        suffix[i].c_str (),
03721                        m_current_package.c_str (),
03722                        m_current_version.c_str (),
03723                        m_current_path.c_str ());
03724               fprintf (f, "if exist %%tempfile%% call %%tempfile%%\n");
03725               fprintf (f, "if exist %%tempfile%% del %%tempfile%%\n");
03726             }
03727 
03728           fprintf (f, "\n");
03729 
03730           fclose (f);
03731 
03732           cmt_string old_file_name = "setup";
03733           old_file_name += ".";
03734           old_file_name += suffix[i];
03735 
03736           CmtSystem::compare_and_update_files (file_name, old_file_name);
03737         }
03738     }
03739 }
03740 
03741 //----------------------------------------------------------
03742 void Cmt::install_test_cleanup_scripts ()
03743 {
03744 #ifdef WIN32
03745   static const int modes = 1;
03746   static const cmt_string suffix[1]   = {"bat"};
03747   static const PrintMode  mode[1]     = {Bat};
03748 #else
03749   static const int modes = 2;
03750   static const cmt_string suffix[2]   = {"csh", "sh"};
03751   static const PrintMode  mode[2]     = {Csh, Sh};
03752 #endif
03753 
03754   cout << "Creating cleanup scripts." << endl;
03755 
03756   cmt_string temp;
03757   int i;
03758 
03759   for (i = 0; i < modes; i++)
03760     {
03761       cmt_string file_name = "cleanup";
03762       file_name += ".";
03763       file_name += suffix[i];
03764       file_name += ".";
03765       file_name += "new";
03766 
03767       FILE* f = fopen (file_name.c_str (), "wb");
03768       if (f != NULL)
03769         {
03770           if (mode[i] == Csh)
03771             {
03772               fprintf (f, "setenv CMTROOT %s\n", m_cmt_root.c_str ());
03773               fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
03774               fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03775               fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
03776               fprintf (f, "${CMTROOT}/mgr/cmt -quiet cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
03777                        "source ${tempfile}\n",
03778                        suffix[i].c_str (),
03779                        m_current_path.c_str ());
03780               fprintf (f, "/bin/rm -f ${tempfile}\n");
03781             }
03782           else if (mode[i] == Sh)
03783             {
03784               fprintf (f, "CMTROOT=%s; export CMTROOT\n", m_cmt_root.c_str ());
03785               fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
03786               fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03787               fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
03788               fprintf (f, "${CMTROOT}/mgr/cmt -quiet cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
03789                        ". ${tempfile}\n",
03790                        suffix[i].c_str (),
03791                        m_current_path.c_str ());
03792               fprintf (f, "/bin/rm -f ${tempfile}\n");
03793             }
03794           else
03795             {
03796               fprintf (f, "set CMTROOT=%s\n", m_cmt_root.c_str ());
03797               fprintf (f, "call %%CMTROOT%%\\mgr\\setup.bat\n");
03798               fprintf (f, "set tempfile=%%HOMEDRIVE%%%%HOMEPATH%%tmpsetup.bat\n");
03799               fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe -quiet cleanup -%s "
03800                        "-pack=cmt_standalone -path=%s "
03801                        "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%tempfile%%\n",
03802                        suffix[i].c_str (),
03803                        m_current_path.c_str ());
03804               fprintf (f, "if exist %%tempfile%% call %%tempfile%%\n");
03805               fprintf (f, "if exist %%tempfile%% del %%tempfile%%\n");
03806             }
03807 
03808           fprintf (f, "\n");
03809 
03810           fclose (f);
03811 
03812           cmt_string old_file_name = "cleanup";
03813           old_file_name += ".";
03814           old_file_name += suffix[i];
03815 
03816           CmtSystem::compare_and_update_files (file_name, old_file_name);
03817         }
03818     }
03819 }
03820 
03821 //----------------------------------------------------------
03822 void Cmt::install_test_setup_scripts ()
03823 {
03824 #ifdef WIN32
03825   static const int modes = 1;
03826   static const cmt_string suffix[1]   = {"bat"};
03827   static const PrintMode  mode[1]     = {Bat};
03828 #else
03829   static const int modes = 2;
03830   static const cmt_string suffix[2]   = {"csh", "sh"};
03831   static const PrintMode  mode[2]     = {Csh, Sh};
03832 #endif
03833 
03834   cout << "Creating setup scripts." << endl;
03835 
03836   cmt_string temp;
03837   int i;
03838 
03839   for (i = 0; i < modes; i++)
03840     {
03841       cmt_string file_name = "setup";
03842       file_name += ".";
03843       file_name += suffix[i];
03844       file_name += ".";
03845       file_name += "new";
03846 
03847       FILE* f = fopen (file_name.c_str (), "wb");
03848       if (f != NULL)
03849         {
03850           if (mode[i] == Csh)
03851             {
03852               fprintf (f, "# echo \"Setting standalone package\"\n");
03853               fprintf (f, "\n");
03854 
03855               fprintf (f, "setenv CMTROOT %s\n", m_cmt_root.c_str ());
03856               fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
03857               fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03858               fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
03859               fprintf (f, "${CMTROOT}/mgr/cmt -quiet setup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
03860                        "source ${tempfile}\n",
03861                        suffix[i].c_str (),
03862                        m_current_path.c_str ());
03863               fprintf (f, "/bin/rm -f ${tempfile}\n");
03864             }
03865           else if (mode[i] == Sh)
03866             {
03867               fprintf (f, "# echo \"Setting standalone package\"\n");
03868               fprintf (f, "\n");
03869 
03870               fprintf (f, "CMTROOT=%s; export CMTROOT\n", m_cmt_root.c_str ());
03871               fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
03872               fprintf (f, "\n");
03873               fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt build temporary_name -quiet`\n");
03874               fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
03875               fprintf (f, "${CMTROOT}/mgr/cmt -quiet setup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
03876                        ". ${tempfile}\n",
03877                        suffix[i].c_str (),
03878                        m_current_path.c_str ());
03879               fprintf (f, "/bin/rm -f ${tempfile}\n");
03880             }
03881           else
03882             {
03883               fprintf (f, "rem Setting standalone package\n");
03884               fprintf (f, "@echo off\n");
03885 
03886               fprintf (f, "set CMTROOT=%s\n", m_cmt_root.c_str ());
03887               fprintf (f, "call %%CMTROOT%%\\mgr\\setup.bat\n");
03888               fprintf (f, "\n");
03889               fprintf (f, "set tempfile=%%HOMEDRIVE%%%%HOMEPATH%%tmpsetup.bat\n");
03890               fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe -quiet setup -%s "
03891                        "-pack=cmt_standalone -path=%s "
03892                        "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%tempfile%%\n",
03893                        suffix[i].c_str (),
03894                        m_current_path.c_str ());
03895               fprintf (f, "if exist %%tempfile%% call %%tempfile%%\n");
03896               fprintf (f, "if exist %%tempfile%% del %%tempfile%%\n");
03897             }
03898 
03899           fprintf (f, "\n");
03900 
03901           fclose (f);
03902 
03903           cmt_string old_file_name = "setup";
03904           old_file_name += ".";
03905           old_file_name += suffix[i];
03906 
03907           CmtSystem::compare_and_update_files (file_name, old_file_name);
03908         }
03909     }
03910 }
03911 
03917 bool Cmt::load (const cmt_string& path,
03918                 const cmt_string& package,
03919                 const cmt_string& version,
03920                 const cmt_string& tag_name)
03921 {
03922   clear ();
03923   configure ();
03924 
03925   m_action  = action_load;
03926   m_recursive = true;
03927 
03928   if (((package != "") && (version != "")) || (m_current_package == ""))
03929     {
03930       //
03931       //  Here we want to connect to a new package, or to the current package
03932       //  but with another tag.
03933       //
03934       //   the 'package' argument may include a directory offset. Thus 'path'
03935       //  is only expected to hold the base directory.
03936       //
03937       cmt_string offset;
03938       cmt_string package_name;
03939       
03940       CmtSystem::dirname (package, offset);
03941       CmtSystem::basename (package, package_name);
03942       
03943       if (offset != "")
03944         {
03945           m_current_path = path;
03946           m_current_path += CmtSystem::file_separator ();
03947           m_current_path += offset;
03948         }
03949       else
03950         {
03951           m_current_path = path;
03952         }
03953       
03954       m_current_package = package_name;
03955       m_current_version = version;
03956     }
03957 
03958   if (tag_name != "")
03959     {
03960       Tag* tag;
03961 
03962       Tag::unmark_all ();
03963       configure_site_tag (0);
03964       configure_uname_tag ();
03965       configure_hosttype_tag ();
03966 
03967       m_current_tag = tag_name;
03968 
03969       //if (!m_quiet) cerr << "load1> current_tag=" << m_current_tag << endl;
03970 
03971       tag = Tag::add (tag_name, PriorityTag, "load", 0);
03972       tag->mark ();
03973     }
03974 
03975   /*
03976     Set to developer mode if positioned into the package
03977     (which is detected since we were able to retreive the
03978     Version, Package and Path)
03979   */
03980 
03981   if ((m_current_path == "") ||
03982       (m_current_package == "") ||
03983       (m_current_version == ""))
03984     {
03985       m_current_access = UserMode;
03986     }
03987   else
03988     {
03989       m_current_access = DeveloperMode;
03990     }
03991 
03992   use_cmt ();
03993 
03994   cmt_string dir;
03995 
03996   /*
03997     Try to access the package.
03998   */
03999 
04000   if (m_current_path != "")
04001     {
04002       dir = m_current_path;
04003     }
04004   else
04005     {
04006       dir = m_default_path;
04007     }
04008 
04009   if (!CmtSystem::cd (m_current_path))
04010     {
04011       if (!m_quiet)
04012         {
04013           cout << "#CMT> Cannot reach the directory " <<
04014             m_current_path << endl;
04015         }
04016       CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
04017       CmtSystem::cd (m_current_dir);
04018 
04019       return (false);
04020     }
04021 
04022   dir += CmtSystem::file_separator ();
04023   dir += m_current_package;
04024 
04025   if (!CmtSystem::cd (m_current_package))
04026     {
04027       if (!m_quiet)
04028         {
04029           cout << "#CMT::load> Cannot reach the package " <<
04030             m_current_package << endl;
04031         }
04032       CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
04033       CmtSystem::cd (m_current_dir);
04034 
04035       return (false);
04036     }
04037 
04038   dir += CmtSystem::file_separator ();
04039   dir += m_current_version;
04040 
04041   if (!CmtSystem::cd (m_current_version))
04042     {
04043       if (!m_quiet)
04044         {
04045           cout << "#CMT> Cannot reach the version " <<
04046             m_current_version << endl;
04047         }
04048       CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
04049       CmtSystem::cd (m_current_dir);
04050 
04051       return (false);
04052     }
04053 
04054   if (CmtSystem::cd ("cmt"))
04055     {
04056       dir += CmtSystem::file_separator ();
04057       dir += "cmt";
04058       m_current_style = cmt_style;
04059     }
04060   else
04061     {
04062       /*
04063         if (!m_quiet)
04064         {
04065         cout << "Cannot reach the cmt branch" << endl;
04066         }
04067       */
04068 
04069       if (CmtSystem::cd ("mgr"))
04070         {
04071           dir += CmtSystem::file_separator ();
04072           dir += "mgr";
04073           m_current_style = mgr_style;
04074         }
04075       else
04076         {
04077           if (!m_quiet)
04078             {
04079               cout << "#CMT> Cannot reach the mgr branch" << endl;
04080             }
04081 
04082           CmtError::set (CmtError::package_not_found,
04083                          "Load> Cannot reach the mgr/cmt directory");
04084           CmtSystem::cd (m_current_dir);
04085 
04086           return (false);
04087         }
04088     }
04089 
04090   /*
04091     Check Tag is always set up
04092   */
04093 
04094   if (m_current_tag == "")
04095     {
04096       char* env;
04097 
04098       env = getenv (m_current_config.c_str ());
04099       if (env != 0)
04100         {
04101           Tag* tag;
04102 
04103           tag = Tag::add (env, PriorityConfig, "load", 0);
04104           tag->mark ();
04105           m_current_tag = env;
04106 
04107           //if (!m_quiet) cerr << "load2> current_tag=" << m_current_tag << endl;
04108 
04109         }
04110       else
04111         {
04112           m_current_tag = m_cmt_config;
04113 
04114           //if (!m_quiet) cerr << "load3> current_tag=" << m_current_tag << endl;
04115 
04116         }
04117     }
04118 
04119   if (m_debug)
04120     {
04121       cout << "pwd = " << CmtSystem::pwd () << endl;
04122     }
04123 
04124   configure_current_dir ();
04125   build_prefix (m_current_package, m_current_prefix);
04126   build_config (m_current_prefix, m_current_config);
04127 
04128   Use* use = &(Use::current());
04129   use->path    = m_current_path;
04130   use->package = m_current_package;
04131   use->version = m_current_version;
04132   use->prefix  = m_current_prefix;
04133   use->done    = false;
04134 
04135   /*
04136     Work on the requirements file.
04137   */
04138 
04139   dir += CmtSystem::file_separator ();
04140   dir += "requirements";
04141   parse_requirements (dir, use);
04142 
04143   if (CmtError::has_pending_error ()) return (false);
04144 
04148   Pattern::apply_all_globals ();
04149 
04150   /*
04151     Select all possible tags
04152   */
04153 
04154   Tag::restore_tree ();
04155 
04156   return (true);
04157 }
04158 
04159 //----------------------------------------------------------
04160 bool Cmt::need_prototypes ()
04161 {
04162   if ((m_current_build_strategy & PrototypesMask) == Prototypes) return (true);
04163   else return (false);
04164 }
04165 
04166 //----------------------------------------------------------
04167 void Cmt::parse_arguments (int argc, char* argv[],
04168                            CmtSystem::cmt_string_vector& arguments,
04169                            cmt_string& extra_line,
04170                            cmt_string& extra_file,
04171                            PrintMode& mode)
04172 {
04173   /*
04174     Decoding arguments.
04175 
04176     While decoding all arguments, no requirements analysis should
04177     occur. Every new option, or parameter should be saved and
04178     used later at actual analysis time.
04179   */
04180 
04181   cmt_string arg;
04182 
04183   m_action = action_none;
04184 
04185   arguments.clear ();
04186   extra_line.erase (0);
04187   extra_file.erase (0);
04188   mode = Csh;
04189 
04190     /*
04191       Tag management.
04192       ---------------
04193 
04194       Tag settings may come from :
04195 
04196       - existing environment variables:
04197 
04198           1) CMTCONFIG
04199 
04200           2) CMTEXTRATAGS for addons
04201 
04202       - arguments:
04203 
04204           -tag=<tag-list>
04205           -tag_add=<tag-list>
04206           -tag_remove=<tag-list>
04207 
04208        o Arguments should take precedence over environment variables.
04209        o when nothing is specified:
04210 
04211           - primary tag = CMTCONFIG
04212           - tag set is empty
04213 
04214 
04215      */
04216 
04217 
04218   restore_all_tags (0);
04219 
04220 #ifdef WIN32
04221   m_build_nmake = true;
04222 #endif
04223 
04224   while (argc > 1)
04225     {
04226       int lf;
04227 
04228       arg = argv[1];
04229       lf = arg.find ('\r');
04230       if (lf != cmt_string::npos) arg.erase (lf);
04231 
04232       if ((arg[0] == '\"') && (arg[arg.size () - 1] == '\"'))
04233         {
04234           arg.erase (0, 1);
04235           arg.erase (arg.size () - 1, 1);
04236         }
04237 
04238       //fprintf (stderr, "arg=[%s]\n", arg.c_str ());
04239 
04240       switch (arg[0])
04241         {
04242         case 'a' :
04243           if (arg == "awk")
04244             {
04245               argc--;
04246               argv++;
04247               while (argc > 1)
04248                 {
04249                   cmt_string& s = arguments.add ();
04250                   s = argv[1];
04251                   argc--;
04252                   argv++;
04253                 }
04254 
04255               m_action = action_awk;
04256             }
04257           break;
04258         case 'b' :
04259           if ((arg == "b") ||
04260               (arg == "br") ||
04261               (arg == "bro") ||
04262               (arg == "broa") ||
04263               (arg == "broad") ||
04264               (arg == "broadc") ||
04265               (arg == "broadca") ||
04266               (arg == "broadcas") ||
04267               (arg == "broadcast"))
04268             {
04269               argc--;
04270               argv++;
04271               while (argc > 1)
04272                 {
04273                   cmt_string& s = arguments.add ();
04274                   s = argv[1];
04275                   argc--;
04276                   argv++;
04277                 }
04278 
04279               m_action = action_broadcast;
04280             }
04281           else if (arg == "build")
04282             {
04283               argc--;
04284               argv++;
04285 
04286               if (argc > 1)
04287                 {
04288                   arg = argv[1];
04289 
04290                   if (arg == "-nmake")
04291                     {
04292                       m_build_nmake = true;
04293                       argc--;
04294                       argv++;
04295                     }
04296                 }
04297 
04298               if (argc > 1)
04299                 {
04300                   arg = argv[1];
04301 
04302                   if (arg == "-nmake")
04303                     {
04304                       argc--;
04305                       argv++;
04306                     }
04307 
04308                   if (arg == "constituent_makefile")
04309                     {
04310                       argc--;
04311                       argv++;
04312                       if (argc > 1)
04313                         {
04314                           cmt_string& s = arguments.add ();
04315                           s = argv[1];
04316 
04317                           m_action = action_build_constituent_makefile;
04318                         }
04319                       else
04320                         {
04321                           if (!m_quiet) cout << "#CMT> syntax error : constituent name missing" << endl;
04322                         }
04323                     }
04324                   else if (arg == "constituents_makefile")
04325                     {
04326                       m_action = action_build_constituents_makefile;
04327                     }
04328                   else if (arg == "dependencies")
04329                     {
04330                       argc--;
04331                       argv++;
04332                       if (argc > 1)
04333                         {
04334                           cmt_string& s = arguments.add ();
04335                           s = argv[1];
04336 
04337                           m_action = action_build_dependencies;
04338                         }
04339                       else
04340                         {
04341                           if (!m_quiet) cout << "#CMT> syntax error : arguments missing " << endl;
04342                         }
04343 
04344                       argc = 0;
04345                     }
04346                   else if (arg == "library_links")
04347                     {
04348                       m_action = action_build_library_links;
04349                     }
04350                   else if (arg == "make_setup")
04351                     {
04352                       m_action = action_build_make_setup;
04353                     }
04354                   else if (arg == "msdev")
04355                     {
04356                       argc--;
04357                       argv++;
04358 
04359                       if (argc > 1)
04360                         {
04361                           cmt_string& s = arguments.add ();
04362                           s = argv[1];
04363                           if (s[0] == '-')
04364                             {
04365                               s = "";
04366                               argc++;
04367                               argv--;
04368                             }
04369                         }
04370 
04371                       m_action = action_build_msdev;
04372                     }
04373                   else if (arg == "os9_makefile")
04374                     {
04375                       argc--;
04376                       argv++;
04377                       if (argc > 1)
04378                         {
04379                           cmt_string& s = arguments.add ();
04380                           s = argv[1];
04381 
04382                           m_action = action_build_os9_makefile;
04383                         }
04384                       else
04385                         {
04386                           if (!m_quiet) cout << "#CMT> syntax error : arguments missing " << endl;
04387                         }
04388                     }
04389                   else if (arg == "prototype")
04390                     {
04391                       argc--;
04392                       argv++;
04393                       if (argc > 1)
04394                         {
04395                           cmt_string& s = arguments.add ();
04396                           s = argv[1];
04397 
04398                           m_action = action_build_prototype;
04399                         }
04400                       else
04401                         {
04402                           if (!m_quiet) cout << "#CMT> syntax error : arguments missing" << endl;
04403                         }
04404                     }
04405                   else if (arg == "readme")
04406                     {
04407                       m_action = action_build_readme;
04408 
04409                       argc--;
04410                       argv++;
04411                       while (argc > 1)
04412                         {
04413                           cmt_string& s = arguments.add ();
04414                           s = argv[1];
04415                           argc--;
04416                           argv++;
04417                         }
04418                     }
04419                   else if (arg == "tag_makefile")
04420                     {
04421                       m_action = action_build_tag_makefile;
04422                     }
04423                   else if (arg == "temporary_name")
04424                     {
04425                       m_action = action_build_temporary_name;
04426                     }
04427                   else if (arg == "triggers")
04428                     {
04429                       argc--;
04430                       argv++;
04431                       if (argc > 1)
04432                         {
04433                           cmt_string& s = arguments.add ();
04434                           s = argv[1];
04435 
04436                           m_action = action_build_triggers;
04437                         }
04438                       else
04439                         {
04440                           if (!m_quiet) cout << "#CMT> syntax error : arguments missing" << endl;
04441                         }
04442                     }
04443                   else if (arg == "windefs")
04444                     {
04445                       argc--;
04446                       argv++;
04447                       if (argc > 1)
04448                         {
04449                           cmt_string& s = arguments.add ();
04450                           s = argv[1];
04451 
04452                           m_action = action_build_windefs;
04453                         }
04454                       else
04455                         {
04456                           if (!m_quiet) cout << "#CMT> syntax error : arguments missing" << endl;
04457                         }
04458                     }
04459                 }
04460               else
04461                 {
04462                   if (!m_quiet) cout << "#CMT> syntax error : don't know what to build" << endl;
04463                 }
04464             }
04465           else
04466             {
04467               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04468             }
04469           break;
04470         case 'c' :
04471           if (arg == "check")
04472             {
04473               argc--;
04474               argv++;
04475 
04476               if (argc > 1)
04477                 {
04478                   arg = argv[1];
04479 
04480                   if (arg == "configuration")
04481                     {
04482                       m_action = action_check_configuration;
04483                     }
04484                   else if (arg == "files")
04485                     {
04486                       argc--;
04487                       argv++;
04488                       if (argc > 1)
04489                         {
04490                           cmt_string& s = arguments.add ();
04491                           s = argv[1];
04492                           argc--;
04493                           argv++;
04494                           if (argc > 1)
04495                             {
04496                               cmt_string& s = arguments.add ();
04497                               s = argv[1];
04498 
04499                               m_action = action_check_files;
04500                             }
04501                           else
04502                             {
04503                               if (!m_quiet) cout << "#CMT> syntax error : reference file name missing" 
04504                                                  << endl;
04505                             }
04506                         }
04507                       else
04508                         {
04509                           if (!m_quiet) cout << "#CMT> syntax error : file name missing" << endl;
04510                         }
04511                     }
04512                   else if (arg == "version")
04513                     {
04514                       argc--;
04515                       argv++;
04516                       if (argc > 1)
04517                         {
04518                           cmt_string& s = arguments.add ();
04519                           s = argv[1];
04520 
04521                           m_action = action_check_version;
04522                         }
04523                       else
04524                         {
04525                           if (!m_quiet) cout << "#CMT> syntax error : package name missing" << endl;
04526                         }
04527                     }
04528                   else
04529                     {
04530                       if (!m_quiet) cout << "#CMT> syntax error : bad check option" << endl;
04531                     }
04532                 }
04533               else
04534                 {
04535                   if (!m_quiet) cout << "#CMT> syntax error : don't know what to check" << endl;
04536                 }
04537             }
04538           else if (arg == "check_files")
04539             {
04540               argc--;
04541               argv++;
04542               if (argc > 1)
04543                 {
04544                   cmt_string& s = arguments.add ();
04545                   s = argv[1];
04546                   argc--;
04547                   argv++;
04548                   if (argc > 1)
04549                     {
04550                       cmt_string& s = arguments.add ();
04551                       s = argv[1];
04552 
04553                       m_action = action_check_files;
04554                     }
04555                   else
04556                     {
04557                       if (!m_quiet) cout << "#CMT> syntax error : reference file missing" << endl;
04558                     }
04559                 }
04560               else
04561                 {
04562                   if (!m_quiet) cout << "#CMT> syntax error : file name missing" << endl;
04563                 }
04564             }
04565           else if ((arg == "co") ||
04566                    (arg == "checkout"))
04567             {
04568               // handle all of the command line arguments in a vector
04569               argc--;
04570               argv++;
04571               if (argc > 1)
04572                 {
04573                   m_action = action_checkout;
04574 
04575                   while (argc > 1)
04576                     {
04577                       cmt_string& s = arguments.add ();
04578                       s = argv[1];
04579                       argc--;
04580                       argv++;
04581                     }
04582                 }
04583               else
04584                 {
04585                   if (!m_quiet) cout << "#CMT> syntax error : checkout arguments missing" << endl;
04586                 }
04587             }
04588           else if (arg == "cleanup")
04589             {
04590               m_action = action_cleanup;
04591             }
04592           else if (arg == "config")
04593             {
04594               argc--;
04595               argv++;
04596               if (argc > 1)
04597                 {
04598                   cout << "#---------------------------------------------------------" << endl;
04599                   cout << "# Warning : using 'cmt config ...' to create a package is "
04600                       "becoming obsolete" << endl;
04601                   cout << "# Please use 'cmt create ...' instead" << endl;
04602                   cout << "#---------------------------------------------------------" << endl;
04603 
04604                   m_current_package = argv[1];
04605                   m_current_version.erase (0);
04606                   m_current_path.erase (0);
04607 
04608                   argc--;
04609                   argv++;
04610                   if (argc > 1)
04611                     {
04612                       m_current_version = argv[1];
04613 
04614                       {
04615                         cmt_string& s = arguments.add ();
04616                         s = m_current_package;
04617                       }
04618                       {
04619                         cmt_string& s = arguments.add ();
04620                         s = m_current_version;
04621                       }
04622 
04623                       argc--;
04624                       argv++;
04625                       if (argc > 1)
04626                         {
04627                           m_current_path = argv[1];
04628                           if (m_current_path[0] == '-')
04629                             {
04630                               m_current_path.erase (0);
04631                             }
04632                         }
04633 
04634                       m_action = action_create;
04635                     }
04636                   else
04637                     {
04638                       if (!m_quiet) cout << "#CMT> syntax error : create arguments missing" << endl;
04639                     }
04640                 }
04641               else
04642                 {
04643                   m_action = action_config;
04644                 }
04645             }
04646           else if (arg == "create")
04647             {
04648               argc--;
04649               argv++;
04650 
04651               if (argc > 1)
04652                 {
04653                   while (argc > 1)
04654                     {
04655                       cmt_string& s = arguments.add ();
04656                       s = argv[1];
04657                       argc--;
04658                       argv++;
04659                     }
04660 
04661                   m_action = action_create;
04662                 }
04663               else
04664                 {
04665                   if (!m_quiet) cout << "#CMT> syntax error : create arguments missing" << endl;
04666                 }
04667             }
04668           else if (arg == "cvsbranches")
04669             {
04670               argc--;
04671               argv++;
04672               if (argc > 1)
04673                 {
04674                   cmt_string& s = arguments.add ();
04675                   s = argv[1];
04676                   argc--;
04677                   argv++;
04678 
04679                   m_action = action_cvsbranches;
04680                 }
04681               else
04682                 {
04683                   if (!m_quiet) cout << "#CMT> syntax error : cvsbranches arguments missing" << endl;
04684                 }
04685             }
04686           else if (arg == "cvssubpackages")
04687             {
04688               argc--;
04689               argv++;
04690               if (argc > 1)
04691                 {
04692                   cmt_string& s = arguments.add ();
04693                   s = argv[1];
04694                   argc--;
04695                   argv++;
04696 
04697                   m_action = action_cvssubpackages;
04698                 }
04699               else
04700                 {
04701                   if (!m_quiet) cout << "#CMT> syntax error : cvssubpackages arguments missing" << endl;
04702                 }
04703             }
04704           else if (arg == "cvstags")
04705             {
04706               argc--;
04707               argv++;
04708               if (argc > 1)
04709                 {
04710                   while (argc > 1)
04711                     {
04712                       cmt_string& s = arguments.add ();
04713                       s = argv[1];
04714                       argc--;
04715                       argv++;
04716                     }
04717 
04718                   m_action = action_cvstags;
04719                 }
04720               else
04721                 {
04722                   if (!m_quiet) cout << "#CMT> syntax error : package name missing" << endl;
04723                 }
04724             }
04725           else
04726             {
04727               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04728             }
04729           break;
04730         case 'e' :
04731           if (arg == "expand")
04732             {
04733               argc--;
04734               argv++;
04735 
04736               if (argc > 1)
04737                 {
04738                   arg = argv[1];
04739 
04740                   if (arg == "model")
04741                     {
04742                       argc--;
04743                       argv++;
04744 
04745                       if (argc > 1)
04746                         {
04747                           while (argc > 1)
04748                             {
04749                               cmt_string& s = arguments.add ();
04750                               s = argv[1];
04751                               argc--;
04752                               argv++;
04753                             }
04754 
04755                           m_action = action_expand_model;
04756                         }
04757                       else
04758                         {
04759                           if (!m_quiet) cout << "#CMT> syntax error : model not specified" << endl;
04760                         }
04761                     }
04762                   else
04763                     {
04764                       if (!m_quiet) cout << "#CMT> syntax error : bad expand option" << endl;
04765                     }
04766                 }
04767               else
04768                 {
04769                   if (!m_quiet) cout << "#CMT> syntax error : don't know what to expand" << endl;
04770                 }
04771             }
04772           else
04773             {
04774               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04775             }
04776           break;
04777         case 'f' :
04778           if ((arg == "f") ||
04779               (arg == "fi") ||
04780               (arg == "fil") ||
04781               (arg == "filt") ||
04782               (arg == "filte") ||
04783               (arg == "filter"))
04784             {
04785               // handle all of the command line arguments in a vector
04786               argc--;
04787               argv++;
04788               while (argc > 1)
04789                 {
04790                   cmt_string& s = arguments.add ();
04791                   s = argv[1];
04792                   argc--;
04793                   argv++;
04794                 }
04795 
04796               m_action = action_filter;
04797             }
04798           else
04799             {
04800               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04801             }
04802           break;
04803         case 'h' :
04804           if ((arg == "h") ||
04805               (arg == "he") ||
04806               (arg == "hel") ||
04807               (arg == "help"))
04808             {
04809               m_action = action_help;
04810             }
04811           else
04812             {
04813               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04814             }
04815           break;
04816         case 'l' :
04817           if (arg == "lock")
04818             {
04819               argc--;
04820               argv++;
04821               if (argc > 1)
04822                 {
04823                   m_current_package = argv[1];
04824                   {
04825                     cmt_string& s = arguments.add ();
04826                     s = m_current_package;
04827                   }
04828 
04829                   m_current_version.erase (0);
04830                   m_current_path.erase (0);
04831 
04832                   argc--;
04833                   argv++;
04834                   if (argc > 1)
04835                     {
04836                       m_current_version = argv[1];
04837 
04838                       {
04839                         cmt_string& s = arguments.add ();
04840                         s = m_current_version;
04841                       }
04842                     
04843                       m_action = action_lock;
04844 
04845                       argc--;
04846                       argv++;
04847                       if (argc > 1)
04848                         {
04849                           m_current_path = argv[1];
04850                           if (m_current_path[0] == '-')
04851                             {
04852                               m_current_path.erase (0);
04853                             }
04854                         }
04855 
04856                       m_current_access = UserMode;
04857                       (Use::current()).set (m_current_package, 
04858                                             m_current_version, 
04859                                             m_current_path);
04860 
04861                     }
04862                   else
04863                     {
04864                       if (!m_quiet) cout << "#CMT> syntax error : version missing" << endl;
04865                     }
04866                 }
04867               else
04868                 {
04869                   m_action = action_lock;
04870                 }
04871             }
04872           else
04873             {
04874               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04875             }
04876           break;
04877         case 'r' :
04878           if (arg == "remove")
04879             {
04880               argc--;
04881               argv++;
04882 
04883               if (argc > 1)
04884                 {
04885                   arg = argv[1];
04886 
04887                   if (arg == "library_links")
04888                     {
04889                       m_action = action_remove_library_links;
04890                     }
04891                   else
04892                     {
04893                       m_current_package = argv[1];
04894                       {
04895                         cmt_string& s = arguments.add ();
04896                         s = m_current_package;
04897                       }
04898                       
04899                       m_current_version.erase (0);
04900                       m_current_path.erase (0);
04901                       
04902                       argc--;
04903                       argv++;
04904                       if (argc > 1)
04905                         {
04906                           m_current_version = argv[1];
04907                           
04908                           {
04909                             cmt_string& s = arguments.add ();
04910                             s = m_current_version;
04911                           }
04912                           
04913                           argc--;
04914                           argv++;
04915                           if (argc > 1)
04916                             {
04917                               m_current_path = argv[1];
04918                               if (m_current_path[0] == '-')
04919                                 {
04920                                   m_current_path.erase (0);
04921                                 }
04922                             }
04923                             
04924                           m_action = action_remove;
04925                         }
04926                       else
04927                         {
04928                           if (!m_quiet) cout << "#CMT> syntax error : version missing" << endl;
04929                         }
04930                     }
04931                 }
04932               else
04933                 {
04934                   if (!m_quiet) cout << "#CMT> syntax error : don't know what to remove" << endl;
04935                 }
04936             }
04937           else if (arg == "run")
04938             {
04939               argc--;
04940               argv++;
04941               if (argc > 1)
04942                 {
04943                   cmt_string& s = arguments.add ();
04944                   s = argv[1];
04945 
04946                   m_action = action_run;
04947                 }
04948               else
04949                 {
04950                   if (!m_quiet) cout << "#CMT> syntax error : run arguments missing" << endl;
04951                 }
04952             }
04953           else if (arg == "run_sequence")
04954             {
04955               argc--;
04956               argv++;
04957               if (argc > 1)
04958                 {
04959                   cmt_string& s = arguments.add ();
04960                   s = argv[1];
04961 
04962                   m_action = action_run_sequence;
04963                 }
04964               else
04965                 {
04966                   if (!m_quiet) cout << "#CMT> syntax error : run_sequence arguments missing" << endl;
04967                 }
04968             }
04969           else
04970             {
04971               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
04972             }
04973           break;
04974         case 's' :
04975           if (arg == "setup")
04976             {
04977               m_action = action_setup;
04978             }
04979           else if ((arg == "s") ||
04980                    (arg == "sh") ||
04981                    (arg == "sho") ||
04982                    (arg == "show"))
04983             {
04984               argc--;
04985               argv++;
04986               if (argc > 1)
04987                 {
04988                   arg = argv[1];
04989 
04990                   if (arg == "all_tags")
04991                     {
04992                       m_action = action_show_all_tags;
04993                     }
04994                   else if (arg == "applied_patterns")
04995                     {
04996                       m_action = action_show_applied_patterns;
04997                     }
04998                   else if (arg == "author")
04999                     {
05000                       m_action = action_show_author;
05001                     }
05002                   else if (arg == "branches")
05003                     {
05004                       m_action = action_show_branches;
05005                     }
05006                   else if (arg == "clients")
05007                     {
05008                       argc--;
05009                       argv++;
05010                       if (argc > 1)
05011                         {
05012                           cmt_string& s = arguments.add ();
05013                           s = argv[1];
05014                           m_current_target = argv[1];
05015 
05016                           m_action = action_show_clients;
05017 
05018                           argc--;
05019                           argv++;
05020                           if (argc > 1)
05021                             {
05022                               cmt_string& s = arguments.add ();
05023                               s = argv[1];
05024 
05025                               argc--;
05026                               argv++;
05027                               if (argc > 1)
05028                                 {
05029                                   cmt_string& s = arguments.add ();
05030                                   s = argv[1];
05031                                 }
05032                             }
05033                         }
05034                       else
05035                         {
05036                           if (!m_quiet) cout << "#CMT> syntax error : package name missing" << endl;
05037                         }
05038                     }
05039                   else if (arg == "constituent")
05040                     {
05041                       argc--;
05042                       argv++;
05043                       if (argc > 1)
05044                         {
05045                           cmt_string& s = arguments.add ();
05046                           s = argv[1];
05047                           m_current_target = argv[1];
05048 
05049                           m_action = action_show_constituent;
05050                         }
05051                       else
05052                         {
05053                           if (!m_quiet) cout << "#CMT> syntax error : constituent name missing" << endl;
05054                         }
05055                     }
05056                   else if (arg == "constituent_names")
05057                     {
05058                       m_action = action_show_constituent_names;
05059                     }
05060                   else if (arg == "constituents")
05061                     {
05062                       m_action = action_show_constituents;
05063                     }
05064                   else if (arg == "fragment")
05065                     {
05066                       argc--;
05067                       argv++;
05068                       if (argc > 1)
05069                         {
05070                           cmt_string& s = arguments.add ();
05071                           s = argv[1];
05072                           m_current_target = argv[1];
05073 
05074                           m_action = action_show_fragment;
05075                         }
05076                       else
05077                         {
05078                           if (!m_quiet) cout << "#CMT> syntax error : fragment name missing" << endl;
05079                         }
05080                     }
05081                   else if (arg == "fragments")
05082                     {
05083                       m_action = action_show_fragments;
05084                     }
05085                   else if (arg == "groups")
05086                     {
05087                       m_action = action_show_groups;
05088                     }
05089                   else if (arg == "include_dirs")
05090                     {
05091                       m_action = action_show_include_dirs;
05092                     }
05093                   else if (arg == "language")
05094                     {
05095                       argc--;
05096                       argv++;
05097                       if (argc > 1)
05098                         {
05099                           cmt_string& s = arguments.add ();
05100                           s = argv[1];
05101                           m_current_target = argv[1];
05102 
05103                           m_action = action_show_language;
05104                         }
05105                       else
05106                         {
05107                           if (!m_quiet) cout << "#CMT> syntax error : language name missing" << endl;
05108                         }
05109                     }
05110                   else if (arg == "languages")
05111                     {
05112                       m_action = action_show_languages;
05113                     }
05114                   else if (arg == "macro")
05115                     {
05116                       argc--;
05117                       argv++;
05118                       if (argc > 1)
05119                         {
05120                           cmt_string& s = arguments.add ();
05121                           s = argv[1];
05122                           m_current_target = argv[1];
05123 
05124                           m_action = action_show_macro;
05125                         }
05126                       else
05127                         {
05128                           if (!m_quiet) cout << "#CMT> syntax error : macro name missing" << endl;
05129                         }
05130                     }
05131                   else if (arg == "macro_names")
05132                     {
05133                       argc--;
05134                       argv++;
05135                       if (argc > 1)
05136                         {
05137                           cmt_string& s = arguments.add ();
05138                           s = argv[1];
05139                         }
05140 
05141                       m_action = action_show_macro_names;
05142                     }
05143                   else if (arg == "macro_value")
05144                     {
05145                       m_quiet = true;
05146                       argc--;
05147                       argv++;
05148                       if (argc > 1)
05149                         {
05150                           cmt_string& s = arguments.add ();
05151                           s = argv[1];
05152                           m_current_target = argv[1];
05153 
05154                           m_action = action_show_macro_value;
05155                         }
05156                       else
05157                         {
05158                           if (!m_quiet) cout << "#CMT> syntax error : macro name missing" << endl;
05159                         }
05160                     }
05161                   else if (arg == "macros")
05162                     {
05163                       argc--;
05164                       argv++;
05165                       if (argc > 1)
05166                         {
05167                           cmt_string& s = arguments.add ();
05168                           s = argv[1];
05169                         }
05170 
05171                       m_action = action_show_macros;
05172                     }
05173                   else if (arg == "manager")
05174                     {
05175                       m_action = action_show_manager;
05176                     }
05177                   else if (arg == "packages")
05178                     {
05179                       argc--;
05180                       argv++;
05181                       if (argc > 1)
05182                         {
05183                           cmt_string& s = arguments.add ();
05184                           s = argv[1];
05185                           m_current_target = argv[1];
05186                         }
05187 
05188                       m_action = action_show_packages;
05189                     }
05190                   else if (arg == "path")
05191                     {
05192                       m_action = action_show_path;
05193                     }
05194                   else if (arg == "pattern")
05195                     {
05196                       argc--;
05197                       argv++;
05198                       if (argc > 1)
05199                         {
05200                           cmt_string& s = arguments.add ();
05201                           s = argv[1];
05202                           m_current_target = argv[1];
05203 
05204                           m_action = action_show_pattern;
05205                         }
05206                       else
05207                         {
05208                           if (!m_quiet) cout << "#CMT> syntax error : pattern name missing" << endl;
05209                         }
05210                     }
05211                   else if (arg == "pattern_names")
05212                     {
05213                       m_action = action_show_pattern_names;
05214                     }
05215                   else if (arg == "patterns")
05216                     {
05217                       m_action = action_show_patterns;
05218                     }
05219                   else if (arg == "pwd")
05220                     {
05221                       m_action = action_show_pwd;
05222                     }
05223                   else if (arg == "set_names")
05224                     {
05225                       argc--;
05226                       argv++;
05227                       if (argc > 1)
05228                         {
05229                           cmt_string& s = arguments.add ();
05230                           s = argv[1];
05231                         }
05232 
05233                       m_action = action_show_set_names;
05234                     }
05235                   else if (arg == "set_value")
05236                     {
05237                       m_quiet = true;
05238                       argc--;
05239                       argv++;
05240                       if (argc > 1)
05241                         {
05242                           cmt_string& s = arguments.add ();
05243                           s = argv[1];
05244                           m_current_target = argv[1];
05245 
05246                           m_action = action_show_set_value;
05247                         }
05248                       else
05249                         {
05250                           if (!m_quiet) cout << "#CMT> syntax error : set name missing" << endl;
05251                         }
05252                     }
05253                   else if (arg == "set")
05254                     {
05255                       argc--;
05256                       argv++;
05257                       if (argc > 1)
05258                         {
05259                           cmt_string& s = arguments.add ();
05260                           s = argv[1];
05261                           m_current_target = argv[1];
05262 
05263                           m_action = action_show_set;
05264                         }
05265                       else
05266                         {
05267                           if (!m_quiet) cout << "#CMT> syntax error : set name missing" << endl;
05268                         }
05269                     }
05270                   else if (arg == "sets")
05271                     {
05272                       argc--;
05273                       argv++;
05274                       if (argc > 1)
05275                         {
05276                           cmt_string& s = arguments.add ();
05277                           s = argv[1];
05278                         }
05279 
05280                       m_action = action_show_sets;
05281                     }
05282                   else if (arg == "strategies")
05283                     {
05284                       m_action = action_show_strategies;
05285                     }
05286                   else if (arg == "tags")
05287                     {
05288                       m_action = action_show_tags;
05289                     }
05290                   else if ((arg == "u") ||
05291                            (arg == "us") ||
05292                            (arg == "use") ||
05293                            (arg == "uses"))
05294                     {
05295                       m_action = action_show_uses;
05296                     }
05297                   else if (arg == "version")
05298                     {
05299                       m_action = action_show_version;
05300                     }
05301                   else if (arg == "versions")
05302                     {
05303                       argc--;
05304                       argv++;
05305                       if (argc > 1)
05306                         {
05307                           cmt_string& s = arguments.add ();
05308                           s = argv[1];
05309                           m_current_target = argv[1];
05310 
05311                           m_action = action_show_versions;
05312                         }
05313                       else
05314                         {
05315                           if (!m_quiet) cout << "#CMT> syntax error : package name missing" << endl;
05316                         }
05317                     }
05318                   else
05319                     {
05320                       if (!m_quiet) cout << "#CMT> syntax error : bad show argument" << endl;
05321                     }
05322                 }
05323               else
05324                 {
05325                   if (!m_quiet) cout << "#CMT> syntax error : don't know what to show" << endl;
05326                 }
05327             }
05328           else if (arg == "system")
05329             {
05330               m_action = action_system;
05331             }
05332           else
05333             {
05334               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
05335             }
05336 
05337           break;
05338         case 'u' :
05339           if (arg == "unlock")
05340             {
05341               argc--;
05342               argv++;
05343               if (argc > 1)
05344                 {
05345                   m_current_package = argv[1];
05346                   {
05347                     cmt_string& s = arguments.add ();
05348                     s = m_current_package;
05349                   }
05350 
05351                   m_current_version.erase (0);
05352                   m_current_path.erase (0);
05353                                         
05354                   argc--;
05355                   argv++;
05356                   if (argc > 1)
05357                     {
05358                       m_current_version = argv[1];
05359 
05360                       {
05361                         cmt_string& s = arguments.add ();
05362                         s = m_current_version;
05363                       }
05364                                                 
05365                       m_action = action_unlock;
05366 
05367                       argc--;
05368                       argv++;
05369                       if (argc > 1)
05370                         {
05371                           m_current_path = argv[1];
05372                           if (m_current_path[0] == '-')
05373                             {
05374                               m_current_path.erase (0);
05375                             }
05376                         }
05377                                                 
05378                       m_current_access = UserMode;
05379                       (Use::current()).set (m_current_package, 
05380                                             m_current_version, 
05381                                             m_current_path);
05382 
05383                     }
05384                   else
05385                     {
05386                       if (!m_quiet) cout << "#CMT> syntax error : version missing" << endl;
05387                     }
05388                 }
05389               else
05390                 {
05391                   m_action = action_unlock;
05392                 }
05393             }
05394           else
05395             {
05396               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
05397             }
05398 
05399           break;
05400         case 'v' :
05401           if ((arg == "v") ||
05402               (arg == "ve") ||
05403               (arg == "ver") ||
05404               (arg == "vers") ||
05405               (arg == "versi") ||
05406               (arg == "versio") ||
05407               (arg == "version"))
05408             {
05409               m_action = action_version;
05410             }
05411           else
05412             {
05413               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
05414             }
05415           break;
05416         case '+' :
05417           if (arg.substr (0, 6) == "+path=")
05418             {
05419               arg.erase (0, 6);
05420               CmtSystem::add_cmt_path (arg, "argument",
05421                                        m_cmt_path, 
05422                                        m_cmt_path_pwds, 
05423                                        m_cmt_path_sources);
05424             }
05425           else
05426             {
05427               if (!m_quiet) cout << "#CMT> syntax error : bad verb " 
05428                                << arg << endl;
05429             }
05430 
05431           break;
05432         case '-' :
05433           if (arg == "-n")
05434             {
05435               m_simulation = true;
05436             }
05437           else if ((arg == "-q") ||
05438                    (arg == "-qu") ||
05439                    (arg == "-qui") ||
05440                    (arg == "-quie") ||
05441                    (arg == "-quiet"))
05442             {
05443               m_quiet = true;
05444             }
05445           else if (arg == "-csh")
05446             {
05447               mode = Csh;
05448             }
05449           else if (arg == "-sh")
05450             {
05451               mode = Sh;
05452             }
05453           else if (arg == "-bat")
05454             {
05455               mode = Bat;
05456             }
05457           else if (arg.substr (0, 5) == "-use=")
05458             {
05459               arg.erase (0, 5);
05460 
05461               if (m_action != action_create)
05462                 {
05463                   CmtSystem::cmt_string_vector words;
05464 
05465                   CmtSystem::split (arg, ":", words);
05466 
05467                   m_current_access = UserMode;
05468 
05469                   if (words.size () > 0) m_current_package = words[0];
05470                   if (words.size () > 1) m_current_version = words[1];
05471                   if (words.size () > 2) m_current_path    = words[2];
05472                   (Use::current()).set (m_current_package, 
05473                                         m_current_version, 
05474                                         m_current_path);
05475                 }
05476             }
05477           else if (arg.substr (0, 6) == "-pack=")
05478             {
05479               arg.erase (0, 6);
05480               if ((m_action != action_create) && (m_current_package != arg))
05481                 {
05482                   //CmtSystem::cd (m_default_path);
05483 
05484                   m_current_access = UserMode;
05485 
05486                   m_current_package = arg;
05487                   m_current_version = "";
05488                   m_current_path    = m_default_path;
05489 
05490                   (Use::current()).set (m_current_package, 
05491                                         m_current_version, 
05492                                         m_current_path);
05493                 }
05494             }
05495           else if (arg.substr (0, 9) == "-version=")
05496             {
05497               arg.erase (0, 9);
05498               if ((m_action != action_create) && (m_current_version != arg))
05499                 {
05500                   m_current_access = UserMode;
05501                   m_current_version = arg;
05502                   (Use::current()).set (m_current_package, 
05503                                         m_current_version, 
05504                                         m_current_path);
05505                 }
05506             }
05507           else if (arg.substr (0, 6) == "-path=")
05508             {
05509               arg.erase (0, 6);
05510 
05511               /*
05512               cerr << "-path=" << arg << 
05513                 " cp=" << m_current_package <<
05514                 " cv=" << m_current_version <<
05515                 " cp=" << m_current_path << endl;
05516               */
05517 
05518               if ((m_action != action_create) && (m_current_path != arg))
05519                 {
05520                   m_current_access = UserMode;
05521                   m_current_path = arg;
05522                   (Use::current()).set (m_current_package, 
05523                                         m_current_version, 
05524                                         m_current_path);
05525 
05526                   CmtSystem::add_cmt_path (m_current_path, "argument",
05527                                            m_cmt_path, 
05528                                            m_cmt_path_pwds, 
05529                                            m_cmt_path_sources);
05530                 }
05531             }
05532           else if (arg.substr (0, 3) == "-f=")
05533             {
05534               arg.substr (3, extra_file);
05535             }
05536           else if (arg.substr (0, 3) == "-e=")
05537             {
05538               cout << "extra statement = " << arg << endl;
05539               arg.substr (3, extra_line);
05540             }
05541           else if (arg.substr (0, 6) == "-home=")
05542             {
05543               arg.erase (0, 6);
05544               if (CmtSystem::test_directory (arg))
05545                 {
05546                   m_cmt_home = arg;
05547                 }
05548             }
05549           else if (arg.substr (0, 5) == "-tag=")
05550             {
05551                 /*
05552                   Here we are going to change the complete tag set
05553                 */
05554 
05555               Tag* tag;
05556               CmtSystem::cmt_string_vector words;
05557               
05559               Tag::clear_all ();
05560               Cmt::m_extra_tags = "";
05561 
05563               configure_site_tag (0);
05564               configure_uname_tag ();
05565               configure_hosttype_tag ();
05566               configure_config_tag ();
05567 
05568               arg.erase (0, 5);
05569 
05570               CmtSystem::split (arg, " \t,", words);
05571 
05572               for (int i = 0; i < words.size (); i++)
05573                 {
05574                   const cmt_string& a = words[i];
05575 
05576                   cmt_string s = a;
05577                   s += ",";
05578 
05579                   if (i == 0)
05580                     {
05581                       m_current_tag = a;
05582 
05583                       if (CmtSystem::testenv ("TAGDEBUG")) cerr 
05584                           << "parse_argument(tag_add)> current_tag=" << m_current_tag << endl;
05585                     }
05586 
05587                   if (Cmt::m_extra_tags.find (s) == cmt_string::npos)
05588                     {
05589                       //if (!m_quiet) cerr << "  a=[" << a << "]" << endl;
05590                       
05592                       if (a == CmtSystem::get_cmt_config ())
05593                         {
05594                           configure_uname_tag ();
05595                         }
05596                       
05597                       tag = Tag::add (a, PriorityArgument, "arguments", 0);
05598                       
05599                       tag->mark ();
05600 
05601                       Cmt::m_extra_tags += a;
05602                       Cmt::m_extra_tags += ",";
05603                     }
05604                 }
05605             }
05606           else if (arg.substr (0, 9) == "-tag_add=")
05607             {
05608               Tag* tag;
05609               CmtSystem::cmt_string_vector words;
05610               
05611               arg.erase (0, 9);
05612 
05613               //if (!m_quiet) cerr << "-tag_add=" << arg << endl;
05614 
05615               CmtSystem::split (arg, " \t,", words);
05616 
05617               for (int i = 0; i < words.size (); i++)
05618                 {
05619                   const cmt_string& a = words[i];
05620 
05621                   cmt_string s = a;
05622                   s += ",";
05623 
05624                   if (Cmt::m_extra_tags.find (s) == cmt_string::npos)
05625                     {
05626                         //if (!m_quiet) cerr << "  a=[" << a << "]" << endl;
05627 
05629                       if (a == CmtSystem::get_cmt_config ())
05630                         {
05631                           configure_uname_tag ();
05632                         }
05633                       
05634                       tag = Tag::add (a, PriorityUserTag, "arguments", 0);
05635                       
05636                       tag->mark ();
05637 
05638                       Cmt::m_extra_tags += a;
05639                       Cmt::m_extra_tags += ",";
05640                     }
05641                 }
05642             }
05643           else if (arg.substr (0, 12) == "-tag_remove=")
05644             {
05645               Tag::TagPtrVector tags = Tag::tags ();
05646               int i;
05647               Tag* tag;
05648 
05649               /*
05650               for (i = 0; i < tags.size (); i++)
05651                 {
05652                   tag = tags[i];
05653                   if ((tag != 0) &&
05654                       (tag->selected))
05655                     {
05656                         if (!m_quiet) cerr << "  original tag_list=" << tag->name << tag->priority << endl;
05657                     }
05658                 }
05659               */
05660 
05661               CmtSystem::cmt_string_vector words;
05662 
05663               arg.erase (0, 12);
05664 
05665               //if (!m_quiet) cerr << "-arg_remove=" << arg << endl;
05666 
05667               CmtSystem::split (arg, " \t,", words);
05668 
05669                 //
05670                 // Now erase all entries in the old list that match
05671                 // the specified tags 
05672                 //
05673 
05674               for (i = 0; i < words.size (); i++)
05675                 {
05676                   const cmt_string& a = words[i];
05677 
05678                   cmt_string s = a;
05679                   s += ",";
05680 
05681                   int pos;
05682 
05683                   pos = Cmt::m_extra_tags.find (s);
05684 
05685                   if (pos != cmt_string::npos)
05686                     {
05687                       Cmt::m_extra_tags.erase (pos, s.size ());
05688                     }
05689 
05690                   //if (!m_quiet) cerr << "  tag_list=[" << tag_list << "]" << endl;
05691                 }
05692 
05693                 //
05694                 // Now reinject the purged list of tags into the database
05695                 // exactly as when using -tag=<tag-list>
05696                 //
05697 
05699               Tag::unmark_all ();
05700 
05702               configure_site_tag (0);
05703               configure_uname_tag ();
05704               configure_hosttype_tag ();
05705               
05706               CmtSystem::split (Cmt::m_extra_tags, " \t,", words);
05707 
05708               for (i = 0; i < words.size (); i++)
05709                 {
05710                   const cmt_string& a = words[i];
05711 
05712                   //fprintf (stderr, "  a=[%s]\n", a.c_str ());
05713 
05715                   if (a == CmtSystem::get_cmt_config ())
05716                     {
05717                       configure_uname_tag ();
05718                     }
05719 
05720                   if (i == 0)
05721                     {
05722                       m_current_tag = a;
05723 
05724                       //if (!m_quiet) cerr << "parse_argument(tag_remove)> current_tag=" 
05725                         //<< m_current_tag << endl;
05726 
05727                       tag = Tag::add (a, PriorityTag, "restore configuration", 0);
05728                     }
05729                   else
05730                     {
05731                       tag = Tag::add (a, PriorityUserTag, "restore configuration", 0);
05732                     }
05733 
05734                   tag->mark ();
05735                 }
05736             }
05737           else if (arg.substr (0, 14) == "-user_context=")
05738             {
05739               arg.erase (0, 14);
05740               if (CmtSystem::test_directory (arg))
05741                 {
05742                   m_cmt_user_context = arg;
05743                 }
05744             }
05745           else
05746             {
05747               if (!m_quiet) cout << "#CMT> syntax error : bad verb " << arg << endl;
05748             }
05749 
05750           break;
05751         default:
05752           if (!m_quiet) cout << "#CMT> syntax error : bad command parameter " << arg << endl;
05753           break;
05754         }
05755 
05756       argc--;
05757       argv++;
05758     }
05759 }
05760 
05768 void Cmt::parse_requirements (const cmt_string& file_name, Use* use)
05769 {
05770   cmt_string actual_file_name = file_name;
05771   cmt_string text;
05772 
05773   CmtError::clear ();
05774 
05775   if (use == 0) use = &(Use::current ());
05776 
05777   if (!CmtSystem::test_file (actual_file_name))
05778     {
05779       actual_file_name = "..";
05780       actual_file_name += CmtSystem::file_separator ();
05781       actual_file_name += "cmt";
05782       actual_file_name += CmtSystem::file_separator ();
05783       actual_file_name += file_name;
05784 
05785       if (!CmtSystem::test_file (actual_file_name))
05786         {
05787           actual_file_name = "..";
05788           actual_file_name += CmtSystem::file_separator ();
05789           actual_file_name += "mgr";
05790           actual_file_name += CmtSystem::file_separator ();
05791           actual_file_name += file_name;
05792 
05793           if (!CmtSystem::test_file (actual_file_name))
05794             {
05795                 /*
05796               cmt_string text;
05797 
05798               text = "Package ";
05799               text += use->package;
05800               text += " version ";
05801               text += use->specified_version;
05802               text += " path ";
05803               text += use->specified_path;
05804               text += " file ";
05805               text += actual_file_name;
05806 
05807               CmtError::set (CmtError::file_access_error, text);
05808                 */
05809 
05810               return;
05811             }
05812         }
05813     }
05814 
05815   text.read (actual_file_name);
05816 
05836   AccessMode saved_current_access;
05837   ScopeType saved_scope;
05838 
05839   saved_current_access = Cmt::m_current_access;
05840   saved_scope          = Cmt::m_scope;
05841 
05842   if (use != &(Use::current ()))
05843     {
05844       Cmt::m_current_access = UserMode;
05845     }
05846   else
05847     {
05848       Cmt::m_current_access = DeveloperMode;
05849     }
05850 
05851   Cmt::m_scope = ScopePublic;
05852 
05853   parse_requirements_text (text, actual_file_name, use);
05854 
05855     //Pattern::apply_all_globals (use);
05856 
05857   Cmt::m_current_access = saved_current_access;
05858   Cmt::m_scope          = saved_scope;
05859 }
05860 
05868 void Cmt::parse_requirements_line (const cmt_string& line,
05869                                    Use* use,
05870                                    const cmt_string& file_name,
05871                                    int line_number)
05872 {
05873   int length;
05874   int nl;
05875   int back_slash;
05876   cmt_string temp_line = line;
05877 
05878   if (temp_line.size () == 0) return;
05879   if (temp_line[0] == '#') return;
05880 
05881   nl = temp_line.find_last_of ('\n');
05882   if (nl != cmt_string::npos) temp_line.erase (nl);
05883 
05884   length = temp_line.size ();
05885   if (length == 0) return;
05886 
05887   //
05888   // We scan the line for handling backslashes.
05889   //
05890   // o Really terminating backslashes (ie those only followed by spaces/tabs
05891   // mean continued line
05892   //
05893   //
05894 
05895   bool finished = true;
05896 
05897   length = temp_line.size ();
05898 
05899   back_slash = temp_line.find_last_of ('\\');
05900 
05901   if (back_slash != cmt_string::npos)
05902     {
05903       //
05904       // This is the last backslash
05905       // check if there are only space chars after it
05906       //
05907       
05908       bool at_end = true;
05909 
05910       for (int i = (back_slash + 1); i < length; i++)
05911         {
05912           char c = temp_line[i];
05913           if ((c != ' ') && (c != '\t'))
05914             {
05915               at_end = false;
05916               break;
05917             }
05918         }
05919 
05920       if (at_end)
05921         {
05922           temp_line.erase (back_slash);
05923           finished = false;
05924         }
05925       else
05926         {
05927           // This was not a trailing backslash.
05928           finished = true;
05929         }
05930     }
05931 
05932   m_filtered_text += temp_line;
05933 
05934   if (!finished)
05935     {
05936       // We still need to accumulate forthcoming lines
05937       // before parsing the resulting text.
05938       return;
05939     }
05940 
05941   /*
05942     Here a full line (possibly accumulating several lines
05943     ended by backslashes) is parsed :
05944     
05945     o Special characters are filtered now :
05946     
05947     <cmt:tab/>  \t
05948     <cmt:cr/>   \r
05949     <cmt:lf/>   \n
05950     
05951     o Split into words (a word is a string not containing
05952     spaces or enclosed in quotes)
05953 
05954     o Parse the word array (function Select)
05955 
05956   */
05957 
05958   m_filtered_text.replace_all ("<cmt:tab/>", "\t");
05959   m_filtered_text.replace_all ("<cmt:cr/>",  "\r");
05960   m_filtered_text.replace_all ("<cmt:lf/>",  "\n");
05961 
05962   if (m_debug)
05963     {
05964       cout << "parse_requirements_line [" << m_filtered_text << "]" << endl;
05965     }
05966   
05967   static CmtSystem::cmt_string_vector words;
05968   
05969   CmtSystem::split (m_filtered_text, " \t", words);
05970   
05971   if (words.size () != 0)
05972     {
05973       select (words, use, file_name, line_number);
05974     }
05975   
05976   m_filtered_text.erase (0);
05977 }
05978 
05986 void Cmt::parse_requirements_text (const cmt_string& text,
05987                                    const cmt_string& file_name,
05988                                    Use* use)
05989 {
05990   cmt_string line;
05991   int pos;
05992   int max_pos;
05993   int line_number = 1;
05994 
05995   if (use == 0) use = &(Use::current ());
05996 
05997   m_filtered_text.erase (0);
05998 
05999   pos = 0;
06000   max_pos = text.size ();
06001 
06002   for (pos = 0; pos < max_pos;)
06003     {
06004       int cr = text.find (pos, "\r\n");
06005       int nl = text.find (pos, '\n');
06006       int first = nl;
06007       int length = 1;
06008 
06009       if (cr != cmt_string::npos)
06010         {
06011           if (nl == cmt_string::npos)
06012             {
06013               first = cr;
06014               length = 2;
06015             }
06016           else
06017             {
06018               first = (nl < cr) ? nl : cr;
06019               length = (nl < cr) ? 1 : 2;
06020             }
06021         }
06022 
06023       if (first == cmt_string::npos)
06024         {
06025           text.substr (pos, line);
06026           pos = max_pos;
06027         }
06028       else if (first > pos)
06029         {
06030           text.substr (pos, first - pos, line);
06031           pos = first + length;
06032         }
06033       else
06034         {
06035           line.erase (0);
06036           pos += length;
06037         }
06038 
06039       parse_requirements_line (line, use, file_name, line_number);
06040 
06041       if ((m_action == action_check_configuration) && CmtError::has_pending_error ())
06042         {
06043           break;
06044         }
06045 
06046       line_number++;
06047     }
06048 }
06049 
06050 //----------------------------------------------------------
06051 int Cmt::parser (const cmt_string& command_line)
06052 {
06053   CmtSystem::cmt_string_vector v;
06054 
06055   CmtSystem::split (command_line, " \t", v);
06056 
06057   int argc = v.size ();
06058 
06059   char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
06060 
06061   int i;
06062   for (i = 0; i < argc; i++)
06063     {
06064       argv[i] = (char*) v[i].c_str ();
06065     }
06066   argv[argc] = 0;
06067 
06068   int status = parser (argc, argv);
06069 
06070   free (argv);
06071 
06072   return (status);
06073 }
06074 
06075 //----------------------------------------------------------
06076 int Cmt::parser (int argc, char* argv[])
06077 {
06078   PrintMode mode = Csh;
06079   CmtSystem::cmt_string_vector arguments;
06080   cmt_string extra_line;
06081   cmt_string extra_file;
06082 
06083   if (argc <= 1)
06084     {
06085       do_help ();
06086       exit (0);
06087     }
06088 
06089   clear ();
06090   configure ();
06091 
06092   CmtError::clear ();
06093 
06094   /*
06095     Set private if positioned inside the package
06096     (which is detected since we were able to retreive the
06097     Version, Package and Path)
06098   */
06099 
06100   if ((m_current_path.size () == 0) ||
06101       (m_current_package.size () == 0) ||
06102       (m_current_version.size () == 0))
06103     {
06104       m_current_access = UserMode;
06105     }
06106   else
06107     {
06108       m_current_access = DeveloperMode;
06109     }
06110 
06111   parse_arguments (argc, argv, arguments,
06112                    extra_line, extra_file, mode);
06113 
06114   if (m_configure_error != "")
06115     {
06116       if (!m_quiet) cout << "# CMT>" << m_configure_error << endl;
06117     }
06118 
06119   if (CmtError::has_pending_error ())
06120     {
06121       int code = CmtError::get_last_error_code ();
06122       if (!m_quiet) CmtError::print ();
06123       clear ();
06124 
06125       return (code);
06126     }
06127 
06128   if (m_debug)
06129     {
06130       cout << "After parse_argument> pack=" << m_current_package
06131            << " m_current_tag=" << m_current_tag
06132            << endl;
06133     }
06134 
06135   /*
06136     Now actual requirements analysis can take place.
06137 
06138     Extra lines or files are analysed first.
06139   */
06140 
06141   if (strlen (extra_file.c_str ()) > 0) parse_requirements (extra_file, 0);
06142   if (strlen (extra_line.c_str ()) > 0) parse_requirements_line (extra_line, 0);
06143 
06144   //
06145   //  For some of the actions, the CMT package must be automatically
06146   //  included
06147   //
06148 
06149   if (m_debug) cerr << "parser1> current_tag=" << m_current_tag << endl;
06150 
06151   switch (m_action)
06152     {
06153       // case action_none :
06154     case action_awk :
06155     case action_broadcast :
06156     case action_build_constituent_makefile :
06157     case action_build_constituents_makefile :
06158     case action_build_dependencies :
06159     case action_build_library_links :
06160     case action_build_make_setup :
06161     case action_build_msdev :
06162     case action_build_os9_makefile :
06163       // case action_build_prototype :
06164     case action_build_readme :
06165     case action_build_tag_makefile :
06166       // case action_build_temporary_name :
06167     case action_build_triggers :
06168     case action_build_windefs :
06169     case action_check_configuration :
06170       // case action_check_files :
06171       // case action_check_version :
06172     case action_checkout :
06173     case action_cleanup :
06174     case action_config :
06175     case action_create :
06176       // case action_cvsbranches :
06177       // case action_cvssubpackages :
06178       // case action_cvstags :
06179     case action_expand_model :
06180     case action_filter :
06181       // case action_help :
06182     case action_load :
06183     case action_lock :
06184     case action_remove :
06185     case action_remove_library_links :
06186     case action_run :
06187     case action_run_sequence :
06188     case action_setup :
06189     case action_show_all_tags :
06190     case action_show_applied_patterns :
06191       // case action_show_author :
06192       // case action_show_branches :
06193       // case action_show_clients :
06194       // case action_show_constituent :
06195       // case action_show_constituent_names :
06196       // case action_show_constituents :
06197     case action_show_fragment :
06198     case action_show_fragments :
06199     case action_show_groups :
06200     case action_show_include_dirs :
06201     case action_show_language :
06202     case action_show_languages :
06203     case action_show_macro :
06204     case action_show_macro_names :
06205     case action_show_macro_value :
06206     case action_show_macros :
06207       // case action_show_manager :
06208       // case action_show_packages :
06209     case action_show_path :
06210     case action_show_pattern :
06211     case action_show_pattern_names :
06212     case action_show_patterns :
06213       // case action_show_pwd :
06214     case action_show_set :
06215     case action_show_set_names :
06216     case action_show_set_value :
06217     case action_show_sets :
06218     case action_show_strategies :
06219     case action_show_tags :
06220     case action_show_uses :
06221     case action_show_version :
06222       // case action_show_versions :
06223       // case action_system :
06224     case action_unlock :
06225     case action_version :
06226       use_cmt ();
06227         //
06228         // Now parse the requirements file stored in ${CMTHOME}
06229         //
06230       
06231       use_home_requirements ();
06232 
06233       break;
06234     default:
06235       break;
06236     }
06237 
06238   if (m_debug) cerr << "parser2> current_tag=" << m_current_tag << endl;
06239 
06240   //
06241   // Setting up recursive actions
06242   //
06243 
06244   switch (m_action)
06245     {
06246       // case action_none :
06247     case action_awk :
06248     case action_broadcast :
06249     case action_build_constituent_makefile :
06250     case action_build_constituents_makefile :
06251     case action_build_dependencies :
06252     case action_build_library_links :
06253     case action_build_make_setup :
06254     case action_build_msdev :
06255     case action_build_os9_makefile :
06256       // case action_build_prototype :
06257     case action_build_readme :
06258     case action_build_tag_makefile :
06259       // case action_build_temporary_name :
06260     case action_build_triggers :
06261     case action_build_windefs :
06262     case action_check_configuration :
06263       // case action_check_files :
06264       // case action_check_version :
06265       // case action_checkout :
06266     case action_cleanup :
06267     case action_config :
06268       // case action_create :
06269       // case action_cvsbranches :
06270       // case action_cvssubpackages :
06271       // case action_cvstags :
06272     case action_expand_model :
06273     case action_filter :
06274       // case action_help :
06275     case action_load :
06276       // case action_lock :
06277       // case action_remove :
06278     case action_remove_library_links :
06279       // case action_run :
06280     case action_run_sequence :
06281     case action_setup :
06282     case action_show_all_tags :
06283     case action_show_applied_patterns :
06284       // case action_show_author :
06285       // case action_show_branches :
06286       // case action_show_clients :
06287     case action_show_constituent :
06288     case action_show_constituent_names :
06289     case action_show_constituents :
06290     case action_show_fragment :
06291     case action_show_fragments :
06292     case action_show_groups :
06293     case action_show_include_dirs :
06294     case action_show_language :
06295     case action_show_languages :
06296     case action_show_macro :
06297     case action_show_macro_names :
06298     case action_show_macro_value :
06299     case action_show_macros :
06300       // case action_show_manager :
06301       // case action_show_packages :
06302     case action_show_path :
06303     case action_show_pattern :
06304     case action_show_pattern_names :
06305     case action_show_patterns :
06306       // case action_show_pwd :
06307     case action_show_set :
06308     case action_show_set_names :
06309     case action_show_set_value :
06310     case action_show_sets :
06311     case action_show_strategies :
06312     case action_show_tags :
06313     case action_show_uses :
06314       // case action_show_version :
06315       // case action_show_versions :
06316       // case action_system :
06317       // case action_unlock :
06318       // case action_version :
06319       m_recursive = true;
06320       break;
06321     default:
06322       m_recursive = false;
06323       break;
06324     }
06325 
06326   //
06327   //  Actions for which the context of the package is checked,
06328   //  and the requirements file is analysed.
06329   //
06330 
06331   switch (m_action)
06332     {
06333     case action_none :
06334     case action_awk :
06335     case action_broadcast :
06336     case action_build_constituent_makefile :
06337     case action_build_constituents_makefile :
06338     case action_build_dependencies :
06339     case action_build_library_links :
06340     case action_build_make_setup :
06341     case action_build_msdev :
06342     case action_build_os9_makefile :
06343       // case action_build_prototype :
06344     case action_build_readme :
06345     case action_build_tag_makefile :
06346       // case action_build_temporary_name :
06347     case action_build_triggers :
06348     case action_build_windefs :
06349     case action_check_configuration :
06350       // case action_check_files :
06351       // case action_check_version :
06352       // case action_checkout :
06353     case action_cleanup :
06354     case action_config :
06355       // case action_create :
06356       // case action_cvsbranches :
06357       // case action_cvssubpackages :
06358       // case action_cvstags :
06359     case action_expand_model :
06360     case action_filter :
06361     case action_help :
06362     case action_load :
06363     case action_lock :
06364       // case action_remove :
06365     case action_remove_library_links :
06366     case action_run :
06367       // case action_run_sequence :
06368     case action_setup :
06369     case action_show_all_tags :
06370     case action_show_applied_patterns :
06371     case action_show_author :
06372     case action_show_branches :
06373       // case action_show_clients :
06374     case action_show_constituent :
06375     case action_show_constituent_names :
06376     case action_show_constituents :
06377     case action_show_fragment :
06378     case action_show_fragments :
06379     case action_show_groups :
06380     case action_show_include_dirs :
06381     case action_show_language :
06382     case action_show_languages :
06383     case action_show_macro :
06384     case action_show_macro_names :
06385     case action_show_macro_value :
06386     case action_show_macros :
06387     case action_show_manager :
06388       // case action_show_packages :
06389     case action_show_path :
06390     case action_show_pattern :
06391     case action_show_pattern_names :
06392     case action_show_patterns :
06393     case action_show_pwd :
06394     case action_show_set :
06395     case action_show_set_names :
06396     case action_show_set_value :
06397     case action_show_sets :
06398     case action_show_strategies :
06399     case action_show_tags :
06400     case action_show_uses :
06401     case action_show_version :
06402       // case action_show_versions :
06403       // case action_system :
06404     case action_unlock :
06405       // case action_version :
06406       reach_current_package ();
06407       use_user_context_requirements ();
06408       break;
06409     default:
06410       break;
06411     }
06412 
06413   if (m_debug) cerr << "parser3> current_tag=" << m_current_tag << endl;
06414 
06415   //
06416   // Perform some actions even if there is an error
06417   //
06418 
06419   if (CmtError::has_pending_error ())
06420     {
06421       int code = CmtError::get_last_error_code ();
06422       if (!m_quiet) CmtError::print ();
06423 
06424       switch (m_action)
06425         {
06426           // case action_none :
06427           // case action_awk :
06428           // case action_broadcast :
06429         case action_build_constituent_makefile :
06430         case action_build_constituents_makefile :
06431         case action_build_dependencies :
06432         case action_build_library_links :
06433         case action_build_make_setup :
06434         case action_build_msdev :
06435         case action_build_os9_makefile :
06436         case action_build_prototype :
06437         case action_build_readme :
06438         case action_build_tag_makefile :
06439           // case action_build_temporary_name :
06440         case action_build_triggers :
06441         case action_build_windefs :
06442         case action_check_configuration :
06443           // case action_check_files :
06444           // case action_check_version :
06445           // case action_checkout :
06446         case action_cleanup :
06447           // case action_config :
06448           // case action_create :
06449           // case action_cvsbranches :
06450           // case action_cvssubpackages :
06451           // case action_cvstags :
06452           // case action_expand_model :
06453           // case action_filter :
06454           // case action_help :
06455         case action_load :
06456         case action_lock :
06457         case action_remove :
06458         case action_remove_library_links :
06459           // case action_run :
06460         case action_run_sequence :
06461         case action_setup :
06462           // case action_show_all_tags :
06463           // case action_show_applied_patterns :
06464           // case action_show_author :
06465           // case action_show_branches :
06466           // case action_show_clients :
06467           // case action_show_constituent :
06468           // case action_show_constituent_names :
06469           // case action_show_constituents :
06470           // case action_show_fragment :
06471           // case action_show_fragments :
06472           // case action_show_groups :
06473           // case action_show_include_dirs :
06474           // case action_show_language :
06475           // case action_show_languages :
06476           // case action_show_macro :
06477           // case action_show_macro_names :
06478           // case action_show_macro_value :
06479           // case action_show_macros :
06480           // case action_show_manager :
06481           // case action_show_packages :
06482           // case action_show_path :
06483           // case action_show_pattern :
06484           // case action_show_pattern_names :
06485           // case action_show_patterns :
06486           // case action_show_pwd :
06487           // case action_show_set :
06488           // case action_show_set_names :
06489           // case action_show_set_value :
06490           // case action_show_sets :
06491           // case action_show_strategies :
06492           // case action_show_tags :
06493           // case action_show_uses :
06494           // case action_show_version :
06495           // case action_show_versions :
06496           // case action_system :
06497         case action_unlock :
06498           // case action_version :
06499           clear ();
06500           return (code);
06501         default:
06502           CmtError::clear ();
06503           break;
06504         }
06505     }
06506 
06507   //
06508   // Perform actions
06509   //
06510 
06511   switch (m_action)
06512     {
06513     case action_none :
06514       CmtError::set (CmtError::syntax_error, "ParseArguments> ");
06515       break;
06516     case action_awk :
06517       do_awk (arguments);
06518       break;
06519     case action_broadcast :
06520       do_broadcast (arguments, argc, argv);
06521       break;
06522     case action_build_constituent_makefile :
06523       do_build_constituent_makefile (arguments, argc, argv);
06524       break;
06525     case action_build_constituents_makefile :
06526       do_build_constituents_makefile (arguments, argc, argv);
06527       break;
06528     case action_build_dependencies :
06529       do_build_dependencies (arguments, argc, argv);
06530       break;
06531     case action_build_library_links :
06532       do_build_library_links ();
06533       break;
06534     case action_build_make_setup :
06535       do_build_make_setup ();
06536       break;
06537     case action_build_msdev :
06538       do_build_msdev (arguments);
06539       break;
06540     case action_build_os9_makefile :
06541       do_build_os9_makefile (arguments);
06542       break;
06543     case action_build_prototype :
06544       do_build_prototype (arguments);
06545       break;
06546     case action_build_readme :
06547       do_build_readme (arguments);
06548       break;
06549     case action_build_tag_makefile :
06550       do_build_tag_makefile ();
06551       break;
06552     case action_build_temporary_name :
06553       do_build_temporary_name ();
06554       break;
06555     case action_build_triggers :
06556       do_build_triggers (arguments);
06557       break;
06558     case action_build_windefs :
06559       do_build_windefs (arguments);
06560       break;
06561     case action_check_configuration :
06562       do_check_configuration ();
06563       break;
06564     case action_check_files :
06565       do_check_files (arguments);
06566       break;
06567     case action_check_version :
06568       do_check_version (arguments);
06569       break;
06570     case action_checkout :
06571       do_checkout (arguments);
06572       break;
06573     case action_cleanup :
06574       do_cleanup (mode);
06575       break;
06576     case action_config :
06577       do_config ();
06578       break;
06579     case action_create :
06580       do_create (arguments);
06581       break;
06582     case action_cvsbranches :
06583       do_cvsbranches (arguments);
06584       break;
06585     case action_cvssubpackages :
06586       do_cvssubpackages (arguments);
06587       break;
06588     case action_cvstags :
06589       do_cvstags (arguments);
06590       break;
06591     case action_expand_model :
06592       do_expand_model (arguments);
06593       break;
06594     case action_filter :
06595       do_filter (arguments);
06596       break;
06597     case action_help :
06598       do_help ();
06599       break;
06600     case action_load :
06601       cout << "#CMT> action not implemented" << endl;
06602       break;
06603     case action_lock :
06604       do_lock (m_current_package, m_current_version, m_current_path);
06605       break;
06606     case action_remove :
06607       do_remove (m_current_package, m_current_version, m_current_path);
06608       break;
06609     case action_remove_library_links :
06610       do_remove_library_links ();
06611       break;
06612     case action_run :
06613       do_run (arguments);
06614       break;
06615     case action_run_sequence :
06616       do_run_sequence (arguments);
06617       break;
06618     case action_setup :
06619       do_setup (mode);
06620       break;
06621     case action_show_all_tags :
06622       do_show_all_tags ();
06623       break;
06624     case action_show_applied_patterns :
06625       do_show_applied_patterns ();
06626       break;
06627     case action_show_author :
06628       do_show_author ();
06629       break;
06630     case action_show_branches :
06631       do_show_branches (mode);
06632       break;
06633     case action_show_clients :
06634       do_show_clients (arguments);
06635       break;
06636     case action_show_constituent :
06637       do_show_constituent (arguments);
06638       break;
06639     case action_show_constituent_names :
06640       do_show_constituent_names ();
06641       break;
06642     case action_show_constituents :
06643       do_show_constituents ();
06644       break;
06645     case action_show_fragment :
06646       do_show_fragment (arguments);
06647       break;
06648     case action_show_fragments :
06649       do_show_fragments ();
06650       break;
06651     case action_show_groups :
06652       do_show_groups ();
06653       break;
06654     case action_show_include_dirs :
06655       do_show_include_dirs ();
06656       break;
06657     case action_show_language :
06658       do_show_language (arguments);
06659       break;
06660     case action_show_languages :
06661       do_show_languages ();
06662       break;
06663     case action_show_macro :
06664       do_show_macro (arguments, mode);
06665       break;
06666     case action_show_macro_names :
06667       do_show_macro_names (arguments, mode);
06668       break;
06669     case action_show_macro_value :
06670       do_show_macro_value (arguments, mode);
06671       break;
06672     case action_show_macros :
06673       do_show_macros (arguments, mode);
06674       break;
06675     case action_show_manager :
06676       do_show_manager ();
06677       break;
06678     case action_show_packages :
06679       do_show_packages (arguments);
06680       break;
06681     case action_show_path :
06682       do_show_path ();
06683       break;
06684     case action_show_pattern :
06685       do_show_pattern (arguments);
06686       break;
06687     case action_show_pattern_names :
06688       do_show_pattern_names ();
06689       break;
06690     case action_show_patterns :
06691       do_show_patterns ();
06692       break;
06693     case action_show_pwd :
06694       do_show_pwd ();
06695       break;
06696     case action_show_set :
06697       do_show_set (arguments, mode);
06698       break;
06699     case action_show_set_names :
06700       do_show_set_names (arguments, mode);
06701       break;
06702     case action_show_set_value :
06703       do_show_set_value (arguments, mode);
06704       break;
06705     case action_show_sets :
06706       do_show_sets (arguments, mode);
06707       break;
06708     case action_show_strategies :
06709       do_show_strategies ();
06710       break;
06711     case action_show_tags :
06712       do_show_tags ();
06713       break;
06714     case action_show_uses :
06715       do_show_uses ();
06716       break;
06717     case action_show_version :
06718       do_show_version ();
06719       break;
06720     case action_show_versions :
06721       do_show_versions (arguments);
06722       break;
06723     case action_system :
06724       do_show_system ();
06725       break;
06726     case action_unlock :
06727       do_unlock (m_current_package, m_current_version, m_current_path);
06728       break;
06729     case action_version :
06730       do_version ();
06731       break;
06732     default:
06733       CmtError::set (CmtError::syntax_error, "ParseArguments>");
06734       break;
06735     }
06736 
06737   if (CmtError::has_pending_error ())
06738     {
06739       int code = CmtError::get_last_error_code ();
06740       if (!m_quiet) CmtError::print ();
06741       clear ();
06742       return (code);
06743     }
06744   else
06745     {
06746       clear ();
06747       return (0);
06748     }
06749 }
06750 
06751 //----------------------------------------------------------
06756 void Cmt::print (PrintMode mode)
06757 {
06758   Use::UsePtrVector& Uses = Use::uses ();
06759 
06760   cmt_string tag;
06761 
06762   set_standard_macros ();
06763 
06764     //cerr << "# current_tag=" << m_current_tag << endl;
06765     //cerr << "# current_config=" << m_current_config << endl;
06766 
06767   if (m_current_tag == "")
06768     {
06769       if (mode == Bat) tag = "%CMTCONFIG%";
06770       else tag = "${CMTCONFIG}";
06771     }
06772   else
06773     {
06774       tag = m_current_tag;
06775     }
06776 
06777   if (m_current_access == DeveloperMode)
06778     {
06779       m_scope = ScopePrivate;
06780     }
06781   else
06782     {
06783       m_scope = ScopePublic;
06784     }
06785 
06786     //
06787     //  Now check if all extra tags are still valid. Some of them
06788     //  may be discarded du to some conflict with highest priority
06789     //  tags, or with exclude statements
06790     //
06791 
06792   {
06793     CmtSystem::cmt_string_vector words;
06794       
06795     cmt_string tags;
06796 
06797     tags = Cmt::m_extra_tags;
06798       
06799     CmtSystem::split (tags, " \t,", words);
06800 
06801     Cmt::m_extra_tags = "";
06802       
06803     for (int i = 0; i < words.size (); i++)
06804       {
06805         Tag* tag;
06806         const cmt_string& a = words[i];
06807 
06808         tag = Tag::find (a);
06809 
06810         if ((tag != 0) && (tag->is_selected ()))
06811           {
06812             Cmt::m_extra_tags += a;
06813             Cmt::m_extra_tags += ",";
06814           }
06815       }
06816   }
06817 
06818   if (Uses.size () > 0)
06819     {
06820       int number;
06821 
06822       for (number = 0; number < Uses.size (); number++)
06823         {
06824           Use& use = *(Uses[number]);
06825 
06826           if (use.discarded) continue;
06827 
06828           print_context (use, mode, tag);
06829         }
06830     }
06831 
06832   print_context (Use::current (), mode, tag);
06833 
06834   Symbol::all_print (mode);
06835   // Script::all_print (mode);
06836 
06837   cout << endl;
06838 }
06839 
06840 //----------------------------------------------------------
06841 void Cmt::print_clean (PrintMode mode)
06842 {
06843   Use::UsePtrVector& Uses = Use::uses ();
06844 
06845   set_standard_macros ();
06846 
06847   Script::all_print_clean (mode);
06848   Symbol::all_print_clean (mode);
06849 
06850   switch (mode)
06851     {
06852     case Csh :
06853       if (m_current_package != "CMT")
06854         {
06855           cout << "unsetenv " << m_current_prefix << "ROOT" << endl;
06856           cout << "unsetenv " << m_current_prefix << "CONFIG" << endl;
06857         }
06858       break;
06859     case Sh :
06860       if (m_current_package != "CMT")
06861         {
06862           cout << "unset " << m_current_prefix << "ROOT" << endl;
06863           cout << "unset " << m_current_prefix << "CONFIG" << endl;
06864         }
06865       break;
06866     case Bat :
06867       if (m_current_package != "CMT")
06868         {
06869           cout << "set " << m_current_prefix << "ROOT=" << endl;
06870           cout << "set " << m_current_prefix << "CONFIG=" << endl;
06871         }
06872       break;
06873     }
06874 
06875   if (Uses.size () > 0)
06876     {
06877       int number;
06878 
06879       for (number = 0; number < Uses.size (); number++)
06880         {
06881           Use* use = Uses[number];
06882 
06883           if (use->package == "CMT") continue;
06884           if (use->package == "methods") continue;
06885           if (use->discarded) continue;
06886 
06887           switch (mode)
06888             {
06889             case Csh :
06890               cout << "unsetenv " << use->prefix << "ROOT" << endl;
06891               cout << "unsetenv " << use->prefix << "CONFIG" << endl;
06892               break;
06893             case Sh :
06894               cout << "unset " << use->prefix << "ROOT" << endl;
06895               cout << "unset " << use->prefix << "CONFIG" << endl;
06896               break;
06897             case Bat :
06898               cout << "set " << use->prefix << "ROOT=" << endl;
06899               cout << "set " << use->prefix << "CONFIG" << endl;
06900               break;
06901             }
06902         }
06903     }
06904 
06905   switch (mode)
06906     {
06907     case Csh :
06908       cout << "unsetenv CMTEXTRATAGS" << endl;
06909       break;
06910     case Sh :
06911       cout << "unset CMTEXTRATAGS" << endl;
06912       break;
06913     case Bat :
06914       cout << "set CMTEXTRATAGS=" << endl;
06915       break;
06916     }
06917 
06918   cout << endl;
06919 }
06920 
06921 //----------------------------------------------------------
06922 void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
06923 {
06924   if (use.package == "cmt_standalone") return;
06925 
06926   cmt_string fs = CmtSystem::file_separator ();
06927 
06928   use.real_path.replace_all (CmtSystem::file_separator (), fs);
06929 
06930   cmt_string system = CmtSystem::get_cmt_config ();
06931 
06932   switch (mode)
06933     {
06934     case Csh :
06935       cout << "setenv " << use.prefix << "ROOT \"" <<
06936         use.real_path << fs <<
06937         use.package << fs <<
06938         use.version << "\"" << endl;
06939         
06940       if (use.package == "CMT")
06941         {
06942             //cout << "setenv CMTCONFIG `${CMTROOT}/mgr/cmt system`; " << endl;
06943           cout << "setenv CMTCONFIG " << system << endl;
06944           //cout << "setenv CMTEXTRATAGS " << Cmt::m_extra_tags << endl;
06945         }
06946       else
06947         {
06948           cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
06949         }
06950         
06951       break;
06952     case Sh :
06953       cout << use.prefix << "ROOT=\"" <<
06954         use.real_path << fs <<
06955         use.package << fs <<
06956         use.version << "\"; export " <<
06957         use.prefix << "ROOT" << endl;
06958         
06959       if (use.package == "CMT")
06960         {
06961           //cout << "CMTCONFIG=`${CMTROOT}/mgr/cmt system`; export CMTCONFIG; ";
06962           cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
06963           //cout << "CMTEXTRATAGS=" << Cmt::m_extra_tags << "; export CMTEXTRATAGS" << endl;
06964         }
06965       else
06966         {
06967           cout << use.prefix << "CONFIG=\"" <<
06968             tag << "\"; export " <<
06969             use.prefix << "CONFIG" << endl;
06970         }
06971         
06972       break;
06973     case Bat :
06974       cout << "set " << use.prefix << "ROOT=" <<
06975         use.real_path << fs <<
06976         use.package << fs <<
06977         use.version << endl;
06978         
06979       if (use.package == "CMT")
06980         {
06981           //cout << "set CMTCONFIG=VisualC" << endl;
06982           cout << "set CMTCONFIG=" << system << endl;
06983           //cout << "set CMTEXTRATAGS=" << Cmt::m_extra_tags << endl;
06984         }
06985       else
06986         {
06987           cout << "set " << use.prefix << "CONFIG=" << tag << endl;
06988         }
06989         
06990       break;
06991     }
06992 }
06993 
07001 void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
07002 {
07003   int number;
07004 
07005   set_standard_macros ();
07006 
07007   cmt_regexp expression (pattern);
07008 
07009   bool has_pattern = (pattern != "");
07010 
07011   for (number = 0; number < Symbol::symbol_number (); number++)
07012     {
07013       Symbol& symbol = Symbol::symbol (number);
07014 
07015       if (has_pattern)
07016         {
07017           if (!expression.match (symbol.name)) continue;
07018         }
07019 
07020       if (m_action == action_show_macros)
07021         {
07022           // Only keep macros.
07023           if ((symbol.command == CommandSet) ||
07024               (symbol.command == CommandSetAppend) ||
07025               (symbol.command == CommandSetPrepend) ||
07026               (symbol.command == CommandSetRemove) ||
07027               (symbol.command == CommandAlias) ||
07028               (symbol.command == CommandPath) ||
07029               (symbol.command == CommandPathAppend) ||
07030               (symbol.command == CommandPathPrepend) ||
07031               (symbol.command == CommandPathRemove)) continue;
07032         }
07033       else if (m_action == action_show_sets)
07034         {
07035           // Exclude macros.
07036           if ((symbol.command == CommandMacro) ||
07037               (symbol.command == CommandMacroAppend) ||
07038               (symbol.command == CommandMacroPrepend) ||
07039               (symbol.command == CommandMacroRemove) ||
07040               (symbol.command == CommandMacroRemoveAll)) continue;
07041         }
07042       else if (m_action == action_build_tag_makefile)
07043         {
07044           // Exclude scripts.
07045           if ((symbol.command == CommandSetupScript) ||
07046               (symbol.command == CommandCleanupScript)) continue;
07047         }
07048 
07049       if (symbol.value_lists.size () < 1) continue;
07050 
07051       symbol.show_macro (mode);
07052     }
07053 }
07054 
07062 void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
07063 {
07064   int number;
07065 
07066   set_standard_macros ();
07067 
07068   cmt_regexp expression (pattern);
07069 
07070   bool has_pattern = (pattern != "");
07071 
07072   for (number = 0; number < Symbol::symbol_number (); number++)
07073     {
07074       Symbol& symbol = Symbol::symbol (number);
07075 
07076       if (has_pattern)
07077         {
07078           if (!expression.match (symbol.name)) continue;
07079         }
07080 
07081       if (m_action == action_show_macro_names)
07082         {
07083           // Only keep macros.
07084           if ((symbol.command == CommandSet) ||
07085               (symbol.command == CommandSetAppend) ||
07086               (symbol.command == CommandSetPrepend) ||
07087               (symbol.command == CommandSetRemove) ||
07088               (symbol.command == CommandAlias) ||
07089               (symbol.command == CommandPath) ||
07090               (symbol.command == CommandPathAppend) ||
07091               (symbol.command == CommandPathPrepend) ||
07092               (symbol.command == CommandPathRemove)) continue;
07093         }
07094       else if (m_action == action_show_set_names)
07095         {
07096           // Exclude macros.
07097           if ((symbol.command == CommandMacro) ||
07098               (symbol.command == CommandMacroAppend) ||
07099               (symbol.command == CommandMacroPrepend) ||
07100               (symbol.command == CommandMacroRemove) ||
07101               (symbol.command == CommandMacroRemoveAll)) continue;
07102         }
07103 
07104       cout << symbol.name << endl;
07105     }
07106 }
07107 
07108 //----------------------------------------------------------
07109 void Cmt::print_tabs (int tabs)
07110 {
07111   while (tabs > 0)
07112     {
07113       cout << "  ";
07114       tabs--;
07115     }
07116 }
07117 
07118 //----------------------------------------------------------
07119 int Cmt::reach_current_package ()
07120 {
07121   Use& use = Use::current ();
07122   cmt_string dir;
07123 
07124   if (m_debug)
07125     {
07126       cout << "Cmt::reach_current_package> pwd = " <<
07127         CmtSystem::pwd () <<
07128         " path=" << m_current_path <<
07129         endl;
07130     }
07131 
07132   /*
07133     Try to access the package.
07134   */
07135 
07136   if (m_current_package == "cmt_standalone")
07137     {
07138       if ((m_current_path != "") && (m_current_path != CmtSystem::pwd ()))
07139         {
07140           if (!CmtSystem::cd (m_current_path))
07141             {
07142               CmtError::set (CmtError::package_not_found,
07143                              "ReachCurrentPackage> Cannot reach the path directory");
07144               return (0);
07145             }
07146         }
07147 
07148       if (!CmtSystem::test_file ("requirements"))
07149         {
07150           if (!m_quiet)
07151             {
07152               cout << "#CMT> Cannot reach the requirements file" << endl;
07153             }
07154               
07155           CmtError::set (CmtError::package_not_found,
07156                          "ReachCurrentPackage> Cannot reach the requirements file");
07157           return (0);
07158         }
07159     }
07160   else if (m_current_package != "")
07161     {
07162       if (!use.move_to ())
07163         {
07164           CmtError::set (CmtError::package_not_found,
07165                          "ReachCurrentPackage> Cannot reach the path directory");
07166           return (0);
07167         }
07168 
07169       m_current_path = use.real_path;
07170 
07171       cmt_string parent = m_current_path;
07172       cmt_string d = m_current_path;
07173 
07174       for (;;)
07175         {
07176           d += "/../";
07177           if (!CmtSystem::is_package_directory (d))
07178             {
07179               CmtSystem::add_cmt_path (parent, "current package",
07180                                        m_cmt_path, 
07181                                        m_cmt_path_pwds, 
07182                                        m_cmt_path_sources);
07183               break;
07184             }
07185           parent = d;
07186         }
07187     }
07188   else
07189     {
07190       //
07191       // The cmt command has been given without explicit search for 
07192       // a package. Thus it is expected that we are in the context of a
07193       // true package.
07194       //
07195       //  This means that there should be a requirements file visible.
07196       //
07197       //  If this is not true, we'll make a try into ../cmt and then
07198       // a last try into ../mgr
07199       //
07200 
07201       if (!CmtSystem::test_file ("requirements"))
07202         {
07203           if (CmtSystem::cd ("../cmt") && 
07204               CmtSystem::test_file ("requirements"))
07205             {
07206               m_current_style = cmt_style;
07207             }
07208           else if (CmtSystem::cd ("../mgr") && 
07209                    CmtSystem::test_file ("requirements"))
07210             {
07211               m_current_style = mgr_style;
07212             }
07213           else
07214             {
07215               if (!m_quiet)
07216                 {
07217                   cout << "#CMT> Cannot reach the mgr branch" << endl;
07218                 }
07219               
07220               CmtError::set (CmtError::package_not_found,
07221                              "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
07222               return (0);
07223             }
07224         }
07225 
07226       dir = CmtSystem::pwd ();
07227 
07228       CmtSystem::dirname (dir, m_current_path);
07229       CmtSystem::basename (m_current_path, m_current_version);
07230       CmtSystem::dirname (m_current_path, m_current_path);
07231       CmtSystem::basename (m_current_path, m_current_package);
07232       CmtSystem::dirname (m_current_path, m_current_path);
07233       
07234       Use& use = Use::current ();
07235       
07236       use.package = m_current_package;
07237       use.version = m_current_version;
07238       use.path    = m_current_path;
07239       use.style   = m_current_style;
07240     }
07241 
07242   configure_current_dir ();
07243 
07244   /*
07245     Check Tag is always set up
07246   */
07247 
07248   if (m_debug) cerr << "reach_current_package0> current_tag=" << m_current_tag << endl;
07249 
07250   if (m_current_tag == "")
07251     {
07252       cmt_string env;
07253 
07254       env = CmtSystem::getenv (m_current_config);
07255       if (env != "")
07256         {
07257           Tag* tag;
07258 
07259           tag = Tag::add (env, PriorityConfig, "reach current package", 0);
07260           tag->mark ();
07261             //m_current_tag = env;
07262 
07263           //if (!m_quiet) cerr << "reach_current_package1> current_tag=" << m_current_tag << endl;
07264 
07265         }
07266     }
07267 
07268   if (m_debug)
07269     {
07270       cout << "pwd = " << CmtSystem::pwd () << endl;
07271     }
07272 
07273   /*
07274     Work on the requirements file.
07275   */
07276 
07277   if (dir != "") dir += CmtSystem::file_separator ();
07278   dir += "requirements";
07279   parse_requirements (dir, 0);
07280 
07281   if (m_debug) cerr << "reach_current_package2> current_tag=" << m_current_tag << endl;
07282 
07304   Pattern::apply_all_globals ();
07305 
07306   /*
07307     Select all possible tags
07308   */
07309 
07310   Tag::restore_tree ();
07311 
07312   return (1);
07313 }
07314 
07320 void Cmt::select (const CmtSystem::cmt_string_vector& words,
07321                   Use* use,
07322                   const cmt_string& file_name,
07323                   int line_number)
07324 {
07325   cmt_string command;
07326   CommandType command_type = CommandNone;
07327   int i;
07328 
07329   CmtError::clear ();
07330 
07331   if (words.size () == 0) return;
07332 
07333   command = words[0];
07334 
07335   if (command.size () == 0) return;
07336 
07337   //
07338   // First analyze the syntax
07339   //
07340 
07341   switch (command[0])
07342     {
07343     case 'a':
07344       if (command == "alias")
07345         {
07346           command_type = CommandAlias;
07347         }
07348       else if (command == "application")
07349         {
07350           command_type = CommandApplication;
07351         }
07352       else if (command == "apply_pattern")
07353         {
07354           command_type = CommandApplyPattern;
07355         }
07356       else if (command == "author")
07357         {
07358           command_type = CommandAuthor;
07359         }
07360       else
07361         {
07362           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07363         }
07364       break;
07365     case 'b':
07366       if (command == "branches")
07367         {
07368           command_type = CommandBranches;
07369         }
07370       else if (command == "build_strategy")
07371         {
07372           command_type = CommandBuildStrategy;
07373         }
07374       else
07375         {
07376           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07377         }
07378       break;
07379     case 'c':
07380       if (command == "cleanup_script")
07381         {
07382           command_type = CommandCleanupScript;
07383         }
07384       else
07385         {
07386           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07387         }
07388       break;
07389     case 'd':
07390       if (command == "document")
07391         {
07392           command_type = CommandDocument;
07393         }
07394       else
07395         {
07396           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07397         }
07398       break;
07399     case 'i':
07400       if (command == "ignore_pattern")
07401         {
07402           command_type = CommandIgnorePattern;
07403         }
07404       else if (command == "include_dirs")
07405         {
07406           command_type = CommandIncludeDirs;
07407         }
07408       else if (command == "include_path")
07409         {
07410           command_type = CommandIncludePath;
07411         }
07412       else
07413         {
07414           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07415         }
07416       break;
07417     case 'l':
07418       if (command == "language")
07419         {
07420           command_type = CommandLanguage;
07421         }
07422       else if (command == "library")
07423         {
07424           command_type = CommandLibrary;
07425         }
07426       else
07427         {
07428           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07429         }
07430       break;
07431     case 'm':
07432       if (command == "macro")
07433         {
07434           command_type = CommandMacro;
07435         }
07436       else if (command == "macro+")
07437         {
07438           command_type = CommandMacroAppend;
07439         }
07440       else if (command == "macro_prepend")
07441         {
07442           command_type = CommandMacroPrepend;
07443         }
07444       else if ((command == "macro_append") ||
07445                (command == "macro+"))
07446         {
07447           command_type = CommandMacroAppend;
07448         }
07449       else if (command == "macro_remove")
07450         {
07451           command_type = CommandMacroRemove;
07452         }
07453       else if (command == "macro_remove_all")
07454         {
07455           command_type = CommandMacroRemoveAll;
07456         }
07457       else if (command == "make_fragment")
07458         {
07459           command_type = CommandMakeFragment;
07460         }
07461       else if (command == "manager")
07462         {
07463           command_type = CommandManager;
07464         }
07465       else
07466         {
07467           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07468         }
07469       break;
07470     case 'p':
07471       if (command == "package")
07472         {
07473           command_type = CommandPackage;
07474         }
07475       else if (command == "path")
07476         {
07477           command_type = CommandPath;
07478         }
07479       else if (command == "path_append")
07480         {
07481           command_type = CommandPathAppend;
07482         }
07483       else if (command == "path_prepend")
07484         {
07485           command_type = CommandPathPrepend;
07486         }
07487       else if (command == "path_remove")
07488         {
07489           command_type = CommandPathRemove;
07490         }
07491       else if (command == "pattern")
07492         {
07493           command_type = CommandPattern;
07494         }
07495       else if (command == "public")
07496         {
07497           command_type = CommandPublic;
07498         }
07499       else if (command == "private")
07500         {
07501           command_type = CommandPrivate;
07502         }
07503       else
07504         {
07505           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07506         }
07507       break;
07508     case 's':
07509       if (command == "set")
07510         {
07511           command_type = CommandSet;
07512         }
07513       else if (command == "set_append")
07514         {
07515           command_type = CommandSetAppend;
07516         }
07517       else if (command == "set_prepend")
07518         {
07519           command_type = CommandSetPrepend;
07520         }
07521       else if (command == "set_remove")
07522         {
07523           command_type = CommandSetRemove;
07524         }
07525       else if (command == "setup_script")
07526         {
07527           command_type = CommandSetupScript;
07528         }
07529       else
07530         {
07531           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07532         }
07533       break;
07534     case 't':
07535       if (command == "tag")
07536         {
07537           command_type = CommandTag;
07538         }
07539       else if (command == "tag_exclude")
07540         {
07541           command_type = CommandTagExclude;
07542         }
07543       else
07544         {
07545           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07546         }
07547       break;
07548     case 'u':
07549       if (command == "use")
07550         {
07551           command_type = CommandUse;
07552         }
07553       else
07554         {
07555           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07556         }
07557       break;
07558     case 'v':
07559       if (command == "version_strategy")
07560         {
07561           command_type = CommandVersionStrategy;
07562         }
07563       else if (command == "version")
07564         {
07565           command_type = CommandVersion;
07566         }
07567       else
07568         {
07569           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07570         }
07571       break;
07572     default:
07573       CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07574       break;
07575     }
07576 
07577   if (CmtError::has_pending_error ())
07578     {
07579       if (!m_quiet)
07580         {
07581           cout << "#CMT> bad syntax in requirements of " << use->package
07582                << " " << use->version 
07583                << " " << use->specified_path 
07584                << " line #" << line_number;
07585           cout << " [" << command << " ...]" << endl;
07586         }
07587 
07588       return;
07589     }
07590 
07591 
07592   //
07593   // Then interpret the action
07594   //
07595 
07596   switch (command_type)
07597     {
07598     case CommandAlias :
07599       Symbol::action (words, command_type, use);
07600       break;
07601     case CommandApplication :
07602       if (use == &(Use::current ()))
07603         {
07604           Constituent::action (Application, words);
07605         }
07606       break;
07607     case CommandApplyPattern :
07608       ApplyPattern::action (words, use);
07609       break;
07610     case CommandAuthor :
07611       use->author_action (words);
07612       break;
07613     case CommandBranches :
07614       if (use == &(Use::current ())) Branch::action (words);
07615       break;
07616     case CommandBuildStrategy :
07617       m_current_build_strategy = DefaultBuildStrategy;
07618 
07619       for (i = 1; i < words.size (); i++)
07620         {
07621           const cmt_string& w = words[i];
07622 
07623           if (w == "prototypes")
07624             {
07625               m_current_build_strategy |= Prototypes;
07626             }
07627           else if (w == "no_prototypes")
07628             {
07629               m_current_build_strategy |= NoPrototypes;
07630             }
07631           else if (w == "keep_makefiles")
07632             {
07633               m_current_build_strategy |= KeepMakefiles;
07634             }
07635           else if (w == "rebuild_makefiles")
07636             {
07637               m_current_build_strategy |= RebuildMakefiles;
07638             }
07639 
07640           if ((m_action == action_show_strategies) && !m_quiet)
07641             {
07642               cout << "# Package " << use->package <<
07643                 " adds " << w << " to build strategy" << endl;
07644             }
07645         }
07646       break;
07647     case CommandCleanupScript :
07648       Script::action (words, CleanupScript, use);
07649       Symbol::action (words, command_type, use);
07650       break;
07651     case CommandDocument :
07652       if (use == &(Use::current ()))
07653         Constituent::action (Document, words);
07654       break;
07655     case CommandIgnorePattern :
07656       IgnorePattern::action (words, use);
07657       break;
07658     case CommandIncludeDirs :
07659       Include::action (words, use);
07660       break;
07661     case CommandIncludePath :
07662       if (words.size () > 1)
07663         {
07664           use->set_include_path (words[1]);
07665         }
07666       break;
07667     case CommandLanguage :
07668       Language::action (words);
07669       break;
07670     case CommandLibrary :
07671       if (use == &(Use::current ()))
07672         Constituent::action (Library, words);
07673       break;
07674     case CommandMacro :
07675     case CommandMacroPrepend :
07676     case CommandMacroAppend :
07677     case CommandMacroRemove :
07678     case CommandMacroRemoveAll :
07679       Symbol::action (words, command_type, use);
07680       break;
07681     case CommandMakeFragment :
07682       Fragment::action (words, use);
07683       break;
07684     case CommandManager :
07685       use->manager_action (words);
07686       break;
07687     case CommandPackage :
07688       if (words.size () > 1)
07689         {
07690           if (use == &(Use::current()))
07691             {
07692               m_current_package = words[1];
07693               build_prefix (m_current_package, m_current_prefix);
07694 
07695               if ((use->package != "") &&
07696                   (use->package != m_current_package))
07697                 {
07698                   /*
07699                     Unknown keyword : just ignore the line
07700                   */
07701                   if (!m_quiet)
07702                     {
07703                       cout << "#CMT> package name mismatch in requirements of " <<
07704                         use->package << " " <<
07705                         use->version << " line #" << line_number;
07706                       cout << " : " << m_current_package << " versus " <<
07707                         use->package << endl;
07708                     }
07709                 }
07710 
07711               use->set (m_current_package,
07712                         m_current_version,
07713                         m_current_path,
07714                         "",
07715                         "");
07716 
07717               use->change_path (m_current_path);
07718               use->style = m_current_style;
07719             }
07720         }
07721       break;
07722     case CommandPath :
07723     case CommandPathAppend :
07724     case CommandPathPrepend :
07725     case CommandPathRemove :
07726       Symbol::action (words, command_type, use);
07727       break;
07728     case CommandPattern :
07729       Pattern::action (words, use);
07730       break;
07731     case CommandPrivate :
07732       m_scope = ScopePrivate;
07733       break;
07734     case CommandPublic :
07735       m_scope = ScopePublic;
07736       break;
07737     case CommandSet :
07738     case CommandSetAppend :
07739     case CommandSetPrepend :
07740     case CommandSetRemove :
07741       Symbol::action (words, command_type, use);
07742       break;
07743     case CommandSetupScript :
07744       Script::action (words, SetupScript, use);
07745       Symbol::action (words, command_type, use);
07746       break;
07747     case CommandTag :
07748       Tag::action (words, use);
07749       break;
07750     case CommandTagExclude :
07751       Tag::action_exclude (words, use);
07752       break;
07753     case CommandUse :
07754       Use::action (words, use);
07755       break;
07756     case CommandVersionStrategy :
07757       if (words.size () > 1)
07758         {
07759           const cmt_string& w = words[1];
07760 
07761           if (w == "best_fit")
07762             {
07763               m_current_strategy = BestFit;
07764             }
07765           else if (w == "best_fit_no_check")
07766             {
07767               m_current_strategy = BestFitNoCheck;
07768             }
07769           else if (w == "first_choice")
07770             {
07771               m_current_strategy = FirstChoice;
07772             }
07773           else if (w == "last_choice")
07774             {
07775               m_current_strategy = LastChoice;
07776             }
07777           else if (w == "keep_all")
07778             {
07779               m_current_strategy = KeepAll;
07780             }
07781 
07782           if ((m_action == action_show_strategies) && !m_quiet)
07783             {
07784               cout << "# Package " << use->package <<
07785                 " sets version strategy to " << w << endl;
07786             }
07787         }
07788       break;
07789     case CommandVersion :
07790       /*
07791         m_current_version = words[1];
07792       */
07793       break;
07794     default:
07795       /*
07796         Unknown keyword : just ignore the line
07797       */
07798       if (!m_quiet)
07799         {
07800           cout << "#CMT> bad syntax in requirements of " << use->package
07801                << " " << use->version << " line #" << line_number;
07802           cout << " [" << command << "...]" << endl;
07803         }
07804 
07805       CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
07806 
07807       return;
07808     }
07809 }
07810 
07811 static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
07812                                  const cmt_string& path)
07813 {
07814   static cmt_string fs = CmtSystem::file_separator ();
07815   cmt_string result;
07816 
07817     /*
07818     //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
07819     {
07820     */
07821 
07822     //
07823     //  If there is a common prefix between
07824     //  use->real_path and pwd
07825     //  we have 
07826     //  use->real_path = /<prefix>/aaa
07827     //  pwd            = /<prefix>/bbb
07828     //
07829     //  Then use->real_path may be expressed as:
07830     //  ../..../../aaa
07831     //   where ../..../../ moves up to /<prefix>
07832     //
07833     //   Then we try to find the shortest between
07834     //
07835     //     /<prefix> and ../..../..
07836     //
07837   cmt_string a = path;
07838   
07839   CmtSystem::cmt_string_vector va;
07840   
07841   va.clear ();
07842   
07843   CmtSystem::split (a, fs, va);
07844   
07845   int m = va.size ();
07846   if (pwd.size () < m) m = pwd.size ();
07847   
07848   int i;
07849   
07850     //cout << "Package " << use->package << endl;
07851   
07852   for (i = 0; i < m; i++)
07853     {
07854       const cmt_string& fa = va[i];
07855       const cmt_string& fb = pwd[i];
07856       
07857         //cout << "  fa=" << fa << " fb=" << fb << endl;
07858       
07859       if (fa != fb) break;
07860     }
07861   
07862   cmt_string ups = "";
07863   
07864   if (i > 0)
07865     {
07866         // We have the prefix.
07867         // if we count what remains from pwd, then 
07868         // we have the number of ../ required to 
07869         // move to /<prefix>
07870       int j;
07871       
07872       for (j = i; j < pwd.size (); j++)
07873         {
07874           if (j > i) ups += fs;
07875           ups += "..";
07876         }
07877 
07878       for (j = i; j < va.size (); j++)
07879         {
07880           ups += fs;
07881           ups += va[j];
07882         }
07883     }
07884   
07885     //
07886     // Here ups contains the ../..../../aaa form
07887     // for the use->real_path or is empty when there
07888     // were no common prefix.
07889     //
07890   
07891     //if (ups != "")
07892   if ((ups != "") &&
07893       (ups.size () < path.size ()))
07894     {
07895       result = ups;
07896     }
07897   else
07898     {
07899       result = path;
07900     }
07901 
07902   return (result);
07903 }
07904 
07909 class StandardMacroBuilder
07910 {
07911 public:
07912 
07913   StandardMacroBuilder (const cmt_string& tag,
07914                         const cmt_string& package,
07915                         const cmt_string& version,
07916                         const cmt_string& prefix,
07917                         CmtDirStyle style)
07918   {
07919     fs = CmtSystem::file_separator ();
07920     buffer = "";
07921     pwd = CmtSystem::pwd ();
07922     CmtSystem::split (pwd, fs, vb);
07923     current_use = &(Use::current ());
07924     current_tag = tag;
07925     current_package = package;
07926     current_version = version;
07927     current_prefix = prefix;
07928     current_style = style;
07929   }
07930 
07931   void apply ()
07932   {
07933     Cmt::parse_requirements_line (buffer, current_use);
07934     buffer = "";
07935   }
07936 
07940   void fill_for_tag ()
07941   {
07942     static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
07943 
07944     if (!Symbol::is_selected ("tag"))
07945       {
07946         if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
07947 
07948         if (current_tag == "")
07949           {
07950             buffer = "macro tag \"$(CMTCONFIG)\"";
07951           }
07952         else
07953           {
07954             buffer = "macro tag \"";
07955             buffer += current_tag;
07956             buffer += "\"";
07957           }
07958         
07959         if (tag_debug) cerr << " define tag: " << buffer << endl;
07960         
07961         apply ();
07962       }
07963   }
07964 
07968   void fill_for_package_tag ()
07969   {
07970     cmt_string package_tag = current_package;
07971     package_tag += "_tag";
07972     
07973     if (!Symbol::is_selected (package_tag))
07974       {
07975         buffer  = "macro ";
07976         buffer += package_tag;
07977         buffer += " \"$(tag)\"";
07978 
07979         apply ();
07980       }
07981   }
07982 
07989   void fill_for_package (const cmt_string& current_dir)
07990   {
07991     cmt_string PACKAGE_ROOT = current_prefix;
07992     PACKAGE_ROOT += "ROOT";
07993     
07994     if (!Symbol::is_selected (PACKAGE_ROOT))
07995       {
07996         if (current_use->path == "")
07997           {
07998             buffer = "macro ";
07999             buffer += PACKAGE_ROOT;
08000             buffer += " \"";
08001             buffer += current_dir;
08002             buffer += "\"";
08003           }
08004         else
08005           {
08006             current_use->path.replace_all (CmtSystem::file_separator (), fs);
08007             
08008             buffer = "macro ";
08009             buffer += PACKAGE_ROOT;
08010             buffer += " \"";
08011             buffer += current_use->path;
08012             buffer += fs;
08013             buffer += current_use->package;
08014             buffer += fs;
08015             buffer += current_use->version;
08016             buffer += "\"";
08017           }
08018         
08019         apply ();
08020       }
08021 
08022     if (!Symbol::is_selected ("PACKAGE_ROOT"))
08023       {
08024         buffer = "macro PACKAGE_ROOT \"$(";
08025         buffer += PACKAGE_ROOT;
08026         buffer += ")\"";
08027 
08028         apply ();
08029       }
08030 
08031     cmt_string package_root = current_use->package;
08032     package_root += "_root";
08033     
08034     if (!Symbol::is_selected (package_root))
08035       {
08036         buffer = "macro ";
08037         buffer += package_root;
08038         buffer += " \"";
08039 
08040         if (current_use->path == "")
08041           {
08042             buffer += current_dir;
08043           }
08044         else
08045           {
08046             current_use->path.replace_all (CmtSystem::file_separator (), fs);
08047 
08048             buffer += get_best_form (vb, current_use->path);
08049             buffer += fs;
08050             buffer += current_use->package;
08051             buffer += fs;
08052             buffer += current_use->version;
08053           }
08054         buffer += "\"";
08055 
08056         apply ();
08057       }
08058 
08059     cmt_string package_version = current_prefix;
08060     package_version += "VERSION";
08061 
08062     if (!Symbol::is_selected (package_version))
08063       {
08064         buffer = "macro ";
08065         buffer += package_version;
08066         buffer += " \"";
08067         buffer += current_use->version;
08068         buffer += "\"";
08069 
08070         apply ();
08071       }
08072   }
08073 
08086   void fill_for_branches ()
08087   {
08092     if (current_style == none_style)
08093       {
08094         buffer = "macro srcdir \".";
08095         buffer += "\"";
08096         apply ();
08097 
08098         buffer = "macro src \".";
08099         buffer += fs;
08100         buffer += "\"";
08101         apply ();
08102 
08103         buffer = "macro inc \".";
08104         buffer += fs;
08105         buffer += "\"";
08106         apply ();
08107 
08108         buffer = "macro mgr \".";
08109         buffer += fs;
08110         buffer += "\"";
08111         apply ();
08112 
08113         buffer = "macro bin \".";
08114         buffer += fs;
08115         buffer += "\"";
08116         apply ();
08117 
08118         buffer = "macro javabin \".";
08119         buffer += fs;
08120         buffer += "\"";
08121         apply ();
08122 
08123         buffer = "macro doc \".";
08124         buffer += fs;
08125         buffer += "\"";
08126         apply ();
08127 
08128         buffer = "macro version \"\"";
08129         apply ();
08130 
08131         buffer = "macro package \"";
08132         buffer += current_package;
08133         buffer += "\"";
08134         apply ();
08135       }
08136     else
08137       {
08138         if (!Symbol::is_selected ("srcdir"))
08139           {
08140             buffer = "macro srcdir \"..";
08141             buffer += fs;
08142             buffer += "src";
08143             buffer += "\"";
08144             apply ();
08145           }
08146         
08147         if (!Symbol::is_selected ("src"))
08148           {
08149             buffer = "macro src \"..";
08150             buffer += fs;
08151             buffer += "src";
08152             buffer += fs;
08153             buffer += "\"";
08154             apply ();
08155           }
08156         
08157         if (!Symbol::is_selected ("inc"))
08158           {
08159             buffer = "macro inc \"..";
08160             buffer += fs;
08161             buffer += "src";
08162             buffer += fs;
08163             buffer += "\"";
08164             apply ();
08165           }
08166         
08167         if (!Symbol::is_selected ("doc"))
08168           {
08169             buffer = "macro doc \"..";
08170             buffer += fs;
08171             buffer += "doc";
08172             buffer += fs;
08173             buffer += "\"";
08174             apply ();
08175           }
08176         
08177         if (!Symbol::is_selected ("bin"))
08178           {
08179             cmt_string package_tag = current_package;
08180             package_tag += "_tag";
08181 
08182             buffer = "macro bin \"..";
08183             buffer += fs;
08184             buffer += "$(";
08185             buffer += package_tag;
08186             buffer += ")";
08187             buffer += fs;
08188             buffer += "\"";
08189             apply ();
08190           }
08191 
08192         if (!Symbol::is_selected ("javabin"))
08193           {
08194             buffer = "macro javabin \"..";
08195             buffer += fs;
08196             buffer += "classes";
08197             buffer += fs;
08198             buffer += "\"";
08199             apply ();
08200           }
08201         
08202         if (current_style == mgr_style)
08203           {
08204             buffer = "macro mgrdir \"mgr\"";
08205             apply ();
08206 
08207             buffer = "macro mgr \"..";
08208             buffer += fs;
08209             buffer += "mgr";
08210             buffer += fs;
08211             buffer += "\"";
08212             apply ();
08213           }
08214         else
08215           {
08216             buffer = "macro mgrdir \"cmt\"";
08217             apply ();
08218 
08219             buffer = "macro mgr \"..";
08220             buffer += fs;
08221             buffer += "cmt";
08222             buffer += fs;
08223             buffer += "\"";
08224             apply ();
08225           }
08226         
08227         buffer = "macro version \"";
08228         buffer += current_version;
08229         buffer += "\"";
08230         apply ();
08231 
08232         buffer = "macro package \"";
08233         buffer += current_package;
08234         buffer += "\"";
08235         apply ();
08236       }
08237   }
08238 
08242   void fill_for_use_tag (Use* use)
08243   {
08244     cmt_string package_tag = use->package + "_tag";
08245 
08246     if (!Symbol::is_selected (package_tag))
08247       {
08248         buffer  = "macro ";
08249         buffer += package_tag;
08250         buffer += " \"$(tag)\"";
08251         apply ();
08252       }
08253   }
08254 
08258   void fill_for_use_ROOT (Use* use)
08259   {
08260     cmt_string PACKAGE_ROOT = use->prefix;
08261     PACKAGE_ROOT += "ROOT";
08262 
08263     if (!Symbol::is_selected (PACKAGE_ROOT))
08264       {
08265         if (use->located ())
08266           {
08267             buffer  = "macro ";
08268             buffer += PACKAGE_ROOT;
08269             buffer += " \"";
08270             buffer += use->get_full_path ();
08271             buffer += "\"";
08272             apply ();
08273           }
08274       }
08275   }
08276 
08280   void fill_for_use_root (Use* use)
08281   {
08282     cmt_string package_root = use->package;
08283     package_root += "_root";
08284 
08285     if (!Symbol::is_selected (package_root))
08286       {
08287         if (use->located ())
08288           {
08289             buffer  = "macro ";
08290             buffer += package_root;
08291             buffer += " \"";
08292             buffer += get_best_form (vb, use->real_path);
08293             buffer += fs;
08294             buffer += use->package;
08295             buffer += fs;
08296             buffer += use->version;
08297             buffer += "\"";
08298             apply ();
08299           }
08300       }
08301   }
08302 
08306   void fill_for_use_version (Use* use)
08307   {
08308     cmt_string package_version = use->prefix;
08309     package_version += "VERSION";
08310     
08311     if (!Symbol::is_selected (package_version))
08312       {
08313         buffer  = "macro ";
08314         buffer += package_version;
08315         buffer += " \"";
08316         buffer += use->version;
08317         buffer += "\"";
08318         apply ();
08319       }
08320   }
08321 
08322   void fill_for_uses ()
08323   {
08324     Use::UsePtrVector& Uses = Use::uses ();
08325 
08326     if (Uses.size () == 0) return;
08327 
08328     for (int number = 0; number < Uses.size (); number++)
08329       {
08330         Use* use = Uses[number];
08331 
08332         if (use->package == "CMT") continue;
08333         if (use->package == "methods") continue;
08334         if (use->discarded) continue;
08335 
08336         fill_for_use_tag (use);
08337         fill_for_use_ROOT (use);
08338         fill_for_use_root (use);
08339         fill_for_use_version (use);
08340       }
08341   }
08342 
08346   void fill_for_use_requirements ()
08347   {
08348     Use::UsePtrVector& Uses = Use::uses ();
08349 
08350     if (Uses.size () == 0) return;
08351 
08352     if (!Symbol::is_selected ("use_requirements"))
08353       {
08354         buffer  = "macro use_requirements \"";
08355         buffer += "requirements ";
08356         
08357         for (int number = 0; number < Uses.size (); number++)
08358           {
08359             Use* use = Uses[number];
08360             
08361             if (use->discarded) continue;
08362             
08363             if (use->located ())
08364               {
08365                 buffer += "$(";
08366                 buffer += use->prefix;
08367                 buffer += "ROOT)";
08368                 buffer += fs;
08369                 
08370                 if (use->style == mgr_style) buffer += "mgr";
08371                 else buffer += "cmt";
08372                 
08373                 buffer += fs;
08374                 buffer += "requirements ";
08375               }
08376           }
08377         
08378         buffer += "\"";
08379         
08380         apply ();
08381       }
08382   }
08383 
08387   void fill_for_use_includes ()
08388   {
08389     Use::UsePtrVector& Uses = Use::uses ();
08390 
08391     if (Uses.size () == 0) return;
08392 
08393     if (!Symbol::is_selected ("use_includes"))
08394       {
08395         buffer = "macro_append use_includes \' ";
08396         
08397         for (int number = 0; number < Uses.size (); number++)
08398           {
08399             Use* use = Uses[number];
08400             
08401             if (use->package == "CMT") continue;
08402             if (use->package == "methods") continue;
08403             
08404             if (Cmt::get_debug ())
08405               {
08406                 cout << "fill use_includes for " << use->package 
08407                      << " discarded=" << use->discarded
08408                      << " auto_imports=" << use->auto_imports << endl;
08409               }
08410             
08411             if (use->discarded) continue;
08412             if (use->auto_imports == Off) continue;
08413             
08414             use->fill_includes_macro (buffer);
08415           }
08416         
08417         buffer += "\'";
08418         
08419         apply ();
08420       }
08421   }
08422 
08426   void fill_for_use_fincludes ()
08427   {
08428     Use::UsePtrVector& Uses = Use::uses ();
08429 
08430     if (Uses.size () == 0) return;
08431 
08432     if (!Symbol::is_selected ("use_fincludes"))
08433       {
08434         buffer = "macro_append use_fincludes \" $(use_includes)\"";
08435         apply ();
08436       }
08437   }
08438 
08442   void fill_for_use_stamps ()
08443   {
08444     Use::UsePtrVector& Uses = Use::uses ();
08445 
08446     if (Uses.size () == 0) return;
08447 
08448     if (!Symbol::is_selected ("use_stamps"))
08449       {
08450         buffer = "macro use_stamps \"";
08451         (Use::current()).fill_macro (buffer, "stamps");
08452         
08453         for (int number = 0; number < Uses.size (); number++)
08454           {
08455             Use* use = Uses[number];
08456             
08457             if (use->package == "CMT") continue;
08458             if (use->package == "methods") continue;
08459             if (use->discarded) continue;
08460             
08461             use->fill_macro (buffer, "stamps");
08462           }
08463         
08464         buffer += "\"";
08465         
08466         apply ();
08467       }
08468   }
08469 
08473   void fill_for_use_cflags ()
08474   {
08475     Use::UsePtrVector& Uses = Use::uses ();
08476 
08477     if (Uses.size () == 0) return;
08478 
08479     if (!Symbol::is_selected ("use_cflags"))
08480       {
08481         Use::fill_macro_all (buffer, "cflags");
08482         apply ();
08483       }
08484   }
08485 
08489   void fill_for_use_pp_cflags ()
08490   {
08491     Use::UsePtrVector& Uses = Use::uses ();
08492 
08493     if (Uses.size () == 0) return;
08494 
08495     if (!Symbol::is_selected ("use_pp_cflags"))
08496       {
08497         Use::fill_macro_all (buffer, "pp_cflags");
08498         apply ();
08499       }
08500   }
08501 
08505   void fill_for_use_cppflags ()
08506   {
08507     Use::UsePtrVector& Uses = Use::uses ();
08508 
08509     if (Uses.size () == 0) return;
08510 
08511     if (!Symbol::is_selected ("use_cppflags"))
08512       {
08513         Use::fill_macro_all (buffer, "cppflags");
08514         apply ();
08515       }
08516   }
08517 
08521   void fill_for_use_pp_cppflags ()
08522   {
08523     Use::UsePtrVector& Uses = Use::uses ();
08524 
08525     if (Uses.size () == 0) return;
08526 
08527     if (!Symbol::is_selected ("use_pp_cppflags"))
08528       {
08529         Use::fill_macro_all (buffer, "pp_cppflags");
08530         apply ();
08531       }
08532   }
08533 
08537   void fill_for_use_fflags ()
08538   {
08539     Use::UsePtrVector& Uses = Use::uses ();
08540 
08541     if (Uses.size () == 0) return;
08542 
08543     if (!Symbol::is_selected ("use_fflags"))
08544       {
08545         Use::fill_macro_all (buffer, "fflags");
08546         apply ();
08547       }
08548   }
08549 
08553   void fill_for_use_pp_fflags ()
08554   {
08555     Use::UsePtrVector& Uses = Use::uses ();
08556 
08557     if (Uses.size () == 0) return;
08558 
08559     if (!Symbol::is_selected ("use_pp_fflags"))
08560       {
08561         Use::fill_macro_all (buffer, "pp_fflags");
08562         apply ();
08563       }
08564   }
08565 
08569   void fill_for_use_linkopts ()
08570   {
08571     Use::UsePtrVector& Uses = Use::uses ();
08572 
08573     if (Uses.size () == 0) return;
08574 
08575     if (!Symbol::is_selected ("use_linkopts"))
08576       {
08577         Use::fill_macro_all (buffer, "linkopts");
08578         apply ();
08579       }
08580   }
08581 
08585   void fill_for_use_libraries ()
08586   {
08587     Use::UsePtrVector& Uses = Use::uses ();
08588 
08589     if (Uses.size () == 0) return;
08590 
08591     if (!Symbol::is_selected ("use_libraries"))
08592       {
08593         buffer  = "macro use_libraries \"";
08594 
08595         for (int number = 0; number < Uses.size (); number++)
08596           {
08597             Use* use = Uses[number];
08598             
08599             if (use->package == "CMT") continue;
08600             if (use->package == "methods") continue;
08601             if (use->discarded) continue;
08602             
08603             use->fill_macro (buffer, "libraries");
08604           }
08605         
08606         buffer += "\"";
08607         
08608         apply ();
08609       }
08610   }
08611 
08615   void fill_for_includes ()
08616   {
08617     Use::UsePtrVector& Uses = Use::uses ();
08618 
08619     if (Uses.size () == 0) return;
08620 
08621     if (!Symbol::is_selected ("includes"))
08622       {
08623         buffer = "macro_append includes \' ";
08624 
08625         Use& use = Use::current();
08626 
08627         if (use.include_path == "")
08628           {
08629             buffer += "$(ppcmd)\"$(srcdir)\" ";
08630           }
08631         else if (use.include_path != "none")
08632           {
08633             buffer += "$(ppcmd)\"";
08634             buffer += use.include_path;
08635             buffer += "\" ";
08636           }
08637         
08638         for (int include_number = 0;
08639              include_number < use.includes.size ();
08640              include_number++)
08641           {
08642             Include& incl = use.includes[include_number];
08643             
08644             buffer += "$(ppcmd)\"";
08645             buffer += incl.name;
08646             buffer += "\" ";
08647           }
08648         
08649         buffer += "$(use_includes)\'";
08650         
08651         apply ();
08652       }
08653   }
08654 
08658   void fill_for_fincludes ()
08659   {
08660     Use::UsePtrVector& Uses = Use::uses ();
08661 
08662     if (Uses.size () == 0) return;
08663 
08664     if (!Symbol::is_selected ("fincludes"))
08665       {
08666         buffer = "macro_append fincludes \" $(includes)\"";
08667         apply ();
08668       }
08669   }
08670 
08677   void fill_for_all_constituents ()
08678   {
08680     Constituent::parse_all ();
08681 
08682     Use::UsePtrVector& Uses = Use::uses ();
08683 
08684     const Constituent::ConstituentVector& constituents =
08685       Constituent::constituents ();
08686 
08687   
08689 
08690     cmt_vector<bool> base_auto_imports_states;
08691 
08692     base_auto_imports_states.resize (Uses.size ());
08693 
08694     int number;
08695 
08696     for (number = 0; number < Uses.size (); number++)
08697       {
08698         Use* use = Uses[number];
08699         base_auto_imports_states[number] = (use->auto_imports != Off);
08700       }
08701 
08703 
08704     for (number = 0; number < constituents.size (); number++)
08705       {
08706         const Constituent& constituent = constituents[number];
08707 
08708         Use::UsePtrVector imports;
08709         int i;
08710 
08728         if (constituent.type == Document) continue;
08729         if (constituent.imports.size () == 0) 
08730           {
08731             buffer = "macro_append ";
08732             buffer += constituent.name;
08733             buffer += "_use_linkopts ";
08734             buffer += " \" ";
08735         
08736             current_use->fill_macro (buffer, "linkopts");
08737         
08738             for (i = 0; i < Uses.size (); i++)
08739               {
08740                 if (base_auto_imports_states[i])
08741                   {
08742                     Use* u = Uses[i];
08743                 
08744                     if (u->package == "CMT") continue;
08745                     if (u->package == "methods") continue;
08746                     if (u->discarded) continue;
08747                     
08748                     u->fill_macro (buffer, "linkopts");
08749                   }
08750               }
08751             buffer += "\"";
08752             apply ();
08753 
08754           /*
08755             buffer = "macro_append ";
08756             buffer += constituent.name;
08757             buffer += "_use_linkopts ";
08758             buffer += " \" $(use_linkopts)\"";
08759             apply ();
08760           */
08761 
08762             continue;
08763           }
08764 
08770         cmt_vector<bool> auto_imports_states (base_auto_imports_states);
08771 
08772         for (i = 0; i < constituent.imports.size (); i++)
08773           {
08774             const cmt_string& import = constituent.imports[i];
08775             
08776             //
08777             // Resolve the imported uses
08778             //
08779 
08780             int use_index = Use::find_index (import, "", "");
08781 
08782             if (use_index >= 0)
08783               {
08784                 Use* u = Uses[use_index];
08785             
08786                 if (u->package == "CMT") continue;
08787                 if (u->package == "methods") continue;
08788                 if (u->discarded) continue;
08789                 if (u->auto_imports != Off) continue;
08790 
08791                 Use::set_auto_imports_state (use_index, auto_imports_states);
08792               }
08793           }
08794 
08799         for (i = 0; i < base_auto_imports_states.size (); i++)
08800           {
08801             if (auto_imports_states[i] != base_auto_imports_states[i])
08802               {
08803                 Use* u = Uses[i];
08804 
08805                 if (u->package == "CMT") continue;
08806                 if (u->package == "methods") continue;
08807                 if (u->discarded) continue;
08808                 if (u->auto_imports != Off) continue;
08809 
08810                 imports.push_back (u);
08811               }
08812           }
08813         
08814         if (imports.size () == 0) return;
08815 
08816         cmt_string prefix;
08817             
08818         //
08819         // Documents are not considered 
08820         //
08821         switch (constituent.type)
08822           {
08823           case Application:
08824             prefix = "app_";
08825             break;
08826           case Library:
08827             prefix = "lib_";
08828             break;
08829           }
08830             
08831         buffer = "macro_append ";
08832         buffer += prefix;
08833         buffer += constituent.name;
08834         buffer += "_cflags ";
08835         buffer += " \' ";
08836         for (i = 0; i < imports.size (); i++)
08837           {
08838             Use* u = imports[i];
08839             
08840             u->fill_includes_macro (buffer);
08841             u->fill_macro (buffer, "cflags");
08842           }
08843         buffer += "\'";
08844         apply ();
08845         
08846         buffer = "macro_append ";
08847         buffer += prefix;
08848         buffer += constituent.name;
08849         buffer += "_pp_cflags ";
08850         buffer += " \" ";
08851         for (i = 0; i < imports.size (); i++)
08852           {
08853             Use* u = imports[i];
08854             
08855             u->fill_macro (buffer, "pp_cflags");
08856           }
08857         buffer += "\"";
08858         apply ();
08859         
08860         buffer = "macro_append ";
08861         buffer += prefix;
08862         buffer += constituent.name;
08863         buffer += "_cppflags ";
08864         buffer += " \' ";
08865         for (i = 0; i < imports.size (); i++)
08866           {
08867             Use* u = imports[i];
08868             
08869             u->fill_includes_macro (buffer);
08870             u->fill_macro (buffer, "cppflags");
08871           }
08872         buffer += "\'";
08873         apply ();
08874         
08875         buffer = "macro_append ";
08876         buffer += prefix;
08877         buffer += constituent.name;
08878         buffer += "_pp_cppflags ";
08879         buffer += " \" ";
08880         for (i = 0; i < imports.size (); i++)
08881           {
08882             Use* u = imports[i];
08883             
08884             u->fill_macro (buffer, "pp_cppflags");
08885           }
08886         buffer += "\"";
08887         apply ();
08888         
08889         buffer = "macro_append ";
08890         buffer += prefix;
08891         buffer += constituent.name;
08892         buffer += "_fflags ";
08893         buffer += " \' ";
08894         for (i = 0; i < imports.size (); i++)
08895           {
08896             Use* u = imports[i];
08897             
08898             u->fill_includes_macro (buffer);
08899             u->fill_macro (buffer, "fflags");
08900           }
08901         buffer += "\'";
08902         apply ();
08903         
08904         buffer = "macro_append ";
08905         buffer += prefix;
08906         buffer += constituent.name;
08907         buffer += "_pp_fflags ";
08908         buffer += " \" ";
08909         for (i = 0; i < imports.size (); i++)
08910           {
08911             Use* u = imports[i];
08912             
08913             u->fill_macro (buffer, "pp_fflags");
08914           }
08915         buffer += "\"";
08916         apply ();
08917 
08925         buffer = "macro_append ";
08926         buffer += constituent.name;
08927         buffer += "linkopts ";
08928         buffer += " \" ";
08929         for (i = 0; i < imports.size (); i++)
08930           {
08931             Use* u = imports[i];
08932             
08933             u->fill_macro (buffer, "linkopts");
08934           }
08935         buffer += "\"";
08936         apply ();
08937         
08944         buffer = "macro_append ";
08945         buffer += constituent.name;
08946         buffer += "_use_linkopts ";
08947         buffer += " \" ";
08948         
08949         current_use->fill_macro (buffer, "linkopts");
08950         
08951         for (i = 0; i < Uses.size (); i++)
08952           {
08953             if (auto_imports_states[i])
08954               {
08955                 Use* u = Uses[i];
08956                 
08957                 if (u->package == "CMT") continue;
08958                 if (u->package == "methods") continue;
08959                 if (u->discarded) continue;
08960                 
08961                 u->fill_macro (buffer, "linkopts");
08962               }
08963           }
08964         buffer += "\"";
08965         apply ();
08966       }
08967   }
08968 
08969 private:
08970   cmt_string fs;
08971   cmt_string buffer;
08972   CmtSystem::cmt_string_vector vb;
08973   cmt_string pwd;
08974   Use* current_use;
08975   cmt_string current_tag; 
08976   cmt_string current_package; 
08977   cmt_string current_version; 
08978   cmt_string current_prefix; 
08979   CmtDirStyle current_style;
08980 };
08981 
08982 //----------------------------------------------------------
08983 void Cmt::set_standard_macros ()
08984 {
08985   if (m_standard_macros_done) return;
08986 
08987   m_standard_macros_done = true;
08988 
08989   int number;
08990   cmt_string temp;
08991   Use::UsePtrVector& Uses = Use::uses ();
08992   Use& current_use = Use::current ();
08993 
08994   cmt_string fs = CmtSystem::file_separator ();
08995 
08996   cmt_string pwd = CmtSystem::pwd ();
08997 
08998   if (CmtSystem::test_file ("../cmt/requirements")) m_current_style = cmt_style;
08999   else if (CmtSystem::test_file ("../mgr/requirements")) m_current_style = mgr_style;
09000   else m_current_style = none_style;
09001 
09002   // Prepare computation of the best form for relative path from current directory
09003   // to package directories.
09004   CmtSystem::cmt_string_vector vb;
09005   CmtSystem::split (pwd, fs, vb);
09006 
09007 
09012   bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
09013 
09014   if (tag_debug) cerr << "set_standard_macro0> current_tag=" << m_current_tag << endl;
09015 
09016   if (m_current_tag != "")
09017     {
09018         // this is when some -tag= argument was used.
09019       if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << m_current_tag << endl;
09020     }
09021   else if (Symbol::is_selected ("CMTCONFIG"))
09022     {
09023         // This is when CMTCONFIG has been set from some requirements file
09024       Symbol* macro = Symbol::find ("CMTCONFIG");
09025       if (macro != 0)
09026         {
09027           m_current_tag = macro->build_macro_value ();
09028           if (tag_debug) cerr << "set_standard_macro1> current_tag=" << m_current_tag << endl;
09029         }
09030     }
09031   else
09032     {
09033         // this is when no -tag= argument was used.
09034       if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << m_current_tag << endl;
09035       if (current_use.package == "CMT")
09036         {
09037           m_current_tag = CmtSystem::getenv ("CMTBIN");
09038         }
09039       else
09040         {
09041           m_current_tag = CmtSystem::getenv ("CMTCONFIG");
09042         }
09043 
09044       if (tag_debug) cerr << "set_standard_macro2> current_tag=" << m_current_tag << endl;
09045     }
09046 
09047   if (m_debug)
09048     {
09049       cout << "set_standard_macro3>" << endl;
09050     }
09051 
09052   StandardMacroBuilder builder (m_current_tag,
09053                                 m_current_package,
09054                                 m_current_version,
09055                                 m_current_prefix,
09056                                 m_current_style);
09057 
09058   builder.fill_for_tag ();
09059   builder.fill_for_package_tag ();
09060   builder.fill_for_package (m_current_dir);
09061   builder.fill_for_branches ();
09062   builder.fill_for_uses ();
09063   builder.fill_for_use_requirements ();
09064   builder.fill_for_use_includes ();
09065   builder.fill_for_use_fincludes ();
09066   builder.fill_for_use_stamps ();
09067   builder.fill_for_use_cflags ();
09068   builder.fill_for_use_pp_cflags ();
09069   builder.fill_for_use_cppflags ();
09070   builder.fill_for_use_pp_cppflags ();
09071   builder.fill_for_use_fflags ();
09072   builder.fill_for_use_pp_fflags ();
09073   builder.fill_for_use_linkopts ();
09074   builder.fill_for_use_libraries ();
09075   builder.fill_for_includes ();
09076   builder.fill_for_fincludes ();
09077   builder.fill_for_all_constituents ();
09078 
09083   const Constituent::ConstituentVector& constituents =
09084     Constituent::constituents ();
09085   
09086   if (!Symbol::is_selected ("constituents"))
09087     {
09088       temp = "macro_append constituents \" ";
09089       
09090       for (number = 0; number < constituents.size (); number++)
09091         {
09092           const Constituent& constituent = constituents[number];
09093 
09094           if (constituent.group == 0)
09095             {
09096               temp += constituent.name;
09097               temp += " ";
09098             }
09099         }
09100       
09101       temp += "\"";
09102       
09103       parse_requirements_line (temp, &current_use);
09104     }
09105 
09106   parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
09107                            &current_use);
09108 
09109   if (!Symbol::is_selected ("constituentsclean"))
09110     {
09111       temp = "macro_append constituentsclean \" ";
09112       
09113       for (number = constituents.size () - 1; number >= 0 ; number--)
09114         {
09115           const Constituent& constituent = constituents[number];
09116 
09117           if (constituent.group == 0)
09118             {
09119               temp += constituent.name;
09120               temp += "clean ";
09121             }
09122         }
09123       
09124       temp += "\"";
09125       
09126       parse_requirements_line (temp, &current_use);
09127     }
09128 
09129   parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
09130                            &current_use);
09131 
09132   const Group::GroupVector& groups = Group::groups ();
09133   
09134   for (number = 0; number < groups.size (); number++)
09135     {
09136       const Group& group = groups[number];
09137 
09138       temp = "macro_append ";
09139       temp += group.name ();
09140       temp += "_constituents \" ";
09141 
09142       int i;
09143 
09144       for (i = 0; i < constituents.size (); i++)
09145         {
09146           const Constituent& constituent = constituents[i];
09147 
09148           if ((constituent.group != 0) && 
09149               (group.name () == constituent.group->name ()))
09150             {
09151               temp += constituent.name;
09152               temp += " ";
09153             }
09154         }
09155       
09156       temp += "\"";
09157       
09158       parse_requirements_line (temp, &current_use);
09159 
09160       temp = "macro_append ";
09161       temp += group.name ();
09162       temp += "_constituentsclean \" ";
09163       
09164       for (i = constituents.size () - 1; i >= 0 ; i--)
09165         {
09166           const Constituent& constituent = constituents[i];
09167 
09168           if ((constituent.group != 0) && 
09169               (group.name () == constituent.group->name ()))
09170             {
09171               temp += constituent.name;
09172               temp += "clean ";
09173             }
09174         }
09175       
09176       temp += "\"";
09177       
09178       parse_requirements_line (temp, &current_use);
09179     }
09180 }
09181 
09182 //----------------------------------------------------------
09183 void Cmt::use_cmt ()
09184 {
09185   UseRef use;
09186   bool recursive_copy = m_recursive;
09187   bool debug_copy = m_debug;
09188 
09189   if (m_default_path.size () <= 0) return;
09190   if (m_current_package == "CMT") return;
09191 
09192   m_recursive = true;
09193   m_debug = false;
09194   use = Use::add (m_default_path, "CMT", m_cmt_version, "", "", 0);
09195   m_recursive = recursive_copy;
09196   m_debug = debug_copy;
09197 }
09198 
09199 //----------------------------------------------------------
09200 void Cmt::use_home_requirements ()
09201 {
09202   cmt_string f = m_cmt_home;
09203 
09204   if (f == "") 
09205     {
09206         //if (!m_quiet) cerr << "No CMTHOME" << endl;
09207       return;
09208     }
09209 
09210     //if (!m_quiet) cerr << "Using CMTHOME in " << f << endl;
09211 
09212   UseRef use;
09213   bool recursive_copy = m_recursive;
09214 
09215   if (m_default_path.size () <= 0) return;
09216   if (m_current_package == "CMT") return;
09217 
09218   m_recursive = true;
09219 
09220   cmt_string name = CmtSystem::get_home_package ();
09221 
09222   use = Use::add (f, name, "", "", "", 0);
09223 
09224   f += CmtSystem::file_separator ();
09225   f += "requirements";
09226   parse_requirements (f, use);
09227 
09228   m_recursive = recursive_copy;
09229 }
09230 
09231 //----------------------------------------------------------
09232 void Cmt::use_user_context_requirements ()
09233 {
09234   cmt_string f = m_cmt_user_context;
09235 
09236   if (f == "") 
09237     {
09238         //if (!m_quiet) cerr << "No CMTUSERCONTEXT" << endl;
09239       return;
09240     }
09241 
09242     //if (!m_quiet) cerr << "Using CMTUSERCONTEXT in " << f << endl;
09243 
09244   UseRef use;
09245   bool recursive_copy = m_recursive;
09246 
09247   if (m_default_path.size () <= 0) return;
09248   if (m_current_package == "CMT") return;
09249 
09250   m_recursive = true;
09251 
09252   cmt_string name = CmtSystem::get_user_context_package ();
09253 
09254   use = Use::add (f, name, "", "", "", 0);
09255 
09256   f += CmtSystem::file_separator ();
09257   f += "requirements";
09258   parse_requirements (f, use);
09259 
09260   m_recursive = recursive_copy;
09261 }
09262 
09263 //-------------------------------------------------
09264 void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
09265                             const cmt_string& separator,
09266                             cmt_string& result)
09267 {
09268   result.erase (0);
09269 
09270   for (int i = 0; i < v.size (); i++)
09271     {
09272       if (i > 0) result += separator;
09273       result += v[i];
09274     }
09275 }
09276 
09277 //-------------------------------------------------
09278 cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
09279 {
09280   cmt_string result;
09281 
09282   vector_to_string (v, " ", result);
09283 
09284   return (result);
09285 }

Generated at Mon Jun 10 17:57:47 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000