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

Last change on this file since 494 was 487, checked in by rybkin, 15 years ago

See C.L. 382

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