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

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

See C.L. 415

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