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

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

See C.L. 399

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