source: CMT/v1r19/source/cmt_parser.cxx @ 11

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

Changing eol-style property

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