source: CMT/v1r20p20080222/source/cmt_parser.cxx @ 593

Last change on this file since 593 was 443, checked in by rybkin, 16 years ago

See C.L. 347

  • Property svn:eol-style set to native
File size: 188.8 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by garonne@lal.in2p3.fr
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12
13//----------------------------------------------------------
14
15#include "cmt_parser.h"
16#include "cmt_version.h"
17
18#include "cmt_database.h"
19#include "cmt_include.h"
20#include "cmt_script.h"
21#include "cmt_generator.h"
22#include "cmt_system.h"
23#include "cmt.h"
24#include "cmt_error.h"
25#include "cmt_cvs.h"
26#include "cmt_lock.h"
27#include "cmt_triggers.h"
28#include "cmt_model.h"
29#include "cmt_awk.h"
30#include "cmt_syntax.h"
31#include "cmt_install_area.h"
32#include "cmt_cmtpath_pattern.h"
33#include "cmt_sequence.h"
34#include "cmt_map.h"
35#include "cmt_project.h"
36#include "cmt_log.h"
37#include "cmt_commands.h"
38
39//----------------------------------------------------------
40//
41//  Static object definitions for the CmtContext class.
42//
43
44static CmtContext Me;
45
46CmtContext::CmtContext ()
47{
48  clear ();
49}
50
51CmtContext::~CmtContext ()
52{
53}
54
55void CmtContext::clear ()
56{
57  m_action         = action_none;
58  m_build_nmake    = false;
59  m_cmt_config     = "";
60  //m_cmt_path.clear ();
61  //m_cmt_path_pwds.clear ();
62  //m_cmt_path_sources.clear ();
63  m_cmt_root       = "";
64  m_cmt_version    = "";
65  m_current_dir     = "";
66  m_current_file_path = "";
67  m_current_package = "";
68  m_current_config  = "";
69  m_current_path    = "";
70  m_current_prefix  = "";
71  m_current_cmtpath = "";
72  m_current_offset  = "";
73
74  m_current_access   = DeveloperMode;
75
76  m_current_tag      = "";
77  m_current_target   = "";
78  m_current_version  = "";
79  m_default_path     = "";
80
81  //m_quiet            = false;
82
83  m_disable_warnings = false;
84  m_warnings         = false;
85  m_recursive        = false;
86
87  m_scope_filtering_mode = default_filtering_mode;
88  m_simulation       = false;
89
90  m_standard_macros_done = false;
91  m_current_access = UserMode;
92  m_current_style = cmt_style;
93  m_current_structuring_style = default_structuring_style;
94  m_all_sets_done = false;
95  m_autoconfigure_cmtpath = false;
96  m_debug = false;
97  if (getenv ("CMTDEBUG") != 0) m_debug = true;
98}
99
100//----------------------------------------------------------
101
102
103//----------------------------------------------------------
104//
105//   Utility classes
106//
107//----------------------------------------------------------
108
109/**
110 *  This PathScanner actor simply displays the package name/version/path
111 *  It is used by the cmt show packages operation
112 */
113class PackageViewer : public PathScanner::actor
114{
115public:
116  void run (const cmt_string& package,
117            const cmt_string& version,
118            const cmt_string& path,
119            const bool without_version_directory=false);
120};
121
122
123/**
124 *  This PathScanner actor accumulates all found packages into a cmt_string_vector
125 *  It is used by the broadcast operation
126 */
127class PackageSelector : public PathScanner::actor
128{
129public:
130  PackageSelector (CmtSystem::cmt_string_vector& uses);
131  void run (const cmt_string& package,
132            const cmt_string& version,
133            const cmt_string& path,
134            const bool without_version_directory=false);
135private:
136  CmtSystem::cmt_string_vector& m_uses;
137};
138
139
140
141/**
142 *  This PathScanner actor collects all packages clients of the specified one
143 *  It is used by the cmt show clients operation
144 */
145class ClientCollector : public PathScanner::actor
146{
147public:
148  ClientCollector (const cmt_string& package,
149                   const cmt_string& version);
150  void run (const cmt_string& package,
151            const cmt_string& version,
152            const cmt_string& path,
153            const bool without_version_directory=false);
154  int count ();
155
156private:
157  const cmt_string& m_package;
158  const cmt_string& m_version;
159  int m_count;
160};
161
162//----------------------------------------------------------
163void PackageViewer::run (const cmt_string& package,
164                         const cmt_string& version,
165                         const cmt_string& path,
166                         const bool without_version_directory)
167{
168  cout << package << " " << version << " " << path << endl;
169}
170
171//----------------------------------------------------------
172PackageSelector::PackageSelector (CmtSystem::cmt_string_vector& uses) : m_uses(uses)
173{
174}
175
176//----------------------------------------------------------
177void PackageSelector::run (const cmt_string& package,
178                           const cmt_string& version,
179                           const cmt_string& path,
180                           const bool without_version_directory)
181{
182  //
183  // this might be called on a package with no version directory.
184  // then simply the version argument is empty.
185  //
186
187  cmt_string r = CmtSystem::file_separator ();
188  r += "requirements";
189
190  cmt_string temp;
191
192  if (version == "")
193    {
194      temp = path;
195      //temp += CmtSystem::file_separator ();
196      //temp += package;
197      temp += CmtSystem::file_separator ();
198      temp += "cmt";
199      temp += r;
200     
201      if (!CmtSystem::test_file (temp)) return;
202    }
203  else
204    {
205      temp = path;
206      //temp += CmtSystem::file_separator ();
207      //temp += package;
208      temp += CmtSystem::file_separator ();
209      temp += version;
210      temp += CmtSystem::file_separator ();
211      temp += "cmt";
212      temp += r;
213     
214      if (!CmtSystem::test_file (temp))
215        {
216          temp = path;
217          //temp += CmtSystem::file_separator ();
218          //temp += package;
219          temp += CmtSystem::file_separator ();
220          temp += version;
221          temp += CmtSystem::file_separator ();
222          temp += "mgr";
223          temp += r;
224         
225          if (!CmtSystem::test_file (temp))
226            {
227              return;
228            }
229        }
230    }
231
232  temp.replace (r.c_str(), "");
233  cmt_string& use = m_uses.add ();
234  use = temp;
235}
236
237//----------------------------------------------------------
238ClientCollector::ClientCollector (const cmt_string& package,
239                                  const cmt_string& version) :
240  m_package (package), m_version (version), m_count (0)
241{
242}
243
244//----------------------------------------------------------
245void ClientCollector::run (const cmt_string& package,
246                           const cmt_string& version,
247                           const cmt_string& path,
248                           const bool without_version_directory)
249{
250  cmt_string dir = path;
251  dir += CmtSystem::file_separator ();
252  dir += package;
253  dir += CmtSystem::file_separator ();     
254  if (version != "" && ! without_version_directory)
255    {
256      dir += version;
257      dir += CmtSystem::file_separator ();
258    }
259
260  cmt_string req;
261 
262  req  = dir;
263  req += "cmt";
264  req += CmtSystem::file_separator ();
265  req += "requirements";
266
267  cmt_string requirements;
268  cmt_string line;
269  CmtSystem::cmt_string_vector words;
270
271  if (CmtSystem::test_file (req))
272    {
273      requirements.read (req);
274    }
275  else
276    {
277      req = dir;
278      req += "mgr";
279      req += CmtSystem::file_separator ();
280      req += "requirements";
281      if (CmtSystem::test_file (req))
282        {
283          requirements.read (req);
284        }
285    }
286
287  if (requirements != "")
288    {
289      int pos = 0;
290      int max_pos = requirements.size ();
291
292      while (pos < max_pos)
293        {
294          int cr = requirements.find (pos, "\r\n");
295          int nl = requirements.find (pos, '\n');
296          int first = nl;
297          int length = 1;
298               
299          if (cr != cmt_string::npos)
300            {
301              if (nl == cmt_string::npos)
302                {
303                  first = cr;
304                  length = 2;
305                }
306              else
307                {
308                  first = (nl < cr) ? nl : cr;
309                  length = (nl < cr) ? 1 : 2;
310                }
311            }
312               
313          if (first == cmt_string::npos)
314            {
315              requirements.substr (pos, line);
316              pos = max_pos;
317            }
318          else if (first > pos)
319            {
320              requirements.substr (pos, first - pos, line);
321              pos = first + length;
322            }
323          else
324            {
325              line.erase (0);
326              pos += length;
327            }
328
329          CmtSystem::split (line, " \t", words);
330
331          if ((words.size () >= 2) && (words[0] == "use")) 
332            {
333              if ((words[1] == m_package) && 
334                  ( (m_version == "") || (words[2] == m_version)))
335                {
336                  cout << "# " << package << " " << version << " " << path;
337                  if (m_version == "" && words.size () > 2)
338                    {
339                      cout << " (use version " << words[2] << ")";
340                    }
341                  cout << endl;
342                  m_count++;
343                }
344            }
345        }
346    }
347}
348
349//----------------------------------------------------------
350int ClientCollector::count ()
351{
352  return (m_count);
353}
354
355
356
357
358//----------------------------------------------------------
359//
360//   The Cmt methods
361//
362//----------------------------------------------------------
363
364
365
366/**
367 *   Append "CONFIG" to the prefix
368 */
369void Cmt::build_config (const cmt_string& prefix,
370                        cmt_string& config)
371{
372  /*
373    Building the config from <prefix>
374  */
375
376  config = prefix;
377  config += "CONFIG";
378}
379
380//----------------------------------------------------------
381void Cmt::build_makefile (const cmt_string& target)
382{
383  Constituent* constituent = 0;
384
385  if (target.size () > 0)
386    {
387      /*
388        Do genmake for one specific target.
389      */
390      constituent = Constituent::find (target);
391      if (constituent != 0)
392        {
393          constituent->build_makefile (Me.m_simulation);
394        }
395    }
396  else
397    {
398      /*
399        Do genmake for all possible targets.
400      */
401      Constituent::build_all_makefiles (Me.m_simulation);
402    }
403}
404
405//----------------------------------------------------------
406void Cmt::build_msdev_file (const cmt_string& target)
407{
408  Constituent* constituent = 0;
409
410  set_standard_macros ();
411
412  if (target != "")
413    {
414      /*
415        Do genmsdev for one specific target.
416      */
417      constituent = Constituent::find (target);
418      if (constituent != 0)
419        {
420          constituent->build_msdev_file (Me.m_simulation);
421        }
422    }
423  else
424    {
425      /*
426        Do genmsdev for all possible targets.
427      */
428      Constituent::build_all_msdev_files (Me.m_simulation);
429    }
430}
431
432/**
433   Visual Studio.net Support                                 
434*/
435void Cmt::build_vsnet_file (const cmt_string& target)       
436{                                                           
437  Constituent* constituent = 0;                             
438                                                             
439  set_standard_macros ();                                   
440                                                             
441  if (target != "")                                         
442    {                                                       
443      /*                                                     
444                                                             Do genvsnet for one specific target.                 
445      */                                                     
446      constituent = Constituent::find (target);             
447      if (constituent != 0)                                 
448        {                                                   
449          constituent->build_vsnet_file (Me.m_simulation);       
450        }                                                   
451    }                                                       
452  else                                                       
453    {                                                       
454      /*                                                     
455                                                             Do genvsnet for all possible targets.               
456      */                                                     
457      Constituent::build_all_vsnet_files (Me.m_simulation);       
458    }                                                       
459}                                                           
460
461//----------------------------------------------------------
462bool Cmt::build_nmake ()
463{
464  return (Me.m_build_nmake);
465}
466
467//----------------------------------------------------------
468void Cmt::build_OS9_makefile (const cmt_string& target)
469{
470  build_makefile (target);
471}
472
473/**
474 *   Convert a package name to its upper case copy
475 */
476void Cmt::build_prefix (const cmt_string& package, cmt_string& prefix)
477{
478  int pos;
479  char c;
480
481  /*
482    Building the prefix from <package>
483  */
484
485  prefix = package;
486
487  for (pos = 0; pos < package.size (); pos++)
488    {
489      c = package[pos];
490      prefix[pos] = toupper (c);
491    }
492}
493
494//----------------------------------------------------------
495void Cmt::clear ()
496{
497  Me.m_quiet = false;
498  Me.clear ();
499
500  Database::clear ();
501  Include::clear_all ();
502  Script::clear_all ();
503  CmtError::clear ();
504}
505
506//----------------------------------------------------------
507//void Cmt::configure ()
508void Cmt::configure (const ArgParser& ap)
509{
510  Log;
511  static bool configured = false;
512
513  if (configured) return;
514
515  Me.clear ();
516
517  log << "configure_default_path" << log_endl;
518  configure_default_path ();
519  log << "configure_version_tag" << log_endl;
520  configure_version_tag ();
521  log << "configure_uname_tag" << log_endl;
522  configure_uname_tag ();
523  log << "configure_hosttype_tag" << log_endl;
524  configure_hosttype_tag ();
525  log << "configure_config_tag" << log_endl;
526  configure_config_tag ();
527  log << "configure_site_tag" << log_endl;
528  configure_site_tag (0);
529  log << "configure_home" << log_endl;
530  // CMTHOME, CMTUSERCONTEXT and CMTPATH
531  configure_home (0);
532  log << "configure_current_dir" << log_endl;
533
534
535  bool save_quiet = Me.m_quiet;
536  Me.m_quiet = true;
537
538  Me.m_autoconfigure_cmtpath = true;
539  configure_cmt_path (0);
540  Me.m_autoconfigure_cmtpath = false;
541
542  Me.m_quiet = save_quiet;
543
544  configure_current_dir ();
545
546  guess_current_project ();
547
548  log << "configure_current_structuring_style" << log_endl;
549  //  configure_current_structuring_style ();
550  configure_current_structuring_style (ap);
551
552  log << "configure_current_package" << log_endl;
553  configure_current_package ();
554
555  Use& use = Use::current();
556
557  use.set (Me.m_current_package,
558           Me.m_current_version,
559           Me.m_current_path,
560           "",
561           "");
562
563  use.style = Me.m_current_style;
564
565  use.change_path (Me.m_current_path);
566
567  if (CmtError::has_pending_error ()) 
568    {
569      Me.m_configure_error = CmtError::get_last_error ();
570    }
571}
572
573//----------------------------------------------------------
574void Cmt::configure_cmt_path (Use* use)
575{
576  if (!Me.m_autoconfigure_cmtpath) return;
577
578  cmt_string s;
579
580  s = Symbol::get_env_value ("CMTPATH");
581
582  {
583    bool q = Me.m_quiet;
584    Me.m_quiet = true; 
585
586    Symbol::filter_path_value ("CMTPATH", s);
587
588    Me.m_quiet = q;
589  }
590
591  IProjectFactory& factory = ProjectFactory::instance ();
592  factory.reset ();
593
594  CmtSystem::get_cmt_paths (factory, s, Me.m_cmt_user_context, Me.m_cmt_home);
595}
596
597//----------------------------------------------------------
598void Cmt::configure_config_tag ()
599{
600  Me.m_cmt_config = CmtSystem::get_cmt_config ();
601  if (Me.m_cmt_config != "")
602    {
603      Tag* tag;
604
605      tag = Tag::add (Me.m_cmt_config, PriorityConfig, "CMTCONFIG", 0);
606      tag->mark ();
607    }
608}
609
610//----------------------------------------------------------
611void Cmt::configure_current_cmtpath ()
612{
613  Use& current_use = Use::current ();
614
615  Me.m_current_cmtpath = "";
616  Me.m_current_offset = "";
617
618  Me.m_current_cmtpath = Project::find_in_cmt_paths (current_use.path);
619
620  if (Me.m_current_cmtpath != "")
621    {
622      static const cmt_string empty_string;
623      static const cmt_string fs = CmtSystem::file_separator ();
624
625      Me.m_current_offset = current_use.path;
626
627      /**
628         try to remove this current CMTPATH entry from path.  This
629         has a meaning when the specified path already contains an
630         absolute path.
631      */
632     
633      Me.m_current_offset.replace (Me.m_current_cmtpath, empty_string);
634      if (Me.m_current_offset[0] == CmtSystem::file_separator ())
635        {
636          // Just in case there is a part left after removing the cmtpath entry
637         
638          Me.m_current_offset.replace (fs, empty_string);
639        }
640    }
641}
642
643class CmtMountFilterParser : public FAwk
644{
645public:
646
647  CmtMountFilterParser ()
648  {
649    reset ();
650  }
651
652  void reset ()
653  {
654    m_current_dir = CmtSystem::pwd ();
655
656    m_done = false;
657    m_prefix = "";
658  }
659
660  bool is_done () const
661  {
662    return (m_done);
663  }
664
665  const cmt_string& get_current_dir () const
666  {
667    return (m_current_dir);
668  }
669
670  void set_prefix (const cmt_string& prefix)
671  {
672    m_prefix = prefix;
673  }
674
675  void filter (const cmt_string& line)
676  {
677    if (m_done) 
678      {
679        stop ();
680        return;
681      }
682
683    CmtSystem::cmt_string_vector words;
684
685    CmtSystem::split (line, " \t", words);
686
687    int requested = 2;
688
689    if (m_prefix != "")
690      {
691        requested++;
692      }
693
694    if (words.size () < requested) return;
695
696    int n = 0;
697
698    if (m_prefix != "")
699      {
700        if (words[n] != m_prefix) return;
701        n++;
702      }
703
704    cmt_string& path_name = words[n];
705    cmt_string& replacement = words[n+1];
706   
707    if (m_current_dir.find (path_name) != cmt_string::npos)
708      {
709        m_current_dir.replace (path_name, replacement);
710        m_done = true;
711        stop ();
712      }
713  }
714
715private:
716  bool m_done;
717  cmt_string m_prefix;
718  cmt_string m_current_dir;
719};
720
721//----------------------------------------------------------
722void Cmt::configure_current_dir ()
723{
724  cmt_string file_name;
725
726  /*
727    Building current_dir :
728
729    o we first get the physical value (using getwd)
730    o then this value is possibly filtered using the
731    cmt_mount_filter file.
732  */
733
734  CmtMountFilterParser mount_filter;
735
736  /**
737     First try with ${CMTROOT}/mgr/cmt_mount_filter
738     with no prefix on lines
739  */
740
741  file_name = Me.m_default_path;
742  if (file_name != "")
743    {
744      file_name += CmtSystem::file_separator ();
745      file_name += "CMT";
746      file_name += CmtSystem::file_separator ();
747      file_name += Me.m_cmt_version;
748      file_name += CmtSystem::file_separator ();
749      file_name += "mgr";
750      file_name += CmtSystem::file_separator ();
751    }
752
753  file_name += "cmt_mount_filter";
754
755  mount_filter.run (file_name);
756
757  /**
758     Now try with .cmtrc
759     with "mount_filter" keyword
760  */
761
762  mount_filter.set_prefix ("mount_filter");
763
764  mount_filter.run (".cmtrc");
765
766  /**
767     Now try with ${HOME}/.cmtrc
768     with "mount_filter" keyword
769  */
770
771  if (CmtSystem::get_home_directory (file_name))
772    {
773      file_name += CmtSystem::file_separator ();
774      file_name += ".cmtrc";
775      mount_filter.run (file_name);
776    }
777
778  Me.m_current_dir = mount_filter.get_current_dir ();
779  Me.m_current_file_path = mount_filter.get_current_dir ();
780
781  cmt_string t = Me.m_current_file_path;
782}
783
784//----------------------------------------------------------
785void Cmt::configure_current_package ()
786{
787  /*
788    Build current_package and current_prefix.
789
790    This is only possible if we are within the cmt/mgr branch of a
791    standard directory tree (i.e. <package>/<version>/cmt or mgr)
792  */
793
794  cmt_string req = "..";
795  req += CmtSystem::file_separator ();
796  req += "cmt";
797  req += CmtSystem::file_separator ();
798  req += "requirements";
799
800  if (CmtSystem::test_file (req))
801    {
802      Me.m_current_style = cmt_style;
803    }
804  else
805    {
806      cmt_string req = "..";
807      req += CmtSystem::file_separator ();
808      req += "mgr";
809      req += CmtSystem::file_separator ();
810      req += "requirements";
811
812      if (CmtSystem::test_file (req))
813        {
814          Me.m_current_style = mgr_style;
815        }
816      else
817        {
818          // This package is probably a standalone one
819          Me.m_current_style = none_style;
820        }
821    }
822
823
824  if (Me.m_current_style != none_style)
825    {
826      //
827      //  Here there is a ../cmt or ../mgr branch in front of us
828      //  and there is a requirements file there
829      //
830
831      cmt_string up_dir;
832      cmt_string up_branch;
833
834      CmtSystem::dirname (Me.m_current_dir, up_dir);
835      CmtSystem::basename (up_dir, up_branch);
836
837      cmt_string version_file = "..";
838      version_file += CmtSystem::file_separator ();
839      version_file += "cmt";
840      version_file += CmtSystem::file_separator ();
841      version_file += "version.cmt";
842
843      if (CmtSystem::test_file (version_file))
844        {
845          //
846          // There is an explicit version descriptor. This one takes precedence
847          // and forces the structuring style to no directory
848          //
849
850          Me.m_current_package = up_branch;
851          CmtSystem::dirname (up_dir, Me.m_current_path);
852
853          if (Me.m_current_version.read (version_file))
854            {
855              int pos;
856
857              pos = Me.m_current_version.find ('\n');
858              if (pos != cmt_string::npos) Me.m_current_version.erase (pos);
859              pos = Me.m_current_version.find ('\r');
860              if (pos != cmt_string::npos) Me.m_current_version.erase (pos);
861            }
862          else
863            {
864              Me.m_current_version = "v*";
865              cerr << "#CMT> Warning: "
866                   << "Could not read `" << version_file << "'."
867                   << " Default version " << Me.m_current_version << endl;
868            }
869
870          if (Me.m_debug)
871            {
872              cout << "Cmt::configure_current_package>" << endl
873                   << " m_current_package " << Me.m_current_package << endl
874                   << " m_current_version " << Me.m_current_version << endl
875                   << " m_current_dir " << Me.m_current_dir << endl
876                   << " pwd " << CmtSystem::pwd ()
877                   << endl;
878            }
879
880          Me.m_current_style = no_version_style;
881        }
882      else
883        {
884          // Try to determine the structuring style from:
885          //
886          CmtStructuringStyle structuring_style(default_structuring_style);
887          CmtStructuringStyle style(default_structuring_style);
888          // - the command line options
889          //   or
890          // - the CMTSTRUCTURINGSTYLE environment variable
891          if (structuring_style == default_structuring_style)
892            {
893              structuring_style = get_current_structuring_style ();
894            }
895          // - the project the package belongs to
896          if (structuring_style == default_structuring_style)
897            {
898              Project* p = Project::get_current ();
899              if (p)
900                {
901                  style = p->get_strategy ("VersionDirectory") ? with_version_directory : without_version_directory ;
902                  StrategyDef* def = StrategyMgr::find_strategy ("VersionDirectory");
903                  if (def != 0)
904                    {
905                      if (p->is_specified (def)) structuring_style = style;
906                    }
907                }
908            }
909          // - the child projects of the project the package belongs to
910          if (structuring_style == default_structuring_style)
911            {
912              structuring_style = style;
913            }
914          // - the default value of the Structure strategy
915          if (structuring_style == default_structuring_style)
916            {
917              structuring_style = StrategyMgr::get_default_strategy ("VersionDirectory") ? with_version_directory : without_version_directory ;
918            }
919
920          // Make use of the structuring style
921          //
922          if (structuring_style == with_version_directory && CmtSystem::is_version_directory (up_branch))
923            {
924              // The up branch IS a version directory.
925             
926              Me.m_current_version = up_branch;
927              CmtSystem::dirname (up_dir, up_dir);
928              CmtSystem::basename (up_dir, Me.m_current_package);
929              CmtSystem::dirname (up_dir, Me.m_current_path);
930            }
931          else
932            {
933              if (structuring_style == with_version_directory)
934                {
935                  cerr << "#CMT> Warning: `"
936                       << up_branch << "' is not correct version syntax."
937                    " Assuming it is package name" << endl;
938                }
939              // No version descriptor
940              // No version directory. The version is defaulted to v*
941             
942              Me.m_current_package = up_branch;
943              Me.m_current_version = "v*";
944              cerr << "#CMT> Warning: "
945                   << "Structuring style used `without_version_directory', `"
946                   << version_file << "' missing."
947                   << " Default version `" << Me.m_current_version << "'" << endl;
948              CmtSystem::dirname (up_dir, Me.m_current_path);
949             
950              Me.m_current_style = no_version_style;
951            }
952        }
953      build_prefix (Me.m_current_package, Me.m_current_prefix);
954      build_config (Me.m_current_prefix, Me.m_current_config);
955    }
956  else
957    {
958      Me.m_current_package = "cmt_standalone";
959      Me.m_current_version = "";
960      Me.m_current_path = Me.m_current_dir;
961      build_prefix (Me.m_current_package, Me.m_current_prefix);
962      build_config (Me.m_current_prefix, Me.m_current_config);
963      Me.m_current_style = none_style;
964    }
965}
966
967//----------------------------------------------------------
968//void Cmt::configure_current_structuring_style ()
969void Cmt::configure_current_structuring_style (const ArgParser& ap)
970{
971  for (int i = ap.argc - 1; i >= 0; i--)
972    {
973      const cmt_string& arg = ap.argv[i];
974      if (arg == "-without_version_directory")
975        {
976          Me.m_current_structuring_style = without_version_directory;
977          return;
978        }
979      else if (arg == "-with_version_directory")
980        {
981          Me.m_current_structuring_style = with_version_directory;
982          return;
983        }
984    }
985
986  cmt_string s;
987
988  s = CmtSystem::getenv ("CMTSTRUCTURINGSTYLE");
989  if (s == "without_version_directory")
990    {
991      Me.m_current_structuring_style = without_version_directory;
992    }
993  else if (s == "with_version_directory")
994    {
995      Me.m_current_structuring_style = with_version_directory;
996    } 
997}
998
999//----------------------------------------------------------
1000void Cmt::configure_default_path ()
1001{
1002  Me.m_default_path = CmtSystem::get_cmt_root ();
1003  CmtSystem::get_cmt_version (Me.m_cmt_version);
1004  Me.m_cmt_root = Me.m_default_path;
1005  Me.m_cmt_root += CmtSystem::file_separator ();
1006  Me.m_cmt_root += "CMT";
1007  Me.m_cmt_root += CmtSystem::file_separator ();
1008  Me.m_cmt_root += Me.m_cmt_version;
1009}
1010
1011//----------------------------------------------------------
1012void Cmt::configure_home (Use* use)
1013{
1014  Me.m_cmt_home = "";
1015
1016  Symbol* symbol = Symbol::find ("CMTHOME");
1017  if (symbol != 0)
1018    {
1019      Me.m_cmt_home = symbol->build_macro_value ();
1020      Symbol::expand (Me.m_cmt_home);
1021    }
1022  else if (CmtSystem::testenv ("CMTHOME"))
1023    {
1024      Me.m_cmt_home = CmtSystem::getenv ("CMTHOME");
1025    }
1026
1027  if ((Me.m_cmt_home != "") && !CmtSystem::test_directory (Me.m_cmt_home))
1028    {
1029      Me.m_cmt_home = "";
1030    }
1031
1032  configure_user_context (0);
1033}
1034
1035//----------------------------------------------------------
1036void Cmt::configure_user_context (Use* use)
1037{
1038  Me.m_cmt_user_context = "";
1039
1040  Symbol* symbol = Symbol::find ("CMTUSERCONTEXT");
1041  if (symbol != 0)
1042    {
1043      Me.m_cmt_user_context = symbol->build_macro_value ();
1044      Symbol::expand (Me.m_cmt_user_context);
1045    }
1046  else if (CmtSystem::testenv ("CMTUSERCONTEXT"))
1047    {
1048      Me.m_cmt_user_context = CmtSystem::getenv ("CMTUSERCONTEXT");
1049    }
1050
1051  if ((Me.m_cmt_user_context != "") && !CmtSystem::test_directory (Me.m_cmt_user_context))
1052    {
1053      Me.m_cmt_user_context = "";
1054    }
1055
1056  if (Me.m_debug) cout << "configure_user_context> user_context=" << Me.m_cmt_user_context << endl;
1057
1058  configure_cmt_path (0);
1059}
1060
1061//----------------------------------------------------------
1062void Cmt::configure_hosttype_tag ()
1063{
1064  cmt_string hosttype;
1065
1066  CmtSystem::get_hosttype (hosttype);
1067
1068  if (hosttype != "")
1069    {
1070      Tag* tag;
1071
1072      tag = Tag::add (hosttype, PriorityUname, "HOSTTYPE", 0);
1073      tag->mark ();
1074    }
1075}
1076
1077//----------------------------------------------------------
1078void Cmt::configure_site_tag (Use* use)
1079{
1080  Symbol* symbol = Symbol::find ("CMTSITE");
1081  if (symbol != 0)
1082    {
1083      Me.m_cmt_site = symbol->build_macro_value ();
1084      Symbol::expand (Me.m_cmt_site);
1085    }
1086  else
1087    {
1088      Me.m_cmt_site = CmtSystem::get_cmt_site ();
1089    }
1090
1091  if (Me.m_cmt_site != "")
1092    {
1093      cmt_string s = "CMTSITE";
1094
1095      if (use != 0)
1096        {
1097          s += " in ";
1098        }
1099
1100      Tag* tag;
1101
1102      tag = Tag::add (Me.m_cmt_site, PrioritySite, s, use);
1103      tag->mark ();
1104    }
1105}
1106
1107//----------------------------------------------------------
1108void Cmt::restore_all_tags (Use* use)
1109{
1110  //cerr << "restore_all_tags" << endl;
1111
1112  Cmt::configure_tags (use);
1113
1114  /*
1115    Then get existing extra tags
1116  */
1117
1118  if (CmtSystem::testenv ("CMTEXTRATAGS"))
1119    {
1120      cmt_string s = "CMTEXTRATAGS";
1121
1122      if (use != 0)
1123        {
1124          s += " in ";
1125        }
1126
1127      Tag* tag;
1128      CmtSystem::cmt_string_vector words;
1129     
1130      cmt_string tags = CmtSystem::getenv ("CMTEXTRATAGS");
1131     
1132      CmtSystem::split (tags, " \t,", words);
1133
1134      Me.m_extra_tags = ",";
1135     
1136      for (int i = 0; i < words.size (); i++)
1137        {
1138          const cmt_string& a = words[i];
1139
1140          Me.m_extra_tags += a;
1141          Me.m_extra_tags += ",";
1142         
1143          tag = Tag::add (a, PriorityUserTag, s, use);
1144         
1145          tag->mark ();
1146        }
1147    }
1148}
1149
1150//----------------------------------------------------------
1151void Cmt::configure_tags (Use* use)
1152{
1153  cmt_string config_tag;
1154
1155  Log;
1156
1157  log << "current_tag=" << Me.m_current_tag << log_endl;
1158
1159  Symbol* symbol = Symbol::find ("CMTCONFIG");
1160  if (symbol != 0)
1161    {
1162      bool show_set_hidden = false;
1163
1164      if (Me.m_action == action_show_set)
1165        {
1166          show_set_hidden = true;
1167          Me.m_action = action_none;
1168        }
1169
1170      config_tag = symbol->build_macro_value ();
1171      Symbol::expand (config_tag);
1172
1173      if (show_set_hidden)
1174        {
1175          show_set_hidden = false;
1176          Me.m_action = action_show_set;
1177        }
1178    }
1179  else if (CmtSystem::testenv ("CMTCONFIG"))
1180    {
1181      config_tag = CmtSystem::getenv ("CMTCONFIG");
1182    }
1183  else if (CmtSystem::testenv ("CMTBIN"))
1184    {
1185      config_tag = CmtSystem::getenv ("CMTBIN");
1186    }
1187
1188  if (config_tag == "")
1189    {
1190      CmtSystem::get_uname (config_tag);
1191    }
1192
1193  log << "current_tag=" << Me.m_current_tag << log_endl;
1194
1195  cmt_string s = "CMTCONFIG";
1196
1197  if (use != 0)
1198    {
1199      s += " in ";
1200    }
1201
1202  Tag* tag;
1203
1204  tag = Tag::add (config_tag, PriorityConfig, s, use);
1205  tag->mark ();
1206
1207  //Me.m_current_tag = config_tag;
1208}
1209
1210//----------------------------------------------------------
1211void Cmt::configure_uname_tag ()
1212{
1213  cmt_string uname;
1214
1215  CmtSystem::get_uname (uname);
1216
1217  if (uname != "")
1218    {
1219      Tag* tag;
1220
1221      tag = Tag::add (uname, PriorityUname, "uname", 0);
1222      tag->mark ();
1223    }
1224}
1225
1226//----------------------------------------------------------
1227void Cmt::configure_version_tag ()
1228{
1229  int v = 0;
1230  int r = 0;
1231  int p = 0;
1232
1233  CmtSystem::is_version_directory (CMTVERSION, v, r, p);
1234
1235  Tag* tag;
1236
1237  static char temp[80];
1238
1239  sprintf (temp, "CMTv%d", v);
1240
1241  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1242  tag->mark ();
1243
1244  sprintf (temp, "CMTr%d", r);
1245
1246  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1247  tag->mark ();
1248
1249  sprintf (temp, "CMTp%d", p);
1250
1251  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1252  tag->mark ();
1253
1254}
1255
1256//----------------------------------------------------------
1257//
1258//   Actions
1259//
1260//----------------------------------------------------------
1261
1262class AwkActor : public Awk
1263{
1264public:
1265
1266  void filter (const cmt_string& line)
1267  {
1268    cout << line << endl;
1269  }
1270};
1271
1272//----------------------------------------------------------
1273void Cmt::do_awk (const ArgParser& ap)
1274{
1275  if (ap.arguments.size () < 1)
1276    {
1277      cerr << "#CMT> cmt awk <file> <pattern>" << endl;
1278      return;
1279    }
1280
1281  const cmt_string& file = ap.arguments[0];
1282  const cmt_string& pattern = ap.arguments[1];
1283  cmt_string text;
1284
1285  text.read (file);
1286
1287  static AwkActor a;
1288
1289  cmt_regexp exp (pattern);
1290
1291  a.run (text, exp);
1292}
1293
1294//----------------------------------------------------------
1295void Cmt::do_broadcast (const ArgParser& ap)
1296{
1297  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
1298
1299  CmtSystem::cmt_string_vector uses;
1300  CmtSystem::cmt_string_vector packages;
1301  CmtSystem::cmt_string_vector versions;
1302  CmtSystem::cmt_string_vector path_selections;
1303  CmtSystem::cmt_string_vector selections;
1304  CmtSystem::cmt_string_vector exclusions;
1305  cmt_string begin;
1306  cmt_string command;
1307  bool is_cmt = false;
1308  int first = 0;
1309  int i;
1310  bool ignore_errors = false;
1311  bool all_packages = false;
1312
1313  bool local = true;
1314
1315  for (i = 0; i < ap.arguments.size (); i++)
1316    {
1317      const cmt_string& w = ap.arguments[i];
1318
1319      //cerr << "broadcast: arg=[" << w << "]" << endl;
1320
1321      if (command == "")
1322        {
1323          if (w.substr (0, 13) == "-all_packages")
1324            {
1325              local = false;
1326              all_packages = true;
1327            }
1328          else if (w.substr (0, 7) == "-depth=")
1329            {
1330              local = false;
1331
1332              cmt_string depth_str;
1333              int depth_value = 0;
1334                         
1335              w.substr (7, depth_str);
1336              if ((sscanf (depth_str.c_str (), "%d", &depth_value) < 1) ||
1337                  (depth_value < 1))
1338                {
1339                  // Syntax error
1340                  //  We shall restrict to packages found within
1341                  // the <depth_value> first elements of CMTPATH.
1342                  //  If CMTPATH is empty, nothing is selected.
1343                  // depth=1 is equivalent to local
1344                }
1345
1346              Project::fill_selection (depth_value, path_selections);
1347            }
1348          else if (w.substr (0, 9) == "-exclude=")
1349            {
1350              cmt_string exclusion;
1351
1352              w.substr (9, exclusion);
1353
1354              int size = exclusion.size ();
1355             
1356              if (size >= 2)
1357                {
1358                  if (((exclusion[0] == '"') && (exclusion[size - 1] == '"')) ||
1359                      ((exclusion[0] == '\'') && (exclusion[size - 1] == '\'')))
1360                    {
1361                      exclusion.erase (size - 1);
1362                      exclusion.erase (0, 1);
1363                    }
1364
1365                  CmtSystem::split (exclusion, " \t", exclusions);
1366                }
1367            }
1368          else if (w.substr (0, 7) == "-global")
1369            {
1370              path_selections.clear ();
1371
1372              local = false;
1373            }
1374          else if (w.substr (0, 6) == "-local")
1375            {
1376              local = true;
1377            }
1378          else if (w.substr (0, 8) == "-select=")
1379            {
1380              cmt_string selection;
1381
1382              w.substr (8, selection);
1383
1384              //cerr << "Select=[" << selection << "]" << endl;
1385
1386              int size = selection.size ();
1387             
1388              if (size >= 2)
1389                {
1390                  if (((selection[0] == '"') && (selection[size - 1] == '"')) ||
1391                      ((selection[0] == '\'') && (selection[size - 1] == '\'')))
1392                    {
1393                      selection.erase (size - 1);
1394                      selection.erase (0, 1);
1395                    }
1396                }
1397
1398              CmtSystem::split (selection, " \t", selections);
1399
1400              //cerr << "Selections.size () = " << selections.size () << endl;
1401            }
1402          else if (w.substr (0, 7) == "-begin=")
1403            {
1404              w.substr (7, begin);
1405            }
1406          else
1407            {
1408              command = w;
1409            }
1410        }
1411      else
1412        {
1413          command += " ";
1414          command += w;
1415        }
1416
1417    }
1418
1419  if (local)
1420    {
1421      Project::fill_selection (1, path_selections);
1422    }
1423
1424  if (command[0] == '-')
1425    {
1426      ignore_errors = true;
1427      command.erase (0, 1);
1428    }
1429
1430  //if (command.substr (0, 3) == "cmt") is_cmt = true;
1431
1432  if (all_packages)
1433    {
1434      PackageSelector selector (uses);
1435      PathScanner scanner;
1436      Project::scan_paths (scanner, selector);
1437    }
1438  else
1439    {
1440      for (i = Uses.size () - 1; i >= 0; i--)
1441        {
1442          Use* use = Uses[i];
1443                 
1444          if (use->discarded) continue;
1445          if (use->m_hidden) continue;
1446
1447          if (!use->located ())
1448            {
1449              if (!Me.m_quiet)
1450                {
1451                  cerr << "#CMT> package " << use->get_package_name () <<
1452                    " " << use->version << " " << use->path <<
1453                    " not found" <<
1454                    endl;
1455                }
1456            }
1457          else
1458            {
1459              if (use->get_package_name () != "CMT")
1460                {
1461                  cmt_string& s = uses.add ();
1462
1463                  use->get_full_path (s);
1464
1465                  s += CmtSystem::file_separator ();
1466                  if (use->style == mgr_style) s += "mgr";
1467                  else s += "cmt";
1468
1469                  cmt_string& v = versions.add ();
1470                  v = use->version;
1471
1472                  cmt_string& p = packages.add ();
1473                  p = use->get_package_name ();
1474                }
1475            }
1476        }
1477         
1478      {
1479        cmt_string& s = uses.add ();
1480                 
1481        Use* use = &(Use::current ());
1482
1483        if (use->get_package_name ().find ("cmt_standalone") != cmt_string::npos)
1484          {
1485            s = CmtSystem::pwd ();
1486          }
1487        else
1488          {
1489            use->get_full_path (s);
1490
1491            s += CmtSystem::file_separator ();
1492                 
1493            if (use->style == mgr_style) s += "mgr";
1494            else s += "cmt";
1495          }
1496
1497        cmt_string& v = versions.add ();
1498        v = use->version;
1499
1500        cmt_string& p = packages.add ();
1501        p = use->get_package_name ();
1502      }
1503    }
1504
1505  bool started = false;
1506
1507  if (begin == "") started = true;
1508
1509  set_standard_macros ();
1510  Cmt::reset_all_sets_done ();
1511  Symbol::all_set ();
1512
1513  for (i = 0; i < uses.size (); i++)
1514    {
1515      const cmt_string& s = uses[i];
1516      const cmt_string& v = versions[i];
1517      const cmt_string& p = packages[i];
1518      cmt_string cmtpath;
1519
1520      bool ok = true;
1521      bool selected = true;
1522      bool excluded = false;
1523
1524      if (path_selections.size () > 0)
1525        {
1526          selected = false;
1527
1528          for (int j = 0; j < path_selections.size (); j++)
1529            {
1530              const cmt_string& sel = path_selections[j];
1531             
1532              if (s.find (sel) != cmt_string::npos) 
1533                {
1534                  cmtpath = sel;
1535                  selected = true;
1536                  break;
1537                }
1538            }
1539
1540          ok = selected;
1541        }
1542
1543      if (ok)
1544        {
1545          if (selections.size () > 0)
1546            {
1547              selected = false;
1548             
1549              for (int j = 0; j < selections.size (); j++)
1550                {
1551                  const cmt_string& sel = selections[j];
1552                 
1553                  if (s.find (sel) != cmt_string::npos) 
1554                    {
1555                      selected = true;
1556                      break;
1557                    }
1558                }
1559             
1560              ok = selected;
1561            }
1562        }
1563
1564      if (ok && !started)
1565        {
1566          if (s.find (begin) != cmt_string::npos)
1567            {
1568              started = true;
1569              ok = true;
1570            }
1571          else
1572            {
1573              ok = false;
1574            }
1575        }
1576
1577
1578      if (ok)
1579        {
1580          excluded = false;
1581
1582          for (int j = 0; j < exclusions.size (); j++)
1583            {
1584              const cmt_string& exc = exclusions[j];
1585             
1586              if (s.find (exc) != cmt_string::npos) 
1587                {
1588                  excluded = true;
1589                  break;
1590                }
1591            }
1592
1593          if (excluded) ok = false;
1594        }
1595
1596      if (!ok) 
1597        {
1598          continue;
1599        }
1600
1601
1602
1603      if (!CmtSystem::cd (s))
1604        {
1605          if (s.find ("cmt_standalone") != cmt_string::npos)
1606            {
1607              cerr << "#CMT> Currently not in a CMT package" << endl;
1608            }
1609          else
1610            {
1611              cerr << "#CMT> Cannot move to the package in " << s << " (" << i+1 << "/" 
1612                   << uses.size () << ")"<< endl;
1613            }
1614
1615          if (!ignore_errors) break;
1616
1617          continue;
1618        }
1619
1620      if (CmtLock::check () == CmtLock::locked_by_another_user)
1621        {
1622          cerr << "#CMT> Ignore locked package in " << s << " (" << i+1 << "/" 
1623               << uses.size () << ")" << endl;
1624          continue;
1625        }
1626
1627      if (cmtpath == "")
1628        {
1629          cmt_string sel = CmtSystem::pwd ();
1630          cmtpath = Project::find_in_cmt_paths (sel);
1631        }
1632
1633      cmt_string cmd = command;
1634      static const cmt_string version_template = "<version>";
1635      cmd.replace_all (version_template, v);
1636
1637      static const cmt_string package_template = "<package>";
1638      cmd.replace_all (package_template, p);
1639
1640      static const cmt_string cmtpath_template = "<package_cmtpath>";
1641      cmd.replace_all (cmtpath_template, cmtpath);
1642
1643      static const cmt_string offset_template = "<package_offset>";
1644
1645      static const cmt_string empty_string;
1646      static const cmt_string fs = CmtSystem::file_separator ();
1647      cmt_string offset = s;
1648      offset.replace (cmtpath, empty_string);
1649      if (offset[0] == CmtSystem::file_separator ())
1650        {
1651          offset.replace (fs, empty_string);
1652        }
1653      CmtSystem::dirname (offset, offset);
1654
1655      cmt_string n;
1656      CmtSystem::basename (offset, n);
1657      if (n == p)
1658        {
1659          CmtSystem::dirname (offset, offset);
1660        }
1661      else
1662        {
1663          CmtSystem::dirname (offset, offset);
1664          CmtSystem::dirname (offset, offset);
1665        }
1666
1667      cmd.replace_all (offset_template, offset);
1668
1669
1670      cout << "#--------------------------------------------------------------" << endl;
1671      cout << "# Now trying [" << cmd << "] in " << s << " (" << i+1 << "/" << uses.size () 
1672           << ")" << endl;
1673      cout << "#--------------------------------------------------------------" << endl;
1674
1675      if (is_cmt)
1676        {
1677          //
1678          //  There is a bug in the recursive use of the parser. Macros are not set correctly.
1679          //  Thus the recursive optimization is now discarded.
1680          //
1681          if (parser (cmd) != 0)
1682            {
1683              CmtError::set (CmtError::execution_error, cmd);
1684              break;
1685            }
1686        }
1687      else
1688        {
1689          int status = CmtSystem::execute (cmd);
1690
1691          //cerr << "do_broadcast> status=" << status << " ignore_errors=" << ignore_errors << endl;
1692
1693          if ((status != 0) && !ignore_errors)
1694            //if ((status != 0) && !ignore_errors)
1695            {
1696              if (status != 2) CmtError::set (CmtError::execution_error, cmd);
1697              break;
1698            }
1699        }
1700    }
1701}
1702
1703//----------------------------------------------------------
1704void Cmt::do_build_constituent_makefile (const ArgParser& ap)
1705{
1706  if (CmtLock::check () == CmtLock::locked_by_another_user)
1707    {
1708      CmtError::set (CmtError::conflicting_lock, "build_constituent_makefile>");
1709      return;
1710    }
1711  if (ap.arguments.size () > 0) 
1712    {
1713      set_standard_macros ();
1714      Generator::build_constituent_makefile (ap.arguments);
1715    }
1716}
1717
1718//----------------------------------------------------------
1719void Cmt::do_build_constituents_makefile (const ArgParser& ap)
1720{
1721  if (CmtLock::check () == CmtLock::locked_by_another_user)
1722    {
1723      CmtError::set (CmtError::conflicting_lock, "build_constituents_makefile>");
1724      return;
1725    }
1726  set_standard_macros ();
1727
1728  Generator::build_constituents_makefile (Me.m_current_package, ap.arguments);
1729}
1730
1731//----------------------------------------------------------
1732void Cmt::do_build_dependencies (const ArgParser& ap,
1733                                 int argc,
1734                                 char* argv[])
1735{
1736  if (CmtLock::check () == CmtLock::locked_by_another_user)
1737    {
1738      CmtError::set (CmtError::conflicting_lock, "build_dependencies>");
1739      return;
1740    }
1741  if (ap.arguments.size () > 0)
1742    {
1743      set_standard_macros ();
1744
1745      Generator::build_dependencies (ap.arguments);
1746    }
1747}
1748
1749//----------------------------------------------------------
1750void Cmt::do_build_library_links (const ArgParser& ap)
1751{
1752  cmt_string cmtinstallarea = "";
1753  cmt_string tag = "";
1754  cmt_string shlibsuffix;
1755  cmt_string symlinkcmd;
1756
1757  if (CmtLock::check () == CmtLock::locked_by_another_user)
1758    {
1759      CmtError::set (CmtError::conflicting_lock, "build_library_links>");
1760      return;
1761    }
1762
1763  set_standard_macros ();
1764
1765  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
1766  Use& current_use = Use::current ();
1767  int i;
1768
1769  {
1770    Symbol* macro = Symbol::find ("shlibsuffix");
1771    if (macro == 0) return;
1772    shlibsuffix = macro->build_macro_value ();
1773    Symbol::expand (shlibsuffix);
1774  }
1775
1776  {
1777    Symbol* macro = Symbol::find ("library_install_command");
1778    if (macro != 0)
1779      {
1780        symlinkcmd = macro->build_macro_value ();
1781        Symbol::expand (symlinkcmd);
1782      }
1783  }
1784
1785  if (current_use.get_strategy ("InstallArea"))
1786    {
1787      const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
1788     
1789      cmt_string s1 = ia_mgr.get_installarea ();
1790
1791      {
1792        Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
1793        if (symbol != 0)
1794          {
1795            s1 = symbol->build_macro_value ();
1796            Symbol::expand (s1);
1797          }
1798      }
1799
1800      cmtinstallarea = s1;
1801                 
1802      cmt_string s2;
1803
1804      {
1805        Symbol* macro = Symbol::find ("tag");
1806        if (macro != 0)
1807          {
1808            s2 = macro->build_macro_value ();
1809            Symbol::expand (s2);
1810          }
1811      }
1812
1813      tag = s2;
1814
1815      cmt_string s = s1;
1816      s += CmtSystem::file_separator ();
1817      s += s2;
1818      s += CmtSystem::file_separator ();
1819      s += "lib";
1820
1821      CmtSystem::mkdir (s);
1822    }
1823
1824  current_use.build_library_links (cmtinstallarea, tag, shlibsuffix, symlinkcmd);
1825
1826  for (i = 0; i < Uses.size (); i++)
1827    {
1828      Use* use = Uses[i];
1829
1830      if (use == 0) continue;
1831      if (use->discarded) continue;
1832      if (use->m_hidden) continue;
1833
1834      if (use->get_package_name () == "CMT") continue;
1835      if (use->get_package_name () == current_use.get_package_name ()) continue;
1836
1837      use->build_library_links (cmtinstallarea, tag, shlibsuffix, symlinkcmd);
1838    }
1839}
1840
1841//----------------------------------------------------------
1842void Cmt::do_build_make_setup (const ArgParser& ap)
1843{
1844  if (CmtLock::check () == CmtLock::locked_by_another_user)
1845    {
1846      CmtError::set (CmtError::conflicting_lock, "build_make_setup>");
1847      return;
1848    }
1849  set_standard_macros ();
1850  Generator::build_make_setup (Me.m_current_package);
1851}
1852
1853//----------------------------------------------------------
1854void Cmt::do_build_msdev (const ArgParser& ap)
1855{
1856  if (CmtLock::check () == CmtLock::locked_by_another_user)
1857    {
1858      CmtError::set (CmtError::conflicting_lock, "build_msdev>");
1859      return;
1860    }
1861
1862  if (true)
1863    {
1864      set_standard_macros ();
1865      if (ap.arguments.size () > 0) build_msdev_file (ap.arguments[0]);
1866      else build_msdev_file ("");
1867    }
1868}
1869
1870void Cmt::do_build_CMT_pacman (const ArgParser& ap)
1871{
1872  cmt_string pacman_file;
1873
1874  pacman_file = Me.m_cmt_root;
1875  pacman_file += CmtSystem::file_separator ();
1876  pacman_file += "mgr";
1877  pacman_file += CmtSystem::file_separator ();
1878  pacman_file += "CMT.pacman";
1879
1880  cmt_string pacman;
1881  cmt_string pattern = "<version>";
1882  cmt_string replacement = CMTVERSION;
1883
1884  pacman.read (pacman_file);
1885
1886  pacman.replace_all (pattern, replacement);
1887
1888  cout << pacman << endl;
1889}
1890
1891// Visual Studio.net Support                                                 
1892//----------------------------------------------------------                 
1893void Cmt::do_build_vsnet (const ArgParser& ap)     
1894{                                                                           
1895  if (CmtLock::check () == CmtLock::locked_by_another_user)                 
1896    {                                                                       
1897      CmtError::set (CmtError::conflicting_lock, "build_vsnet>");           
1898      return;                                                               
1899    }                                                                       
1900                                                                             
1901  if (true)                                                                 
1902    {                                                                       
1903      set_standard_macros ();                                               
1904      if (ap.arguments.size () > 0) build_vsnet_file (ap.arguments[0]);           
1905      else build_vsnet_file ("");                                           
1906    }                                                                       
1907}                                                                           
1908
1909//----------------------------------------------------------
1910void Cmt::do_build_os9_makefile (const ArgParser& ap)
1911{
1912  if (CmtLock::check () == CmtLock::locked_by_another_user)
1913    {
1914      CmtError::set (CmtError::conflicting_lock, "build_os9_makefile>");
1915      return;
1916    }
1917
1918  if (ap.arguments.size () > 0) 
1919    {
1920      set_standard_macros ();
1921      build_OS9_makefile (ap.arguments[0]);
1922    }
1923}
1924
1925//----------------------------------------------------------
1926void Cmt::do_build_prototype (const ArgParser& ap)
1927{
1928  if (CmtLock::check () == CmtLock::locked_by_another_user)
1929    {
1930      CmtError::set (CmtError::conflicting_lock, "build_prototype>");
1931      return;
1932    }
1933
1934  if (ap.arguments.size () > 0) 
1935    {
1936      set_standard_macros ();
1937      Generator::build_prototype (ap.arguments[0]);
1938    }
1939}
1940
1941//----------------------------------------------------------
1942void Cmt::do_build_readme (const ArgParser& ap)
1943{
1944  if (CmtLock::check () == CmtLock::locked_by_another_user)
1945    {
1946      CmtError::set (CmtError::conflicting_lock, "build_readme>");
1947      return;
1948    }
1949
1950  set_standard_macros ();
1951  Generator::build_readme (ap.arguments);
1952}
1953
1954//----------------------------------------------------------
1955void Cmt::do_build_tag_makefile (const ArgParser& ap)
1956{
1957  if (CmtLock::check () == CmtLock::locked_by_another_user)
1958    {
1959      CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
1960      return;
1961    }
1962
1963  print_macros (Make);
1964}
1965
1966//----------------------------------------------------------
1967void Cmt::do_build_temporary_name (const ArgParser& ap)
1968{
1969  cmt_string name = CmtSystem::get_temporary_name ();
1970  cout << name << endl;
1971}
1972
1973//----------------------------------------------------------
1974void Cmt::do_build_triggers (const ArgParser& ap)
1975{
1976  if (CmtLock::check () == CmtLock::locked_by_another_user)
1977    {
1978      CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
1979      return;
1980    }
1981
1982  if (ap.arguments.size () > 0) 
1983    {
1984      set_standard_macros ();
1985      TriggerGenerator::run (ap.arguments[0]);
1986    }
1987}
1988
1989//----------------------------------------------------------
1990void Cmt::do_build_windefs (const ArgParser& ap)
1991{
1992  if (CmtLock::check () == CmtLock::locked_by_another_user)
1993    {
1994      CmtError::set (CmtError::conflicting_lock, "build_windefs>");
1995      return;
1996    }
1997
1998  if (ap.arguments.size () > 0) 
1999    {
2000      set_standard_macros ();
2001      Generator::build_windefs (ap.arguments[0]);
2002    }
2003}
2004
2005//----------------------------------------------------------
2006void Cmt::do_check_configuration (const ArgParser& ap)
2007{
2008  cmt_string env;
2009  Tag* tag;
2010
2011  set_standard_macros ();
2012
2013  static CmtSystem::cmt_string_vector tags;
2014
2015  CmtSystem::split (Me.m_extra_tags, " \t,", tags);
2016
2017  for (int i = 0; i < tags.size (); i++)
2018    {
2019      const cmt_string& t = tags[i];
2020
2021      tag = Tag::find (t);
2022      if (tag == 0) continue;
2023
2024      if (!Tag::check_tag_used (tag) && !Symbol::check_tag_used (tag)) 
2025        {
2026          cerr << "#CMT> The tag " << t << " is not used in any tag expression. Please check spelling" << endl;
2027        }
2028    }
2029
2030  Symbol::check_all_paths ();
2031
2032  env = CmtSystem::getenv ("CMTSITE");
2033  if (env == "") 
2034    {
2035      return;
2036    }
2037
2038  tag = Tag::find (env);
2039  if (tag == 0) 
2040    {
2041      return;
2042    }
2043
2044  if (!Tag::check_tag_used (tag) && !Symbol::check_tag_used (tag) && Cmt::get_warnings ()) 
2045    {
2046      cerr << "#CMT> The CMTSITE value " << env << " is not used in any tag expression. Please check spelling" << endl;
2047    }
2048
2049}
2050
2051//----------------------------------------------------------
2052void Cmt::do_check_files (const ArgParser& ap)
2053{
2054  if (ap.arguments.size () >= 2) 
2055    {
2056      cmt_string first_file = ap.arguments[0];
2057      cmt_string second_file = ap.arguments[1];
2058         
2059      if (first_file == "") return;
2060      if (second_file == "") return;
2061         
2062      CmtSystem::compare_and_update_files (first_file, second_file);
2063    }
2064}
2065
2066//----------------------------------------------------------
2067void Cmt::do_check_version (const ArgParser& ap)
2068{
2069  if (ap.arguments.size () > 0)
2070    {
2071      cmt_string name = ap.arguments[0];
2072         
2073      if (name == "") return;
2074      int v = 0;
2075      int r = 0;
2076      int p = 0;
2077         
2078      bool ok = CmtSystem::is_version_directory (name, v, r, p);
2079         
2080      if (ok)
2081        {
2082          cout << "# " << name << " is version " << v << " release " << r << " patch " << p << endl;
2083        }
2084      else
2085        {
2086          cout << "# " << name << " is not a version tag" << endl;
2087        }
2088    }
2089}
2090
2091//----------------------------------------------------------
2092void Cmt::do_checkout (const ArgParser& ap)
2093{
2094  Cvs::checkout (ap.arguments);
2095}
2096
2097//----------------------------------------------------------
2098void Cmt::do_cleanup (const ArgParser& ap)
2099{
2100  print_clean (ap.mode);
2101}
2102
2103//----------------------------------------------------------
2104void Cmt::do_config (const ArgParser& ap)
2105{
2106  if (CmtLock::check () == CmtLock::locked_by_another_user)
2107    {
2108      CmtError::set (CmtError::conflicting_lock, "config>");
2109      return;
2110    }
2111
2112  //Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2113
2114  Use& current_use = Use::current ();
2115
2116  if (Me.m_debug)
2117    {
2118      cout << "Cmt::do_config> " << endl;
2119      cout << "pwd " << CmtSystem::pwd () << endl;
2120      cout << "current_dir " << Me.m_current_dir << endl;
2121      cout << "default_path " << Me.m_default_path << endl;
2122      cout << "cmt config " <<
2123        Me.m_current_package << " " <<
2124        Me.m_current_version << " " <<
2125        Me.m_current_path << endl;
2126    }
2127
2128  if (Me.m_current_package == "CMT") return;
2129  if (Me.m_current_package == "methods") return;
2130
2131  cmt_string branch;
2132
2133  CmtSystem::basename (Me.m_current_dir, branch);
2134
2135  if ((branch != "mgr") && (branch != "cmt"))
2136    {
2137
2138      //
2139      // Here we are in a standalone package (ie completely unstructured)
2140      //
2141
2142      if (CmtSystem::test_file ("requirements"))
2143        {
2144          cout << "------------------------------------------" << endl;
2145          cout << "Configuring environment for standalone package." << endl;
2146          cout << "CMT version " << Me.m_cmt_version << "." << endl;
2147          cout << "System is " << Me.m_cmt_config << endl;
2148          cout << "------------------------------------------" << endl;
2149
2150          install_test_setup_scripts ();
2151          install_test_cleanup_scripts ();
2152
2153          Generator::build_default_makefile ();
2154        }
2155      else
2156        {
2157          cout << "==============================================" << endl;
2158          cout << "cmt config must be operated either upon "
2159            "an existing package" << endl;
2160          cout << " (ie. when a requirements file already exists)" << endl;
2161          cout << "   > cd ..." << endl;
2162          cout << "   > cmt config" << endl;
2163          cout << "or to create a new package" << endl;
2164          cout << "   > cmt config <package> <version> [<path>]" << endl;
2165          cout << "==============================================" << endl;
2166        }
2167
2168      return;
2169    }
2170
2171  //  configure_current_package ();
2172
2173  Generator::build_default_makefile ();
2174
2175  CmtSystem::cmt_string_vector makes;
2176  cmt_regexp expression ("[.]n?make(sav)?$");
2177
2178  CmtSystem::scan_dir (".", expression, makes);
2179 
2180  if (makes.size () > 0)
2181    {
2182      cout << "Removing all previous make fragments from " << branch << endl;
2183
2184      for (int i = 0; i < makes.size (); i++)
2185        {
2186          const cmt_string& s = makes[i];
2187          CmtSystem::cmt_string_vector words;
2188          CmtSystem::split (s, '.', words);
2189          if (words.size()>=2)
2190            if (CmtSystem::get_makefile_suffix () == "nmake" && words[1] == "nmake")
2191              CmtSystem::remove_file (s);
2192            else if (CmtSystem::get_makefile_suffix () == "make" && words[1] == "make")
2193              CmtSystem::remove_file (s);
2194        }
2195    }
2196 
2197
2198  CmtSystem::cd ("..");
2199
2200  CmtSystem::scan_dir (Me.m_cmt_config, expression, makes); 
2201   
2202  if (makes.size () > 0) 
2203    {
2204      cout << "Removing all previous make fragments from "
2205           << Me.m_cmt_config << endl; 
2206
2207      for (int i = 0; i < makes.size (); i++) 
2208        { 
2209          const cmt_string& s = makes[i];
2210          CmtSystem::cmt_string_vector words;
2211          CmtSystem::split (s, '.', words);
2212          if (words.size()>=2)
2213            if (CmtSystem::get_makefile_suffix () == "nmake" && words[1] == "nmake")
2214              CmtSystem::remove_file (s);
2215            else if (CmtSystem::get_makefile_suffix () == "make" && words[1] == "make")
2216              CmtSystem::remove_file (s);
2217        }   
2218    } 
2219
2220  CmtSystem::cd (branch); 
2221
2222  Use& use = Use::current ();
2223
2224  use.set (Me.m_current_package,
2225           Me.m_current_version,
2226           Me.m_current_path,
2227           "",
2228           "");
2229
2230  use.change_path (Me.m_current_path);
2231  use.style     = Me.m_current_style;
2232
2233  Me.m_quiet = true;
2234
2235  if (!reach_current_package ())
2236    {
2237      cout << "Cannot read the requirements file" << endl;
2238      return;
2239    }
2240
2241  install_setup_scripts ();
2242  install_cleanup_scripts ();
2243  install_native_version_file ();
2244
2245  CmtSystem::cd ("..");
2246
2247  Branch::BranchVector& branches = Branch::branches ();
2248
2249  int i;
2250
2251  for (i = 0; i < branches.size (); i++)
2252    {
2253      const Branch& branch = branches[i];
2254      const cmt_string& branch_name = branch.name ();
2255
2256      if (!CmtSystem::test_directory (branch_name))
2257        {
2258          if (!CmtSystem::mkdir (branch_name))
2259            {
2260              cout << "Cannot create the " << branch_name <<" branch" << endl;
2261            }
2262          else
2263            {
2264              cout << "Installing the " << branch_name << " directory" << endl;
2265            }
2266        }
2267      else
2268        {
2269          cout << branch_name << " directory already installed" << endl;
2270        }
2271    }
2272}
2273
2274
2275//----------------------------------------------------------
2276void Cmt::do_relocate (const ArgParser& ap)
2277{
2278  if (CmtLock::check () == CmtLock::locked_by_another_user)
2279    {
2280      CmtError::set (CmtError::conflicting_lock, "relocate>");
2281      return;
2282    }
2283
2284  Use& current_use = Use::current ();
2285
2286  if (Me.m_debug)
2287    {
2288      cout << "Cmt::do_relocate> " << endl;
2289      cout << "pwd "          << CmtSystem::pwd () << endl;
2290      cout << "current_dir "  << Me.m_current_dir << endl;
2291      cout << "default_path " << Me.m_default_path << endl;
2292      cout << "cmt config "   <<
2293        Me.m_current_package << " " <<
2294        Me.m_current_version << " " <<
2295        Me.m_current_path << endl;
2296    }
2297
2298  if (Me.m_current_package == "CMT")     return;
2299  if (Me.m_current_package == "methods") return;
2300
2301  cmt_string branch;
2302
2303  CmtSystem::basename (Me.m_current_dir, branch);
2304
2305  if ((branch != "mgr") && (branch != "cmt"))
2306    {
2307
2308      //
2309      // Here we are in a standalone package (ie completely unstructured)
2310      //
2311
2312      if (CmtSystem::test_file ("requirements"))
2313        {
2314          cout << "------------------------------------------" << endl;
2315          cout << "Configuring environment for standalone package." << endl;
2316          cout << "CMT version " << Me.m_cmt_version << "." << endl;
2317          cout << "System is "   << Me.m_cmt_config << endl;
2318          cout << "------------------------------------------" << endl;
2319
2320          install_test_setup_scripts ();
2321          install_test_cleanup_scripts ();
2322
2323          Generator::build_default_makefile ();
2324        }
2325      else
2326        {
2327          cout << "==============================================" << endl;
2328          cout << "cmt relocate must be operated either upon "
2329            "an existing package" << endl;
2330          cout << " (ie. when a requirements file already exists)" << endl;
2331          cout << "   > cd ..." << endl;
2332          cout << "   > cmt relocate" << endl;
2333          cout << "or to create a new package" << endl;
2334          cout << "   > cmt relocate <package> <version> [<path>]" << endl;
2335          cout << "==============================================" << endl;
2336        }
2337
2338      return;
2339    }
2340
2341  //  configure_current_package ();
2342
2343  Generator::build_default_makefile ();
2344 
2345  CmtSystem::cd ("..");   
2346  CmtSystem::cd (branch); 
2347
2348  Use& use = Use::current ();
2349
2350  use.set (Me.m_current_package,
2351           Me.m_current_version,
2352           Me.m_current_path,
2353           "",
2354           "");
2355
2356  use.change_path (Me.m_current_path);
2357  use.style     = Me.m_current_style;
2358
2359  Me.m_quiet = true;
2360   
2361  if (!reach_current_package ())
2362    {
2363      cout << "Cannot read the requirements file" << endl;
2364      return;
2365    }
2366
2367  install_setup_scripts ();
2368  install_cleanup_scripts ();
2369
2370  CmtSystem::cd ("..");
2371
2372  Branch::BranchVector& branches = Branch::branches ();
2373
2374  int i;
2375
2376  for (i = 0; i < branches.size (); i++)
2377    {
2378      const Branch& branch = branches[i];
2379      const cmt_string& branch_name = branch.name ();
2380
2381      if (!CmtSystem::test_directory (branch_name))
2382        {
2383          if (!CmtSystem::mkdir (branch_name))
2384            {
2385              cout << "Cannot create the " << branch_name <<" branch" << endl;
2386            }
2387          else
2388            {
2389              cout << "Installing the " << branch_name << " directory" << endl;
2390            }
2391        }
2392      else
2393        {
2394          cout << branch_name << " directory already installed" << endl;
2395        }
2396    }
2397}
2398
2399//----------------------------------------------------------
2400void Cmt::do_create (const ArgParser& ap)
2401{
2402  if (ap.arguments.size () < 2) return;
2403
2404  const cmt_string& package = ap.arguments[0];
2405  const cmt_string& version = ap.arguments[1];
2406  cmt_string offset;
2407  if (ap.arguments.size () >= 3) offset = ap.arguments[2];
2408
2409  if (Me.m_debug)
2410    {
2411      cout << "do_create>Me.m_current_package=" << Me.m_current_package << endl;
2412      cout << "do_create>package=" << package << endl;
2413    }
2414
2415  //if (Me.m_current_package == "CMT") return;
2416  //if (Me.m_current_package == "methods") return;
2417
2418  cmt_string the_path;
2419
2420  the_path = CmtSystem::pwd ();
2421
2422  if (offset != "")
2423    {
2424      if (!CmtSystem::absolute_path (offset))
2425        {
2426          // offset is really a relative offset
2427          the_path += CmtSystem::file_separator ();
2428          the_path += offset;
2429        }
2430      else // absolute path
2431        {
2432          the_path = offset;
2433        }
2434    }
2435
2436  CmtSystem::compress_path (the_path);
2437
2438  // Now 'the_path' contains the complete path where the package will be created
2439
2440  cout << "------------------------------------------" << endl;
2441  cout << "Configuring environment for package " << package <<
2442    " version " << version << "." << endl;
2443  cout << "CMT version " << Me.m_cmt_version << "." << endl;
2444  cout << "Root set to " << the_path << "." << endl;
2445  cout << "System is " << Me.m_cmt_config << endl;
2446  cout << "------------------------------------------" << endl;
2447
2448  if (!CmtSystem::test_directory (the_path))
2449    {
2450      if (!CmtSystem::mkdir (the_path))
2451        {
2452          cout << "Cannot create the path directory" << endl;
2453          return;
2454        }
2455      else
2456        {
2457          cout << "Installing the path directory" << endl;
2458        }
2459    }
2460
2461  CmtSystem::cd (the_path);
2462
2463  if (!CmtSystem::test_directory (package))
2464    {
2465      if (!CmtSystem::mkdir (package))
2466        {
2467          cout << "Cannot create the package directory" << endl;
2468          return;
2469        }
2470      else
2471        {
2472          cout << "Installing the package directory" << endl;
2473        }
2474    }
2475  else
2476    {
2477      cout << "Package directory already installed" << endl;
2478    }
2479
2480  CmtSystem::cd (package);
2481
2482  Use& current_use = Use::current ();
2483
2484  bool with_version_dir = current_use.get_strategy ("VersionDirectory");
2485
2486  CmtStructuringStyle style = get_current_structuring_style ();
2487
2488  if (style != default_structuring_style)
2489    {
2490      if (with_version_dir)
2491        {
2492          if (style == without_version_directory)
2493            {
2494              with_version_dir = false;
2495            }
2496        }
2497      else
2498        {
2499          if (style == with_version_directory)
2500            {
2501              with_version_dir = true;
2502            }
2503        }
2504    }
2505
2506  if (with_version_dir)
2507    {
2508      if (!CmtSystem::test_directory (version))
2509        {
2510          if (!CmtSystem::mkdir (version))
2511            {
2512              cout << "Cannot create the version directory" << endl;
2513              return;
2514            }
2515          else
2516            {
2517              cout << "Installing the version directory" << endl;
2518            }
2519        }
2520      else
2521        {
2522          cout << "Version directory already installed" << endl;
2523        }
2524
2525      CmtSystem::cd (version);
2526    }
2527  else
2528    {
2529      cout << "Version directory will not be created due to structuring style" << endl;
2530    }
2531
2532  if (!CmtSystem::test_directory ("cmt"))
2533    {
2534      if (!CmtSystem::test_directory ("mgr"))
2535        {
2536          if (!CmtSystem::mkdir ("cmt"))
2537            {
2538              cout << "Cannot create the cmt directory" << endl;
2539              return;
2540            }
2541          else
2542            {
2543              if (with_version_dir)
2544                {
2545                  Me.m_current_style = cmt_style;
2546                }
2547              else
2548                {
2549                  Me.m_current_style = no_version_style;
2550                }
2551
2552              cout << "Installing the cmt directory" << endl;
2553            }
2554        }
2555      else
2556        {
2557          if (with_version_dir)
2558            {
2559              Me.m_current_style = mgr_style;
2560            }
2561          else
2562            {
2563              Me.m_current_style = no_version_style;
2564            }
2565         
2566          cout << "Mgr directory already installed" << endl;
2567        }
2568    }
2569  else
2570    {
2571      if (with_version_dir)
2572        {
2573          Me.m_current_style = cmt_style;
2574        }
2575      else
2576        {
2577          Me.m_current_style = no_version_style;
2578        }
2579
2580      cout << "Cmt directory already installed" << endl;
2581    }
2582
2583  if (!CmtSystem::test_directory ("src"))
2584    {
2585      if (!CmtSystem::mkdir ("src"))
2586        {
2587          cout << "Cannot create the src directory" << endl;
2588          return;
2589        }
2590      else
2591        {
2592          cout << "Installing the src directory" << endl;
2593        }
2594    }
2595  else
2596    {
2597      cout << "src directory already installed" << endl;
2598    }
2599
2600  switch (Me.m_current_style)
2601    {
2602    case cmt_style:
2603    case no_version_style:
2604      CmtSystem::cd ("cmt");
2605      break;
2606    case mgr_style:
2607      CmtSystem::cd ("mgr");
2608      break;
2609    }
2610
2611  Generator::build_default_makefile ();
2612
2613  if (!CmtSystem::test_file ("requirements"))
2614    {
2615      // create an empty requirement file.
2616      ofstream f ("requirements");
2617      if (f)
2618        {
2619          f << "package " << package << endl;
2620          f << endl;
2621          f.close ();
2622        }
2623    }
2624
2625  if (!with_version_dir)
2626    {
2627      ofstream f ("version.cmt");
2628      if (f)
2629        {
2630          f << version << endl;
2631          f.close ();
2632        }
2633    }
2634
2635  Me.m_current_package = package;
2636  Me.m_current_version = version;
2637  Me.m_current_path    = the_path;
2638  Me.m_current_dir     = CmtSystem::pwd ();
2639
2640  do_config (ap);
2641}
2642
2643//----------------------------------------------------------
2644void Cmt::do_create_project (const ArgParser& ap)
2645{
2646  int argc = ap.arguments.size ();
2647  int arg = 0;
2648
2649  if (argc < 1) return;
2650
2651  cmt_string project;
2652  cmt_string release;
2653  cmt_string path;
2654
2655  project = ap.arguments[arg]; argc--; arg++;
2656
2657  if (argc > 0)
2658    {
2659      release = ap.arguments[arg];
2660
2661      if (release[0] != '-')
2662        {
2663          argc--; 
2664          arg++;
2665          if (argc > 0)
2666            {
2667              path = ap.arguments[arg];
2668              if (path[0] != '-')
2669                {
2670                  argc--; arg++;
2671                }
2672              else
2673                {
2674                  path = "";
2675                }
2676            }
2677        }
2678      else
2679        {
2680          release = "";
2681        }
2682    }
2683
2684  if (Project::create (project, release, path))
2685    {
2686      while (argc > 0)
2687        {
2688          const cmt_string& argument = ap.arguments[arg]; argc--; arg++;
2689         
2690          if (argument.substr (0, 5) == "-use=")
2691            {
2692              cmt_string use;
2693
2694              argument.substr (5, use);
2695
2696              CmtSystem::cmt_string_vector words;
2697              CmtSystem::split (use, ":", words);
2698
2699              ofstream f (Project::get_project_file_name (), ios_base::app);
2700              if (f)
2701                {
2702                  f << "use " << words[0] << " " << words[1] << " " << words[2] << endl;
2703                  f << endl;
2704                  f.close ();
2705                }
2706            }
2707        }
2708    }
2709}
2710
2711//----------------------------------------------------------
2712void Cmt::do_cvsbranches (const ArgParser& ap)
2713{
2714  Cvs::branches (ap.arguments[0]);
2715}
2716
2717//----------------------------------------------------------
2718void Cmt::do_cvssubpackages (const ArgParser& ap)
2719{
2720  Cvs::subpackages (ap.arguments[0]);
2721}
2722
2723//----------------------------------------------------------
2724void Cmt::do_cvssubprojects (const ArgParser& ap)
2725{
2726  Cvs::subprojects (ap.arguments[0]);
2727}
2728
2729//----------------------------------------------------------
2730void Cmt::do_cvstags (const ArgParser& ap)
2731{
2732  Cvs::tags (ap.arguments);
2733}
2734
2735//----------------------------------------------------------
2736void Cmt::do_do (const ArgParser& ap)
2737{
2738  if (ap.arguments.size () > 0) 
2739    {
2740      set_standard_macros ();
2741      Cmt::reset_all_sets_done ();
2742      Symbol::all_set ();
2743      Generator::build_default_makefile ();
2744
2745      Symbol* symbol = Symbol::find (ap.arguments[0]);
2746
2747      if (symbol == 0)
2748        {
2749          Me.m_action = action_show_action_names;
2750          /*
2751            if (!Me.m_quiet)
2752            {
2753            cerr << "Existing actions:" << endl;
2754            print_symbol_names (ap.mode);
2755            }
2756          */
2757          CmtError::set (CmtError::unknown_command, ap.arguments[0]);
2758          return;
2759        }
2760
2761      /*
2762        We convert extra arguments into the standard macro cmt_args
2763      */
2764
2765      cmt_string args;
2766
2767      for (int i = 1; i < ap.arguments.size (); i++)
2768        {
2769          cmt_string s = ap.arguments[i];
2770          if (i > 1) args += " ";
2771          args += s;
2772        }
2773
2774      cmt_string r = "macro cmt_args \"";
2775      r += args;
2776      r += "\"";
2777
2778      Use* current_use = &(Use::current ());
2779     
2780      SyntaxParser::parse_requirements_line (r, current_use);
2781
2782      cmt_string cmd = symbol->build_macro_value ();
2783      Symbol::expand (cmd);
2784
2785      cerr << "Execute action " << ap.arguments[0] << " => " << cmd << endl;
2786
2787      int status = CmtSystem::execute (cmd);
2788      if (status != 0)
2789        {
2790          CmtError::set (CmtError::execution_failed, ap.arguments[0], status);
2791        }
2792    }
2793}
2794
2795//----------------------------------------------------------
2796void Cmt::do_expand_model (const ArgParser& ap)
2797{
2798  set_standard_macros ();
2799
2800  if ((ap.arguments[0] == "-strict") && (ap.arguments.size () > 1))
2801    {
2802      CmtModel::strict_expand (ap.arguments[1]);
2803    }
2804  else if ((ap.arguments[0] == "-test") && (ap.arguments.size () > 2))
2805    {
2806      CmtModel::test_regexp (ap.arguments[1], ap.arguments[2]);
2807    }
2808  else if (ap.arguments.size () > 0)
2809    {
2810      CmtModel::expand (ap.arguments[0]);
2811    }
2812}
2813
2814/**
2815 *  Handle free filtering of text files containing $(xxx) or ${xxx} patterns
2816 *
2817 *  Substitution is performed against CMT macros and environment variables.
2818 *
2819 *  Arguments:
2820 *
2821 *    cmt filter input-file-name output-file-name
2822 *
2823 */
2824void Cmt::do_filter (const ArgParser& ap)
2825{
2826  if (ap.arguments.size () < 2) return;
2827
2828  cmt_string& input = ap.arguments[0];
2829  cmt_string& output = ap.arguments[1];
2830
2831  if (!CmtSystem::test_file (input))
2832    {
2833      cerr << "#CMT> File " << input << " not found" << endl;
2834      return;
2835    }
2836
2837  cmt_string text;
2838
2839  text.read (input);
2840
2841  set_standard_macros ();
2842
2843  Symbol::expand (text);
2844
2845  FILE* file = fopen (output, "wb");
2846  if (file == NULL)
2847    {
2848      cerr << "#CMT> Cannot write filtered file " << output << endl;
2849    }
2850  else
2851    {
2852      text.write (file);
2853      fclose (file);
2854    }
2855}
2856
2857//----------------------------------------------------------
2858void Cmt::do_help (const ArgParser& ap)
2859{
2860  //cerr << "ap.help_action=" << ap.help_action << " Me.m_action=" << Me.m_action << endl;
2861  if (Me.m_action == action_none)
2862    {
2863      CommandHelp::show_all ();
2864    }
2865  else
2866    {
2867      CommandHelp::show (Me.m_action);
2868    }
2869}
2870
2871//----------------------------------------------------------
2872void Cmt::do_lock (const ArgParser& ap)
2873{
2874  const cmt_string& package = Me.m_current_package;
2875  const cmt_string& version = Me.m_current_version;
2876  const cmt_string& path    = Me.m_current_path;
2877
2878  //(unsused) Use& use = Use::current();
2879
2880  cerr << "try to lock package " << package << " in " << CmtSystem::pwd () << endl;
2881
2882  set_standard_macros ();
2883
2884  CmtLock::status status = CmtLock::lock ();
2885}
2886
2887//----------------------------------------------------------
2888void Cmt::do_remove (const ArgParser& ap)
2889{
2890  const cmt_string& package = Me.m_current_package;
2891  const cmt_string& version = Me.m_current_version;
2892  const cmt_string& path    = Me.m_current_path;
2893
2894  //Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2895
2896  if (Me.m_current_package == "CMT") return;
2897  if (Me.m_current_package == "methods") return;
2898
2899  cmt_string the_path;
2900
2901  //the_path = Me.m_default_path;
2902  the_path = CmtSystem::pwd ();
2903
2904  if (path != "")
2905    {
2906      if (!CmtSystem::absolute_path (path))
2907        {
2908          // path is just a suffix
2909          the_path += CmtSystem::file_separator ();
2910          the_path += path;
2911        }
2912      else // absolute path
2913        {
2914          the_path = path;
2915        }
2916    }
2917
2918  CmtSystem::compress_path (the_path);
2919
2920  cout << "------------------------------------------" << endl;
2921  cout << "Removing package " << package <<
2922    " version " << version << "." << endl;
2923  cout << "CMT version " << Me.m_cmt_version << "." << endl;
2924  cout << "Root set to " << the_path << "." << endl;
2925  cout << "System is " << Me.m_cmt_config << endl;
2926  cout << "------------------------------------------" << endl;
2927
2928  the_path += CmtSystem::file_separator ();
2929  the_path += package;
2930
2931  if (!CmtSystem::cd (the_path))
2932    {
2933      cerr << "Path " << the_path << " not reachable" << endl;
2934      return;
2935    }
2936
2937  if (CmtSystem::test_directory (version))
2938    {
2939      if (CmtSystem::remove_directory (version))
2940        {
2941          cerr << "Version " << version << " has been removed from " << the_path << endl;
2942          CmtSystem::cmt_string_vector contents;
2943          CmtSystem::scan_dir (".", contents);
2944          if (contents.size () == 0)
2945            {
2946              CmtSystem::cd ("..");
2947              if (CmtSystem::remove_directory (package))
2948                {
2949                  cerr << "Package " << package << " has no more versions. Thus it has been removed."<< endl;
2950                }
2951            }
2952        }
2953      else
2954        {
2955          cerr << "Impossible to remove version " << version << " from " << the_path << endl;
2956        }
2957    }
2958  else if (CmtSystem::test_directory ("cmt"))
2959    {
2960      CmtSystem::cd ("cmt");
2961
2962      cmt_string v;
2963
2964      v.read ("version.cmt");
2965      if (v == version)
2966        {
2967          CmtSystem::cd ("..");
2968          if (!CmtSystem::remove_directory ("cmt"))
2969            {
2970              cerr << "Unstructured version " << version
2971                   << " has been removed from " << the_path << endl;
2972            }
2973          else
2974            {
2975              cerr << "Impossible to remove unstructured version " << version
2976                   << " from " << the_path << endl;
2977            }
2978        }
2979      else
2980        {
2981          cerr << "Version " << version << " not found" << endl;
2982        }
2983    }
2984  else
2985    {
2986      cerr << "Version " << version << " not found" << endl;
2987    }
2988}
2989
2990//----------------------------------------------------------
2991void Cmt::do_remove_library_links (const ArgParser& ap)
2992{
2993  if (CmtLock::check () == CmtLock::locked_by_another_user)
2994    {
2995      CmtError::set (CmtError::conflicting_lock, "remove_library_links>");
2996      return;
2997    }
2998
2999  set_standard_macros ();
3000
3001  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
3002  Use& current_use = Use::current ();
3003  int i;
3004  cmt_string shlibsuffix;
3005  cmt_string symunlink;
3006
3007  {
3008    Symbol* macro = Symbol::find ("shlibsuffix");
3009    if (macro == 0) return;
3010    shlibsuffix = macro->build_macro_value ();
3011    Symbol::expand (shlibsuffix);
3012  }
3013
3014  {
3015    Symbol* macro = Symbol::find ("symunlink");
3016    if (macro == 0) return;
3017    symunlink = macro->build_macro_value ();
3018    Symbol::expand (symunlink);
3019  }
3020
3021  for (i = 0; i < Uses.size (); i++)
3022    {
3023      Use* use = Uses[i];
3024
3025      if (use->discarded) continue;
3026      if (use->m_hidden) continue;
3027
3028      if (!use->located ())
3029        {
3030          if (!Me.m_quiet)
3031            {
3032              cerr << "#CMT> package " << use->get_package_name () <<
3033                " " << use->version << " " << use->path << 
3034                " not found" <<
3035                endl;
3036            }
3037        }
3038      else
3039        {
3040          if (use->get_package_name () == "CMT") continue;
3041          if (use->get_package_name () == current_use.get_package_name ()) continue;
3042
3043          cmt_string s;
3044
3045          s = use->get_package_name ();
3046          s += "_libraries";
3047
3048          Symbol* libraries_macro = Symbol::find (s);
3049
3050          if (libraries_macro == 0) continue;
3051
3052          cmt_string libraries = libraries_macro->build_macro_value ();
3053          Symbol::expand (libraries);
3054
3055          static CmtSystem::cmt_string_vector values;
3056
3057          CmtSystem::split (libraries, " \t", values);
3058
3059          for (int j = 0; j < values.size (); j++)
3060            {
3061              const cmt_string& library = values[j];
3062
3063              static cmt_string libname;
3064              static cmt_string name;
3065
3066              // Is it a simple name or a complete path?
3067
3068              libname = library;
3069              Symbol::expand (libname);
3070
3071              if (CmtSystem::absolute_path (libname))
3072                {
3073                  /**
3074                   *   We assume here that "library" contains a complete path.
3075                   *   (including the complete syntax libxxx.so)
3076                   */
3077
3078                  cmt_string suffix;
3079                  CmtSystem::basename (library, name);
3080                }
3081              else
3082                {
3083                  /**
3084                   *   Here we expect that only the base name of the library
3085                   *   is given : ie it should not contain the "lib" prefix,
3086                   *   nor the suffix .so, nor any path prefix.
3087                   *    This of course should generally correspond to a constituent name.
3088                   */
3089
3090                  name = "lib";
3091                  name += libname;
3092                  name += ".";
3093                  name += shlibsuffix;
3094                }
3095
3096              Symbol::expand (libname);
3097
3098              if (current_use.get_strategy ("InstallArea"))
3099                {
3100                  const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
3101
3102                  cmt_string s1 = ia_mgr.get_installarea ();
3103
3104                  {
3105                    Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
3106                    if (symbol != 0)
3107                      {
3108                        s1 = symbol->build_macro_value ();
3109                        Symbol::expand (s1);
3110                      }
3111                  }
3112                 
3113                  cmt_string s2;
3114
3115                  {
3116                    Symbol* macro = Symbol::find ("tag");
3117                    if (macro != 0)
3118                      {
3119                        s2 = macro->build_macro_value ();
3120                        Symbol::expand (s2);
3121                      }
3122                  }
3123
3124                  // Now deleting the reference file
3125
3126                  s = symunlink;
3127                  s += " ";
3128                  s += s1;
3129                  s += CmtSystem::file_separator ();
3130                  s += s2;
3131                  s += CmtSystem::file_separator ();
3132                  s += "lib";
3133                  s += CmtSystem::file_separator ();
3134                  s += name;
3135                  s += ".cmtref";
3136                  s += " ";
3137                  s += s1;
3138                  s += CmtSystem::file_separator ();
3139                  s += s2;
3140                  s += CmtSystem::file_separator ();
3141                  s += "lib";
3142                  s += CmtSystem::file_separator ();
3143                  s += name;
3144                }
3145              else
3146                {
3147                  s = symunlink;
3148                  s += " ../$(";
3149                  s += current_use.get_package_name ();
3150                  s += "_tag)/";
3151                  s += name;
3152                }
3153
3154              Symbol::expand (s);
3155
3156              if (!Me.m_quiet) cerr << s << endl;
3157
3158              int status = CmtSystem::execute (s);
3159
3160              if (status != 0)
3161                {
3162                  if (status != 2) CmtError::set (CmtError::execution_error, s);
3163
3164                  cerr << "#CMT> Cannot remove the symbolic link " << s << endl;
3165
3166                  break;
3167                }
3168            }
3169        }
3170    }
3171}
3172
3173//----------------------------------------------------------
3174void Cmt::do_run (const ArgParser& ap)
3175{
3176  if (ap.arguments.size () > 0) 
3177    {
3178      set_standard_macros ();
3179      Cmt::reset_all_sets_done ();
3180      Symbol::all_set ();
3181
3182      cmt_string cmd;
3183
3184      for (int i = 0; i < ap.arguments.size (); i++)
3185        {
3186          cmd += ap.arguments[i];
3187          cmd += " ";
3188        }
3189
3190      CmtSystem::execute (cmd);
3191    }
3192}
3193
3194//----------------------------------------------------------
3195void Cmt::do_run_sequence (const ArgParser& ap)
3196{
3197  if (ap.arguments.size () == 0) cerr << "#CMT> run_sequence: no sequence specified" << endl;
3198
3199  SequenceRunner runner;
3200
3201  cerr << "# cmt run_sequence: sequence " << ap.arguments[0] << endl;
3202
3203  runner.run (ap.arguments[0]);
3204}
3205
3206//----------------------------------------------------------
3207void Cmt::do_set_version (const ArgParser& ap)
3208{
3209  if (ap.arguments.size () == 0) cerr << "#CMT> set version: no version specified" << endl;
3210
3211  const cmt_string& version = ap.arguments[0];
3212
3213  int v, r, p;
3214
3215  if (!CmtSystem::is_version_directory (version, v, r, p))
3216    {
3217      cerr << "#CMT> set version " << version << " is not a correct version syntax" << endl;
3218      return;
3219    }
3220
3221  if ((v == -1) || (r == -1) || (p == -1))
3222    {
3223      cerr << "#CMT> set version " << version
3224           << " You cannot use wild card to set a version" << endl;
3225      return;
3226    }
3227
3228  // We want to install the version.cmt file
3229
3230  // We first check we are in a cmt branch
3231  cmt_string h = CmtSystem::pwd ();
3232  cmt_string branch;
3233  CmtSystem::basename (h, branch);
3234
3235  if (branch != "cmt")
3236    {
3237      cerr << "#CMT> set version " << version << " must be applied in a cmt directory" 
3238           << endl;
3239      return;
3240    }
3241
3242  CmtSystem::dirname (h, h);
3243  CmtSystem::basename (h, branch);
3244
3245  if (branch == version)
3246    {
3247      cerr << "#CMT> set version " << version << " is already available as a version directory" 
3248           << endl;
3249      return;
3250    }
3251
3252  cerr << "Writing version file : " << version << endl;
3253
3254  version.write ("version.cmt");
3255}
3256
3257//----------------------------------------------------------
3258void Cmt::do_set_versions (const ArgParser& ap)
3259{
3260  CmtSystem::cmt_string_vector args;
3261
3262  args = ap.arguments;
3263  {
3264    cmt_string& s = args.add ();
3265    s = "cmt";
3266  }
3267  {
3268    cmt_string& s = args.add ();
3269    s = "set";
3270  }
3271  {
3272    cmt_string& s = args.add ();
3273    s = "version";
3274  }
3275  {
3276    cmt_string& s = args.add ();
3277    s = "<version>";
3278  }
3279
3280  Me.m_action = action_broadcast;
3281
3282  do_broadcast (ap);
3283}
3284
3285//----------------------------------------------------------
3286void Cmt::do_setup (const ArgParser& ap)
3287{
3288  Use& current_use = Use::current ();
3289
3290  do_check_configuration (ap);
3291
3292  print (ap.mode);
3293
3294  //
3295  //  Try a cleanup of the installation area
3296  //
3297  if (current_use.get_strategy ("InstallArea"))
3298    {
3299      CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
3300
3301      ia_mgr.setup ();
3302    }
3303}
3304
3305//----------------------------------------------------------
3306void Cmt::do_show_action (const ArgParser& ap)
3307{
3308  cmt_string target;
3309
3310  if (ap.arguments.size () > 0) target = ap.arguments[0];
3311
3312  Symbol* symbol;
3313
3314  set_standard_macros ();
3315
3316  symbol = Symbol::find (target);
3317
3318  if (symbol == 0) 
3319    {
3320      cmt_string t = " ";
3321      t += target;
3322      t += " is not defined ";
3323
3324      CmtError::set (CmtError::symbol_not_found, t);
3325
3326      return;
3327    }
3328  else
3329    {
3330      cmt_string t = target;
3331      t += " is a ";
3332
3333      if ((Me.m_action == action_show_action) ||
3334          (Me.m_action == action_show_action_value))
3335        {
3336          if (symbol->type != Symbol::SymbolAction)
3337            {
3338              if (symbol->type == Symbol::SymbolMacro)
3339                {
3340                  t += "macro";
3341                }
3342              else if (symbol->type == Symbol::SymbolSet)
3343                {
3344                  t += "set";
3345                }
3346              else if (symbol->type == Symbol::SymbolPath)
3347                {
3348                  t += "path";
3349                }
3350              else if (symbol->type == Symbol::SymbolAlias)
3351                {
3352                  t += "alias";
3353                }
3354
3355              CmtError::set (CmtError::warning, t);
3356            }
3357        }
3358    }
3359
3360  if (symbol->value_lists.size () < 1) return;
3361
3362  symbol->show_macro (ap.mode);
3363}
3364
3365//----------------------------------------------------------
3366void Cmt::do_show_action_names (const ArgParser& ap)
3367{
3368  if (ap.arguments.size () > 0)
3369    {
3370      const cmt_string& pattern = ap.arguments[0];
3371      print_symbol_names (ap.mode, pattern);
3372    }
3373  else
3374    {
3375      print_symbol_names (ap.mode);
3376    }
3377}
3378
3379//----------------------------------------------------------
3380void Cmt::do_show_action_value (const ArgParser& ap)
3381{
3382  do_show_macro (ap);
3383}
3384
3385//----------------------------------------------------------
3386void Cmt::do_show_actions (const ArgParser& ap)
3387{
3388  if (ap.arguments.size () > 0)
3389    {
3390      const cmt_string& pattern = ap.arguments[0];
3391      print_macros (ap.mode, pattern);
3392    }
3393  else
3394    {
3395      print_macros (ap.mode);
3396    }
3397}
3398
3399//----------------------------------------------------------
3400void Cmt::do_show_all_tags (const ArgParser& /*ap*/)
3401{
3402  Tag::TagPtrVector tags = Tag::tags ();
3403  int index;
3404
3405  set_standard_macros ();
3406
3407  for (index = 0; index < tags.size (); index++)
3408    {
3409      const Tag* tag = tags[index];
3410      if (tag != 0)
3411        {
3412          tag->show_definition (true);
3413        }
3414    }
3415}
3416
3417//----------------------------------------------------------
3418void Cmt::do_show_applied_patterns (const ArgParser& /*ap*/)
3419{
3420  Pattern::show_all_applied_patterns ();
3421}
3422
3423//----------------------------------------------------------
3424void Cmt::do_show_author (const ArgParser& /*ap*/)
3425{
3426  Use& use = Use::current();
3427
3428  cout << use.author << endl;
3429 
3430}
3431//----------------------------------------------------------
3432void Cmt::do_show_project_author (const ArgParser& /*ap*/)
3433{
3434  cmt_string cmtpath;
3435  cmt_string offset;
3436
3437  Use& use = Use::current();   
3438  use.get_cmtpath_and_offset (cmtpath, offset);
3439
3440  Project* p = Project::find_by_cmtpath (cmtpath);
3441
3442  cout << p->get_author () << endl;
3443}
3444
3445//----------------------------------------------------------
3446void Cmt::do_show_branches (const ArgParser& ap)
3447{
3448  Branch::print_all (ap.mode);
3449}
3450
3451//----------------------------------------------------------
3452void Cmt::do_show_clients (const ArgParser& ap)
3453{
3454  cmt_string package   = "";
3455  cmt_string version   = "";
3456  cmt_string path_name = "";
3457
3458  if (ap.arguments.size () >= 1) package  = ap.arguments[0];
3459  if (ap.arguments.size () >= 2) version  = ap.arguments[1];
3460  if (ap.arguments.size () >= 3) path_name = ap.arguments[2];
3461
3462  PathScanner scanner;
3463  ClientCollector collector (package, version);
3464
3465  clear     ();
3466  //  configure ();
3467  configure (ap);
3468
3469  cout << "# ----------- Clients of " << package <<
3470    " " << version <<
3471    " " << path_name <<
3472    endl;
3473
3474  if (path_name == "")
3475    {
3476      Project::scan_paths (scanner, collector);
3477    }
3478  else
3479    {
3480      scanner.scan_path (path_name, collector);
3481    }
3482
3483  cout << "# ----------- " << collector.count () << " clients found." << endl;
3484}
3485
3486//----------------------------------------------------------
3487void Cmt::do_show_cmtpath_patterns (const ArgParser& /*ap*/)
3488{
3489  set_standard_macros ();
3490  CmtPathPattern::show_all ();
3491}
3492
3493//----------------------------------------------------------
3494void Cmt::do_show_constituent (const ArgParser& ap)
3495{
3496  if (ap.arguments.size () > 0) 
3497    {
3498      set_standard_macros ();
3499
3500      Constituent* c = Constituent::find (ap.arguments[0]);
3501      if (c != 0)
3502        {
3503          c->show ();
3504        }
3505    }
3506}
3507
3508//----------------------------------------------------------
3509void Cmt::do_show_constituent_names (const ArgParser& /*ap*/)
3510{
3511  set_standard_macros ();
3512  Constituent::show_names ();
3513}
3514
3515//----------------------------------------------------------
3516void Cmt::do_show_constituents (const ArgParser& /*ap*/)
3517{
3518  set_standard_macros ();
3519  Constituent::show_all ();
3520}
3521
3522//----------------------------------------------------------
3523void Cmt::do_show_cycles (const ArgParser& /*ap*/)
3524{
3525  set_standard_macros ();
3526  Use& use = Use::current();
3527
3528  use.show_cycles ();
3529}
3530
3531//----------------------------------------------------------
3532void Cmt::do_show_fragment (const ArgParser& ap)
3533{
3534  if (ap.arguments.size () > 0) Fragment::show (ap.arguments[0]);
3535}
3536
3537//----------------------------------------------------------
3538void Cmt::do_show_fragments (const ArgParser& /*ap*/)
3539{
3540  Fragment::show_all ();
3541}
3542
3543//----------------------------------------------------------
3544void Cmt::do_show_groups (const ArgParser& /*ap*/)
3545{
3546  Group::show_all ();
3547}
3548
3549//----------------------------------------------------------
3550void Cmt::do_show_include_dirs (const ArgParser& /*ap*/)
3551{
3552  cmt_string temp;
3553
3554  Use& use = Use::current();
3555
3556  set_standard_macros ();
3557
3558  if (use.include_path == "")
3559    {
3560      temp += "$(src) ";
3561    }
3562  else if (use.include_path != "none")
3563    {
3564      temp += use.include_path;
3565      temp += " ";
3566    }
3567
3568  for (int include_number = 0;
3569       include_number < use.includes.size ();
3570       include_number++)
3571    {
3572      Include& incl = use.includes[include_number];
3573
3574      if (incl.name == "") continue;
3575
3576      temp += incl.name;
3577      temp += " ";
3578    }
3579
3580  cout << temp << endl;
3581}
3582
3583//----------------------------------------------------------
3584void Cmt::do_show_language (const ArgParser& ap)
3585{
3586  if (ap.arguments.size () > 0) 
3587    {
3588      set_standard_macros ();
3589      Language::show (ap.arguments[0]);
3590    }
3591}
3592
3593//----------------------------------------------------------
3594void Cmt::do_show_languages (const ArgParser& /*ap*/)
3595{
3596  set_standard_macros ();
3597  Language::show_all ();
3598}
3599
3600//----------------------------------------------------------
3601void Cmt::do_show_macro (const ArgParser& ap)
3602{
3603  cmt_string target;
3604
3605  if (ap.arguments.size () > 0) target = ap.arguments[0];
3606
3607  Symbol* symbol;
3608
3609  set_standard_macros ();
3610
3611  symbol = Symbol::find (target);
3612
3613  if (symbol == 0) 
3614    {
3615      cmt_string t = " ";
3616      t += target;
3617      t += " is not defined ";
3618
3619      CmtError::set (CmtError::symbol_not_found, t);
3620
3621      return;
3622    }
3623  else
3624    {
3625      cmt_string t = target;
3626      t += " is a ";
3627
3628      if ((Me.m_action == action_show_macro) ||
3629          (Me.m_action == action_show_macro_value))
3630        {
3631          if (symbol->type != Symbol::SymbolMacro)
3632            {
3633              if (symbol->type == Symbol::SymbolAction)
3634                {
3635                  t += "action";
3636                }
3637              else if (symbol->type == Symbol::SymbolSet)
3638                {
3639                  t += "set";
3640                }
3641              else if (symbol->type == Symbol::SymbolPath)
3642                {
3643                  t += "path";
3644                }
3645              else if (symbol->type == Symbol::SymbolAlias)
3646                {
3647                  t += "alias";
3648                }
3649
3650              CmtError::set (CmtError::warning, t);
3651            }
3652        }
3653      else if ((Me.m_action == action_show_set) ||
3654               (Me.m_action == action_show_set_value))
3655        {
3656          if ((symbol->type != Symbol::SymbolSet) &&
3657              (symbol->type != Symbol::SymbolPath) &&
3658              (symbol->type != Symbol::SymbolAction) &&
3659              (symbol->type != Symbol::SymbolAlias))
3660            {
3661              t += "macro";
3662
3663              CmtError::set (CmtError::warning, t);
3664            }
3665        }
3666    }
3667
3668  if (symbol->value_lists.size () < 1) return;
3669
3670  symbol->show_macro (ap.mode);
3671}
3672
3673//----------------------------------------------------------
3674void Cmt::do_show_macro_names (const ArgParser& ap)
3675{
3676  if (ap.arguments.size () > 0)
3677    {
3678      const cmt_string& pattern = ap.arguments[0];
3679      print_symbol_names (ap.mode, pattern);
3680    }
3681  else
3682    {
3683      print_symbol_names (ap.mode);
3684    }
3685}
3686
3687//----------------------------------------------------------
3688void Cmt::do_show_macro_value (const ArgParser& ap)
3689{
3690  do_show_macro (ap);
3691}
3692
3693//----------------------------------------------------------
3694void Cmt::do_show_macros (const ArgParser& ap)
3695{
3696  if (ap.arguments.size () > 0)
3697    {
3698      const cmt_string& pattern = ap.arguments[0];
3699      print_macros (ap.mode, pattern);
3700    }
3701  else
3702    {
3703      print_macros (ap.mode);
3704    }
3705}
3706
3707//----------------------------------------------------------
3708void Cmt::do_show_manager (const ArgParser& /*ap*/)
3709{
3710  Use& use = Use::current();
3711
3712  cout << use.manager << endl;
3713}
3714
3715//----------------------------------------------------------
3716void Cmt::do_show_packages (const ArgParser& ap)
3717{
3718  cmt_string path_name;
3719
3720  if (ap.arguments.size () > 0) path_name = ap.arguments[0];
3721
3722  PathScanner   scanner;
3723  PackageViewer viewer;
3724
3725  if (path_name == "")
3726    {
3727      Project::scan_paths (scanner, viewer);
3728    }
3729  else
3730    {
3731      scanner.scan_path (path_name, viewer);
3732    }
3733}
3734
3735//----------------------------------------------------------
3736void Cmt::do_show_path (const ArgParser& /*ap*/)
3737{
3738  Project::show_paths ();
3739}
3740
3741//----------------------------------------------------------
3742void Cmt::do_show_pattern (const ArgParser& ap)
3743{
3744  cmt_string name;
3745  if (ap.arguments.size () > 0) name = ap.arguments[0];
3746  Pattern::show (name);
3747}
3748
3749//----------------------------------------------------------
3750void Cmt::do_show_pattern_names (const ArgParser& /*ap*/)
3751{
3752  Pattern::show_all_names ();
3753}
3754
3755//----------------------------------------------------------
3756void Cmt::do_show_patterns (const ArgParser& /*ap*/)
3757{
3758  Pattern::show_all ();
3759}
3760
3761//----------------------------------------------------------
3762void Cmt::do_show_projects (const ArgParser& /*ap*/)
3763{
3764  Project::show_all ();
3765}
3766
3767//----------------------------------------------------------
3768void Cmt::do_show_pwd (const ArgParser& /*ap*/)
3769{
3770  cout << Me.m_current_dir << endl;
3771}
3772
3773//----------------------------------------------------------
3774void Cmt::do_show_setup (const ArgParser& ap)
3775{
3776  cout << "----------> uses" << endl;
3777  do_show_uses (ap);
3778
3779  cout << "----------> tags" << endl;
3780  do_show_tags (ap);
3781
3782  cout << "----------> CMTPATH" << endl;
3783  do_show_path (ap);
3784}
3785
3786//----------------------------------------------------------
3787void Cmt::do_show_set (const ArgParser& ap)
3788{
3789  do_show_macro (ap);
3790}
3791
3792//----------------------------------------------------------
3793void Cmt::do_show_set_names (const ArgParser& ap)
3794{
3795  if (ap.arguments.size () > 0)
3796    {
3797      const cmt_string& pattern = ap.arguments[0];
3798      print_symbol_names (ap.mode, pattern);
3799    }
3800  else
3801    {
3802      print_symbol_names (ap.mode);
3803    }
3804}
3805
3806//----------------------------------------------------------
3807void Cmt::do_show_set_value (const ArgParser& ap)
3808{
3809  do_show_macro (ap);
3810}
3811
3812//----------------------------------------------------------
3813void Cmt::do_show_sets (const ArgParser& ap)
3814{
3815  if (ap.arguments.size () > 0)
3816    {
3817      const cmt_string& pattern = ap.arguments[0];
3818      print_macros (ap.mode, pattern);
3819    }
3820  else
3821    {
3822      print_macros (ap.mode);
3823    }
3824}
3825
3826//----------------------------------------------------------
3827void Cmt::do_show_strategies (const ArgParser& /*ap*/)
3828{
3829  Use& current_use = Use::current ();
3830
3831  Project::show_specified_strategies_for_all ();
3832
3833  Project* p = Project::get_current ();
3834
3835  /*
3836    if (p != 0) p->show ();
3837    else cout << "No current project" << endl;
3838  */
3839
3840  cout << "Build strategy     : ";
3841
3842  if (current_use.get_strategy ("BuildPrototypes"))
3843    {
3844      cout << "prototypes";
3845    }
3846  else
3847    {
3848      cout << "no_prototypes";
3849    }
3850 
3851  if (current_use.get_strategy ("InstallArea"))
3852    {
3853      cout << " with_installarea";
3854    }
3855  else
3856    {
3857      cout << " without_installarea";
3858    }
3859 
3860  cout << endl;
3861
3862  cout << "Setup strategy     : ";
3863 
3864  if (current_use.get_strategy ("SetupConfig"))
3865    {
3866      cout << "config";
3867    }
3868  else
3869    {
3870      cout << "no_config";
3871    }
3872 
3873  if (current_use.get_strategy ("SetupRoot"))
3874    {
3875      cout << " root";
3876    }
3877  else
3878    {
3879      cout << " no_root";
3880    }
3881 
3882  if (current_use.get_strategy ("SetupCleanup"))
3883    {
3884      cout << " cleanup";
3885    }
3886  else
3887    {
3888      cout << " no_cleanup";
3889    }
3890
3891  cout << endl;
3892 
3893  cout << "Structure strategy : ";
3894 
3895  if (current_use.get_strategy ("VersionDirectory"))
3896    {
3897      cout << "with_version_directory";
3898    }
3899  else
3900    {
3901      cout << "without_version_directory";
3902    }
3903 
3904  cout << endl;
3905
3906  if (Me.m_current_structuring_style != default_structuring_style)
3907    {
3908      cout << "Structuring style  : ";
3909
3910      switch (Me.m_current_structuring_style)
3911        {
3912        case without_version_directory:
3913          cout << "without_version_directory";
3914          break;
3915        case with_version_directory:
3916          cout << "with_version_directory";
3917          break;
3918        }
3919
3920      cout << endl;
3921    }
3922}
3923
3924//----------------------------------------------------------
3925void Cmt::do_show_tags (const ArgParser& /*ap*/)
3926{
3927  Tag::TagPtrVector tags = Tag::tags ();
3928  int index;
3929
3930  set_standard_macros ();
3931
3932  for (index = 0; index < tags.size (); index++)
3933    {
3934      const Tag* tag = tags[index];
3935      if (tag != 0)
3936        {
3937          tag->show (Me.m_quiet);
3938        }
3939    }
3940}
3941
3942//----------------------------------------------------------
3943void Cmt::do_show_use_paths (const ArgParser& ap)
3944{
3945  const cmt_string& to_name = ap.arguments[0];
3946
3947  Use* current = &(Use::current());
3948
3949  current->get_all_clients (to_name);
3950}
3951
3952//----------------------------------------------------------
3953void Cmt::do_show_uses (const ArgParser& /*ap*/)
3954{
3955  Use::show_all ();
3956}
3957
3958//----------------------------------------------------------
3959void Cmt::do_show_version (const ArgParser& /*ap*/)
3960{
3961  cout << Me.m_current_version << endl;
3962}
3963
3964//----------------------------------------------------------
3965void Cmt::do_show_versions (const ArgParser& ap)
3966{
3967  cmt_string package_name;
3968
3969  if (ap.arguments.size () > 0) package_name = ap.arguments[0];
3970
3971  PathScanner scanner;
3972
3973  Project::scan_paths_for_package (scanner, package_name);
3974}
3975
3976//----------------------------------------------------------
3977void Cmt::do_show_system (const ArgParser& /*ap*/)
3978{
3979  cout << CmtSystem::get_cmt_config () << endl;
3980}
3981
3982//----------------------------------------------------------
3983void Cmt::do_unlock (const ArgParser& /*ap*/)
3984{
3985  const cmt_string& package = Me.m_current_package;
3986  const cmt_string& version = Me.m_current_version;
3987  const cmt_string& path    = Me.m_current_path;
3988
3989  // (unused??) Use& use = Use::current();
3990
3991  cerr << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
3992
3993  set_standard_macros ();
3994
3995  CmtLock::status status = CmtLock::unlock ();
3996}
3997
3998//----------------------------------------------------------
3999void Cmt::do_version (const ArgParser& /*ap*/)
4000{
4001  cout << CMTVERSION << endl;
4002}
4003
4004
4005
4006//----------------------------------------------------------
4007ActionType Cmt::get_action ()
4008{
4009  return (Me.m_action);
4010}
4011
4012/*
4013  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
4014  {
4015  return (Me.m_cmt_path);
4016  }
4017
4018  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_pwds ()
4019  {
4020  return (Me.m_cmt_path_pwds);
4021  }
4022
4023  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_sources ()
4024  {
4025  return (Me.m_cmt_path_sources);
4026  }
4027*/
4028
4029const cmt_string& Cmt::get_cmt_home ()
4030{
4031  return (Me.m_cmt_home);
4032}
4033
4034const cmt_string& Cmt::get_cmt_user_context ()
4035{
4036  return (Me.m_cmt_user_context);
4037}
4038
4039const cmt_string& Cmt::get_cmt_version ()
4040{
4041  return (Me.m_cmt_version);
4042}
4043
4044const cmt_string& Cmt::get_current_dir ()
4045{
4046  return (Me.m_current_dir);
4047}
4048
4049const cmt_string& Cmt::get_current_package ()
4050{
4051  return (Me.m_current_package);
4052}
4053
4054const cmt_string& Cmt::get_current_cmtpath ()
4055{
4056  return (Me.m_current_cmtpath);
4057}
4058
4059const cmt_string& Cmt::get_current_offset ()
4060{
4061  return (Me.m_current_offset);
4062}
4063
4064AccessMode Cmt::get_current_access ()
4065{
4066  return (Me.m_current_access);
4067}
4068
4069CmtStructuringStyle Cmt::get_current_structuring_style ()
4070{
4071  return (Me.m_current_structuring_style);
4072}
4073
4074CmtDirStyle Cmt::get_current_style ()
4075{
4076  return (Me.m_current_style);
4077}
4078
4079const cmt_string& Cmt::get_current_version ()
4080{
4081  return (Me.m_current_version);
4082}
4083
4084const cmt_string& Cmt::get_current_target ()
4085{
4086  return (Me.m_current_target);
4087}
4088
4089bool Cmt::get_debug ()
4090{
4091  return (Me.m_debug);
4092}
4093
4094bool Cmt::get_quiet ()
4095{
4096  return (Me.m_quiet);
4097}
4098
4099bool Cmt::get_disable_warnings ()
4100{
4101  return (Me.m_disable_warnings);
4102}
4103
4104bool Cmt::get_warnings ()
4105{
4106  return (Me.m_warnings);
4107}
4108
4109bool Cmt::get_recursive ()
4110{
4111  return (Me.m_recursive);
4112}
4113
4114CmtScopeFilteringMode Cmt::get_scope_filtering_mode ()
4115{
4116  if (Me.m_scope_filtering_mode == default_filtering_mode)
4117    {
4118      return (block_private_uses);
4119    }
4120  else
4121    {
4122      return (Me.m_scope_filtering_mode);
4123    }
4124}
4125
4126//----------------------------------------------------------
4127bool Cmt::get_all_sets_done ()
4128{
4129  return (Me.m_all_sets_done);
4130}
4131
4132/**---------------------------------------------------------
4133   guess_current_project
4134
4135   if current directory is in one of the CMTPATHs, do nothing.
4136
4137   Otherwise, we want to guess the current project
4138
4139   move up in directories until cmt/project.cmt is found
4140
4141   for (;;)
4142   {
4143   if test -f ./cmt/project.cmt
4144   ok:
4145   this directory should become the first entry of the CMTPATH
4146   break
4147
4148   if (at top) break;
4149
4150   move up
4151   }
4152*/
4153void Cmt::guess_current_project ()
4154{
4155  Log;
4156
4157  log << "guess_current_project" << log_endl;
4158
4159  cmt_string here = CmtSystem::pwd ();
4160
4161  if (Project::find_in_cmt_paths (Me.m_current_dir) == "")
4162    {
4163      cmt_string project_file = "cmt";
4164      project_file += CmtSystem::file_separator ();
4165      project_file += Project::get_project_file_name ();
4166
4167      cmt_string pwd;
4168
4169      for (;;)
4170        {
4171          pwd = CmtSystem::pwd ();
4172          if (CmtSystem::test_file (project_file))
4173            {
4174              //this directory should become the first entry of the CMTPATH
4175
4176              IProjectFactory& factory = ProjectFactory::instance ();
4177              factory.create_project ("", pwd, "CurrentProject", 0);
4178
4179              break;
4180            }
4181
4182          log << "pwd=" << CmtSystem::pwd () << log_endl;
4183         
4184          if (!CmtSystem::cd (".."))
4185            {
4186              break;
4187            }
4188
4189          if (CmtSystem::pwd () == pwd)
4190            {
4191              break;
4192            }
4193        }
4194
4195      CmtSystem::cd (Me.m_current_dir);
4196    }
4197
4198  //cmt_string buffer = "path CMTPATH \n";
4199  cmt_string buffer;
4200  Project::fill_cmtpaths (buffer);
4201  //cerr << "buffer = " << buffer << endl;
4202  Use& use = Use::current();
4203
4204  bool save_quiet = Me.m_quiet;
4205  Me.m_quiet = true;
4206
4207  SyntaxParser::parse_requirements_text (buffer, "", &use);
4208
4209  Me.m_quiet = save_quiet;
4210
4211  Me.m_autoconfigure_cmtpath = true;
4212
4213  CmtSystem::cd (here);
4214}
4215
4216//----------------------------------------------------------
4217const cmt_string& Cmt::filter_dir (const cmt_string& dir)
4218{
4219  static cmt_string newdir;
4220
4221  CmtSystem::compress_path (dir, newdir);
4222
4223  return (newdir);
4224}
4225
4226//----------------------------------------------------------
4227static void dos_script_prefix (FILE* f, 
4228                               const cmt_string& cmt_root, 
4229                               const cmt_string& package, 
4230                               const cmt_string& version, 
4231                               const cmt_string& path, 
4232                               const cmt_string& action, 
4233                               const cmt_string& option = "")
4234{
4235  cmt_string no_device = path;
4236
4237  if (CmtSystem::absolute_path (path)) 
4238    {
4239      if (path[1] == ':')
4240        {
4241          no_device = path.substr (2);
4242        }
4243    }
4244
4245  if (package == "cmt_standalone")
4246    {
4247      no_device = "";
4248    }
4249  else
4250    {
4251      no_device = "..\\..\\..";
4252      if (Cmt::get_current_style () == no_version_style)
4253        {
4254          no_device = "..\\..";
4255        }
4256    }
4257
4258
4259  fprintf (f, "@echo off\n");
4260  fprintf (f, "if NOT DEFINED CMTROOT set CMTROOT=%s& set PATH=%%CMTROOT%%\\%%CMTBIN%%;%%PATH%%& set CMTBIN=VisualC& if not defined CMTCONFIG set CMTCONFIG=%%CMTBIN%%\n", cmt_root.c_str ());
4261  fprintf (f, "\n");
4262  fprintf (f, "set cmttempfile=\"%%TEMP%%\\tmpsetup.bat\"\n");
4263  fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe %s -bat "
4264           " -pack=%s -version=%s -path=\"%%~d0%%~p0%s\" "
4265           " %s "
4266           "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%cmttempfile%%\n",
4267           action.c_str (),
4268           package.c_str (),
4269           version.c_str (),
4270           no_device.c_str (),
4271           option.c_str ());
4272  fprintf (f, "if exist %%cmttempfile%% call %%cmttempfile%%\n");
4273  fprintf (f, "if exist %%cmttempfile%% del %%cmttempfile%%\n");
4274  fprintf (f, "set cmttempfile=\n");
4275}
4276
4277//----------------------------------------------------------
4278void Cmt::install_cleanup_scripts ()
4279{
4280#ifdef WIN32
4281  static const int modes = 1;
4282  static const cmt_string suffix[1]   = {"bat"};
4283  static const PrintMode  mode[1]     = {Bat};
4284#else
4285  static const int modes = 2;
4286  static const cmt_string suffix[2]   = {"csh", "sh"};
4287  static const PrintMode  mode[2]     = {Csh, Sh};
4288#endif
4289
4290  cerr << "Creating cleanup scripts." << endl;
4291
4292  cmt_string temp;
4293  int i;
4294
4295  cmt_string version = Me.m_current_version;
4296  if (version == "v*") version = "";
4297
4298  for (i = 0; i < modes; i++)
4299    {
4300      cmt_string file_name = "cleanup";
4301      file_name += ".";
4302      file_name += suffix[i];
4303      file_name += ".";
4304      file_name += "new";
4305
4306      FILE* f = fopen (file_name.c_str (), "wb");
4307      if (f != NULL)
4308        {
4309          if (mode[i] == Csh)
4310            {
4311              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4312              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4313              fprintf (f, "endif\n");
4314              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4315              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4316              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4317              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4318                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4319                       "source ${tempfile}\n",
4320                       suffix[i].c_str (),
4321                       Me.m_current_package.c_str (),
4322                       version.c_str (),
4323                       Me.m_current_path.c_str ());
4324              fprintf (f, "/bin/rm -f ${tempfile}\n");
4325            }
4326          else if (mode[i] == Sh)
4327            {
4328              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4329              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4330              fprintf (f, "fi\n");
4331              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4332              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4333              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4334              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4335                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4336                       ". ${tempfile}\n",
4337                       suffix[i].c_str (),
4338                       Me.m_current_package.c_str (),
4339                       version.c_str (),
4340                       Me.m_current_path.c_str ());
4341              fprintf (f, "/bin/rm -f ${tempfile}\n");
4342            }
4343          else if (mode[i] == Bat)
4344            {
4345              dos_script_prefix (f, Me.m_cmt_root, 
4346                                 Me.m_current_package, version, Me.m_current_path,
4347                                 "cleanup");
4348            }
4349
4350          fprintf (f, "\n");
4351
4352          fclose (f);
4353
4354          cmt_string old_file_name = "cleanup";
4355          old_file_name += ".";
4356          old_file_name += suffix[i];
4357
4358          CmtSystem::compare_and_update_files (file_name, old_file_name);
4359        }
4360    }
4361}
4362
4363//----------------------------------------------------------
4364void Cmt::install_setup_scripts ()
4365{
4366#ifdef WIN32
4367  static const int modes = 1;
4368  static const cmt_string suffix[1]   = {"bat"};
4369  static const PrintMode  mode[1]     = {Bat};
4370#else
4371  static const int modes = 2;
4372  static const cmt_string suffix[2]   = {"csh", "sh"};
4373  static const PrintMode  mode[2]     = {Csh, Sh};
4374#endif
4375
4376  cerr << "Creating setup scripts." << endl;
4377
4378  Use& current_use = Use::current ();
4379 
4380  cmt_string no_cleanup_opt;
4381
4382  if (current_use.get_strategy ("SetupCleanup"))
4383    {
4384      no_cleanup_opt = " -no_cleanup";
4385    }
4386
4387  cmt_string temp;
4388  int i;
4389
4390  cmt_string version = Me.m_current_version;
4391  if (version == "v*") version = "";
4392
4393  for (i = 0; i < modes; i++)
4394    {
4395      cmt_string file_name = "setup";
4396      file_name += ".";
4397      file_name += suffix[i];
4398      file_name += ".";
4399      file_name += "new";
4400
4401      FILE* f = fopen (file_name.c_str (), "wb");
4402      if (f != NULL)
4403        {
4404          if (mode[i] == Csh)
4405            {
4406              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4407                       Me.m_current_package.c_str (),
4408                       version.c_str (),
4409                       Me.m_current_path.c_str ());
4410              fprintf (f, "\n");
4411
4412              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4413              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4414              fprintf (f, "endif\n");
4415              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4416              fprintf (f, "\n");
4417              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4418              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4419              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4420                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4421                       "source ${tempfile}\n",
4422                       suffix[i].c_str (),
4423                       Me.m_current_package.c_str (),
4424                       version.c_str (),
4425                       Me.m_current_path.c_str (),
4426                       no_cleanup_opt.c_str ());
4427              fprintf (f, "/bin/rm -f ${tempfile}\n");
4428            }
4429          else if (mode[i] == Sh)
4430            {
4431              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4432                       Me.m_current_package.c_str (),
4433                       version.c_str (),
4434                       Me.m_current_path.c_str ());
4435              fprintf (f, "\n");
4436
4437              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4438              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4439              fprintf (f, "fi\n");
4440              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4441              fprintf (f, "\n");
4442              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4443              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4444              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4445                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4446                       ". ${tempfile}\n",
4447                       suffix[i].c_str (),
4448                       Me.m_current_package.c_str (),
4449                       version.c_str (),
4450                       Me.m_current_path.c_str (),
4451                       no_cleanup_opt.c_str ());
4452              fprintf (f, "/bin/rm -f ${tempfile}\n");
4453            }
4454          else if (mode[i] == Bat)
4455            {
4456              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
4457                       Me.m_current_package.c_str (),
4458                       version.c_str ());
4459              dos_script_prefix (f, Me.m_cmt_root, 
4460                                 Me.m_current_package, version, Me.m_current_path,
4461                                 "setup", no_cleanup_opt);
4462            }
4463
4464          fprintf (f, "\n");
4465
4466          fclose (f);
4467
4468          cmt_string old_file_name = "setup";
4469          old_file_name += ".";
4470          old_file_name += suffix[i];
4471
4472          CmtSystem::compare_and_update_files (file_name, old_file_name);
4473        }
4474    }
4475}
4476
4477//----------------------------------------------------------
4478void Cmt::install_test_cleanup_scripts ()
4479{
4480#ifdef WIN32
4481  static const int modes = 1;
4482  static const cmt_string suffix[1]   = {"bat"};
4483  static const PrintMode  mode[1]     = {Bat};
4484#else
4485  static const int modes = 2;
4486  static const cmt_string suffix[2]   = {"csh", "sh"};
4487  static const PrintMode  mode[2]     = {Csh, Sh};
4488#endif
4489
4490  cerr << "Creating cleanup scripts." << endl;
4491
4492  cmt_string temp;
4493  int i;
4494
4495  cmt_string version = Me.m_current_version;
4496  if (version == "v*") version = "";
4497
4498  for (i = 0; i < modes; i++)
4499    {
4500      cmt_string file_name = "cleanup";
4501      file_name += ".";
4502      file_name += suffix[i];
4503      file_name += ".";
4504      file_name += "new";
4505
4506      FILE* f = fopen (file_name.c_str (), "wb");
4507      if (f != NULL)
4508        {
4509          if (mode[i] == Csh)
4510            {
4511              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4512              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4513              fprintf (f, "endif\n");
4514              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4515              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4516              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4517              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4518                       "source ${tempfile}\n",
4519                       suffix[i].c_str (),
4520                       Me.m_current_path.c_str ());
4521              fprintf (f, "/bin/rm -f ${tempfile}\n");
4522            }
4523          else if (mode[i] == Sh)
4524            {
4525              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4526              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4527              fprintf (f, "fi\n");
4528              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4529              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4530              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4531              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4532                       ". ${tempfile}\n",
4533                       suffix[i].c_str (),
4534                       Me.m_current_path.c_str ());
4535              fprintf (f, "/bin/rm -f ${tempfile}\n");
4536            }
4537          else
4538            {
4539              dos_script_prefix (f, Me.m_cmt_root, 
4540                                 "cmt_standalone", "", Me.m_current_path, 
4541                                 "cleanup");
4542            }
4543
4544          fprintf (f, "\n");
4545
4546          fclose (f);
4547
4548          cmt_string old_file_name = "cleanup";
4549          old_file_name += ".";
4550          old_file_name += suffix[i];
4551
4552          CmtSystem::compare_and_update_files (file_name, old_file_name);
4553        }
4554    }
4555}
4556
4557//----------------------------------------------------------
4558void Cmt::install_native_version_file ()
4559{   
4560  Use& current_use        = Use::current ();
4561  cmt_string package_name = current_use.get_package_name();
4562  cmt_string macro_name   = package_name + "_native_version";
4563  Symbol* macro           = Symbol::find (macro_name);
4564  if (macro != 0)
4565    {
4566      cmt_string value = macro->resolve_macro_value ();
4567      if (value != "")
4568        {
4569          cerr << "Creating native_version file." << endl;   
4570
4571          FILE* f = fopen ("new.native_version.cmt", "wb");
4572
4573          if (f != NULL)
4574            {
4575              fprintf (f, "%s\n", value.c_str ());
4576            }     
4577
4578          fclose (f);
4579
4580          CmtSystem::compare_and_update_files ("new.native_version.cmt", "native_version.cmt");
4581        } 
4582    }   
4583}
4584//----------------------------------------------------------
4585void Cmt::install_test_setup_scripts ()
4586{
4587#ifdef WIN32
4588  static const int modes = 1;
4589  static const cmt_string suffix[1]   = {"bat"};
4590  static const PrintMode  mode[1]     = {Bat};
4591#else
4592  static const int modes = 2;
4593  static const cmt_string suffix[2]   = {"csh", "sh"};
4594  static const PrintMode  mode[2]     = {Csh, Sh};
4595#endif
4596
4597  cerr << "Creating setup scripts." << endl;
4598
4599  Use& current_use = Use::current ();
4600
4601  cmt_string no_cleanup_opt;
4602
4603  if (current_use.get_strategy ("SetupCleanup"))
4604    {
4605      no_cleanup_opt = " -no_cleanup";
4606    }
4607
4608  cmt_string temp;
4609  int i;
4610
4611  for (i = 0; i < modes; i++)
4612    {
4613      cmt_string file_name = "setup";
4614      file_name += ".";
4615      file_name += suffix[i];
4616      file_name += ".";
4617      file_name += "new";
4618
4619      FILE* f = fopen (file_name.c_str (), "wb");
4620      if (f != NULL)
4621        {
4622          if (mode[i] == Csh)
4623            {
4624              fprintf (f, "# echo \"Setting standalone package\"\n");
4625              fprintf (f, "\n");
4626
4627              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4628              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4629              fprintf (f, "endif\n");
4630              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4631              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4632              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4633              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4634                       "source ${tempfile}\n",
4635                       suffix[i].c_str (),
4636                       Me.m_current_path.c_str (),
4637                       no_cleanup_opt.c_str ());
4638              fprintf (f, "/bin/rm -f ${tempfile}\n");
4639            }
4640          else if (mode[i] == Sh)
4641            {
4642              fprintf (f, "# echo \"Setting standalone package\"\n");
4643              fprintf (f, "\n");
4644
4645              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4646              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4647              fprintf (f, "fi\n");
4648              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4649              fprintf (f, "\n");
4650              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4651              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4652              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4653                       ". ${tempfile}\n",
4654                       suffix[i].c_str (),
4655                       Me.m_current_path.c_str (),
4656                       no_cleanup_opt.c_str ());
4657              fprintf (f, "/bin/rm -f ${tempfile}\n");
4658            }
4659          else
4660            {
4661              fprintf (f, "rem Setting standalone package\n");
4662              dos_script_prefix (f, Me.m_cmt_root, 
4663                                 "cmt_standalone", "", Me.m_current_path, 
4664                                 "setup", no_cleanup_opt);
4665            }
4666
4667          fprintf (f, "\n");
4668
4669          fclose (f);
4670
4671          cmt_string old_file_name = "setup";
4672          old_file_name += ".";
4673          old_file_name += suffix[i];
4674
4675          CmtSystem::compare_and_update_files (file_name, old_file_name);
4676        }
4677    }
4678}
4679
4680/**
4681 *    load is only called from the Windows GUI which pretends to access directly
4682 *   the internal data model.
4683 *    This is considered to be rather unsafe, and should be replaced by query functions.
4684 */
4685//bool Cmt::load (const cmt_string& path,
4686bool Cmt::load (const ArgParser& ap,
4687                const cmt_string& path,
4688                const cmt_string& package,
4689                const cmt_string& version,
4690                const cmt_string& tag_name)
4691{
4692  clear ();
4693  //  configure ();
4694  configure (ap);
4695
4696  Me.m_action  = action_load;
4697  Me.m_recursive = true;
4698
4699  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
4700    {
4701      //
4702      //  Here we want to connect to a new package, or to the current package
4703      //  but with another tag.
4704      //
4705      //   the 'package' argument may include a directory offset. Thus 'path'
4706      //  is only expected to hold the base directory.
4707      //
4708      cmt_string offset;
4709      cmt_string package_name;
4710     
4711      CmtSystem::dirname (package, offset);
4712      CmtSystem::basename (package, package_name);
4713     
4714      if (offset != "")
4715        {
4716          Me.m_current_path = path;
4717          Me.m_current_path += CmtSystem::file_separator ();
4718          Me.m_current_path += offset;
4719        }
4720      else
4721        {
4722          Me.m_current_path = path;
4723        }
4724     
4725      Me.m_current_package = package_name;
4726      Me.m_current_version = version;
4727    }
4728
4729  if (tag_name != "")
4730    {
4731      Tag* tag;
4732
4733      Tag::unmark_all ();
4734      configure_version_tag ();
4735      configure_site_tag (0);
4736      configure_uname_tag ();
4737      configure_hosttype_tag ();
4738
4739      Me.m_current_tag = tag_name;
4740
4741      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
4742
4743      tag = Tag::add (tag_name, PriorityTag, "load", 0);
4744      tag->mark ();
4745    }
4746
4747  /*
4748    Set to developer mode if positioned into the package
4749    (which is detected since we were able to retreive the
4750    Version, Package and Path)
4751  */
4752
4753  if ((Me.m_current_path == "") ||
4754      (Me.m_current_package == "") ||
4755      (Me.m_current_version == ""))
4756    {
4757      Me.m_current_access = UserMode;
4758    }
4759  else
4760    {
4761      Me.m_current_access = DeveloperMode;
4762    }
4763
4764  use_cmt ();
4765
4766  cmt_string dir;
4767
4768  /*
4769    Try to access the package.
4770  */
4771
4772  if (Me.m_current_path != "")
4773    {
4774      dir = Me.m_current_path;
4775    }
4776  else
4777    {
4778      dir = Me.m_default_path;
4779    }
4780
4781  if (!CmtSystem::cd (Me.m_current_path))
4782    {
4783      if (!Me.m_quiet)
4784        {
4785          cerr << "#CMT> Cannot reach the directory " <<
4786            Me.m_current_path << endl;
4787        }
4788      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
4789      CmtSystem::cd (Me.m_current_dir);
4790
4791      return (false);
4792    }
4793
4794  dir += CmtSystem::file_separator ();
4795  dir += Me.m_current_package;
4796
4797  if (!CmtSystem::cd (Me.m_current_package))
4798    {
4799      if (!Me.m_quiet)
4800        {
4801          cerr << "#CMT::load> Cannot reach the package " <<
4802            Me.m_current_package << endl;
4803        }
4804      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
4805      CmtSystem::cd (Me.m_current_dir);
4806
4807      return (false);
4808    }
4809
4810  dir += CmtSystem::file_separator ();
4811  dir += Me.m_current_version;
4812
4813  Me.m_current_style = none_style;
4814
4815  if (!CmtSystem::cd (Me.m_current_version))
4816    {
4817      if (!CmtSystem::test_directory ("cmt"))
4818        {
4819          if (!Me.m_quiet)
4820            {
4821              cerr << "#CMT> Cannot reach the version " <<
4822                Me.m_current_version << endl;
4823            }
4824          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
4825          CmtSystem::cd (Me.m_current_dir);
4826
4827          return (false);
4828        }
4829      else
4830        {
4831          Me.m_current_style = no_version_style;
4832        }
4833    }
4834
4835  if (CmtSystem::cd ("cmt"))
4836    {
4837      dir += CmtSystem::file_separator ();
4838      dir += "cmt";
4839      if (Me.m_current_style == none_style) Me.m_current_style = cmt_style;
4840    }
4841  else
4842    {
4843      /*
4844        if (!Me.m_quiet)
4845        {
4846        cerr << "Cannot reach the cmt branch" << endl;
4847        }
4848      */
4849
4850      if (CmtSystem::cd ("mgr"))
4851        {
4852          dir += CmtSystem::file_separator ();
4853          dir += "mgr";
4854          if (Me.m_current_style == none_style) Me.m_current_style = mgr_style;
4855        }
4856      else
4857        {
4858          if (!Me.m_quiet)
4859            {
4860              cerr << "#CMT> Cannot reach the mgr branch" << endl;
4861            }
4862
4863          CmtError::set (CmtError::package_not_found,
4864                         "Load> Cannot reach the mgr/cmt directory");
4865          CmtSystem::cd (Me.m_current_dir);
4866
4867          return (false);
4868        }
4869    }
4870
4871  /*
4872    Check Tag is always set up
4873  */
4874
4875  if (Me.m_current_tag == "")
4876    {
4877      char* env;
4878
4879      env = getenv (Me.m_current_config.c_str ());
4880      if (env != 0)
4881        {
4882          Tag* tag;
4883
4884          tag = Tag::add (env, PriorityConfig, "load", 0);
4885          tag->mark ();
4886          Me.m_current_tag = env;
4887
4888          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
4889
4890        }
4891      else
4892        {
4893          Me.m_current_tag = Me.m_cmt_config;
4894
4895          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
4896
4897        }
4898    }
4899
4900  if (Me.m_debug)
4901    {
4902      cout << "pwd = " << CmtSystem::pwd () << endl;
4903    }
4904
4905  configure_current_dir ();
4906  build_prefix (Me.m_current_package, Me.m_current_prefix);
4907  build_config (Me.m_current_prefix, Me.m_current_config);
4908
4909  Use* use = &(Use::current());
4910  use->path    = Me.m_current_path;
4911  use->set_package_name (Me.m_current_package);
4912  use->version = Me.m_current_version;
4913  use->prefix  = Me.m_current_prefix;
4914  use->done    = false;
4915  use->style   = Me.m_current_style;
4916
4917  /*
4918    Work on the requirements file.
4919  */
4920
4921  dir += CmtSystem::file_separator ();
4922  dir += "requirements";
4923  SyntaxParser::parse_requirements (dir, use);
4924
4925  if (CmtError::has_pending_error ()) return (false);
4926
4927  /**
4928   * See reach_current_package for an explanation of this call
4929   */
4930  Pattern::apply_all_globals ();
4931
4932  /*
4933    Select all possible tags
4934  */
4935
4936  Tag::restore_tree ();
4937
4938  return (true);
4939}
4940
4941//----------------------------------------------------------
4942bool Cmt::need_prototypes ()
4943{
4944  Use& current_use = Use::current ();
4945
4946  if (current_use.get_strategy ("BuildPrototypes")) return (true);
4947  else return (false);
4948}
4949
4950//----------------------------------------------------------
4951void Cmt::parse_arguments (ArgParser& ap)
4952{
4953  /*
4954    Decoding arguments.
4955
4956    While decoding all arguments, no requirements analysis should
4957    occur. Every new option, or parameter should be saved and
4958    used later at actual analysis time.
4959  */
4960
4961  Me.m_action = action_none;
4962
4963  restore_all_tags (0);
4964
4965#ifdef WIN32
4966  Me.m_build_nmake = true;
4967#endif
4968
4969  ap.parse ();
4970}
4971
4972//----------------------------------------------------------
4973int Cmt::parser (const cmt_string& command_line)
4974{
4975  CmtSystem::cmt_string_vector v;
4976
4977  CmtSystem::split (command_line, " \t", v);
4978
4979  int argc = v.size ();
4980
4981  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
4982
4983  int i;
4984  for (i = 0; i < argc; i++)
4985    {
4986      argv[i] = (char*) v[i].c_str ();
4987    }
4988  argv[argc] = 0;
4989
4990  int status = parser (argc, argv);
4991
4992  free (argv);
4993
4994  return (status);
4995}
4996
4997//----------------------------------------------------------
4998int Cmt::parser (int argc, char* argv[])
4999{
5000  ArgParser ap (Me);
5001 
5002  ap.argc = argc;
5003  ap.argv = argv;
5004
5005  if (argc <= 1)
5006    {
5007      do_help (ap);
5008      exit (0);
5009    }
5010
5011  clear ();
5012
5013  //  configure ();
5014  configure (ap);
5015
5016  CmtError::clear ();
5017
5018  /*
5019    Set private if positioned inside the package
5020    (which is detected since we were able to retreive the
5021    Version, Package and Path)
5022  */
5023
5024  if ((Me.m_current_path.size () == 0) ||
5025      (Me.m_current_package.size () == 0) ||
5026      (Me.m_current_version.size () == 0))
5027    {
5028      Me.m_current_access = UserMode;
5029    }
5030  else
5031    {
5032      Me.m_current_access = DeveloperMode;
5033    }
5034 
5035  parse_arguments (ap);
5036 
5037  if (Me.m_debug)
5038    {
5039      cout << "After parse_argument> pack=" << Me.m_current_package
5040           << " Me.m_current_tag=" << Me.m_current_tag
5041           << " cwd=" << CmtSystem::pwd () 
5042           << " mode=" << Me.m_current_access
5043           << endl;
5044    }
5045
5046  if (Me.m_configure_error != "")
5047    {
5048      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
5049      return (CmtError::execution_error);
5050    }
5051
5052  if (CmtError::has_pending_error ())
5053    {
5054      int code = CmtError::get_last_error_code ();
5055      if (!Me.m_quiet) CmtError::print ();
5056      clear ();
5057
5058      return (code);
5059    }
5060
5061  /*
5062    Now actual requirements analysis can take place.
5063
5064    Extra lines or files are analysed first.
5065  */
5066
5067  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
5068  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
5069
5070  //
5071  //  For some of the actions, the CMT package must be automatically
5072  //  included
5073  //
5074
5075  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
5076
5077  if (ap.help_action == action_help)
5078    {
5079      do_help (ap);
5080      return (0);
5081    }
5082
5083  switch (Me.m_action)
5084    {
5085      // case action_none :
5086    case action_awk :
5087    case action_broadcast :
5088    case action_build_constituent_makefile :
5089    case action_build_constituents_makefile :
5090    case action_build_dependencies :
5091    case action_build_library_links :
5092    case action_build_make_setup :
5093    case action_build_msdev :
5094    case action_build_CMT_pacman :
5095    case action_build_vsnet :     
5096    case action_build_os9_makefile :
5097      // case action_build_prototype :
5098    case action_build_readme :
5099    case action_build_tag_makefile :
5100      // case action_build_temporary_name :
5101    case action_build_triggers :
5102    case action_build_windefs :
5103    case action_check_configuration :
5104      // case action_check_files :
5105      // case action_check_version :
5106    case action_checkout :
5107    case action_cleanup :
5108    case action_config :
5109    case action_create :
5110      // case action_create_project :
5111    case action_cvsbranches :
5112    case action_cvssubpackages :
5113    case action_cvssubprojects :
5114    case action_cvstags :
5115    case action_do :
5116    case action_expand_model :
5117    case action_filter :
5118      // case action_help :
5119    case action_load :
5120    case action_lock :
5121    case action_relocate:
5122    case action_remove :
5123    case action_remove_library_links :
5124    case action_run :
5125    case action_run_sequence :
5126    case action_set_version :
5127    case action_set_versions :
5128    case action_setup :
5129    case action_show_action :
5130    case action_show_action_names :
5131    case action_show_action_value :
5132    case action_show_actions :
5133    case action_show_all_tags :
5134    case action_show_applied_patterns :
5135      // case action_show_author :
5136      // case action_show_branches :
5137      // case action_show_clients :
5138    case action_show_cmtpath_patterns :
5139    case action_show_constituent :
5140    case action_show_constituent_names :
5141    case action_show_constituents :
5142    case action_show_cycles :
5143    case action_show_fragment :
5144    case action_show_fragments :
5145    case action_show_groups :
5146    case action_show_include_dirs :
5147    case action_show_language :
5148    case action_show_languages :
5149    case action_show_macro :
5150    case action_show_macro_names :
5151    case action_show_macro_value :
5152    case action_show_macros :
5153      // case action_show_manager :
5154    case action_show_packages :
5155    case action_show_path :
5156    case action_show_pattern :
5157    case action_show_pattern_names :
5158    case action_show_patterns :
5159    case action_show_projects :
5160      // case action_show_pwd :
5161    case action_show_setup :
5162    case action_show_set :
5163    case action_show_set_names :
5164    case action_show_set_value :
5165    case action_show_sets :
5166    case action_show_strategies :
5167    case action_show_tags :
5168    case action_show_use_paths :
5169    case action_show_uses :
5170    case action_show_version :
5171      // case action_show_versions :
5172      // case action_system :
5173    case action_unlock :
5174    case action_version :
5175      use_cmt ();
5176      //
5177      // Now parse the requirements file stored in ${CMTHOME}
5178      //
5179     
5180      use_home_requirements ();
5181
5182      break;
5183    default:
5184      break;
5185    }
5186
5187  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
5188
5189  //
5190  // Setting up recursive actions
5191  //
5192
5193  switch (Me.m_action)
5194    {
5195      // case action_none :
5196    case action_awk :
5197    case action_broadcast :
5198    case action_build_constituent_makefile :
5199    case action_build_constituents_makefile :
5200    case action_build_dependencies :
5201    case action_build_library_links :
5202    case action_build_make_setup :
5203    case action_build_msdev :
5204    case action_build_CMT_pacman :
5205    case action_build_vsnet :     
5206    case action_build_os9_makefile :
5207      // case action_build_prototype :
5208    case action_build_readme :
5209    case action_build_tag_makefile :
5210      // case action_build_temporary_name :
5211    case action_build_triggers :
5212    case action_build_windefs :
5213    case action_check_configuration :
5214      // case action_check_files :
5215      // case action_check_version :
5216      // case action_checkout :
5217    case action_cleanup :
5218    case action_config :
5219      // case action_create :
5220      // case action_create_project :
5221      // case action_cvsbranches :
5222      // case action_cvssubpackages :
5223      // case action_cvssubprojects :
5224      // case action_cvstags :
5225    case action_do :
5226    case action_expand_model :
5227    case action_filter :
5228      // case action_help :
5229    case action_load :
5230      // case action_lock :
5231      // case action_remove :
5232    case action_relocate:
5233    case action_remove_library_links :
5234    case action_run :
5235    case action_run_sequence :
5236      // case action_set_version :
5237    case action_set_versions :
5238    case action_setup :
5239    case action_show_action :
5240    case action_show_action_names :
5241    case action_show_action_value :
5242    case action_show_actions :
5243    case action_show_all_tags :
5244    case action_show_applied_patterns :
5245      // case action_show_author :
5246      // case action_show_branches :
5247      // case action_show_clients :
5248    case action_show_cmtpath_patterns :
5249    case action_show_constituent :
5250    case action_show_constituent_names :
5251    case action_show_constituents :
5252    case action_show_cycles :
5253    case action_show_fragment :
5254    case action_show_fragments :
5255    case action_show_groups :
5256    case action_show_include_dirs :
5257    case action_show_language :
5258    case action_show_languages :
5259    case action_show_macro :
5260    case action_show_macro_names :
5261    case action_show_macro_value :
5262    case action_show_macros :
5263      // case action_show_manager :
5264    case action_show_packages :
5265    case action_show_path :
5266    case action_show_pattern :
5267    case action_show_pattern_names :
5268    case action_show_patterns :
5269    case action_show_projects :
5270      // case action_show_pwd :
5271    case action_show_setup :
5272    case action_show_set :
5273    case action_show_set_names :
5274    case action_show_set_value :
5275    case action_show_sets :
5276    case action_show_strategies :
5277    case action_show_tags :
5278    case action_show_use_paths :
5279    case action_show_uses :
5280      // case action_show_version :
5281      // case action_show_versions :
5282      // case action_system :
5283      // case action_unlock :
5284      // case action_version :
5285      Me.m_recursive = true;
5286      break;
5287    default:
5288      Me.m_recursive = false;
5289      break;
5290    }
5291
5292  //
5293  //  Actions for which the context of the package is checked,
5294  //  and the requirements file is analysed.
5295  //
5296
5297  switch (Me.m_action)
5298    {
5299    case action_none :
5300    case action_awk :
5301    case action_broadcast :
5302    case action_build_constituent_makefile :
5303    case action_build_constituents_makefile :
5304    case action_build_dependencies :
5305    case action_build_library_links :
5306    case action_build_make_setup :
5307    case action_build_msdev :
5308    case action_build_CMT_pacman :
5309    case action_build_vsnet :     
5310    case action_build_os9_makefile :
5311      // case action_build_prototype :
5312    case action_build_readme :
5313    case action_build_tag_makefile :
5314      // case action_build_temporary_name :
5315    case action_build_triggers :
5316    case action_build_windefs :
5317    case action_check_configuration :
5318      // case action_check_files :
5319      // case action_check_version :
5320      // case action_checkout :
5321    case action_cleanup :
5322    case action_config :
5323      // case action_create :
5324      // case action_create_project :
5325      // case action_cvsbranches :
5326      // case action_cvssubpackages :
5327      // case action_cvssubprojects :
5328      // case action_cvstags :
5329    case action_do :
5330    case action_expand_model :
5331    case action_filter :
5332      // case action_help :
5333    case action_load :
5334    case action_lock :
5335      // case action_remove :
5336    case action_relocate :
5337    case action_remove_library_links :
5338    case action_run :
5339      // case action_run_sequence :
5340      // case action_set_version :
5341    case action_set_versions :
5342    case action_setup :
5343    case action_show_action :
5344    case action_show_action_names :
5345    case action_show_action_value :
5346    case action_show_actions :
5347    case action_show_all_tags :
5348    case action_show_applied_patterns :
5349    case action_show_author :
5350    case action_show_branches :
5351      // case action_show_clients :
5352    case action_show_cmtpath_patterns :
5353    case action_show_constituent :
5354    case action_show_constituent_names :
5355    case action_show_constituents :
5356    case action_show_cycles :
5357    case action_show_fragment :
5358    case action_show_fragments :
5359    case action_show_groups :
5360    case action_show_include_dirs :
5361    case action_show_language :
5362    case action_show_languages :
5363    case action_show_macro :
5364    case action_show_macro_names :
5365    case action_show_macro_value :
5366    case action_show_macros :
5367    case action_show_manager :
5368    case action_show_packages :
5369    case action_show_path :
5370    case action_show_pattern :
5371    case action_show_pattern_names :
5372    case action_show_patterns :
5373    case action_show_projects :
5374    case action_show_project_author :
5375    case action_show_pwd :
5376    case action_show_setup :
5377    case action_show_set :
5378    case action_show_set_names :
5379    case action_show_set_value :
5380    case action_show_sets :
5381    case action_show_strategies :
5382    case action_show_tags :
5383    case action_show_use_paths :
5384    case action_show_uses :
5385    case action_show_version :
5386      // case action_show_versions :
5387      // case action_system :
5388    case action_unlock :
5389      // case action_version :
5390      {
5391        bool w = Me.m_warnings;
5392        Me.m_warnings = false;
5393        reach_current_package ();
5394        use_user_context_requirements ();
5395        Me.m_warnings = w;
5396      }
5397      break;
5398    default:
5399      break;
5400    }
5401
5402  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
5403
5404  //
5405  // Perform some actions even if there is an error
5406  //
5407
5408  if (CmtError::has_pending_error ())
5409    {
5410      int code = CmtError::get_last_error_code ();
5411      if (!Me.m_quiet) CmtError::print ();
5412
5413      switch (Me.m_action)
5414        {
5415          // case action_none :
5416          // case action_awk :
5417          // case action_broadcast :
5418        case action_build_constituent_makefile :
5419        case action_build_constituents_makefile :
5420        case action_build_dependencies :
5421        case action_build_library_links :
5422        case action_build_make_setup :
5423        case action_build_msdev :
5424        case action_build_CMT_pacman :
5425        case action_build_vsnet :     
5426        case action_build_os9_makefile :
5427        case action_build_prototype :
5428        case action_build_readme :
5429        case action_build_tag_makefile :
5430          // case action_build_temporary_name :
5431        case action_build_triggers :
5432        case action_build_windefs :
5433        case action_check_configuration :
5434          // case action_check_files :
5435          // case action_check_version :
5436          // case action_checkout :
5437        case action_cleanup :
5438          // case action_config :
5439          // case action_create :
5440          // case action_create_project :
5441          // case action_cvsbranches :
5442          // case action_cvssubpackages :
5443          // case action_cvssubprojects :
5444          // case action_cvstags :
5445          // case action_do :
5446          // case action_expand_model :
5447          // case action_filter :
5448          // case action_help :
5449        case action_load :
5450        case action_lock :
5451        case action_relocate :
5452        case action_remove :
5453        case action_remove_library_links :
5454          // case action_run :
5455        case action_run_sequence :
5456          // case action_set_version :
5457          // case action_set_versions :
5458        case action_setup :
5459          // case action_show_action :
5460          // case action_show_action_names :
5461          // case action_show_action_value :
5462          // case action_show_actions :
5463          // case action_show_all_tags :
5464          // case action_show_applied_patterns :
5465          // case action_show_author :
5466          // case action_show_branches :
5467          // case action_show_clients :
5468          // case action_show_cmtpath_patterns :
5469          // case action_show_constituent :
5470          // case action_show_constituent_names :
5471          // case action_show_constituents :
5472          // case action_show_cycles :
5473          // case action_show_fragment :
5474          // case action_show_fragments :
5475          // case action_show_groups :
5476          // case action_show_include_dirs :
5477          // case action_show_language :
5478          // case action_show_languages :
5479          // case action_show_macro :
5480          // case action_show_macro_names :
5481          // case action_show_macro_value :
5482          // case action_show_macros :
5483          // case action_show_manager :
5484          // case action_show_packages :
5485          // case action_show_path :
5486          // case action_show_pattern :
5487          // case action_show_pattern_names :
5488          // case action_show_patterns :
5489          // case action_show_projects :
5490          // case action_show_pwd :
5491          // case action_show_setup :
5492          // case action_show_set :
5493          // case action_show_set_names :
5494          // case action_show_set_value :
5495          // case action_show_sets :
5496          // case action_show_strategies :
5497          // case action_show_tags :
5498          // case action_show_use_paths :
5499          // case action_show_uses :
5500          // case action_show_version :
5501          // case action_show_versions :
5502          // case action_system :
5503        case action_unlock :
5504          // case action_version :
5505          clear ();
5506          return (code);
5507        default:
5508          CmtError::clear ();
5509          break;
5510        }
5511    }
5512
5513  //
5514  // Perform actions
5515  //
5516
5517  if (!Me.m_simulation)
5518    {
5519      switch (Me.m_action)
5520        {
5521        case action_none :
5522          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
5523          break;
5524        case action_awk :
5525          do_awk (ap);
5526          break;
5527        case action_broadcast :
5528          do_broadcast (ap);
5529          break;
5530        case action_build_constituent_makefile :
5531          do_build_constituent_makefile (ap);
5532          break;
5533        case action_build_constituents_makefile :
5534          do_build_constituents_makefile (ap);
5535          break;
5536        case action_build_dependencies :
5537          do_build_dependencies (ap, argc, argv);
5538          break;
5539        case action_build_library_links :
5540          do_build_library_links (ap);
5541          break;
5542        case action_build_make_setup :
5543          do_build_make_setup (ap);
5544          break;
5545        case action_build_msdev :
5546          do_build_msdev (ap);
5547          break;
5548        case action_build_CMT_pacman :
5549          do_build_CMT_pacman (ap);
5550          break;
5551        case action_build_vsnet :     
5552          do_build_vsnet (ap);
5553          break;
5554        case action_build_os9_makefile :
5555          do_build_os9_makefile (ap);
5556          break;
5557        case action_build_prototype :
5558          do_build_prototype (ap);
5559          break;
5560        case action_build_readme :
5561          do_build_readme (ap);
5562          break;
5563        case action_build_tag_makefile :
5564          do_build_tag_makefile (ap);
5565          break;
5566        case action_build_temporary_name :
5567          do_build_temporary_name (ap);
5568          break;
5569        case action_build_triggers :
5570          do_build_triggers (ap);
5571          break;
5572        case action_build_windefs :
5573          do_build_windefs (ap);
5574          break;
5575        case action_check_configuration :
5576          do_check_configuration (ap);
5577          break;
5578        case action_check_files :
5579          do_check_files (ap);
5580          break;
5581        case action_check_version :
5582          do_check_version (ap);
5583          break;
5584        case action_checkout :
5585          do_checkout (ap);
5586          break;
5587        case action_cleanup :
5588          do_cleanup (ap);
5589          break;
5590        case action_config :
5591          do_config (ap);
5592          break;
5593        case action_create :
5594          do_create (ap);
5595          break;
5596        case action_create_project :
5597          do_create_project (ap);
5598          break;
5599        case action_cvsbranches :
5600          do_cvsbranches (ap);
5601          break;
5602        case action_cvssubpackages :
5603          do_cvssubpackages (ap);
5604          break;
5605        case action_cvssubprojects :
5606          do_cvssubprojects (ap);
5607          break;
5608        case action_cvstags :
5609          do_cvstags (ap);
5610          break;
5611        case action_do :
5612          do_do (ap);
5613          break;
5614        case action_expand_model :
5615          do_expand_model (ap);
5616          break;
5617        case action_filter :
5618          do_filter (ap);
5619          break;
5620        case action_help :
5621          do_help (ap);
5622          break;
5623        case action_load :
5624          cerr << "#CMT> action not implemented" << endl;
5625          break;
5626        case action_lock :
5627          do_lock (ap);
5628          break;
5629        case action_relocate :
5630          do_relocate (ap);
5631          break;
5632        case action_remove :
5633          do_remove (ap);
5634          break;
5635        case action_remove_library_links :
5636          do_remove_library_links (ap);
5637          break;
5638        case action_run :
5639          do_run (ap);
5640          break;
5641        case action_run_sequence :
5642          do_run_sequence (ap);
5643          break;
5644        case action_set_version :
5645          do_set_version (ap);
5646          break;
5647        case action_set_versions :
5648          do_set_versions (ap);
5649          break;
5650        case action_setup :
5651          do_setup (ap);
5652          break;
5653        case action_show_action :
5654          do_show_action (ap);
5655          break;
5656        case action_show_action_names :
5657          do_show_action_names (ap);
5658          break;
5659        case action_show_action_value :
5660          do_show_action_value (ap);
5661          break;
5662        case action_show_actions :
5663          do_show_actions (ap);
5664          break;
5665        case action_show_all_tags :
5666          do_show_all_tags (ap);
5667          break;
5668        case action_show_applied_patterns :
5669          do_show_applied_patterns (ap);
5670          break;
5671        case action_show_author :
5672          do_show_author (ap);
5673          break;
5674        case action_show_branches :
5675          do_show_branches (ap);
5676          break;
5677        case action_show_clients :
5678          do_show_clients (ap);
5679          break;
5680        case action_show_cmtpath_patterns :
5681          do_show_cmtpath_patterns (ap);
5682          break;
5683        case action_show_constituent :
5684          do_show_constituent (ap);
5685          break;
5686        case action_show_constituent_names :
5687          do_show_constituent_names (ap);
5688          break;
5689        case action_show_constituents :
5690          do_show_constituents (ap);
5691          break;
5692        case action_show_cycles :
5693          do_show_cycles (ap);
5694          break;
5695        case action_show_fragment :
5696          do_show_fragment (ap);
5697          break;
5698        case action_show_fragments :
5699          do_show_fragments (ap);
5700          break;
5701        case action_show_groups :
5702          do_show_groups (ap);
5703          break;
5704        case action_show_include_dirs :
5705          do_show_include_dirs (ap);
5706          break;
5707        case action_show_language :
5708          do_show_language (ap);
5709          break;
5710        case action_show_languages :
5711          do_show_languages (ap);
5712          break;
5713        case action_show_macro :
5714          do_show_macro (ap);
5715          break;
5716        case action_show_macro_names :
5717          do_show_macro_names (ap);
5718          break;
5719        case action_show_macro_value :
5720          do_show_macro_value (ap);
5721          break;
5722        case action_show_macros :
5723          do_show_macros (ap);
5724          break;
5725        case action_show_manager :
5726          do_show_manager (ap);
5727          break;
5728        case action_show_packages :
5729          do_show_packages (ap);
5730          break;
5731        case action_show_path :
5732          do_show_path (ap);
5733          break;
5734        case action_show_pattern :
5735          do_show_pattern (ap);
5736          break;
5737        case action_show_pattern_names :
5738          do_show_pattern_names (ap);
5739          break;
5740        case action_show_patterns :
5741          do_show_patterns (ap);
5742          break;
5743        case action_show_projects :
5744          do_show_projects (ap);
5745          break;
5746        case action_show_project_author :
5747          do_show_project_author (ap);
5748          break;
5749        case action_show_pwd :
5750          do_show_pwd (ap);
5751          break;
5752        case action_show_setup :
5753          do_show_setup (ap);
5754          break;
5755        case action_show_set :
5756          do_show_set (ap);
5757          break;
5758        case action_show_set_names :
5759          do_show_set_names (ap);
5760          break;
5761        case action_show_set_value :
5762          do_show_set_value (ap);
5763          break;
5764        case action_show_sets :
5765          do_show_sets (ap);
5766          break;
5767        case action_show_strategies :
5768          do_show_strategies (ap);
5769          break;
5770        case action_show_tags :
5771          do_show_tags (ap);
5772          break;
5773        case action_show_use_paths :
5774          do_show_use_paths (ap);
5775          break;
5776        case action_show_uses :
5777          do_show_uses (ap);
5778          break;
5779        case action_show_version :
5780          do_show_version (ap);
5781          break;
5782        case action_show_versions :
5783          do_show_versions (ap);
5784          break;
5785        case action_system :
5786          do_show_system (ap);
5787          break;
5788        case action_unlock :
5789          do_unlock (ap);
5790          break;
5791        case action_version :
5792          do_version (ap);
5793          break;
5794        default:
5795          CmtError::set (CmtError::syntax_error, "ParseArguments>");
5796          break;
5797        }
5798    }
5799
5800  if (CmtError::has_pending_error ())
5801    {
5802      int code = CmtError::get_last_error_code ();     
5803      if (code == CmtError::execution_failed)
5804        {
5805          code = CmtError::get_last_execution_error();
5806        }   
5807     
5808      if (!Me.m_quiet) CmtError::print ();
5809      clear ();
5810      return (code);
5811    }
5812  else
5813    {
5814      clear ();
5815      return (0);
5816    }
5817}
5818
5819
5820/**
5821 * Format as one single line a set of 'setenv' statements
5822 * joined with semi-colons to form one shell command.
5823 */
5824void Cmt::print (PrintMode mode)
5825{
5826  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5827  Use& current_use = Use::current ();
5828
5829  cmt_string tag;
5830
5831  set_standard_macros ();
5832
5833  //cerr << "# current_tag=" << Me.m_current_tag << endl;
5834  //cerr << "# current_config=" << Me.m_current_config << endl;
5835
5836  if (Me.m_current_tag == "")
5837    {
5838      if (mode == Bat) tag = "%CMTCONFIG%";
5839      else tag = "${CMTCONFIG}";
5840    }
5841  else
5842    {
5843      tag = Me.m_current_tag;
5844    }
5845
5846  //
5847  //  Now check if all extra tags are still valid. Some of them
5848  //  may be discarded du to some conflict with highest priority
5849  //  tags, or with exclude statements
5850  //
5851
5852  {
5853    CmtSystem::cmt_string_vector words;
5854     
5855    cmt_string tags;
5856
5857    tags = Me.m_extra_tags;
5858     
5859    CmtSystem::split (tags, " \t,", words);
5860
5861    Me.m_extra_tags = ",";
5862     
5863    for (int i = 0; i < words.size (); i++)
5864      {
5865        Tag* tag;
5866        const cmt_string& a = words[i];
5867
5868        tag = Tag::find (a);
5869
5870        if ((tag != 0) && (tag->is_selected ()))
5871          {
5872            Me.m_extra_tags += a;
5873            Me.m_extra_tags += ",";
5874          }
5875      }
5876  }
5877
5878  if (Me.m_debug)
5879    {
5880      cout << "Before all print contexts" << endl;
5881    }
5882
5883  if (Uses.size () > 0)
5884    {
5885      int number;
5886
5887      for (number = 0; number < Uses.size (); number++)
5888        {
5889          Use& use = *(Uses[number]);
5890
5891          if (use.discarded) continue;
5892          if (use.m_hidden) continue;
5893         
5894          print_context (use, mode, tag);
5895        }
5896    }
5897
5898  print_context (Use::current (), mode, tag);
5899
5900  if (Me.m_debug)
5901    {
5902      cout << "After all print contexts" << endl;
5903    }
5904
5905  Symbol::all_print (mode);
5906  // Script::all_print (mode);
5907
5908  if (Me.m_debug)
5909    {
5910      cout << "After all print" << endl;
5911    }
5912
5913  cout << endl;
5914}
5915
5916
5917/**
5918 * Format as one single line a set of 'unsetenv' statements
5919 * joined with semi-colons to form one shell command.
5920 */
5921void Cmt::print_clean (PrintMode mode)
5922{
5923  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5924
5925  set_standard_macros ();
5926
5927  Script::all_print_clean (mode);
5928  Symbol::all_print_clean (mode);
5929
5930  switch (mode)
5931    {
5932    case Csh :
5933      if (Me.m_current_package != "CMT")
5934        {
5935          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
5936          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
5937        }
5938      break;
5939    case Sh :
5940      if (Me.m_current_package != "CMT")
5941        {
5942          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
5943          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
5944        }
5945      break;
5946    case Bat :
5947      if (Me.m_current_package != "CMT")
5948        {
5949          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
5950          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
5951        }
5952      break;
5953    }
5954
5955  if (Uses.size () > 0)
5956    {
5957      int number;
5958
5959      for (number = 0; number < Uses.size (); number++)
5960        {
5961          Use* use = Uses[number];
5962
5963          if (use->discarded) continue;
5964          if (use->m_hidden) continue;
5965
5966          Package* p = use->get_package ();
5967          if (p->is_cmt ()) continue;
5968
5969
5970          switch (mode)
5971            {
5972            case Csh :
5973              cout << "unsetenv " << use->prefix << "ROOT" << endl;
5974              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
5975              break;
5976            case Sh :
5977              cout << "unset " << use->prefix << "ROOT" << endl;
5978              cout << "unset " << use->prefix << "CONFIG" << endl;
5979              break;
5980            case Bat :
5981              cout << "set " << use->prefix << "ROOT=" << endl;
5982              cout << "set " << use->prefix << "CONFIG" << endl;
5983              break;
5984            }
5985        }
5986    }
5987
5988  switch (mode)
5989    {
5990    case Csh :
5991      cout << "unsetenv CMTEXTRATAGS" << endl;
5992      break;
5993    case Sh :
5994      cout << "unset CMTEXTRATAGS" << endl;
5995      break;
5996    case Bat :
5997      cout << "set CMTEXTRATAGS=" << endl;
5998      break;
5999    }
6000
6001  cout << endl;
6002}
6003
6004//----------------------------------------------------------
6005void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
6006{
6007  if (use.get_package_name () == "cmt_standalone") return;
6008
6009  cmt_string fs = CmtSystem::file_separator ();
6010
6011  use.real_path.replace_all (CmtSystem::file_separator (), fs);
6012
6013  cmt_string system = CmtSystem::get_cmt_config ();
6014
6015  bool do_config = use.get_strategy ("SetupConfig");
6016  bool do_root   = use.get_strategy ("SetupRoot");
6017   
6018 
6019  switch (mode)
6020    {
6021    case Csh :
6022      if (do_root)
6023        {
6024          cout << "setenv " << use.prefix << "ROOT \"" <<
6025            use.get_full_path () << "\"" << endl;
6026        }
6027
6028      if (use.get_package_name () == "CMT")
6029        {
6030          cout << "setenv CMTCONFIG " << system << endl;
6031        }
6032      else
6033        {
6034          if (do_config)
6035            {
6036              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
6037            }
6038        }
6039       
6040      break;
6041    case Sh :
6042      if (do_root)
6043        {
6044          cout << use.prefix << "ROOT=\"" <<
6045            use.get_full_path () << "\"; export " <<
6046            use.prefix << "ROOT" << endl;
6047        }
6048
6049      if (use.get_package_name () == "CMT")
6050        {
6051          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
6052        }
6053      else
6054        {
6055          if (do_config)
6056            {
6057              cout << use.prefix << "CONFIG=\"" <<
6058                tag << "\"; export " <<
6059                use.prefix << "CONFIG" << endl;
6060            }
6061        }
6062       
6063      break;
6064    case Bat :
6065      if (do_root)
6066        {
6067          cout << "set " << use.prefix << "ROOT=" <<
6068            use.get_full_path () << endl;
6069        }
6070
6071      if (use.get_package_name () == "CMT")
6072        {
6073          cout << "set CMTCONFIG=" << system << endl;
6074        }
6075      else
6076        {
6077          if (do_config)
6078            {
6079              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
6080            }
6081        }
6082       
6083      break;
6084    }
6085}
6086
6087/**
6088 *  Format a set of make macro definitions (one per line)
6089 * Each macro value is provided enclosed in single quotes
6090 *
6091 *  Take the macro values from the macro statements found
6092 * in recursively read requirements files.
6093 */
6094void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
6095{
6096  int number;
6097
6098  set_standard_macros ();
6099
6100  cmt_regexp expression (pattern);
6101
6102  bool has_pattern = (pattern != "");
6103
6104  for (number = 0; number < Symbol::symbol_number (); number++)
6105    {
6106      Symbol& symbol = Symbol::symbol (number);
6107
6108      if (has_pattern)
6109        {
6110          if (!expression.match (symbol.name)) continue;
6111        }
6112
6113      if (Me.m_action == action_show_macro_names)
6114        {
6115          // Only keep macros.
6116          if ((symbol.type == Symbol::SymbolSet) ||
6117              (symbol.type == Symbol::SymbolAlias) ||
6118              (symbol.type == Symbol::SymbolPath) ||
6119              (symbol.type == Symbol::SymbolAction)) continue;
6120        }
6121      else if (Me.m_action == action_show_set_names)
6122        {
6123          // Exclude macros.
6124          if ((symbol.type == Symbol::SymbolMacro) ||
6125              (symbol.type == Symbol::SymbolAction)) continue;
6126        }
6127      else if (Me.m_action == action_show_action_names)
6128        {
6129          // Exclude macros.
6130          if (symbol.type != Symbol::SymbolAction) continue;
6131        }
6132
6133      cout << symbol.name << endl;
6134    }
6135}
6136
6137/**
6138 *  Format a set of make macro definitions (one per line)
6139 * Each macro value is provided enclosed in single quotes
6140 *
6141 *  Take the macro values from the macro statements found
6142 * in recursively read requirements files.
6143 */
6144void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
6145{
6146  int number;
6147
6148  set_standard_macros ();
6149
6150  cmt_regexp expression (pattern);
6151
6152  bool has_pattern = (pattern != "");
6153
6154  for (number = 0; number < Symbol::symbol_number (); number++)
6155    {
6156      Symbol& symbol = Symbol::symbol (number);
6157
6158      if (has_pattern)
6159        {
6160          if (!expression.match (symbol.name)) continue;
6161        }
6162
6163      if (Me.m_action == action_show_macros)
6164        {
6165          // Only keep macros.
6166          if ((symbol.type == Symbol::SymbolSet) ||
6167              (symbol.type == Symbol::SymbolAlias) ||
6168              (symbol.type == Symbol::SymbolPath) ||
6169              (symbol.type == Symbol::SymbolAction)) continue;
6170        }
6171      else if (Me.m_action == action_show_sets)
6172        {
6173          // Exclude macros.
6174          if ((symbol.type == Symbol::SymbolMacro) ||
6175              (symbol.type == Symbol::SymbolAction)) continue;
6176        }
6177      else if (Me.m_action == action_build_tag_makefile)
6178        {
6179          // Exclude scripts and actions
6180          if ((symbol.type == Symbol::SymbolSetupScript) ||
6181              (symbol.type == Symbol::SymbolCleanupScript) ||
6182              (symbol.type == Symbol::SymbolAction)) continue;
6183        }
6184      else if (Me.m_action == action_show_actions)
6185        {
6186          if (symbol.type != Symbol::SymbolAction) continue;
6187        }
6188
6189      if (symbol.value_lists.size () < 1) continue;
6190
6191      symbol.show_macro (mode);
6192    }
6193}
6194
6195//----------------------------------------------------------
6196void Cmt::print_tabs (int tabs)
6197{
6198  while (tabs > 0)
6199    {
6200      cout << "  ";
6201      tabs--;
6202    }
6203}
6204
6205//----------------------------------------------------------
6206int Cmt::reach_current_package ()
6207{
6208  Use& use = Use::current ();
6209  cmt_string dir;
6210
6211  if (Me.m_debug)
6212    {
6213      cout << "Cmt::reach_current_package> pwd = " 
6214           << CmtSystem::pwd () 
6215           << " path=" << Me.m_current_path
6216           << " package=" << Me.m_current_package
6217           << endl;
6218    }
6219
6220  /*
6221    Try to access the package.
6222  */
6223
6224  if (Me.m_current_package == "cmt_standalone")
6225    {
6226      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
6227        {
6228          if (!CmtSystem::cd (Me.m_current_path))
6229            {
6230              CmtError::set (CmtError::package_not_found,
6231                             "ReachCurrentPackage> Cannot reach the path directory");
6232              return (0);
6233            }
6234        }
6235
6236      if (!CmtSystem::test_file ("requirements"))
6237        {
6238          return (0);
6239        }
6240    }
6241  else if (Me.m_current_package != "")
6242    {
6243      if (!use.move_to ())
6244        {
6245          CmtError::set (CmtError::package_not_found,
6246                         "ReachCurrentPackage> Cannot reach the path directory");
6247          return (0);
6248        }
6249
6250      Me.m_current_path = use.real_path;
6251    }
6252  else
6253    {
6254      //
6255      // The cmt command has been given without explicit search for
6256      // a package. Thus it is expected that we are in the context of a
6257      // true package.
6258      //
6259      //  This means that there should be a requirements file visible.
6260      //
6261      //  If this is not true, we'll make a try into ../cmt and then
6262      // a last try into ../mgr
6263      //
6264
6265      if (!CmtSystem::test_file ("requirements"))
6266        {
6267          if (CmtSystem::cd ("../cmt") && 
6268              CmtSystem::test_file ("requirements"))
6269            {
6270              Me.m_current_style = cmt_style;
6271            }
6272          else if (CmtSystem::cd ("../mgr") && 
6273                   CmtSystem::test_file ("requirements"))
6274            {
6275              Me.m_current_style = mgr_style;
6276            }
6277          else
6278            {
6279              if (!Me.m_quiet)
6280                {
6281                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
6282                }
6283             
6284              CmtError::set (CmtError::package_not_found,
6285                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
6286              return (0);
6287            }
6288        }
6289
6290      dir = CmtSystem::pwd ();
6291
6292      CmtSystem::dirname (dir, Me.m_current_path);
6293      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
6294
6295      if (CmtSystem::is_version_directory (Me.m_current_version))
6296        {
6297          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6298          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
6299          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6300        }
6301      else
6302        {
6303          Me.m_current_package = Me.m_current_version;
6304          Me.m_current_version = "";
6305          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6306
6307          Me.m_current_style = no_version_style;
6308        }
6309
6310      use.set_package_name (Me.m_current_package);
6311      use.version = Me.m_current_version;
6312      use.path    = Me.m_current_path;
6313      use.style   = Me.m_current_style;
6314    }
6315
6316  configure_current_dir ();
6317  build_prefix (Me.m_current_package, Me.m_current_prefix);
6318  build_config (Me.m_current_prefix, Me.m_current_config);
6319
6320  /*
6321    Check Tag is always set up
6322  */
6323
6324  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
6325
6326  if (Me.m_current_tag == "")
6327    {
6328      cmt_string env;
6329
6330      env = CmtSystem::getenv (Me.m_current_config);
6331      if (env != "")
6332        {
6333          Tag* tag;
6334
6335          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
6336          tag->mark ();
6337          //Me.m_current_tag = env;
6338
6339          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
6340
6341        }
6342    }
6343
6344  if (Me.m_debug)
6345    {
6346      cout << "pwd = " << CmtSystem::pwd () << endl;
6347    }
6348
6349  /*
6350    Work on the requirements file.
6351  */
6352
6353  if (dir != "") dir += CmtSystem::file_separator ();
6354  dir += "requirements";
6355  SyntaxParser::parse_requirements (dir, &use);
6356
6357  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
6358
6359  /**
6360   *   It would be useful to change this mechanism. Instead of
6361   *  applying all global patterns at once to all use contexts, it
6362   *  would be much better to apply it at the end of each
6363   *  requirements file parsing, and only in the context the
6364   *  appropriate Use.
6365   *
6366   *   This would avoid the current flaw which is that when a global
6367   *  pattern specifies a "private" definition, it is actually
6368   *  applied in the scope context of the Current Use and not in
6369   *  each individual Use. Therefore the private is lost.
6370   *
6371   *   However, this induces problems since some pattern definitions
6372   *  are done AFTER the use statements, which will NOT receive the
6373   *  pattern aplications.
6374   *
6375   *   Therefore it is decided to leave this "bad" mechanism until
6376   *  everybody is aware of this constraint.
6377   *
6378   *
6379   */
6380  Pattern::apply_all_globals ();
6381
6382  /*
6383    Select all possible tags
6384  */
6385
6386  Tag::restore_tree ();
6387
6388  return (1);
6389}
6390
6391static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
6392                                 const cmt_string& path)
6393{
6394  static cmt_string fs = CmtSystem::file_separator ();
6395  cmt_string result;
6396
6397  /*
6398  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
6399  {
6400  */
6401
6402  //
6403  //  If there is a common prefix between
6404  //  use->real_path and pwd
6405  //  we have
6406  //  use->real_path = /<prefix>/aaa
6407  //  pwd            = /<prefix>/bbb
6408  //
6409  //  Then use->real_path may be expressed as:
6410  //  ../..../../aaa
6411  //   where ../..../../ moves up to /<prefix>
6412  //
6413  //   Then we try to find the shortest between
6414  //
6415  //     /<prefix> and ../..../..
6416  //
6417  cmt_string a = path;
6418 
6419  CmtSystem::cmt_string_vector va;
6420 
6421  va.clear ();
6422 
6423  CmtSystem::split (a, fs, va);
6424 
6425  int m = va.size ();
6426  if (pwd.size () < m) m = pwd.size ();
6427 
6428  int i;
6429 
6430  for (i = 0; i < m; i++)
6431    {
6432      const cmt_string& fa = va[i];
6433      const cmt_string& fb = pwd[i];
6434     
6435      if (fa != fb) break;
6436    }
6437 
6438  cmt_string ups = "";
6439 
6440  if (i > 0)
6441    {
6442      // We have the prefix.
6443      // if we count what remains from pwd, then
6444      // we have the number of ../ required to
6445      // move to /<prefix>
6446      int j;
6447     
6448      for (j = i; j < pwd.size (); j++)
6449        {
6450          if (j > i) ups += fs;
6451          ups += "..";
6452        }
6453
6454      for (j = i; j < va.size (); j++)
6455        {
6456          ups += fs;
6457          ups += va[j];
6458        }
6459    }
6460 
6461  //
6462  // Here ups contains the ../..../../aaa form
6463  // for the use->real_path or is empty when there
6464  // were no common prefix.
6465  //
6466 
6467  //if (ups != "")
6468  if ((ups != "") &&
6469      (ups.size () < path.size ()))
6470    {
6471      result = ups;
6472    }
6473  else
6474    {
6475      result = path;
6476    }
6477
6478  return (result);
6479}
6480
6481/**
6482 *   This completely local class holds primitive actions for building
6483 *   standard macros.
6484 */
6485class StandardMacroBuilder
6486{
6487public:
6488
6489  /**
6490   *  CMTVERSION
6491   */
6492  void fill_for_CMTVERSION ()
6493  {
6494    buffer = "macro CMTVERSION \"";
6495    buffer += CMTVERSION;
6496    buffer += "\"";
6497    apply ();
6498  }
6499
6500  StandardMacroBuilder (const cmt_string& tag,
6501                        const cmt_string& package,
6502                        const cmt_string& version,
6503                        const cmt_string& prefix,
6504                        CmtDirStyle style)
6505  {
6506    fs = CmtSystem::file_separator ();
6507    buffer = "";
6508    pwd = CmtSystem::pwd ();
6509    CmtSystem::split (pwd, fs, vb);
6510    current_use = &(Use::current ());
6511    current_tag = tag;
6512    current_package = package;
6513    current_version = version;
6514    current_prefix = prefix;
6515    current_style = style;
6516  }
6517
6518  void apply ()
6519  {
6520    SyntaxParser::parse_requirements_line (buffer, current_use);
6521    buffer = "";
6522  }
6523
6524  /**
6525   *   tag
6526   */
6527  void fill_for_tag ()
6528  {
6529    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
6530
6531    if (!Symbol::is_selected ("tag"))
6532      {
6533        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
6534
6535        if (current_tag == "")
6536          {
6537            buffer = "macro tag \"$(CMTCONFIG)\"";
6538          }
6539        else
6540          {
6541            buffer = "macro tag \"";
6542            buffer += current_tag;
6543            buffer += "\"";
6544          }
6545       
6546        if (tag_debug) cerr << " define tag: " << buffer << endl;
6547       
6548        apply ();
6549      }
6550  }
6551
6552  /**
6553   *   PACKAGE_ROOT
6554   */
6555  void fill_for_package (const cmt_string& current_dir)
6556  {
6557    buffer = "macro package \"";
6558    buffer += current_package;
6559    buffer += "\"";
6560    apply ();
6561
6562    buffer = "macro version \"";
6563    buffer += current_version;
6564    buffer += "\"";
6565    apply ();
6566
6567    if (!Symbol::is_selected ("PACKAGE_ROOT"))
6568      {
6569        buffer = "macro PACKAGE_ROOT \"$(";
6570        buffer += current_prefix;
6571        buffer += "ROOT";
6572        buffer += ")\"";
6573
6574        apply ();
6575      }
6576  }
6577
6578  /**
6579   *   srcdir
6580   *   src       =$(srcdir)/
6581   *   inc
6582   *   mgrdir
6583   *   mgr       =../$(mgrdir)/
6584   *   bin
6585   *   javabin
6586   *   doc
6587   *   version
6588   *   package
6589   *
6590   *   <package>_project
6591   *   <package>_cmtpath
6592   *   <package>_offset
6593   *   package_cmtpath
6594   *   package_offset
6595   *   project
6596   *
6597   */
6598  void fill_for_branches ()
6599  {
6600    /**
6601     *    Basic macros  (src, mgr, ...)
6602     */
6603   
6604    if (current_style == none_style)
6605      {
6606        buffer = "macro srcdir \".";
6607        buffer += "\"";
6608        apply ();
6609
6610        buffer = "macro src \".";
6611        buffer += fs;
6612        buffer += "\"";
6613        apply ();
6614
6615        buffer = "macro inc \".";
6616        buffer += fs;
6617        buffer += "\"";
6618        apply ();
6619
6620        buffer = "macro mgr \".";
6621        buffer += fs;
6622        buffer += "\"";
6623        apply ();
6624
6625        buffer = "macro bin \".";
6626        buffer += fs;
6627        buffer += "\"";
6628        apply ();
6629
6630        buffer = "macro javabin \".";
6631        buffer += fs;
6632        buffer += "\"";
6633        apply ();
6634
6635        buffer = "macro doc \".";
6636        buffer += fs;
6637        buffer += "\"";
6638        apply ();
6639      }
6640    else
6641      {
6642        if (!Symbol::is_selected ("srcdir"))
6643          {
6644            buffer = "macro srcdir \"..";
6645            buffer += fs;
6646            buffer += "src";
6647            buffer += "\"";
6648            apply ();
6649          }
6650       
6651        if (!Symbol::is_selected ("src"))
6652          {
6653            buffer = "macro src \"..";
6654            buffer += fs;
6655            buffer += "src";
6656            buffer += fs;
6657            buffer += "\"";
6658            apply ();
6659          }
6660       
6661        if (!Symbol::is_selected ("inc"))
6662          {
6663            buffer = "macro inc \"..";
6664            buffer += fs;
6665            buffer += "src";
6666            buffer += fs;
6667            buffer += "\"";
6668            apply ();
6669          }
6670       
6671        if (!Symbol::is_selected ("doc"))
6672          {
6673            buffer = "macro doc \"..";
6674            buffer += fs;
6675            buffer += "doc";
6676            buffer += fs;
6677            buffer += "\"";
6678            apply ();
6679          }
6680       
6681        if (!Symbol::is_selected ("bin"))
6682          {
6683            cmt_string package_tag = current_package;
6684            package_tag += "_tag";
6685
6686            buffer = "macro bin \"..";
6687            buffer += fs;
6688            buffer += "$(";
6689            buffer += package_tag;
6690            buffer += ")";
6691            buffer += fs;
6692            buffer += "\"";
6693            apply ();
6694          }
6695
6696        if (!Symbol::is_selected ("javabin"))
6697          {
6698            buffer = "macro javabin \"..";
6699            buffer += fs;
6700            buffer += "classes";
6701            buffer += fs;
6702            buffer += "\"";
6703            apply ();
6704          }
6705       
6706        if (current_style == mgr_style)
6707          {
6708            buffer = "macro mgrdir \"mgr\"";
6709            apply ();
6710
6711            buffer = "macro mgr \"..";
6712            buffer += fs;
6713            buffer += "mgr";
6714            buffer += fs;
6715            buffer += "\"";
6716            apply ();
6717          }
6718        else
6719          {
6720            buffer = "macro mgrdir \"cmt\"";
6721            apply ();
6722
6723            buffer = "macro mgr \"..";
6724            buffer += fs;
6725            buffer += "cmt";
6726            buffer += fs;
6727            buffer += "\"";
6728            apply ();
6729          }
6730
6731        Cmt::configure_current_cmtpath ();
6732      }
6733  }
6734
6735  /**
6736   *   project
6737   */
6738  void fill_for_project ()
6739  {
6740    if (current_style == none_style) return;
6741
6742    cmt_string project_name;
6743    Project* project = Project::get_current ();
6744    if (project != 0)
6745      {
6746        project_name = project->get_name ();
6747      }
6748
6749    buffer = "macro project \"";
6750    buffer += project_name;
6751    buffer += "\"";
6752    apply ();
6753  }
6754
6755  /**
6756   *   use_requirements
6757   */
6758  void fill_for_use_requirements ()
6759  {
6760    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6761
6762    if (Uses.size () == 0) return;
6763
6764    if (!Symbol::is_selected ("use_requirements"))
6765      {
6766        buffer  = "macro use_requirements \"";
6767        buffer += "requirements ";
6768       
6769        for (int number = 0; number < Uses.size (); number++)
6770          {
6771            Use* use = Uses[number];
6772           
6773            if (use->discarded) continue;
6774            if (use->m_hidden) continue;
6775           
6776            if (use->located ())
6777              {
6778                buffer += "$(";
6779                buffer += use->prefix;
6780                buffer += "ROOT)";
6781                buffer += fs;
6782               
6783                if (use->style == mgr_style) buffer += "mgr";
6784                else buffer += "cmt";
6785               
6786                buffer += fs;
6787                buffer += "requirements ";
6788              }
6789          }
6790       
6791        buffer += "\"";
6792       
6793        apply ();
6794      }
6795  }
6796
6797  /**
6798   *   use_includes
6799   */
6800  void fill_for_use_includes ()
6801  {
6802    Include::parse_all (&(Use::current()));
6803
6804    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6805
6806    if (Uses.size () == 0) return;
6807
6808    if (!Symbol::is_selected ("use_includes"))
6809      {
6810        buffer = "macro_append use_includes \' ";
6811       
6812        for (int number = 0; number < Uses.size (); number++)
6813          {
6814            Use* use = Uses[number];
6815           
6816            if (use->discarded) continue;
6817            if (use->m_hidden) continue;
6818
6819            Package* p = use->get_package ();
6820            if (p->is_cmt ()) continue;
6821
6822            if (Cmt::get_debug ())
6823              {
6824                cout << "fill use_includes for " << use->get_package_name () 
6825                     << " discarded=" << use->discarded
6826                     << " auto_imports=" << use->auto_imports << endl;
6827              }
6828           
6829            if (use->auto_imports == Off) continue;
6830           
6831            Include::parse_all (use);
6832
6833            use->fill_includes_macro (buffer);
6834          }
6835       
6836        buffer += "\'";
6837       
6838        apply ();
6839      }
6840  }
6841
6842  /**
6843   *   use_fincludes
6844   */
6845  void fill_for_use_fincludes ()
6846  {
6847    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6848
6849    if (Uses.size () == 0) return;
6850
6851    if (!Symbol::is_selected ("use_fincludes"))
6852      {
6853        buffer = "macro_append use_fincludes \" $(use_includes)\"";
6854        apply ();
6855      }
6856  }
6857
6858  /**
6859   *   use_stamps
6860   */
6861  void fill_for_use_stamps ()
6862  {
6863    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6864
6865    if (Uses.size () == 0) return;
6866
6867    if (!Symbol::is_selected ("use_stamps"))
6868      {
6869        buffer = "macro use_stamps \"";
6870        (Use::current()).fill_macro (buffer, "stamps");
6871       
6872        for (int number = 0; number < Uses.size (); number++)
6873          {
6874            Use* use = Uses[number];
6875           
6876            if (use->discarded) continue;
6877            if (use->m_hidden) continue;
6878
6879            Package* p = use->get_package ();
6880            if (p->is_cmt ()) continue;
6881           
6882            use->fill_macro (buffer, "stamps");
6883          }
6884       
6885        buffer += "\"";
6886       
6887        apply ();
6888      }
6889  }
6890
6891  /**
6892   *   use_cflags
6893   */
6894  void fill_for_use_cflags ()
6895  {
6896    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6897
6898    if (Uses.size () == 0) return;
6899
6900    if (!Symbol::is_selected ("use_cflags"))
6901      {
6902        Use::fill_macro_all (buffer, "cflags");
6903        apply ();
6904      }
6905  }
6906
6907  /**
6908   *   use_pp_cflags
6909   */
6910  void fill_for_use_pp_cflags ()
6911  {
6912    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6913
6914    if (Uses.size () == 0) return;
6915
6916    if (!Symbol::is_selected ("use_pp_cflags"))
6917      {
6918        Use::fill_macro_all (buffer, "pp_cflags");
6919        apply ();
6920      }
6921  }
6922
6923  /**
6924   *   use_cppflags
6925   */
6926  void fill_for_use_cppflags ()
6927  {
6928    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6929
6930    if (Uses.size () == 0) return;
6931
6932    if (!Symbol::is_selected ("use_cppflags"))
6933      {
6934        Use::fill_macro_all (buffer, "cppflags");
6935        apply ();
6936      }
6937  }
6938
6939  /**
6940   *   use_pp_cppflags
6941   */
6942  void fill_for_use_pp_cppflags ()
6943  {
6944    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6945
6946    if (Uses.size () == 0) return;
6947
6948    if (!Symbol::is_selected ("use_pp_cppflags"))
6949      {
6950        Use::fill_macro_all (buffer, "pp_cppflags");
6951        apply ();
6952      }
6953  }
6954
6955  /**
6956   *   use_fflags
6957   */
6958  void fill_for_use_fflags ()
6959  {
6960    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6961
6962    if (Uses.size () == 0) return;
6963
6964    if (!Symbol::is_selected ("use_fflags"))
6965      {
6966        Use::fill_macro_all (buffer, "fflags");
6967        apply ();
6968      }
6969  }
6970
6971  /**
6972   *   use_pp_fflags
6973   */
6974  void fill_for_use_pp_fflags ()
6975  {
6976    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6977
6978    if (Uses.size () == 0) return;
6979
6980    if (!Symbol::is_selected ("use_pp_fflags"))
6981      {
6982        Use::fill_macro_all (buffer, "pp_fflags");
6983        apply ();
6984      }
6985  }
6986
6987  /**
6988   *   use_linkopts
6989   */
6990  void fill_for_use_linkopts ()
6991  {
6992    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6993
6994    if (Uses.size () == 0) return;
6995
6996    if (!Symbol::is_selected ("use_linkopts"))
6997      {
6998        Use::fill_macro_all (buffer, "linkopts");
6999        apply ();
7000      }
7001  }
7002
7003  /**
7004   *   use_libraries
7005   */
7006  void fill_for_use_libraries ()
7007  {
7008    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7009
7010    if (Uses.size () == 0) return;
7011
7012    if (!Symbol::is_selected ("use_libraries"))
7013      {
7014        buffer  = "macro use_libraries \"";
7015
7016        for (int number = 0; number < Uses.size (); number++)
7017          {
7018            Use* use = Uses[number];
7019           
7020            if (use->discarded) continue;
7021            if (use->m_hidden) continue;
7022           
7023            Package* p = use->get_package ();
7024            if (p->is_cmt ()) continue;
7025
7026            use->fill_macro (buffer, "libraries");
7027          }
7028       
7029        buffer += "\"";
7030       
7031        apply ();
7032      }
7033  }
7034
7035  /**
7036   *   includes
7037   */
7038  void fill_for_includes ()
7039  {
7040    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7041
7042    if (Uses.size () == 0) return;
7043
7044    if (!Symbol::is_selected ("includes"))
7045      {
7046        buffer = "macro_append includes \' ";
7047
7048        Use& use = Use::current();
7049
7050        if (use.include_path == "")
7051          {
7052            buffer += "$(ppcmd)\"$(srcdir)\" ";
7053          }
7054        else if (use.include_path != "none")
7055          {
7056            buffer += "$(ppcmd)\"";
7057            buffer += use.include_path;
7058            buffer += "\" ";
7059          }
7060
7061        for (int include_number = 0;
7062             include_number < use.includes.size ();
7063             include_number++)
7064          {
7065            Include& incl = use.includes[include_number];
7066
7067            if (incl.name == "") continue;
7068
7069            buffer += "$(ppcmd)\"";
7070            buffer += incl.name;
7071            buffer += "\" ";
7072          }
7073       
7074        buffer += "$(use_includes)\'";
7075       
7076        apply ();
7077      }
7078  }
7079
7080  /**
7081   *   fincludes
7082   */
7083  void fill_for_fincludes ()
7084  {
7085    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7086
7087    if (Uses.size () == 0) return;
7088
7089    if (!Symbol::is_selected ("fincludes"))
7090      {
7091        buffer = "macro_append fincludes \" $(includes)\"";
7092        apply ();
7093      }
7094  }
7095
7096  /**
7097   *  Macros specific to constituents.
7098   *  This includes the compiler flags
7099   *  and fills in these macros from uses packages. This takes care
7100   *  of -no_auto_imports and -import= directives
7101   *
7102   *    <constituent>_use_linkopts
7103   *    <prefix>_<constituent>_cflags
7104   *    <prefix>_<constituent>_pp_cflags
7105   *    <prefix>_<constituent>_cppflags
7106   *    <prefix>_<constituent>_pp_cppflags
7107   *    <prefix>_<constituent>_fflags
7108   *    <prefix>_<constituent>_pp_fflags
7109   *    <constituent>linkopts
7110   *    <constituent>_GUID
7111   *
7112   */
7113  void fill_for_all_constituents ()
7114  {
7115    /// First, finish the parsing of constituent parameters.
7116    if (Cmt::get_debug ())
7117      {
7118        cout << "fill_for_all_constituents>" << endl;
7119      }
7120
7121    Constituent::parse_all ();
7122
7123    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7124   
7125    const Constituent::ConstituentVector& constituents =
7126      Constituent::constituents ();
7127
7128 
7129    // Prepare the auto_imports states in a vector
7130    cmt_vector<bool> base_auto_imports_states;
7131
7132    base_auto_imports_states.resize (Uses.size ());
7133
7134    int number;
7135   
7136    for (number = 0; number < Uses.size (); number++)
7137      {
7138        Use* use = Uses[number];
7139        base_auto_imports_states[number] = (use->auto_imports != Off);
7140      }
7141   
7142    // Now scan all constituents
7143       
7144    for (number = 0; number < constituents.size (); number++)
7145      {
7146        const Constituent& constituent = constituents[number];
7147       
7148        if (Cmt::get_debug ())
7149          {
7150            cout << "Checking " << constituent.name  << " against imports requests" << endl;
7151          }
7152        Use::UsePtrVector imports;
7153        int i;
7154       
7155        /**
7156         *  Problem for imports in constituents.
7157         *
7158         *     1) use_xxx has holes due to the corresponding
7159         *         -no_auto_imports options attached to some
7160         *        use statements (including the transitive ones)
7161         *
7162         *     2) the -import=yyy options provided to a given constituent
7163         *        should restore the appropriate holes as well as
7164         *        all transitive ones.
7165         *
7166         *     3) for use_linkopts, missing pieces must be filled at
7167         *        the right position. (for others, order is not relevant
7168         *        while transitive access is required for all)
7169         *
7170         */
7171       
7172        if (constituent.type == Document)
7173          { 
7174            continue;
7175          }
7176       
7177        if (constituent.imports.size () == 0) 
7178          {
7179            buffer = "macro_append ";
7180            buffer += constituent.name;
7181            buffer += "_use_linkopts ";
7182            buffer += " \" ";
7183           
7184            current_use->fill_macro (buffer, "linkopts");
7185           
7186            for (i = 0; i < Uses.size (); i++)
7187              {
7188                if (base_auto_imports_states[i])
7189                  {
7190                    Use* u = Uses[i];
7191                   
7192                    if (u->discarded) continue;
7193                    if (u->m_hidden) continue;
7194                   
7195                    Package* p = u->get_package ();
7196                    if (p->is_cmt ()) continue;
7197                   
7198                    u->fill_macro (buffer, "linkopts");
7199                  }
7200              }
7201            buffer += "\"";
7202            apply ();
7203           
7204            /*
7205              buffer = "macro_append ";
7206              buffer += constituent.name;
7207              buffer += "_use_linkopts ";
7208             
7209              buffer += " \" $(use_linkopts)\"";
7210              apply ();
7211            */
7212           
7213            continue;
7214          }
7215       
7216        // From here on, the constituent HAS import options.
7217       
7218        /**
7219         * Create a private copy of the state vector. This private copy
7220         * will be updated according to -import=xxx modifiers for the
7221         * current constituent.
7222         */
7223        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
7224       
7225        for (i = 0; i < constituent.imports.size (); i++)
7226          {
7227            const cmt_string& import = constituent.imports[i];
7228           
7229            //
7230            // Resolve the imported uses
7231            //
7232           
7233            int use_index = Use::find_index (import, "", "");
7234           
7235            if (use_index >= 0)
7236              {
7237                Use* u = Uses[use_index];
7238               
7239                if (u->discarded) continue;
7240                if (u->m_hidden) continue;
7241               
7242                if (Cmt::get_debug ())
7243                  {
7244                    cout << constituent.name  << " needs imports " << import << " "
7245                         << use_index << " " 
7246                         << u->get_package()->get_name() << " "
7247                         << " u->auto_imports=" << u->auto_imports
7248                         << " Off=" << Off
7249                         << " On=" << On
7250                         << endl;
7251                  }
7252               
7253                Package* p = u->get_package ();
7254                if (p->is_cmt ()) continue;
7255               
7256                if (u->auto_imports != Off) continue;
7257               
7258                Use::set_auto_imports_state (use_index, auto_imports_states);
7259              }
7260          }
7261       
7262        if (Cmt::get_debug ())
7263          {
7264            cout << constituent.name  << " has imports " << endl;
7265          }
7266       
7267       
7268        /**
7269         *   Find all newly exposed packages and precompute this list inside
7270         *   a vector.
7271         */
7272        for (i = 0; i < base_auto_imports_states.size (); i++)
7273          {
7274            if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
7275           
7276            Use* u = Uses[i];
7277           
7278            if (u->discarded) continue;
7279            if (u->m_hidden)  continue;
7280           
7281            Package* p = u->get_package ();
7282            if (p->is_cmt ()) continue;
7283           
7284            if (Cmt::get_debug ())
7285              {
7286                cout << constituent.name  << " has import " << p->get_name () << endl;
7287              }
7288           
7289            imports.push_back (u);
7290          }
7291       
7292        if (imports.size () == 0) continue;
7293       
7294        cmt_string prefix;
7295       
7296        //
7297        // Documents are not considered
7298        //
7299        switch (constituent.type)
7300          {
7301          case Application:
7302            prefix = "app_";
7303            break;
7304          case Library:
7305            prefix = "lib_";
7306            break;
7307          }
7308       
7309        buffer = "macro_append ";
7310        buffer += prefix;
7311        buffer += constituent.name;
7312        buffer += "_cflags ";
7313        buffer += " \' ";
7314        for (i = 0; i < imports.size (); i++)
7315          {
7316            Use* u = imports[i];
7317           
7318            u->fill_includes_macro (buffer);
7319            u->fill_macro (buffer, "cflags");
7320          }
7321        buffer += "\'";
7322        apply ();
7323       
7324        buffer = "macro_append ";
7325        buffer += prefix;
7326        buffer += constituent.name;
7327        buffer += "_pp_cflags ";
7328        buffer += " \" ";
7329        for (i = 0; i < imports.size (); i++)
7330          {
7331            Use* u = imports[i];
7332           
7333            u->fill_macro (buffer, "pp_cflags");
7334          }
7335        buffer += "\"";
7336        apply ();
7337       
7338        buffer = "macro_append ";
7339        buffer += prefix;
7340        buffer += constituent.name;
7341        buffer += "_cppflags ";
7342        buffer += " \' ";
7343        for (i = 0; i < imports.size (); i++)
7344          {
7345            Use* u = imports[i];
7346           
7347            u->fill_includes_macro (buffer);
7348            u->fill_macro (buffer, "cppflags");
7349          }
7350        buffer += "\'";
7351        apply ();
7352       
7353        buffer = "macro_append ";
7354        buffer += prefix;
7355        buffer += constituent.name;
7356        buffer += "_pp_cppflags ";
7357        buffer += " \" ";
7358        for (i = 0; i < imports.size (); i++)
7359          {
7360            Use* u = imports[i];
7361           
7362            u->fill_macro (buffer, "pp_cppflags");
7363          }
7364        buffer += "\"";
7365        apply ();
7366       
7367        buffer = "macro_append ";
7368        buffer += prefix;
7369        buffer += constituent.name;
7370        buffer += "_fflags ";
7371        buffer += " \' ";
7372        for (i = 0; i < imports.size (); i++)
7373          {
7374            Use* u = imports[i];
7375           
7376            u->fill_includes_macro (buffer);
7377            u->fill_macro (buffer, "fflags");
7378          }
7379        buffer += "\'";
7380        apply ();
7381       
7382        buffer = "macro_append ";
7383        buffer += prefix;
7384        buffer += constituent.name;
7385        buffer += "_pp_fflags ";
7386        buffer += " \" ";
7387        for (i = 0; i < imports.size (); i++)
7388          {
7389            Use* u = imports[i];
7390           
7391            u->fill_macro (buffer, "pp_fflags");
7392          }
7393        buffer += "\"";
7394        apply ();
7395       
7396        /**
7397         *  Setting ${CONSTITUENT}linkopts is a temporary solution
7398         *  until the backward compatibility solution for a proper
7399         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
7400         *  is acheived.
7401         *
7402         */
7403        buffer = "macro_append ";
7404        buffer += constituent.name;
7405        buffer += "linkopts ";
7406        buffer += " \" ";
7407        for (i = 0; i < imports.size (); i++)
7408          {
7409            Use* u = imports[i];
7410           
7411            u->fill_macro (buffer, "linkopts");
7412          }
7413        buffer += "\"";
7414        apply ();
7415       
7416        /**
7417         *  Only for linkopts we take care of the order. This means
7418         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
7419         *
7420         *  (see the application fragments)
7421         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
7422         */
7423        buffer = "macro_append ";
7424        buffer += constituent.name;
7425        buffer += "_use_linkopts ";
7426        buffer += " \" ";
7427       
7428        current_use->fill_macro (buffer, "linkopts");
7429       
7430        for (i = 0; i < Uses.size (); i++)
7431          {
7432            if (auto_imports_states[i])
7433              {
7434                Use* u = Uses[i];
7435               
7436                if (u->discarded) continue;
7437                if (u->m_hidden) continue;
7438               
7439                Package* p = u->get_package ();
7440                if (p->is_cmt ()) continue;
7441               
7442                u->fill_macro (buffer, "linkopts");
7443              }
7444          }
7445        buffer += "\"";
7446        apply ();
7447       
7448        //==== GLAST addition for vs.net ==========
7449        buffer = "macro ";
7450        buffer += constituent.name;
7451        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
7452        apply ();
7453      }
7454  }
7455 
7456  /**
7457   *   Macros implied or required to manage constituents.
7458   */
7459  void fill_for_constituent_macros ()
7460  {
7461    int number;
7462    cmt_string temp;
7463
7464    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
7465 
7466    if (!Symbol::is_selected ("constituents"))
7467      {
7468        temp = "macro_append constituents \" ";
7469       
7470        for (number = 0; number < constituents.size (); number++)
7471          {
7472            const Constituent& constituent = constituents[number];
7473           
7474            if (constituent.group == 0)
7475              {
7476                temp += constituent.name;
7477                temp += " ";
7478              }
7479          }
7480       
7481        temp += "\"";
7482       
7483        SyntaxParser::parse_requirements_line (temp, current_use);
7484      }
7485   
7486    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
7487                                           current_use);
7488   
7489    if (!Symbol::is_selected ("constituentsclean"))
7490      {
7491        temp = "macro_append constituentsclean \" ";
7492       
7493        for (number = constituents.size () - 1; number >= 0 ; number--)
7494          {
7495            const Constituent& constituent = constituents[number];
7496           
7497            if (constituent.group == 0)
7498              {
7499                temp += constituent.name;
7500                temp += "clean ";
7501              }
7502          }
7503       
7504        temp += "\"";
7505       
7506        SyntaxParser::parse_requirements_line (temp, current_use);
7507      }
7508   
7509    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
7510                                           current_use);
7511   
7512    const Group::GroupVector& groups = Group::groups ();
7513   
7514    for (number = 0; number < groups.size (); number++)
7515      {
7516        const Group& group = groups[number];
7517       
7518        temp = "macro_append ";
7519        temp += group.name ();
7520        temp += "_constituents \" ";
7521       
7522        int i;
7523       
7524        for (i = 0; i < constituents.size (); i++)
7525          {
7526            const Constituent& constituent = constituents[i];
7527           
7528            if ((constituent.group != 0) && 
7529                (group.name () == constituent.group->name ()))
7530              {
7531                temp += constituent.name;
7532                temp += " ";
7533              }
7534          }
7535       
7536        temp += "\"";
7537       
7538        SyntaxParser::parse_requirements_line (temp, current_use);
7539       
7540        temp = "macro_append ";
7541        temp += group.name ();
7542        temp += "_constituentsclean \" ";
7543       
7544        for (i = constituents.size () - 1; i >= 0 ; i--)
7545          {
7546            const Constituent& constituent = constituents[i];
7547           
7548            if ((constituent.group != 0) && 
7549                (group.name () == constituent.group->name ()))
7550              {
7551                temp += constituent.name;
7552                temp += "clean ";
7553              }
7554          }
7555       
7556        temp += "\"";
7557       
7558        SyntaxParser::parse_requirements_line (temp, current_use);
7559      }
7560  }
7561
7562  /**
7563   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
7564   */
7565  void fill_for_install_area ()
7566  {
7567    CmtPathPattern::apply_all ();
7568
7569    const Use& current_use = Use::current ();
7570
7571    if (current_use.get_strategy ("InstallArea"))
7572      {
7573        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
7574       
7575        ia_mgr.setup ();
7576      }
7577  }
7578
7579  /**
7580   * Macros to be defined once current_package is known
7581   * and even before reading its requirements file.
7582   */
7583  void fill_for_current_package (const cmt_string& current_dir)
7584  {
7585    fill_for_tag ();
7586    fill_for_package (current_dir);
7587  }
7588
7589private:
7590  cmt_string fs;
7591  cmt_string buffer;
7592  CmtSystem::cmt_string_vector vb;
7593  cmt_string pwd;
7594  Use* current_use;
7595  cmt_string current_tag; 
7596  cmt_string current_package; 
7597  cmt_string current_version; 
7598  cmt_string current_prefix; 
7599  CmtDirStyle current_style;
7600};
7601
7602//----------------------------------------------------------
7603void Cmt::set_current_access (AccessMode mode)
7604{
7605  Me.m_current_access = mode;
7606}
7607
7608//----------------------------------------------------------
7609void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
7610{
7611  Me.m_scope_filtering_mode = mode;
7612}
7613
7614//----------------------------------------------------------
7615void Cmt::set_standard_macros ()
7616{
7617  if (Me.m_standard_macros_done) return;
7618
7619  Me.m_standard_macros_done = true;
7620
7621  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7622  Use& current_use = Use::current ();
7623
7624  cmt_string fs = CmtSystem::file_separator ();
7625
7626  cmt_string pwd = CmtSystem::pwd ();
7627
7628  /**
7629   * This is already done in
7630   void Cmt::configure_current_package ()
7631
7632  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
7633  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
7634  else Me.m_current_style = none_style;
7635
7636  {
7637    cmt_string v;
7638    CmtSystem::dirname (pwd, v);
7639    CmtSystem::basename (v, v);
7640    if (!CmtSystem::is_version_directory (v))
7641      {
7642        Me.m_current_style = no_version_style;
7643      }
7644  }
7645  */
7646
7647  // Prepare computation of the best form for relative path from current directory
7648  // to package directories.
7649  CmtSystem::cmt_string_vector vb;
7650  CmtSystem::split (pwd, fs, vb);
7651
7652
7653  /**
7654   *    TAG management
7655   */
7656
7657  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
7658
7659  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
7660
7661  if (Me.m_current_tag != "")
7662    {
7663      // this is when some -tag= argument was used.
7664      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
7665    }
7666  else if (Symbol::is_selected ("CMTCONFIG"))
7667    {
7668      // This is when CMTCONFIG has been set from some requirements file
7669      Symbol* macro = Symbol::find ("CMTCONFIG");
7670      if (macro != 0)
7671        {
7672          Me.m_current_tag = macro->build_macro_value ();
7673          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
7674        }
7675    }
7676  else
7677    {
7678      // this is when no -tag= argument was used.
7679      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
7680      if (current_use.get_package_name () == "CMT")
7681        {
7682          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
7683        }
7684      else
7685        {
7686          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
7687        }
7688
7689      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
7690    }
7691
7692  if (Me.m_debug)
7693    {
7694      cout << "set_standard_macro3>" << endl;
7695    }
7696
7697  StandardMacroBuilder builder (Me.m_current_tag,
7698                                Me.m_current_package,
7699                                Me.m_current_version,
7700                                Me.m_current_prefix,
7701                                Me.m_current_style);
7702
7703
7704  builder.fill_for_current_package (Me.m_current_dir);
7705
7706  builder.fill_for_branches ();
7707  builder.fill_for_project ();
7708
7709  builder.fill_for_install_area ();
7710
7711  builder.fill_for_use_requirements ();
7712  builder.fill_for_use_includes ();
7713  builder.fill_for_use_fincludes ();
7714  builder.fill_for_use_stamps ();
7715  builder.fill_for_use_cflags ();
7716  builder.fill_for_use_pp_cflags ();
7717  builder.fill_for_use_cppflags ();
7718  builder.fill_for_use_pp_cppflags ();
7719  builder.fill_for_use_fflags ();
7720  builder.fill_for_use_pp_fflags ();
7721  builder.fill_for_use_linkopts ();
7722  builder.fill_for_use_libraries ();
7723  builder.fill_for_includes ();
7724  builder.fill_for_fincludes ();
7725  builder.fill_for_all_constituents ();
7726  builder.fill_for_constituent_macros ();
7727}
7728
7729void Cmt::set_all_sets_done ()
7730{
7731  Me.m_all_sets_done = true;
7732}
7733
7734void Cmt::reset_all_sets_done ()
7735{
7736  Me.m_all_sets_done = false;
7737}
7738
7739//----------------------------------------------------------
7740void Cmt::use_cmt ()
7741{
7742  UseRef use;
7743  bool recursive_copy = Me.m_recursive;
7744  bool debug_copy = Me.m_debug;
7745
7746  if (Me.m_default_path.size () <= 0) return;
7747  if (Me.m_current_package == "CMT") return;
7748
7749  Me.m_recursive = true;
7750  //Me.m_debug = false;
7751  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
7752  Me.m_recursive = recursive_copy;
7753  Me.m_debug = debug_copy;
7754}
7755
7756//----------------------------------------------------------
7757void Cmt::use_home_requirements ()
7758{
7759  use_special_requirements (Me.m_cmt_home, 
7760                            CmtSystem::get_home_package (), 
7761                            "requirements");
7762}
7763
7764//----------------------------------------------------------
7765void Cmt::use_user_context_requirements ()
7766{
7767  use_special_requirements (Me.m_cmt_user_context, 
7768                            CmtSystem::get_user_context_package (), 
7769                            "requirements");
7770}
7771
7772//----------------------------------------------------------
7773void Cmt::use_special_requirements (const cmt_string& path, 
7774                                    const cmt_string& name, 
7775                                    const cmt_string& file_name)
7776{
7777  if (path == "") 
7778    {
7779      return;
7780    }
7781
7782  UseRef use;
7783  bool recursive_copy = Me.m_recursive;
7784
7785  if (Me.m_default_path.size () <= 0) return;
7786  if (Me.m_current_package == "CMT") return;
7787
7788  Me.m_recursive = true;
7789
7790  use = Use::add (path, name, "v0", "", "", "", 0);
7791
7792  cmt_string f = Me.m_cmt_user_context;
7793  f += CmtSystem::file_separator ();
7794  f += file_name;
7795  SyntaxParser::parse_requirements (f, use);
7796
7797  Me.m_recursive = recursive_copy;
7798}
7799
7800//-------------------------------------------------
7801void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
7802                            const cmt_string& separator,
7803                            cmt_string& result)
7804{
7805  result.erase (0);
7806
7807  for (int i = 0; i < v.size (); i++)
7808    {
7809      const cmt_string& s = v[i];
7810      if (s == "") continue;
7811
7812      if (i > 0) result += separator;
7813      result += v[i];
7814    }
7815}
7816
7817//-------------------------------------------------
7818cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
7819{
7820  cmt_string result;
7821
7822  vector_to_string (v, " ", result);
7823
7824  return (result);
7825}
Note: See TracBrowser for help on using the repository browser.