source: CMT/v1r18p20050501/source/cmt_parser.cxx

Last change on this file was 42, checked in by arnault, 19 years ago

Preparing support for projects in CVS - See CL 270

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