source: CMT/v1r18p20050901/source/cmt_parser.cxx @ 634

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

Add structure_strategy - see CL#278

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