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

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

See C.L. 379

  • Property svn:eol-style set to native
File size: 203.9 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  Group::show_all ();
3889}
3890
3891//----------------------------------------------------------
3892void Cmt::do_show_include_dirs (const ArgParser& /*ap*/)
3893{
3894  cmt_string temp;
3895
3896  Use& use = Use::current();
3897
3898  set_standard_macros ();
3899
3900  if (use.include_path == "")
3901    {
3902      temp += "$(src) ";
3903    }
3904  else if (use.include_path != "none")
3905    {
3906      temp += use.include_path;
3907      temp += " ";
3908    }
3909
3910  for (int include_number = 0;
3911       include_number < use.includes.size ();
3912       include_number++)
3913    {
3914      Include& incl = use.includes[include_number];
3915
3916      if (incl.name == "") continue;
3917
3918      temp += incl.name;
3919      temp += " ";
3920    }
3921
3922  cout << temp << endl;
3923}
3924
3925//----------------------------------------------------------
3926void Cmt::do_show_language (const ArgParser& ap)
3927{
3928  if (ap.arguments.size () > 0) 
3929    {
3930      set_standard_macros ();
3931      Language::show (ap.arguments[0]);
3932    }
3933}
3934
3935//----------------------------------------------------------
3936void Cmt::do_show_languages (const ArgParser& /*ap*/)
3937{
3938  set_standard_macros ();
3939  Language::show_all ();
3940}
3941
3942//----------------------------------------------------------
3943void Cmt::do_show_macro (const ArgParser& ap)
3944{
3945  cmt_string target;
3946
3947  if (ap.arguments.size () > 0) target = ap.arguments[0];
3948
3949  Symbol* symbol;
3950
3951  set_standard_macros ();
3952
3953  symbol = Symbol::find (target);
3954
3955  if (symbol == 0) 
3956    {
3957      cmt_string t = " ";
3958      t += target;
3959      t += " is not defined ";
3960
3961      CmtError::set (CmtError::symbol_not_found, t);
3962
3963      return;
3964    }
3965  else
3966    {
3967      cmt_string t = target;
3968      t += " is a ";
3969
3970      if ((Me.m_action == action_show_macro) ||
3971          (Me.m_action == action_show_macro_value))
3972        {
3973          if (symbol->type != Symbol::SymbolMacro)
3974            {
3975              if (symbol->type == Symbol::SymbolAction)
3976                {
3977                  t += "action";
3978                }
3979              else if (symbol->type == Symbol::SymbolSet)
3980                {
3981                  t += "set";
3982                }
3983              else if (symbol->type == Symbol::SymbolPath)
3984                {
3985                  t += "path";
3986                }
3987              else if (symbol->type == Symbol::SymbolAlias)
3988                {
3989                  t += "alias";
3990                }
3991
3992              CmtError::set (CmtError::warning, t);
3993            }
3994        }
3995      else if ((Me.m_action == action_show_set) ||
3996               (Me.m_action == action_show_set_value))
3997        {
3998          if ((symbol->type != Symbol::SymbolSet) &&
3999              (symbol->type != Symbol::SymbolPath) &&
4000              (symbol->type != Symbol::SymbolAction) &&
4001              (symbol->type != Symbol::SymbolAlias))
4002            {
4003              t += "macro";
4004
4005              CmtError::set (CmtError::warning, t);
4006            }
4007        }
4008    }
4009
4010  if (symbol->value_lists.size () < 1) return;
4011
4012  symbol->show_macro (ap.mode);
4013}
4014
4015//----------------------------------------------------------
4016void Cmt::do_show_macro_names (const ArgParser& ap)
4017{
4018  if (ap.arguments.size () > 0)
4019    {
4020      const cmt_string& pattern = ap.arguments[0];
4021      print_symbol_names (ap.mode, pattern);
4022    }
4023  else
4024    {
4025      print_symbol_names (ap.mode);
4026    }
4027}
4028
4029//----------------------------------------------------------
4030void Cmt::do_show_macro_value (const ArgParser& ap)
4031{
4032  do_show_macro (ap);
4033}
4034
4035//----------------------------------------------------------
4036void Cmt::do_show_macros (const ArgParser& ap)
4037{
4038  if (ap.arguments.size () > 0)
4039    {
4040      const cmt_string& pattern = ap.arguments[0];
4041      print_macros (ap.mode, pattern);
4042    }
4043  else
4044    {
4045      print_macros (ap.mode);
4046    }
4047}
4048
4049//----------------------------------------------------------
4050void Cmt::do_show_manager (const ArgParser& /*ap*/)
4051{
4052  Use& use = Use::current();
4053
4054  cout << use.manager << endl;
4055}
4056
4057//----------------------------------------------------------
4058void Cmt::do_show_packages (const ArgParser& ap)
4059{
4060  cmt_string path_name;
4061
4062  if (ap.arguments.size () > 0) path_name = ap.arguments[0];
4063
4064  PathScanner   scanner;
4065  PackageViewer viewer;
4066
4067  if (path_name == "")
4068    {
4069      Project::scan_paths (scanner, viewer);
4070    }
4071  else
4072    {
4073      scanner.scan_path (path_name, viewer);
4074    }
4075}
4076
4077//----------------------------------------------------------
4078void Cmt::do_show_path (const ArgParser& ap)
4079{
4080  Project::show_paths (ap.arguments);
4081}
4082
4083//----------------------------------------------------------
4084void Cmt::do_show_pattern (const ArgParser& ap)
4085{
4086  cmt_string name;
4087  if (ap.arguments.size () > 0) name = ap.arguments[0];
4088  Pattern::show (name);
4089}
4090
4091//----------------------------------------------------------
4092void Cmt::do_show_pattern_names (const ArgParser& /*ap*/)
4093{
4094  Pattern::show_all_names ();
4095}
4096
4097//----------------------------------------------------------
4098void Cmt::do_show_patterns (const ArgParser& /*ap*/)
4099{
4100  Pattern::show_all ();
4101}
4102
4103//----------------------------------------------------------
4104void Cmt::do_show_projects (const ArgParser& /*ap*/)
4105{
4106  Project::show_all ();
4107}
4108
4109//----------------------------------------------------------
4110void Cmt::do_show_pwd (const ArgParser& /*ap*/)
4111{
4112  cout << Me.m_current_dir << endl;
4113}
4114
4115//----------------------------------------------------------
4116void Cmt::do_show_setup (const ArgParser& ap)
4117{
4118  cout << "----------> uses" << endl;
4119  do_show_uses (ap);
4120
4121  cout << "----------> tags" << endl;
4122  do_show_tags (ap);
4123
4124  cout << "----------> CMTPATH" << endl;
4125  do_show_path (ap);
4126}
4127
4128//----------------------------------------------------------
4129void Cmt::do_show_set (const ArgParser& ap)
4130{
4131  do_show_macro (ap);
4132}
4133
4134//----------------------------------------------------------
4135void Cmt::do_show_set_names (const ArgParser& ap)
4136{
4137  if (ap.arguments.size () > 0)
4138    {
4139      const cmt_string& pattern = ap.arguments[0];
4140      print_symbol_names (ap.mode, pattern);
4141    }
4142  else
4143    {
4144      print_symbol_names (ap.mode);
4145    }
4146}
4147
4148//----------------------------------------------------------
4149void Cmt::do_show_set_value (const ArgParser& ap)
4150{
4151  do_show_macro (ap);
4152}
4153
4154//----------------------------------------------------------
4155void Cmt::do_show_sets (const ArgParser& ap)
4156{
4157  if (ap.arguments.size () > 0)
4158    {
4159      const cmt_string& pattern = ap.arguments[0];
4160      print_macros (ap.mode, pattern);
4161    }
4162  else
4163    {
4164      print_macros (ap.mode);
4165    }
4166}
4167
4168//----------------------------------------------------------
4169void Cmt::do_show_strategies (const ArgParser& /*ap*/)
4170{
4171  Use& current_use = Use::current ();
4172
4173  Project::show_specified_strategies_for_all ();
4174
4175  Project* p = Project::get_current ();
4176
4177  /*
4178    if (p != 0) p->show ();
4179    else cout << "No current project" << endl;
4180  */
4181
4182  cout << "Build strategy     : ";
4183
4184  if (current_use.get_strategy ("BuildPrototypes"))
4185    {
4186      cout << "prototypes";
4187    }
4188  else
4189    {
4190      cout << "no_prototypes";
4191    }
4192 
4193  if (current_use.get_strategy ("InstallArea"))
4194    {
4195      cout << " with_installarea";
4196    }
4197  else
4198    {
4199      cout << " without_installarea";
4200    }
4201 
4202  cout << endl;
4203
4204  cout << "Setup strategy     : ";
4205 
4206  if (current_use.get_strategy ("SetupConfig"))
4207    {
4208      cout << "config";
4209    }
4210  else
4211    {
4212      cout << "no_config";
4213    }
4214 
4215  if (current_use.get_strategy ("SetupRoot"))
4216    {
4217      cout << " root";
4218    }
4219  else
4220    {
4221      cout << " no_root";
4222    }
4223 
4224  if (current_use.get_strategy ("SetupCleanup"))
4225    {
4226      cout << " cleanup";
4227    }
4228  else
4229    {
4230      cout << " no_cleanup";
4231    }
4232
4233  cout << endl;
4234 
4235  cout << "Structure strategy : ";
4236 
4237  if (current_use.get_strategy ("VersionDirectory"))
4238    {
4239      cout << "with_version_directory";
4240    }
4241  else
4242    {
4243      cout << "without_version_directory";
4244    }
4245 
4246  cout << endl;
4247
4248  if (Me.m_current_structuring_style != default_structuring_style)
4249    {
4250      cout << "Structuring style  : ";
4251
4252      switch (Me.m_current_structuring_style)
4253        {
4254        case without_version_directory:
4255          cout << "without_version_directory";
4256          break;
4257        case with_version_directory:
4258          cout << "with_version_directory";
4259          break;
4260        }
4261
4262      cout << endl;
4263    }
4264}
4265
4266//----------------------------------------------------------
4267void Cmt::do_show_tags (const ArgParser& /*ap*/)
4268{
4269  Tag::TagPtrVector tags = Tag::tags ();
4270  int index;
4271
4272  set_standard_macros ();
4273
4274  for (index = 0; index < tags.size (); index++)
4275    {
4276      const Tag* tag = tags[index];
4277      if (tag != 0)
4278        {
4279          tag->show (Me.m_quiet);
4280        }
4281    }
4282}
4283
4284//----------------------------------------------------------
4285void Cmt::do_show_use_paths (const ArgParser& ap)
4286{
4287  const cmt_string& to_name = ap.arguments[0];
4288
4289  Use* current = &(Use::current());
4290
4291  current->get_all_clients (to_name);
4292}
4293
4294//----------------------------------------------------------
4295void Cmt::do_show_uses (const ArgParser& /*ap*/)
4296{
4297  Use::show_all ();
4298}
4299
4300//----------------------------------------------------------
4301void Cmt::do_show_version (const ArgParser& /*ap*/)
4302{
4303  cout << Me.m_current_version << endl;
4304}
4305
4306//----------------------------------------------------------
4307void Cmt::do_show_versions (const ArgParser& ap)
4308{
4309  cmt_string package_name;
4310
4311  if (ap.arguments.size () > 0) package_name = ap.arguments[0];
4312
4313  PathScanner scanner;
4314
4315  Project::scan_paths_for_package (scanner, package_name);
4316}
4317
4318//----------------------------------------------------------
4319void Cmt::do_show_system (const ArgParser& /*ap*/)
4320{
4321  cout << CmtSystem::get_cmt_config () << endl;
4322}
4323
4324//----------------------------------------------------------
4325void Cmt::do_unlock (const ArgParser& /*ap*/)
4326{
4327  const cmt_string& package = Me.m_current_package;
4328  const cmt_string& version = Me.m_current_version;
4329  const cmt_string& path    = Me.m_current_path;
4330
4331  // (unused??) Use& use = Use::current();
4332
4333  CmtMessage::info ("try to unlock package " + package + " in " + CmtSystem::pwd ());
4334  //  cerr << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
4335
4336  set_standard_macros ();
4337
4338  CmtLock::status status = CmtLock::unlock ();
4339}
4340
4341//----------------------------------------------------------
4342void Cmt::do_version (const ArgParser& /*ap*/)
4343{
4344  cout << CMTVERSION << endl;
4345}
4346
4347
4348
4349//----------------------------------------------------------
4350ActionType Cmt::get_action ()
4351{
4352  return (Me.m_action);
4353}
4354
4355/*
4356  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
4357  {
4358  return (Me.m_cmt_path);
4359  }
4360
4361  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_pwds ()
4362  {
4363  return (Me.m_cmt_path_pwds);
4364  }
4365
4366  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_sources ()
4367  {
4368  return (Me.m_cmt_path_sources);
4369  }
4370*/
4371
4372const cmt_string& Cmt::get_cmt_home ()
4373{
4374  return (Me.m_cmt_home);
4375}
4376
4377const cmt_string& Cmt::get_cmt_user_context ()
4378{
4379  return (Me.m_cmt_user_context);
4380}
4381
4382const cmt_string& Cmt::get_cmt_version ()
4383{
4384  return (Me.m_cmt_version);
4385}
4386
4387const cmt_string& Cmt::get_current_dir ()
4388{
4389  return (Me.m_current_dir);
4390}
4391
4392const cmt_string& Cmt::get_current_package ()
4393{
4394  return (Me.m_current_package);
4395}
4396
4397const cmt_string& Cmt::get_current_cmtpath ()
4398{
4399  return (Me.m_current_cmtpath);
4400}
4401
4402const cmt_string& Cmt::get_current_offset ()
4403{
4404  return (Me.m_current_offset);
4405}
4406
4407AccessMode Cmt::get_current_access ()
4408{
4409  return (Me.m_current_access);
4410}
4411
4412CmtStructuringStyle Cmt::get_current_structuring_style ()
4413{
4414  return (Me.m_current_structuring_style);
4415}
4416
4417CmtDirStyle Cmt::get_current_style ()
4418{
4419  return (Me.m_current_style);
4420}
4421
4422const cmt_string& Cmt::get_current_version ()
4423{
4424  return (Me.m_current_version);
4425}
4426
4427const cmt_string& Cmt::get_current_target ()
4428{
4429  return (Me.m_current_target);
4430}
4431
4432bool Cmt::get_debug ()
4433{
4434  return (Me.m_debug);
4435}
4436
4437bool Cmt::get_quiet ()
4438{
4439  return (Me.m_quiet);
4440}
4441
4442bool Cmt::get_disable_warnings ()
4443{
4444  return (Me.m_disable_warnings);
4445}
4446
4447bool Cmt::get_warnings ()
4448{
4449  return (Me.m_warnings);
4450}
4451
4452bool Cmt::get_recursive ()
4453{
4454  return (Me.m_recursive);
4455}
4456
4457CmtScopeFilteringMode Cmt::get_scope_filtering_mode ()
4458{
4459  if (Me.m_scope_filtering_mode == default_filtering_mode)
4460    {
4461      return (block_private_uses);
4462    }
4463  else
4464    {
4465      return (Me.m_scope_filtering_mode);
4466    }
4467}
4468
4469//----------------------------------------------------------
4470bool Cmt::get_all_sets_done ()
4471{
4472  return (Me.m_all_sets_done);
4473}
4474
4475//----------------------------------------------------------
4476void Cmt::get_cmt_flags (CmtSystem::cmt_string_vector& flags)
4477{
4478  CmtSystem::split (CmtSystem::getenv ("CMTFLAGS"), " \t", flags);
4479}
4480
4481//----------------------------------------------------------
4482cmt_string Cmt::get_cmt_flags ()
4483{
4484  return CmtSystem::getenv ("CMTFLAGS");
4485}
4486
4487//----------------------------------------------------------
4488bool Cmt::set_cmt_flags (const cmt_string& cmtflags)
4489{
4490  return CmtSystem::putenv ("CMTFLAGS", cmtflags) ?
4491    true :
4492    (CmtMessage::error ("Cannot set `CMTFLAGS' to `" + cmtflags +
4493                        "' in the environment"),
4494     false) ;
4495}
4496
4497//----------------------------------------------------------
4498bool Cmt::add_cmt_flag (const cmt_string& flag)
4499{
4500  CmtSystem::cmt_string_vector flags;
4501  get_cmt_flags (flags);
4502  cmt_string cmtflags;
4503  for (int i = 0; i < flags.size (); i++)
4504    {
4505      if (flags[i] == flag) continue;
4506      if (cmtflags == "")
4507        cmtflags = flags[i]; 
4508      else
4509        cmtflags += " " + flags[i]; 
4510    }
4511
4512  if (cmtflags == "")
4513    cmtflags = flag; 
4514  else
4515    cmtflags += " " + flag; 
4516
4517  return set_cmt_flags (cmtflags);
4518}
4519
4520/**---------------------------------------------------------
4521   guess_current_project
4522
4523   if current directory is in one of the CMTPATHs, do nothing.
4524
4525   Otherwise, we want to guess the current project
4526
4527   move up in directories until cmt/project.cmt is found
4528
4529   for (;;)
4530   {
4531   if test -f ./cmt/project.cmt
4532   ok:
4533   this directory should become the first entry of the CMTPATH
4534   break
4535
4536   if (at top) break;
4537
4538   move up
4539   }
4540*/
4541void Cmt::guess_current_project ()
4542{
4543  Log;
4544
4545  log << "guess_current_project" << log_endl;
4546
4547  cmt_string here = CmtSystem::pwd ();
4548
4549  if (Project::find_in_cmt_paths (Me.m_current_dir) == "")
4550    {
4551      cmt_string project_file = "cmt";
4552      project_file += CmtSystem::file_separator ();
4553      project_file += Project::get_project_file_name ();
4554
4555      cmt_string pwd;
4556
4557      for (;;)
4558        {
4559          pwd = CmtSystem::pwd ();
4560          if (CmtSystem::test_file (project_file))
4561            {
4562              //this directory should become the first entry of the CMTPATH
4563
4564              IProjectFactory& factory = ProjectFactory::instance ();
4565              factory.create_project ("", pwd, "CurrentProject", 0);
4566
4567              break;
4568            }
4569
4570          log << "pwd=" << CmtSystem::pwd () << log_endl;
4571         
4572          if (!CmtSystem::cd (".."))
4573            {
4574              log << "Cannot cd up..." << log_endl;
4575              break;
4576            }
4577
4578          if (CmtSystem::pwd () == pwd)
4579            {
4580              log << "Looks the same pwd..." << log_endl;
4581              break;
4582            }
4583        }
4584
4585      CmtSystem::cd (Me.m_current_dir);
4586    }
4587
4588  //cmt_string buffer = "path CMTPATH \n";
4589  cmt_string buffer;
4590  Project::fill_cmtpaths (buffer);
4591  //cerr << "buffer = " << buffer << endl;
4592  Use& use = Use::current();
4593
4594  bool save_quiet = Me.m_quiet;
4595  Me.m_quiet = true;
4596
4597  SyntaxParser::parse_requirements_text (buffer, "", &use);
4598
4599  Me.m_quiet = save_quiet;
4600
4601  Me.m_autoconfigure_cmtpath = true;
4602
4603  CmtSystem::cd (here);
4604}
4605
4606//----------------------------------------------------------
4607const cmt_string& Cmt::filter_dir (const cmt_string& dir)
4608{
4609  static cmt_string newdir;
4610
4611  CmtSystem::compress_path (dir, newdir);
4612
4613  return (newdir);
4614}
4615
4616//----------------------------------------------------------
4617static void dos_script_prefix (FILE* f, 
4618                               const cmt_string& cmt_root, 
4619                               const cmt_string& package, 
4620                               const cmt_string& version, 
4621                               const cmt_string& path, 
4622                               const cmt_string& action, 
4623                               const cmt_string& option = "")
4624{
4625  cmt_string no_device = path;
4626
4627  if (CmtSystem::absolute_path (path)) 
4628    {
4629      if (path[1] == ':')
4630        {
4631          no_device = path.substr (2);
4632        }
4633    }
4634
4635  if (package == "cmt_standalone")
4636    {
4637      no_device = "";
4638    }
4639  else
4640    {
4641      no_device = "..\\..\\..";
4642      if (Cmt::get_current_style () == no_version_style)
4643        {
4644          no_device = "..\\..";
4645        }
4646    }
4647
4648
4649  fprintf (f, "@echo off\n");
4650  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 ());
4651  fprintf (f, "\n");
4652  fprintf (f, "set cmttempfile=\"%%TEMP%%\\tmpsetup.bat\"\n");
4653  fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe %s -bat "
4654           " -pack=%s -version=%s -path=\"%%~d0%%~p0%s\" "
4655           " %s "
4656           "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%cmttempfile%%\n",
4657           action.c_str (),
4658           package.c_str (),
4659           version.c_str (),
4660           no_device.c_str (),
4661           option.c_str ());
4662  fprintf (f, "if exist %%cmttempfile%% call %%cmttempfile%%\n");
4663  fprintf (f, "if exist %%cmttempfile%% del %%cmttempfile%%\n");
4664  fprintf (f, "set cmttempfile=\n");
4665}
4666
4667//----------------------------------------------------------
4668void Cmt::install_cleanup_scripts ()
4669{
4670#ifdef WIN32
4671  static const int modes = 1;
4672  static const cmt_string suffix[1]   = {"bat"};
4673  static const PrintMode  mode[1]     = {Bat};
4674#else
4675  static const int modes = 2;
4676  static const cmt_string suffix[2]   = {"csh", "sh"};
4677  static const PrintMode  mode[2]     = {Csh, Sh};
4678#endif
4679
4680  if (CmtMessage::active (Error))
4681    cerr << "Creating cleanup scripts." << endl;
4682
4683  cmt_string temp;
4684  int i;
4685
4686  cmt_string version = Me.m_current_version;
4687  if (version == "v*") version = "";
4688
4689  for (i = 0; i < modes; i++)
4690    {
4691      cmt_string file_name = "cleanup";
4692      file_name += ".";
4693      file_name += suffix[i];
4694      file_name += ".";
4695      file_name += "new";
4696
4697      FILE* f = fopen (file_name.c_str (), "wb");
4698      if (f != NULL)
4699        {
4700          if (mode[i] == Csh)
4701            {
4702              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4703              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4704              fprintf (f, "endif\n");
4705              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4706              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4707              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4708              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4709                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4710                       "source ${tempfile}\n",
4711                       suffix[i].c_str (),
4712                       Me.m_current_package.c_str (),
4713                       version.c_str (),
4714                       Me.m_current_path.c_str ());
4715              fprintf (f, "/bin/rm -f ${tempfile}\n");
4716            }
4717          else if (mode[i] == Sh)
4718            {
4719              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4720              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4721              fprintf (f, "fi\n");
4722              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4723              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4724              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4725              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4726                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4727                       ". ${tempfile}\n",
4728                       suffix[i].c_str (),
4729                       Me.m_current_package.c_str (),
4730                       version.c_str (),
4731                       Me.m_current_path.c_str ());
4732              fprintf (f, "/bin/rm -f ${tempfile}\n");
4733            }
4734          else if (mode[i] == Bat)
4735            {
4736              dos_script_prefix (f, Me.m_cmt_root, 
4737                                 Me.m_current_package, version, Me.m_current_path,
4738                                 "cleanup");
4739            }
4740
4741          fprintf (f, "\n");
4742
4743          fclose (f);
4744
4745          cmt_string old_file_name = "cleanup";
4746          old_file_name += ".";
4747          old_file_name += suffix[i];
4748
4749          CmtSystem::compare_and_update_files (file_name, old_file_name);
4750        }
4751    }
4752}
4753
4754//----------------------------------------------------------
4755void Cmt::install_setup_scripts ()
4756{
4757#ifdef WIN32
4758  static const int modes = 1;
4759  static const cmt_string suffix[1]   = {"bat"};
4760  static const PrintMode  mode[1]     = {Bat};
4761#else
4762  static const int modes = 2;
4763  static const cmt_string suffix[2]   = {"csh", "sh"};
4764  static const PrintMode  mode[2]     = {Csh, Sh};
4765#endif
4766
4767  if (CmtMessage::active (Error))
4768    cerr << "Creating setup scripts." << endl;
4769
4770  Use& current_use = Use::current ();
4771 
4772  cmt_string no_cleanup_opt;
4773
4774  if (current_use.get_strategy ("SetupCleanup"))
4775    {
4776      no_cleanup_opt = " -no_cleanup";
4777    }
4778
4779  cmt_string temp;
4780  int i;
4781
4782  cmt_string version = Me.m_current_version;
4783  if (version == "v*") version = "";
4784
4785  for (i = 0; i < modes; i++)
4786    {
4787      cmt_string file_name = "setup";
4788      file_name += ".";
4789      file_name += suffix[i];
4790      file_name += ".";
4791      file_name += "new";
4792
4793      FILE* f = fopen (file_name.c_str (), "wb");
4794      if (f != NULL)
4795        {
4796          if (mode[i] == Csh)
4797            {
4798              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4799                       Me.m_current_package.c_str (),
4800                       version.c_str (),
4801                       Me.m_current_path.c_str ());
4802              fprintf (f, "\n");
4803
4804              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4805              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4806              fprintf (f, "endif\n");
4807              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4808              fprintf (f, "\n");
4809              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4810              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4811              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4812                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4813                       "source ${tempfile}\n",
4814                       suffix[i].c_str (),
4815                       Me.m_current_package.c_str (),
4816                       version.c_str (),
4817                       Me.m_current_path.c_str (),
4818                       no_cleanup_opt.c_str ());
4819              fprintf (f, "/bin/rm -f ${tempfile}\n");
4820            }
4821          else if (mode[i] == Sh)
4822            {
4823              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4824                       Me.m_current_package.c_str (),
4825                       version.c_str (),
4826                       Me.m_current_path.c_str ());
4827              fprintf (f, "\n");
4828
4829              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4830              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4831              fprintf (f, "fi\n");
4832              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4833              fprintf (f, "\n");
4834              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4835              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4836              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4837                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4838                       ". ${tempfile}\n",
4839                       suffix[i].c_str (),
4840                       Me.m_current_package.c_str (),
4841                       version.c_str (),
4842                       Me.m_current_path.c_str (),
4843                       no_cleanup_opt.c_str ());
4844              fprintf (f, "/bin/rm -f ${tempfile}\n");
4845            }
4846          else if (mode[i] == Bat)
4847            {
4848              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
4849                       Me.m_current_package.c_str (),
4850                       version.c_str ());
4851              dos_script_prefix (f, Me.m_cmt_root, 
4852                                 Me.m_current_package, version, Me.m_current_path,
4853                                 "setup", no_cleanup_opt);
4854            }
4855
4856          fprintf (f, "\n");
4857
4858          fclose (f);
4859
4860          cmt_string old_file_name = "setup";
4861          old_file_name += ".";
4862          old_file_name += suffix[i];
4863
4864          CmtSystem::compare_and_update_files (file_name, old_file_name);
4865        }
4866    }
4867}
4868
4869//----------------------------------------------------------
4870void Cmt::install_test_cleanup_scripts ()
4871{
4872#ifdef WIN32
4873  static const int modes = 1;
4874  static const cmt_string suffix[1]   = {"bat"};
4875  static const PrintMode  mode[1]     = {Bat};
4876#else
4877  static const int modes = 2;
4878  static const cmt_string suffix[2]   = {"csh", "sh"};
4879  static const PrintMode  mode[2]     = {Csh, Sh};
4880#endif
4881
4882  if (CmtMessage::active (Error))
4883    cerr << "Creating cleanup scripts." << endl;
4884
4885  cmt_string temp;
4886  int i;
4887
4888  cmt_string version = Me.m_current_version;
4889  if (version == "v*") version = "";
4890
4891  for (i = 0; i < modes; i++)
4892    {
4893      cmt_string file_name = "cleanup";
4894      file_name += ".";
4895      file_name += suffix[i];
4896      file_name += ".";
4897      file_name += "new";
4898
4899      FILE* f = fopen (file_name.c_str (), "wb");
4900      if (f != NULL)
4901        {
4902          if (mode[i] == Csh)
4903            {
4904              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4905              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4906              fprintf (f, "endif\n");
4907              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4908              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4909              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4910              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4911                       "source ${tempfile}\n",
4912                       suffix[i].c_str (),
4913                       Me.m_current_path.c_str ());
4914              fprintf (f, "/bin/rm -f ${tempfile}\n");
4915            }
4916          else if (mode[i] == Sh)
4917            {
4918              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4919              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4920              fprintf (f, "fi\n");
4921              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4922              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4923              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4924              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4925                       ". ${tempfile}\n",
4926                       suffix[i].c_str (),
4927                       Me.m_current_path.c_str ());
4928              fprintf (f, "/bin/rm -f ${tempfile}\n");
4929            }
4930          else
4931            {
4932              dos_script_prefix (f, Me.m_cmt_root, 
4933                                 "cmt_standalone", "", Me.m_current_path, 
4934                                 "cleanup");
4935            }
4936
4937          fprintf (f, "\n");
4938
4939          fclose (f);
4940
4941          cmt_string old_file_name = "cleanup";
4942          old_file_name += ".";
4943          old_file_name += suffix[i];
4944
4945          CmtSystem::compare_and_update_files (file_name, old_file_name);
4946        }
4947    }
4948}
4949
4950//----------------------------------------------------------
4951void Cmt::install_native_version_file ()
4952{   
4953  Use& current_use        = Use::current ();
4954  cmt_string package_name = current_use.get_package_name();
4955  cmt_string macro_name   = package_name + "_native_version";
4956  Symbol* macro           = Symbol::find (macro_name);
4957  if (macro != 0)
4958    {
4959      cmt_string value = macro->resolve_macro_value ();
4960      if (value != "")
4961        {
4962          if (CmtMessage::active (Info))
4963            cerr << "Creating native_version file." << endl;   
4964
4965          FILE* f = fopen ("new.native_version.cmt", "wb");
4966
4967          if (f != NULL)
4968            {
4969              fprintf (f, "%s\n", value.c_str ());
4970            }     
4971
4972          fclose (f);
4973
4974          CmtSystem::compare_and_update_files ("new.native_version.cmt", "native_version.cmt");
4975        } 
4976    }   
4977}
4978//----------------------------------------------------------
4979void Cmt::install_test_setup_scripts ()
4980{
4981#ifdef WIN32
4982  static const int modes = 1;
4983  static const cmt_string suffix[1]   = {"bat"};
4984  static const PrintMode  mode[1]     = {Bat};
4985#else
4986  static const int modes = 2;
4987  static const cmt_string suffix[2]   = {"csh", "sh"};
4988  static const PrintMode  mode[2]     = {Csh, Sh};
4989#endif
4990
4991  if (CmtMessage::active (Error))
4992    cerr << "Creating setup scripts." << endl;
4993
4994  Use& current_use = Use::current ();
4995
4996  cmt_string no_cleanup_opt;
4997
4998  if (current_use.get_strategy ("SetupCleanup"))
4999    {
5000      no_cleanup_opt = " -no_cleanup";
5001    }
5002
5003  cmt_string temp;
5004  int i;
5005
5006  for (i = 0; i < modes; i++)
5007    {
5008      cmt_string file_name = "setup";
5009      file_name += ".";
5010      file_name += suffix[i];
5011      file_name += ".";
5012      file_name += "new";
5013
5014      FILE* f = fopen (file_name.c_str (), "wb");
5015      if (f != NULL)
5016        {
5017          if (mode[i] == Csh)
5018            {
5019              fprintf (f, "# echo \"Setting standalone package\"\n");
5020              fprintf (f, "\n");
5021
5022              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5023              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5024              fprintf (f, "endif\n");
5025              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5026              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5027              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
5028              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
5029                       "source ${tempfile}\n",
5030                       suffix[i].c_str (),
5031                       Me.m_current_path.c_str (),
5032                       no_cleanup_opt.c_str ());
5033              fprintf (f, "/bin/rm -f ${tempfile}\n");
5034            }
5035          else if (mode[i] == Sh)
5036            {
5037              fprintf (f, "# echo \"Setting standalone package\"\n");
5038              fprintf (f, "\n");
5039
5040              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5041              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5042              fprintf (f, "fi\n");
5043              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5044              fprintf (f, "\n");
5045              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5046              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
5047              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
5048                       ". ${tempfile}\n",
5049                       suffix[i].c_str (),
5050                       Me.m_current_path.c_str (),
5051                       no_cleanup_opt.c_str ());
5052              fprintf (f, "/bin/rm -f ${tempfile}\n");
5053            }
5054          else
5055            {
5056              fprintf (f, "rem Setting standalone package\n");
5057              dos_script_prefix (f, Me.m_cmt_root, 
5058                                 "cmt_standalone", "", Me.m_current_path, 
5059                                 "setup", no_cleanup_opt);
5060            }
5061
5062          fprintf (f, "\n");
5063
5064          fclose (f);
5065
5066          cmt_string old_file_name = "setup";
5067          old_file_name += ".";
5068          old_file_name += suffix[i];
5069
5070          CmtSystem::compare_and_update_files (file_name, old_file_name);
5071        }
5072    }
5073}
5074
5075/**
5076 *    load is only called from the Windows GUI which pretends to access directly
5077 *   the internal data model.
5078 *    This is considered to be rather unsafe, and should be replaced by query functions.
5079 */
5080//bool Cmt::load (const cmt_string& path,
5081bool Cmt::load (const ArgParser& ap,
5082                const cmt_string& path,
5083                const cmt_string& package,
5084                const cmt_string& version,
5085                const cmt_string& tag_name)
5086{
5087  clear ();
5088  //  configure ();
5089  configure (ap);
5090
5091  Me.m_action  = action_load;
5092  Me.m_recursive = true;
5093
5094  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
5095    {
5096      //
5097      //  Here we want to connect to a new package, or to the current package
5098      //  but with another tag.
5099      //
5100      //   the 'package' argument may include a directory offset. Thus 'path'
5101      //  is only expected to hold the base directory.
5102      //
5103      cmt_string offset;
5104      cmt_string package_name;
5105     
5106      CmtSystem::dirname (package, offset);
5107      CmtSystem::basename (package, package_name);
5108     
5109      if (offset != "")
5110        {
5111          Me.m_current_path = path;
5112          Me.m_current_path += CmtSystem::file_separator ();
5113          Me.m_current_path += offset;
5114        }
5115      else
5116        {
5117          Me.m_current_path = path;
5118        }
5119     
5120      Me.m_current_package = package_name;
5121      Me.m_current_version = version;
5122    }
5123
5124  if (tag_name != "")
5125    {
5126      Tag* tag;
5127
5128      Tag::unmark_all ();
5129      configure_version_tag ();
5130      configure_site_tag (0);
5131      configure_uname_tag ();
5132      configure_hosttype_tag ();
5133
5134      Me.m_current_tag = tag_name;
5135
5136      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
5137
5138      tag = Tag::add (tag_name, PriorityTag, "load", 0);
5139      tag->mark ();
5140    }
5141
5142  /*
5143    Set to developer mode if positioned into the package
5144    (which is detected since we were able to retreive the
5145    Version, Package and Path)
5146  */
5147
5148  if ((Me.m_current_path == "") ||
5149      (Me.m_current_package == "") ||
5150      (Me.m_current_version == ""))
5151    {
5152      Me.m_current_access = UserMode;
5153    }
5154  else
5155    {
5156      Me.m_current_access = DeveloperMode;
5157    }
5158
5159  use_cmt ();
5160
5161  cmt_string dir;
5162
5163  /*
5164    Try to access the package.
5165  */
5166
5167  if (Me.m_current_path != "")
5168    {
5169      dir = Me.m_current_path;
5170    }
5171  else
5172    {
5173      dir = Me.m_default_path;
5174    }
5175
5176  if (!CmtSystem::cd (Me.m_current_path))
5177    {
5178      CmtMessage::error ("Cannot reach the directory " + Me.m_current_path);
5179      /*
5180      if (!Me.m_quiet)
5181        {
5182          cerr << "#CMT> Cannot reach the directory " <<
5183            Me.m_current_path << endl;
5184        }
5185      */
5186      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
5187      CmtSystem::cd (Me.m_current_dir);
5188
5189      return (false);
5190    }
5191
5192  dir += CmtSystem::file_separator ();
5193  dir += Me.m_current_package;
5194
5195  if (!CmtSystem::cd (Me.m_current_package))
5196    {
5197      CmtMessage::error ("Cannot reach the package " + Me.m_current_package);
5198      /*
5199      if (!Me.m_quiet)
5200        {
5201          cerr << "#CMT::load> Cannot reach the package " <<
5202            Me.m_current_package << endl;
5203        }
5204      */
5205      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
5206      CmtSystem::cd (Me.m_current_dir);
5207
5208      return (false);
5209    }
5210
5211  dir += CmtSystem::file_separator ();
5212  dir += Me.m_current_version;
5213
5214  Me.m_current_style = none_style;
5215
5216  if (!CmtSystem::cd (Me.m_current_version))
5217    {
5218      if (!CmtSystem::test_directory ("cmt"))
5219        {
5220          CmtMessage::error ("Cannot reach the version " + Me.m_current_version);
5221          /*
5222          if (!Me.m_quiet)
5223            {
5224              cerr << "#CMT> Cannot reach the version " <<
5225                Me.m_current_version << endl;
5226            }
5227          */
5228          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
5229          CmtSystem::cd (Me.m_current_dir);
5230
5231          return (false);
5232        }
5233      else
5234        {
5235          Me.m_current_style = no_version_style;
5236        }
5237    }
5238
5239  if (CmtSystem::cd ("cmt"))
5240    {
5241      dir += CmtSystem::file_separator ();
5242      dir += "cmt";
5243      if (Me.m_current_style == none_style) Me.m_current_style = cmt_style;
5244    }
5245  else
5246    {
5247      /*
5248        if (!Me.m_quiet)
5249        {
5250        cerr << "Cannot reach the cmt branch" << endl;
5251        }
5252      */
5253
5254      if (CmtSystem::cd ("mgr"))
5255        {
5256          dir += CmtSystem::file_separator ();
5257          dir += "mgr";
5258          if (Me.m_current_style == none_style) Me.m_current_style = mgr_style;
5259        }
5260      else
5261        {
5262          CmtMessage::error ("Cannot reach the mgr branch");
5263          /*
5264          if (!Me.m_quiet)
5265            {
5266              cerr << "#CMT> Cannot reach the mgr branch" << endl;
5267            }
5268          */
5269
5270          CmtError::set (CmtError::package_not_found,
5271                         "Load> Cannot reach the mgr/cmt directory");
5272          CmtSystem::cd (Me.m_current_dir);
5273
5274          return (false);
5275        }
5276    }
5277
5278  /*
5279    Check Tag is always set up
5280  */
5281
5282  if (Me.m_current_tag == "")
5283    {
5284      char* env;
5285
5286      env = getenv (Me.m_current_config.c_str ());
5287      if (env != 0)
5288        {
5289          Tag* tag;
5290
5291          tag = Tag::add (env, PriorityConfig, "load", 0);
5292          tag->mark ();
5293          Me.m_current_tag = env;
5294
5295          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
5296
5297        }
5298      else
5299        {
5300          Me.m_current_tag = Me.m_cmt_config;
5301
5302          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
5303
5304        }
5305    }
5306
5307  if (Me.m_debug)
5308    {
5309      cout << "pwd = " << CmtSystem::pwd () << endl;
5310    }
5311
5312  configure_current_dir ();
5313  build_prefix (Me.m_current_package, Me.m_current_prefix);
5314  build_config (Me.m_current_prefix, Me.m_current_config);
5315
5316  Use* use = &(Use::current());
5317  use->path    = Me.m_current_path;
5318  use->set_package_name (Me.m_current_package);
5319  use->version = Me.m_current_version;
5320  use->prefix  = Me.m_current_prefix;
5321  use->done    = false;
5322  use->style   = Me.m_current_style;
5323
5324  /*
5325    Work on the requirements file.
5326  */
5327
5328  dir += CmtSystem::file_separator ();
5329  dir += "requirements";
5330  SyntaxParser::parse_requirements (dir, use);
5331
5332  if (CmtError::has_pending_error ()) return (false);
5333
5334  /**
5335   * See reach_current_package for an explanation of this call
5336   */
5337  Pattern::apply_all_globals ();
5338
5339  /*
5340    Select all possible tags
5341  */
5342
5343  Tag::restore_tree ();
5344
5345  return (true);
5346}
5347
5348//----------------------------------------------------------
5349bool Cmt::need_prototypes ()
5350{
5351  Use& current_use = Use::current ();
5352
5353  if (current_use.get_strategy ("BuildPrototypes")) return (true);
5354  else return (false);
5355}
5356
5357//----------------------------------------------------------
5358void Cmt::parse_arguments (ArgParser& ap)
5359{
5360  /*
5361    Decoding arguments.
5362
5363    While decoding all arguments, no requirements analysis should
5364    occur. Every new option, or parameter should be saved and
5365    used later at actual analysis time.
5366  */
5367
5368  Me.m_action = action_none;
5369
5370  restore_all_tags (0);
5371
5372#ifdef WIN32
5373  Me.m_build_nmake = true;
5374#endif
5375
5376  ap.parse ();
5377}
5378
5379//----------------------------------------------------------
5380int Cmt::parser (const cmt_string& command_line)
5381{
5382  CmtSystem::cmt_string_vector v;
5383
5384  CmtSystem::split (command_line, " \t", v);
5385
5386  int argc = v.size ();
5387
5388  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
5389
5390  int i;
5391  for (i = 0; i < argc; i++)
5392    {
5393      argv[i] = (char*) v[i].c_str ();
5394    }
5395  argv[argc] = 0;
5396
5397  int status = parser (argc, argv);
5398
5399  free (argv);
5400
5401  return (status);
5402}
5403
5404//----------------------------------------------------------
5405int Cmt::parser (int argc, char* argv[])
5406{
5407  ArgParser ap (Me);
5408 
5409  ap.argc = argc;
5410  ap.argv = argv;
5411
5412  if (argc <= 1)
5413    {
5414      do_help (ap);
5415      exit (0);
5416    }
5417
5418  // save CMTFLAGS
5419  cmt_string cmtflags (get_cmt_flags ());
5420
5421  clear ();
5422
5423  //  configure ();
5424  configure (ap);
5425
5426  CmtError::clear ();
5427
5428  /*
5429    Set private if positioned inside the package
5430    (which is detected since we were able to retreive the
5431    Version, Package and Path)
5432  */
5433
5434  if ((Me.m_current_path.size () == 0) ||
5435      (Me.m_current_package.size () == 0) ||
5436      (Me.m_current_version.size () == 0))
5437    {
5438      Me.m_current_access = UserMode;
5439    }
5440  else
5441    {
5442      Me.m_current_access = DeveloperMode;
5443    }
5444 
5445  parse_arguments (ap);
5446 
5447  if (Me.m_debug)
5448    {
5449      cout << "After parse_argument> pack=" << Me.m_current_package
5450           << " Me.m_current_tag=" << Me.m_current_tag
5451           << " cwd=" << CmtSystem::pwd () 
5452           << " mode=" << Me.m_current_access
5453           << endl;
5454    }
5455
5456  if (Me.m_configure_error != "")
5457    {
5458      CmtMessage::error (Me.m_configure_error);
5459      //      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
5460      return (CmtError::execution_error);
5461    }
5462
5463  if (CmtError::has_pending_error ())
5464    {
5465      int code = CmtError::get_last_error_code ();
5466      if (!Me.m_quiet) CmtError::print ();
5467      clear ();
5468
5469      return (code);
5470    }
5471
5472  /*
5473    Now actual requirements analysis can take place.
5474
5475    Extra lines or files are analysed first.
5476  */
5477
5478  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
5479  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
5480
5481  //
5482  //  For some of the actions, the CMT package must be automatically
5483  //  included
5484  //
5485
5486  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
5487
5488  if (ap.help_action == action_help)
5489    {
5490      do_help (ap);
5491      return (0);
5492    }
5493
5494  switch (Me.m_action)
5495    {
5496      // case action_none :
5497    case action_awk :
5498    case action_broadcast :
5499    case action_build_constituent_makefile :
5500    case action_build_constituents_makefile :
5501    case action_build_dependencies :
5502    case action_build_library_links :
5503    case action_build_make_setup :
5504    case action_build_msdev :
5505    case action_build_CMT_pacman :
5506    case action_build_vsnet :     
5507    case action_build_os9_makefile :
5508      // case action_build_prototype :
5509    case action_build_readme :
5510    case action_build_tag_makefile :
5511      // case action_build_temporary_name :
5512    case action_build_triggers :
5513    case action_build_windefs :
5514    case action_check_configuration :
5515      // case action_check_files :
5516      // case action_check_version :
5517    case action_checkout :
5518    case action_cleanup :
5519    case action_config :
5520    case action_create :
5521      // case action_create_project :
5522    case action_cvsbranches :
5523    case action_cvssubpackages :
5524    case action_cvssubprojects :
5525    case action_cvstags :
5526    case action_do :
5527    case action_expand_model :
5528    case action_filter :
5529      // case action_help :
5530    case action_load :
5531    case action_lock :
5532    case action_relocate:
5533    case action_remove :
5534    case action_remove_library_links :
5535    case action_run :
5536    case action_run_sequence :
5537    case action_set_version :
5538    case action_set_versions :
5539    case action_setup :
5540    case action_show_action :
5541    case action_show_action_names :
5542    case action_show_action_value :
5543    case action_show_actions :
5544    case action_show_all_tags :
5545    case action_show_applied_patterns :
5546      // case action_show_author :
5547      // case action_show_branches :
5548      // case action_show_clients :
5549    case action_show_cmtpath_patterns :
5550    case action_show_constituent :
5551    case action_show_constituent_names :
5552    case action_show_constituents :
5553    case action_show_cycles :
5554    case action_show_fragment :
5555    case action_show_fragments :
5556    case action_show_groups :
5557    case action_show_include_dirs :
5558    case action_show_language :
5559    case action_show_languages :
5560    case action_show_macro :
5561    case action_show_macro_names :
5562    case action_show_macro_value :
5563    case action_show_macros :
5564      // case action_show_manager :
5565    case action_show_packages :
5566    case action_show_path :
5567    case action_show_pattern :
5568    case action_show_pattern_names :
5569    case action_show_patterns :
5570    case action_show_projects :
5571      // case action_show_pwd :
5572    case action_show_setup :
5573    case action_show_set :
5574    case action_show_set_names :
5575    case action_show_set_value :
5576    case action_show_sets :
5577    case action_show_strategies :
5578    case action_show_tags :
5579    case action_show_use_paths :
5580    case action_show_uses :
5581    case action_show_version :
5582      // case action_show_versions :
5583      // case action_system :
5584    case action_unlock :
5585    case action_version :
5586      use_cmt ();
5587      //
5588      // Now parse the requirements file stored in ${CMTHOME}
5589      //
5590     
5591      use_home_requirements ();
5592
5593      break;
5594    default:
5595      break;
5596    }
5597
5598  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
5599
5600  //
5601  // Setting up recursive actions
5602  //
5603
5604  switch (Me.m_action)
5605    {
5606      // case action_none :
5607    case action_awk :
5608    case action_broadcast :
5609    case action_build_constituent_makefile :
5610    case action_build_constituents_makefile :
5611    case action_build_dependencies :
5612    case action_build_library_links :
5613    case action_build_make_setup :
5614    case action_build_msdev :
5615    case action_build_CMT_pacman :
5616    case action_build_vsnet :     
5617    case action_build_os9_makefile :
5618      // case action_build_prototype :
5619    case action_build_readme :
5620    case action_build_tag_makefile :
5621      // case action_build_temporary_name :
5622    case action_build_triggers :
5623    case action_build_windefs :
5624    case action_check_configuration :
5625      // case action_check_files :
5626      // case action_check_version :
5627      // case action_checkout :
5628    case action_cleanup :
5629    case action_config :
5630      // case action_create :
5631      // case action_create_project :
5632      // case action_cvsbranches :
5633      // case action_cvssubpackages :
5634      // case action_cvssubprojects :
5635      // case action_cvstags :
5636    case action_do :
5637    case action_expand_model :
5638    case action_filter :
5639      // case action_help :
5640    case action_load :
5641      // case action_lock :
5642      // case action_remove :
5643    case action_relocate:
5644    case action_remove_library_links :
5645    case action_run :
5646    case action_run_sequence :
5647      // case action_set_version :
5648    case action_set_versions :
5649    case action_setup :
5650    case action_show_action :
5651    case action_show_action_names :
5652    case action_show_action_value :
5653    case action_show_actions :
5654    case action_show_all_tags :
5655    case action_show_applied_patterns :
5656      // case action_show_author :
5657      // case action_show_branches :
5658      // case action_show_clients :
5659    case action_show_cmtpath_patterns :
5660    case action_show_constituent :
5661    case action_show_constituent_names :
5662    case action_show_constituents :
5663    case action_show_cycles :
5664    case action_show_fragment :
5665    case action_show_fragments :
5666    case action_show_groups :
5667    case action_show_include_dirs :
5668    case action_show_language :
5669    case action_show_languages :
5670    case action_show_macro :
5671    case action_show_macro_names :
5672    case action_show_macro_value :
5673    case action_show_macros :
5674      // case action_show_manager :
5675    case action_show_packages :
5676    case action_show_path :
5677    case action_show_pattern :
5678    case action_show_pattern_names :
5679    case action_show_patterns :
5680    case action_show_projects :
5681      // case action_show_pwd :
5682    case action_show_setup :
5683    case action_show_set :
5684    case action_show_set_names :
5685    case action_show_set_value :
5686    case action_show_sets :
5687    case action_show_strategies :
5688    case action_show_tags :
5689    case action_show_use_paths :
5690    case action_show_uses :
5691      // case action_show_version :
5692      // case action_show_versions :
5693      // case action_system :
5694      // case action_unlock :
5695      // case action_version :
5696      Me.m_recursive = true;
5697      break;
5698    default:
5699      Me.m_recursive = false;
5700      break;
5701    }
5702
5703  //
5704  //  Actions for which the context of the package is checked,
5705  //  and the requirements file is analysed.
5706  //
5707
5708  switch (Me.m_action)
5709    {
5710    case action_none :
5711    case action_awk :
5712    case action_broadcast :
5713    case action_build_constituent_makefile :
5714    case action_build_constituents_makefile :
5715    case action_build_dependencies :
5716    case action_build_library_links :
5717    case action_build_make_setup :
5718    case action_build_msdev :
5719    case action_build_CMT_pacman :
5720    case action_build_vsnet :     
5721    case action_build_os9_makefile :
5722      // case action_build_prototype :
5723    case action_build_readme :
5724    case action_build_tag_makefile :
5725      // case action_build_temporary_name :
5726    case action_build_triggers :
5727    case action_build_windefs :
5728    case action_check_configuration :
5729      // case action_check_files :
5730      // case action_check_version :
5731      // case action_checkout :
5732    case action_cleanup :
5733    case action_config :
5734      // case action_create :
5735      // case action_create_project :
5736      // case action_cvsbranches :
5737      // case action_cvssubpackages :
5738      // case action_cvssubprojects :
5739      // case action_cvstags :
5740    case action_do :
5741    case action_expand_model :
5742    case action_filter :
5743      // case action_help :
5744    case action_load :
5745    case action_lock :
5746      // case action_remove :
5747    case action_relocate :
5748    case action_remove_library_links :
5749    case action_run :
5750      // case action_run_sequence :
5751      // case action_set_version :
5752    case action_set_versions :
5753    case action_setup :
5754    case action_show_action :
5755    case action_show_action_names :
5756    case action_show_action_value :
5757    case action_show_actions :
5758    case action_show_all_tags :
5759    case action_show_applied_patterns :
5760    case action_show_author :
5761    case action_show_branches :
5762      // case action_show_clients :
5763    case action_show_cmtpath_patterns :
5764    case action_show_constituent :
5765    case action_show_constituent_names :
5766    case action_show_constituents :
5767    case action_show_cycles :
5768    case action_show_fragment :
5769    case action_show_fragments :
5770    case action_show_groups :
5771    case action_show_include_dirs :
5772    case action_show_language :
5773    case action_show_languages :
5774    case action_show_macro :
5775    case action_show_macro_names :
5776    case action_show_macro_value :
5777    case action_show_macros :
5778    case action_show_manager :
5779    case action_show_packages :
5780    case action_show_path :
5781    case action_show_pattern :
5782    case action_show_pattern_names :
5783    case action_show_patterns :
5784    case action_show_projects :
5785    case action_show_project_author :
5786    case action_show_pwd :
5787    case action_show_setup :
5788    case action_show_set :
5789    case action_show_set_names :
5790    case action_show_set_value :
5791    case action_show_sets :
5792    case action_show_strategies :
5793    case action_show_tags :
5794    case action_show_use_paths :
5795    case action_show_uses :
5796    case action_show_version :
5797      // case action_show_versions :
5798      // case action_system :
5799    case action_unlock :
5800      // case action_version :
5801      {
5802        bool w = Me.m_warnings;
5803        Me.m_warnings = false;
5804        reach_current_package ();
5805        use_user_context_requirements ();
5806        Me.m_warnings = w;
5807      }
5808      break;
5809    default:
5810      break;
5811    }
5812
5813  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
5814
5815  //
5816  // Perform some actions even if there is an error
5817  //
5818
5819  if (CmtError::has_pending_error ())
5820    {
5821      int code = CmtError::get_last_error_code ();
5822      if (!Me.m_quiet) CmtError::print ();
5823
5824      switch (Me.m_action)
5825        {
5826          // case action_none :
5827          // case action_awk :
5828          // case action_broadcast :
5829        case action_build_constituent_makefile :
5830        case action_build_constituents_makefile :
5831        case action_build_dependencies :
5832        case action_build_library_links :
5833        case action_build_make_setup :
5834        case action_build_msdev :
5835        case action_build_CMT_pacman :
5836        case action_build_vsnet :     
5837        case action_build_os9_makefile :
5838        case action_build_prototype :
5839        case action_build_readme :
5840        case action_build_tag_makefile :
5841          // case action_build_temporary_name :
5842        case action_build_triggers :
5843        case action_build_windefs :
5844        case action_check_configuration :
5845          // case action_check_files :
5846          // case action_check_version :
5847          // case action_checkout :
5848        case action_cleanup :
5849          // case action_config :
5850          // case action_create :
5851          // case action_create_project :
5852          // case action_cvsbranches :
5853          // case action_cvssubpackages :
5854          // case action_cvssubprojects :
5855          // case action_cvstags :
5856          // case action_do :
5857          // case action_expand_model :
5858          // case action_filter :
5859          // case action_help :
5860        case action_load :
5861        case action_lock :
5862        case action_relocate :
5863        case action_remove :
5864        case action_remove_library_links :
5865          // case action_run :
5866        case action_run_sequence :
5867          // case action_set_version :
5868          // case action_set_versions :
5869        case action_setup :
5870          // case action_show_action :
5871          // case action_show_action_names :
5872          // case action_show_action_value :
5873          // case action_show_actions :
5874          // case action_show_all_tags :
5875          // case action_show_applied_patterns :
5876          // case action_show_author :
5877          // case action_show_branches :
5878          // case action_show_clients :
5879          // case action_show_cmtpath_patterns :
5880          // case action_show_constituent :
5881          // case action_show_constituent_names :
5882          // case action_show_constituents :
5883          // case action_show_cycles :
5884          // case action_show_fragment :
5885          // case action_show_fragments :
5886          // case action_show_groups :
5887          // case action_show_include_dirs :
5888          // case action_show_language :
5889          // case action_show_languages :
5890          // case action_show_macro :
5891          // case action_show_macro_names :
5892          // case action_show_macro_value :
5893          // case action_show_macros :
5894          // case action_show_manager :
5895          // case action_show_packages :
5896          // case action_show_path :
5897          // case action_show_pattern :
5898          // case action_show_pattern_names :
5899          // case action_show_patterns :
5900          // case action_show_projects :
5901          // case action_show_pwd :
5902          // case action_show_setup :
5903          // case action_show_set :
5904          // case action_show_set_names :
5905          // case action_show_set_value :
5906          // case action_show_sets :
5907          // case action_show_strategies :
5908          // case action_show_tags :
5909          // case action_show_use_paths :
5910          // case action_show_uses :
5911          // case action_show_version :
5912          // case action_show_versions :
5913          // case action_system :
5914        case action_unlock :
5915          // case action_version :
5916          clear ();
5917          return (code);
5918        default:
5919          CmtError::clear ();
5920          break;
5921        }
5922    }
5923
5924  //
5925  // Perform actions
5926  //
5927
5928  if (!Me.m_simulation)
5929    {
5930      switch (Me.m_action)
5931        {
5932        case action_none :
5933          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
5934          break;
5935        case action_awk :
5936          do_awk (ap);
5937          break;
5938        case action_broadcast :
5939          do_broadcast (ap);
5940          break;
5941        case action_build_constituent_makefile :
5942          do_build_constituent_makefile (ap);
5943          break;
5944        case action_build_constituents_makefile :
5945          do_build_constituents_makefile (ap);
5946          break;
5947        case action_build_dependencies :
5948          do_build_dependencies (ap, argc, argv);
5949          break;
5950        case action_build_library_links :
5951          do_build_library_links (ap);
5952          break;
5953        case action_build_make_setup :
5954          do_build_make_setup (ap);
5955          break;
5956        case action_build_msdev :
5957          do_build_msdev (ap);
5958          break;
5959        case action_build_CMT_pacman :
5960          do_build_CMT_pacman (ap);
5961          break;
5962        case action_build_vsnet :     
5963          do_build_vsnet (ap);
5964          break;
5965        case action_build_os9_makefile :
5966          do_build_os9_makefile (ap);
5967          break;
5968        case action_build_prototype :
5969          do_build_prototype (ap);
5970          break;
5971        case action_build_readme :
5972          do_build_readme (ap);
5973          break;
5974        case action_build_tag_makefile :
5975          do_build_tag_makefile (ap);
5976          break;
5977        case action_build_temporary_name :
5978          do_build_temporary_name (ap);
5979          break;
5980        case action_build_triggers :
5981          do_build_triggers (ap);
5982          break;
5983        case action_build_windefs :
5984          do_build_windefs (ap);
5985          break;
5986        case action_check_configuration :
5987          do_check_configuration (ap);
5988          break;
5989        case action_check_files :
5990          do_check_files (ap);
5991          break;
5992        case action_check_version :
5993          do_check_version (ap);
5994          break;
5995        case action_checkout :
5996          do_checkout (ap);
5997          break;
5998        case action_cleanup :
5999          do_cleanup (ap);
6000          break;
6001        case action_config :
6002          do_config (ap);
6003          break;
6004        case action_create :
6005          do_create (ap);
6006          break;
6007        case action_create_project :
6008          do_create_project (ap);
6009          break;
6010        case action_cvsbranches :
6011          do_cvsbranches (ap);
6012          break;
6013        case action_cvssubpackages :
6014          do_cvssubpackages (ap);
6015          break;
6016        case action_cvssubprojects :
6017          do_cvssubprojects (ap);
6018          break;
6019        case action_cvstags :
6020          do_cvstags (ap);
6021          break;
6022        case action_do :
6023          do_do (ap);
6024          break;
6025        case action_expand_model :
6026          do_expand_model (ap);
6027          break;
6028        case action_filter :
6029          do_filter (ap);
6030          break;
6031        case action_help :
6032          do_help (ap);
6033          break;
6034        case action_load :
6035          CmtMessage::error ("action not implemented");
6036          //      cerr << "#CMT> action not implemented" << endl;
6037          break;
6038        case action_lock :
6039          do_lock (ap);
6040          break;
6041        case action_relocate :
6042          do_relocate (ap);
6043          break;
6044        case action_remove :
6045          do_remove (ap);
6046          break;
6047        case action_remove_library_links :
6048          do_remove_library_links (ap);
6049          break;
6050        case action_run :
6051          do_run (ap);
6052          break;
6053        case action_run_sequence :
6054          do_run_sequence (ap);
6055          break;
6056        case action_set_version :
6057          do_set_version (ap);
6058          break;
6059        case action_set_versions :
6060          do_set_versions (ap);
6061          break;
6062        case action_setup :
6063          do_setup (ap);
6064          break;
6065        case action_show_action :
6066          do_show_action (ap);
6067          break;
6068        case action_show_action_names :
6069          do_show_action_names (ap);
6070          break;
6071        case action_show_action_value :
6072          do_show_action_value (ap);
6073          break;
6074        case action_show_actions :
6075          do_show_actions (ap);
6076          break;
6077        case action_show_all_tags :
6078          do_show_all_tags (ap);
6079          break;
6080        case action_show_applied_patterns :
6081          do_show_applied_patterns (ap);
6082          break;
6083        case action_show_author :
6084          do_show_author (ap);
6085          break;
6086        case action_show_branches :
6087          do_show_branches (ap);
6088          break;
6089        case action_show_clients :
6090          do_show_clients (ap);
6091          break;
6092        case action_show_cmtpath_patterns :
6093          do_show_cmtpath_patterns (ap);
6094          break;
6095        case action_show_constituent :
6096          do_show_constituent (ap);
6097          break;
6098        case action_show_constituent_names :
6099          do_show_constituent_names (ap);
6100          break;
6101        case action_show_constituents :
6102          do_show_constituents (ap);
6103          break;
6104        case action_show_cycles :
6105          do_show_cycles (ap);
6106          break;
6107        case action_show_fragment :
6108          do_show_fragment (ap);
6109          break;
6110        case action_show_fragments :
6111          do_show_fragments (ap);
6112          break;
6113        case action_show_groups :
6114          do_show_groups (ap);
6115          break;
6116        case action_show_include_dirs :
6117          do_show_include_dirs (ap);
6118          break;
6119        case action_show_language :
6120          do_show_language (ap);
6121          break;
6122        case action_show_languages :
6123          do_show_languages (ap);
6124          break;
6125        case action_show_macro :
6126          do_show_macro (ap);
6127          break;
6128        case action_show_macro_names :
6129          do_show_macro_names (ap);
6130          break;
6131        case action_show_macro_value :
6132          do_show_macro_value (ap);
6133          break;
6134        case action_show_macros :
6135          do_show_macros (ap);
6136          break;
6137        case action_show_manager :
6138          do_show_manager (ap);
6139          break;
6140        case action_show_packages :
6141          do_show_packages (ap);
6142          break;
6143        case action_show_path :
6144          do_show_path (ap);
6145          break;
6146        case action_show_pattern :
6147          do_show_pattern (ap);
6148          break;
6149        case action_show_pattern_names :
6150          do_show_pattern_names (ap);
6151          break;
6152        case action_show_patterns :
6153          do_show_patterns (ap);
6154          break;
6155        case action_show_projects :
6156          do_show_projects (ap);
6157          break;
6158        case action_show_project_author :
6159          do_show_project_author (ap);
6160          break;
6161        case action_show_pwd :
6162          do_show_pwd (ap);
6163          break;
6164        case action_show_setup :
6165          do_show_setup (ap);
6166          break;
6167        case action_show_set :
6168          do_show_set (ap);
6169          break;
6170        case action_show_set_names :
6171          do_show_set_names (ap);
6172          break;
6173        case action_show_set_value :
6174          do_show_set_value (ap);
6175          break;
6176        case action_show_sets :
6177          do_show_sets (ap);
6178          break;
6179        case action_show_strategies :
6180          do_show_strategies (ap);
6181          break;
6182        case action_show_tags :
6183          do_show_tags (ap);
6184          break;
6185        case action_show_use_paths :
6186          do_show_use_paths (ap);
6187          break;
6188        case action_show_uses :
6189          do_show_uses (ap);
6190          break;
6191        case action_show_version :
6192          do_show_version (ap);
6193          break;
6194        case action_show_versions :
6195          do_show_versions (ap);
6196          break;
6197        case action_system :
6198          do_show_system (ap);
6199          break;
6200        case action_unlock :
6201          do_unlock (ap);
6202          break;
6203        case action_version :
6204          do_version (ap);
6205          break;
6206        default:
6207          CmtError::set (CmtError::syntax_error, "ParseArguments>");
6208          break;
6209        }
6210    }
6211
6212  // restore CMTFLAGS
6213  set_cmt_flags (cmtflags);
6214
6215  if (CmtError::has_pending_error ())
6216    {
6217      int code = CmtError::get_last_error_code ();     
6218      if (code == CmtError::execution_failed)
6219        {
6220          code = CmtError::get_last_execution_error();
6221        }   
6222     
6223      if (!Me.m_quiet) CmtError::print ();
6224      clear ();
6225      return (code);
6226    }
6227  else
6228    {
6229      clear ();
6230      return (0);
6231    }
6232}
6233
6234
6235/**
6236 * Format as one single line a set of 'setenv' statements
6237 * joined with semi-colons to form one shell command.
6238 */
6239void Cmt::print (PrintMode mode)
6240{
6241  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6242  Use& current_use = Use::current ();
6243
6244  cmt_string tag;
6245
6246  set_standard_macros ();
6247
6248  //cerr << "# current_tag=" << Me.m_current_tag << endl;
6249  //cerr << "# current_config=" << Me.m_current_config << endl;
6250
6251  if (Me.m_current_tag == "")
6252    {
6253      if (mode == Bat) tag = "%CMTCONFIG%";
6254      else tag = "${CMTCONFIG}";
6255    }
6256  else
6257    {
6258      tag = Me.m_current_tag;
6259    }
6260
6261  //
6262  //  Now check if all extra tags are still valid. Some of them
6263  //  may be discarded du to some conflict with highest priority
6264  //  tags, or with exclude statements
6265  //
6266
6267  {
6268    CmtSystem::cmt_string_vector words;
6269     
6270    cmt_string tags;
6271
6272    tags = Me.m_extra_tags;
6273     
6274    CmtSystem::split (tags, " \t,", words);
6275
6276    Me.m_extra_tags = ",";
6277     
6278    for (int i = 0; i < words.size (); i++)
6279      {
6280        Tag* tag;
6281        const cmt_string& a = words[i];
6282
6283        tag = Tag::find (a);
6284
6285        if ((tag != 0) && (tag->is_selected ()))
6286          {
6287            Me.m_extra_tags += a;
6288            Me.m_extra_tags += ",";
6289          }
6290      }
6291  }
6292
6293  if (Me.m_debug)
6294    {
6295      cout << "Before all print contexts" << endl;
6296    }
6297
6298  if (Uses.size () > 0)
6299    {
6300      int number;
6301
6302      for (number = 0; number < Uses.size (); number++)
6303        {
6304          Use& use = *(Uses[number]);
6305
6306          if (use.discarded) continue;
6307          if (use.m_hidden) continue;
6308         
6309          print_context (use, mode, tag);
6310        }
6311    }
6312
6313  print_context (Use::current (), mode, tag);
6314
6315  if (Me.m_debug)
6316    {
6317      cout << "After all print contexts" << endl;
6318    }
6319
6320  Symbol::all_print (mode);
6321  // Script::all_print (mode);
6322
6323  if (Me.m_debug)
6324    {
6325      cout << "After all print" << endl;
6326    }
6327
6328  cout << endl;
6329}
6330
6331
6332/**
6333 * Format as one single line a set of 'unsetenv' statements
6334 * joined with semi-colons to form one shell command.
6335 */
6336void Cmt::print_clean (PrintMode mode)
6337{
6338  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6339
6340  set_standard_macros ();
6341
6342  Script::all_print_clean (mode);
6343  Symbol::all_print_clean (mode);
6344
6345  switch (mode)
6346    {
6347    case Csh :
6348      if (Me.m_current_package != "CMT")
6349        {
6350          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
6351          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
6352        }
6353      break;
6354    case Sh :
6355      if (Me.m_current_package != "CMT")
6356        {
6357          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
6358          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
6359        }
6360      break;
6361    case Bat :
6362      if (Me.m_current_package != "CMT")
6363        {
6364          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
6365          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
6366        }
6367      break;
6368    }
6369
6370  if (Uses.size () > 0)
6371    {
6372      int number;
6373
6374      for (number = 0; number < Uses.size (); number++)
6375        {
6376          Use* use = Uses[number];
6377
6378          if (use->discarded) continue;
6379          if (use->m_hidden) continue;
6380
6381          Package* p = use->get_package ();
6382          if (p->is_cmt ()) continue;
6383
6384
6385          switch (mode)
6386            {
6387            case Csh :
6388              cout << "unsetenv " << use->prefix << "ROOT" << endl;
6389              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
6390              break;
6391            case Sh :
6392              cout << "unset " << use->prefix << "ROOT" << endl;
6393              cout << "unset " << use->prefix << "CONFIG" << endl;
6394              break;
6395            case Bat :
6396              cout << "set " << use->prefix << "ROOT=" << endl;
6397              cout << "set " << use->prefix << "CONFIG" << endl;
6398              break;
6399            }
6400        }
6401    }
6402
6403  switch (mode)
6404    {
6405    case Csh :
6406      cout << "unsetenv CMTEXTRATAGS" << endl;
6407      break;
6408    case Sh :
6409      cout << "unset CMTEXTRATAGS" << endl;
6410      break;
6411    case Bat :
6412      cout << "set CMTEXTRATAGS=" << endl;
6413      break;
6414    }
6415
6416  cout << endl;
6417}
6418
6419//----------------------------------------------------------
6420void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
6421{
6422  if (use.get_package_name () == "cmt_standalone") return;
6423
6424  cmt_string fs = CmtSystem::file_separator ();
6425
6426  use.real_path.replace_all (CmtSystem::file_separator (), fs);
6427
6428  cmt_string system = CmtSystem::get_cmt_config ();
6429
6430  bool do_config = use.get_strategy ("SetupConfig");
6431  bool do_root   = use.get_strategy ("SetupRoot");
6432   
6433 
6434  switch (mode)
6435    {
6436    case Csh :
6437      if (do_root)
6438        {
6439          cout << "setenv " << use.prefix << "ROOT \"" <<
6440            use.get_full_path () << "\"" << endl;
6441        }
6442
6443      if (use.get_package_name () == "CMT")
6444        {
6445          cout << "setenv CMTCONFIG " << system << endl;
6446        }
6447      else
6448        {
6449          if (do_config)
6450            {
6451              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
6452            }
6453        }
6454       
6455      break;
6456    case Sh :
6457      if (do_root)
6458        {
6459          cout << use.prefix << "ROOT=\"" <<
6460            use.get_full_path () << "\"; export " <<
6461            use.prefix << "ROOT" << endl;
6462        }
6463
6464      if (use.get_package_name () == "CMT")
6465        {
6466          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
6467        }
6468      else
6469        {
6470          if (do_config)
6471            {
6472              cout << use.prefix << "CONFIG=\"" <<
6473                tag << "\"; export " <<
6474                use.prefix << "CONFIG" << endl;
6475            }
6476        }
6477       
6478      break;
6479    case Bat :
6480      if (do_root)
6481        {
6482          cout << "set " << use.prefix << "ROOT=" <<
6483            use.get_full_path () << endl;
6484        }
6485
6486      if (use.get_package_name () == "CMT")
6487        {
6488          cout << "set CMTCONFIG=" << system << endl;
6489        }
6490      else
6491        {
6492          if (do_config)
6493            {
6494              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
6495            }
6496        }
6497       
6498      break;
6499    }
6500}
6501
6502/**
6503 *  Format a set of make macro definitions (one per line)
6504 * Each macro value is provided enclosed in single quotes
6505 *
6506 *  Take the macro values from the macro statements found
6507 * in recursively read requirements files.
6508 */
6509void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
6510{
6511  int number;
6512
6513  set_standard_macros ();
6514
6515  cmt_regexp expression (pattern);
6516
6517  bool has_pattern = (pattern != "");
6518
6519  for (number = 0; number < Symbol::symbol_number (); number++)
6520    {
6521      Symbol& symbol = Symbol::symbol (number);
6522
6523      if (has_pattern)
6524        {
6525          if (!expression.match (symbol.name)) continue;
6526        }
6527
6528      if (Me.m_action == action_show_macro_names)
6529        {
6530          // Only keep macros.
6531          if ((symbol.type == Symbol::SymbolSet) ||
6532              (symbol.type == Symbol::SymbolAlias) ||
6533              (symbol.type == Symbol::SymbolPath) ||
6534              (symbol.type == Symbol::SymbolAction)) continue;
6535        }
6536      else if (Me.m_action == action_show_set_names)
6537        {
6538          // Exclude macros.
6539          if ((symbol.type == Symbol::SymbolMacro) ||
6540              (symbol.type == Symbol::SymbolAction)) continue;
6541        }
6542      else if (Me.m_action == action_show_action_names)
6543        {
6544          // Exclude macros.
6545          if (symbol.type != Symbol::SymbolAction) continue;
6546        }
6547
6548      cout << symbol.name << endl;
6549    }
6550}
6551
6552/**
6553 *  Format a set of make macro definitions (one per line)
6554 * Each macro value is provided enclosed in single quotes
6555 *
6556 *  Take the macro values from the macro statements found
6557 * in recursively read requirements files.
6558 */
6559void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
6560{
6561  int number;
6562
6563  set_standard_macros ();
6564
6565  cmt_regexp expression (pattern);
6566
6567  bool has_pattern = (pattern != "");
6568
6569  for (number = 0; number < Symbol::symbol_number (); number++)
6570    {
6571      Symbol& symbol = Symbol::symbol (number);
6572
6573      if (has_pattern)
6574        {
6575          if (!expression.match (symbol.name)) continue;
6576        }
6577
6578      if (Me.m_action == action_show_macros)
6579        {
6580          // Only keep macros.
6581          if ((symbol.type == Symbol::SymbolSet) ||
6582              (symbol.type == Symbol::SymbolAlias) ||
6583              (symbol.type == Symbol::SymbolPath) ||
6584              (symbol.type == Symbol::SymbolAction)) continue;
6585        }
6586      else if (Me.m_action == action_show_sets)
6587        {
6588          // Exclude macros.
6589          if ((symbol.type == Symbol::SymbolMacro) ||
6590              (symbol.type == Symbol::SymbolAction)) continue;
6591        }
6592      else if (Me.m_action == action_build_tag_makefile)
6593        {
6594          // Exclude scripts and actions
6595          if ((symbol.type == Symbol::SymbolSetupScript) ||
6596              (symbol.type == Symbol::SymbolCleanupScript) ||
6597              (symbol.type == Symbol::SymbolAction)) continue;
6598        }
6599      else if (Me.m_action == action_show_actions)
6600        {
6601          if (symbol.type != Symbol::SymbolAction) continue;
6602        }
6603
6604      if (symbol.value_lists.size () < 1) continue;
6605
6606      symbol.show_macro (mode);
6607    }
6608}
6609
6610//----------------------------------------------------------
6611void Cmt::print_tabs (int tabs)
6612{
6613  while (tabs > 0)
6614    {
6615      cout << "  ";
6616      tabs--;
6617    }
6618}
6619
6620//----------------------------------------------------------
6621int Cmt::reach_current_package ()
6622{
6623  Use& use = Use::current ();
6624  cmt_string dir;
6625
6626  if (Me.m_debug)
6627    {
6628      cout << "Cmt::reach_current_package> pwd = " 
6629           << CmtSystem::pwd () 
6630           << " path=" << Me.m_current_path
6631           << " package=" << Me.m_current_package
6632           << endl;
6633    }
6634
6635  /*
6636    Try to access the package.
6637  */
6638
6639  if (Me.m_current_package == "cmt_standalone")
6640    {
6641      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
6642        {
6643          if (!CmtSystem::cd (Me.m_current_path))
6644            {
6645              CmtError::set (CmtError::package_not_found,
6646                             "ReachCurrentPackage> Cannot reach the path directory");
6647              return (0);
6648            }
6649        }
6650
6651      if (!CmtSystem::test_file ("requirements"))
6652        {
6653          return (0);
6654        }
6655    }
6656  else if (Me.m_current_package != "")
6657    {
6658      if (!use.move_to ())
6659        {
6660          CmtError::set (CmtError::package_not_found,
6661                         "ReachCurrentPackage> Cannot reach the path directory");
6662          return (0);
6663        }
6664
6665      Me.m_current_path = use.real_path;
6666    }
6667  else
6668    {
6669      //
6670      // The cmt command has been given without explicit search for
6671      // a package. Thus it is expected that we are in the context of a
6672      // true package.
6673      //
6674      //  This means that there should be a requirements file visible.
6675      //
6676      //  If this is not true, we'll make a try into ../cmt and then
6677      // a last try into ../mgr
6678      //
6679
6680      if (!CmtSystem::test_file ("requirements"))
6681        {
6682          if (CmtSystem::cd ("../cmt") && 
6683              CmtSystem::test_file ("requirements"))
6684            {
6685              Me.m_current_style = cmt_style;
6686            }
6687          else if (CmtSystem::cd ("../mgr") && 
6688                   CmtSystem::test_file ("requirements"))
6689            {
6690              Me.m_current_style = mgr_style;
6691            }
6692          else
6693            {
6694              CmtMessage::error ("Cannot reach the mgr branch");
6695              /*
6696              if (!Me.m_quiet)
6697                {
6698                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
6699                }
6700              */
6701             
6702              CmtError::set (CmtError::package_not_found,
6703                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
6704              return (0);
6705            }
6706        }
6707
6708      dir = CmtSystem::pwd ();
6709
6710      CmtSystem::dirname (dir, Me.m_current_path);
6711      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
6712
6713      if (CmtSystem::is_version_directory (Me.m_current_version))
6714        {
6715          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6716          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
6717          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6718        }
6719      else
6720        {
6721          Me.m_current_package = Me.m_current_version;
6722          Me.m_current_version = "";
6723          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6724
6725          Me.m_current_style = no_version_style;
6726        }
6727
6728      use.set_package_name (Me.m_current_package);
6729      use.version = Me.m_current_version;
6730      use.path    = Me.m_current_path;
6731      use.style   = Me.m_current_style;
6732    }
6733
6734  configure_current_dir ();
6735  build_prefix (Me.m_current_package, Me.m_current_prefix);
6736  build_config (Me.m_current_prefix, Me.m_current_config);
6737
6738  /*
6739    Check Tag is always set up
6740  */
6741
6742  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
6743
6744  if (Me.m_current_tag == "")
6745    {
6746      cmt_string env;
6747
6748      env = CmtSystem::getenv (Me.m_current_config);
6749      if (env != "")
6750        {
6751          Tag* tag;
6752
6753          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
6754          tag->mark ();
6755          //Me.m_current_tag = env;
6756
6757          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
6758
6759        }
6760    }
6761
6762  if (Me.m_debug)
6763    {
6764      cout << "pwd = " << CmtSystem::pwd () << endl;
6765    }
6766
6767  /*
6768    Work on the requirements file.
6769  */
6770
6771  if (dir != "") dir += CmtSystem::file_separator ();
6772  dir += "requirements";
6773  SyntaxParser::parse_requirements (dir, &use);
6774
6775  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
6776
6777  /**
6778   *   It would be useful to change this mechanism. Instead of
6779   *  applying all global patterns at once to all use contexts, it
6780   *  would be much better to apply it at the end of each
6781   *  requirements file parsing, and only in the context the
6782   *  appropriate Use.
6783   *
6784   *   This would avoid the current flaw which is that when a global
6785   *  pattern specifies a "private" definition, it is actually
6786   *  applied in the scope context of the Current Use and not in
6787   *  each individual Use. Therefore the private is lost.
6788   *
6789   *   However, this induces problems since some pattern definitions
6790   *  are done AFTER the use statements, which will NOT receive the
6791   *  pattern aplications.
6792   *
6793   *   Therefore it is decided to leave this "bad" mechanism until
6794   *  everybody is aware of this constraint.
6795   *
6796   *
6797   */
6798  Pattern::apply_all_globals ();
6799
6800  /*
6801    Select all possible tags
6802  */
6803
6804  Tag::restore_tree ();
6805
6806  return (1);
6807}
6808
6809static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
6810                                 const cmt_string& path)
6811{
6812  static cmt_string fs = CmtSystem::file_separator ();
6813  cmt_string result;
6814
6815  /*
6816  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
6817  {
6818  */
6819
6820  //
6821  //  If there is a common prefix between
6822  //  use->real_path and pwd
6823  //  we have
6824  //  use->real_path = /<prefix>/aaa
6825  //  pwd            = /<prefix>/bbb
6826  //
6827  //  Then use->real_path may be expressed as:
6828  //  ../..../../aaa
6829  //   where ../..../../ moves up to /<prefix>
6830  //
6831  //   Then we try to find the shortest between
6832  //
6833  //     /<prefix> and ../..../..
6834  //
6835  cmt_string a = path;
6836 
6837  CmtSystem::cmt_string_vector va;
6838 
6839  va.clear ();
6840 
6841  CmtSystem::split (a, fs, va);
6842 
6843  int m = va.size ();
6844  if (pwd.size () < m) m = pwd.size ();
6845 
6846  int i;
6847 
6848  for (i = 0; i < m; i++)
6849    {
6850      const cmt_string& fa = va[i];
6851      const cmt_string& fb = pwd[i];
6852     
6853      if (fa != fb) break;
6854    }
6855 
6856  cmt_string ups = "";
6857 
6858  if (i > 0)
6859    {
6860      // We have the prefix.
6861      // if we count what remains from pwd, then
6862      // we have the number of ../ required to
6863      // move to /<prefix>
6864      int j;
6865     
6866      for (j = i; j < pwd.size (); j++)
6867        {
6868          if (j > i) ups += fs;
6869          ups += "..";
6870        }
6871
6872      for (j = i; j < va.size (); j++)
6873        {
6874          ups += fs;
6875          ups += va[j];
6876        }
6877    }
6878 
6879  //
6880  // Here ups contains the ../..../../aaa form
6881  // for the use->real_path or is empty when there
6882  // were no common prefix.
6883  //
6884 
6885  //if (ups != "")
6886  if ((ups != "") &&
6887      (ups.size () < path.size ()))
6888    {
6889      result = ups;
6890    }
6891  else
6892    {
6893      result = path;
6894    }
6895
6896  return (result);
6897}
6898
6899/**
6900 *   This completely local class holds primitive actions for building
6901 *   standard macros.
6902 */
6903class StandardMacroBuilder
6904{
6905public:
6906
6907  /**
6908   *  CMTVERSION
6909   */
6910  void fill_for_CMTVERSION ()
6911  {
6912    buffer = "macro CMTVERSION \"";
6913    buffer += CMTVERSION;
6914    buffer += "\"";
6915    apply ();
6916  }
6917
6918  StandardMacroBuilder (const cmt_string& tag,
6919                        const cmt_string& package,
6920                        const cmt_string& version,
6921                        const cmt_string& prefix,
6922                        CmtDirStyle style)
6923  {
6924    fs = CmtSystem::file_separator ();
6925    buffer = "";
6926    pwd = CmtSystem::pwd ();
6927    CmtSystem::split (pwd, fs, vb);
6928    current_use = &(Use::current ());
6929    current_tag = tag;
6930    current_package = package;
6931    current_version = version;
6932    current_prefix = prefix;
6933    current_style = style;
6934  }
6935
6936  void apply ()
6937  {
6938    SyntaxParser::parse_requirements_line (buffer, current_use);
6939    buffer = "";
6940  }
6941
6942  /**
6943   *   tag
6944   */
6945  void fill_for_tag ()
6946  {
6947    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
6948
6949    if (!Symbol::is_selected ("tag"))
6950      {
6951        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
6952
6953        if (current_tag == "")
6954          {
6955            buffer = "macro tag \"$(CMTCONFIG)\"";
6956          }
6957        else
6958          {
6959            buffer = "macro tag \"";
6960            buffer += current_tag;
6961            buffer += "\"";
6962          }
6963       
6964        if (tag_debug) cerr << " define tag: " << buffer << endl;
6965       
6966        apply ();
6967      }
6968  }
6969
6970  /**
6971   *   PACKAGE_ROOT
6972   */
6973  void fill_for_package (const cmt_string& current_dir)
6974  {
6975    buffer = "macro package \"";
6976    buffer += current_package;
6977    buffer += "\"";
6978    apply ();
6979
6980    buffer = "macro version \"";
6981    buffer += current_version;
6982    buffer += "\"";
6983    apply ();
6984
6985    if (!Symbol::is_selected ("PACKAGE_ROOT"))
6986      {
6987        buffer = "macro PACKAGE_ROOT \"$(";
6988        buffer += current_prefix;
6989        buffer += "ROOT";
6990        buffer += ")\"";
6991
6992        apply ();
6993      }
6994  }
6995
6996  /**
6997   *   srcdir
6998   *   src       =$(srcdir)/
6999   *   inc
7000   *   mgrdir
7001   *   mgr       =../$(mgrdir)/
7002   *   bin
7003   *   javabin
7004   *   doc
7005   *   version
7006   *   package
7007   *
7008   *   <package>_project
7009   *   <package>_cmtpath
7010   *   <package>_offset
7011   *   package_cmtpath
7012   *   package_offset
7013   *   project
7014   *
7015   */
7016  void fill_for_branches ()
7017  {
7018    /**
7019     *    Basic macros  (src, mgr, ...)
7020     */
7021   
7022    if (current_style == none_style)
7023      {
7024        buffer = "macro srcdir \".";
7025        buffer += "\"";
7026        apply ();
7027
7028        buffer = "macro src \".";
7029        buffer += fs;
7030        buffer += "\"";
7031        apply ();
7032
7033        buffer = "macro inc \".";
7034        buffer += fs;
7035        buffer += "\"";
7036        apply ();
7037
7038        buffer = "macro mgr \".";
7039        buffer += fs;
7040        buffer += "\"";
7041        apply ();
7042
7043        buffer = "macro bin \".";
7044        buffer += fs;
7045        buffer += "\"";
7046        apply ();
7047
7048        buffer = "macro BIN \"";
7049        buffer += pwd;
7050        buffer += fs;
7051        buffer += "\"";
7052        apply ();
7053
7054        buffer = "macro javabin \".";
7055        buffer += fs;
7056        buffer += "\"";
7057        apply ();
7058
7059        buffer = "macro doc \".";
7060        buffer += fs;
7061        buffer += "\"";
7062        apply ();
7063      }
7064    else
7065      {
7066        if (!Symbol::is_selected ("srcdir"))
7067          {
7068            buffer = "macro srcdir \"..";
7069            buffer += fs;
7070            buffer += "src";
7071            buffer += "\"";
7072            apply ();
7073          }
7074       
7075        if (!Symbol::is_selected ("src"))
7076          {
7077            buffer = "macro src \"..";
7078            buffer += fs;
7079            buffer += "src";
7080            buffer += fs;
7081            buffer += "\"";
7082            apply ();
7083          }
7084       
7085        if (!Symbol::is_selected ("inc"))
7086          {
7087            buffer = "macro inc \"..";
7088            buffer += fs;
7089            buffer += "src";
7090            buffer += fs;
7091            buffer += "\"";
7092            apply ();
7093          }
7094       
7095        if (!Symbol::is_selected ("doc"))
7096          {
7097            buffer = "macro doc \"..";
7098            buffer += fs;
7099            buffer += "doc";
7100            buffer += fs;
7101            buffer += "\"";
7102            apply ();
7103          }
7104       
7105        if (!Symbol::is_selected ("bin"))
7106          {
7107            cmt_string package_tag = current_package;
7108            package_tag += "_tag";
7109
7110            buffer = "macro bin \"..";
7111            buffer += fs;
7112            buffer += "$(";
7113            buffer += package_tag;
7114            buffer += ")";
7115            buffer += fs;
7116            buffer += "\"";
7117            apply ();
7118
7119            cmt_string pardir;
7120            CmtSystem::dirname (pwd, pardir);
7121            //            buffer = "macro BIN \"$(PACKAGE_ROOT)";
7122            buffer = "macro BIN \"";
7123            buffer += pardir;
7124            buffer += fs;
7125            buffer += "$(";
7126            buffer += package_tag;
7127            buffer += ")";
7128            buffer += fs;
7129            buffer += "\"";
7130            apply ();
7131          }
7132        else
7133          {
7134            cmt_string temp = "$(bin)";
7135            Symbol::expand (temp);
7136            int len (temp.size());
7137            cmt_string atemp;
7138            if (CmtSystem::absolute_path (temp))
7139              {
7140                CmtSystem::compress_path (temp, atemp);
7141              }
7142            else
7143              {
7144                atemp = pwd + fs + temp;
7145                CmtSystem::compress_path (atemp);
7146              }
7147            buffer = "macro BIN \"";
7148            buffer += atemp;
7149            buffer += "\"";
7150            apply ();
7151            if (0 != len && fs != temp[len - 1])
7152              {
7153                buffer = "macro_append bin \"";
7154                buffer += fs;
7155                buffer += "\"";
7156                apply ();
7157
7158                buffer = "macro_append BIN \"";
7159                buffer += fs;
7160                buffer += "\"";
7161                apply ();
7162              }
7163          }
7164
7165        if (!Symbol::is_selected ("javabin"))
7166          {
7167            buffer = "macro javabin \"..";
7168            buffer += fs;
7169            buffer += "classes";
7170            buffer += fs;
7171            buffer += "\"";
7172            apply ();
7173          }
7174       
7175        if (current_style == mgr_style)
7176          {
7177            buffer = "macro mgrdir \"mgr\"";
7178            apply ();
7179
7180            buffer = "macro mgr \"..";
7181            buffer += fs;
7182            buffer += "mgr";
7183            buffer += fs;
7184            buffer += "\"";
7185            apply ();
7186          }
7187        else
7188          {
7189            buffer = "macro mgrdir \"cmt\"";
7190            apply ();
7191
7192            buffer = "macro mgr \"..";
7193            buffer += fs;
7194            buffer += "cmt";
7195            buffer += fs;
7196            buffer += "\"";
7197            apply ();
7198          }
7199
7200        Cmt::configure_current_cmtpath ();
7201      }
7202  }
7203
7204  /**
7205   *   project
7206   */
7207  void fill_for_project ()
7208  {
7209    if (current_style == none_style) return;
7210
7211    cmt_string project_name;
7212    Project* project = Project::get_current ();
7213    if (project != 0)
7214      {
7215        project_name = project->get_name ();
7216      }
7217
7218    buffer = "macro project \"";
7219    buffer += project_name;
7220    buffer += "\"";
7221    apply ();
7222  }
7223
7224  /**
7225   *   use_requirements
7226   */
7227  void fill_for_use_requirements ()
7228  {
7229    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7230
7231    if (Uses.size () == 0) return;
7232
7233    if (!Symbol::is_selected ("use_requirements"))
7234      {
7235        buffer  = "macro use_requirements \"";
7236        buffer += "requirements ";
7237       
7238        for (int number = 0; number < Uses.size (); number++)
7239          {
7240            Use* use = Uses[number];
7241           
7242            if (use->discarded) continue;
7243            if (use->m_hidden) continue;
7244           
7245            if (use->located ())
7246              {
7247                buffer += "$(";
7248                buffer += use->prefix;
7249                buffer += "ROOT)";
7250                buffer += fs;
7251               
7252                if (use->style == mgr_style) buffer += "mgr";
7253                else buffer += "cmt";
7254               
7255                buffer += fs;
7256                buffer += "requirements ";
7257              }
7258          }
7259       
7260        buffer += "\"";
7261       
7262        apply ();
7263      }
7264  }
7265
7266  /**
7267   *   use_includes
7268   */
7269  void fill_for_use_includes ()
7270  {
7271    Include::parse_all (&(Use::current()));
7272
7273    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7274
7275    if (Uses.size () == 0) return;
7276
7277    if (!Symbol::is_selected ("use_includes"))
7278      {
7279        buffer = "macro_append use_includes \' ";
7280       
7281        for (int number = 0; number < Uses.size (); number++)
7282          {
7283            Use* use = Uses[number];
7284           
7285            if (use->discarded) continue;
7286            if (use->m_hidden) continue;
7287
7288            Package* p = use->get_package ();
7289            if (p->is_cmt ()) continue;
7290
7291            if (Cmt::get_debug ())
7292              {
7293                cout << "fill use_includes for " << use->get_package_name () 
7294                     << " discarded=" << use->discarded
7295                     << " auto_imports=" << use->auto_imports << endl;
7296              }
7297           
7298            if (use->auto_imports == Off) continue;
7299           
7300            Include::parse_all (use);
7301
7302            use->fill_includes_macro (buffer);
7303          }
7304       
7305        buffer += "\'";
7306       
7307        apply ();
7308      }
7309  }
7310
7311  /**
7312   *   use_fincludes
7313   */
7314  void fill_for_use_fincludes ()
7315  {
7316    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7317
7318    if (Uses.size () == 0) return;
7319
7320    if (!Symbol::is_selected ("use_fincludes"))
7321      {
7322        buffer = "macro_append use_fincludes \" $(use_includes)\"";
7323        apply ();
7324      }
7325  }
7326
7327  /**
7328   *   use_stamps
7329   */
7330  void fill_for_use_stamps ()
7331  {
7332    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7333
7334    if (Uses.size () == 0) return;
7335
7336    if (!Symbol::is_selected ("use_stamps"))
7337      {
7338        /*
7339        buffer = "macro use_stamps \"";
7340        (Use::current()).fill_macro (buffer, "stamps");
7341       
7342        for (int number = 0; number < Uses.size (); number++)
7343          {
7344            Use* use = Uses[number];
7345           
7346            if (use->discarded) continue;
7347            if (use->m_hidden) continue;
7348
7349            Package* p = use->get_package ();
7350            if (p->is_cmt ()) continue;
7351           
7352            use->fill_macro (buffer, "stamps");
7353          }
7354       
7355        buffer += "\"";
7356        */
7357        Use::fill_macro_all (buffer, "stamps");
7358        apply ();
7359      }
7360  }
7361
7362  /**
7363   *   use_cflags
7364   */
7365  void fill_for_use_cflags ()
7366  {
7367    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7368
7369    if (Uses.size () == 0) return;
7370
7371    if (!Symbol::is_selected ("use_cflags"))
7372      {
7373        Use::fill_macro_all (buffer, "cflags");
7374        apply ();
7375      }
7376  }
7377
7378  /**
7379   *   use_pp_cflags
7380   */
7381  void fill_for_use_pp_cflags ()
7382  {
7383    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7384
7385    if (Uses.size () == 0) return;
7386
7387    if (!Symbol::is_selected ("use_pp_cflags"))
7388      {
7389        Use::fill_macro_all (buffer, "pp_cflags");
7390        apply ();
7391      }
7392  }
7393
7394  /**
7395   *   use_cppflags
7396   */
7397  void fill_for_use_cppflags ()
7398  {
7399    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7400
7401    if (Uses.size () == 0) return;
7402
7403    if (!Symbol::is_selected ("use_cppflags"))
7404      {
7405        Use::fill_macro_all (buffer, "cppflags");
7406        apply ();
7407      }
7408  }
7409
7410  /**
7411   *   use_pp_cppflags
7412   */
7413  void fill_for_use_pp_cppflags ()
7414  {
7415    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7416
7417    if (Uses.size () == 0) return;
7418
7419    if (!Symbol::is_selected ("use_pp_cppflags"))
7420      {
7421        Use::fill_macro_all (buffer, "pp_cppflags");
7422        apply ();
7423      }
7424  }
7425
7426  /**
7427   *   use_fflags
7428   */
7429  void fill_for_use_fflags ()
7430  {
7431    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7432
7433    if (Uses.size () == 0) return;
7434
7435    if (!Symbol::is_selected ("use_fflags"))
7436      {
7437        Use::fill_macro_all (buffer, "fflags");
7438        apply ();
7439      }
7440  }
7441
7442  /**
7443   *   use_pp_fflags
7444   */
7445  void fill_for_use_pp_fflags ()
7446  {
7447    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7448
7449    if (Uses.size () == 0) return;
7450
7451    if (!Symbol::is_selected ("use_pp_fflags"))
7452      {
7453        Use::fill_macro_all (buffer, "pp_fflags");
7454        apply ();
7455      }
7456  }
7457
7458  /**
7459   *   use_linkopts
7460   */
7461  void fill_for_use_linkopts ()
7462  {
7463    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7464
7465    if (Uses.size () == 0) return;
7466
7467    if (!Symbol::is_selected ("use_linkopts"))
7468      {
7469        Use::fill_macro_all (buffer, "linkopts");
7470        apply ();
7471      }
7472  }
7473
7474  /**
7475   *   use_libraries
7476   */
7477  void fill_for_use_libraries ()
7478  {
7479    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7480
7481    if (Uses.size () == 0) return;
7482
7483    if (!Symbol::is_selected ("use_libraries"))
7484      {
7485        /*
7486        buffer  = "macro use_libraries \"";
7487
7488        for (int number = 0; number < Uses.size (); number++)
7489          {
7490            Use* use = Uses[number];
7491           
7492            if (use->discarded) continue;
7493            if (use->m_hidden) continue;
7494           
7495            Package* p = use->get_package ();
7496            if (p->is_cmt ()) continue;
7497
7498            use->fill_macro (buffer, "libraries");
7499          }
7500       
7501        buffer += "\"";
7502        */       
7503        Use::fill_macro_all (buffer, "libraries");
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>_libraries
7585   *    <constituent>_stamps
7586   *
7587   */
7588  void fill_for_all_constituents ()
7589  {
7590    /// First, finish the parsing of constituent parameters.
7591    if (Cmt::get_debug ())
7592      {
7593        cout << "fill_for_all_constituents>" << endl;
7594      }
7595
7596    Constituent::parse_all ();
7597
7598    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7599   
7600    const Constituent::ConstituentVector& constituents =
7601      Constituent::constituents ();
7602
7603 
7604    // Prepare the auto_imports states in a vector
7605    cmt_vector<bool> base_auto_imports_states;
7606
7607    base_auto_imports_states.resize (Uses.size ());
7608
7609    int number;
7610   
7611    for (number = 0; number < Uses.size (); number++)
7612      {
7613        Use* use = Uses[number];
7614        base_auto_imports_states[number] = (use->auto_imports != Off);
7615      }
7616   
7617    // Now scan all constituents
7618       
7619    for (number = 0; number < constituents.size (); number++)
7620      {
7621        const Constituent& constituent = constituents[number];
7622       
7623        //==== GLAST addition for vs.net ==========
7624        buffer = "macro ";
7625        buffer += constituent.name;
7626        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
7627        apply ();
7628       
7629        if (Cmt::get_debug ())
7630          {
7631            cout << "Checking " << constituent.name  << " against imports requests" << endl;
7632          }
7633        Use::UsePtrVector imports;
7634        int i;
7635       
7636        /**
7637         *  Problem for imports in constituents.
7638         *
7639         *     1) use_xxx has holes due to the corresponding
7640         *         -no_auto_imports options attached to some
7641         *        use statements (including the transitive ones)
7642         *
7643         *     2) the -import=yyy options provided to a given constituent
7644         *        should restore the appropriate holes as well as
7645         *        all transitive ones.
7646         *
7647         *     3) for use_linkopts, missing pieces must be filled at
7648         *        the right position. (for others, order is not relevant
7649         *        while transitive access is required for all)
7650         *
7651         */
7652       
7653        if (constituent.type == Document)
7654          { 
7655            continue;
7656          }
7657       
7658        if (constituent.imports.size () == 0) 
7659          {
7660            buffer = "macro_append ";
7661            buffer += constituent.name;
7662            buffer += "_use_linkopts ";
7663            buffer += " \" ";
7664           
7665            current_use->fill_macro (buffer, "linkopts");
7666           
7667            for (i = 0; i < Uses.size (); i++)
7668              {
7669                if (base_auto_imports_states[i])
7670                  {
7671                    Use* u = Uses[i];
7672                   
7673                    if (u->discarded) continue;
7674                    if (u->m_hidden) continue;
7675                   
7676                    Package* p = u->get_package ();
7677                    if (p->is_cmt ()) continue;
7678                   
7679                    u->fill_macro (buffer, "linkopts");
7680                  }
7681              }
7682            buffer += "\"";
7683            apply ();
7684           
7685            /*
7686              buffer = "macro_append ";
7687              buffer += constituent.name;
7688              buffer += "_use_linkopts ";
7689             
7690              buffer += " \" $(use_linkopts)\"";
7691              apply ();
7692            */
7693           
7694            continue;
7695          }
7696       
7697        // From here on, the constituent HAS import options.
7698       
7699        /**
7700         * Create a private copy of the state vector. This private copy
7701         * will be updated according to -import=xxx modifiers for the
7702         * current constituent.
7703         */
7704        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
7705       
7706        for (i = 0; i < constituent.imports.size (); i++)
7707          {
7708            const cmt_string& import = constituent.imports[i];
7709           
7710            //
7711            // Resolve the imported uses
7712            //
7713           
7714            int use_index = Use::find_index (import, "", "");
7715           
7716            if (use_index >= 0)
7717              {
7718                Use* u = Uses[use_index];
7719               
7720                if (u->discarded) continue;
7721                if (u->m_hidden) continue;
7722               
7723                if (Cmt::get_debug ())
7724                  {
7725                    cout << constituent.name  << " needs imports " << import << " "
7726                         << use_index << " " 
7727                         << u->get_package()->get_name() << " "
7728                         << " u->auto_imports=" << u->auto_imports
7729                         << " Off=" << Off
7730                         << " On=" << On
7731                         << endl;
7732                  }
7733               
7734                Package* p = u->get_package ();
7735                if (p->is_cmt ()) continue;
7736               
7737                if (u->auto_imports != Off) continue;
7738               
7739                Use::set_auto_imports_state (use_index, auto_imports_states);
7740              }
7741          }
7742       
7743        if (Cmt::get_debug ())
7744          {
7745            cout << constituent.name  << " has imports " << endl;
7746          }
7747       
7748       
7749        /**
7750         *   Find all newly exposed packages and precompute this list inside
7751         *   a vector.
7752         */
7753        for (i = 0; i < base_auto_imports_states.size (); i++)
7754          {
7755            //      if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
7756            if (base_auto_imports_states[i] == On || auto_imports_states[i] == Off) continue;
7757            /**
7758             *  Consider the package (i) for import only if it is:
7759             *   o not imported yet (i.e., base_auto_imports_states[i] != On)
7760             *   o requested for import according to -import=xxx modifiers for
7761             *     the current constituent (i.e., auto_imports_states[i] != Off)
7762             */
7763            Use* u = Uses[i];
7764           
7765            if (u->discarded) continue;
7766            if (u->m_hidden)  continue;
7767           
7768            Package* p = u->get_package ();
7769            if (p->is_cmt ()) continue;
7770           
7771            if (Cmt::get_debug ())
7772              {
7773                cout << constituent.name  << " has import " << p->get_name () << endl;
7774              }
7775           
7776            imports.push_back (u);
7777          }
7778       
7779        /**
7780         *  Only for linkopts we take care of the order. This means
7781         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
7782         *
7783         *  (see the application fragments)
7784         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
7785         */
7786        buffer = "macro_append ";
7787        buffer += constituent.name;
7788        buffer += "_use_linkopts ";
7789        buffer += " \" ";
7790       
7791        current_use->fill_macro (buffer, "linkopts");
7792       
7793        for (i = 0; i < Uses.size (); i++)
7794          {
7795            if (auto_imports_states[i])
7796              {
7797                Use* u = Uses[i];
7798               
7799                if (u->discarded) continue;
7800                if (u->m_hidden) continue;
7801               
7802                Package* p = u->get_package ();
7803                if (p->is_cmt ()) continue;
7804               
7805                u->fill_macro (buffer, "linkopts");
7806              }
7807          }
7808        buffer += "\"";
7809        apply ();
7810       
7811        if (imports.size () == 0) continue;
7812       
7813        cmt_string prefix;
7814       
7815        //
7816        // Documents are not considered
7817        //
7818        switch (constituent.type)
7819          {
7820          case Application:
7821            prefix = "app_";
7822            break;
7823          case Library:
7824            prefix = "lib_";
7825            break;
7826          }
7827       
7828        buffer = "macro_append ";
7829        buffer += prefix;
7830        buffer += constituent.name;
7831        buffer += "_cflags ";
7832        buffer += " \' ";
7833        for (i = 0; i < imports.size (); i++)
7834          {
7835            Use* u = imports[i];
7836           
7837            u->fill_includes_macro (buffer);
7838            u->fill_macro (buffer, "cflags");
7839          }
7840        buffer += "\'";
7841        apply ();
7842       
7843        buffer = "macro_append ";
7844        buffer += prefix;
7845        buffer += constituent.name;
7846        buffer += "_pp_cflags ";
7847        buffer += " \" ";
7848        for (i = 0; i < imports.size (); i++)
7849          {
7850            Use* u = imports[i];
7851           
7852            u->fill_macro (buffer, "pp_cflags");
7853          }
7854        buffer += "\"";
7855        apply ();
7856       
7857        buffer = "macro_append ";
7858        buffer += prefix;
7859        buffer += constituent.name;
7860        buffer += "_cppflags ";
7861        buffer += " \' ";
7862        for (i = 0; i < imports.size (); i++)
7863          {
7864            Use* u = imports[i];
7865           
7866            u->fill_includes_macro (buffer);
7867            u->fill_macro (buffer, "cppflags");
7868          }
7869        buffer += "\'";
7870        apply ();
7871       
7872        buffer = "macro_append ";
7873        buffer += prefix;
7874        buffer += constituent.name;
7875        buffer += "_pp_cppflags ";
7876        buffer += " \" ";
7877        for (i = 0; i < imports.size (); i++)
7878          {
7879            Use* u = imports[i];
7880           
7881            u->fill_macro (buffer, "pp_cppflags");
7882          }
7883        buffer += "\"";
7884        apply ();
7885       
7886        buffer = "macro_append ";
7887        buffer += prefix;
7888        buffer += constituent.name;
7889        buffer += "_fflags ";
7890        buffer += " \' ";
7891        for (i = 0; i < imports.size (); i++)
7892          {
7893            Use* u = imports[i];
7894           
7895            u->fill_includes_macro (buffer);
7896            u->fill_macro (buffer, "fflags");
7897          }
7898        buffer += "\'";
7899        apply ();
7900       
7901        buffer = "macro_append ";
7902        buffer += prefix;
7903        buffer += constituent.name;
7904        buffer += "_pp_fflags ";
7905        buffer += " \" ";
7906        for (i = 0; i < imports.size (); i++)
7907          {
7908            Use* u = imports[i];
7909           
7910            u->fill_macro (buffer, "pp_fflags");
7911          }
7912        buffer += "\"";
7913        apply ();
7914       
7915        buffer = "macro_append ";
7916        buffer += constituent.name;
7917        buffer += "_libraries ";
7918        buffer += " \" ";
7919        for (i = 0; i < imports.size (); i++)
7920          {
7921            Use* u = imports[i];
7922           
7923            u->fill_macro (buffer, "libraries");
7924          }
7925        buffer += "\"";
7926        apply ();
7927
7928        buffer = "macro_append ";
7929        buffer += constituent.name;
7930        buffer += "_stamps ";
7931        buffer += " \" ";
7932        for (i = 0; i < imports.size (); i++)
7933          {
7934            Use* u = imports[i];
7935           
7936            u->fill_macro (buffer, "stamps");
7937          }
7938        buffer += "\"";
7939        apply ();
7940
7941        /**
7942         *  Setting ${CONSTITUENT}linkopts is a temporary solution
7943         *  until the backward compatibility solution for a proper
7944         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
7945         *  is acheived.
7946         *
7947         */
7948        /**
7949        buffer = "macro_append ";
7950        buffer += constituent.name;
7951        buffer += "linkopts ";
7952        buffer += " \" ";
7953        for (i = 0; i < imports.size (); i++)
7954          {
7955            Use* u = imports[i];
7956           
7957            u->fill_macro (buffer, "linkopts");
7958          }
7959        buffer += "\"";
7960        apply ();
7961        */
7962      }
7963  }
7964 
7965  /**
7966   *   Macros implied or required to manage constituents.
7967   */
7968  void fill_for_constituent_macros ()
7969  {
7970    int number;
7971    cmt_string temp;
7972
7973    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
7974 
7975    if (!Symbol::is_selected ("constituents"))
7976      {
7977        temp = "macro_append constituents \" ";
7978       
7979        for (number = 0; number < constituents.size (); number++)
7980          {
7981            const Constituent& constituent = constituents[number];
7982           
7983            if (constituent.group == 0)
7984              {
7985                temp += constituent.name;
7986                temp += " ";
7987              }
7988          }
7989       
7990        temp += "\"";
7991       
7992        SyntaxParser::parse_requirements_line (temp, current_use);
7993      }
7994   
7995    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
7996                                           current_use);
7997   
7998    if (!Symbol::is_selected ("constituentsclean"))
7999      {
8000        temp = "macro_append constituentsclean \" ";
8001       
8002        for (number = constituents.size () - 1; number >= 0 ; number--)
8003          {
8004            const Constituent& constituent = constituents[number];
8005           
8006            if (constituent.group == 0)
8007              {
8008                temp += constituent.name;
8009                temp += "clean ";
8010              }
8011          }
8012       
8013        temp += "\"";
8014       
8015        SyntaxParser::parse_requirements_line (temp, current_use);
8016      }
8017   
8018    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
8019                                           current_use);
8020   
8021    const Group::GroupVector& groups = Group::groups ();
8022   
8023    for (number = 0; number < groups.size (); number++)
8024      {
8025        const Group& group = groups[number];
8026       
8027        temp = "macro_append ";
8028        temp += group.name ();
8029        temp += "_constituents \" ";
8030       
8031        int i;
8032       
8033        for (i = 0; i < constituents.size (); i++)
8034          {
8035            const Constituent& constituent = constituents[i];
8036           
8037            if ((constituent.group != 0) && 
8038                (group.name () == constituent.group->name ()))
8039              {
8040                temp += constituent.name;
8041                temp += " ";
8042              }
8043          }
8044       
8045        temp += "\"";
8046       
8047        SyntaxParser::parse_requirements_line (temp, current_use);
8048       
8049        temp = "macro_append ";
8050        temp += group.name ();
8051        temp += "_constituentsclean \" ";
8052       
8053        for (i = constituents.size () - 1; i >= 0 ; i--)
8054          {
8055            const Constituent& constituent = constituents[i];
8056           
8057            if ((constituent.group != 0) && 
8058                (group.name () == constituent.group->name ()))
8059              {
8060                temp += constituent.name;
8061                temp += "clean ";
8062              }
8063          }
8064       
8065        temp += "\"";
8066       
8067        SyntaxParser::parse_requirements_line (temp, current_use);
8068      }
8069  }
8070
8071  /**
8072   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
8073   */
8074  void fill_for_install_area ()
8075  {
8076    CmtPathPattern::apply_all ();
8077
8078    const Use& current_use = Use::current ();
8079
8080    if (current_use.get_strategy ("InstallArea"))
8081      {
8082        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
8083       
8084        ia_mgr.setup ();
8085      }
8086  }
8087
8088  /**
8089   * Macros to be defined once current_package is known
8090   * and even before reading its requirements file.
8091   */
8092  void fill_for_current_package (const cmt_string& current_dir)
8093  {
8094    fill_for_tag ();
8095    fill_for_package (current_dir);
8096  }
8097
8098private:
8099  cmt_string fs;
8100  cmt_string buffer;
8101  CmtSystem::cmt_string_vector vb;
8102  cmt_string pwd;
8103  Use* current_use;
8104  cmt_string current_tag; 
8105  cmt_string current_package; 
8106  cmt_string current_version; 
8107  cmt_string current_prefix; 
8108  CmtDirStyle current_style;
8109};
8110
8111//----------------------------------------------------------
8112void Cmt::set_current_access (AccessMode mode)
8113{
8114  Me.m_current_access = mode;
8115}
8116
8117//----------------------------------------------------------
8118void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
8119{
8120  Me.m_scope_filtering_mode = mode;
8121}
8122
8123//----------------------------------------------------------
8124void Cmt::set_standard_macros ()
8125{
8126  if (Me.m_standard_macros_done) return;
8127
8128  Me.m_standard_macros_done = true;
8129
8130  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8131  Use& current_use = Use::current ();
8132
8133  cmt_string fs = CmtSystem::file_separator ();
8134
8135  cmt_string pwd = CmtSystem::pwd ();
8136
8137  /**
8138   * This is already done in
8139   void Cmt::configure_current_package ()
8140
8141  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
8142  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
8143  else Me.m_current_style = none_style;
8144
8145  {
8146    cmt_string v;
8147    CmtSystem::dirname (pwd, v);
8148    CmtSystem::basename (v, v);
8149    if (!CmtSystem::is_version_directory (v))
8150      {
8151        Me.m_current_style = no_version_style;
8152      }
8153  }
8154  */
8155
8156  // Prepare computation of the best form for relative path from current directory
8157  // to package directories.
8158  CmtSystem::cmt_string_vector vb;
8159  CmtSystem::split (pwd, fs, vb);
8160
8161
8162  /**
8163   *    TAG management
8164   */
8165
8166  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
8167
8168  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
8169
8170  if (Me.m_current_tag != "")
8171    {
8172      // this is when some -tag= argument was used.
8173      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
8174    }
8175  else if (Symbol::is_selected ("CMTCONFIG"))
8176    {
8177      // This is when CMTCONFIG has been set from some requirements file
8178      Symbol* macro = Symbol::find ("CMTCONFIG");
8179      if (macro != 0)
8180        {
8181          Me.m_current_tag = macro->build_macro_value ();
8182          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
8183        }
8184    }
8185  else
8186    {
8187      // this is when no -tag= argument was used.
8188      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
8189      if (current_use.get_package_name () == "CMT")
8190        {
8191          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
8192        }
8193      else
8194        {
8195          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
8196        }
8197
8198      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
8199    }
8200
8201  if (Me.m_debug)
8202    {
8203      cout << "set_standard_macro3>" << endl;
8204    }
8205
8206  StandardMacroBuilder builder (Me.m_current_tag,
8207                                Me.m_current_package,
8208                                Me.m_current_version,
8209                                Me.m_current_prefix,
8210                                Me.m_current_style);
8211
8212
8213  builder.fill_for_current_package (Me.m_current_dir);
8214
8215  builder.fill_for_branches ();
8216  builder.fill_for_project ();
8217
8218  builder.fill_for_install_area ();
8219
8220  builder.fill_for_use_requirements ();
8221  builder.fill_for_use_includes ();
8222  builder.fill_for_use_fincludes ();
8223  builder.fill_for_use_stamps ();
8224  builder.fill_for_use_cflags ();
8225  builder.fill_for_use_pp_cflags ();
8226  builder.fill_for_use_cppflags ();
8227  builder.fill_for_use_pp_cppflags ();
8228  builder.fill_for_use_fflags ();
8229  builder.fill_for_use_pp_fflags ();
8230  builder.fill_for_use_linkopts ();
8231  builder.fill_for_use_libraries ();
8232  builder.fill_for_includes ();
8233  builder.fill_for_fincludes ();
8234  builder.fill_for_all_constituents ();
8235  builder.fill_for_constituent_macros ();
8236}
8237
8238void Cmt::set_all_sets_done ()
8239{
8240  Me.m_all_sets_done = true;
8241}
8242
8243void Cmt::reset_all_sets_done ()
8244{
8245  Me.m_all_sets_done = false;
8246}
8247
8248//----------------------------------------------------------
8249void Cmt::use_cmt ()
8250{
8251  UseRef use;
8252  bool recursive_copy = Me.m_recursive;
8253  bool debug_copy = Me.m_debug;
8254
8255  if (Me.m_default_path.size () <= 0) return;
8256  if (Me.m_current_package == "CMT") return;
8257
8258  Me.m_recursive = true;
8259  //Me.m_debug = false;
8260  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
8261  Me.m_recursive = recursive_copy;
8262  Me.m_debug = debug_copy;
8263}
8264
8265//----------------------------------------------------------
8266void Cmt::use_home_requirements ()
8267{
8268  use_special_requirements (Me.m_cmt_home, 
8269                            CmtSystem::get_home_package (), 
8270                            "requirements");
8271}
8272
8273//----------------------------------------------------------
8274void Cmt::use_user_context_requirements ()
8275{
8276  use_special_requirements (Me.m_cmt_user_context, 
8277                            CmtSystem::get_user_context_package (), 
8278                            "requirements");
8279}
8280
8281//----------------------------------------------------------
8282void Cmt::use_special_requirements (const cmt_string& path, 
8283                                    const cmt_string& name, 
8284                                    const cmt_string& file_name)
8285{
8286  if (path == "") 
8287    {
8288      return;
8289    }
8290
8291  UseRef use;
8292  bool recursive_copy = Me.m_recursive;
8293
8294  if (Me.m_default_path.size () <= 0) return;
8295  if (Me.m_current_package == "CMT") return;
8296
8297  Me.m_recursive = true;
8298
8299  use = Use::add (path, name, "v0", "", "", "", 0);
8300
8301  cmt_string f = path;
8302  f += CmtSystem::file_separator ();
8303  f += file_name;
8304  SyntaxParser::parse_requirements (f, use);
8305
8306  Me.m_recursive = recursive_copy;
8307}
8308
8309//-------------------------------------------------
8310void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
8311                            const cmt_string& separator,
8312                            cmt_string& result)
8313{
8314  result.erase (0);
8315
8316  for (int i = 0; i < v.size (); i++)
8317    {
8318      const cmt_string& s = v[i];
8319      if (s == "") continue;
8320
8321      if (i > 0) result += separator;
8322      result += v[i];
8323    }
8324}
8325
8326//-------------------------------------------------
8327cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
8328{
8329  cmt_string result;
8330
8331  vector_to_string (v, " ", result);
8332
8333  return (result);
8334}
Note: See TracBrowser for help on using the repository browser.