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

Last change on this file since 610 was 610, checked in by rybkin, 12 years ago

See C.L. 485

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