source: CMT/v1r18p20050401/source/cmt_parser.cxx

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

create project improvements - see CL261

  • Property svn:eol-style set to native
File size: 180.7 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_cvstags (const ArgParser& ap)
2471{
2472  Cvs::tags (ap.arguments);
2473}
2474
2475//----------------------------------------------------------
2476void Cmt::do_do (const ArgParser& ap)
2477{
2478  if (ap.arguments.size () > 0) 
2479    {
2480      set_standard_macros ();
2481      Cmt::reset_all_sets_done ();
2482      Symbol::all_set ();
2483      Generator::build_default_makefile ();
2484
2485      Symbol* symbol = Symbol::find (ap.arguments[0]);
2486
2487      if (symbol == 0)
2488        {
2489          Me.m_action = action_show_action_names;
2490          /*
2491          if (!Me.m_quiet)
2492            {
2493              cerr << "Existing actions:" << endl;
2494              print_symbol_names (ap.mode);
2495            }
2496          */
2497          CmtError::set (CmtError::unknown_command, ap.arguments[0]);
2498          return;
2499        }
2500
2501      /*
2502        We convert extra arguments into the standard macro cmt_args
2503      */
2504
2505      cmt_string args;
2506
2507      for (int i = 1; i < ap.arguments.size (); i++)
2508        {
2509          cmt_string s = ap.arguments[i];
2510          if (i > 1) args += " ";
2511          args += s;
2512        }
2513
2514      cmt_string r = "macro cmt_args \"";
2515      r += args;
2516      r += "\"";
2517
2518      Use* current_use = &(Use::current ());
2519     
2520      SyntaxParser::parse_requirements_line (r, current_use);
2521
2522      cmt_string cmd = symbol->build_macro_value ();
2523      Symbol::expand (cmd);
2524
2525      cout << "Execute action " << ap.arguments[0] << " => " << cmd << endl;
2526
2527      CmtSystem::execute (cmd);
2528    }
2529}
2530
2531//----------------------------------------------------------
2532void Cmt::do_expand_model (const ArgParser& ap)
2533{
2534  set_standard_macros ();
2535
2536  if ((ap.arguments[0] == "-strict") && (ap.arguments.size () > 1))
2537    {
2538      CmtModel::strict_expand (ap.arguments[1]);
2539    }
2540  else if ((ap.arguments[0] == "-test") && (ap.arguments.size () > 2))
2541    {
2542      CmtModel::test_regexp (ap.arguments[1], ap.arguments[2]);
2543    }
2544  else if (ap.arguments.size () > 0)
2545    {
2546      CmtModel::expand (ap.arguments[0]);
2547    }
2548}
2549
2550/**
2551 *  Handle free filtering of text files containing $(xxx) or ${xxx} patterns
2552 *
2553 *  Substitution is performed against CMT macros and environment variables.
2554 *
2555 *  Arguments:
2556 *
2557 *    cmt filter input-file-name output-file-name
2558 *
2559 */
2560void Cmt::do_filter (const ArgParser& ap)
2561{
2562  if (ap.arguments.size () < 2) return;
2563
2564  cmt_string& input = ap.arguments[0];
2565  cmt_string& output = ap.arguments[1];
2566
2567  if (!CmtSystem::test_file (input))
2568    {
2569      cerr << "#CMT> File " << input << " not found" << endl;
2570      return;
2571    }
2572
2573  cmt_string text;
2574
2575  text.read (input);
2576
2577  set_standard_macros ();
2578
2579  Symbol::expand (text);
2580
2581  FILE* file = fopen (output, "wb");
2582  if (file == NULL)
2583    {
2584      cerr << "#CMT> Cannot write filtered file " << output << endl;
2585    }
2586  else
2587    {
2588      text.write (file);
2589      fclose (file);
2590    }
2591}
2592
2593//----------------------------------------------------------
2594void Cmt::do_help (const ArgParser& ap)
2595{
2596  //cerr << "ap.help_action=" << ap.help_action << " Me.m_action=" << Me.m_action << endl;
2597  if (Me.m_action == action_none)
2598    {
2599      CommandHelp::show_all ();
2600    }
2601  else
2602    {
2603      CommandHelp::show (Me.m_action);
2604    }
2605}
2606
2607//----------------------------------------------------------
2608void Cmt::do_lock (const ArgParser& ap)
2609{
2610  const cmt_string& package = Me.m_current_package;
2611  const cmt_string& version = Me.m_current_version;
2612  const cmt_string& path    = Me.m_current_path;
2613
2614  //(unsused) Use& use = Use::current();
2615
2616  cout << "try to lock package " << package << " in " << CmtSystem::pwd () << endl;
2617
2618  set_standard_macros ();
2619
2620  CmtLock::status status = CmtLock::lock ();
2621}
2622
2623//----------------------------------------------------------
2624void Cmt::do_remove (const ArgParser& ap)
2625{
2626  const cmt_string& package = Me.m_current_package;
2627  const cmt_string& version = Me.m_current_version;
2628  const cmt_string& path    = Me.m_current_path;
2629
2630    //Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2631
2632  if (Me.m_current_package == "CMT") return;
2633  if (Me.m_current_package == "methods") return;
2634
2635  cmt_string the_path;
2636
2637  //the_path = Me.m_default_path;
2638  the_path = CmtSystem::pwd ();
2639
2640  if (path != "")
2641    {
2642      if (!CmtSystem::absolute_path (path))
2643        {
2644          // path is just a suffix
2645          the_path += CmtSystem::file_separator ();
2646          the_path += path;
2647        }
2648      else // absolute path
2649        {
2650          the_path = path;
2651        }
2652    }
2653
2654  CmtSystem::compress_path (the_path);
2655
2656  cout << "------------------------------------------" << endl;
2657  cout << "Removing package " << package <<
2658    " version " << version << "." << endl;
2659  cout << "CMT version " << Me.m_cmt_version << "." << endl;
2660  cout << "Root set to " << the_path << "." << endl;
2661  cout << "System is " << Me.m_cmt_config << endl;
2662  cout << "------------------------------------------" << endl;
2663
2664  the_path += CmtSystem::file_separator ();
2665  the_path += package;
2666
2667  if (!CmtSystem::cd (the_path))
2668    {
2669      cout << "Path " << the_path << " not reachable" << endl;
2670      return;
2671    }
2672
2673  if (CmtSystem::test_directory (version))
2674    {
2675      if (CmtSystem::remove_directory (version))
2676        {
2677          cout << "Version " << version << " has been removed from " << the_path << endl;
2678          CmtSystem::cmt_string_vector contents;
2679          CmtSystem::scan_dir (".", contents);
2680          if (contents.size () == 0)
2681            {
2682              CmtSystem::cd ("..");
2683              if (CmtSystem::remove_directory (package))
2684                {
2685                  cout << "Package " << package << " has no more versions. Thus it has been removed."<< endl;
2686                }
2687            }
2688        }
2689      else
2690        {
2691          cout << "Impossible to remove version " << version << " from " << the_path << endl;
2692        }
2693    }
2694  else if (CmtSystem::test_directory ("cmt"))
2695    {
2696      CmtSystem::cd ("cmt");
2697
2698      cmt_string v;
2699
2700      v.read ("version.cmt");
2701      if (v == version)
2702        {
2703          CmtSystem::cd ("..");
2704          if (!CmtSystem::remove_directory ("cmt"))
2705            {
2706              cout << "Unstructured version " << version
2707                   << " has been removed from " << the_path << endl;
2708            }
2709          else
2710            {
2711              cout << "Impossible to remove unstructured version " << version
2712                   << " from " << the_path << endl;
2713            }
2714        }
2715      else
2716        {
2717          cout << "Version " << version << " not found" << endl;
2718        }
2719    }
2720  else
2721    {
2722      cout << "Version " << version << " not found" << endl;
2723    }
2724}
2725
2726//----------------------------------------------------------
2727void Cmt::do_remove_library_links (const ArgParser& ap)
2728{
2729  if (CmtLock::check () == CmtLock::locked_by_another_user)
2730    {
2731      CmtError::set (CmtError::conflicting_lock, "remove_library_links>");
2732      return;
2733    }
2734
2735  set_standard_macros ();
2736
2737  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2738  Use& current_use = Use::current ();
2739  int i;
2740  cmt_string shlibsuffix;
2741  cmt_string symunlink;
2742
2743  {
2744    Symbol* macro = Symbol::find ("shlibsuffix");
2745    if (macro == 0) return;
2746    shlibsuffix = macro->build_macro_value ();
2747    Symbol::expand (shlibsuffix);
2748  }
2749
2750  {
2751    Symbol* macro = Symbol::find ("symunlink");
2752    if (macro == 0) return;
2753    symunlink = macro->build_macro_value ();
2754    Symbol::expand (symunlink);
2755  }
2756
2757  for (i = 0; i < Uses.size (); i++)
2758    {
2759      Use* use = Uses[i];
2760
2761      if (use->discarded) continue;
2762
2763      if (!use->located ())
2764        {
2765          if (!Me.m_quiet)
2766            {
2767              cerr << "#CMT> package " << use->get_package_name () <<
2768                  " " << use->version << " " << use->path << 
2769                  " not found" <<
2770                  endl;
2771            }
2772        }
2773      else
2774        {
2775          if (use->get_package_name () == "CMT") continue;
2776          if (use->get_package_name () == current_use.get_package_name ()) continue;
2777
2778          cmt_string s;
2779
2780          s = use->get_package_name ();
2781          s += "_libraries";
2782
2783          Symbol* libraries_macro = Symbol::find (s);
2784
2785          if (libraries_macro == 0) continue;
2786
2787          cmt_string libraries = libraries_macro->build_macro_value ();
2788          Symbol::expand (libraries);
2789
2790          static CmtSystem::cmt_string_vector values;
2791
2792          CmtSystem::split (libraries, " \t", values);
2793
2794          for (int j = 0; j < values.size (); j++)
2795            {
2796              const cmt_string& library = values[j];
2797
2798              static cmt_string libname;
2799              static cmt_string name;
2800
2801              // Is it a simple name or a complete path?
2802
2803              libname = library;
2804              Symbol::expand (libname);
2805
2806              if (CmtSystem::absolute_path (libname))
2807                {
2808                  /**
2809                   *   We assume here that "library" contains a complete path.
2810                   *   (including the complete syntax libxxx.so)
2811                   */
2812
2813                  cmt_string suffix;
2814                  CmtSystem::basename (library, name);
2815                }
2816              else
2817                {
2818                  /**
2819                   *   Here we expect that only the base name of the library
2820                   *   is given : ie it should not contain the "lib" prefix,
2821                   *   nor the suffix .so, nor any path prefix.
2822                   *    This of course should generally correspond to a constituent name.
2823                   */
2824
2825                  name = "lib";
2826                  name += libname;
2827                  name += ".";
2828                  name += shlibsuffix;
2829                }
2830
2831              Symbol::expand (libname);
2832
2833              if (get_strategy ("InstallArea"))
2834                {
2835                  const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
2836
2837                  //cout << "#IA4>" << endl;
2838
2839                  cmt_string s1 = ia_mgr.get_installarea ();
2840
2841                  {
2842                    Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
2843                    if (symbol != 0)
2844                      {
2845                        s1 = symbol->build_macro_value ();
2846                        Symbol::expand (s1);
2847                      }
2848                  }
2849                 
2850                  cmt_string s2;
2851
2852                  {
2853                    Symbol* macro = Symbol::find ("tag");
2854                    if (macro != 0)
2855                      {
2856                        s2 = macro->build_macro_value ();
2857                        Symbol::expand (s2);
2858                      }
2859                  }
2860
2861                    // Now deleting the reference file
2862
2863                  s = symunlink;
2864                  s += " ";
2865                  s += s1;
2866                  s += CmtSystem::file_separator ();
2867                  s += s2;
2868                  s += CmtSystem::file_separator ();
2869                  s += "lib";
2870                  s += CmtSystem::file_separator ();
2871                  s += name;
2872                  s += ".cmtref";
2873                  s += " ";
2874                  s += s1;
2875                  s += CmtSystem::file_separator ();
2876                  s += s2;
2877                  s += CmtSystem::file_separator ();
2878                  s += "lib";
2879                  s += CmtSystem::file_separator ();
2880                  s += name;
2881                }
2882              else
2883                {
2884                  s = symunlink;
2885                  s += " ../$(";
2886                  s += current_use.get_package_name ();
2887                  s += "_tag)/";
2888                  s += name;
2889                }
2890
2891              Symbol::expand (s);
2892
2893              if (!Me.m_quiet) cout << s << endl;
2894              int status = CmtSystem::execute (s);
2895
2896              if (status != 0)
2897                {
2898                  if (status != 2) CmtError::set (CmtError::execution_error, s);
2899
2900                  cerr << "#CMT> Cannot remove the symbolic link " << s << endl;
2901
2902                  break;
2903                }
2904            }
2905        }
2906    }
2907}
2908
2909//----------------------------------------------------------
2910void Cmt::do_run (const ArgParser& ap)
2911{
2912  if (ap.arguments.size () > 0) 
2913    {
2914      set_standard_macros ();
2915      Cmt::reset_all_sets_done ();
2916      Symbol::all_set ();
2917
2918      cmt_string cmd;
2919
2920      for (int i = 0; i < ap.arguments.size (); i++)
2921        {
2922          cmd += ap.arguments[i];
2923          cmd += " ";
2924        }
2925
2926      CmtSystem::execute (cmd);
2927    }
2928}
2929
2930//----------------------------------------------------------
2931void Cmt::do_run_sequence (const ArgParser& ap)
2932{
2933  if (ap.arguments.size () == 0) cerr << "#CMT> run_sequence: no sequence specified" << endl;
2934
2935  SequenceRunner runner;
2936
2937  cout << "# cmt run_sequence: sequence " << ap.arguments[0] << endl;
2938
2939  runner.run (ap.arguments[0]);
2940}
2941
2942//----------------------------------------------------------
2943void Cmt::do_set_version (const ArgParser& ap)
2944{
2945  if (ap.arguments.size () == 0) cerr << "#CMT> set version: no version specified" << endl;
2946
2947  const cmt_string& version = ap.arguments[0];
2948
2949  int v, r, p;
2950
2951  if (!CmtSystem::is_version_directory (version, v, r, p))
2952    {
2953      cerr << "#CMT> set version " << version << " is not a correct version syntax" << endl;
2954      return;
2955    }
2956
2957  if ((v == -1) || (r == -1) || (p == -1))
2958    {
2959      cerr << "#CMT> set version " << version
2960           << " You cannot use wild card to set a version" << endl;
2961      return;
2962    }
2963
2964  // We want to install the version.cmt file
2965
2966  // We first check we are in a cmt branch
2967  cmt_string h = CmtSystem::pwd ();
2968  cmt_string branch;
2969  CmtSystem::basename (h, branch);
2970
2971  if (branch != "cmt")
2972    {
2973      cerr << "#CMT> set version " << version << " must be applied in a cmt directory" 
2974           << endl;
2975      return;
2976    }
2977
2978  CmtSystem::dirname (h, h);
2979  CmtSystem::basename (h, branch);
2980
2981  if (branch == version)
2982    {
2983      cerr << "#CMT> set version " << version << " is already available as a version directory" 
2984           << endl;
2985      return;
2986    }
2987
2988  cout << "Writing version file : " << version << endl;
2989
2990  version.write ("version.cmt");
2991}
2992
2993//----------------------------------------------------------
2994void Cmt::do_set_versions (const ArgParser& ap)
2995{
2996  CmtSystem::cmt_string_vector args;
2997
2998  args = ap.arguments;
2999  {
3000    cmt_string& s = args.add ();
3001    s = "cmt";
3002  }
3003  {
3004    cmt_string& s = args.add ();
3005    s = "set";
3006  }
3007  {
3008    cmt_string& s = args.add ();
3009    s = "version";
3010  }
3011  {
3012    cmt_string& s = args.add ();
3013    s = "<version>";
3014  }
3015
3016  Me.m_action = action_broadcast;
3017
3018  do_broadcast (ap);
3019}
3020
3021//----------------------------------------------------------
3022void Cmt::do_setup (const ArgParser& ap)
3023{
3024
3025  do_check_configuration (ap);
3026
3027  print (ap.mode);
3028
3029    //
3030    //  Try a cleanup of the installation area
3031    //
3032  if (get_strategy ("InstallArea"))
3033    {
3034      CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
3035
3036      //cout << "#IA5>" << endl;
3037
3038      ia_mgr.setup ();
3039
3040      /*
3041      if (get_strategy ("SetupCleanup"))
3042        {
3043          const cmt_string& installarea = ia_mgr.get_installarea ();
3044
3045          if (installarea != "")
3046            {
3047              cmt_string q;
3048             
3049              switch (mode)
3050                {
3051                case Sh :
3052                case Csh :
3053                  q = "\'";
3054                  break;
3055                default :
3056                  break;
3057                }
3058             
3059              if (!Me.m_quiet)
3060                {
3061                  cout << "echo "  << q
3062                       << "# Doing cleanup in the installation area " << installarea
3063                       << q << endl;
3064                }
3065            }
3066
3067          ia_mgr.config ();
3068        }
3069      */
3070    }
3071}
3072
3073//----------------------------------------------------------
3074void Cmt::do_show_action (const ArgParser& ap)
3075{
3076  cmt_string target;
3077
3078  if (ap.arguments.size () > 0) target = ap.arguments[0];
3079
3080  Symbol* symbol;
3081
3082  set_standard_macros ();
3083
3084  symbol = Symbol::find (target);
3085
3086  if (symbol == 0) 
3087    {
3088      cmt_string t = " ";
3089      t += target;
3090      t += " is not defined ";
3091
3092      CmtError::set (CmtError::symbol_not_found, t);
3093
3094      return;
3095    }
3096  else
3097    {
3098      cmt_string t = target;
3099      t += " is a ";
3100
3101      if ((Me.m_action == action_show_action) ||
3102          (Me.m_action == action_show_action_value))
3103        {
3104          if (symbol->type != Symbol::SymbolAction)
3105            {
3106              if (symbol->type == Symbol::SymbolMacro)
3107                {
3108                  t += "macro";
3109                }
3110              else if (symbol->type == Symbol::SymbolSet)
3111                {
3112                  t += "set";
3113                }
3114              else if (symbol->type == Symbol::SymbolPath)
3115                {
3116                  t += "path";
3117                }
3118              else if (symbol->type == Symbol::SymbolAlias)
3119                {
3120                  t += "alias";
3121                }
3122
3123              CmtError::set (CmtError::warning, t);
3124            }
3125        }
3126    }
3127
3128  if (symbol->value_lists.size () < 1) return;
3129
3130  symbol->show_macro (ap.mode);
3131}
3132
3133//----------------------------------------------------------
3134void Cmt::do_show_action_names (const ArgParser& ap)
3135{
3136  if (ap.arguments.size () > 0)
3137    {
3138      const cmt_string& pattern = ap.arguments[0];
3139      print_symbol_names (ap.mode, pattern);
3140    }
3141  else
3142    {
3143      print_symbol_names (ap.mode);
3144    }
3145}
3146
3147//----------------------------------------------------------
3148void Cmt::do_show_action_value (const ArgParser& ap)
3149{
3150  do_show_macro (ap);
3151}
3152
3153//----------------------------------------------------------
3154void Cmt::do_show_actions (const ArgParser& ap)
3155{
3156  if (ap.arguments.size () > 0)
3157    {
3158      const cmt_string& pattern = ap.arguments[0];
3159      print_macros (ap.mode, pattern);
3160    }
3161  else
3162    {
3163      print_macros (ap.mode);
3164    }
3165}
3166
3167//----------------------------------------------------------
3168void Cmt::do_show_all_tags (const ArgParser& /*ap*/)
3169{
3170  Tag::TagPtrVector tags = Tag::tags ();
3171  int index;
3172
3173  set_standard_macros ();
3174
3175  for (index = 0; index < tags.size (); index++)
3176    {
3177      const Tag* tag = tags[index];
3178      if (tag != 0)
3179        {
3180          tag->show_definition (true);
3181        }
3182    }
3183}
3184
3185//----------------------------------------------------------
3186void Cmt::do_show_applied_patterns (const ArgParser& /*ap*/)
3187{
3188  Pattern::show_all_applied_patterns ();
3189}
3190
3191//----------------------------------------------------------
3192void Cmt::do_show_author (const ArgParser& /*ap*/)
3193{
3194  Use& use = Use::current();
3195
3196  cout << use.author << endl;
3197}
3198
3199//----------------------------------------------------------
3200void Cmt::do_show_branches (const ArgParser& ap)
3201{
3202  Branch::print_all (ap.mode);
3203}
3204
3205//----------------------------------------------------------
3206void Cmt::do_show_clients (const ArgParser& ap)
3207{
3208  cmt_string package;
3209  cmt_string version;
3210  cmt_string path_name;
3211
3212  if (ap.arguments.size () >= 1) package = ap.arguments[0];
3213  if (ap.arguments.size () >= 2) version = ap.arguments[1];
3214  if (ap.arguments.size () >= 3) path_name = ap.arguments[2];
3215
3216  PathScanner scanner;
3217  ClientCollector collector (package, version);
3218
3219  clear ();
3220  configure ();
3221
3222  cout << "# ----------- Clients of " << package <<
3223    " " << version <<
3224    " " << path_name <<
3225    endl;
3226
3227  if (path_name == "")
3228    {
3229      Project::scan_paths (scanner, collector);
3230    }
3231  else
3232    {
3233      scanner.scan_path (path_name, collector);
3234    }
3235  cout << "# ----------- " << collector.count () << " clients found." << endl;
3236}
3237
3238//----------------------------------------------------------
3239void Cmt::do_show_cmtpath_patterns (const ArgParser& /*ap*/)
3240{
3241  set_standard_macros ();
3242  CmtPathPattern::show_all ();
3243}
3244
3245//----------------------------------------------------------
3246void Cmt::do_show_constituent (const ArgParser& ap)
3247{
3248  if (ap.arguments.size () > 0) 
3249    {
3250      set_standard_macros ();
3251
3252      Constituent* c = Constituent::find (ap.arguments[0]);
3253      if (c != 0)
3254        {
3255          c->show ();
3256        }
3257    }
3258}
3259
3260//----------------------------------------------------------
3261void Cmt::do_show_constituent_names (const ArgParser& /*ap*/)
3262{
3263  set_standard_macros ();
3264  Constituent::show_names ();
3265}
3266
3267//----------------------------------------------------------
3268void Cmt::do_show_constituents (const ArgParser& /*ap*/)
3269{
3270  set_standard_macros ();
3271  Constituent::show_all ();
3272}
3273
3274//----------------------------------------------------------
3275void Cmt::do_show_cycles (const ArgParser& /*ap*/)
3276{
3277  set_standard_macros ();
3278  Use& use = Use::current();
3279
3280  use.show_cycles ();
3281}
3282
3283//----------------------------------------------------------
3284void Cmt::do_show_fragment (const ArgParser& ap)
3285{
3286  if (ap.arguments.size () > 0) Fragment::show (ap.arguments[0]);
3287}
3288
3289//----------------------------------------------------------
3290void Cmt::do_show_fragments (const ArgParser& /*ap*/)
3291{
3292  Fragment::show_all ();
3293}
3294
3295//----------------------------------------------------------
3296void Cmt::do_show_groups (const ArgParser& /*ap*/)
3297{
3298  Group::show_all ();
3299}
3300
3301//----------------------------------------------------------
3302void Cmt::do_show_include_dirs (const ArgParser& /*ap*/)
3303{
3304  cmt_string temp;
3305
3306  Use& use = Use::current();
3307
3308  set_standard_macros ();
3309
3310  if (use.include_path == "")
3311    {
3312      temp += "$(src) ";
3313    }
3314  else if (use.include_path != "none")
3315    {
3316      temp += use.include_path;
3317      temp += " ";
3318    }
3319
3320  for (int include_number = 0;
3321       include_number < use.includes.size ();
3322       include_number++)
3323    {
3324      Include& incl = use.includes[include_number];
3325     
3326      temp += incl.name;
3327      temp += " ";
3328    }
3329
3330  cout << temp << endl;
3331}
3332
3333//----------------------------------------------------------
3334void Cmt::do_show_language (const ArgParser& ap)
3335{
3336  if (ap.arguments.size () > 0) 
3337    {
3338      set_standard_macros ();
3339      Language::show (ap.arguments[0]);
3340    }
3341}
3342
3343//----------------------------------------------------------
3344void Cmt::do_show_languages (const ArgParser& /*ap*/)
3345{
3346  set_standard_macros ();
3347  Language::show_all ();
3348}
3349
3350//----------------------------------------------------------
3351void Cmt::do_show_macro (const ArgParser& ap)
3352{
3353  cmt_string target;
3354
3355  if (ap.arguments.size () > 0) target = ap.arguments[0];
3356
3357  Symbol* symbol;
3358
3359  set_standard_macros ();
3360
3361  symbol = Symbol::find (target);
3362
3363  if (symbol == 0) 
3364    {
3365      cmt_string t = " ";
3366      t += target;
3367      t += " is not defined ";
3368
3369      CmtError::set (CmtError::symbol_not_found, t);
3370
3371      return;
3372    }
3373  else
3374    {
3375      cmt_string t = target;
3376      t += " is a ";
3377
3378      if ((Me.m_action == action_show_macro) ||
3379          (Me.m_action == action_show_macro_value))
3380        {
3381          if (symbol->type != Symbol::SymbolMacro)
3382            {
3383              if (symbol->type == Symbol::SymbolAction)
3384                {
3385                  t += "action";
3386                }
3387              else if (symbol->type == Symbol::SymbolSet)
3388                {
3389                  t += "set";
3390                }
3391              else if (symbol->type == Symbol::SymbolPath)
3392                {
3393                  t += "path";
3394                }
3395              else if (symbol->type == Symbol::SymbolAlias)
3396                {
3397                  t += "alias";
3398                }
3399
3400              CmtError::set (CmtError::warning, t);
3401            }
3402        }
3403      else if ((Me.m_action == action_show_set) ||
3404               (Me.m_action == action_show_set_value))
3405        {
3406          if ((symbol->type != Symbol::SymbolSet) &&
3407              (symbol->type != Symbol::SymbolPath) &&
3408              (symbol->type != Symbol::SymbolAction) &&
3409              (symbol->type != Symbol::SymbolAlias))
3410            {
3411              t += "macro";
3412
3413              CmtError::set (CmtError::warning, t);
3414            }
3415        }
3416    }
3417
3418  if (symbol->value_lists.size () < 1) return;
3419
3420  symbol->show_macro (ap.mode);
3421}
3422
3423//----------------------------------------------------------
3424void Cmt::do_show_macro_names (const ArgParser& ap)
3425{
3426  if (ap.arguments.size () > 0)
3427    {
3428      const cmt_string& pattern = ap.arguments[0];
3429      print_symbol_names (ap.mode, pattern);
3430    }
3431  else
3432    {
3433      print_symbol_names (ap.mode);
3434    }
3435}
3436
3437//----------------------------------------------------------
3438void Cmt::do_show_macro_value (const ArgParser& ap)
3439{
3440  do_show_macro (ap);
3441}
3442
3443//----------------------------------------------------------
3444void Cmt::do_show_macros (const ArgParser& ap)
3445{
3446  if (ap.arguments.size () > 0)
3447    {
3448      const cmt_string& pattern = ap.arguments[0];
3449      print_macros (ap.mode, pattern);
3450    }
3451  else
3452    {
3453      print_macros (ap.mode);
3454    }
3455}
3456
3457//----------------------------------------------------------
3458void Cmt::do_show_manager (const ArgParser& /*ap*/)
3459{
3460  Use& use = Use::current();
3461
3462  cout << use.manager << endl;
3463}
3464
3465//----------------------------------------------------------
3466void Cmt::do_show_packages (const ArgParser& ap)
3467{
3468  cmt_string path_name;
3469
3470  if (ap.arguments.size () > 0) path_name = ap.arguments[0];
3471
3472  PathScanner scanner;
3473  PackageViewer viewer;
3474
3475  if (path_name == "")
3476    {
3477      Project::scan_paths (scanner, viewer);
3478    }
3479  else
3480    {
3481      scanner.scan_path (path_name, viewer);
3482    }
3483}
3484
3485//----------------------------------------------------------
3486void Cmt::do_show_path (const ArgParser& /*ap*/)
3487{
3488  Project::show_paths ();
3489}
3490
3491//----------------------------------------------------------
3492void Cmt::do_show_pattern (const ArgParser& ap)
3493{
3494  cmt_string name;
3495  if (ap.arguments.size () > 0) name = ap.arguments[0];
3496  Pattern::show (name);
3497}
3498
3499//----------------------------------------------------------
3500void Cmt::do_show_pattern_names (const ArgParser& /*ap*/)
3501{
3502  Pattern::show_all_names ();
3503}
3504
3505//----------------------------------------------------------
3506void Cmt::do_show_patterns (const ArgParser& /*ap*/)
3507{
3508  Pattern::show_all ();
3509}
3510
3511//----------------------------------------------------------
3512void Cmt::do_show_projects (const ArgParser& /*ap*/)
3513{
3514  Project::show_all ();
3515}
3516
3517//----------------------------------------------------------
3518void Cmt::do_show_pwd (const ArgParser& /*ap*/)
3519{
3520  cout << Me.m_current_dir << endl;
3521}
3522
3523//----------------------------------------------------------
3524void Cmt::do_show_setup (const ArgParser& ap)
3525{
3526  cout << "----------> uses" << endl;
3527  do_show_uses (ap);
3528
3529  cout << "----------> tags" << endl;
3530  do_show_tags (ap);
3531
3532  cout << "----------> CMTPATH" << endl;
3533  do_show_path (ap);
3534}
3535
3536//----------------------------------------------------------
3537void Cmt::do_show_set (const ArgParser& ap)
3538{
3539  do_show_macro (ap);
3540}
3541
3542//----------------------------------------------------------
3543void Cmt::do_show_set_names (const ArgParser& ap)
3544{
3545  if (ap.arguments.size () > 0)
3546    {
3547      const cmt_string& pattern = ap.arguments[0];
3548      print_symbol_names (ap.mode, pattern);
3549    }
3550  else
3551    {
3552      print_symbol_names (ap.mode);
3553    }
3554}
3555
3556//----------------------------------------------------------
3557void Cmt::do_show_set_value (const ArgParser& ap)
3558{
3559  do_show_macro (ap);
3560}
3561
3562//----------------------------------------------------------
3563void Cmt::do_show_sets (const ArgParser& ap)
3564{
3565  if (ap.arguments.size () > 0)
3566    {
3567      const cmt_string& pattern = ap.arguments[0];
3568      print_macros (ap.mode, pattern);
3569    }
3570  else
3571    {
3572      print_macros (ap.mode);
3573    }
3574}
3575
3576//----------------------------------------------------------
3577void Cmt::do_show_strategies (const ArgParser& /*ap*/)
3578{
3579  Project::show_specified_strategies_for_all ();
3580
3581  Project* p = Project::get_current ();
3582
3583  /*
3584    if (p != 0) p->show ();
3585    else cout << "No current project" << endl;
3586  */
3587
3588  cout << "Structuring style : ";
3589
3590  switch (Me.m_current_structuring_style)
3591    {
3592    case without_version_directory:
3593      cout << "without_version_directory";
3594      break;
3595    case with_version_directory:
3596      cout << "with_version_directory";
3597      break;
3598    }
3599
3600  cout << endl;
3601
3602  cout << "Build strategy    : ";
3603
3604  if (get_strategy ("BuildPrototypes"))
3605    {
3606      cout << "prototypes";
3607    }
3608  else
3609    {
3610      cout << "no_prototypes";
3611    }
3612 
3613  if (get_strategy ("InstallArea"))
3614    {
3615      cout << " with_installarea";
3616    }
3617  else
3618    {
3619      cout << " without_installarea";
3620    }
3621 
3622  cout << endl;
3623
3624  cout << "Setup strategy    : ";
3625 
3626  if (get_strategy ("SetupConfig"))
3627    {
3628      cout << "config";
3629    }
3630  else
3631    {
3632      cout << "no_config";
3633    }
3634 
3635  if (get_strategy ("SetupRoot"))
3636    {
3637      cout << " root";
3638    }
3639  else
3640    {
3641      cout << " no_root";
3642    }
3643 
3644  if (get_strategy ("SetupCleanup"))
3645    {
3646      cout << " cleanup";
3647    }
3648  else
3649    {
3650      cout << " no_cleanup";
3651    }
3652 
3653  cout << endl;
3654}
3655
3656//----------------------------------------------------------
3657void Cmt::do_show_tags (const ArgParser& /*ap*/)
3658{
3659  Tag::TagPtrVector tags = Tag::tags ();
3660  int index;
3661
3662  set_standard_macros ();
3663
3664  for (index = 0; index < tags.size (); index++)
3665    {
3666      const Tag* tag = tags[index];
3667      if (tag != 0)
3668        {
3669          tag->show (Me.m_quiet);
3670        }
3671    }
3672}
3673
3674//----------------------------------------------------------
3675void Cmt::do_show_use_paths (const ArgParser& ap)
3676{
3677  const cmt_string& to_name = ap.arguments[0];
3678
3679  Use* current = &(Use::current());
3680
3681  current->get_all_clients (to_name);
3682}
3683
3684//----------------------------------------------------------
3685void Cmt::do_show_uses (const ArgParser& /*ap*/)
3686{
3687  Use::show_all ();
3688}
3689
3690//----------------------------------------------------------
3691void Cmt::do_show_version (const ArgParser& /*ap*/)
3692{
3693  cout << Me.m_current_version << endl;
3694}
3695
3696//----------------------------------------------------------
3697void Cmt::do_show_versions (const ArgParser& ap)
3698{
3699  cmt_string package_name;
3700
3701  if (ap.arguments.size () > 0) package_name = ap.arguments[0];
3702
3703  PathScanner scanner;
3704
3705  Project::scan_paths_for_package (scanner, package_name);
3706}
3707
3708//----------------------------------------------------------
3709void Cmt::do_show_system (const ArgParser& /*ap*/)
3710{
3711  cout << CmtSystem::get_cmt_config () << endl;
3712}
3713
3714//----------------------------------------------------------
3715void Cmt::do_unlock (const ArgParser& /*ap*/)
3716{
3717  const cmt_string& package = Me.m_current_package;
3718  const cmt_string& version = Me.m_current_version;
3719  const cmt_string& path    = Me.m_current_path;
3720
3721  // (unused??) Use& use = Use::current();
3722
3723  cout << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
3724
3725  set_standard_macros ();
3726
3727  CmtLock::status status = CmtLock::unlock ();
3728}
3729
3730//----------------------------------------------------------
3731void Cmt::do_version (const ArgParser& /*ap*/)
3732{
3733  cout << CMTVERSION << endl;
3734}
3735
3736
3737
3738//----------------------------------------------------------
3739ActionType Cmt::get_action ()
3740{
3741  return (Me.m_action);
3742}
3743
3744/*
3745const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
3746{
3747  return (Me.m_cmt_path);
3748}
3749
3750const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_pwds ()
3751{
3752  return (Me.m_cmt_path_pwds);
3753}
3754
3755const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_sources ()
3756{
3757  return (Me.m_cmt_path_sources);
3758}
3759*/
3760
3761const cmt_string& Cmt::get_cmt_home ()
3762{
3763  return (Me.m_cmt_home);
3764}
3765
3766const cmt_string& Cmt::get_cmt_user_context ()
3767{
3768  return (Me.m_cmt_user_context);
3769}
3770
3771const cmt_string& Cmt::get_cmt_version ()
3772{
3773  return (Me.m_cmt_version);
3774}
3775
3776const cmt_string& Cmt::get_current_dir ()
3777{
3778  return (Me.m_current_dir);
3779}
3780
3781const cmt_string& Cmt::get_current_package ()
3782{
3783  return (Me.m_current_package);
3784}
3785
3786const cmt_string& Cmt::get_current_cmtpath ()
3787{
3788  return (Me.m_current_cmtpath);
3789}
3790
3791const cmt_string& Cmt::get_current_offset ()
3792{
3793  return (Me.m_current_offset);
3794}
3795
3796AccessMode Cmt::get_current_access ()
3797{
3798  return (Me.m_current_access);
3799}
3800
3801CmtStructuringStyle Cmt::get_current_structuring_style ()
3802{
3803  return (Me.m_current_structuring_style);
3804}
3805
3806CmtDirStyle Cmt::get_current_style ()
3807{
3808  return (Me.m_current_style);
3809}
3810
3811const cmt_string& Cmt::get_current_version ()
3812{
3813  return (Me.m_current_version);
3814}
3815
3816const cmt_string& Cmt::get_current_target ()
3817{
3818  return (Me.m_current_target);
3819}
3820
3821bool Cmt::get_debug ()
3822{
3823  return (Me.m_debug);
3824}
3825
3826bool Cmt::get_quiet ()
3827{
3828  return (Me.m_quiet);
3829}
3830
3831bool Cmt::get_recursive ()
3832{
3833  return (Me.m_recursive);
3834}
3835
3836CmtScopeFilteringMode Cmt::get_scope_filtering_mode ()
3837{
3838  if (Me.m_scope_filtering_mode == default_filtering_mode)
3839    {
3840      return (block_private_uses);
3841    }
3842  else
3843    {
3844      return (Me.m_scope_filtering_mode);
3845    }
3846}
3847
3848//----------------------------------------------------------
3849bool Cmt::get_all_sets_done ()
3850{
3851  return (Me.m_all_sets_done);
3852}
3853
3854/**---------------------------------------------------------
3855  guess_current_project
3856
3857   if current directory is in one of the CMTPATHs, do nothing.
3858
3859  Otherwise, we want to guess the current project
3860
3861  move up in directories until cmt/project.cmt is found
3862
3863  for (;;)
3864  {
3865    if test -f ./cmt/project.cmt
3866      ok:
3867        this directory should become the first entry of the CMTPATH
3868        break
3869
3870    if (at top) break;
3871
3872    move up
3873  }
3874  */
3875void Cmt::guess_current_project ()
3876{
3877  Log;
3878
3879  log << "guess_current_project" << log_endl;
3880
3881  if (Project::find_in_cmt_paths (Me.m_current_dir) == "")
3882    {
3883      cmt_string project_file = "cmt";
3884      project_file += CmtSystem::file_separator ();
3885      project_file += Project::get_project_file_name ();
3886
3887      cmt_string pwd;
3888
3889      for (;;)
3890        {
3891          pwd = CmtSystem::pwd ();
3892          if (CmtSystem::test_file (project_file))
3893            {
3894              //this directory should become the first entry of the CMTPATH
3895
3896              IProjectFactory& factory = ProjectFactory::instance ();
3897              factory.create_project ("", pwd, "CurrentProject", 0);
3898
3899              /*
3900              cmt_string temp = "path_prepend CMTPATH \"";
3901              temp += pwd;
3902              temp += "\"";
3903             
3904              Use& use = Use::current();
3905
3906              SyntaxParser::parse_requirements_line (temp, &use);
3907              */
3908
3909              break;
3910            }
3911
3912          log << "pwd=" << CmtSystem::pwd () << log_endl;
3913         
3914          if (!CmtSystem::cd (".."))
3915            {
3916              break;
3917            }
3918          if (CmtSystem::pwd () == pwd)
3919            {
3920              break;
3921            }
3922        }
3923      CmtSystem::cd (Me.m_current_dir);
3924    }
3925
3926  //cmt_string buffer = "path CMTPATH \n";
3927  cmt_string buffer;
3928  Project::fill_cmtpaths (buffer);
3929  //cerr << "buffer = " << buffer << endl;
3930  Use& use = Use::current();
3931  bool save_quiet = Me.m_quiet;
3932  Me.m_quiet = true;
3933  SyntaxParser::parse_requirements_text (buffer, "", &use);
3934  Me.m_quiet = save_quiet;
3935
3936  Me.m_autoconfigure_cmtpath = true;
3937}
3938
3939//----------------------------------------------------------
3940const cmt_string& Cmt::filter_dir (const cmt_string& dir)
3941{
3942  static cmt_string newdir;
3943
3944  CmtSystem::compress_path (dir, newdir);
3945
3946  return (newdir);
3947}
3948
3949//----------------------------------------------------------
3950static void dos_script_prefix (FILE* f, 
3951                               const cmt_string& cmt_root, 
3952                               const cmt_string& package, 
3953                               const cmt_string& version, 
3954                               const cmt_string& path, 
3955                               const cmt_string& action, 
3956                               const cmt_string& option = "")
3957{
3958  cmt_string no_device = path;
3959
3960  if (CmtSystem::absolute_path (path)) 
3961    {
3962      if (path[1] == ':')
3963        {
3964          no_device = path.substr (2);
3965        }
3966    }
3967
3968  if (package == "cmt_standalone")
3969    {
3970      no_device = "";
3971    }
3972  else
3973    {
3974      no_device = "..\\..\\..";
3975      if (Cmt::get_current_style () == no_version_style)
3976        {
3977          no_device = "..\\..";
3978        }
3979    }
3980
3981
3982  fprintf (f, "@echo off\n");
3983  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 ());
3984  fprintf (f, "\n");
3985  fprintf (f, "set cmttempfile=\"%%TEMP%%\\tmpsetup.bat\"\n");
3986  fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe %s -bat "
3987           " -pack=%s -version=%s -path=%%~d0%%~p0%s "
3988           " %s "
3989           "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%cmttempfile%%\n",
3990           action.c_str (),
3991           package.c_str (),
3992           version.c_str (),
3993           no_device.c_str (),
3994           option.c_str ());
3995  fprintf (f, "if exist %%cmttempfile%% call %%cmttempfile%%\n");
3996  fprintf (f, "if exist %%cmttempfile%% del %%cmttempfile%%\n");
3997  fprintf (f, "set cmttempfile=\n");
3998}
3999
4000//----------------------------------------------------------
4001void Cmt::install_cleanup_scripts ()
4002{
4003#ifdef WIN32
4004  static const int modes = 1;
4005  static const cmt_string suffix[1]   = {"bat"};
4006  static const PrintMode  mode[1]     = {Bat};
4007#else
4008  static const int modes = 2;
4009  static const cmt_string suffix[2]   = {"csh", "sh"};
4010  static const PrintMode  mode[2]     = {Csh, Sh};
4011#endif
4012
4013  cout << "Creating cleanup scripts." << endl;
4014
4015  cmt_string temp;
4016  int i;
4017
4018  cmt_string version = Me.m_current_version;
4019  if (version == "v*") version = "";
4020
4021  for (i = 0; i < modes; i++)
4022    {
4023      cmt_string file_name = "cleanup";
4024      file_name += ".";
4025      file_name += suffix[i];
4026      file_name += ".";
4027      file_name += "new";
4028
4029      FILE* f = fopen (file_name.c_str (), "wb");
4030      if (f != NULL)
4031        {
4032          if (mode[i] == Csh)
4033            {
4034              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4035              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4036              fprintf (f, "endif\n");
4037              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4038              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4039              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4040              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4041                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4042                       "source ${tempfile}\n",
4043                       suffix[i].c_str (),
4044                       Me.m_current_package.c_str (),
4045                       version.c_str (),
4046                       Me.m_current_path.c_str ());
4047              fprintf (f, "/bin/rm -f ${tempfile}\n");
4048            }
4049          else if (mode[i] == Sh)
4050            {
4051              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4052              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4053              fprintf (f, "fi\n");
4054              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4055              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4056              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4057              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4058                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4059                       ". ${tempfile}\n",
4060                       suffix[i].c_str (),
4061                       Me.m_current_package.c_str (),
4062                       version.c_str (),
4063                       Me.m_current_path.c_str ());
4064              fprintf (f, "/bin/rm -f ${tempfile}\n");
4065            }
4066          else if (mode[i] == Bat)
4067            {
4068              dos_script_prefix (f, Me.m_cmt_root, 
4069                                 Me.m_current_package, version, Me.m_current_path,
4070                                 "cleanup");
4071            }
4072
4073          fprintf (f, "\n");
4074
4075          fclose (f);
4076
4077          cmt_string old_file_name = "cleanup";
4078          old_file_name += ".";
4079          old_file_name += suffix[i];
4080
4081          CmtSystem::compare_and_update_files (file_name, old_file_name);
4082        }
4083    }
4084}
4085
4086//----------------------------------------------------------
4087void Cmt::install_setup_scripts ()
4088{
4089#ifdef WIN32
4090  static const int modes = 1;
4091  static const cmt_string suffix[1]   = {"bat"};
4092  static const PrintMode  mode[1]     = {Bat};
4093#else
4094  static const int modes = 2;
4095  static const cmt_string suffix[2]   = {"csh", "sh"};
4096  static const PrintMode  mode[2]     = {Csh, Sh};
4097#endif
4098
4099  cout << "Creating setup scripts." << endl;
4100
4101 
4102  cmt_string no_cleanup_opt;
4103
4104  if (get_strategy ("SetupCleanup"))
4105    {
4106      no_cleanup_opt = " -no_cleanup";
4107    }
4108
4109  cmt_string temp;
4110  int i;
4111
4112  cmt_string version = Me.m_current_version;
4113  if (version == "v*") version = "";
4114
4115  for (i = 0; i < modes; i++)
4116    {
4117      cmt_string file_name = "setup";
4118      file_name += ".";
4119      file_name += suffix[i];
4120      file_name += ".";
4121      file_name += "new";
4122
4123      FILE* f = fopen (file_name.c_str (), "wb");
4124      if (f != NULL)
4125        {
4126          if (mode[i] == Csh)
4127            {
4128              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4129                       Me.m_current_package.c_str (),
4130                       version.c_str (),
4131                       Me.m_current_path.c_str ());
4132              fprintf (f, "\n");
4133
4134              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4135              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4136              fprintf (f, "endif\n");
4137              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4138              fprintf (f, "\n");
4139              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4140              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4141              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4142                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4143                       "source ${tempfile}\n",
4144                       suffix[i].c_str (),
4145                       Me.m_current_package.c_str (),
4146                       version.c_str (),
4147                       Me.m_current_path.c_str (),
4148                       no_cleanup_opt.c_str ());
4149              fprintf (f, "/bin/rm -f ${tempfile}\n");
4150            }
4151          else if (mode[i] == Sh)
4152            {
4153              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4154                       Me.m_current_package.c_str (),
4155                       version.c_str (),
4156                       Me.m_current_path.c_str ());
4157              fprintf (f, "\n");
4158
4159              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4160              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4161              fprintf (f, "fi\n");
4162              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4163              fprintf (f, "\n");
4164              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4165              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4166              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4167                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4168                       ". ${tempfile}\n",
4169                       suffix[i].c_str (),
4170                       Me.m_current_package.c_str (),
4171                       version.c_str (),
4172                       Me.m_current_path.c_str (),
4173                       no_cleanup_opt.c_str ());
4174              fprintf (f, "/bin/rm -f ${tempfile}\n");
4175            }
4176          else if (mode[i] == Bat)
4177            {
4178              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
4179                       Me.m_current_package.c_str (),
4180                       version.c_str ());
4181              dos_script_prefix (f, Me.m_cmt_root, 
4182                                 Me.m_current_package, version, Me.m_current_path,
4183                                 "setup", no_cleanup_opt);
4184            }
4185
4186          fprintf (f, "\n");
4187
4188          fclose (f);
4189
4190          cmt_string old_file_name = "setup";
4191          old_file_name += ".";
4192          old_file_name += suffix[i];
4193
4194          CmtSystem::compare_and_update_files (file_name, old_file_name);
4195        }
4196    }
4197}
4198
4199//----------------------------------------------------------
4200void Cmt::install_test_cleanup_scripts ()
4201{
4202#ifdef WIN32
4203  static const int modes = 1;
4204  static const cmt_string suffix[1]   = {"bat"};
4205  static const PrintMode  mode[1]     = {Bat};
4206#else
4207  static const int modes = 2;
4208  static const cmt_string suffix[2]   = {"csh", "sh"};
4209  static const PrintMode  mode[2]     = {Csh, Sh};
4210#endif
4211
4212  cout << "Creating cleanup scripts." << endl;
4213
4214  cmt_string temp;
4215  int i;
4216
4217  cmt_string version = Me.m_current_version;
4218  if (version == "v*") version = "";
4219
4220  for (i = 0; i < modes; i++)
4221    {
4222      cmt_string file_name = "cleanup";
4223      file_name += ".";
4224      file_name += suffix[i];
4225      file_name += ".";
4226      file_name += "new";
4227
4228      FILE* f = fopen (file_name.c_str (), "wb");
4229      if (f != NULL)
4230        {
4231          if (mode[i] == Csh)
4232            {
4233              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4234              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4235              fprintf (f, "endif\n");
4236              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4237              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4238              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4239              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4240                       "source ${tempfile}\n",
4241                       suffix[i].c_str (),
4242                       Me.m_current_path.c_str ());
4243              fprintf (f, "/bin/rm -f ${tempfile}\n");
4244            }
4245          else if (mode[i] == Sh)
4246            {
4247              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4248              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4249              fprintf (f, "fi\n");
4250              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4251              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4252              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4253              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4254                       ". ${tempfile}\n",
4255                       suffix[i].c_str (),
4256                       Me.m_current_path.c_str ());
4257              fprintf (f, "/bin/rm -f ${tempfile}\n");
4258            }
4259          else
4260            {
4261              dos_script_prefix (f, Me.m_cmt_root, 
4262                                 "cmt_standalone", "", Me.m_current_path, 
4263                                 "cleanup");
4264            }
4265
4266          fprintf (f, "\n");
4267
4268          fclose (f);
4269
4270          cmt_string old_file_name = "cleanup";
4271          old_file_name += ".";
4272          old_file_name += suffix[i];
4273
4274          CmtSystem::compare_and_update_files (file_name, old_file_name);
4275        }
4276    }
4277}
4278
4279//----------------------------------------------------------
4280void Cmt::install_test_setup_scripts ()
4281{
4282#ifdef WIN32
4283  static const int modes = 1;
4284  static const cmt_string suffix[1]   = {"bat"};
4285  static const PrintMode  mode[1]     = {Bat};
4286#else
4287  static const int modes = 2;
4288  static const cmt_string suffix[2]   = {"csh", "sh"};
4289  static const PrintMode  mode[2]     = {Csh, Sh};
4290#endif
4291
4292  cout << "Creating setup scripts." << endl;
4293
4294  cmt_string no_cleanup_opt;
4295
4296  if (get_strategy ("SetupCleanup"))
4297    {
4298      no_cleanup_opt = " -no_cleanup";
4299    }
4300
4301  cmt_string temp;
4302  int i;
4303
4304  for (i = 0; i < modes; i++)
4305    {
4306      cmt_string file_name = "setup";
4307      file_name += ".";
4308      file_name += suffix[i];
4309      file_name += ".";
4310      file_name += "new";
4311
4312      FILE* f = fopen (file_name.c_str (), "wb");
4313      if (f != NULL)
4314        {
4315          if (mode[i] == Csh)
4316            {
4317              fprintf (f, "# echo \"Setting standalone package\"\n");
4318              fprintf (f, "\n");
4319
4320              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4321              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4322              fprintf (f, "endif\n");
4323              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4324              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4325              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4326              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4327                       "source ${tempfile}\n",
4328                       suffix[i].c_str (),
4329                       Me.m_current_path.c_str (),
4330                       no_cleanup_opt.c_str ());
4331              fprintf (f, "/bin/rm -f ${tempfile}\n");
4332            }
4333          else if (mode[i] == Sh)
4334            {
4335              fprintf (f, "# echo \"Setting standalone package\"\n");
4336              fprintf (f, "\n");
4337
4338              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4339              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4340              fprintf (f, "fi\n");
4341              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4342              fprintf (f, "\n");
4343              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4344              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4345              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4346                       ". ${tempfile}\n",
4347                       suffix[i].c_str (),
4348                       Me.m_current_path.c_str (),
4349                       no_cleanup_opt.c_str ());
4350              fprintf (f, "/bin/rm -f ${tempfile}\n");
4351            }
4352          else
4353            {
4354              fprintf (f, "rem Setting standalone package\n");
4355              dos_script_prefix (f, Me.m_cmt_root, 
4356                                 "cmt_standalone", "", Me.m_current_path, 
4357                                 "setup", no_cleanup_opt);
4358            }
4359
4360          fprintf (f, "\n");
4361
4362          fclose (f);
4363
4364          cmt_string old_file_name = "setup";
4365          old_file_name += ".";
4366          old_file_name += suffix[i];
4367
4368          CmtSystem::compare_and_update_files (file_name, old_file_name);
4369        }
4370    }
4371}
4372
4373/**
4374 *    load is only called from the Windows GUI which pretends to access directly
4375 *   the internal data model.
4376 *    This is considered to be rather unsafe, and should be replaced by query functions.
4377 */
4378bool Cmt::load (const cmt_string& path,
4379                const cmt_string& package,
4380                const cmt_string& version,
4381                const cmt_string& tag_name)
4382{
4383  clear ();
4384  configure ();
4385
4386  Me.m_action  = action_load;
4387  Me.m_recursive = true;
4388
4389  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
4390    {
4391      //
4392      //  Here we want to connect to a new package, or to the current package
4393      //  but with another tag.
4394      //
4395      //   the 'package' argument may include a directory offset. Thus 'path'
4396      //  is only expected to hold the base directory.
4397      //
4398      cmt_string offset;
4399      cmt_string package_name;
4400     
4401      CmtSystem::dirname (package, offset);
4402      CmtSystem::basename (package, package_name);
4403     
4404      if (offset != "")
4405        {
4406          Me.m_current_path = path;
4407          Me.m_current_path += CmtSystem::file_separator ();
4408          Me.m_current_path += offset;
4409        }
4410      else
4411        {
4412          Me.m_current_path = path;
4413        }
4414     
4415      Me.m_current_package = package_name;
4416      Me.m_current_version = version;
4417    }
4418
4419  if (tag_name != "")
4420    {
4421      Tag* tag;
4422
4423      Tag::unmark_all ();
4424      configure_version_tag ();
4425      configure_site_tag (0);
4426      configure_uname_tag ();
4427      configure_hosttype_tag ();
4428
4429      Me.m_current_tag = tag_name;
4430
4431      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
4432
4433      tag = Tag::add (tag_name, PriorityTag, "load", 0);
4434      tag->mark ();
4435    }
4436
4437  /*
4438    Set to developer mode if positioned into the package
4439    (which is detected since we were able to retreive the
4440    Version, Package and Path)
4441  */
4442
4443  if ((Me.m_current_path == "") ||
4444      (Me.m_current_package == "") ||
4445      (Me.m_current_version == ""))
4446    {
4447      Me.m_current_access = UserMode;
4448    }
4449  else
4450    {
4451      Me.m_current_access = DeveloperMode;
4452    }
4453
4454  use_cmt ();
4455
4456  cmt_string dir;
4457
4458  /*
4459    Try to access the package.
4460  */
4461
4462  if (Me.m_current_path != "")
4463    {
4464      dir = Me.m_current_path;
4465    }
4466  else
4467    {
4468      dir = Me.m_default_path;
4469    }
4470
4471  if (!CmtSystem::cd (Me.m_current_path))
4472    {
4473      if (!Me.m_quiet)
4474        {
4475          cerr << "#CMT> Cannot reach the directory " <<
4476            Me.m_current_path << endl;
4477        }
4478      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
4479      CmtSystem::cd (Me.m_current_dir);
4480
4481      return (false);
4482    }
4483
4484  dir += CmtSystem::file_separator ();
4485  dir += Me.m_current_package;
4486
4487  if (!CmtSystem::cd (Me.m_current_package))
4488    {
4489      if (!Me.m_quiet)
4490        {
4491          cerr << "#CMT::load> Cannot reach the package " <<
4492            Me.m_current_package << endl;
4493        }
4494      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
4495      CmtSystem::cd (Me.m_current_dir);
4496
4497      return (false);
4498    }
4499
4500  dir += CmtSystem::file_separator ();
4501  dir += Me.m_current_version;
4502
4503  Me.m_current_style = none_style;
4504
4505  if (!CmtSystem::cd (Me.m_current_version))
4506    {
4507      if (!CmtSystem::test_directory ("cmt"))
4508        {
4509          if (!Me.m_quiet)
4510            {
4511              cerr << "#CMT> Cannot reach the version " <<
4512                Me.m_current_version << endl;
4513            }
4514          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
4515          CmtSystem::cd (Me.m_current_dir);
4516
4517          return (false);
4518        }
4519      else
4520        {
4521          Me.m_current_style = no_version_style;
4522        }
4523    }
4524
4525  if (CmtSystem::cd ("cmt"))
4526    {
4527      dir += CmtSystem::file_separator ();
4528      dir += "cmt";
4529      if (Me.m_current_style == none_style) Me.m_current_style = cmt_style;
4530    }
4531  else
4532    {
4533      /*
4534        if (!Me.m_quiet)
4535        {
4536        cerr << "Cannot reach the cmt branch" << endl;
4537        }
4538      */
4539
4540      if (CmtSystem::cd ("mgr"))
4541        {
4542          dir += CmtSystem::file_separator ();
4543          dir += "mgr";
4544          if (Me.m_current_style == none_style) Me.m_current_style = mgr_style;
4545        }
4546      else
4547        {
4548          if (!Me.m_quiet)
4549            {
4550              cerr << "#CMT> Cannot reach the mgr branch" << endl;
4551            }
4552
4553          CmtError::set (CmtError::package_not_found,
4554                         "Load> Cannot reach the mgr/cmt directory");
4555          CmtSystem::cd (Me.m_current_dir);
4556
4557          return (false);
4558        }
4559    }
4560
4561  /*
4562    Check Tag is always set up
4563  */
4564
4565  if (Me.m_current_tag == "")
4566    {
4567      char* env;
4568
4569      env = getenv (Me.m_current_config.c_str ());
4570      if (env != 0)
4571        {
4572          Tag* tag;
4573
4574          tag = Tag::add (env, PriorityConfig, "load", 0);
4575          tag->mark ();
4576          Me.m_current_tag = env;
4577
4578          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
4579
4580        }
4581      else
4582        {
4583          Me.m_current_tag = Me.m_cmt_config;
4584
4585          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
4586
4587        }
4588    }
4589
4590  if (Me.m_debug)
4591    {
4592      cout << "pwd = " << CmtSystem::pwd () << endl;
4593    }
4594
4595  configure_current_dir ();
4596  build_prefix (Me.m_current_package, Me.m_current_prefix);
4597  build_config (Me.m_current_prefix, Me.m_current_config);
4598
4599  Use* use = &(Use::current());
4600  use->path    = Me.m_current_path;
4601  use->set_package_name (Me.m_current_package);
4602  use->version = Me.m_current_version;
4603  use->prefix  = Me.m_current_prefix;
4604  use->done    = false;
4605  use->style   = Me.m_current_style;
4606
4607  /*
4608    Work on the requirements file.
4609  */
4610
4611  dir += CmtSystem::file_separator ();
4612  dir += "requirements";
4613  SyntaxParser::parse_requirements (dir, use);
4614
4615  if (CmtError::has_pending_error ()) return (false);
4616
4617    /**
4618     * See reach_current_package for an explanation of this call
4619     */
4620  Pattern::apply_all_globals ();
4621
4622  /*
4623    Select all possible tags
4624  */
4625
4626  Tag::restore_tree ();
4627
4628  return (true);
4629}
4630
4631//----------------------------------------------------------
4632bool Cmt::need_prototypes ()
4633{
4634  if (get_strategy ("BuildPrototypes")) return (true);
4635  else return (false);
4636}
4637
4638//----------------------------------------------------------
4639void Cmt::parse_arguments (ArgParser& ap)
4640{
4641  /*
4642    Decoding arguments.
4643
4644    While decoding all arguments, no requirements analysis should
4645    occur. Every new option, or parameter should be saved and
4646    used later at actual analysis time.
4647  */
4648
4649  Me.m_action = action_none;
4650
4651  restore_all_tags (0);
4652
4653#ifdef WIN32
4654  Me.m_build_nmake = true;
4655#endif
4656
4657  ap.parse ();
4658}
4659
4660//----------------------------------------------------------
4661int Cmt::parser (const cmt_string& command_line)
4662{
4663  CmtSystem::cmt_string_vector v;
4664
4665  CmtSystem::split (command_line, " \t", v);
4666
4667  int argc = v.size ();
4668
4669  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
4670
4671  int i;
4672  for (i = 0; i < argc; i++)
4673    {
4674      argv[i] = (char*) v[i].c_str ();
4675    }
4676  argv[argc] = 0;
4677
4678  int status = parser (argc, argv);
4679
4680  free (argv);
4681
4682  return (status);
4683}
4684
4685//----------------------------------------------------------
4686int Cmt::parser (int argc, char* argv[])
4687{
4688  ArgParser ap (Me);
4689
4690  ap.argc = argc;
4691  ap.argv = argv;
4692
4693  if (argc <= 1)
4694    {
4695      do_help (ap);
4696      exit (0);
4697    }
4698
4699  clear ();
4700  configure ();
4701
4702  CmtError::clear ();
4703
4704  /*
4705    Set private if positioned inside the package
4706    (which is detected since we were able to retreive the
4707    Version, Package and Path)
4708  */
4709
4710  if ((Me.m_current_path.size () == 0) ||
4711      (Me.m_current_package.size () == 0) ||
4712      (Me.m_current_version.size () == 0))
4713    {
4714      Me.m_current_access = UserMode;
4715    }
4716  else
4717    {
4718      Me.m_current_access = DeveloperMode;
4719    }
4720
4721  parse_arguments (ap);
4722
4723  if (Me.m_debug)
4724    {
4725      cout << "After parse_argument> pack=" << Me.m_current_package
4726           << " Me.m_current_tag=" << Me.m_current_tag
4727           << " cwd=" << CmtSystem::pwd () 
4728           << " mode=" << Me.m_current_access
4729           << endl;
4730    }
4731
4732  if (Me.m_configure_error != "")
4733    {
4734      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
4735      return (CmtError::execution_error);
4736    }
4737
4738  if (CmtError::has_pending_error ())
4739    {
4740      int code = CmtError::get_last_error_code ();
4741      if (!Me.m_quiet) CmtError::print ();
4742      clear ();
4743
4744      return (code);
4745    }
4746
4747  /*
4748    Now actual requirements analysis can take place.
4749
4750    Extra lines or files are analysed first.
4751  */
4752
4753  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
4754  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
4755
4756  //
4757  //  For some of the actions, the CMT package must be automatically
4758  //  included
4759  //
4760
4761  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
4762
4763  if (ap.help_action == action_help)
4764    {
4765      do_help (ap);
4766      return (0);
4767    }
4768
4769  switch (Me.m_action)
4770    {
4771      // case action_none :
4772    case action_awk :
4773    case action_broadcast :
4774    case action_build_constituent_makefile :
4775    case action_build_constituents_makefile :
4776    case action_build_dependencies :
4777    case action_build_library_links :
4778    case action_build_make_setup :
4779    case action_build_msdev :
4780    case action_build_CMT_pacman :
4781    case action_build_vsnet :     
4782    case action_build_os9_makefile :
4783      // case action_build_prototype :
4784    case action_build_readme :
4785    case action_build_tag_makefile :
4786      // case action_build_temporary_name :
4787    case action_build_triggers :
4788    case action_build_windefs :
4789    case action_check_configuration :
4790      // case action_check_files :
4791      // case action_check_version :
4792    case action_checkout :
4793    case action_cleanup :
4794    case action_config :
4795    case action_create :
4796      // case action_create_project :
4797      // case action_cvsbranches :
4798      // case action_cvssubpackages :
4799      // case action_cvstags :
4800    case action_do :
4801    case action_expand_model :
4802    case action_filter :
4803      // case action_help :
4804    case action_load :
4805    case action_lock :
4806    case action_remove :
4807    case action_remove_library_links :
4808    case action_run :
4809    case action_run_sequence :
4810    case action_set_version :
4811    case action_set_versions :
4812    case action_setup :
4813    case action_show_action :
4814    case action_show_action_names :
4815    case action_show_action_value :
4816    case action_show_actions :
4817    case action_show_all_tags :
4818    case action_show_applied_patterns :
4819      // case action_show_author :
4820      // case action_show_branches :
4821      // case action_show_clients :
4822    case action_show_cmtpath_patterns :
4823    case action_show_constituent :
4824    case action_show_constituent_names :
4825    case action_show_constituents :
4826    case action_show_cycles :
4827    case action_show_fragment :
4828    case action_show_fragments :
4829    case action_show_groups :
4830    case action_show_include_dirs :
4831    case action_show_language :
4832    case action_show_languages :
4833    case action_show_macro :
4834    case action_show_macro_names :
4835    case action_show_macro_value :
4836    case action_show_macros :
4837      // case action_show_manager :
4838    case action_show_packages :
4839    case action_show_path :
4840    case action_show_pattern :
4841    case action_show_pattern_names :
4842    case action_show_patterns :
4843    case action_show_projects :
4844      // case action_show_pwd :
4845    case action_show_setup :
4846    case action_show_set :
4847    case action_show_set_names :
4848    case action_show_set_value :
4849    case action_show_sets :
4850    case action_show_strategies :
4851    case action_show_tags :
4852    case action_show_use_paths :
4853    case action_show_uses :
4854    case action_show_version :
4855      // case action_show_versions :
4856      // case action_system :
4857    case action_unlock :
4858    case action_version :
4859      use_cmt ();
4860        //
4861        // Now parse the requirements file stored in ${CMTHOME}
4862        //
4863     
4864      use_home_requirements ();
4865
4866      break;
4867    default:
4868      break;
4869    }
4870
4871  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
4872
4873  //
4874  // Setting up recursive actions
4875  //
4876
4877  switch (Me.m_action)
4878    {
4879      // case action_none :
4880    case action_awk :
4881    case action_broadcast :
4882    case action_build_constituent_makefile :
4883    case action_build_constituents_makefile :
4884    case action_build_dependencies :
4885    case action_build_library_links :
4886    case action_build_make_setup :
4887    case action_build_msdev :
4888    case action_build_CMT_pacman :
4889    case action_build_vsnet :     
4890    case action_build_os9_makefile :
4891      // case action_build_prototype :
4892    case action_build_readme :
4893    case action_build_tag_makefile :
4894      // case action_build_temporary_name :
4895    case action_build_triggers :
4896    case action_build_windefs :
4897    case action_check_configuration :
4898      // case action_check_files :
4899      // case action_check_version :
4900      // case action_checkout :
4901    case action_cleanup :
4902    case action_config :
4903      // case action_create :
4904      // case action_create_project :
4905      // case action_cvsbranches :
4906      // case action_cvssubpackages :
4907      // case action_cvstags :
4908    case action_do :
4909    case action_expand_model :
4910    case action_filter :
4911      // case action_help :
4912    case action_load :
4913      // case action_lock :
4914      // case action_remove :
4915    case action_remove_library_links :
4916    case action_run :
4917    case action_run_sequence :
4918      // case action_set_version :
4919    case action_set_versions :
4920    case action_setup :
4921    case action_show_action :
4922    case action_show_action_names :
4923    case action_show_action_value :
4924    case action_show_actions :
4925    case action_show_all_tags :
4926    case action_show_applied_patterns :
4927      // case action_show_author :
4928      // case action_show_branches :
4929      // case action_show_clients :
4930    case action_show_cmtpath_patterns :
4931    case action_show_constituent :
4932    case action_show_constituent_names :
4933    case action_show_constituents :
4934    case action_show_cycles :
4935    case action_show_fragment :
4936    case action_show_fragments :
4937    case action_show_groups :
4938    case action_show_include_dirs :
4939    case action_show_language :
4940    case action_show_languages :
4941    case action_show_macro :
4942    case action_show_macro_names :
4943    case action_show_macro_value :
4944    case action_show_macros :
4945      // case action_show_manager :
4946    case action_show_packages :
4947    case action_show_path :
4948    case action_show_pattern :
4949    case action_show_pattern_names :
4950    case action_show_patterns :
4951    case action_show_projects :
4952      // case action_show_pwd :
4953    case action_show_setup :
4954    case action_show_set :
4955    case action_show_set_names :
4956    case action_show_set_value :
4957    case action_show_sets :
4958    case action_show_strategies :
4959    case action_show_tags :
4960    case action_show_use_paths :
4961    case action_show_uses :
4962      // case action_show_version :
4963      // case action_show_versions :
4964      // case action_system :
4965      // case action_unlock :
4966      // case action_version :
4967      Me.m_recursive = true;
4968      break;
4969    default:
4970      Me.m_recursive = false;
4971      break;
4972    }
4973
4974  //
4975  //  Actions for which the context of the package is checked,
4976  //  and the requirements file is analysed.
4977  //
4978
4979  switch (Me.m_action)
4980    {
4981    case action_none :
4982    case action_awk :
4983    case action_broadcast :
4984    case action_build_constituent_makefile :
4985    case action_build_constituents_makefile :
4986    case action_build_dependencies :
4987    case action_build_library_links :
4988    case action_build_make_setup :
4989    case action_build_msdev :
4990    case action_build_CMT_pacman :
4991    case action_build_vsnet :     
4992    case action_build_os9_makefile :
4993      // case action_build_prototype :
4994    case action_build_readme :
4995    case action_build_tag_makefile :
4996      // case action_build_temporary_name :
4997    case action_build_triggers :
4998    case action_build_windefs :
4999    case action_check_configuration :
5000      // case action_check_files :
5001      // case action_check_version :
5002      // case action_checkout :
5003    case action_cleanup :
5004    case action_config :
5005      // case action_create :
5006      // case action_create_project :
5007      // case action_cvsbranches :
5008      // case action_cvssubpackages :
5009      // case action_cvstags :
5010    case action_do :
5011    case action_expand_model :
5012    case action_filter :
5013      // case action_help :
5014    case action_load :
5015    case action_lock :
5016      // case action_remove :
5017    case action_remove_library_links :
5018    case action_run :
5019      // case action_run_sequence :
5020      // case action_set_version :
5021    case action_set_versions :
5022    case action_setup :
5023    case action_show_action :
5024    case action_show_action_names :
5025    case action_show_action_value :
5026    case action_show_actions :
5027    case action_show_all_tags :
5028    case action_show_applied_patterns :
5029    case action_show_author :
5030    case action_show_branches :
5031      // case action_show_clients :
5032    case action_show_cmtpath_patterns :
5033    case action_show_constituent :
5034    case action_show_constituent_names :
5035    case action_show_constituents :
5036    case action_show_cycles :
5037    case action_show_fragment :
5038    case action_show_fragments :
5039    case action_show_groups :
5040    case action_show_include_dirs :
5041    case action_show_language :
5042    case action_show_languages :
5043    case action_show_macro :
5044    case action_show_macro_names :
5045    case action_show_macro_value :
5046    case action_show_macros :
5047    case action_show_manager :
5048    case action_show_packages :
5049    case action_show_path :
5050    case action_show_pattern :
5051    case action_show_pattern_names :
5052    case action_show_patterns :
5053    case action_show_projects :
5054    case action_show_pwd :
5055    case action_show_setup :
5056    case action_show_set :
5057    case action_show_set_names :
5058    case action_show_set_value :
5059    case action_show_sets :
5060    case action_show_strategies :
5061    case action_show_tags :
5062    case action_show_use_paths :
5063    case action_show_uses :
5064    case action_show_version :
5065      // case action_show_versions :
5066      // case action_system :
5067    case action_unlock :
5068      // case action_version :
5069      reach_current_package ();
5070      use_user_context_requirements ();
5071      break;
5072    default:
5073      break;
5074    }
5075
5076  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
5077
5078  //
5079  // Perform some actions even if there is an error
5080  //
5081
5082  if (CmtError::has_pending_error ())
5083    {
5084      int code = CmtError::get_last_error_code ();
5085      if (!Me.m_quiet) CmtError::print ();
5086
5087      switch (Me.m_action)
5088        {
5089          // case action_none :
5090          // case action_awk :
5091          // case action_broadcast :
5092        case action_build_constituent_makefile :
5093        case action_build_constituents_makefile :
5094        case action_build_dependencies :
5095        case action_build_library_links :
5096        case action_build_make_setup :
5097        case action_build_msdev :
5098        case action_build_CMT_pacman :
5099        case action_build_vsnet :     
5100        case action_build_os9_makefile :
5101        case action_build_prototype :
5102        case action_build_readme :
5103        case action_build_tag_makefile :
5104          // case action_build_temporary_name :
5105        case action_build_triggers :
5106        case action_build_windefs :
5107        case action_check_configuration :
5108          // case action_check_files :
5109          // case action_check_version :
5110          // case action_checkout :
5111        case action_cleanup :
5112          // case action_config :
5113          // case action_create :
5114          // case action_create_project :
5115          // case action_cvsbranches :
5116          // case action_cvssubpackages :
5117          // case action_cvstags :
5118          // case action_do :
5119          // case action_expand_model :
5120          // case action_filter :
5121          // case action_help :
5122        case action_load :
5123        case action_lock :
5124        case action_remove :
5125        case action_remove_library_links :
5126          // case action_run :
5127        case action_run_sequence :
5128          // case action_set_version :
5129          // case action_set_versions :
5130        case action_setup :
5131          // case action_show_action :
5132          // case action_show_action_names :
5133          // case action_show_action_value :
5134          // case action_show_actions :
5135          // case action_show_all_tags :
5136          // case action_show_applied_patterns :
5137          // case action_show_author :
5138          // case action_show_branches :
5139          // case action_show_clients :
5140          // case action_show_cmtpath_patterns :
5141          // case action_show_constituent :
5142          // case action_show_constituent_names :
5143          // case action_show_constituents :
5144          // case action_show_cycles :
5145          // case action_show_fragment :
5146          // case action_show_fragments :
5147          // case action_show_groups :
5148          // case action_show_include_dirs :
5149          // case action_show_language :
5150          // case action_show_languages :
5151          // case action_show_macro :
5152          // case action_show_macro_names :
5153          // case action_show_macro_value :
5154          // case action_show_macros :
5155          // case action_show_manager :
5156          // case action_show_packages :
5157          // case action_show_path :
5158          // case action_show_pattern :
5159          // case action_show_pattern_names :
5160          // case action_show_patterns :
5161          // case action_show_projects :
5162          // case action_show_pwd :
5163          // case action_show_setup :
5164          // case action_show_set :
5165          // case action_show_set_names :
5166          // case action_show_set_value :
5167          // case action_show_sets :
5168          // case action_show_strategies :
5169          // case action_show_tags :
5170          // case action_show_use_paths :
5171          // case action_show_uses :
5172          // case action_show_version :
5173          // case action_show_versions :
5174          // case action_system :
5175        case action_unlock :
5176          // case action_version :
5177          clear ();
5178          return (code);
5179        default:
5180          CmtError::clear ();
5181          break;
5182        }
5183    }
5184
5185  //
5186  // Perform actions
5187  //
5188
5189  if (!Me.m_simulation)
5190    {
5191      switch (Me.m_action)
5192        {
5193        case action_none :
5194          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
5195          break;
5196        case action_awk :
5197          do_awk (ap);
5198      break;
5199        case action_broadcast :
5200          do_broadcast (ap);
5201          break;
5202        case action_build_constituent_makefile :
5203          do_build_constituent_makefile (ap);
5204          break;
5205        case action_build_constituents_makefile :
5206          do_build_constituents_makefile (ap);
5207          break;
5208        case action_build_dependencies :
5209          do_build_dependencies (ap, argc, argv);
5210          break;
5211        case action_build_library_links :
5212          do_build_library_links (ap);
5213          break;
5214        case action_build_make_setup :
5215          do_build_make_setup (ap);
5216          break;
5217        case action_build_msdev :
5218          do_build_msdev (ap);
5219          break;
5220        case action_build_CMT_pacman :
5221          do_build_CMT_pacman (ap);
5222          break;
5223        case action_build_vsnet :     
5224          do_build_vsnet (ap);
5225          break;
5226        case action_build_os9_makefile :
5227          do_build_os9_makefile (ap);
5228          break;
5229        case action_build_prototype :
5230          do_build_prototype (ap);
5231          break;
5232        case action_build_readme :
5233          do_build_readme (ap);
5234          break;
5235        case action_build_tag_makefile :
5236          do_build_tag_makefile (ap);
5237          break;
5238        case action_build_temporary_name :
5239          do_build_temporary_name (ap);
5240          break;
5241        case action_build_triggers :
5242          do_build_triggers (ap);
5243          break;
5244        case action_build_windefs :
5245          do_build_windefs (ap);
5246          break;
5247        case action_check_configuration :
5248          do_check_configuration (ap);
5249          break;
5250        case action_check_files :
5251          do_check_files (ap);
5252          break;
5253        case action_check_version :
5254          do_check_version (ap);
5255          break;
5256        case action_checkout :
5257          do_checkout (ap);
5258          break;
5259        case action_cleanup :
5260          do_cleanup (ap);
5261          break;
5262        case action_config :
5263          do_config (ap);
5264          break;
5265        case action_create :
5266          do_create (ap);
5267          break;
5268        case action_create_project :
5269          do_create_project (ap);
5270          break;
5271        case action_cvsbranches :
5272          do_cvsbranches (ap);
5273          break;
5274        case action_cvssubpackages :
5275          do_cvssubpackages (ap);
5276          break;
5277        case action_cvstags :
5278          do_cvstags (ap);
5279          break;
5280        case action_do :
5281          do_do (ap);
5282          break;
5283        case action_expand_model :
5284          do_expand_model (ap);
5285          break;
5286        case action_filter :
5287          do_filter (ap);
5288          break;
5289        case action_help :
5290          do_help (ap);
5291          break;
5292        case action_load :
5293          cerr << "#CMT> action not implemented" << endl;
5294          break;
5295        case action_lock :
5296          do_lock (ap);
5297          break;
5298        case action_remove :
5299          do_remove (ap);
5300          break;
5301        case action_remove_library_links :
5302          do_remove_library_links (ap);
5303          break;
5304        case action_run :
5305          do_run (ap);
5306          break;
5307        case action_run_sequence :
5308          do_run_sequence (ap);
5309          break;
5310        case action_set_version :
5311          do_set_version (ap);
5312          break;
5313        case action_set_versions :
5314          do_set_versions (ap);
5315          break;
5316        case action_setup :
5317          do_setup (ap);
5318          break;
5319        case action_show_action :
5320          do_show_action (ap);
5321          break;
5322        case action_show_action_names :
5323          do_show_action_names (ap);
5324          break;
5325        case action_show_action_value :
5326          do_show_action_value (ap);
5327          break;
5328        case action_show_actions :
5329          do_show_actions (ap);
5330          break;
5331        case action_show_all_tags :
5332          do_show_all_tags (ap);
5333          break;
5334        case action_show_applied_patterns :
5335          do_show_applied_patterns (ap);
5336          break;
5337        case action_show_author :
5338          do_show_author (ap);
5339          break;
5340        case action_show_branches :
5341          do_show_branches (ap);
5342          break;
5343        case action_show_clients :
5344          do_show_clients (ap);
5345          break;
5346        case action_show_cmtpath_patterns :
5347          do_show_cmtpath_patterns (ap);
5348          break;
5349        case action_show_constituent :
5350          do_show_constituent (ap);
5351          break;
5352        case action_show_constituent_names :
5353          do_show_constituent_names (ap);
5354          break;
5355        case action_show_constituents :
5356          do_show_constituents (ap);
5357          break;
5358        case action_show_cycles :
5359          do_show_cycles (ap);
5360          break;
5361        case action_show_fragment :
5362          do_show_fragment (ap);
5363          break;
5364        case action_show_fragments :
5365          do_show_fragments (ap);
5366          break;
5367        case action_show_groups :
5368          do_show_groups (ap);
5369          break;
5370        case action_show_include_dirs :
5371          do_show_include_dirs (ap);
5372          break;
5373        case action_show_language :
5374          do_show_language (ap);
5375          break;
5376        case action_show_languages :
5377          do_show_languages (ap);
5378          break;
5379        case action_show_macro :
5380          do_show_macro (ap);
5381          break;
5382        case action_show_macro_names :
5383          do_show_macro_names (ap);
5384          break;
5385        case action_show_macro_value :
5386          do_show_macro_value (ap);
5387          break;
5388        case action_show_macros :
5389          do_show_macros (ap);
5390          break;
5391        case action_show_manager :
5392          do_show_manager (ap);
5393          break;
5394        case action_show_packages :
5395          do_show_packages (ap);
5396          break;
5397        case action_show_path :
5398          do_show_path (ap);
5399          break;
5400        case action_show_pattern :
5401          do_show_pattern (ap);
5402          break;
5403        case action_show_pattern_names :
5404          do_show_pattern_names (ap);
5405          break;
5406        case action_show_patterns :
5407          do_show_patterns (ap);
5408          break;
5409        case action_show_projects :
5410          do_show_projects (ap);
5411          break;
5412        case action_show_pwd :
5413          do_show_pwd (ap);
5414          break;
5415        case action_show_setup :
5416          do_show_setup (ap);
5417          break;
5418        case action_show_set :
5419          do_show_set (ap);
5420          break;
5421        case action_show_set_names :
5422          do_show_set_names (ap);
5423          break;
5424        case action_show_set_value :
5425          do_show_set_value (ap);
5426          break;
5427        case action_show_sets :
5428          do_show_sets (ap);
5429          break;
5430        case action_show_strategies :
5431          do_show_strategies (ap);
5432          break;
5433        case action_show_tags :
5434          do_show_tags (ap);
5435          break;
5436        case action_show_use_paths :
5437          do_show_use_paths (ap);
5438          break;
5439        case action_show_uses :
5440          do_show_uses (ap);
5441          break;
5442        case action_show_version :
5443          do_show_version (ap);
5444          break;
5445        case action_show_versions :
5446          do_show_versions (ap);
5447          break;
5448        case action_system :
5449          do_show_system (ap);
5450          break;
5451        case action_unlock :
5452          do_unlock (ap);
5453          break;
5454        case action_version :
5455          do_version (ap);
5456          break;
5457        default:
5458          CmtError::set (CmtError::syntax_error, "ParseArguments>");
5459          break;
5460        }
5461    }
5462
5463  if (CmtError::has_pending_error ())
5464    {
5465      int code = CmtError::get_last_error_code ();
5466      if (!Me.m_quiet) CmtError::print ();
5467      clear ();
5468      return (code);
5469    }
5470  else
5471    {
5472      clear ();
5473      return (0);
5474    }
5475}
5476
5477
5478/**
5479 * Format as one single line a set of 'setenv' statements
5480 * joined with semi-colons to form one shell command.
5481 */
5482void Cmt::print (PrintMode mode)
5483{
5484  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5485  Use& current_use = Use::current ();
5486
5487  cmt_string tag;
5488
5489  set_standard_macros ();
5490
5491    //cerr << "# current_tag=" << Me.m_current_tag << endl;
5492    //cerr << "# current_config=" << Me.m_current_config << endl;
5493
5494  if (Me.m_current_tag == "")
5495    {
5496      if (mode == Bat) tag = "%CMTCONFIG%";
5497      else tag = "${CMTCONFIG}";
5498    }
5499  else
5500    {
5501      tag = Me.m_current_tag;
5502    }
5503
5504    //
5505    //  Now check if all extra tags are still valid. Some of them
5506    //  may be discarded du to some conflict with highest priority
5507    //  tags, or with exclude statements
5508    //
5509
5510  {
5511    CmtSystem::cmt_string_vector words;
5512     
5513    cmt_string tags;
5514
5515    tags = Me.m_extra_tags;
5516     
5517    CmtSystem::split (tags, " \t,", words);
5518
5519    Me.m_extra_tags = ",";
5520     
5521    for (int i = 0; i < words.size (); i++)
5522      {
5523        Tag* tag;
5524        const cmt_string& a = words[i];
5525
5526        tag = Tag::find (a);
5527
5528        if ((tag != 0) && (tag->is_selected ()))
5529          {
5530            Me.m_extra_tags += a;
5531            Me.m_extra_tags += ",";
5532          }
5533      }
5534  }
5535
5536  if (Me.m_debug)
5537    {
5538      cout << "Before all print contexts" << endl;
5539    }
5540
5541  if (Uses.size () > 0)
5542    {
5543      int number;
5544
5545      for (number = 0; number < Uses.size (); number++)
5546        {
5547          Use& use = *(Uses[number]);
5548
5549          if (use.discarded) continue;
5550
5551          print_context (use, mode, tag);
5552        }
5553    }
5554
5555  print_context (Use::current (), mode, tag);
5556
5557  if (Me.m_debug)
5558    {
5559      cout << "After all print contexts" << endl;
5560    }
5561
5562  Symbol::all_print (mode);
5563  // Script::all_print (mode);
5564
5565  if (Me.m_debug)
5566    {
5567      cout << "After all print" << endl;
5568    }
5569
5570  cout << endl;
5571}
5572
5573
5574/**
5575 * Format as one single line a set of 'unsetenv' statements
5576 * joined with semi-colons to form one shell command.
5577 */
5578void Cmt::print_clean (PrintMode mode)
5579{
5580  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5581
5582  set_standard_macros ();
5583
5584  Script::all_print_clean (mode);
5585  Symbol::all_print_clean (mode);
5586
5587  switch (mode)
5588    {
5589    case Csh :
5590      if (Me.m_current_package != "CMT")
5591        {
5592          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
5593          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
5594        }
5595      break;
5596    case Sh :
5597      if (Me.m_current_package != "CMT")
5598        {
5599          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
5600          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
5601        }
5602      break;
5603    case Bat :
5604      if (Me.m_current_package != "CMT")
5605        {
5606          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
5607          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
5608        }
5609      break;
5610    }
5611
5612  if (Uses.size () > 0)
5613    {
5614      int number;
5615
5616      for (number = 0; number < Uses.size (); number++)
5617        {
5618          Use* use = Uses[number];
5619
5620          if (use->discarded) continue;
5621
5622          Package* p = use->get_package ();
5623          if (p->is_cmt ()) continue;
5624
5625          switch (mode)
5626            {
5627            case Csh :
5628              cout << "unsetenv " << use->prefix << "ROOT" << endl;
5629              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
5630              break;
5631            case Sh :
5632              cout << "unset " << use->prefix << "ROOT" << endl;
5633              cout << "unset " << use->prefix << "CONFIG" << endl;
5634              break;
5635            case Bat :
5636              cout << "set " << use->prefix << "ROOT=" << endl;
5637              cout << "set " << use->prefix << "CONFIG" << endl;
5638              break;
5639            }
5640        }
5641    }
5642
5643  switch (mode)
5644    {
5645    case Csh :
5646      cout << "unsetenv CMTEXTRATAGS" << endl;
5647      break;
5648    case Sh :
5649      cout << "unset CMTEXTRATAGS" << endl;
5650      break;
5651    case Bat :
5652      cout << "set CMTEXTRATAGS=" << endl;
5653      break;
5654    }
5655
5656  cout << endl;
5657}
5658
5659//----------------------------------------------------------
5660void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
5661{
5662  if (use.get_package_name () == "cmt_standalone") return;
5663
5664  cmt_string fs = CmtSystem::file_separator ();
5665
5666  use.real_path.replace_all (CmtSystem::file_separator (), fs);
5667
5668  cmt_string system = CmtSystem::get_cmt_config ();
5669
5670  bool do_config = get_strategy ("SetupConfig");
5671  bool do_root = get_strategy ("SetupRoot");
5672
5673  switch (mode)
5674    {
5675    case Csh :
5676      if (do_root)
5677        {
5678          cout << "setenv " << use.prefix << "ROOT \"" <<
5679            use.get_full_path () << "\"" << endl;
5680        }
5681
5682      if (use.get_package_name () == "CMT")
5683        {
5684          cout << "setenv CMTCONFIG " << system << endl;
5685        }
5686      else
5687        {
5688          if (do_config)
5689            {
5690              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
5691            }
5692        }
5693       
5694      break;
5695    case Sh :
5696      if (do_root)
5697        {
5698          cout << use.prefix << "ROOT=\"" <<
5699            use.get_full_path () << "\"; export " <<
5700            use.prefix << "ROOT" << endl;
5701        }
5702
5703      if (use.get_package_name () == "CMT")
5704        {
5705          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
5706        }
5707      else
5708        {
5709          if (do_config)
5710            {
5711              cout << use.prefix << "CONFIG=\"" <<
5712                tag << "\"; export " <<
5713                use.prefix << "CONFIG" << endl;
5714            }
5715        }
5716       
5717      break;
5718    case Bat :
5719      if (do_root)
5720        {
5721          cout << "set " << use.prefix << "ROOT=" <<
5722            use.get_full_path () << endl;
5723        }
5724
5725      if (use.get_package_name () == "CMT")
5726        {
5727          cout << "set CMTCONFIG=" << system << endl;
5728        }
5729      else
5730        {
5731          if (do_config)
5732            {
5733              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
5734            }
5735        }
5736       
5737      break;
5738    }
5739}
5740
5741/**
5742 *  Format a set of make macro definitions (one per line)
5743 * Each macro value is provided enclosed in single quotes
5744 *
5745 *  Take the macro values from the macro statements found
5746 * in recursively read requirements files.
5747 */
5748void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
5749{
5750  int number;
5751
5752  set_standard_macros ();
5753
5754  cmt_regexp expression (pattern);
5755
5756  bool has_pattern = (pattern != "");
5757
5758  for (number = 0; number < Symbol::symbol_number (); number++)
5759    {
5760      Symbol& symbol = Symbol::symbol (number);
5761
5762      if (has_pattern)
5763       {
5764         if (!expression.match (symbol.name)) continue;
5765       }
5766
5767      if (Me.m_action == action_show_macro_names)
5768        {
5769          // Only keep macros.
5770          if ((symbol.type == Symbol::SymbolSet) ||
5771              (symbol.type == Symbol::SymbolAlias) ||
5772              (symbol.type == Symbol::SymbolPath) ||
5773              (symbol.type == Symbol::SymbolAction)) continue;
5774        }
5775      else if (Me.m_action == action_show_set_names)
5776        {
5777          // Exclude macros.
5778          if ((symbol.type == Symbol::SymbolMacro) ||
5779              (symbol.type == Symbol::SymbolAction)) continue;
5780        }
5781      else if (Me.m_action == action_show_action_names)
5782        {
5783          // Exclude macros.
5784          if (symbol.type != Symbol::SymbolAction) continue;
5785        }
5786
5787      cout << symbol.name << endl;
5788    }
5789}
5790
5791/**
5792 *  Format a set of make macro definitions (one per line)
5793 * Each macro value is provided enclosed in single quotes
5794 *
5795 *  Take the macro values from the macro statements found
5796 * in recursively read requirements files.
5797 */
5798void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
5799{
5800  int number;
5801
5802  set_standard_macros ();
5803
5804  cmt_regexp expression (pattern);
5805
5806  bool has_pattern = (pattern != "");
5807
5808  for (number = 0; number < Symbol::symbol_number (); number++)
5809    {
5810      Symbol& symbol = Symbol::symbol (number);
5811
5812      if (has_pattern)
5813        {
5814          if (!expression.match (symbol.name)) continue;
5815        }
5816
5817      if (Me.m_action == action_show_macros)
5818        {
5819          // Only keep macros.
5820          if ((symbol.type == Symbol::SymbolSet) ||
5821              (symbol.type == Symbol::SymbolAlias) ||
5822              (symbol.type == Symbol::SymbolPath) ||
5823              (symbol.type == Symbol::SymbolAction)) continue;
5824        }
5825      else if (Me.m_action == action_show_sets)
5826        {
5827          // Exclude macros.
5828          if ((symbol.type == Symbol::SymbolMacro) ||
5829              (symbol.type == Symbol::SymbolAction)) continue;
5830        }
5831      else if (Me.m_action == action_build_tag_makefile)
5832        {
5833          // Exclude scripts and actions
5834          if ((symbol.type == Symbol::SymbolSetupScript) ||
5835              (symbol.type == Symbol::SymbolCleanupScript) ||
5836              (symbol.type == Symbol::SymbolAction)) continue;
5837        }
5838      else if (Me.m_action == action_show_actions)
5839        {
5840          if (symbol.type != Symbol::SymbolAction) continue;
5841        }
5842
5843      if (symbol.value_lists.size () < 1) continue;
5844
5845      symbol.show_macro (mode);
5846    }
5847}
5848
5849//----------------------------------------------------------
5850void Cmt::print_tabs (int tabs)
5851{
5852  while (tabs > 0)
5853    {
5854      cout << "  ";
5855      tabs--;
5856    }
5857}
5858
5859//----------------------------------------------------------
5860int Cmt::reach_current_package ()
5861{
5862  Use& use = Use::current ();
5863  cmt_string dir;
5864
5865  if (Me.m_debug)
5866    {
5867      cout << "Cmt::reach_current_package> pwd = " 
5868           << CmtSystem::pwd () 
5869           << " path=" << Me.m_current_path
5870           << " package=" << Me.m_current_package
5871           << endl;
5872    }
5873
5874  /*
5875    Try to access the package.
5876  */
5877
5878  if (Me.m_current_package == "cmt_standalone")
5879    {
5880      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
5881        {
5882          if (!CmtSystem::cd (Me.m_current_path))
5883            {
5884              CmtError::set (CmtError::package_not_found,
5885                             "ReachCurrentPackage> Cannot reach the path directory");
5886              return (0);
5887            }
5888        }
5889
5890      if (!CmtSystem::test_file ("requirements"))
5891        {
5892            /*
5893          if (!Me.m_quiet)
5894            {
5895              cout << "#CMT> Cannot reach the requirements file" << endl;
5896            }
5897             
5898          CmtError::set (CmtError::package_not_found,
5899                         "ReachCurrentPackage> Cannot reach the requirements file");
5900            */
5901          return (0);
5902        }
5903    }
5904  else if (Me.m_current_package != "")
5905    {
5906      if (!use.move_to ())
5907        {
5908          CmtError::set (CmtError::package_not_found,
5909                         "ReachCurrentPackage> Cannot reach the path directory");
5910          return (0);
5911        }
5912
5913      Me.m_current_path = use.real_path;
5914    }
5915  else
5916    {
5917      //
5918      // The cmt command has been given without explicit search for
5919      // a package. Thus it is expected that we are in the context of a
5920      // true package.
5921      //
5922      //  This means that there should be a requirements file visible.
5923      //
5924      //  If this is not true, we'll make a try into ../cmt and then
5925      // a last try into ../mgr
5926      //
5927
5928      if (!CmtSystem::test_file ("requirements"))
5929        {
5930          if (CmtSystem::cd ("../cmt") && 
5931              CmtSystem::test_file ("requirements"))
5932            {
5933              Me.m_current_style = cmt_style;
5934            }
5935          else if (CmtSystem::cd ("../mgr") && 
5936                   CmtSystem::test_file ("requirements"))
5937            {
5938              Me.m_current_style = mgr_style;
5939            }
5940          else
5941            {
5942              if (!Me.m_quiet)
5943                {
5944                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
5945                }
5946             
5947              CmtError::set (CmtError::package_not_found,
5948                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
5949              return (0);
5950            }
5951        }
5952
5953      dir = CmtSystem::pwd ();
5954
5955      CmtSystem::dirname (dir, Me.m_current_path);
5956      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
5957
5958      if (CmtSystem::is_version_directory (Me.m_current_version))
5959        {
5960          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
5961          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
5962          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
5963        }
5964      else
5965        {
5966          Me.m_current_package = Me.m_current_version;
5967          Me.m_current_version = "";
5968          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
5969
5970          Me.m_current_style = no_version_style;
5971        }
5972
5973      use.set_package_name (Me.m_current_package);
5974      use.version = Me.m_current_version;
5975      use.path    = Me.m_current_path;
5976      use.style   = Me.m_current_style;
5977    }
5978
5979  configure_current_dir ();
5980  build_prefix (Me.m_current_package, Me.m_current_prefix);
5981  build_config (Me.m_current_prefix, Me.m_current_config);
5982
5983  /*
5984    Check Tag is always set up
5985  */
5986
5987  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
5988
5989  if (Me.m_current_tag == "")
5990    {
5991      cmt_string env;
5992
5993      env = CmtSystem::getenv (Me.m_current_config);
5994      if (env != "")
5995        {
5996          Tag* tag;
5997
5998          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
5999          tag->mark ();
6000            //Me.m_current_tag = env;
6001
6002          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
6003
6004        }
6005    }
6006
6007  if (Me.m_debug)
6008    {
6009      cout << "pwd = " << CmtSystem::pwd () << endl;
6010    }
6011
6012  /*
6013    Work on the requirements file.
6014  */
6015
6016  if (dir != "") dir += CmtSystem::file_separator ();
6017  dir += "requirements";
6018  SyntaxParser::parse_requirements (dir, &use);
6019
6020  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
6021
6022    /**
6023     *   It would be useful to change this mechanism. Instead of
6024     *  applying all global patterns at once to all use contexts, it
6025     *  would be much better to apply it at the end of each
6026     *  requirements file parsing, and only in the context the
6027     *  appropriate Use.
6028     *
6029     *   This would avoid the current flaw which is that when a global
6030     *  pattern specifies a "private" definition, it is actually
6031     *  applied in the scope context of the Current Use and not in
6032     *  each individual Use. Therefore the private is lost.
6033     *
6034     *   However, this induces problems since some pattern definitions
6035     *  are done AFTER the use statements, which will NOT receive the
6036     *  pattern aplications.
6037     *
6038     *   Therefore it is decided to leave this "bad" mechanism until
6039     *  everybody is aware of this constraint.
6040     *
6041     *
6042     */
6043  Pattern::apply_all_globals ();
6044
6045  /*
6046    Select all possible tags
6047  */
6048
6049  Tag::restore_tree ();
6050
6051  return (1);
6052}
6053
6054static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
6055                                 const cmt_string& path)
6056{
6057  static cmt_string fs = CmtSystem::file_separator ();
6058  cmt_string result;
6059
6060    /*
6061    //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
6062    {
6063    */
6064
6065    //
6066    //  If there is a common prefix between
6067    //  use->real_path and pwd
6068    //  we have
6069    //  use->real_path = /<prefix>/aaa
6070    //  pwd            = /<prefix>/bbb
6071    //
6072    //  Then use->real_path may be expressed as:
6073    //  ../..../../aaa
6074    //   where ../..../../ moves up to /<prefix>
6075    //
6076    //   Then we try to find the shortest between
6077    //
6078    //     /<prefix> and ../..../..
6079    //
6080  cmt_string a = path;
6081 
6082  CmtSystem::cmt_string_vector va;
6083 
6084  va.clear ();
6085 
6086  CmtSystem::split (a, fs, va);
6087 
6088  int m = va.size ();
6089  if (pwd.size () < m) m = pwd.size ();
6090 
6091  int i;
6092 
6093    //cout << "Package " << use->get_package_name () << endl;
6094 
6095  for (i = 0; i < m; i++)
6096    {
6097      const cmt_string& fa = va[i];
6098      const cmt_string& fb = pwd[i];
6099     
6100        //cout << "  fa=" << fa << " fb=" << fb << endl;
6101     
6102      if (fa != fb) break;
6103    }
6104 
6105  cmt_string ups = "";
6106 
6107  if (i > 0)
6108    {
6109        // We have the prefix.
6110        // if we count what remains from pwd, then
6111        // we have the number of ../ required to
6112        // move to /<prefix>
6113      int j;
6114     
6115      for (j = i; j < pwd.size (); j++)
6116        {
6117          if (j > i) ups += fs;
6118          ups += "..";
6119        }
6120
6121      for (j = i; j < va.size (); j++)
6122        {
6123          ups += fs;
6124          ups += va[j];
6125        }
6126    }
6127 
6128    //
6129    // Here ups contains the ../..../../aaa form
6130    // for the use->real_path or is empty when there
6131    // were no common prefix.
6132    //
6133 
6134    //if (ups != "")
6135  if ((ups != "") &&
6136      (ups.size () < path.size ()))
6137    {
6138      result = ups;
6139    }
6140  else
6141    {
6142      result = path;
6143    }
6144
6145  return (result);
6146}
6147
6148/**
6149 *   This completely local class holds primitive actions for building
6150 *   standard macros.
6151 */
6152class StandardMacroBuilder
6153{
6154public:
6155
6156  /**
6157   *  CMTVERSION
6158   */
6159  void fill_for_CMTVERSION ()
6160  {
6161    buffer = "macro CMTVERSION \"";
6162    buffer += CMTVERSION;
6163    buffer += "\"";
6164    apply ();
6165  }
6166
6167  StandardMacroBuilder (const cmt_string& tag,
6168                        const cmt_string& package,
6169                        const cmt_string& version,
6170                        const cmt_string& prefix,
6171                        CmtDirStyle style)
6172  {
6173    fs = CmtSystem::file_separator ();
6174    buffer = "";
6175    pwd = CmtSystem::pwd ();
6176    CmtSystem::split (pwd, fs, vb);
6177    current_use = &(Use::current ());
6178    current_tag = tag;
6179    current_package = package;
6180    current_version = version;
6181    current_prefix = prefix;
6182    current_style = style;
6183  }
6184
6185  void apply ()
6186  {
6187    SyntaxParser::parse_requirements_line (buffer, current_use);
6188    buffer = "";
6189  }
6190
6191  /**
6192   *   tag
6193   */
6194  void fill_for_tag ()
6195  {
6196    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
6197
6198    if (!Symbol::is_selected ("tag"))
6199      {
6200        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
6201
6202        if (current_tag == "")
6203          {
6204            buffer = "macro tag \"$(CMTCONFIG)\"";
6205          }
6206        else
6207          {
6208            buffer = "macro tag \"";
6209            buffer += current_tag;
6210            buffer += "\"";
6211          }
6212       
6213        if (tag_debug) cerr << " define tag: " << buffer << endl;
6214       
6215        apply ();
6216      }
6217  }
6218
6219  /**
6220   *   PACKAGE_ROOT
6221   */
6222  void fill_for_package (const cmt_string& current_dir)
6223  {
6224    buffer = "macro package \"";
6225    buffer += current_package;
6226    buffer += "\"";
6227    apply ();
6228
6229    buffer = "macro version \"";
6230    buffer += current_version;
6231    buffer += "\"";
6232    apply ();
6233
6234    if (!Symbol::is_selected ("PACKAGE_ROOT"))
6235      {
6236        buffer = "macro PACKAGE_ROOT \"$(";
6237        buffer += current_prefix;
6238        buffer += "ROOT";
6239        buffer += ")\"";
6240
6241        apply ();
6242      }
6243  }
6244
6245  /**
6246   *   srcdir
6247   *   src       =$(srcdir)/
6248   *   inc
6249   *   mgrdir
6250   *   mgr       =../$(mgrdir)/
6251   *   bin
6252   *   javabin
6253   *   doc
6254   *   version
6255   *   package
6256   *
6257   *   <package>_project
6258   *   <package>_cmtpath
6259   *   <package>_offset
6260   *   package_cmtpath
6261   *   package_offset
6262   *   project
6263   *
6264   */
6265  void fill_for_branches ()
6266  {
6267    /**
6268     *    Basic macros  (src, mgr, ...)
6269     */
6270   
6271    if (current_style == none_style)
6272      {
6273        buffer = "macro srcdir \".";
6274        buffer += "\"";
6275        apply ();
6276
6277        buffer = "macro src \".";
6278        buffer += fs;
6279        buffer += "\"";
6280        apply ();
6281
6282        buffer = "macro inc \".";
6283        buffer += fs;
6284        buffer += "\"";
6285        apply ();
6286
6287        buffer = "macro mgr \".";
6288        buffer += fs;
6289        buffer += "\"";
6290        apply ();
6291
6292        buffer = "macro bin \".";
6293        buffer += fs;
6294        buffer += "\"";
6295        apply ();
6296
6297        buffer = "macro javabin \".";
6298        buffer += fs;
6299        buffer += "\"";
6300        apply ();
6301
6302        buffer = "macro doc \".";
6303        buffer += fs;
6304        buffer += "\"";
6305        apply ();
6306      }
6307    else
6308      {
6309        if (!Symbol::is_selected ("srcdir"))
6310          {
6311            buffer = "macro srcdir \"..";
6312            buffer += fs;
6313            buffer += "src";
6314            buffer += "\"";
6315            apply ();
6316          }
6317       
6318        if (!Symbol::is_selected ("src"))
6319          {
6320            buffer = "macro src \"..";
6321            buffer += fs;
6322            buffer += "src";
6323            buffer += fs;
6324            buffer += "\"";
6325            apply ();
6326          }
6327       
6328        if (!Symbol::is_selected ("inc"))
6329          {
6330            buffer = "macro inc \"..";
6331            buffer += fs;
6332            buffer += "src";
6333            buffer += fs;
6334            buffer += "\"";
6335            apply ();
6336          }
6337       
6338        if (!Symbol::is_selected ("doc"))
6339          {
6340            buffer = "macro doc \"..";
6341            buffer += fs;
6342            buffer += "doc";
6343            buffer += fs;
6344            buffer += "\"";
6345            apply ();
6346          }
6347       
6348        if (!Symbol::is_selected ("bin"))
6349          {
6350            cmt_string package_tag = current_package;
6351            package_tag += "_tag";
6352
6353            buffer = "macro bin \"..";
6354            buffer += fs;
6355            buffer += "$(";
6356            buffer += package_tag;
6357            buffer += ")";
6358            buffer += fs;
6359            buffer += "\"";
6360            apply ();
6361          }
6362
6363        if (!Symbol::is_selected ("javabin"))
6364          {
6365            buffer = "macro javabin \"..";
6366            buffer += fs;
6367            buffer += "classes";
6368            buffer += fs;
6369            buffer += "\"";
6370            apply ();
6371          }
6372       
6373        if (current_style == mgr_style)
6374          {
6375            buffer = "macro mgrdir \"mgr\"";
6376            apply ();
6377
6378            buffer = "macro mgr \"..";
6379            buffer += fs;
6380            buffer += "mgr";
6381            buffer += fs;
6382            buffer += "\"";
6383            apply ();
6384          }
6385        else
6386          {
6387            buffer = "macro mgrdir \"cmt\"";
6388            apply ();
6389
6390            buffer = "macro mgr \"..";
6391            buffer += fs;
6392            buffer += "cmt";
6393            buffer += fs;
6394            buffer += "\"";
6395            apply ();
6396          }
6397
6398        Cmt::configure_current_cmtpath ();
6399      }
6400  }
6401
6402  /**
6403   *   project
6404   */
6405  void fill_for_project ()
6406  {
6407    if (current_style == none_style) return;
6408
6409    cmt_string project_name;
6410    Project* project = Project::get_current ();
6411    if (project != 0)
6412      {
6413        project_name = project->get_name ();
6414      }
6415
6416    buffer = "macro project \"";
6417    buffer += project_name;
6418    buffer += "\"";
6419    apply ();
6420  }
6421
6422  /**
6423   *   use_requirements
6424   */
6425  void fill_for_use_requirements ()
6426  {
6427    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6428
6429    if (Uses.size () == 0) return;
6430
6431    if (!Symbol::is_selected ("use_requirements"))
6432      {
6433        buffer  = "macro use_requirements \"";
6434        buffer += "requirements ";
6435       
6436        for (int number = 0; number < Uses.size (); number++)
6437          {
6438            Use* use = Uses[number];
6439           
6440            if (use->discarded) continue;
6441           
6442            if (use->located ())
6443              {
6444                buffer += "$(";
6445                buffer += use->prefix;
6446                buffer += "ROOT)";
6447                buffer += fs;
6448               
6449                if (use->style == mgr_style) buffer += "mgr";
6450                else buffer += "cmt";
6451               
6452                buffer += fs;
6453                buffer += "requirements ";
6454              }
6455          }
6456       
6457        buffer += "\"";
6458       
6459        apply ();
6460      }
6461  }
6462
6463  /**
6464   *   use_includes
6465   */
6466  void fill_for_use_includes ()
6467  {
6468    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6469
6470    if (Uses.size () == 0) return;
6471
6472    if (!Symbol::is_selected ("use_includes"))
6473      {
6474        buffer = "macro_append use_includes \' ";
6475       
6476        for (int number = 0; number < Uses.size (); number++)
6477          {
6478            Use* use = Uses[number];
6479           
6480            if (use->discarded) continue;
6481
6482            Package* p = use->get_package ();
6483            if (p->is_cmt ()) continue;
6484
6485            if (Cmt::get_debug ())
6486              {
6487                cout << "fill use_includes for " << use->get_package_name () 
6488                     << " discarded=" << use->discarded
6489                     << " auto_imports=" << use->auto_imports << endl;
6490              }
6491           
6492            if (use->auto_imports == Off) continue;
6493           
6494            use->fill_includes_macro (buffer);
6495          }
6496       
6497        buffer += "\'";
6498       
6499        apply ();
6500      }
6501  }
6502
6503  /**
6504   *   use_fincludes
6505   */
6506  void fill_for_use_fincludes ()
6507  {
6508    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6509
6510    if (Uses.size () == 0) return;
6511
6512    if (!Symbol::is_selected ("use_fincludes"))
6513      {
6514        buffer = "macro_append use_fincludes \" $(use_includes)\"";
6515        apply ();
6516      }
6517  }
6518
6519  /**
6520   *   use_stamps
6521   */
6522  void fill_for_use_stamps ()
6523  {
6524    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6525
6526    if (Uses.size () == 0) return;
6527
6528    if (!Symbol::is_selected ("use_stamps"))
6529      {
6530        buffer = "macro use_stamps \"";
6531        (Use::current()).fill_macro (buffer, "stamps");
6532       
6533        for (int number = 0; number < Uses.size (); number++)
6534          {
6535            Use* use = Uses[number];
6536           
6537            if (use->discarded) continue;
6538
6539            Package* p = use->get_package ();
6540            if (p->is_cmt ()) continue;
6541           
6542            use->fill_macro (buffer, "stamps");
6543          }
6544       
6545        buffer += "\"";
6546       
6547        apply ();
6548      }
6549  }
6550
6551  /**
6552   *   use_cflags
6553   */
6554  void fill_for_use_cflags ()
6555  {
6556    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6557
6558    if (Uses.size () == 0) return;
6559
6560    if (!Symbol::is_selected ("use_cflags"))
6561      {
6562        Use::fill_macro_all (buffer, "cflags");
6563        apply ();
6564      }
6565  }
6566
6567  /**
6568   *   use_pp_cflags
6569   */
6570  void fill_for_use_pp_cflags ()
6571  {
6572    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6573
6574    if (Uses.size () == 0) return;
6575
6576    if (!Symbol::is_selected ("use_pp_cflags"))
6577      {
6578        Use::fill_macro_all (buffer, "pp_cflags");
6579        apply ();
6580      }
6581  }
6582
6583  /**
6584   *   use_cppflags
6585   */
6586  void fill_for_use_cppflags ()
6587  {
6588    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6589
6590    if (Uses.size () == 0) return;
6591
6592    if (!Symbol::is_selected ("use_cppflags"))
6593      {
6594        Use::fill_macro_all (buffer, "cppflags");
6595        apply ();
6596      }
6597  }
6598
6599  /**
6600   *   use_pp_cppflags
6601   */
6602  void fill_for_use_pp_cppflags ()
6603  {
6604    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6605
6606    if (Uses.size () == 0) return;
6607
6608    if (!Symbol::is_selected ("use_pp_cppflags"))
6609      {
6610        Use::fill_macro_all (buffer, "pp_cppflags");
6611        apply ();
6612      }
6613  }
6614
6615  /**
6616   *   use_fflags
6617   */
6618  void fill_for_use_fflags ()
6619  {
6620    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6621
6622    if (Uses.size () == 0) return;
6623
6624    if (!Symbol::is_selected ("use_fflags"))
6625      {
6626        Use::fill_macro_all (buffer, "fflags");
6627        apply ();
6628      }
6629  }
6630
6631  /**
6632   *   use_pp_fflags
6633   */
6634  void fill_for_use_pp_fflags ()
6635  {
6636    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6637
6638    if (Uses.size () == 0) return;
6639
6640    if (!Symbol::is_selected ("use_pp_fflags"))
6641      {
6642        Use::fill_macro_all (buffer, "pp_fflags");
6643        apply ();
6644      }
6645  }
6646
6647  /**
6648   *   use_linkopts
6649   */
6650  void fill_for_use_linkopts ()
6651  {
6652    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6653
6654    if (Uses.size () == 0) return;
6655
6656    if (!Symbol::is_selected ("use_linkopts"))
6657      {
6658        Use::fill_macro_all (buffer, "linkopts");
6659        apply ();
6660      }
6661  }
6662
6663  /**
6664   *   use_libraries
6665   */
6666  void fill_for_use_libraries ()
6667  {
6668    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6669
6670    if (Uses.size () == 0) return;
6671
6672    if (!Symbol::is_selected ("use_libraries"))
6673      {
6674        buffer  = "macro use_libraries \"";
6675
6676        for (int number = 0; number < Uses.size (); number++)
6677          {
6678            Use* use = Uses[number];
6679           
6680            if (use->discarded) continue;
6681           
6682            Package* p = use->get_package ();
6683            if (p->is_cmt ()) continue;
6684
6685            use->fill_macro (buffer, "libraries");
6686          }
6687       
6688        buffer += "\"";
6689       
6690        apply ();
6691      }
6692  }
6693
6694  /**
6695   *   includes
6696   */
6697  void fill_for_includes ()
6698  {
6699    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6700
6701    if (Uses.size () == 0) return;
6702
6703    if (!Symbol::is_selected ("includes"))
6704      {
6705        buffer = "macro_append includes \' ";
6706
6707        Use& use = Use::current();
6708
6709        if (use.include_path == "")
6710          {
6711            buffer += "$(ppcmd)\"$(srcdir)\" ";
6712          }
6713        else if (use.include_path != "none")
6714          {
6715            buffer += "$(ppcmd)\"";
6716            buffer += use.include_path;
6717            buffer += "\" ";
6718          }
6719       
6720        for (int include_number = 0;
6721             include_number < use.includes.size ();
6722             include_number++)
6723          {
6724            Include& incl = use.includes[include_number];
6725           
6726            buffer += "$(ppcmd)\"";
6727            buffer += incl.name;
6728            buffer += "\" ";
6729          }
6730       
6731        buffer += "$(use_includes)\'";
6732       
6733        apply ();
6734      }
6735  }
6736
6737  /**
6738   *   fincludes
6739   */
6740  void fill_for_fincludes ()
6741  {
6742    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6743
6744    if (Uses.size () == 0) return;
6745
6746    if (!Symbol::is_selected ("fincludes"))
6747      {
6748        buffer = "macro_append fincludes \" $(includes)\"";
6749        apply ();
6750      }
6751  }
6752
6753  /**
6754   *  Macros specific to constituents.
6755   *  This includes the compiler flags
6756   *  and fills in these macros from uses packages. This takes care
6757   *  of -no_auto_imports and -import= directives
6758   *
6759   *    <constituent>_use_linkopts
6760   *    <prefix>_<constituent>_cflags
6761   *    <prefix>_<constituent>_pp_cflags
6762   *    <prefix>_<constituent>_cppflags
6763   *    <prefix>_<constituent>_pp_cppflags
6764   *    <prefix>_<constituent>_fflags
6765   *    <prefix>_<constituent>_pp_fflags
6766   *    <constituent>linkopts
6767   *    <constituent>_GUID
6768   *
6769   */
6770  void fill_for_all_constituents ()
6771  {
6772    /// First, finish the parsing of constituent parameters.
6773    Constituent::parse_all ();
6774
6775    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6776
6777    const Constituent::ConstituentVector& constituents =
6778      Constituent::constituents ();
6779
6780 
6781    /// Prepare the auto_imports states in a vector
6782
6783    cmt_vector<bool> base_auto_imports_states;
6784
6785    base_auto_imports_states.resize (Uses.size ());
6786
6787    int number;
6788
6789    for (number = 0; number < Uses.size (); number++)
6790      {
6791        Use* use = Uses[number];
6792        base_auto_imports_states[number] = (use->auto_imports != Off);
6793      }
6794
6795    /// Now scan all constituents
6796
6797    for (number = 0; number < constituents.size (); number++)
6798      {
6799        const Constituent& constituent = constituents[number];
6800
6801        if (Cmt::get_debug ())
6802          {
6803            cout << "Checking " << constituent.name  << " against imports requests" << endl;
6804          }
6805
6806        Use::UsePtrVector imports;
6807        int i;
6808
6809        /**
6810         *  Problem for imports in constituents.
6811         *
6812         *     1) use_xxx has holes due to the corresponding
6813         *         -no_auto_imports options attached to some
6814         *        use statements (including the transitive ones)
6815         *
6816         *     2) the -import=yyy options provided to a given constituent
6817         *        should restore the appropriate holes as well as
6818         *        all transitive ones.
6819         *
6820         *     3) for use_linkopts, missing pieces must be filled at
6821         *        the right position. (for others, order is not relevant
6822         *        while transitive access is required for all)
6823         *
6824         */
6825
6826        if (constituent.type == Document) continue;
6827        if (constituent.imports.size () == 0) 
6828          {
6829            buffer = "macro_append ";
6830            buffer += constituent.name;
6831            buffer += "_use_linkopts ";
6832            buffer += " \" ";
6833       
6834            current_use->fill_macro (buffer, "linkopts");
6835       
6836            for (i = 0; i < Uses.size (); i++)
6837              {
6838                if (base_auto_imports_states[i])
6839                  {
6840                    Use* u = Uses[i];
6841               
6842                    if (u->discarded) continue;
6843
6844                    Package* p = u->get_package ();
6845                    if (p->is_cmt ()) continue;
6846                   
6847                    u->fill_macro (buffer, "linkopts");
6848                  }
6849              }
6850            buffer += "\"";
6851            apply ();
6852
6853          /*
6854            buffer = "macro_append ";
6855            buffer += constituent.name;
6856            buffer += "_use_linkopts ";
6857
6858            buffer += " \" $(use_linkopts)\"";
6859            apply ();
6860            */
6861
6862            continue;
6863          }
6864
6865        /**
6866         * Create a private copy of the state vector. This private copy
6867         * will be updated according to -import=xxx modifiers for the
6868         * current constituent.
6869         */
6870        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
6871
6872        for (i = 0; i < constituent.imports.size (); i++)
6873          {
6874            const cmt_string& import = constituent.imports[i];
6875           
6876            //
6877            // Resolve the imported uses
6878            //
6879
6880            int use_index = Use::find_index (import, "", "");
6881
6882            if (use_index >= 0)
6883              {
6884                Use* u = Uses[use_index];
6885           
6886                if (u->discarded) continue;
6887
6888                if (Cmt::get_debug ())
6889                  {
6890                    cout << constituent.name  << " needs imports " << import << " "
6891                         << use_index << " " 
6892                         << u->get_package()->get_name() << endl;
6893                  }
6894
6895                Package* p = u->get_package ();
6896                if (p->is_cmt ()) continue;
6897
6898                if (u->auto_imports != Off) continue;
6899
6900                Use::set_auto_imports_state (use_index, auto_imports_states);
6901              }
6902          }
6903
6904        if (Cmt::get_debug ())
6905          {
6906            cout << constituent.name  << " has imports " << endl;
6907          }
6908
6909
6910        /**
6911         *   Find all newly exposed packages and precompute this list inside
6912         *   a vector.
6913         */
6914        for (i = 0; i < base_auto_imports_states.size (); i++)
6915          {
6916            if (auto_imports_states[i] != base_auto_imports_states[i])
6917              {
6918                Use* u = Uses[i];
6919
6920                if (u->discarded) continue;
6921
6922                Package* p = u->get_package ();
6923                if (p->is_cmt ()) continue;
6924
6925                if (Cmt::get_debug ())
6926                  {
6927                    cout << constituent.name  << " has import " << p->get_name () << endl;
6928                  }
6929
6930                if (u->auto_imports != Off) continue;
6931
6932                imports.push_back (u);
6933              }
6934          }
6935       
6936        if (imports.size () == 0) continue;
6937
6938        cmt_string prefix;
6939           
6940        //
6941        // Documents are not considered
6942        //
6943        switch (constituent.type)
6944          {
6945          case Application:
6946            prefix = "app_";
6947            break;
6948          case Library:
6949            prefix = "lib_";
6950            break;
6951          }
6952           
6953        buffer = "macro_append ";
6954        buffer += prefix;
6955        buffer += constituent.name;
6956        buffer += "_cflags ";
6957        buffer += " \' ";
6958        for (i = 0; i < imports.size (); i++)
6959          {
6960            Use* u = imports[i];
6961           
6962            u->fill_includes_macro (buffer);
6963            u->fill_macro (buffer, "cflags");
6964          }
6965        buffer += "\'";
6966        apply ();
6967       
6968        buffer = "macro_append ";
6969        buffer += prefix;
6970        buffer += constituent.name;
6971        buffer += "_pp_cflags ";
6972        buffer += " \" ";
6973        for (i = 0; i < imports.size (); i++)
6974          {
6975            Use* u = imports[i];
6976           
6977            u->fill_macro (buffer, "pp_cflags");
6978          }
6979        buffer += "\"";
6980        apply ();
6981       
6982        buffer = "macro_append ";
6983        buffer += prefix;
6984        buffer += constituent.name;
6985        buffer += "_cppflags ";
6986        buffer += " \' ";
6987        for (i = 0; i < imports.size (); i++)
6988          {
6989            Use* u = imports[i];
6990           
6991            u->fill_includes_macro (buffer);
6992            u->fill_macro (buffer, "cppflags");
6993          }
6994        buffer += "\'";
6995        apply ();
6996       
6997        buffer = "macro_append ";
6998        buffer += prefix;
6999        buffer += constituent.name;
7000        buffer += "_pp_cppflags ";
7001        buffer += " \" ";
7002        for (i = 0; i < imports.size (); i++)
7003          {
7004            Use* u = imports[i];
7005           
7006            u->fill_macro (buffer, "pp_cppflags");
7007          }
7008        buffer += "\"";
7009        apply ();
7010       
7011        buffer = "macro_append ";
7012        buffer += prefix;
7013        buffer += constituent.name;
7014        buffer += "_fflags ";
7015        buffer += " \' ";
7016        for (i = 0; i < imports.size (); i++)
7017          {
7018            Use* u = imports[i];
7019           
7020            u->fill_includes_macro (buffer);
7021            u->fill_macro (buffer, "fflags");
7022          }
7023        buffer += "\'";
7024        apply ();
7025       
7026        buffer = "macro_append ";
7027        buffer += prefix;
7028        buffer += constituent.name;
7029        buffer += "_pp_fflags ";
7030        buffer += " \" ";
7031        for (i = 0; i < imports.size (); i++)
7032          {
7033            Use* u = imports[i];
7034           
7035            u->fill_macro (buffer, "pp_fflags");
7036          }
7037        buffer += "\"";
7038        apply ();
7039       
7040        /**
7041           *  Setting ${CONSTITUENT}linkopts is a temporary solution
7042           *  until the backward compatibility solution for a proper
7043           *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
7044           *  is acheived.
7045           *
7046           */
7047       buffer = "macro_append ";
7048       buffer += constituent.name;
7049       buffer += "linkopts ";
7050       buffer += " \" ";
7051       for (i = 0; i < imports.size (); i++)
7052         {
7053           Use* u = imports[i];
7054           
7055           u->fill_macro (buffer, "linkopts");
7056         }
7057       buffer += "\"";
7058       apply ();
7059       
7060       /**
7061         *  Only for linkopts we take care of the order. This means
7062        *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
7063         *
7064         *  (see the application fragments)
7065         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
7066         */
7067        buffer = "macro_append ";
7068        buffer += constituent.name;
7069        buffer += "_use_linkopts ";
7070        buffer += " \" ";
7071       
7072        current_use->fill_macro (buffer, "linkopts");
7073       
7074        for (i = 0; i < Uses.size (); i++)
7075          {
7076            if (auto_imports_states[i])
7077              {
7078                Use* u = Uses[i];
7079               
7080                if (u->discarded) continue;
7081               
7082                Package* p = u->get_package ();
7083                if (p->is_cmt ()) continue;
7084
7085                u->fill_macro (buffer, "linkopts");
7086              }
7087          }
7088        buffer += "\"";
7089        apply ();
7090
7091        //==== GLAST addition for vs.net ==========
7092        buffer = "macro ";
7093        buffer += constituent.name;
7094        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
7095        apply ();
7096      }
7097  }
7098
7099  /**
7100   *   Macros implied or required to manage constituents.
7101   */
7102  void fill_for_constituent_macros ()
7103  {
7104    int number;
7105    cmt_string temp;
7106
7107    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
7108 
7109    if (!Symbol::is_selected ("constituents"))
7110      {
7111        temp = "macro_append constituents \" ";
7112       
7113        for (number = 0; number < constituents.size (); number++)
7114          {
7115            const Constituent& constituent = constituents[number];
7116           
7117            if (constituent.group == 0)
7118              {
7119                temp += constituent.name;
7120                temp += " ";
7121              }
7122          }
7123       
7124        temp += "\"";
7125       
7126        SyntaxParser::parse_requirements_line (temp, current_use);
7127      }
7128   
7129    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
7130                                           current_use);
7131   
7132    if (!Symbol::is_selected ("constituentsclean"))
7133      {
7134        temp = "macro_append constituentsclean \" ";
7135       
7136        for (number = constituents.size () - 1; number >= 0 ; number--)
7137          {
7138            const Constituent& constituent = constituents[number];
7139           
7140            if (constituent.group == 0)
7141              {
7142                temp += constituent.name;
7143                temp += "clean ";
7144              }
7145          }
7146       
7147        temp += "\"";
7148       
7149        SyntaxParser::parse_requirements_line (temp, current_use);
7150      }
7151   
7152    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
7153                                           current_use);
7154   
7155    const Group::GroupVector& groups = Group::groups ();
7156   
7157    for (number = 0; number < groups.size (); number++)
7158      {
7159        const Group& group = groups[number];
7160       
7161        temp = "macro_append ";
7162        temp += group.name ();
7163        temp += "_constituents \" ";
7164       
7165        int i;
7166       
7167        for (i = 0; i < constituents.size (); i++)
7168          {
7169            const Constituent& constituent = constituents[i];
7170           
7171            if ((constituent.group != 0) && 
7172                (group.name () == constituent.group->name ()))
7173              {
7174                temp += constituent.name;
7175                temp += " ";
7176              }
7177          }
7178       
7179        temp += "\"";
7180       
7181        SyntaxParser::parse_requirements_line (temp, current_use);
7182       
7183        temp = "macro_append ";
7184        temp += group.name ();
7185        temp += "_constituentsclean \" ";
7186       
7187        for (i = constituents.size () - 1; i >= 0 ; i--)
7188          {
7189            const Constituent& constituent = constituents[i];
7190           
7191            if ((constituent.group != 0) && 
7192                (group.name () == constituent.group->name ()))
7193              {
7194                temp += constituent.name;
7195                temp += "clean ";
7196              }
7197          }
7198       
7199        temp += "\"";
7200       
7201        SyntaxParser::parse_requirements_line (temp, current_use);
7202    }
7203  }
7204
7205  /**
7206   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
7207   */
7208  void fill_for_install_area ()
7209  {
7210    CmtPathPattern::apply_all ();
7211
7212    if (get_strategy ("InstallArea"))
7213      {
7214        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
7215
7216        //cout << "#IA7>" << endl;
7217       
7218        ia_mgr.setup ();
7219      }
7220  }
7221
7222  /**
7223   * Macros to be defined once current_package is known
7224   * and even before reading its requirements file.
7225   */
7226  void fill_for_current_package (const cmt_string& current_dir)
7227  {
7228    fill_for_tag ();
7229    fill_for_package (current_dir);
7230  }
7231
7232private:
7233  cmt_string fs;
7234  cmt_string buffer;
7235  CmtSystem::cmt_string_vector vb;
7236  cmt_string pwd;
7237  Use* current_use;
7238  cmt_string current_tag; 
7239  cmt_string current_package; 
7240  cmt_string current_version; 
7241  cmt_string current_prefix; 
7242  CmtDirStyle current_style;
7243};
7244
7245//----------------------------------------------------------
7246void Cmt::set_current_access (AccessMode mode)
7247{
7248  Me.m_current_access = mode;
7249}
7250
7251//----------------------------------------------------------
7252void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
7253{
7254  Me.m_scope_filtering_mode = mode;
7255}
7256
7257//----------------------------------------------------------
7258void Cmt::set_standard_macros ()
7259{
7260  if (Me.m_standard_macros_done) return;
7261
7262  Me.m_standard_macros_done = true;
7263
7264  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7265  Use& current_use = Use::current ();
7266
7267  cmt_string fs = CmtSystem::file_separator ();
7268
7269  cmt_string pwd = CmtSystem::pwd ();
7270
7271  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
7272  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
7273  else Me.m_current_style = none_style;
7274
7275  {
7276    cmt_string v;
7277    CmtSystem::dirname (pwd, v);
7278    CmtSystem::basename (v, v);
7279    if (!CmtSystem::is_version_directory (v))
7280      {
7281        Me.m_current_style = no_version_style;
7282      }
7283  }
7284
7285  // Prepare computation of the best form for relative path from current directory
7286  // to package directories.
7287  CmtSystem::cmt_string_vector vb;
7288  CmtSystem::split (pwd, fs, vb);
7289
7290
7291    /**
7292     *    TAG management
7293     */
7294
7295  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
7296
7297  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
7298
7299  if (Me.m_current_tag != "")
7300    {
7301        // this is when some -tag= argument was used.
7302      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
7303    }
7304  else if (Symbol::is_selected ("CMTCONFIG"))
7305    {
7306        // This is when CMTCONFIG has been set from some requirements file
7307      Symbol* macro = Symbol::find ("CMTCONFIG");
7308      if (macro != 0)
7309        {
7310          Me.m_current_tag = macro->build_macro_value ();
7311          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
7312        }
7313    }
7314  else
7315    {
7316        // this is when no -tag= argument was used.
7317      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
7318      if (current_use.get_package_name () == "CMT")
7319        {
7320          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
7321        }
7322      else
7323        {
7324          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
7325        }
7326
7327      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
7328    }
7329
7330  if (Me.m_debug)
7331    {
7332      cout << "set_standard_macro3>" << endl;
7333    }
7334
7335  StandardMacroBuilder builder (Me.m_current_tag,
7336                                Me.m_current_package,
7337                                Me.m_current_version,
7338                                Me.m_current_prefix,
7339                                Me.m_current_style);
7340
7341
7342    //
7343    //  Definitions for installation area mechanisms
7344    //
7345  /*
7346  if (get_strategy ("InstallArea"))
7347    {
7348      CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
7349
7350      //cout << "#IA6>" << endl;
7351
7352      ia_mgr.setup_current_installarea ();
7353    }
7354  */
7355
7356  builder.fill_for_current_package (Me.m_current_dir);
7357
7358  builder.fill_for_branches ();
7359  builder.fill_for_project ();
7360
7361  builder.fill_for_install_area ();
7362
7363  builder.fill_for_use_requirements ();
7364  builder.fill_for_use_includes ();
7365  builder.fill_for_use_fincludes ();
7366  builder.fill_for_use_stamps ();
7367  builder.fill_for_use_cflags ();
7368  builder.fill_for_use_pp_cflags ();
7369  builder.fill_for_use_cppflags ();
7370  builder.fill_for_use_pp_cppflags ();
7371  builder.fill_for_use_fflags ();
7372  builder.fill_for_use_pp_fflags ();
7373  builder.fill_for_use_linkopts ();
7374  builder.fill_for_use_libraries ();
7375  builder.fill_for_includes ();
7376  builder.fill_for_fincludes ();
7377  builder.fill_for_all_constituents ();
7378  builder.fill_for_constituent_macros ();
7379}
7380
7381void Cmt::set_all_sets_done ()
7382{
7383  Me.m_all_sets_done = true;
7384}
7385
7386void Cmt::reset_all_sets_done ()
7387{
7388  Me.m_all_sets_done = false;
7389}
7390
7391//----------------------------------------------------------
7392void Cmt::use_cmt ()
7393{
7394  UseRef use;
7395  bool recursive_copy = Me.m_recursive;
7396  bool debug_copy = Me.m_debug;
7397
7398  if (Me.m_default_path.size () <= 0) return;
7399  if (Me.m_current_package == "CMT") return;
7400
7401  Me.m_recursive = true;
7402  Me.m_debug = false;
7403  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", 0);
7404  Me.m_recursive = recursive_copy;
7405  Me.m_debug = debug_copy;
7406}
7407
7408//----------------------------------------------------------
7409void Cmt::use_home_requirements ()
7410{
7411  use_special_requirements (Me.m_cmt_home, 
7412                            CmtSystem::get_home_package (), 
7413                            "requirements");
7414}
7415
7416//----------------------------------------------------------
7417void Cmt::use_user_context_requirements ()
7418{
7419  use_special_requirements (Me.m_cmt_user_context, 
7420                            CmtSystem::get_user_context_package (), 
7421                            "requirements");
7422}
7423
7424//----------------------------------------------------------
7425void Cmt::use_special_requirements (const cmt_string& path, 
7426                                    const cmt_string& name, 
7427                                    const cmt_string& file_name)
7428{
7429  if (path == "") 
7430    {
7431      return;
7432    }
7433
7434  UseRef use;
7435  bool recursive_copy = Me.m_recursive;
7436
7437  if (Me.m_default_path.size () <= 0) return;
7438  if (Me.m_current_package == "CMT") return;
7439
7440  Me.m_recursive = true;
7441
7442  use = Use::add (path, name, "v0", "", "", 0);
7443
7444  cmt_string f = Me.m_cmt_user_context;
7445  f += CmtSystem::file_separator ();
7446  f += file_name;
7447  SyntaxParser::parse_requirements (f, use);
7448
7449  Me.m_recursive = recursive_copy;
7450}
7451
7452//-------------------------------------------------
7453void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
7454                            const cmt_string& separator,
7455                            cmt_string& result)
7456{
7457  result.erase (0);
7458
7459  for (int i = 0; i < v.size (); i++)
7460    {
7461      const cmt_string& s = v[i];
7462      if (s == "") continue;
7463
7464      if (i > 0) result += separator;
7465      result += v[i];
7466    }
7467}
7468
7469//-------------------------------------------------
7470cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
7471{
7472  cmt_string result;
7473
7474  vector_to_string (v, " ", result);
7475
7476  return (result);
7477}
Note: See TracBrowser for help on using the repository browser.