source: CMT/HEAD/source/cmt_parser.cxx @ 463

Last change on this file since 463 was 463, checked in by rybkin, 16 years ago

See C.L. 364

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