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

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

See C.L. 416

  • Property svn:eol-style set to native
File size: 214.7 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                       "  echo \"${CMTROOT}/mgr/cmt cleanup -%s "
4842                       "-pack=%s -version=%s -path=%s $* >${tempfile}\"\n"
4843                       "  set cmtcleanupstatus=2\n"
4844                       "  /bin/rm -f ${tempfile}\n"
4845                       "  exit $cmtcleanupstatus\n"
4846                       "endif\n"
4847                       "set cmtcleanupstatus=0\n"
4848                       "source ${tempfile}\n"
4849                       "if ( $status != 0 ) then\n"
4850                       "  set cmtcleanupstatus=2\n"
4851                       "endif\n"
4852                       "/bin/rm -f ${tempfile}\n"
4853                       "exit $cmtcleanupstatus\n",
4854                       suffix[i].c_str (),
4855                       Me.m_current_package.c_str (),
4856                       version.c_str (),
4857                       Me.m_current_path.c_str ());
4858            }
4859          else if (mode[i] == Sh)
4860            {
4861              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4862              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4863              fprintf (f, "fi\n");
4864              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4865              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4866              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4867              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4868                       "-pack=%s -version=%s -path=%s $* >${tempfile}\n",
4869                       suffix[i].c_str (),
4870                       Me.m_current_package.c_str (),
4871                       version.c_str (),
4872                       Me.m_current_path.c_str ());
4873              fprintf (f,
4874                       "if test $? != 0 ; then\n"
4875                       "  echo >&2 \"${CMTROOT}/mgr/cmt cleanup -%s "
4876                       "-pack=%s -version=%s -path=%s $* >${tempfile}\"\n"
4877                       "  cmtcleanupstatus=2\n"
4878                       "  /bin/rm -f ${tempfile}\n"
4879                       "  return $cmtcleanupstatus\n"
4880                       "fi\n"
4881                       "cmtcleanupstatus=0\n"
4882                       ". ${tempfile}\n"
4883                       "if test $? != 0 ; then\n"
4884                       "  cmtcleanupstatus=2\n"
4885                       "fi\n"
4886                       "/bin/rm -f ${tempfile}\n"
4887                       "return $cmtcleanupstatus\n",
4888                       suffix[i].c_str (),
4889                       Me.m_current_package.c_str (),
4890                       version.c_str (),
4891                       Me.m_current_path.c_str ());
4892            }
4893          else if (mode[i] == Bat)
4894            {
4895              dos_script_prefix (f, Me.m_cmt_root, 
4896                                 Me.m_current_package, version, Me.m_current_path,
4897                                 "cleanup");
4898            }
4899
4900          fprintf (f, "\n");
4901
4902          CmtSystem::close_ostream (f, file_name);
4903          //          fclose (f);
4904
4905          cmt_string old_file_name = "cleanup";
4906          old_file_name += ".";
4907          old_file_name += suffix[i];
4908
4909          CmtSystem::compare_and_update_files (file_name, old_file_name);
4910        }
4911      else
4912        {
4913          CmtError::set (CmtError::file_access_error, file_name);
4914        }
4915    }
4916}
4917
4918//----------------------------------------------------------
4919void Cmt::install_setup_scripts ()
4920{
4921#ifdef WIN32
4922  static const int modes = 1;
4923  static const cmt_string suffix[1]   = {"bat"};
4924  static const PrintMode  mode[1]     = {Bat};
4925#else
4926  static const int modes = 2;
4927  static const cmt_string suffix[2]   = {"csh", "sh"};
4928  static const PrintMode  mode[2]     = {Csh, Sh};
4929#endif
4930
4931  Use& current_use = Use::current ();
4932
4933  if (!current_use.get_strategy ("SetupScripts"))
4934    {
4935      for (int i = 0; i < modes; i++)
4936        {
4937          cmt_string old_file_name = "setup";
4938          old_file_name += ".";
4939          old_file_name += suffix[i];
4940          if (CmtSystem::test_file (old_file_name))
4941            {
4942              if (CmtMessage::active (Error))
4943                cerr << "Removing setup script " + old_file_name << endl;
4944              CmtSystem::remove_file (old_file_name);
4945            }
4946        }
4947      return;
4948    }
4949
4950  if (CmtMessage::active (Error))
4951    cerr << "Creating setup scripts." << endl;
4952 
4953  cmt_string no_cleanup_opt;
4954
4955  if (current_use.get_strategy ("SetupCleanup"))
4956    {
4957      no_cleanup_opt = " -no_cleanup";
4958    }
4959
4960  cmt_string temp;
4961  int i;
4962
4963  cmt_string version = Me.m_current_version;
4964  if (version == "v*") version = "";
4965
4966  for (i = 0; i < modes; i++)
4967    {
4968      cmt_string file_name = "setup";
4969      file_name += ".";
4970      file_name += suffix[i];
4971      file_name += ".";
4972      file_name += "new";
4973
4974      FILE* f = fopen (file_name.c_str (), "wb");
4975      if (f != NULL)
4976        {
4977          if (mode[i] == Csh)
4978            {
4979              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4980                       Me.m_current_package.c_str (),
4981                       version.c_str (),
4982                       Me.m_current_path.c_str ());
4983              fprintf (f, "\n");
4984
4985              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4986              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4987              fprintf (f, "endif\n");
4988              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4989              fprintf (f, "\n");
4990              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4991              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4992              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4993                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}\n",
4994                       suffix[i].c_str (),
4995                       Me.m_current_package.c_str (),
4996                       version.c_str (),
4997                       Me.m_current_path.c_str (),
4998                       no_cleanup_opt.c_str ());
4999              fprintf (f,
5000                       "if ( $status != 0 ) then\n"
5001                       "  echo \"${CMTROOT}/mgr/cmt setup -%s "
5002                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}\"\n"
5003                       "  set cmtsetupstatus=2\n"
5004                       "  /bin/rm -f ${tempfile}\n"
5005                       "  exit $cmtsetupstatus\n"
5006                       "endif\n"
5007                       "set cmtsetupstatus=0\n"
5008                       "source ${tempfile}\n"
5009                       "if ( $status != 0 ) then\n"
5010                       "  set cmtsetupstatus=2\n"
5011                       "endif\n"
5012                       "/bin/rm -f ${tempfile}\n"
5013                       "exit $cmtsetupstatus\n",
5014                       suffix[i].c_str (),
5015                       Me.m_current_package.c_str (),
5016                       version.c_str (),
5017                       Me.m_current_path.c_str (),
5018                       no_cleanup_opt.c_str ());
5019            }
5020          else if (mode[i] == Sh)
5021            {
5022              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
5023                       Me.m_current_package.c_str (),
5024                       version.c_str (),
5025                       Me.m_current_path.c_str ());
5026              fprintf (f, "\n");
5027
5028              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5029              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5030              fprintf (f, "fi\n");
5031              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5032              fprintf (f, "\n");
5033              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5034              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
5035              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
5036                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}\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              fprintf (f,
5043                       "if test $? != 0 ; then\n"
5044                       "  echo >&2 \"${CMTROOT}/mgr/cmt setup -%s "
5045                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}\"\n"
5046                       "  cmtsetupstatus=2\n"
5047                       "  /bin/rm -f ${tempfile}\n"
5048                       "  return $cmtsetupstatus\n"
5049                       "fi\n"
5050                       "cmtsetupstatus=0\n"
5051                       ". ${tempfile}\n"
5052                       "if test $? != 0 ; then\n"
5053                       "  cmtsetupstatus=2\n"
5054                       "fi\n"
5055                       "/bin/rm -f ${tempfile}\n"
5056                       "return $cmtsetupstatus\n",
5057                       suffix[i].c_str (),
5058                       Me.m_current_package.c_str (),
5059                       version.c_str (),
5060                       Me.m_current_path.c_str (),
5061                       no_cleanup_opt.c_str ());
5062            }
5063          else if (mode[i] == Bat)
5064            {
5065              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
5066                       Me.m_current_package.c_str (),
5067                       version.c_str ());
5068              dos_script_prefix (f, Me.m_cmt_root, 
5069                                 Me.m_current_package, version, Me.m_current_path,
5070                                 "setup", no_cleanup_opt);
5071            }
5072
5073          fprintf (f, "\n");
5074
5075          CmtSystem::close_ostream (f, file_name);
5076          //          fclose (f);
5077
5078          cmt_string old_file_name = "setup";
5079          old_file_name += ".";
5080          old_file_name += suffix[i];
5081
5082          CmtSystem::compare_and_update_files (file_name, old_file_name);
5083        }
5084      else
5085        {
5086          CmtError::set (CmtError::file_access_error, file_name);
5087        }
5088    }
5089}
5090
5091//----------------------------------------------------------
5092void Cmt::install_test_cleanup_scripts ()
5093{
5094#ifdef WIN32
5095  static const int modes = 1;
5096  static const cmt_string suffix[1]   = {"bat"};
5097  static const PrintMode  mode[1]     = {Bat};
5098#else
5099  static const int modes = 2;
5100  static const cmt_string suffix[2]   = {"csh", "sh"};
5101  static const PrintMode  mode[2]     = {Csh, Sh};
5102#endif
5103
5104  Use& current_use = Use::current ();
5105
5106  if (!current_use.get_strategy ("SetupScripts"))
5107    {
5108      for (int i = 0; i < modes; i++)
5109        {
5110          cmt_string old_file_name = "cleanup";
5111          old_file_name += ".";
5112          old_file_name += suffix[i];
5113          if (CmtSystem::test_file (old_file_name))
5114            {
5115              if (CmtMessage::active (Error))
5116                cerr << "Removing cleanup script " + old_file_name << endl;
5117              CmtSystem::remove_file (old_file_name);
5118            }
5119        }
5120      return;
5121    }
5122
5123  if (CmtMessage::active (Error))
5124    cerr << "Creating cleanup scripts." << endl;
5125
5126  cmt_string temp;
5127  int i;
5128
5129  cmt_string version = Me.m_current_version;
5130  if (version == "v*") version = "";
5131
5132  for (i = 0; i < modes; i++)
5133    {
5134      cmt_string file_name = "cleanup";
5135      file_name += ".";
5136      file_name += suffix[i];
5137      file_name += ".";
5138      file_name += "new";
5139
5140      FILE* f = fopen (file_name.c_str (), "wb");
5141      if (f != NULL)
5142        {
5143          if (mode[i] == Csh)
5144            {
5145              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5146              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5147              fprintf (f, "endif\n");
5148              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5149              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5150              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
5151              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}\n",
5152                       suffix[i].c_str (),
5153                       Me.m_current_path.c_str ());
5154              fprintf (f,
5155                       "if ( $status != 0 ) then\n"
5156                       "  echo \"${CMTROOT}/mgr/cmt cleanup -%s "
5157                       "-pack=cmt_standalone -path=%s $* >${tempfile}\"\n"
5158                       "  set cmtcleanupstatus=2\n"
5159                       "  /bin/rm -f ${tempfile}\n"
5160                       "  exit $cmtcleanupstatus\n"
5161                       "endif\n"
5162                       "set cmtcleanupstatus=0\n"
5163                       "source ${tempfile}\n"
5164                       "if ( $status != 0 ) then\n"
5165                       "  set cmtcleanupstatus=2\n"
5166                       "endif\n"
5167                       "/bin/rm -f ${tempfile}\n"
5168                       "exit $cmtcleanupstatus\n",
5169                       suffix[i].c_str (),
5170                       Me.m_current_path.c_str ());
5171            }
5172          else if (mode[i] == Sh)
5173            {
5174              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5175              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5176              fprintf (f, "fi\n");
5177              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5178              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5179              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
5180              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}\n",
5181                       suffix[i].c_str (),
5182                       Me.m_current_path.c_str ());
5183              fprintf (f,
5184                       "if test $? != 0 ; then\n"
5185                       "  echo >&2 \"${CMTROOT}/mgr/cmt cleanup -%s "
5186                       "-pack=cmt_standalone -path=%s $* >${tempfile}\"\n"
5187                       "  cmtcleanupstatus=2\n"
5188                       "  /bin/rm -f ${tempfile}\n"
5189                       "  return $cmtcleanupstatus\n"
5190                       "fi\n"
5191                       "cmtcleanupstatus=0\n"
5192                       ". ${tempfile}\n"
5193                       "if test $? != 0 ; then\n"
5194                       "  cmtcleanupstatus=2\n"
5195                       "fi\n"
5196                       "/bin/rm -f ${tempfile}\n"
5197                       "return $cmtcleanupstatus\n",
5198                       suffix[i].c_str (),
5199                       Me.m_current_path.c_str ());
5200            }
5201          else
5202            {
5203              dos_script_prefix (f, Me.m_cmt_root, 
5204                                 "cmt_standalone", "", Me.m_current_path, 
5205                                 "cleanup");
5206            }
5207
5208          fprintf (f, "\n");
5209
5210          CmtSystem::close_ostream (f, file_name);
5211          //          fclose (f);
5212
5213          cmt_string old_file_name = "cleanup";
5214          old_file_name += ".";
5215          old_file_name += suffix[i];
5216
5217          CmtSystem::compare_and_update_files (file_name, old_file_name);
5218        }
5219      else
5220        {
5221          CmtError::set (CmtError::file_access_error, file_name);
5222        }
5223    }
5224}
5225
5226//----------------------------------------------------------
5227void Cmt::install_native_version_file ()
5228{   
5229  Use& current_use        = Use::current ();
5230  cmt_string package_name = current_use.get_package_name();
5231  cmt_string macro_name   = package_name + "_native_version";
5232  Symbol* macro           = Symbol::find (macro_name);
5233  if (macro != 0)
5234    {
5235      cmt_string value = macro->resolve_macro_value ();
5236      if (value != "")
5237        {
5238          if (CmtMessage::active (Info))
5239            cerr << "Creating native_version file." << endl;   
5240
5241          cmt_string file_name ("new.native_version.cmt");
5242          FILE* f = fopen (file_name.c_str (), "wb");
5243          if (f != NULL)
5244            {
5245              fprintf (f, "%s\n", value.c_str ());
5246              CmtSystem::close_ostream (f, file_name);
5247              //          fclose (f);
5248             
5249              CmtSystem::compare_and_update_files ("new.native_version.cmt", "native_version.cmt");
5250            }     
5251          else
5252            {
5253              CmtError::set (CmtError::file_access_error, file_name);
5254            }
5255        } 
5256    }   
5257}
5258//----------------------------------------------------------
5259void Cmt::install_test_setup_scripts ()
5260{
5261#ifdef WIN32
5262  static const int modes = 1;
5263  static const cmt_string suffix[1]   = {"bat"};
5264  static const PrintMode  mode[1]     = {Bat};
5265#else
5266  static const int modes = 2;
5267  static const cmt_string suffix[2]   = {"csh", "sh"};
5268  static const PrintMode  mode[2]     = {Csh, Sh};
5269#endif
5270
5271  Use& current_use = Use::current ();
5272
5273  if (!current_use.get_strategy ("SetupScripts"))
5274    {
5275      for (int i = 0; i < modes; i++)
5276        {
5277          cmt_string old_file_name = "setup";
5278          old_file_name += ".";
5279          old_file_name += suffix[i];
5280          if (CmtSystem::test_file (old_file_name))
5281            {
5282              if (CmtMessage::active (Error))
5283                cerr << "Removing setup script " + old_file_name << endl;
5284              CmtSystem::remove_file (old_file_name);
5285            }
5286        }
5287      return;
5288    }
5289
5290  if (CmtMessage::active (Error))
5291    cerr << "Creating setup scripts." << endl;
5292
5293  cmt_string no_cleanup_opt;
5294
5295  if (current_use.get_strategy ("SetupCleanup"))
5296    {
5297      no_cleanup_opt = " -no_cleanup";
5298    }
5299
5300  cmt_string temp;
5301  int i;
5302
5303  for (i = 0; i < modes; i++)
5304    {
5305      cmt_string file_name = "setup";
5306      file_name += ".";
5307      file_name += suffix[i];
5308      file_name += ".";
5309      file_name += "new";
5310
5311      FILE* f = fopen (file_name.c_str (), "wb");
5312      if (f != NULL)
5313        {
5314          if (mode[i] == Csh)
5315            {
5316              fprintf (f, "# echo \"Setting standalone package\"\n");
5317              fprintf (f, "\n");
5318
5319              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5320              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5321              fprintf (f, "endif\n");
5322              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5323              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5324              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
5325              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}\n",
5326                       suffix[i].c_str (),
5327                       Me.m_current_path.c_str (),
5328                       no_cleanup_opt.c_str ());
5329              fprintf (f,
5330                       "if ( $status != 0 ) then\n"
5331                       "  echo \"${CMTROOT}/mgr/cmt setup -%s "
5332                       "-pack=cmt_standalone -path=%s %s $* >${tempfile}\"\n"
5333                       "  set cmtsetupstatus=2\n"
5334                       "  /bin/rm -f ${tempfile}\n"
5335                       "  exit $cmtsetupstatus\n"
5336                       "endif\n"
5337                       "set cmtsetupstatus=0\n"
5338                       "source ${tempfile}\n"
5339                       "if ( $status != 0 ) then\n"
5340                       "  set cmtsetupstatus=2\n"
5341                       "endif\n"
5342                       "/bin/rm -f ${tempfile}\n"
5343                       "exit $cmtsetupstatus\n",
5344                       suffix[i].c_str (),
5345                       Me.m_current_path.c_str (),
5346                       no_cleanup_opt.c_str ());
5347            }
5348          else if (mode[i] == Sh)
5349            {
5350              fprintf (f, "# echo \"Setting standalone package\"\n");
5351              fprintf (f, "\n");
5352
5353              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5354              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5355              fprintf (f, "fi\n");
5356              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5357              fprintf (f, "\n");
5358              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
5359              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
5360              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}\n",
5361                       suffix[i].c_str (),
5362                       Me.m_current_path.c_str (),
5363                       no_cleanup_opt.c_str ());
5364              fprintf (f,
5365                       "if test $? != 0 ; then\n"
5366                       "  echo >&2 \"${CMTROOT}/mgr/cmt setup -%s "
5367                       "-pack=cmt_standalone -path=%s %s $* >${tempfile}\"\n"
5368                       "  cmtsetupstatus=2\n"
5369                       "  /bin/rm -f ${tempfile}\n"
5370                       "  return $cmtsetupstatus\n"
5371                       "fi\n"
5372                       "cmtsetupstatus=0\n"
5373                       ". ${tempfile}\n"
5374                       "if test $? != 0 ; then\n"
5375                       "  cmtsetupstatus=2\n"
5376                       "fi\n"
5377                       "/bin/rm -f ${tempfile}\n"
5378                       "return $cmtsetupstatus\n",
5379                       suffix[i].c_str (),
5380                       Me.m_current_path.c_str (),
5381                       no_cleanup_opt.c_str ());
5382            }
5383          else
5384            {
5385              fprintf (f, "rem Setting standalone package\n");
5386              dos_script_prefix (f, Me.m_cmt_root, 
5387                                 "cmt_standalone", "", Me.m_current_path, 
5388                                 "setup", no_cleanup_opt);
5389            }
5390
5391          fprintf (f, "\n");
5392
5393          CmtSystem::close_ostream (f, file_name);
5394          //          fclose (f);
5395
5396          cmt_string old_file_name = "setup";
5397          old_file_name += ".";
5398          old_file_name += suffix[i];
5399
5400          CmtSystem::compare_and_update_files (file_name, old_file_name);
5401        }
5402      else
5403        {
5404          CmtError::set (CmtError::file_access_error, file_name);
5405        }
5406    }
5407}
5408
5409/**
5410 *    load is only called from the Windows GUI which pretends to access directly
5411 *   the internal data model.
5412 *    This is considered to be rather unsafe, and should be replaced by query functions.
5413 */
5414//bool Cmt::load (const cmt_string& path,
5415bool Cmt::load (const ArgParser& ap,
5416                const cmt_string& path,
5417                const cmt_string& package,
5418                const cmt_string& version,
5419                const cmt_string& tag_name)
5420{
5421  clear ();
5422  //  configure ();
5423  configure (ap);
5424
5425  Me.m_action  = action_load;
5426  Me.m_recursive = true;
5427
5428  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
5429    {
5430      //
5431      //  Here we want to connect to a new package, or to the current package
5432      //  but with another tag.
5433      //
5434      //   the 'package' argument may include a directory offset. Thus 'path'
5435      //  is only expected to hold the base directory.
5436      //
5437      cmt_string offset;
5438      cmt_string package_name;
5439     
5440      CmtSystem::dirname (package, offset);
5441      CmtSystem::basename (package, package_name);
5442     
5443      if (offset != "")
5444        {
5445          Me.m_current_path = path;
5446          Me.m_current_path += CmtSystem::file_separator ();
5447          Me.m_current_path += offset;
5448        }
5449      else
5450        {
5451          Me.m_current_path = path;
5452        }
5453     
5454      Me.m_current_package = package_name;
5455      Me.m_current_version = version;
5456    }
5457
5458  if (tag_name != "")
5459    {
5460      Tag* tag;
5461
5462      Tag::unmark_all ();
5463      configure_version_tag ();
5464      configure_site_tag (0);
5465      configure_uname_tag ();
5466      configure_hosttype_tag ();
5467
5468      Me.m_current_tag = tag_name;
5469
5470      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
5471
5472      tag = Tag::add (tag_name, PriorityTag, "load", 0);
5473      tag->mark ();
5474    }
5475
5476  /*
5477    Set to developer mode if positioned into the package
5478    (which is detected since we were able to retreive the
5479    Version, Package and Path)
5480  */
5481
5482  if ((Me.m_current_path == "") ||
5483      (Me.m_current_package == "") ||
5484      (Me.m_current_version == ""))
5485    {
5486      Me.m_current_access = UserMode;
5487    }
5488  else
5489    {
5490      Me.m_current_access = DeveloperMode;
5491    }
5492
5493  use_cmt ();
5494
5495  cmt_string dir;
5496
5497  /*
5498    Try to access the package.
5499  */
5500
5501  if (Me.m_current_path != "")
5502    {
5503      dir = Me.m_current_path;
5504    }
5505  else
5506    {
5507      dir = Me.m_default_path;
5508    }
5509
5510  if (!CmtSystem::cd (Me.m_current_path))
5511    {
5512      CmtMessage::error ("Cannot reach the directory " + Me.m_current_path);
5513      /*
5514      if (!Me.m_quiet)
5515        {
5516          cerr << "#CMT> Cannot reach the directory " <<
5517            Me.m_current_path << endl;
5518        }
5519      */
5520      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
5521      CmtSystem::cd (Me.m_current_dir);
5522
5523      return (false);
5524    }
5525
5526  dir += CmtSystem::file_separator ();
5527  dir += Me.m_current_package;
5528
5529  if (!CmtSystem::cd (Me.m_current_package))
5530    {
5531      CmtMessage::error ("Cannot reach the package " + Me.m_current_package);
5532      /*
5533      if (!Me.m_quiet)
5534        {
5535          cerr << "#CMT::load> Cannot reach the package " <<
5536            Me.m_current_package << endl;
5537        }
5538      */
5539      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
5540      CmtSystem::cd (Me.m_current_dir);
5541
5542      return (false);
5543    }
5544
5545  dir += CmtSystem::file_separator ();
5546  dir += Me.m_current_version;
5547
5548  Me.m_current_style = none_style;
5549
5550  if (!CmtSystem::cd (Me.m_current_version))
5551    {
5552      if (!CmtSystem::test_directory ("cmt"))
5553        {
5554          CmtMessage::error ("Cannot reach the version " + Me.m_current_version);
5555          /*
5556          if (!Me.m_quiet)
5557            {
5558              cerr << "#CMT> Cannot reach the version " <<
5559                Me.m_current_version << endl;
5560            }
5561          */
5562          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
5563          CmtSystem::cd (Me.m_current_dir);
5564
5565          return (false);
5566        }
5567      else
5568        {
5569          Me.m_current_style = no_version_style;
5570        }
5571    }
5572
5573  if (CmtSystem::cd ("cmt"))
5574    {
5575      dir += CmtSystem::file_separator ();
5576      dir += "cmt";
5577      if (Me.m_current_style == none_style) Me.m_current_style = cmt_style;
5578    }
5579  else
5580    {
5581      /*
5582        if (!Me.m_quiet)
5583        {
5584        cerr << "Cannot reach the cmt branch" << endl;
5585        }
5586      */
5587
5588      if (CmtSystem::cd ("mgr"))
5589        {
5590          dir += CmtSystem::file_separator ();
5591          dir += "mgr";
5592          if (Me.m_current_style == none_style) Me.m_current_style = mgr_style;
5593        }
5594      else
5595        {
5596          CmtMessage::error ("Cannot reach the mgr branch");
5597          /*
5598          if (!Me.m_quiet)
5599            {
5600              cerr << "#CMT> Cannot reach the mgr branch" << endl;
5601            }
5602          */
5603
5604          CmtError::set (CmtError::package_not_found,
5605                         "Load> Cannot reach the mgr/cmt directory");
5606          CmtSystem::cd (Me.m_current_dir);
5607
5608          return (false);
5609        }
5610    }
5611
5612  /*
5613    Check Tag is always set up
5614  */
5615
5616  if (Me.m_current_tag == "")
5617    {
5618      char* env;
5619
5620      env = getenv (Me.m_current_config.c_str ());
5621      if (env != 0)
5622        {
5623          Tag* tag;
5624
5625          tag = Tag::add (env, PriorityConfig, "load", 0);
5626          tag->mark ();
5627          Me.m_current_tag = env;
5628
5629          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
5630
5631        }
5632      else
5633        {
5634          Me.m_current_tag = Me.m_cmt_config;
5635
5636          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
5637
5638        }
5639    }
5640
5641  if (Me.m_debug)
5642    {
5643      cout << "pwd = " << CmtSystem::pwd () << endl;
5644    }
5645
5646  configure_current_dir ();
5647  build_prefix (Me.m_current_package, Me.m_current_prefix);
5648  build_config (Me.m_current_prefix, Me.m_current_config);
5649
5650  Use* use = &(Use::current());
5651  use->path    = Me.m_current_path;
5652  use->set_package_name (Me.m_current_package);
5653  use->version = Me.m_current_version;
5654  use->prefix  = Me.m_current_prefix;
5655  use->done    = false;
5656  use->style   = Me.m_current_style;
5657
5658  /*
5659    Work on the requirements file.
5660  */
5661
5662  dir += CmtSystem::file_separator ();
5663  dir += "requirements";
5664  SyntaxParser::parse_requirements (dir, use);
5665
5666  if (CmtError::has_pending_error ()) return (false);
5667
5668  /**
5669   * See reach_current_package for an explanation of this call
5670   */
5671  Pattern::apply_all_globals ();
5672
5673  /*
5674    Select all possible tags
5675  */
5676
5677  Tag::restore_tree ();
5678
5679  return (true);
5680}
5681
5682//----------------------------------------------------------
5683bool Cmt::need_prototypes ()
5684{
5685  Use& current_use = Use::current ();
5686
5687  if (current_use.get_strategy ("BuildPrototypes")) return (true);
5688  else return (false);
5689}
5690
5691//----------------------------------------------------------
5692void Cmt::parse_arguments (ArgParser& ap)
5693{
5694  /*
5695    Decoding arguments.
5696
5697    While decoding all arguments, no requirements analysis should
5698    occur. Every new option, or parameter should be saved and
5699    used later at actual analysis time.
5700  */
5701
5702  Me.m_action = action_none;
5703
5704  restore_all_tags (0);
5705
5706#ifdef WIN32
5707  Me.m_build_nmake = true;
5708#endif
5709
5710  ap.parse ();
5711}
5712
5713//----------------------------------------------------------
5714int Cmt::parser (const cmt_string& command_line)
5715{
5716  CmtSystem::cmt_string_vector v;
5717
5718  CmtSystem::split (command_line, " \t", v);
5719
5720  int argc = v.size ();
5721
5722  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
5723
5724  int i;
5725  for (i = 0; i < argc; i++)
5726    {
5727      argv[i] = (char*) v[i].c_str ();
5728    }
5729  argv[argc] = 0;
5730
5731  int status = parser (argc, argv);
5732
5733  free (argv);
5734
5735  return (status);
5736}
5737
5738//----------------------------------------------------------
5739int Cmt::parser (int argc, char* argv[])
5740{
5741  ArgParser ap (Me);
5742 
5743  ap.argc = argc;
5744  ap.argv = argv;
5745
5746  if (argc <= 1)
5747    {
5748      do_help (ap);
5749      return 2;
5750      //      exit (0);
5751    }
5752
5753  // save CMTFLAGS
5754  cmt_string cmtflags (get_cmt_flags ());
5755
5756  clear ();
5757
5758  //  configure ();
5759  configure (ap);
5760
5761  CmtError::clear ();
5762
5763  /*
5764    Set private if positioned inside the package
5765    (which is detected since we were able to retreive the
5766    Version, Package and Path)
5767  */
5768
5769  if ((Me.m_current_path.size () == 0) ||
5770      (Me.m_current_package.size () == 0) ||
5771      (Me.m_current_version.size () == 0))
5772    {
5773      Me.m_current_access = UserMode;
5774    }
5775  else
5776    {
5777      Me.m_current_access = DeveloperMode;
5778    }
5779 
5780  parse_arguments (ap);
5781 
5782  if (Me.m_debug)
5783    {
5784      cout << "After parse_argument> pack=" << Me.m_current_package
5785           << " Me.m_current_tag=" << Me.m_current_tag
5786           << " cwd=" << CmtSystem::pwd () 
5787           << " mode=" << Me.m_current_access
5788           << endl;
5789    }
5790
5791  if (Me.m_configure_error != "")
5792    {
5793      CmtMessage::error (Me.m_configure_error);
5794      //      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
5795      return (CmtError::execution_error);
5796    }
5797
5798  if (CmtError::has_pending_error ())
5799    {
5800      int code = CmtError::get_last_error_code ();
5801      CmtError::print ();
5802      //      if (!Me.m_quiet) CmtError::print ();
5803      clear ();
5804
5805      return (code);
5806    }
5807
5808  /*
5809    Now actual requirements analysis can take place.
5810
5811    Extra lines or files are analysed first.
5812  */
5813
5814  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
5815  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
5816
5817  //
5818  //  For some of the actions, the CMT package must be automatically
5819  //  included
5820  //
5821
5822  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
5823
5824  if (ap.help_action == action_help)
5825    {
5826      do_help (ap);
5827      int code (0);
5828      if (CmtError::has_pending_error ())
5829        {
5830          code = CmtError::get_last_error_code ();
5831          CmtError::print ();
5832        }
5833      return code;
5834      //return (0);
5835    }
5836
5837  switch (Me.m_action)
5838    {
5839      // case action_none :
5840    case action_awk :
5841    case action_broadcast :
5842    case action_build_constituent_makefile :
5843    case action_build_constituents_makefile :
5844    case action_build_dependencies :
5845    case action_build_library_links :
5846    case action_build_make_setup :
5847    case action_build_msdev :
5848    case action_build_CMT_pacman :
5849    case action_build_vsnet :     
5850    case action_build_os9_makefile :
5851      // case action_build_prototype :
5852    case action_build_readme :
5853    case action_build_tag_makefile :
5854      // case action_build_temporary_name :
5855    case action_build_triggers :
5856    case action_build_windefs :
5857    case action_check_configuration :
5858      // case action_check_files :
5859      // case action_check_version :
5860    case action_checkout :
5861    case action_cleanup :
5862    case action_config :
5863    case action_create :
5864      // case action_create_project :
5865    case action_cvsbranches :
5866    case action_cvssubpackages :
5867    case action_cvssubprojects :
5868    case action_cvstags :
5869    case action_do :
5870    case action_expand_model :
5871    case action_filter :
5872      // case action_help :
5873    case action_load :
5874    case action_lock :
5875    case action_relocate:
5876    case action_remove :
5877    case action_remove_library_links :
5878    case action_run :
5879    case action_run_sequence :
5880    case action_set_version :
5881    case action_set_versions :
5882    case action_setup :
5883    case action_show_action :
5884    case action_show_action_names :
5885    case action_show_action_value :
5886    case action_show_actions :
5887    case action_show_all_tags :
5888    case action_show_applied_patterns :
5889      // case action_show_author :
5890      // case action_show_branches :
5891      // case action_show_clients :
5892    case action_show_cmtpath_patterns :
5893    case action_show_constituent :
5894    case action_show_constituent_names :
5895    case action_show_constituents :
5896    case action_show_container :
5897    case action_show_cycles :
5898    case action_show_fragment :
5899    case action_show_fragments :
5900    case action_show_groups :
5901    case action_show_include_dirs :
5902    case action_show_language :
5903    case action_show_languages :
5904    case action_show_macro :
5905    case action_show_macro_names :
5906    case action_show_macro_value :
5907    case action_show_macros :
5908      // case action_show_manager :
5909    case action_show_packages :
5910    case action_show_path :
5911    case action_show_pattern :
5912    case action_show_pattern_names :
5913    case action_show_patterns :
5914    case action_show_projects :
5915      // case action_show_pwd :
5916    case action_show_setup :
5917    case action_show_set :
5918    case action_show_set_names :
5919    case action_show_set_value :
5920    case action_show_sets :
5921    case action_show_strategies :
5922    case action_show_tags :
5923    case action_show_use_paths :
5924    case action_show_uses :
5925    case action_show_version :
5926      // case action_show_versions :
5927      // case action_system :
5928    case action_unlock :
5929    case action_version :
5930      use_cmt ();
5931      //
5932      // Now parse the requirements file stored in ${CMTHOME}
5933      //
5934     
5935      use_home_requirements ();
5936
5937      configure_devenv_tag ();
5938
5939      break;
5940    default:
5941      break;
5942    }
5943
5944  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
5945
5946  //
5947  // Setting up recursive actions
5948  //
5949
5950  switch (Me.m_action)
5951    {
5952      // case action_none :
5953    case action_awk :
5954    case action_broadcast :
5955    case action_build_constituent_makefile :
5956    case action_build_constituents_makefile :
5957    case action_build_dependencies :
5958    case action_build_library_links :
5959    case action_build_make_setup :
5960    case action_build_msdev :
5961    case action_build_CMT_pacman :
5962    case action_build_vsnet :     
5963    case action_build_os9_makefile :
5964      // case action_build_prototype :
5965    case action_build_readme :
5966    case action_build_tag_makefile :
5967      // case action_build_temporary_name :
5968    case action_build_triggers :
5969    case action_build_windefs :
5970    case action_check_configuration :
5971      // case action_check_files :
5972      // case action_check_version :
5973      // case action_checkout :
5974    case action_cleanup :
5975    case action_config :
5976      // case action_create :
5977      // case action_create_project :
5978      // case action_cvsbranches :
5979      // case action_cvssubpackages :
5980      // case action_cvssubprojects :
5981      // case action_cvstags :
5982    case action_do :
5983    case action_expand_model :
5984    case action_filter :
5985      // case action_help :
5986    case action_load :
5987      // case action_lock :
5988      // case action_remove :
5989    case action_relocate:
5990    case action_remove_library_links :
5991    case action_run :
5992    case action_run_sequence :
5993      // case action_set_version :
5994    case action_set_versions :
5995    case action_setup :
5996    case action_show_action :
5997    case action_show_action_names :
5998    case action_show_action_value :
5999    case action_show_actions :
6000    case action_show_all_tags :
6001    case action_show_applied_patterns :
6002      // case action_show_author :
6003      // case action_show_branches :
6004      // case action_show_clients :
6005    case action_show_cmtpath_patterns :
6006    case action_show_constituent :
6007    case action_show_constituent_names :
6008    case action_show_constituents :
6009    case action_show_container :
6010    case action_show_cycles :
6011    case action_show_fragment :
6012    case action_show_fragments :
6013    case action_show_groups :
6014    case action_show_include_dirs :
6015    case action_show_language :
6016    case action_show_languages :
6017    case action_show_macro :
6018    case action_show_macro_names :
6019    case action_show_macro_value :
6020    case action_show_macros :
6021      // case action_show_manager :
6022    case action_show_packages :
6023    case action_show_path :
6024    case action_show_pattern :
6025    case action_show_pattern_names :
6026    case action_show_patterns :
6027    case action_show_projects :
6028      // case action_show_pwd :
6029    case action_show_setup :
6030    case action_show_set :
6031    case action_show_set_names :
6032    case action_show_set_value :
6033    case action_show_sets :
6034    case action_show_strategies :
6035    case action_show_tags :
6036    case action_show_use_paths :
6037    case action_show_uses :
6038      // case action_show_version :
6039      // case action_show_versions :
6040      // case action_system :
6041      // case action_unlock :
6042      // case action_version :
6043      Me.m_recursive = true;
6044      break;
6045    default:
6046      Me.m_recursive = false;
6047      break;
6048    }
6049
6050  //
6051  //  Actions for which the context of the package is checked,
6052  //  and the requirements file is analysed.
6053  //
6054
6055  switch (Me.m_action)
6056    {
6057    case action_none :
6058    case action_awk :
6059    case action_broadcast :
6060    case action_build_constituent_makefile :
6061    case action_build_constituents_makefile :
6062    case action_build_dependencies :
6063    case action_build_library_links :
6064    case action_build_make_setup :
6065    case action_build_msdev :
6066    case action_build_CMT_pacman :
6067    case action_build_vsnet :     
6068    case action_build_os9_makefile :
6069      // case action_build_prototype :
6070    case action_build_readme :
6071    case action_build_tag_makefile :
6072      // case action_build_temporary_name :
6073    case action_build_triggers :
6074    case action_build_windefs :
6075    case action_check_configuration :
6076      // case action_check_files :
6077      // case action_check_version :
6078      // case action_checkout :
6079    case action_cleanup :
6080    case action_config :
6081      // case action_create :
6082      // case action_create_project :
6083      // case action_cvsbranches :
6084      // case action_cvssubpackages :
6085      // case action_cvssubprojects :
6086      // case action_cvstags :
6087    case action_do :
6088    case action_expand_model :
6089    case action_filter :
6090      // case action_help :
6091    case action_load :
6092    case action_lock :
6093      // case action_remove :
6094    case action_relocate :
6095    case action_remove_library_links :
6096    case action_run :
6097      // case action_run_sequence :
6098      // case action_set_version :
6099    case action_set_versions :
6100    case action_setup :
6101    case action_show_action :
6102    case action_show_action_names :
6103    case action_show_action_value :
6104    case action_show_actions :
6105    case action_show_all_tags :
6106    case action_show_applied_patterns :
6107    case action_show_author :
6108    case action_show_branches :
6109      // case action_show_clients :
6110    case action_show_cmtpath_patterns :
6111    case action_show_constituent :
6112    case action_show_constituent_names :
6113    case action_show_constituents :
6114    case action_show_container :
6115    case action_show_cycles :
6116    case action_show_fragment :
6117    case action_show_fragments :
6118    case action_show_groups :
6119    case action_show_include_dirs :
6120    case action_show_language :
6121    case action_show_languages :
6122    case action_show_macro :
6123    case action_show_macro_names :
6124    case action_show_macro_value :
6125    case action_show_macros :
6126    case action_show_manager :
6127    case action_show_packages :
6128    case action_show_path :
6129    case action_show_pattern :
6130    case action_show_pattern_names :
6131    case action_show_patterns :
6132    case action_show_projects :
6133    case action_show_project_author :
6134    case action_show_pwd :
6135    case action_show_setup :
6136    case action_show_set :
6137    case action_show_set_names :
6138    case action_show_set_value :
6139    case action_show_sets :
6140    case action_show_strategies :
6141    case action_show_tags :
6142    case action_show_use_paths :
6143    case action_show_uses :
6144    case action_show_version :
6145      // case action_show_versions :
6146      // case action_system :
6147    case action_unlock :
6148      // case action_version :
6149      {
6150        bool w = Me.m_warnings;
6151        Me.m_warnings = false;
6152        reach_current_package ();
6153        use_user_context_requirements ();
6154        Me.m_warnings = w;
6155      }
6156      break;
6157    default:
6158      break;
6159    }
6160
6161  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
6162
6163  //
6164  // Perform some actions even if there is an error
6165  //
6166
6167  if (CmtError::has_pending_error ())
6168    {
6169      int code = CmtError::get_last_error_code ();
6170      if (!Me.m_quiet) CmtError::print ();
6171
6172      switch (Me.m_action)
6173        {
6174          // case action_none :
6175          // case action_awk :
6176          // case action_broadcast :
6177        case action_build_constituent_makefile :
6178        case action_build_constituents_makefile :
6179        case action_build_dependencies :
6180        case action_build_library_links :
6181        case action_build_make_setup :
6182        case action_build_msdev :
6183        case action_build_CMT_pacman :
6184        case action_build_vsnet :     
6185        case action_build_os9_makefile :
6186        case action_build_prototype :
6187        case action_build_readme :
6188        case action_build_tag_makefile :
6189          // case action_build_temporary_name :
6190        case action_build_triggers :
6191        case action_build_windefs :
6192        case action_check_configuration :
6193          // case action_check_files :
6194          // case action_check_version :
6195          // case action_checkout :
6196        case action_cleanup :
6197          // case action_config :
6198          // case action_create :
6199          // case action_create_project :
6200          // case action_cvsbranches :
6201          // case action_cvssubpackages :
6202          // case action_cvssubprojects :
6203          // case action_cvstags :
6204          // case action_do :
6205          // case action_expand_model :
6206          // case action_filter :
6207          // case action_help :
6208        case action_load :
6209        case action_lock :
6210        case action_relocate :
6211        case action_remove :
6212        case action_remove_library_links :
6213          // case action_run :
6214        case action_run_sequence :
6215          // case action_set_version :
6216          // case action_set_versions :
6217        case action_setup :
6218          // case action_show_action :
6219          // case action_show_action_names :
6220          // case action_show_action_value :
6221          // case action_show_actions :
6222          // case action_show_all_tags :
6223          // case action_show_applied_patterns :
6224          // case action_show_author :
6225          // case action_show_branches :
6226          // case action_show_clients :
6227          // case action_show_cmtpath_patterns :
6228          // case action_show_constituent :
6229          // case action_show_container :
6230          // case action_show_constituent_names :
6231          // case action_show_constituents :
6232          // case action_show_cycles :
6233          // case action_show_fragment :
6234          // case action_show_fragments :
6235          // case action_show_groups :
6236          // case action_show_include_dirs :
6237          // case action_show_language :
6238          // case action_show_languages :
6239          // case action_show_macro :
6240          // case action_show_macro_names :
6241          // case action_show_macro_value :
6242          // case action_show_macros :
6243          // case action_show_manager :
6244          // case action_show_packages :
6245          // case action_show_path :
6246          // case action_show_pattern :
6247          // case action_show_pattern_names :
6248          // case action_show_patterns :
6249          // case action_show_projects :
6250          // case action_show_pwd :
6251          // case action_show_setup :
6252          // case action_show_set :
6253          // case action_show_set_names :
6254          // case action_show_set_value :
6255          // case action_show_sets :
6256          // case action_show_strategies :
6257          // case action_show_tags :
6258          // case action_show_use_paths :
6259          // case action_show_uses :
6260          // case action_show_version :
6261          // case action_show_versions :
6262          // case action_system :
6263        case action_unlock :
6264          // case action_version :
6265          clear ();
6266          return (code);
6267        default:
6268          CmtError::clear ();
6269          break;
6270        }
6271    }
6272
6273  //
6274  // Perform actions
6275  //
6276
6277  if (!Me.m_simulation)
6278    {
6279      switch (Me.m_action)
6280        {
6281        case action_none :
6282          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
6283          break;
6284        case action_awk :
6285          do_awk (ap);
6286          break;
6287        case action_broadcast :
6288          do_broadcast (ap);
6289          break;
6290        case action_build_constituent_makefile :
6291          do_build_constituent_makefile (ap);
6292          break;
6293        case action_build_constituents_makefile :
6294          do_build_constituents_makefile (ap);
6295          break;
6296        case action_build_dependencies :
6297          do_build_dependencies (ap, argc, argv);
6298          break;
6299        case action_build_library_links :
6300          do_build_library_links (ap);
6301          break;
6302        case action_build_make_setup :
6303          do_build_make_setup (ap);
6304          break;
6305        case action_build_msdev :
6306          do_build_msdev (ap);
6307          break;
6308        case action_build_CMT_pacman :
6309          do_build_CMT_pacman (ap);
6310          break;
6311        case action_build_vsnet :     
6312          do_build_vsnet (ap);
6313          break;
6314        case action_build_os9_makefile :
6315          do_build_os9_makefile (ap);
6316          break;
6317        case action_build_prototype :
6318          do_build_prototype (ap);
6319          break;
6320        case action_build_readme :
6321          do_build_readme (ap);
6322          break;
6323        case action_build_tag_makefile :
6324          do_build_tag_makefile (ap);
6325          break;
6326        case action_build_temporary_name :
6327          do_build_temporary_name (ap);
6328          break;
6329        case action_build_triggers :
6330          do_build_triggers (ap);
6331          break;
6332        case action_build_windefs :
6333          do_build_windefs (ap);
6334          break;
6335        case action_check_configuration :
6336          do_check_configuration (ap);
6337          break;
6338        case action_check_files :
6339          do_check_files (ap);
6340          break;
6341        case action_check_version :
6342          do_check_version (ap);
6343          break;
6344        case action_checkout :
6345          do_checkout (ap);
6346          break;
6347        case action_cleanup :
6348          do_cleanup (ap);
6349          break;
6350        case action_config :
6351          do_config (ap);
6352          break;
6353        case action_create :
6354          do_create (ap);
6355          break;
6356        case action_create_project :
6357          do_create_project (ap);
6358          break;
6359        case action_cvsbranches :
6360          do_cvsbranches (ap);
6361          break;
6362        case action_cvssubpackages :
6363          do_cvssubpackages (ap);
6364          break;
6365        case action_cvssubprojects :
6366          do_cvssubprojects (ap);
6367          break;
6368        case action_cvstags :
6369          do_cvstags (ap);
6370          break;
6371        case action_do :
6372          do_do (ap);
6373          break;
6374        case action_expand_model :
6375          do_expand_model (ap);
6376          break;
6377        case action_filter :
6378          do_filter (ap);
6379          break;
6380        case action_help :
6381          do_help (ap);
6382          break;
6383        case action_load :
6384          CmtMessage::error ("action not implemented");
6385          //      cerr << "#CMT> action not implemented" << endl;
6386          break;
6387        case action_lock :
6388          do_lock (ap);
6389          break;
6390        case action_relocate :
6391          do_relocate (ap);
6392          break;
6393        case action_remove :
6394          do_remove (ap);
6395          break;
6396        case action_remove_library_links :
6397          do_remove_library_links (ap);
6398          break;
6399        case action_run :
6400          do_run (ap);
6401          break;
6402        case action_run_sequence :
6403          do_run_sequence (ap);
6404          break;
6405        case action_set_version :
6406          do_set_version (ap);
6407          break;
6408        case action_set_versions :
6409          do_set_versions (ap);
6410          break;
6411        case action_setup :
6412          do_setup (ap);
6413          break;
6414        case action_show_action :
6415          do_show_action (ap);
6416          break;
6417        case action_show_action_names :
6418          do_show_action_names (ap);
6419          break;
6420        case action_show_action_value :
6421          do_show_action_value (ap);
6422          break;
6423        case action_show_actions :
6424          do_show_actions (ap);
6425          break;
6426        case action_show_all_tags :
6427          do_show_all_tags (ap);
6428          break;
6429        case action_show_applied_patterns :
6430          do_show_applied_patterns (ap);
6431          break;
6432        case action_show_author :
6433          do_show_author (ap);
6434          break;
6435        case action_show_branches :
6436          do_show_branches (ap);
6437          break;
6438        case action_show_container :
6439          do_show_container (ap);
6440          break;
6441        case action_show_clients :
6442          do_show_clients (ap);
6443          break;
6444        case action_show_cmtpath_patterns :
6445          do_show_cmtpath_patterns (ap);
6446          break;
6447        case action_show_constituent :
6448          do_show_constituent (ap);
6449          break;
6450        case action_show_constituent_names :
6451          do_show_constituent_names (ap);
6452          break;
6453        case action_show_constituents :
6454          do_show_constituents (ap);
6455          break;
6456        case action_show_cycles :
6457          do_show_cycles (ap);
6458          break;
6459        case action_show_fragment :
6460          do_show_fragment (ap);
6461          break;
6462        case action_show_fragments :
6463          do_show_fragments (ap);
6464          break;
6465        case action_show_groups :
6466          do_show_groups (ap);
6467          break;
6468        case action_show_include_dirs :
6469          do_show_include_dirs (ap);
6470          break;
6471        case action_show_language :
6472          do_show_language (ap);
6473          break;
6474        case action_show_languages :
6475          do_show_languages (ap);
6476          break;
6477        case action_show_macro :
6478          do_show_macro (ap);
6479          break;
6480        case action_show_macro_names :
6481          do_show_macro_names (ap);
6482          break;
6483        case action_show_macro_value :
6484          do_show_macro_value (ap);
6485          break;
6486        case action_show_macros :
6487          do_show_macros (ap);
6488          break;
6489        case action_show_manager :
6490          do_show_manager (ap);
6491          break;
6492        case action_show_packages :
6493          do_show_packages (ap);
6494          break;
6495        case action_show_path :
6496          do_show_path (ap);
6497          break;
6498        case action_show_pattern :
6499          do_show_pattern (ap);
6500          break;
6501        case action_show_pattern_names :
6502          do_show_pattern_names (ap);
6503          break;
6504        case action_show_patterns :
6505          do_show_patterns (ap);
6506          break;
6507        case action_show_projects :
6508          do_show_projects (ap);
6509          break;
6510        case action_show_project_author :
6511          do_show_project_author (ap);
6512          break;
6513        case action_show_pwd :
6514          do_show_pwd (ap);
6515          break;
6516        case action_show_setup :
6517          do_show_setup (ap);
6518          break;
6519        case action_show_set :
6520          do_show_set (ap);
6521          break;
6522        case action_show_set_names :
6523          do_show_set_names (ap);
6524          break;
6525        case action_show_set_value :
6526          do_show_set_value (ap);
6527          break;
6528        case action_show_sets :
6529          do_show_sets (ap);
6530          break;
6531        case action_show_strategies :
6532          do_show_strategies (ap);
6533          break;
6534        case action_show_tags :
6535          do_show_tags (ap);
6536          break;
6537        case action_show_use_paths :
6538          do_show_use_paths (ap);
6539          break;
6540        case action_show_uses :
6541          do_show_uses (ap);
6542          break;
6543        case action_show_version :
6544          do_show_version (ap);
6545          break;
6546        case action_show_versions :
6547          do_show_versions (ap);
6548          break;
6549        case action_system :
6550          do_show_system (ap);
6551          break;
6552        case action_unlock :
6553          do_unlock (ap);
6554          break;
6555        case action_version :
6556          do_version (ap);
6557          break;
6558        default:
6559          CmtError::set (CmtError::syntax_error, "ParseArguments>");
6560          break;
6561        }
6562    }
6563
6564  // restore CMTFLAGS
6565  set_cmt_flags (cmtflags);
6566
6567  if (CmtError::has_pending_error ())
6568    {
6569      int code = CmtError::get_last_error_code ();     
6570      if (code == CmtError::execution_failed)
6571        {
6572          code = CmtError::get_last_execution_error();
6573        }   
6574     
6575      CmtError::print ();
6576      //      if (!Me.m_quiet) CmtError::print ();
6577      clear ();
6578      return (code);
6579    }
6580  else
6581    {
6582      clear ();
6583      return (0);
6584    }
6585}
6586
6587
6588/**
6589 * Format as one single line a set of 'setenv' statements
6590 * joined with semi-colons to form one shell command.
6591 */
6592void Cmt::print (PrintMode mode)
6593{
6594  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6595  Use& current_use = Use::current ();
6596
6597  cmt_string tag;
6598
6599  set_standard_macros ();
6600
6601  //cerr << "# current_tag=" << Me.m_current_tag << endl;
6602  //cerr << "# current_config=" << Me.m_current_config << endl;
6603
6604  if (Me.m_current_tag == "")
6605    {
6606      if (mode == Bat) tag = "%CMTCONFIG%";
6607      else tag = "${CMTCONFIG}";
6608    }
6609  else
6610    {
6611      tag = Me.m_current_tag;
6612    }
6613
6614  //
6615  //  Now check if all extra tags are still valid. Some of them
6616  //  may be discarded du to some conflict with highest priority
6617  //  tags, or with exclude statements
6618  //
6619
6620  {
6621    CmtSystem::cmt_string_vector words;
6622     
6623    cmt_string tags;
6624
6625    tags = Me.m_extra_tags;
6626     
6627    CmtSystem::split (tags, " \t,", words);
6628
6629    Me.m_extra_tags = ",";
6630     
6631    for (int i = 0; i < words.size (); i++)
6632      {
6633        Tag* tag;
6634        const cmt_string& a = words[i];
6635
6636        tag = Tag::find (a);
6637
6638        if ((tag != 0) && (tag->is_selected ()))
6639          {
6640            Me.m_extra_tags += a;
6641            Me.m_extra_tags += ",";
6642          }
6643      }
6644  }
6645
6646  if (Me.m_debug)
6647    {
6648      cout << "Before all print contexts" << endl;
6649    }
6650
6651  if (Uses.size () > 0)
6652    {
6653      int number;
6654
6655      for (number = 0; number < Uses.size (); number++)
6656        {
6657          Use& use = *(Uses[number]);
6658
6659          if (use.discarded) continue;
6660          if (use.m_hidden) continue;
6661         
6662          print_context (use, mode, tag);
6663        }
6664    }
6665
6666  print_context (Use::current (), mode, tag);
6667
6668  if (Me.m_debug)
6669    {
6670      cout << "After all print contexts" << endl;
6671    }
6672
6673  Symbol::all_print (mode);
6674  // Script::all_print (mode);
6675
6676  if (Me.m_debug)
6677    {
6678      cout << "After all print" << endl;
6679    }
6680
6681  cout << endl;
6682}
6683
6684
6685/**
6686 * Format as one single line a set of 'unsetenv' statements
6687 * joined with semi-colons to form one shell command.
6688 */
6689void Cmt::print_clean (PrintMode mode)
6690{
6691  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6692
6693  set_standard_macros ();
6694
6695  Script::all_print_clean (mode);
6696  Symbol::all_print_clean (mode);
6697
6698  switch (mode)
6699    {
6700    case Csh :
6701      if (Me.m_current_package != "CMT")
6702        {
6703          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
6704          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
6705        }
6706      break;
6707    case Sh :
6708      if (Me.m_current_package != "CMT")
6709        {
6710          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
6711          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
6712        }
6713      break;
6714    case Bat :
6715      if (Me.m_current_package != "CMT")
6716        {
6717          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
6718          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
6719        }
6720      break;
6721    }
6722
6723  if (Uses.size () > 0)
6724    {
6725      int number;
6726
6727      for (number = 0; number < Uses.size (); number++)
6728        {
6729          Use* use = Uses[number];
6730
6731          if (use->discarded) continue;
6732          if (use->m_hidden) continue;
6733
6734          Package* p = use->get_package ();
6735          if (p->is_cmt ()) continue;
6736
6737
6738          switch (mode)
6739            {
6740            case Csh :
6741              cout << "unsetenv " << use->prefix << "ROOT" << endl;
6742              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
6743              break;
6744            case Sh :
6745              cout << "unset " << use->prefix << "ROOT" << endl;
6746              cout << "unset " << use->prefix << "CONFIG" << endl;
6747              break;
6748            case Bat :
6749              cout << "set " << use->prefix << "ROOT=" << endl;
6750              cout << "set " << use->prefix << "CONFIG" << endl;
6751              break;
6752            }
6753        }
6754    }
6755
6756  switch (mode)
6757    {
6758    case Csh :
6759      cout << "unsetenv CMTEXTRATAGS" << endl;
6760      break;
6761    case Sh :
6762      cout << "unset CMTEXTRATAGS" << endl;
6763      break;
6764    case Bat :
6765      cout << "set CMTEXTRATAGS=" << endl;
6766      break;
6767    }
6768
6769  cout << endl;
6770}
6771
6772//----------------------------------------------------------
6773void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
6774{
6775  if (use.get_package_name () == "cmt_standalone") return;
6776
6777  cmt_string fs = CmtSystem::file_separator ();
6778
6779  use.real_path.replace_all (CmtSystem::file_separator (), fs);
6780
6781  cmt_string system = CmtSystem::get_cmt_config ();
6782
6783  bool do_config = use.get_strategy ("SetupConfig");
6784  bool do_root   = use.get_strategy ("SetupRoot");
6785   
6786 
6787  switch (mode)
6788    {
6789    case Csh :
6790      if (do_root)
6791        {
6792          cout << "setenv " << use.prefix << "ROOT \"" <<
6793            use.get_full_path () << "\"" << endl;
6794        }
6795
6796      if (use.get_package_name () == "CMT")
6797        {
6798          cout << "setenv CMTCONFIG " << system << endl;
6799        }
6800      else
6801        {
6802          if (do_config)
6803            {
6804              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
6805            }
6806        }
6807       
6808      break;
6809    case Sh :
6810      if (do_root)
6811        {
6812          cout << use.prefix << "ROOT=\"" <<
6813            use.get_full_path () << "\"; export " <<
6814            use.prefix << "ROOT" << endl;
6815        }
6816
6817      if (use.get_package_name () == "CMT")
6818        {
6819          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
6820        }
6821      else
6822        {
6823          if (do_config)
6824            {
6825              cout << use.prefix << "CONFIG=\"" <<
6826                tag << "\"; export " <<
6827                use.prefix << "CONFIG" << endl;
6828            }
6829        }
6830       
6831      break;
6832    case Bat :
6833      if (do_root)
6834        {
6835          cout << "set " << use.prefix << "ROOT=" <<
6836            use.get_full_path () << endl;
6837        }
6838
6839      if (use.get_package_name () == "CMT")
6840        {
6841          cout << "set CMTCONFIG=" << system << endl;
6842        }
6843      else
6844        {
6845          if (do_config)
6846            {
6847              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
6848            }
6849        }
6850       
6851      break;
6852    }
6853}
6854
6855/**
6856 *  Format a set of make macro definitions (one per line)
6857 * Each macro value is provided enclosed in single quotes
6858 *
6859 *  Take the macro values from the macro statements found
6860 * in recursively read requirements files.
6861 */
6862void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
6863{
6864  int number;
6865
6866  set_standard_macros ();
6867
6868  cmt_regexp expression (pattern);
6869
6870  bool has_pattern = (pattern != "");
6871
6872  for (number = 0; number < Symbol::symbol_number (); number++)
6873    {
6874      Symbol& symbol = Symbol::symbol (number);
6875
6876      if (has_pattern)
6877        {
6878          if (!expression.match (symbol.name)) continue;
6879        }
6880
6881      if (Me.m_action == action_show_macro_names)
6882        {
6883          // Only keep macros.
6884          if ((symbol.type == Symbol::SymbolSet) ||
6885              (symbol.type == Symbol::SymbolAlias) ||
6886              (symbol.type == Symbol::SymbolPath) ||
6887              (symbol.type == Symbol::SymbolAction)) continue;
6888        }
6889      else if (Me.m_action == action_show_set_names)
6890        {
6891          // Exclude macros.
6892          if ((symbol.type == Symbol::SymbolMacro) ||
6893              (symbol.type == Symbol::SymbolAction)) continue;
6894        }
6895      else if (Me.m_action == action_show_action_names)
6896        {
6897          // Exclude macros.
6898          if (symbol.type != Symbol::SymbolAction) continue;
6899        }
6900
6901      cout << symbol.name << endl;
6902    }
6903}
6904
6905/**
6906 *  Format a set of make macro definitions (one per line)
6907 * Each macro value is provided enclosed in single quotes
6908 *
6909 *  Take the macro values from the macro statements found
6910 * in recursively read requirements files.
6911 */
6912void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
6913{
6914  int number;
6915
6916  set_standard_macros ();
6917
6918  cmt_regexp expression (pattern);
6919
6920  bool has_pattern = (pattern != "");
6921
6922  for (number = 0; number < Symbol::symbol_number (); number++)
6923    {
6924      Symbol& symbol = Symbol::symbol (number);
6925
6926      if (has_pattern)
6927        {
6928          if (!expression.match (symbol.name)) continue;
6929        }
6930
6931      if (Me.m_action == action_show_macros)
6932        {
6933          // Only keep macros.
6934          if ((symbol.type == Symbol::SymbolSet) ||
6935              (symbol.type == Symbol::SymbolAlias) ||
6936              (symbol.type == Symbol::SymbolPath) ||
6937              (symbol.type == Symbol::SymbolAction)) continue;
6938        }
6939      else if (Me.m_action == action_show_sets)
6940        {
6941          // Exclude macros.
6942          if ((symbol.type == Symbol::SymbolMacro) ||
6943              (symbol.type == Symbol::SymbolAction)) continue;
6944        }
6945      else if (Me.m_action == action_build_tag_makefile)
6946        {
6947          // Exclude scripts and actions
6948          if ((symbol.type == Symbol::SymbolSetupScript) ||
6949              (symbol.type == Symbol::SymbolCleanupScript) ||
6950              (symbol.type == Symbol::SymbolAction)) continue;
6951        }
6952      else if (Me.m_action == action_show_actions)
6953        {
6954          if (symbol.type != Symbol::SymbolAction) continue;
6955        }
6956
6957      if (symbol.value_lists.size () < 1) continue;
6958
6959      symbol.show_macro (mode);
6960    }
6961}
6962
6963//----------------------------------------------------------
6964void Cmt::print_tabs (int tabs)
6965{
6966  while (tabs > 0)
6967    {
6968      cout << "  ";
6969      tabs--;
6970    }
6971}
6972
6973//----------------------------------------------------------
6974int Cmt::reach_current_package ()
6975{
6976  Use& use = Use::current ();
6977  cmt_string dir;
6978
6979  if (Me.m_debug)
6980    {
6981      cout << "Cmt::reach_current_package> pwd = " 
6982           << CmtSystem::pwd () 
6983           << " path=" << Me.m_current_path
6984           << " package=" << Me.m_current_package
6985           << endl;
6986    }
6987
6988  /*
6989    Try to access the package.
6990  */
6991
6992  if (Me.m_current_package == "cmt_standalone")
6993    {
6994      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
6995        {
6996          if (!CmtSystem::cd (Me.m_current_path))
6997            {
6998              CmtError::set (CmtError::package_not_found,
6999                             "ReachCurrentPackage> Cannot reach the path directory");
7000              return (0);
7001            }
7002        }
7003
7004      if (!CmtSystem::test_file ("requirements"))
7005        {
7006          return (0);
7007        }
7008    }
7009  else if (Me.m_current_package != "")
7010    {
7011      if (!use.move_to ())
7012        {
7013          CmtError::set (CmtError::package_not_found,
7014                         "ReachCurrentPackage> Cannot reach the path directory");
7015          return (0);
7016        }
7017
7018      Me.m_current_path = use.real_path;
7019    }
7020  else
7021    {
7022      //
7023      // The cmt command has been given without explicit search for
7024      // a package. Thus it is expected that we are in the context of a
7025      // true package.
7026      //
7027      //  This means that there should be a requirements file visible.
7028      //
7029      //  If this is not true, we'll make a try into ../cmt and then
7030      // a last try into ../mgr
7031      //
7032
7033      if (!CmtSystem::test_file ("requirements"))
7034        {
7035          if (CmtSystem::cd ("../cmt") && 
7036              CmtSystem::test_file ("requirements"))
7037            {
7038              Me.m_current_style = cmt_style;
7039            }
7040          else if (CmtSystem::cd ("../mgr") && 
7041                   CmtSystem::test_file ("requirements"))
7042            {
7043              Me.m_current_style = mgr_style;
7044            }
7045          else
7046            {
7047              CmtMessage::error ("Cannot reach the mgr branch");
7048              /*
7049              if (!Me.m_quiet)
7050                {
7051                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
7052                }
7053              */
7054             
7055              CmtError::set (CmtError::package_not_found,
7056                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
7057              return (0);
7058            }
7059        }
7060
7061      dir = CmtSystem::pwd ();
7062
7063      CmtSystem::dirname (dir, Me.m_current_path);
7064      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
7065
7066      if (CmtSystem::is_version_directory (Me.m_current_version))
7067        {
7068          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7069          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
7070          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7071        }
7072      else
7073        {
7074          Me.m_current_package = Me.m_current_version;
7075          Me.m_current_version = "";
7076          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7077
7078          Me.m_current_style = no_version_style;
7079        }
7080
7081      use.set_package_name (Me.m_current_package);
7082      use.version = Me.m_current_version;
7083      use.path    = Me.m_current_path;
7084      use.style   = Me.m_current_style;
7085    }
7086
7087  configure_current_dir ();
7088  build_prefix (Me.m_current_package, Me.m_current_prefix);
7089  build_config (Me.m_current_prefix, Me.m_current_config);
7090
7091  /*
7092    Check Tag is always set up
7093  */
7094
7095  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
7096
7097  if (Me.m_current_tag == "")
7098    {
7099      cmt_string env;
7100
7101      env = CmtSystem::getenv (Me.m_current_config);
7102      if (env != "")
7103        {
7104          Tag* tag;
7105
7106          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
7107          tag->mark ();
7108          //Me.m_current_tag = env;
7109
7110          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
7111
7112        }
7113    }
7114
7115  if (Me.m_debug)
7116    {
7117      cout << "pwd = " << CmtSystem::pwd () << endl;
7118    }
7119
7120  /*
7121    Work on the requirements file.
7122  */
7123
7124  if (dir != "") dir += CmtSystem::file_separator ();
7125  dir += "requirements";
7126  SyntaxParser::parse_requirements (dir, &use);
7127
7128  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
7129
7130  /**
7131   *   It would be useful to change this mechanism. Instead of
7132   *  applying all global patterns at once to all use contexts, it
7133   *  would be much better to apply it at the end of each
7134   *  requirements file parsing, and only in the context the
7135   *  appropriate Use.
7136   *
7137   *   This would avoid the current flaw which is that when a global
7138   *  pattern specifies a "private" definition, it is actually
7139   *  applied in the scope context of the Current Use and not in
7140   *  each individual Use. Therefore the private is lost.
7141   *
7142   *   However, this induces problems since some pattern definitions
7143   *  are done AFTER the use statements, which will NOT receive the
7144   *  pattern aplications.
7145   *
7146   *   Therefore it is decided to leave this "bad" mechanism until
7147   *  everybody is aware of this constraint.
7148   *
7149   *
7150   */
7151  Pattern::apply_all_globals ();
7152
7153  /*
7154    Select all possible tags
7155  */
7156
7157  Tag::restore_tree ();
7158
7159  return (1);
7160}
7161
7162static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
7163                                 const cmt_string& path)
7164{
7165  static cmt_string fs = CmtSystem::file_separator ();
7166  cmt_string result;
7167
7168  /*
7169  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
7170  {
7171  */
7172
7173  //
7174  //  If there is a common prefix between
7175  //  use->real_path and pwd
7176  //  we have
7177  //  use->real_path = /<prefix>/aaa
7178  //  pwd            = /<prefix>/bbb
7179  //
7180  //  Then use->real_path may be expressed as:
7181  //  ../..../../aaa
7182  //   where ../..../../ moves up to /<prefix>
7183  //
7184  //   Then we try to find the shortest between
7185  //
7186  //     /<prefix> and ../..../..
7187  //
7188  cmt_string a = path;
7189 
7190  CmtSystem::cmt_string_vector va;
7191 
7192  va.clear ();
7193 
7194  CmtSystem::split (a, fs, va);
7195 
7196  int m = va.size ();
7197  if (pwd.size () < m) m = pwd.size ();
7198 
7199  int i;
7200 
7201  for (i = 0; i < m; i++)
7202    {
7203      const cmt_string& fa = va[i];
7204      const cmt_string& fb = pwd[i];
7205     
7206      if (fa != fb) break;
7207    }
7208 
7209  cmt_string ups = "";
7210 
7211  if (i > 0)
7212    {
7213      // We have the prefix.
7214      // if we count what remains from pwd, then
7215      // we have the number of ../ required to
7216      // move to /<prefix>
7217      int j;
7218     
7219      for (j = i; j < pwd.size (); j++)
7220        {
7221          if (j > i) ups += fs;
7222          ups += "..";
7223        }
7224
7225      for (j = i; j < va.size (); j++)
7226        {
7227          ups += fs;
7228          ups += va[j];
7229        }
7230    }
7231 
7232  //
7233  // Here ups contains the ../..../../aaa form
7234  // for the use->real_path or is empty when there
7235  // were no common prefix.
7236  //
7237 
7238  //if (ups != "")
7239  if ((ups != "") &&
7240      (ups.size () < path.size ()))
7241    {
7242      result = ups;
7243    }
7244  else
7245    {
7246      result = path;
7247    }
7248
7249  return (result);
7250}
7251
7252/**
7253 *   This completely local class holds primitive actions for building
7254 *   standard macros.
7255 */
7256class StandardMacroBuilder
7257{
7258public:
7259
7260  /**
7261   *  CMTVERSION
7262   */
7263  void fill_for_CMTVERSION ()
7264  {
7265    buffer = "macro CMTVERSION \"";
7266    buffer += CMTVERSION;
7267    buffer += "\"";
7268    apply ();
7269  }
7270
7271  StandardMacroBuilder (const cmt_string& tag,
7272                        const cmt_string& package,
7273                        const cmt_string& version,
7274                        const cmt_string& prefix,
7275                        CmtDirStyle style)
7276  {
7277    fs = CmtSystem::file_separator ();
7278    buffer = "";
7279    pwd = CmtSystem::pwd ();
7280    CmtSystem::split (pwd, fs, vb);
7281    current_use = &(Use::current ());
7282    current_tag = tag;
7283    current_package = package;
7284    current_version = version;
7285    current_prefix = prefix;
7286    current_style = style;
7287  }
7288
7289  void apply ()
7290  {
7291    SyntaxParser::parse_requirements_line (buffer, current_use);
7292    buffer = "";
7293  }
7294
7295  /**
7296   *   tag
7297   */
7298  void fill_for_tag ()
7299  {
7300    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
7301
7302    if (!Symbol::is_selected ("tag"))
7303      {
7304        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
7305
7306        if (current_tag == "")
7307          {
7308            buffer = "macro tag \"$(CMTCONFIG)\"";
7309          }
7310        else
7311          {
7312            buffer = "macro tag \"";
7313            buffer += current_tag;
7314            buffer += "\"";
7315          }
7316       
7317        if (tag_debug) cerr << " define tag: " << buffer << endl;
7318       
7319        apply ();
7320      }
7321  }
7322
7323  /**
7324   *   PACKAGE_ROOT
7325   */
7326  void fill_for_package (const cmt_string& current_dir)
7327  {
7328    buffer = "macro package \"";
7329    buffer += current_package;
7330    buffer += "\"";
7331    apply ();
7332
7333    buffer = "macro version \"";
7334    buffer += current_version;
7335    buffer += "\"";
7336    apply ();
7337
7338    if (!Symbol::is_selected ("PACKAGE_ROOT"))
7339      {
7340        buffer = "macro PACKAGE_ROOT \"$(";
7341        buffer += current_prefix;
7342        buffer += "ROOT";
7343        buffer += ")\"";
7344
7345        apply ();
7346      }
7347  }
7348
7349  /**
7350   *   srcdir
7351   *   src       =$(srcdir)/
7352   *   inc
7353   *   mgrdir
7354   *   mgr       =../$(mgrdir)/
7355   *   bin
7356   *   javabin
7357   *   doc
7358   *   version
7359   *   package
7360   *
7361   *   <package>_project
7362   *   <package>_cmtpath
7363   *   <package>_offset
7364   *   package_cmtpath
7365   *   package_offset
7366   *   project
7367   *
7368   */
7369  void fill_for_branches ()
7370  {
7371    /**
7372     *    Basic macros  (src, mgr, ...)
7373     */
7374   
7375    if (current_style == none_style)
7376      {
7377        buffer = "macro srcdir \".";
7378        buffer += "\"";
7379        apply ();
7380
7381        buffer = "macro src \".";
7382        buffer += fs;
7383        buffer += "\"";
7384        apply ();
7385
7386        buffer = "macro inc \".";
7387        buffer += fs;
7388        buffer += "\"";
7389        apply ();
7390
7391        buffer = "macro mgr \".";
7392        buffer += fs;
7393        buffer += "\"";
7394        apply ();
7395
7396        buffer = "macro bin \".";
7397        buffer += fs;
7398        buffer += "\"";
7399        apply ();
7400
7401        buffer = "macro BIN \"";
7402        buffer += pwd;
7403        buffer += fs;
7404        buffer += "\"";
7405        apply ();
7406
7407        buffer = "macro javabin \".";
7408        buffer += fs;
7409        buffer += "\"";
7410        apply ();
7411
7412        buffer = "macro doc \".";
7413        buffer += fs;
7414        buffer += "\"";
7415        apply ();
7416      }
7417    else
7418      {
7419        if (!Symbol::is_selected ("srcdir"))
7420          {
7421            buffer = "macro srcdir \"..";
7422            buffer += fs;
7423            buffer += "src";
7424            buffer += "\"";
7425            apply ();
7426          }
7427       
7428        if (!Symbol::is_selected ("src"))
7429          {
7430            buffer = "macro src \"..";
7431            buffer += fs;
7432            buffer += "src";
7433            buffer += fs;
7434            buffer += "\"";
7435            apply ();
7436          }
7437       
7438        if (!Symbol::is_selected ("inc"))
7439          {
7440            buffer = "macro inc \"..";
7441            buffer += fs;
7442            buffer += "src";
7443            buffer += fs;
7444            buffer += "\"";
7445            apply ();
7446          }
7447       
7448        if (!Symbol::is_selected ("doc"))
7449          {
7450            buffer = "macro doc \"..";
7451            buffer += fs;
7452            buffer += "doc";
7453            buffer += fs;
7454            buffer += "\"";
7455            apply ();
7456          }
7457       
7458        if (!Symbol::is_selected ("bin"))
7459          {
7460            cmt_string package_tag = current_package;
7461            package_tag += "_tag";
7462
7463            buffer = "macro bin \"..";
7464            buffer += fs;
7465            buffer += "$(";
7466            buffer += package_tag;
7467            buffer += ")";
7468            buffer += fs;
7469            buffer += "\"";
7470            apply ();
7471
7472            cmt_string pardir;
7473            CmtSystem::dirname (pwd, pardir);
7474            //            buffer = "macro BIN \"$(PACKAGE_ROOT)";
7475            buffer = "macro BIN \"";
7476            buffer += pardir;
7477            buffer += fs;
7478            buffer += "$(";
7479            buffer += package_tag;
7480            buffer += ")";
7481            buffer += fs;
7482            buffer += "\"";
7483            apply ();
7484          }
7485        else
7486          {
7487            cmt_string temp = "$(bin)";
7488            Symbol::expand (temp);
7489            int len (temp.size());
7490            cmt_string atemp;
7491            if (CmtSystem::absolute_path (temp))
7492              {
7493                CmtSystem::compress_path (temp, atemp);
7494              }
7495            else
7496              {
7497                atemp = pwd + fs + temp;
7498                CmtSystem::compress_path (atemp);
7499              }
7500            buffer = "macro BIN \"";
7501            buffer += atemp;
7502            buffer += "\"";
7503            apply ();
7504            if (0 != len && fs != temp[len - 1])
7505              {
7506                buffer = "macro_append bin \"";
7507                buffer += fs;
7508                buffer += "\"";
7509                apply ();
7510
7511                buffer = "macro_append BIN \"";
7512                buffer += fs;
7513                buffer += "\"";
7514                apply ();
7515              }
7516          }
7517
7518        if (!Symbol::is_selected ("javabin"))
7519          {
7520            buffer = "macro javabin \"..";
7521            buffer += fs;
7522            buffer += "classes";
7523            buffer += fs;
7524            buffer += "\"";
7525            apply ();
7526          }
7527       
7528        if (current_style == mgr_style)
7529          {
7530            buffer = "macro mgrdir \"mgr\"";
7531            apply ();
7532
7533            buffer = "macro mgr \"..";
7534            buffer += fs;
7535            buffer += "mgr";
7536            buffer += fs;
7537            buffer += "\"";
7538            apply ();
7539          }
7540        else
7541          {
7542            buffer = "macro mgrdir \"cmt\"";
7543            apply ();
7544
7545            buffer = "macro mgr \"..";
7546            buffer += fs;
7547            buffer += "cmt";
7548            buffer += fs;
7549            buffer += "\"";
7550            apply ();
7551          }
7552
7553        Cmt::configure_current_cmtpath ();
7554      }
7555  }
7556
7557  /**
7558   *   project
7559   */
7560  void fill_for_project ()
7561  {
7562    if (current_style == none_style) return;
7563
7564    cmt_string project_name;
7565    Project* project = Project::get_current ();
7566    if (project != 0)
7567      {
7568        project_name = project->get_name ();
7569      }
7570
7571    buffer = "macro project \"";
7572    buffer += project_name;
7573    buffer += "\"";
7574    apply ();
7575  }
7576
7577  /**
7578   *   use_requirements
7579   */
7580  void fill_for_use_requirements ()
7581  {
7582    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7583
7584    if (Uses.size () == 0) return;
7585
7586    if (!Symbol::is_selected ("use_requirements"))
7587      {
7588        buffer  = "macro use_requirements \"";
7589        buffer += "requirements ";
7590       
7591        for (int number = 0; number < Uses.size (); number++)
7592          {
7593            Use* use = Uses[number];
7594           
7595            if (use->discarded) continue;
7596            if (use->m_hidden) continue;
7597           
7598            if (use->located ())
7599              {
7600                buffer += "$(";
7601                buffer += use->get_package_name ();
7602                buffer += "_root)";
7603//                 buffer += use->prefix;
7604//                 buffer += "ROOT)";
7605                buffer += fs;
7606               
7607                if (use->style == mgr_style) buffer += "mgr";
7608                else buffer += "cmt";
7609               
7610                buffer += fs;
7611                buffer += "requirements ";
7612              }
7613          }
7614       
7615        buffer += "\"";
7616       
7617        apply ();
7618      }
7619  }
7620
7621  /**
7622   *   use_includes
7623   */
7624  void fill_for_use_includes ()
7625  {
7626    Include::parse_all (&(Use::current()));
7627
7628    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7629
7630    if (Uses.size () == 0) return;
7631
7632    if (!Symbol::is_selected ("use_includes"))
7633      {
7634        buffer = "macro_append use_includes \' ";
7635       
7636        for (int number = 0; number < Uses.size (); number++)
7637          {
7638            Use* use = Uses[number];
7639           
7640            if (use->discarded) continue;
7641            if (use->m_hidden) continue;
7642
7643            Package* p = use->get_package ();
7644            if (p->is_cmt ()) continue;
7645
7646            if (Cmt::get_debug ())
7647              {
7648                cout << "fill use_includes for " << use->get_package_name () 
7649                     << " discarded=" << use->discarded
7650                     << " auto_imports=" << use->auto_imports << endl;
7651              }
7652           
7653            if (use->auto_imports == Off) continue;
7654           
7655            Include::parse_all (use);
7656
7657            use->fill_includes_macro (buffer);
7658          }
7659       
7660        buffer += "\'";
7661       
7662        apply ();
7663      }
7664  }
7665
7666  /**
7667   *   use_fincludes
7668   */
7669  void fill_for_use_fincludes ()
7670  {
7671    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7672
7673    if (Uses.size () == 0) return;
7674
7675    if (!Symbol::is_selected ("use_fincludes"))
7676      {
7677        buffer = "macro_append use_fincludes \" $(use_includes)\"";
7678        apply ();
7679      }
7680  }
7681
7682  /**
7683   *   use_stamps
7684   */
7685  void fill_for_use_stamps ()
7686  {
7687    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7688
7689    if (Uses.size () == 0) return;
7690
7691    if (!Symbol::is_selected ("use_stamps"))
7692      {
7693        /*
7694        buffer = "macro use_stamps \"";
7695        (Use::current()).fill_macro (buffer, "stamps");
7696       
7697        for (int number = 0; number < Uses.size (); number++)
7698          {
7699            Use* use = Uses[number];
7700           
7701            if (use->discarded) continue;
7702            if (use->m_hidden) continue;
7703
7704            Package* p = use->get_package ();
7705            if (p->is_cmt ()) continue;
7706           
7707            use->fill_macro (buffer, "stamps");
7708          }
7709       
7710        buffer += "\"";
7711        */
7712        Use::fill_macro_all (buffer, "stamps");
7713        apply ();
7714      }
7715  }
7716
7717  /**
7718   *   use_cflags
7719   */
7720  void fill_for_use_cflags ()
7721  {
7722    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7723
7724    if (Uses.size () == 0) return;
7725
7726    if (!Symbol::is_selected ("use_cflags"))
7727      {
7728        Use::fill_macro_all (buffer, "cflags");
7729        apply ();
7730      }
7731  }
7732
7733  /**
7734   *   use_pp_cflags
7735   */
7736  void fill_for_use_pp_cflags ()
7737  {
7738    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7739
7740    if (Uses.size () == 0) return;
7741
7742    if (!Symbol::is_selected ("use_pp_cflags"))
7743      {
7744        Use::fill_macro_all (buffer, "pp_cflags");
7745        apply ();
7746      }
7747  }
7748
7749  /**
7750   *   use_cppflags
7751   */
7752  void fill_for_use_cppflags ()
7753  {
7754    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7755
7756    if (Uses.size () == 0) return;
7757
7758    if (!Symbol::is_selected ("use_cppflags"))
7759      {
7760        Use::fill_macro_all (buffer, "cppflags");
7761        apply ();
7762      }
7763  }
7764
7765  /**
7766   *   use_pp_cppflags
7767   */
7768  void fill_for_use_pp_cppflags ()
7769  {
7770    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7771
7772    if (Uses.size () == 0) return;
7773
7774    if (!Symbol::is_selected ("use_pp_cppflags"))
7775      {
7776        Use::fill_macro_all (buffer, "pp_cppflags");
7777        apply ();
7778      }
7779  }
7780
7781  /**
7782   *   use_fflags
7783   */
7784  void fill_for_use_fflags ()
7785  {
7786    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7787
7788    if (Uses.size () == 0) return;
7789
7790    if (!Symbol::is_selected ("use_fflags"))
7791      {
7792        Use::fill_macro_all (buffer, "fflags");
7793        apply ();
7794      }
7795  }
7796
7797  /**
7798   *   use_pp_fflags
7799   */
7800  void fill_for_use_pp_fflags ()
7801  {
7802    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7803
7804    if (Uses.size () == 0) return;
7805
7806    if (!Symbol::is_selected ("use_pp_fflags"))
7807      {
7808        Use::fill_macro_all (buffer, "pp_fflags");
7809        apply ();
7810      }
7811  }
7812
7813  /**
7814   *   use_linkopts
7815   */
7816  void fill_for_use_linkopts ()
7817  {
7818    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7819
7820    if (Uses.size () == 0) return;
7821
7822    if (!Symbol::is_selected ("use_linkopts"))
7823      {
7824        Use::fill_macro_all (buffer, "linkopts");
7825        apply ();
7826      }
7827  }
7828
7829  /**
7830   *   use_libraries
7831   */
7832  void fill_for_use_libraries ()
7833  {
7834    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7835
7836    if (Uses.size () == 0) return;
7837
7838    if (!Symbol::is_selected ("use_libraries"))
7839      {
7840        buffer  = "macro use_libraries \"";
7841
7842        for (int number = 0; number < Uses.size (); number++)
7843          {
7844            Use* use = Uses[number];
7845           
7846            if (use->discarded) continue;
7847            if (use->m_hidden) continue;
7848           
7849            Package* p = use->get_package ();
7850            if (p->is_cmt ()) continue;
7851
7852            use->fill_macro (buffer, "libraries");
7853          }
7854       
7855        buffer += "\"";
7856
7857        apply ();
7858      }
7859  }
7860
7861  /**
7862   *   includes
7863   */
7864  void fill_for_includes ()
7865  {
7866    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7867
7868    if (Uses.size () == 0) return;
7869
7870    if (!Symbol::is_selected ("includes"))
7871      {
7872        buffer = "macro_append includes \' ";
7873
7874        Use& use = Use::current();
7875
7876        if (use.include_path == "")
7877          {
7878            buffer += "$(ppcmd)\"$(srcdir)\" ";
7879          }
7880        else if (use.include_path != "none")
7881          {
7882            buffer += "$(ppcmd)\"";
7883            buffer += use.include_path;
7884            buffer += "\" ";
7885          }
7886
7887        for (int include_number = 0;
7888             include_number < use.includes.size ();
7889             include_number++)
7890          {
7891            Include& incl = use.includes[include_number];
7892
7893            if (incl.name == "") continue;
7894
7895            buffer += "$(ppcmd)\"";
7896            buffer += incl.name;
7897            buffer += "\" ";
7898          }
7899       
7900        buffer += "$(use_includes)\'";
7901       
7902        apply ();
7903      }
7904  }
7905
7906  /**
7907   *   fincludes
7908   */
7909  void fill_for_fincludes ()
7910  {
7911    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7912
7913    if (Uses.size () == 0) return;
7914
7915    if (!Symbol::is_selected ("fincludes"))
7916      {
7917        buffer = "macro_append fincludes \" $(includes)\"";
7918        apply ();
7919      }
7920  }
7921
7922  /**
7923   *  Macros specific to constituents.
7924   *  This includes the compiler flags
7925   *  and fills in these macros from uses packages. This takes care
7926   *  of -no_auto_imports and -import= directives
7927   *
7928   *    <constituent>_use_linkopts
7929   *    <prefix>_<constituent>_cflags
7930   *    <prefix>_<constituent>_pp_cflags
7931   *    <prefix>_<constituent>_cppflags
7932   *    <prefix>_<constituent>_pp_cppflags
7933   *    <prefix>_<constituent>_fflags
7934   *    <prefix>_<constituent>_pp_fflags
7935   *    <constituent>linkopts
7936   *    <constituent>_GUID
7937   *    <constituent>_stamps
7938   *
7939   */
7940  void fill_for_all_constituents ()
7941  {
7942    /// First, finish the parsing of constituent parameters.
7943    if (Cmt::get_debug ())
7944      {
7945        cout << "fill_for_all_constituents>" << endl;
7946      }
7947
7948    Constituent::parse_all ();
7949
7950    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7951   
7952    const Constituent::ConstituentVector& constituents =
7953      Constituent::constituents ();
7954
7955 
7956    // Prepare the auto_imports states in a vector
7957    cmt_vector<bool> base_auto_imports_states;
7958
7959    base_auto_imports_states.resize (Uses.size ());
7960
7961    int number;
7962   
7963    for (number = 0; number < Uses.size (); number++)
7964      {
7965        Use* use = Uses[number];
7966        base_auto_imports_states[number] = (use->auto_imports != Off);
7967      }
7968   
7969    // Now scan all constituents
7970       
7971    for (number = 0; number < constituents.size (); number++)
7972      {
7973        const Constituent& constituent = constituents[number];
7974       
7975        //==== GLAST addition for vs.net ==========
7976        buffer = "macro ";
7977        buffer += constituent.name;
7978        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
7979        apply ();
7980       
7981        if (Cmt::get_debug ())
7982          {
7983            cout << "Checking " << constituent.name  << " against imports requests" << endl;
7984          }
7985        Use::UsePtrVector imports;
7986        int i;
7987       
7988        /**
7989         *  Problem for imports in constituents.
7990         *
7991         *     1) use_xxx has holes due to the corresponding
7992         *         -no_auto_imports options attached to some
7993         *        use statements (including the transitive ones)
7994         *
7995         *     2) the -import=yyy options provided to a given constituent
7996         *        should restore the appropriate holes as well as
7997         *        all transitive ones.
7998         *
7999         *     3) for use_linkopts, missing pieces must be filled at
8000         *        the right position. (for others, order is not relevant
8001         *        while transitive access is required for all)
8002         *
8003         */
8004       
8005        if (constituent.type == Document)
8006          { 
8007            continue;
8008          }
8009       
8010        if (constituent.imports.size () == 0) 
8011          {
8012            buffer = "macro_append ";
8013            buffer += constituent.name;
8014            buffer += "_use_linkopts ";
8015            buffer += " \" ";
8016           
8017            current_use->fill_macro (buffer, "linkopts");
8018           
8019            for (i = 0; i < Uses.size (); i++)
8020              {
8021                if (base_auto_imports_states[i])
8022                  {
8023                    Use* u = Uses[i];
8024                   
8025                    if (u->discarded) continue;
8026                    if (u->m_hidden) continue;
8027                   
8028                    Package* p = u->get_package ();
8029                    if (p->is_cmt ()) continue;
8030                   
8031                    u->fill_macro (buffer, "linkopts");
8032                  }
8033              }
8034            buffer += "\"";
8035            apply ();
8036           
8037            /*
8038              buffer = "macro_append ";
8039              buffer += constituent.name;
8040              buffer += "_use_linkopts ";
8041             
8042              buffer += " \" $(use_linkopts)\"";
8043              apply ();
8044            */
8045           
8046            continue;
8047          }
8048       
8049        // From here on, the constituent HAS import options.
8050       
8051        /**
8052         * Create a private copy of the state vector. This private copy
8053         * will be updated according to -import=xxx modifiers for the
8054         * current constituent.
8055         */
8056        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
8057       
8058        for (i = 0; i < constituent.imports.size (); i++)
8059          {
8060            const cmt_string& import = constituent.imports[i];
8061           
8062            //
8063            // Resolve the imported uses
8064            //
8065           
8066            int use_index = Use::find_index (import, "", "");
8067           
8068            if (use_index >= 0)
8069              {
8070                Use* u = Uses[use_index];
8071               
8072                if (u->discarded) continue;
8073                if (u->m_hidden) continue;
8074               
8075                if (Cmt::get_debug ())
8076                  {
8077                    cout << constituent.name  << " needs imports " << import << " "
8078                         << use_index << " " 
8079                         << u->get_package()->get_name() << " "
8080                         << " u->auto_imports=" << u->auto_imports
8081                         << " Off=" << Off
8082                         << " On=" << On
8083                         << endl;
8084                  }
8085               
8086                Package* p = u->get_package ();
8087                if (p->is_cmt ()) continue;
8088               
8089                if (u->auto_imports != Off) continue;
8090               
8091                Use::set_auto_imports_state (use_index, auto_imports_states);
8092              }
8093          }
8094       
8095        if (Cmt::get_debug ())
8096          {
8097            cout << constituent.name  << " has imports " << endl;
8098          }
8099       
8100       
8101        /**
8102         *   Find all newly exposed packages and precompute this list inside
8103         *   a vector.
8104         */
8105        for (i = 0; i < base_auto_imports_states.size (); i++)
8106          {
8107            //      if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
8108            if (base_auto_imports_states[i] == On || auto_imports_states[i] == Off) continue;
8109            /**
8110             *  Consider the package (i) for import only if it is:
8111             *   o not imported yet (i.e., base_auto_imports_states[i] != On)
8112             *   o requested for import according to -import=xxx modifiers for
8113             *     the current constituent (i.e., auto_imports_states[i] != Off)
8114             */
8115            Use* u = Uses[i];
8116           
8117            if (u->discarded) continue;
8118            if (u->m_hidden)  continue;
8119           
8120            Package* p = u->get_package ();
8121            if (p->is_cmt ()) continue;
8122           
8123            if (Cmt::get_debug ())
8124              {
8125                cout << constituent.name  << " has import " << p->get_name () << endl;
8126              }
8127           
8128            imports.push_back (u);
8129          }
8130       
8131        /**
8132         *  Only for linkopts we take care of the order. This means
8133         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
8134         *
8135         *  (see the application fragments)
8136         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
8137         */
8138        buffer = "macro_append ";
8139        buffer += constituent.name;
8140        buffer += "_use_linkopts ";
8141        buffer += " \" ";
8142       
8143        current_use->fill_macro (buffer, "linkopts");
8144       
8145        for (i = 0; i < Uses.size (); i++)
8146          {
8147            if (auto_imports_states[i])
8148              {
8149                Use* u = Uses[i];
8150               
8151                if (u->discarded) continue;
8152                if (u->m_hidden) continue;
8153               
8154                Package* p = u->get_package ();
8155                if (p->is_cmt ()) continue;
8156               
8157                u->fill_macro (buffer, "linkopts");
8158              }
8159          }
8160        buffer += "\"";
8161        apply ();
8162       
8163        if (imports.size () == 0) continue;
8164       
8165        cmt_string prefix;
8166       
8167        //
8168        // Documents are not considered
8169        //
8170        switch (constituent.type)
8171          {
8172          case Application:
8173            prefix = "app_";
8174            break;
8175          case Library:
8176            prefix = "lib_";
8177            break;
8178          }
8179       
8180        buffer = "macro_append ";
8181        buffer += prefix;
8182        buffer += constituent.name;
8183        buffer += "_cflags ";
8184        buffer += " \' ";
8185        for (i = 0; i < imports.size (); i++)
8186          {
8187            Use* u = imports[i];
8188           
8189            u->fill_includes_macro (buffer);
8190            u->fill_macro (buffer, "cflags");
8191          }
8192        buffer += "\'";
8193        apply ();
8194       
8195        buffer = "macro_append ";
8196        buffer += prefix;
8197        buffer += constituent.name;
8198        buffer += "_pp_cflags ";
8199        buffer += " \" ";
8200        for (i = 0; i < imports.size (); i++)
8201          {
8202            Use* u = imports[i];
8203           
8204            u->fill_macro (buffer, "pp_cflags");
8205          }
8206        buffer += "\"";
8207        apply ();
8208       
8209        buffer = "macro_append ";
8210        buffer += prefix;
8211        buffer += constituent.name;
8212        buffer += "_cppflags ";
8213        buffer += " \' ";
8214        for (i = 0; i < imports.size (); i++)
8215          {
8216            Use* u = imports[i];
8217           
8218            u->fill_includes_macro (buffer);
8219            u->fill_macro (buffer, "cppflags");
8220          }
8221        buffer += "\'";
8222        apply ();
8223       
8224        buffer = "macro_append ";
8225        buffer += prefix;
8226        buffer += constituent.name;
8227        buffer += "_pp_cppflags ";
8228        buffer += " \" ";
8229        for (i = 0; i < imports.size (); i++)
8230          {
8231            Use* u = imports[i];
8232           
8233            u->fill_macro (buffer, "pp_cppflags");
8234          }
8235        buffer += "\"";
8236        apply ();
8237       
8238        buffer = "macro_append ";
8239        buffer += prefix;
8240        buffer += constituent.name;
8241        buffer += "_fflags ";
8242        buffer += " \' ";
8243        for (i = 0; i < imports.size (); i++)
8244          {
8245            Use* u = imports[i];
8246           
8247            u->fill_includes_macro (buffer);
8248            u->fill_macro (buffer, "fflags");
8249          }
8250        buffer += "\'";
8251        apply ();
8252       
8253        buffer = "macro_append ";
8254        buffer += prefix;
8255        buffer += constituent.name;
8256        buffer += "_pp_fflags ";
8257        buffer += " \" ";
8258        for (i = 0; i < imports.size (); i++)
8259          {
8260            Use* u = imports[i];
8261           
8262            u->fill_macro (buffer, "pp_fflags");
8263          }
8264        buffer += "\"";
8265        apply ();
8266
8267        buffer = "macro_append ";
8268        buffer += constituent.name;
8269        buffer += "_stamps ";
8270        buffer += " \" ";
8271        for (i = 0; i < imports.size (); i++)
8272          {
8273            Use* u = imports[i];
8274           
8275            u->fill_macro (buffer, "stamps");
8276          }
8277        buffer += "\"";
8278        apply ();
8279
8280        /**
8281         *  Setting ${CONSTITUENT}linkopts is a temporary solution
8282         *  until the backward compatibility solution for a proper
8283         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
8284         *  is acheived.
8285         *
8286         */
8287        /**
8288        buffer = "macro_append ";
8289        buffer += constituent.name;
8290        buffer += "linkopts ";
8291        buffer += " \" ";
8292        for (i = 0; i < imports.size (); i++)
8293          {
8294            Use* u = imports[i];
8295           
8296            u->fill_macro (buffer, "linkopts");
8297          }
8298        buffer += "\"";
8299        apply ();
8300        */
8301      }
8302  }
8303 
8304  /**
8305   *   Macros implied or required to manage constituents.
8306   */
8307  void fill_for_constituent_macros ()
8308  {
8309    int number;
8310    cmt_string temp;
8311
8312    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
8313 
8314    if (!Symbol::is_selected ("constituents"))
8315      {
8316        temp = "macro_append constituents \" ";
8317       
8318        for (number = 0; number < constituents.size (); number++)
8319          {
8320            const Constituent& constituent = constituents[number];
8321           
8322            if (constituent.group == 0)
8323              {
8324                temp += constituent.name;
8325                temp += " ";
8326              }
8327          }
8328       
8329        temp += "\"";
8330       
8331        SyntaxParser::parse_requirements_line (temp, current_use);
8332      }
8333   
8334    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
8335                                           current_use);
8336   
8337    if (!Symbol::is_selected ("constituentsclean"))
8338      {
8339        temp = "macro_append constituentsclean \" ";
8340       
8341        for (number = constituents.size () - 1; number >= 0 ; number--)
8342          {
8343            const Constituent& constituent = constituents[number];
8344           
8345            if (constituent.group == 0)
8346              {
8347                temp += constituent.name;
8348                temp += "clean ";
8349              }
8350          }
8351       
8352        temp += "\"";
8353       
8354        SyntaxParser::parse_requirements_line (temp, current_use);
8355      }
8356   
8357    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
8358                                           current_use);
8359   
8360    const Group::GroupVector& groups = Group::groups ();
8361   
8362    for (number = 0; number < groups.size (); number++)
8363      {
8364        const Group& group = groups[number];
8365       
8366        temp = "macro_append ";
8367        temp += group.name ();
8368        temp += "_constituents \" ";
8369       
8370        int i;
8371       
8372        for (i = 0; i < constituents.size (); i++)
8373          {
8374            const Constituent& constituent = constituents[i];
8375           
8376            if ((constituent.group != 0) && 
8377                (group.name () == constituent.group->name ()))
8378              {
8379                temp += constituent.name;
8380                temp += " ";
8381              }
8382          }
8383       
8384        temp += "\"";
8385       
8386        SyntaxParser::parse_requirements_line (temp, current_use);
8387       
8388        temp = "macro_append ";
8389        temp += group.name ();
8390        temp += "_constituentsclean \" ";
8391       
8392        for (i = constituents.size () - 1; i >= 0 ; i--)
8393          {
8394            const Constituent& constituent = constituents[i];
8395           
8396            if ((constituent.group != 0) && 
8397                (group.name () == constituent.group->name ()))
8398              {
8399                temp += constituent.name;
8400                temp += "clean ";
8401              }
8402          }
8403       
8404        temp += "\"";
8405       
8406        SyntaxParser::parse_requirements_line (temp, current_use);
8407      }
8408  }
8409
8410  /**
8411   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
8412   */
8413  void fill_for_install_area ()
8414  {
8415    CmtPathPattern::apply_all ();
8416
8417    const Use& current_use = Use::current ();
8418
8419    if (current_use.get_strategy ("InstallArea"))
8420      {
8421        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
8422       
8423        ia_mgr.setup ();
8424      }
8425  }
8426
8427  /**
8428   * Macros to be defined once current_package is known
8429   * and even before reading its requirements file.
8430   */
8431  void fill_for_current_package (const cmt_string& current_dir)
8432  {
8433    fill_for_tag ();
8434    fill_for_package (current_dir);
8435  }
8436
8437private:
8438  cmt_string fs;
8439  cmt_string buffer;
8440  CmtSystem::cmt_string_vector vb;
8441  cmt_string pwd;
8442  Use* current_use;
8443  cmt_string current_tag; 
8444  cmt_string current_package; 
8445  cmt_string current_version; 
8446  cmt_string current_prefix; 
8447  CmtDirStyle current_style;
8448};
8449
8450//----------------------------------------------------------
8451void Cmt::set_current_access (AccessMode mode)
8452{
8453  Me.m_current_access = mode;
8454}
8455
8456//----------------------------------------------------------
8457void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
8458{
8459  Me.m_scope_filtering_mode = mode;
8460}
8461
8462//----------------------------------------------------------
8463void Cmt::set_standard_macros ()
8464{
8465  if (Me.m_standard_macros_done) return;
8466
8467  Me.m_standard_macros_done = true;
8468
8469  //  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8470  Use& current_use = Use::current ();
8471
8472  cmt_string fs = CmtSystem::file_separator ();
8473
8474  cmt_string pwd = CmtSystem::pwd ();
8475
8476  /**
8477   * This is a check for package names
8478   */
8479  if (CmtMessage::active (Verbose))
8480    {
8481      Use::UsePtrVector uses (Use::get_ordered_uses ());
8482      uses.push_back (&current_use);
8483      for (int i = uses.size () - 1; i >= 0; i--)
8484        {
8485          Use* use = uses[i];
8486          if (use->discarded) continue;
8487          if (use->m_hidden) continue;
8488          if (!use->located ()) continue;
8489          for (int j = i - 1; j >= 0; j--)
8490            {
8491              Use* use2 = uses[j];
8492              if (use2->discarded) continue;
8493              if (use2->m_hidden) continue;
8494              if (!use2->located ()) continue;
8495              if (use->prefix == use2->prefix)
8496                {
8497                  CmtMessage::warning (use->prefix + "ROOT, "
8498                                       + use->prefix + "VERSION ill-defined: "
8499                                       + use->get_package_name () + " and "
8500                                       + use2->get_package_name ()
8501                                       + " package name conflict");
8502                }
8503            }
8504        }
8505    }
8506  /**
8507   * This is already done in
8508   void Cmt::configure_current_package ()
8509
8510  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
8511  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
8512  else Me.m_current_style = none_style;
8513
8514  {
8515    cmt_string v;
8516    CmtSystem::dirname (pwd, v);
8517    CmtSystem::basename (v, v);
8518    if (!CmtSystem::is_version_directory (v))
8519      {
8520        Me.m_current_style = no_version_style;
8521      }
8522  }
8523  */
8524
8525  // Prepare computation of the best form for relative path from current directory
8526  // to package directories.
8527  CmtSystem::cmt_string_vector vb;
8528  CmtSystem::split (pwd, fs, vb);
8529
8530
8531  /**
8532   *    TAG management
8533   */
8534
8535  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
8536
8537  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
8538
8539  if (Me.m_current_tag != "")
8540    {
8541      // this is when some -tag= argument was used.
8542      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
8543    }
8544  else if (Symbol::is_selected ("CMTCONFIG"))
8545    {
8546      // This is when CMTCONFIG has been set from some requirements file
8547      Symbol* macro = Symbol::find ("CMTCONFIG");
8548      if (macro != 0)
8549        {
8550          Me.m_current_tag = macro->build_macro_value ();
8551          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
8552        }
8553    }
8554  else
8555    {
8556      // this is when no -tag= argument was used.
8557      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
8558      if (current_use.get_package_name () == "CMT")
8559        {
8560          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
8561        }
8562      else
8563        {
8564          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
8565        }
8566
8567      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
8568    }
8569
8570  if (Me.m_debug)
8571    {
8572      cout << "set_standard_macro3>" << endl;
8573    }
8574
8575  StandardMacroBuilder builder (Me.m_current_tag,
8576                                Me.m_current_package,
8577                                Me.m_current_version,
8578                                Me.m_current_prefix,
8579                                Me.m_current_style);
8580
8581
8582  builder.fill_for_current_package (Me.m_current_dir);
8583
8584  builder.fill_for_branches ();
8585  builder.fill_for_project ();
8586
8587  builder.fill_for_install_area ();
8588
8589  builder.fill_for_use_requirements ();
8590  builder.fill_for_use_includes ();
8591  builder.fill_for_use_fincludes ();
8592  builder.fill_for_use_stamps ();
8593  builder.fill_for_use_cflags ();
8594  builder.fill_for_use_pp_cflags ();
8595  builder.fill_for_use_cppflags ();
8596  builder.fill_for_use_pp_cppflags ();
8597  builder.fill_for_use_fflags ();
8598  builder.fill_for_use_pp_fflags ();
8599  builder.fill_for_use_linkopts ();
8600  builder.fill_for_use_libraries ();
8601  builder.fill_for_includes ();
8602  builder.fill_for_fincludes ();
8603  builder.fill_for_all_constituents ();
8604  builder.fill_for_constituent_macros ();
8605}
8606
8607void Cmt::set_all_sets_done ()
8608{
8609  Me.m_all_sets_done = true;
8610}
8611
8612void Cmt::reset_all_sets_done ()
8613{
8614  Me.m_all_sets_done = false;
8615}
8616
8617//----------------------------------------------------------
8618void Cmt::use_cmt ()
8619{
8620  UseRef use;
8621  bool recursive_copy = Me.m_recursive;
8622  bool debug_copy = Me.m_debug;
8623
8624  if (Me.m_default_path.size () <= 0) return;
8625  if (Me.m_current_package == "CMT") return;
8626
8627  Me.m_recursive = true;
8628  //Me.m_debug = false;
8629  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
8630  Me.m_recursive = recursive_copy;
8631  Me.m_debug = debug_copy;
8632}
8633
8634//----------------------------------------------------------
8635void Cmt::use_home_requirements ()
8636{
8637  use_special_requirements (Me.m_cmt_home, 
8638                            CmtSystem::get_home_package (), 
8639                            "requirements");
8640}
8641
8642//----------------------------------------------------------
8643void Cmt::use_user_context_requirements ()
8644{
8645  use_special_requirements (Me.m_cmt_user_context, 
8646                            CmtSystem::get_user_context_package (), 
8647                            "requirements");
8648}
8649
8650//----------------------------------------------------------
8651void Cmt::use_special_requirements (const cmt_string& path, 
8652                                    const cmt_string& name, 
8653                                    const cmt_string& file_name)
8654{
8655  if (path == "") 
8656    {
8657      return;
8658    }
8659
8660  UseRef use;
8661  bool recursive_copy = Me.m_recursive;
8662
8663  if (Me.m_default_path.size () <= 0) return;
8664  if (Me.m_current_package == "CMT") return;
8665
8666  Me.m_recursive = true;
8667
8668  use = Use::add (path, name, "v0", "", "", "", 0);
8669
8670  cmt_string f = path;
8671  f += CmtSystem::file_separator ();
8672  f += file_name;
8673  SyntaxParser::parse_requirements (f, use);
8674
8675  Me.m_recursive = recursive_copy;
8676}
8677
8678//-------------------------------------------------
8679void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
8680                            const cmt_string& separator,
8681                            cmt_string& result)
8682{
8683  result.erase (0);
8684
8685  for (int i = 0; i < v.size (); i++)
8686    {
8687      const cmt_string& s = v[i];
8688      if (s == "") continue;
8689
8690      if (i > 0) result += separator;
8691      result += v[i];
8692    }
8693}
8694
8695//-------------------------------------------------
8696cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
8697{
8698  cmt_string result;
8699
8700  vector_to_string (v, " ", result);
8701
8702  return (result);
8703}
Note: See TracBrowser for help on using the repository browser.