source: CMT/v1r18p20060301/source/cmt_parser.cxx @ 615

Last change on this file since 615 was 144, checked in by arnault, 18 years ago

Various fixes and message cleanups see CL 294 and 295

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