source: CMT/v1r25-branch/source/cmt_parser.cxx @ 637

Last change on this file since 637 was 637, checked in by rybkin, 11 years ago

merge -r 618:627 HEAD

  • Property svn:eol-style set to native
File size: 249.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  do_show_macro (ap);
4356}
4357
4358//----------------------------------------------------------
4359void Cmt::do_show_action_names (const ArgParser& ap)
4360{
4361  if (ap.arguments.size () > 0)
4362    {
4363      const cmt_string& pattern = ap.arguments[0];
4364      print_symbol_names (ap.mode, pattern);
4365    }
4366  else
4367    {
4368      print_symbol_names (ap.mode);
4369    }
4370}
4371
4372//----------------------------------------------------------
4373void Cmt::do_show_action_value (const ArgParser& ap)
4374{
4375  do_show_macro (ap);
4376}
4377
4378//----------------------------------------------------------
4379void Cmt::do_show_actions (const ArgParser& ap)
4380{
4381  if (ap.arguments.size () > 0)
4382    {
4383      const cmt_string& pattern = ap.arguments[0];
4384      print_macros (ap.mode, pattern);
4385    }
4386  else
4387    {
4388      print_macros (ap.mode);
4389    }
4390}
4391
4392//----------------------------------------------------------
4393void Cmt::do_show_alias (const ArgParser& ap)
4394{
4395  do_show_macro (ap);
4396}
4397
4398//----------------------------------------------------------
4399void Cmt::do_show_alias_names (const ArgParser& ap)
4400{
4401  if (ap.arguments.size () > 0)
4402    {
4403      const cmt_string& pattern = ap.arguments[0];
4404      print_symbol_names (ap.mode, pattern);
4405    }
4406  else
4407    {
4408      print_symbol_names (ap.mode);
4409    }
4410}
4411
4412//----------------------------------------------------------
4413void Cmt::do_show_alias_value (const ArgParser& ap)
4414{
4415  do_show_macro (ap);
4416}
4417
4418//----------------------------------------------------------
4419void Cmt::do_show_aliases (const ArgParser& ap)
4420{
4421  if (ap.arguments.size () > 0)
4422    {
4423      const cmt_string& pattern = ap.arguments[0];
4424      print_macros (ap.mode, pattern);
4425    }
4426  else
4427    {
4428      print_macros (ap.mode);
4429    }
4430}
4431
4432//----------------------------------------------------------
4433void Cmt::do_show_all_tags (const ArgParser& /*ap*/)
4434{
4435  Tag::TagPtrVector tags = Tag::tags ();
4436  int index;
4437
4438  set_standard_macros ();
4439
4440  for (index = 0; index < tags.size (); index++)
4441    {
4442      const Tag* tag = tags[index];
4443      if (tag != 0)
4444        {
4445          tag->show_definition (true);
4446        }
4447    }
4448}
4449
4450//----------------------------------------------------------
4451void Cmt::do_show_applied_patterns (const ArgParser& /*ap*/)
4452{
4453  Pattern::show_all_applied_patterns ();
4454}
4455
4456//----------------------------------------------------------
4457void Cmt::do_show_author (const ArgParser& /*ap*/)
4458{
4459  Use& use = Use::current();
4460
4461  cout << use.author << endl;
4462 
4463}
4464//----------------------------------------------------------
4465void Cmt::do_show_project_author (const ArgParser& /*ap*/)
4466{
4467  cmt_string cmtpath;
4468  cmt_string offset;
4469
4470  Use& use = Use::current();   
4471  use.get_cmtpath_and_offset (cmtpath, offset);
4472
4473  Project* p = Project::find_by_cmtpath (cmtpath);
4474
4475  cout << p->get_author () << endl;
4476}
4477
4478//----------------------------------------------------------
4479void Cmt::do_show_branches (const ArgParser& ap)
4480{
4481  Branch::print_all (ap.mode);
4482}
4483
4484//----------------------------------------------------------
4485void Cmt::do_show_clients (const ArgParser& ap)
4486{
4487  cmt_string package   = "";
4488  cmt_string version   = "";
4489  cmt_string path_name = "";
4490
4491  if (ap.arguments.size () >= 1) package  = ap.arguments[0];
4492  if (ap.arguments.size () >= 2) version  = ap.arguments[1];
4493  if (ap.arguments.size () >= 3) path_name = ap.arguments[2];
4494
4495  PathScanner scanner;
4496  ClientCollector collector (package, version);
4497
4498  clear     ();
4499  //  configure ();
4500  configure (ap);
4501
4502  cout << "# ----------- Clients of " << package
4503       << (version != "" ? " " + version : "")
4504       << (path_name != "" ? " (" + path_name + ")": "")
4505    //    " " << version <<
4506    //    " " << path_name <<
4507       << endl;
4508
4509  if (path_name == "")
4510    {
4511      Project::scan_paths (scanner, collector);
4512    }
4513  else
4514    {
4515      scanner.scan_path (path_name, collector);
4516    }
4517
4518  cout << "# ----------- " << collector.count () << " clients found." << endl;
4519}
4520
4521//----------------------------------------------------------
4522void Cmt::do_show_cmtpath_patterns (const ArgParser& /*ap*/)
4523{
4524  set_standard_macros ();
4525  CmtPathPattern::show_all ();
4526}
4527
4528//----------------------------------------------------------
4529void Cmt::do_show_constituent (const ArgParser& ap)
4530{
4531  if (ap.arguments.size () > 0) 
4532    {
4533      set_standard_macros ();
4534
4535      Constituent* c = Constituent::find (ap.arguments[0]);
4536      if (c != 0)
4537        {
4538          c->show ();
4539        }
4540      else
4541        {
4542          cmt_string t (ap.arguments[0]);
4543          CmtError::set (CmtError::constituent_not_found, t);
4544        }
4545    }
4546}
4547
4548//----------------------------------------------------------
4549void Cmt::do_show_constituent_names (const ArgParser& /*ap*/)
4550{
4551  set_standard_macros ();
4552  Constituent::show_names ();
4553}
4554
4555//----------------------------------------------------------
4556void Cmt::do_show_constituents (const ArgParser& /*ap*/)
4557{
4558  set_standard_macros ();
4559  Constituent::show_all ();
4560}
4561
4562//----------------------------------------------------------
4563void Cmt::do_show_container (const ArgParser& ap)
4564{
4565  if (ap.arguments.size () == 0)
4566    {
4567      Project::show_container ();
4568    }
4569  else
4570    {
4571      for (int i = 0; i < ap.arguments.size (); i++)
4572        {
4573          const cmt_string& path_name = ap.arguments[i];
4574          if (CmtSystem::test_directory (path_name))
4575            {
4576              Project::show_container (path_name);
4577            }
4578          else
4579            {
4580              CmtMessage::warning ("No such directory: " + path_name);
4581              CmtError::set (CmtError::path_not_found, path_name);
4582            }
4583        }
4584    }
4585}
4586
4587//----------------------------------------------------------
4588void Cmt::do_show_cycles (const ArgParser& /*ap*/)
4589{
4590  set_standard_macros ();
4591  Use& use = Use::current();
4592
4593  use.show_cycles ();
4594}
4595
4596//----------------------------------------------------------
4597void Cmt::do_show_fragment (const ArgParser& ap)
4598{
4599  if (ap.arguments.size () > 0) Fragment::show (ap.arguments[0]);
4600}
4601
4602//----------------------------------------------------------
4603void Cmt::do_show_fragments (const ArgParser& /*ap*/)
4604{
4605  Fragment::show_all ();
4606}
4607
4608//----------------------------------------------------------
4609void Cmt::do_show_groups (const ArgParser& /*ap*/)
4610{
4611  Constituent::parse_all ();
4612  //  set_standard_macros ();
4613  Group::show_all ();
4614}
4615
4616//----------------------------------------------------------
4617void Cmt::do_show_include_dirs (const ArgParser& /*ap*/)
4618{
4619  cmt_string temp;
4620
4621  Use& use = Use::current();
4622
4623  set_standard_macros ();
4624
4625  if (use.include_path == "")
4626    {
4627      temp += "$(src) ";
4628    }
4629  else if (use.include_path != "none")
4630    {
4631      temp += use.include_path;
4632      temp += " ";
4633    }
4634
4635  for (int include_number = 0;
4636       include_number < use.includes.size ();
4637       include_number++)
4638    {
4639      Include& incl = use.includes[include_number];
4640
4641      if (incl.name == "") continue;
4642
4643      temp += incl.name;
4644      temp += " ";
4645    }
4646
4647  cout << temp << endl;
4648}
4649
4650//----------------------------------------------------------
4651void Cmt::do_show_language (const ArgParser& ap)
4652{
4653  if (ap.arguments.size () > 0) 
4654    {
4655      set_standard_macros ();
4656      Language::show (ap.arguments[0]);
4657    }
4658}
4659
4660//----------------------------------------------------------
4661void Cmt::do_show_languages (const ArgParser& /*ap*/)
4662{
4663  set_standard_macros ();
4664  Language::show_all ();
4665}
4666
4667//----------------------------------------------------------
4668static bool is_upperroot (const cmt_string& name)
4669{
4670  int r = name.find_last_of ("ROOT");
4671  if (r == cmt_string::npos ||
4672      (r + 4) != name.size () ||
4673      r == 0)
4674    return false;
4675  for (int i = 0; i < r; i++)
4676    if (islower (name[i])) return false;
4677  return true;
4678}
4679
4680//----------------------------------------------------------
4681void Cmt::do_show_macro (const ArgParser& ap)
4682{
4683  cmt_string target;
4684
4685  if (ap.arguments.size () > 0) target = ap.arguments[0];
4686
4687  Symbol* symbol;
4688
4689  set_standard_macros ();
4690
4691  symbol = Symbol::find (target);
4692
4693  if (symbol == 0) 
4694    {
4695      cmt_string t = " ";
4696      t += target;
4697      t += " is not defined ";
4698
4699      CmtError::set (CmtError::symbol_not_found, t);
4700
4701      return;
4702    }
4703  else
4704    {
4705      cmt_string t = target;
4706      t += " is ";
4707
4708      if ((Me.m_action == action_show_macro) ||
4709          (Me.m_action == action_show_macro_value))
4710        {
4711          if (symbol->type != Symbol::SymbolMacro)
4712            {
4713              if (symbol->type == Symbol::SymbolAction)
4714                {
4715                  t += "action";
4716                }
4717              else if (symbol->type == Symbol::SymbolSet)
4718                {
4719                  t += "set";
4720                }
4721              else if (symbol->type == Symbol::SymbolPath)
4722                {
4723                  t += "path";
4724                }
4725              else if (symbol->type == Symbol::SymbolAlias)
4726                {
4727                  t += "alias";
4728                }
4729
4730              if (!is_upperroot (symbol->name))
4731                CmtError::set (CmtError::wrong_symbol_type, t);
4732            }
4733        }
4734      else if ((Me.m_action == action_show_set) ||
4735               (Me.m_action == action_show_set_value))
4736        {
4737          if ((symbol->type != Symbol::SymbolSet) &&
4738              (symbol->type != Symbol::SymbolPath) &&
4739              (symbol->type != Symbol::SymbolAction) &&
4740              (symbol->type != Symbol::SymbolAlias))
4741            {
4742              t += "macro";
4743
4744              if (!is_upperroot (symbol->name))
4745                CmtError::set (CmtError::wrong_symbol_type, t);
4746            }
4747        }
4748      else if (
4749               ((Me.m_action == action_show_action ||
4750                 Me.m_action == action_show_action_value) &&
4751                symbol->type != Symbol::SymbolAction)
4752               ||
4753               ((Me.m_action == action_show_alias ||
4754                 Me.m_action == action_show_alias_value) &&
4755                symbol->type != Symbol::SymbolAlias)
4756               )
4757        {
4758          switch (symbol->type)
4759            {
4760            case Symbol::SymbolUndefined:
4761              t += "undefined";
4762              break;
4763            case Symbol::SymbolAction:
4764              t += "action";
4765              break;
4766            case Symbol::SymbolAlias:
4767              t += "alias";
4768              break;
4769            case Symbol::SymbolMacro:
4770              t += "macro";
4771              break;
4772            case Symbol::SymbolSetupScript:
4773              t += "setup_script";
4774              break;
4775            case Symbol::SymbolCleanupScript:
4776              t += "cleanup_script";
4777              break;
4778            case Symbol::SymbolSet:
4779              t += "set";
4780              break;
4781            case Symbol::SymbolPath:
4782              t += "path";
4783              break;
4784            default:
4785              t += "unknown";
4786              break;
4787            }
4788         
4789          CmtError::set (CmtError::wrong_symbol_type, t);
4790        }
4791    }
4792
4793  if (symbol->value_lists.size () < 1) return;
4794
4795  symbol->show_macro (ap.mode);
4796}
4797
4798//----------------------------------------------------------
4799void Cmt::do_show_macro_names (const ArgParser& ap)
4800{
4801  if (ap.arguments.size () > 0)
4802    {
4803      const cmt_string& pattern = ap.arguments[0];
4804      print_symbol_names (ap.mode, pattern);
4805    }
4806  else
4807    {
4808      print_symbol_names (ap.mode);
4809    }
4810}
4811
4812//----------------------------------------------------------
4813void Cmt::do_show_macro_value (const ArgParser& ap)
4814{
4815  do_show_macro (ap);
4816}
4817
4818//----------------------------------------------------------
4819void Cmt::do_show_macros (const ArgParser& ap)
4820{
4821  if (ap.arguments.size () > 0)
4822    {
4823      const cmt_string& pattern = ap.arguments[0];
4824      print_macros (ap.mode, pattern);
4825    }
4826  else
4827    {
4828      print_macros (ap.mode);
4829    }
4830}
4831
4832//----------------------------------------------------------
4833void Cmt::do_show_manager (const ArgParser& /*ap*/)
4834{
4835  Use& use = Use::current();
4836
4837  cout << use.manager << endl;
4838}
4839
4840//----------------------------------------------------------
4841void Cmt::do_show_packages (const ArgParser& ap)
4842{
4843  PathScanner   scanner;
4844  PackageViewer viewer;
4845
4846  if (ap.arguments.size () == 0)
4847    {
4848      Project::scan_paths (scanner, viewer);
4849    }
4850  else
4851    {
4852      for (int i = 0; i < ap.arguments.size (); i++)
4853        {
4854          const cmt_string& path_name = ap.arguments[i];
4855          if (CmtSystem::test_directory (path_name))
4856            {
4857              scanner.scan_path (path_name, viewer);
4858            }
4859          else
4860            {
4861              CmtMessage::warning ("No such directory: " + path_name);
4862              CmtError::set (CmtError::path_not_found, path_name);
4863            }
4864        }
4865    }
4866}
4867
4868//----------------------------------------------------------
4869void Cmt::do_show_path (const ArgParser& ap, ostream& out)
4870{
4871  Project::show_paths (ap.arguments, out);
4872}
4873
4874//----------------------------------------------------------
4875void Cmt::do_show_pattern (const ArgParser& ap)
4876{
4877  cmt_string name;
4878  if (ap.arguments.size () > 0) name = ap.arguments[0];
4879  Pattern::show (name);
4880}
4881
4882//----------------------------------------------------------
4883void Cmt::do_show_pattern_names (const ArgParser& /*ap*/)
4884{
4885  Pattern::show_all_names ();
4886}
4887
4888//----------------------------------------------------------
4889void Cmt::do_show_patterns (const ArgParser& /*ap*/)
4890{
4891  Pattern::show_all ();
4892}
4893
4894//----------------------------------------------------------
4895void Cmt::do_show_projects (const ArgParser& ap)
4896//void Cmt::do_show_projects (const ArgParser& /*ap*/)
4897{
4898  Project::show_all (ap.mode);
4899}
4900
4901//----------------------------------------------------------
4902void Cmt::do_show_pwd (const ArgParser& /*ap*/)
4903{
4904  cout << Me.m_current_dir << endl;
4905}
4906
4907//----------------------------------------------------------
4908void Cmt::do_show_setup (const ArgParser& ap, ostream& out)
4909//void Cmt::do_show_setup (const ArgParser& ap)
4910{
4911  out << "----------> uses" << endl;
4912  do_show_uses (ap, out);
4913  // This is temporary to ensure that Make - which runs "cmt show setup" -
4914  // does not fail for packages with unresolved uses
4915  if (CmtError::get_last_error_code () == CmtError::package_not_found)
4916    CmtError::clear ();
4917
4918  out << "----------> tags" << endl;
4919  do_show_tags (ap, out);
4920
4921  out << "----------> CMTPATH" << endl;
4922  do_show_path (ap, out);
4923}
4924
4925//----------------------------------------------------------
4926void Cmt::do_show_set (const ArgParser& ap)
4927{
4928  do_show_macro (ap);
4929}
4930
4931//----------------------------------------------------------
4932void Cmt::do_show_set_names (const ArgParser& ap)
4933{
4934  if (ap.arguments.size () > 0)
4935    {
4936      const cmt_string& pattern = ap.arguments[0];
4937      print_symbol_names (ap.mode, pattern);
4938    }
4939  else
4940    {
4941      print_symbol_names (ap.mode);
4942    }
4943}
4944
4945//----------------------------------------------------------
4946void Cmt::do_show_set_value (const ArgParser& ap)
4947{
4948  do_show_macro (ap);
4949}
4950
4951//----------------------------------------------------------
4952void Cmt::do_show_sets (const ArgParser& ap)
4953{
4954  if (ap.arguments.size () > 0)
4955    {
4956      const cmt_string& pattern = ap.arguments[0];
4957      print_macros (ap.mode, pattern);
4958    }
4959  else
4960    {
4961      print_macros (ap.mode);
4962    }
4963}
4964
4965//----------------------------------------------------------
4966void Cmt::do_show_strategies (const ArgParser& /*ap*/)
4967{
4968  Use& current_use = Use::current ();
4969
4970  Project::show_specified_strategies_for_all ();
4971
4972  Project* p = Project::get_current ();
4973
4974  /*
4975    if (p != 0) p->show ();
4976    else cout << "No current project" << endl;
4977  */
4978
4979  cout << "Build strategy     : ";
4980
4981  if (current_use.get_strategy ("BuildPrototypes"))
4982    {
4983      cout << "prototypes";
4984    }
4985  else
4986    {
4987      cout << "no_prototypes";
4988    }
4989 
4990  if (current_use.get_strategy ("InstallArea"))
4991    {
4992      cout << " with_installarea";
4993    }
4994  else
4995    {
4996      cout << " without_installarea";
4997    }
4998 
4999  cout << endl;
5000
5001  cout << "Setup strategy     : ";
5002 
5003  if (current_use.get_strategy ("SetupConfig"))
5004    {
5005      cout << "config";
5006    }
5007  else
5008    {
5009      cout << "no_config";
5010    }
5011 
5012  if (current_use.get_strategy ("SetupRoot"))
5013    {
5014      cout << " root";
5015    }
5016  else
5017    {
5018      cout << " no_root";
5019    }
5020 
5021  if (current_use.get_strategy ("SetupCleanup"))
5022    {
5023      cout << " cleanup";
5024    }
5025  else
5026    {
5027      cout << " no_cleanup";
5028    }
5029
5030  if (current_use.get_strategy ("SetupScripts"))
5031    {
5032      cout << " scripts";
5033    }
5034  else
5035    {
5036      cout << " no_scripts";
5037    }
5038
5039  cout << endl;
5040 
5041  cout << "Structure strategy : ";
5042 
5043  if (current_use.get_strategy ("VersionDirectory"))
5044    {
5045      cout << "with_version_directory";
5046    }
5047  else
5048    {
5049      cout << "without_version_directory";
5050    }
5051 
5052  cout << endl;
5053
5054  if (Me.m_current_structuring_style != default_structuring_style)
5055    {
5056      cout << "Structuring style  : ";
5057
5058      switch (Me.m_current_structuring_style)
5059        {
5060        case without_version_directory:
5061          cout << "without_version_directory";
5062          break;
5063        case with_version_directory:
5064          cout << "with_version_directory";
5065          break;
5066        }
5067
5068      cout << endl;
5069    }
5070}
5071
5072//----------------------------------------------------------
5073void Cmt::do_show_tags (const ArgParser& /*ap*/, ostream& out)
5074{
5075  Tag::TagPtrVector tags = Tag::tags ();
5076  int index;
5077
5078  set_standard_macros ();
5079
5080  for (index = 0; index < tags.size (); index++)
5081    {
5082      const Tag* tag = tags[index];
5083      if (tag != 0)
5084        {
5085          tag->show (Me.m_quiet, out);
5086        }
5087    }
5088}
5089
5090//----------------------------------------------------------
5091void Cmt::do_show_use_paths (const ArgParser& ap)
5092{
5093  const cmt_string& to_name = ap.arguments[0];
5094
5095  Use* current = &(Use::current());
5096
5097  if (!current->get_all_clients (to_name))
5098    CmtError::set (CmtError::package_not_found, to_name);
5099}
5100
5101//----------------------------------------------------------
5102void Cmt::do_show_uses (const ArgParser& ap, ostream& out)
5103//void Cmt::do_show_uses (const ArgParser& /*ap*/, ostream& out)
5104{
5105  Use::show_all (false, out, ap.mode);
5106  //  Use::show_all (false, out);
5107}
5108
5109//----------------------------------------------------------
5110void Cmt::do_show_version (const ArgParser& /*ap*/)
5111{
5112  cout << Me.m_current_version << endl;
5113}
5114
5115//----------------------------------------------------------
5116void Cmt::do_show_versions (const ArgParser& ap)
5117{
5118  cmt_string package_name;
5119
5120  if (ap.arguments.size () > 0) package_name = ap.arguments[0];
5121
5122  PathScanner scanner;
5123
5124  Project::scan_paths_for_package (scanner, package_name);
5125}
5126
5127//----------------------------------------------------------
5128void Cmt::do_show_system (const ArgParser& /*ap*/)
5129{
5130  cout << CmtSystem::get_cmt_config () << endl;
5131}
5132
5133//----------------------------------------------------------
5134void Cmt::do_unlock (const ArgParser& /*ap*/)
5135{
5136  const cmt_string& package = Me.m_current_package;
5137  const cmt_string& version = Me.m_current_version;
5138  const cmt_string& path    = Me.m_current_path;
5139
5140  // (unused??) Use& use = Use::current();
5141
5142  CmtMessage::info ("try to unlock package " + package + " in " + CmtSystem::pwd ());
5143  //  cerr << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
5144
5145  set_standard_macros ();
5146
5147  CmtLock::status status = CmtLock::unlock ();
5148}
5149
5150//----------------------------------------------------------
5151void Cmt::do_version (const ArgParser& /*ap*/)
5152{
5153  cout << CMTVERSION << endl;
5154}
5155
5156
5157
5158//----------------------------------------------------------
5159ActionType Cmt::get_action ()
5160{
5161  return (Me.m_action);
5162}
5163
5164/*
5165  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
5166  {
5167  return (Me.m_cmt_path);
5168  }
5169
5170  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_pwds ()
5171  {
5172  return (Me.m_cmt_path_pwds);
5173  }
5174
5175  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_sources ()
5176  {
5177  return (Me.m_cmt_path_sources);
5178  }
5179*/
5180
5181const cmt_string& Cmt::get_cmt_home ()
5182{
5183  return (Me.m_cmt_home);
5184}
5185
5186const cmt_string& Cmt::get_cmt_user_context ()
5187{
5188  return (Me.m_cmt_user_context);
5189}
5190
5191const cmt_string& Cmt::get_cmt_version ()
5192{
5193  return (Me.m_cmt_version);
5194}
5195
5196const cmt_string& Cmt::get_current_dir ()
5197{
5198  return (Me.m_current_dir);
5199}
5200
5201const cmt_string Cmt::get_current_dir_real ()
5202{
5203  cmt_string current_dir_real;
5204  if (CmtSystem::realpath_ (Me.m_current_dir, current_dir_real))
5205    return current_dir_real;
5206  return (Me.m_current_dir);
5207}
5208
5209const cmt_string& Cmt::get_current_package ()
5210{
5211  return (Me.m_current_package);
5212}
5213
5214const cmt_string& Cmt::get_current_path ()
5215{
5216  return (Me.m_current_path);
5217}
5218
5219const cmt_string& Cmt::get_current_cmtpath ()
5220{
5221  return (Me.m_current_cmtpath);
5222}
5223
5224const cmt_string& Cmt::get_current_offset ()
5225{
5226  return (Me.m_current_offset);
5227}
5228
5229AccessMode Cmt::get_current_access ()
5230{
5231  return (Me.m_current_access);
5232}
5233
5234CmtStructuringStyle Cmt::get_current_structuring_style ()
5235{
5236  return (Me.m_current_structuring_style);
5237}
5238
5239CmtDirStyle Cmt::get_current_style ()
5240{
5241  return (Me.m_current_style);
5242}
5243
5244const cmt_string& Cmt::get_current_version ()
5245{
5246  return (Me.m_current_version);
5247}
5248
5249const cmt_string& Cmt::get_current_target ()
5250{
5251  return (Me.m_current_target);
5252}
5253
5254bool Cmt::get_debug ()
5255{
5256  return (Me.m_debug);
5257}
5258
5259bool Cmt::get_quiet ()
5260{
5261  return (Me.m_quiet);
5262}
5263
5264bool Cmt::get_disable_warnings ()
5265{
5266  return (Me.m_disable_warnings);
5267}
5268
5269bool Cmt::get_warnings ()
5270{
5271  return (Me.m_warnings);
5272}
5273
5274bool Cmt::get_recursive ()
5275{
5276  return (Me.m_recursive);
5277}
5278
5279CmtScopeFilteringMode Cmt::get_scope_filtering_mode ()
5280{
5281  if (Me.m_scope_filtering_mode == default_filtering_mode)
5282    {
5283      return (block_private_uses);
5284    }
5285  else
5286    {
5287      return (Me.m_scope_filtering_mode);
5288    }
5289}
5290
5291//----------------------------------------------------------
5292bool Cmt::get_all_sets_done ()
5293{
5294  return (Me.m_all_sets_done);
5295}
5296
5297//----------------------------------------------------------
5298void Cmt::get_cmt_flags (CmtSystem::cmt_string_vector& flags)
5299{
5300  CmtSystem::split (CmtSystem::getenv ("CMTFLAGS"), " \t", flags);
5301}
5302
5303//----------------------------------------------------------
5304cmt_string Cmt::get_cmt_flags ()
5305{
5306  return CmtSystem::getenv ("CMTFLAGS");
5307}
5308
5309//----------------------------------------------------------
5310class CmtFlagsReader : public FAwk
5311{
5312public:
5313
5314  CmtFlagsReader ()
5315  { }
5316 
5317  CmtFlagsReader (const cmt_string& pattern)
5318    : m_pattern (pattern)
5319  { m_condition = ok; }
5320 
5321  const cmt_string& get_pattern () const
5322  {
5323    return (m_pattern);
5324  }
5325 
5326  const cmt_string& get_cmt_flags () const
5327  {
5328    return (m_cmt_flags);
5329  }
5330 
5331  void filter (const cmt_string& line)
5332  {
5333    int p (line.find (m_pattern));
5334    if (p == cmt_string::npos) return;
5335    if (m_cmt_flags.size () != 0)
5336      m_cmt_flags += " " + line.substr (p + m_pattern.size ());
5337    else
5338      m_cmt_flags = line.substr (p + m_pattern.size ());
5339    //stop ();
5340  }
5341 
5342private:
5343  const cmt_string m_pattern;
5344  cmt_string m_cmt_flags;
5345};
5346
5347//----------------------------------------------------------
5348cmt_string Cmt::get_cmt_flags (const cmt_string& file_name)
5349{
5350  cmt_string result;
5351  CmtFlagsReader reader ("CMTFLAGS:");
5352  Awk::condition c = reader.run (file_name, reader.get_pattern ());
5353  if (Awk::failed != c)
5354    result = reader.get_cmt_flags ();
5355  else
5356    CmtError::set (CmtError::file_access_error, file_name);
5357  return result;
5358}
5359
5360//----------------------------------------------------------
5361bool Cmt::set_cmt_flags (const cmt_string& cmtflags)
5362{
5363  return CmtSystem::putenv ("CMTFLAGS", cmtflags) ?
5364    true :
5365    (CmtMessage::error ("Cannot set `CMTFLAGS' to `" + cmtflags +
5366                        "' in the environment"),
5367     false) ;
5368}
5369
5370//----------------------------------------------------------
5371bool Cmt::add_cmt_flag (const cmt_string& flag)
5372{
5373  CmtSystem::cmt_string_vector flags;
5374  get_cmt_flags (flags);
5375  cmt_string cmtflags;
5376  for (int i = 0; i < flags.size (); i++)
5377    {
5378      if (flags[i] == flag) continue;
5379      if (cmtflags == "")
5380        cmtflags = flags[i]; 
5381      else
5382        cmtflags += " " + flags[i]; 
5383    }
5384
5385  if (cmtflags == "")
5386    cmtflags = flag; 
5387  else
5388    cmtflags += " " + flag; 
5389
5390  return set_cmt_flags (cmtflags);
5391}
5392
5393/**---------------------------------------------------------
5394   guess_current_project
5395
5396   if current directory is in one of the CMTPATHs, do nothing.
5397
5398   Otherwise, we want to guess the current project
5399
5400   move up in directories until cmt/project.cmt is found
5401
5402   for (;;)
5403   {
5404   if test -f ./cmt/project.cmt
5405   ok:
5406   this directory should become the first entry of the CMTPATH
5407   break
5408
5409   if (at top) break;
5410
5411   move up
5412   }
5413*/
5414void Cmt::guess_current_project ()
5415{
5416  Log;
5417
5418  log << "guess_current_project" << log_endl;
5419
5420  cmt_string here = CmtSystem::pwd ();
5421
5422  Use& use = Use::current();
5423  cmt_string current_path (Me.m_current_dir);
5424  if (use.located ())
5425    {
5426      current_path = use.real_path;
5427      CmtMessage::verbose ("Using current use real_path `" + current_path + "'");
5428    }
5429
5430  if (Project::find_in_cmt_paths (current_path) == "")
5431    //  if (Project::find_in_cmt_paths (Me.m_current_dir) == "")
5432    {
5433      if (!CmtSystem::cd (current_path))
5434        {
5435          CmtError::set (CmtError::file_access_error, current_path);
5436          CmtError::print ();
5437          return;
5438        }
5439      cmt_string project_file = "cmt";
5440      project_file += CmtSystem::file_separator ();
5441      project_file += Project::get_project_file_name ();
5442
5443      cmt_string pwd;
5444
5445      for (;;)
5446        {
5447          pwd = CmtSystem::pwd ();
5448          if (CmtSystem::test_file (project_file))
5449            {
5450              //this directory should become the first entry of the CMTPATH
5451
5452              IProjectFactory& factory = ProjectFactory::instance ();
5453              factory.create_project ("", pwd, "CurrentProject", 0);
5454
5455              break;
5456            }
5457
5458          log << "pwd=" << CmtSystem::pwd () << log_endl;
5459         
5460          if (!CmtSystem::cd (".."))
5461            {
5462              log << "Cannot cd up..." << log_endl;
5463              break;
5464            }
5465
5466          if (CmtSystem::pwd () == pwd)
5467            {
5468              log << "Looks the same pwd..." << log_endl;
5469              break;
5470            }
5471        }
5472
5473      CmtSystem::cd (Me.m_current_dir);
5474    }
5475
5476  //cmt_string buffer = "path CMTPATH \n";
5477  cmt_string buffer;
5478  Project::fill_cmtpaths (buffer);
5479  //cerr << "buffer = " << buffer << endl;
5480  //  Use& use = Use::current();
5481
5482  bool save_quiet = Me.m_quiet;
5483  Me.m_quiet = true;
5484
5485  SyntaxParser::parse_requirements_text (buffer, "", &use);
5486
5487  Me.m_quiet = save_quiet;
5488
5489  Me.m_autoconfigure_cmtpath = true;
5490
5491  CmtSystem::cd (here);
5492}
5493
5494//----------------------------------------------------------
5495const cmt_string& Cmt::filter_dir (const cmt_string& dir)
5496{
5497  static cmt_string newdir;
5498
5499  CmtSystem::compress_path (dir, newdir);
5500
5501  return (newdir);
5502}
5503
5504//----------------------------------------------------------
5505static void dos_script_prefix (FILE* f, 
5506                               const cmt_string& cmt_root, 
5507                               const cmt_string& package, 
5508                               const cmt_string& mangled_package, 
5509                               const cmt_string& version, 
5510                               const cmt_string& path, 
5511                               const cmt_string& action, 
5512                               const cmt_string& option = "")
5513{
5514  cmt_string no_device = path;
5515
5516  if (CmtSystem::absolute_path (path)) 
5517    {
5518      if (path[1] == ':')
5519        {
5520          no_device = path.substr (2);
5521        }
5522    }
5523
5524  if (package == "cmt_standalone")
5525    {
5526      no_device = "";
5527    }
5528  else
5529    {
5530      no_device = "..\\..\\..";
5531      if (Cmt::get_current_structuring_style () == without_version_directory)
5532        //      if (Cmt::get_current_style () == no_version_style)
5533        {
5534          no_device = "..\\..";
5535        }
5536    }
5537
5538
5539  fprintf (f, "@echo off\n");
5540  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 ());
5541  fprintf (f, "\n");
5542  fprintf (f, "set cmt%stempfile=\"%%TEMP%%\\cmt%stempfile.bat\"\n", mangled_package.c_str (), mangled_package.c_str ());
5543  fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe %s -bat "
5544           " -pack=%s -version=%s -path=\"%%~d0%%~p0%s\" "
5545           " %s "
5546           "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%cmt%stempfile%%\n",
5547           action.c_str (),
5548           package.c_str (),
5549           version.c_str (),
5550           no_device.c_str (),
5551           option.c_str (), mangled_package.c_str ());
5552  fprintf (f, "if exist %%cmt%stempfile%% call %%cmt%stempfile%%\n", mangled_package.c_str (), mangled_package.c_str ());
5553  fprintf (f, "if exist %%cmt%stempfile%% del %%cmt%stempfile%%\n", mangled_package.c_str (), mangled_package.c_str ());
5554  fprintf (f, "set cmt%stempfile=\n", mangled_package.c_str ());
5555}
5556
5557//----------------------------------------------------------
5558void Cmt::install_cleanup_scripts ()
5559{
5560#ifdef WIN32
5561  static const int modes = 1;
5562  static const cmt_string suffix[1]   = {"bat"};
5563  static const PrintMode  mode[1]     = {Bat};
5564#else
5565  static const int modes = 2;
5566  static const cmt_string suffix[2]   = {"csh", "sh"};
5567  static const PrintMode  mode[2]     = {Csh, Sh};
5568#endif
5569
5570  Use& current_use = Use::current ();
5571
5572  if (!current_use.get_strategy ("SetupScripts"))
5573    {
5574      for (int i = 0; i < modes; i++)
5575        {
5576          cmt_string old_file_name = "cleanup";
5577          old_file_name += ".";
5578          old_file_name += suffix[i];
5579          if (CmtSystem::test_file (old_file_name))
5580            {
5581              if (CmtMessage::active (Error))
5582                cerr << "Removing cleanup script " + old_file_name << endl;
5583              CmtSystem::remove_file (old_file_name);
5584            }
5585        }
5586      return;
5587    }
5588
5589  if (CmtMessage::active (Error))
5590    cerr << "Creating cleanup scripts." << endl;
5591
5592  cmt_string temp;
5593  int i;
5594
5595  cmt_string version = Me.m_current_version;
5596  if (version == "v*") version = "";
5597  cmt_string mangled_package = CmtSystem::mangle (Me.m_current_package);
5598
5599  for (i = 0; i < modes; i++)
5600    {
5601      cmt_string file_name = "cleanup";
5602      file_name += ".";
5603      file_name += suffix[i];
5604      file_name += ".";
5605      file_name += "new";
5606
5607      FILE* f = fopen (file_name.c_str (), "wb");
5608      if (f != NULL)
5609        {
5610          if (mode[i] == Csh)
5611            {
5612              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5613              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5614              fprintf (f, "endif\n");
5615              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5616              fprintf (f, "set cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
5617              fprintf (f, "if $status != 0 then\n  set cmt%stempfile=/tmp/cmt.$$\nendif\n", mangled_package.c_str ());
5618              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
5619                       "-pack=%s -version=%s -path=%s $* >${cmt%stempfile}\n",
5620                       suffix[i].c_str (),
5621                       Me.m_current_package.c_str (),
5622                       version.c_str (),
5623                       Me.m_current_path.c_str (), mangled_package.c_str ());
5624              fprintf (f,
5625                       "if ( $status != 0 ) then\n"
5626                       "  echo \"${CMTROOT}/mgr/cmt cleanup -%s "
5627                       "-pack=%s -version=%s -path=%s $* >${cmt%stempfile}\"\n"
5628                       "  set cmtcleanupstatus=2\n"
5629                       "  /bin/rm -f ${cmt%stempfile}\n"
5630                       "  unset cmt%stempfile\n"
5631                       "  exit $cmtcleanupstatus\n"
5632                       "endif\n"
5633                       "set cmtcleanupstatus=0\n"
5634                       "source ${cmt%stempfile}\n"
5635                       "if ( $status != 0 ) then\n"
5636                       "  set cmtcleanupstatus=2\n"
5637                       "endif\n"
5638                       "/bin/rm -f ${cmt%stempfile}\n"
5639                       "unset cmt%stempfile\n"
5640                       "exit $cmtcleanupstatus\n",
5641                       suffix[i].c_str (),
5642                       Me.m_current_package.c_str (),
5643                       version.c_str (),
5644                       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 ());
5645            }
5646          else if (mode[i] == Sh)
5647            {
5648              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5649              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5650              fprintf (f, "fi\n");
5651              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5652              fprintf (f, "cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
5653              fprintf (f, "if test ! $? = 0 ; then cmt%stempfile=/tmp/cmt.$$; fi\n", mangled_package.c_str ());
5654              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
5655                       "-pack=%s -version=%s -path=%s $* >${cmt%stempfile}\n",
5656                       suffix[i].c_str (),
5657                       Me.m_current_package.c_str (),
5658                       version.c_str (),
5659                       Me.m_current_path.c_str (), mangled_package.c_str ());
5660              fprintf (f,
5661                       "if test $? != 0 ; then\n"
5662                       "  echo >&2 \"${CMTROOT}/mgr/cmt cleanup -%s "
5663                       "-pack=%s -version=%s -path=%s $* >${cmt%stempfile}\"\n"
5664                       "  cmtcleanupstatus=2\n"
5665                       "  /bin/rm -f ${cmt%stempfile}\n"
5666                       "  unset cmt%stempfile\n"
5667                       "  return $cmtcleanupstatus\n"
5668                       "fi\n"
5669                       "cmtcleanupstatus=0\n"
5670                       ". ${cmt%stempfile}\n"
5671                       "if test $? != 0 ; then\n"
5672                       "  cmtcleanupstatus=2\n"
5673                       "fi\n"
5674                       "/bin/rm -f ${cmt%stempfile}\n"
5675                       "unset cmt%stempfile\n"
5676                       "return $cmtcleanupstatus\n",
5677                       suffix[i].c_str (),
5678                       Me.m_current_package.c_str (),
5679                       version.c_str (),
5680                       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 ());
5681            }
5682          else if (mode[i] == Bat)
5683            {
5684              dos_script_prefix (f, Me.m_cmt_root, 
5685                                 Me.m_current_package, mangled_package, version, Me.m_current_path,
5686                                 "cleanup");
5687            }
5688
5689          fprintf (f, "\n");
5690
5691          CmtSystem::close_ostream (f, file_name);
5692          //          fclose (f);
5693
5694          cmt_string old_file_name = "cleanup";
5695          old_file_name += ".";
5696          old_file_name += suffix[i];
5697
5698          CmtSystem::compare_and_update_files (file_name, old_file_name);
5699        }
5700      else
5701        {
5702          CmtError::set (CmtError::file_access_error, file_name);
5703        }
5704    }
5705}
5706
5707//----------------------------------------------------------
5708void Cmt::install_setup_scripts ()
5709{
5710#ifdef WIN32
5711  static const int modes = 1;
5712  static const cmt_string suffix[1]   = {"bat"};
5713  static const PrintMode  mode[1]     = {Bat};
5714#else
5715  static const int modes = 2;
5716  static const cmt_string suffix[2]   = {"csh", "sh"};
5717  static const PrintMode  mode[2]     = {Csh, Sh};
5718#endif
5719
5720  Use& current_use = Use::current ();
5721
5722  if (!current_use.get_strategy ("SetupScripts"))
5723    {
5724      for (int i = 0; i < modes; i++)
5725        {
5726          cmt_string old_file_name = "setup";
5727          old_file_name += ".";
5728          old_file_name += suffix[i];
5729          if (CmtSystem::test_file (old_file_name))
5730            {
5731              if (CmtMessage::active (Error))
5732                cerr << "Removing setup script " + old_file_name << endl;
5733              CmtSystem::remove_file (old_file_name);
5734            }
5735        }
5736      return;
5737    }
5738
5739  if (CmtMessage::active (Error))
5740    cerr << "Creating setup scripts." << endl;
5741 
5742  cmt_string no_cleanup_opt;
5743
5744  if (current_use.get_strategy ("SetupCleanup"))
5745    {
5746      no_cleanup_opt = " -no_cleanup";
5747    }
5748
5749  cmt_string temp;
5750  int i;
5751
5752  cmt_string version = Me.m_current_version;
5753  if (version == "v*") version = "";
5754  cmt_string mangled_package = CmtSystem::mangle (Me.m_current_package);
5755
5756  for (i = 0; i < modes; i++)
5757    {
5758      cmt_string file_name = "setup";
5759      file_name += ".";
5760      file_name += suffix[i];
5761      file_name += ".";
5762      file_name += "new";
5763
5764      FILE* f = fopen (file_name.c_str (), "wb");
5765      if (f != NULL)
5766        {
5767          if (mode[i] == Csh)
5768            {
5769              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
5770                       Me.m_current_package.c_str (),
5771                       version.c_str (),
5772                       Me.m_current_path.c_str ());
5773              fprintf (f, "\n");
5774
5775              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5776              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5777              fprintf (f, "endif\n");
5778              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5779              fprintf (f, "set cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
5780              fprintf (f, "if $status != 0 then\n  set cmt%stempfile=/tmp/cmt.$$\nendif\n", mangled_package.c_str ());
5781              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
5782                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\n",
5783                       suffix[i].c_str (),
5784                       Me.m_current_package.c_str (),
5785                       version.c_str (),
5786                       Me.m_current_path.c_str (),
5787                       no_cleanup_opt.c_str (), mangled_package.c_str ());
5788              fprintf (f,
5789                       "if ( $status != 0 ) then\n"
5790                       "  echo \"${CMTROOT}/mgr/cmt setup -%s "
5791                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\"\n"
5792                       "  set cmtsetupstatus=2\n"
5793                       "  /bin/rm -f ${cmt%stempfile}\n"
5794                       "  unset cmt%stempfile\n"
5795                       "  exit $cmtsetupstatus\n"
5796                       "endif\n"
5797                       "set cmtsetupstatus=0\n"
5798                       "source ${cmt%stempfile}\n"
5799                       "if ( $status != 0 ) then\n"
5800                       "  set cmtsetupstatus=2\n"
5801                       "endif\n"
5802                       "/bin/rm -f ${cmt%stempfile}\n"
5803                       "unset cmt%stempfile\n"
5804                       "exit $cmtsetupstatus\n",
5805                       suffix[i].c_str (),
5806                       Me.m_current_package.c_str (),
5807                       version.c_str (),
5808                       Me.m_current_path.c_str (),
5809                       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 ());
5810            }
5811          else if (mode[i] == Sh)
5812            {
5813              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
5814                       Me.m_current_package.c_str (),
5815                       version.c_str (),
5816                       Me.m_current_path.c_str ());
5817              fprintf (f, "\n");
5818
5819              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
5820              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
5821              fprintf (f, "fi\n");
5822              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
5823              fprintf (f, "cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
5824              fprintf (f, "if test ! $? = 0 ; then cmt%stempfile=/tmp/cmt.$$; fi\n", mangled_package.c_str ());
5825              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
5826                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\n",
5827                       suffix[i].c_str (),
5828                       Me.m_current_package.c_str (),
5829                       version.c_str (),
5830                       Me.m_current_path.c_str (),
5831                       no_cleanup_opt.c_str (), mangled_package.c_str ());
5832              fprintf (f,
5833                       "if test $? != 0 ; then\n"
5834                       "  echo >&2 \"${CMTROOT}/mgr/cmt setup -%s "
5835                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\"\n"
5836                       "  cmtsetupstatus=2\n"
5837                       "  /bin/rm -f ${cmt%stempfile}\n"
5838                       "  unset cmt%stempfile\n"
5839                       "  return $cmtsetupstatus\n"
5840                       "fi\n"
5841                       "cmtsetupstatus=0\n"
5842                       ". ${cmt%stempfile}\n"
5843                       "if test $? != 0 ; then\n"
5844                       "  cmtsetupstatus=2\n"
5845                       "fi\n"
5846                       "/bin/rm -f ${cmt%stempfile}\n"
5847                       "unset cmt%stempfile\n"
5848                       "return $cmtsetupstatus\n",
5849                       suffix[i].c_str (),
5850                       Me.m_current_package.c_str (),
5851                       version.c_str (),
5852                       Me.m_current_path.c_str (),
5853                       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 ());
5854            }
5855          else if (mode[i] == Bat)
5856            {
5857              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
5858                       Me.m_current_package.c_str (),
5859                       version.c_str ());
5860              dos_script_prefix (f, Me.m_cmt_root, 
5861                                 Me.m_current_package, mangled_package, version, Me.m_current_path,
5862                                 "setup", no_cleanup_opt);
5863            }
5864
5865          fprintf (f, "\n");
5866
5867          CmtSystem::close_ostream (f, file_name);
5868          //          fclose (f);
5869
5870          cmt_string old_file_name = "setup";
5871          old_file_name += ".";
5872          old_file_name += suffix[i];
5873
5874          CmtSystem::compare_and_update_files (file_name, old_file_name);
5875        }
5876      else
5877        {
5878          CmtError::set (CmtError::file_access_error, file_name);
5879        }
5880    }
5881}
5882
5883//----------------------------------------------------------
5884void Cmt::install_scripts (ScriptType type, const cmt_string& flags)
5885{
5886#ifdef WIN32
5887  static const int modes = 1;
5888  static const cmt_string suffix[1]   = {"bat"};
5889  static const PrintMode  mode[1]     = {Bat};
5890#else
5891  static const int modes = 2;
5892  static const cmt_string suffix[2]   = {"csh", "sh"};
5893  static const PrintMode  mode[2]     = {Csh, Sh};
5894#endif
5895
5896  Use& current_use = Use::current ();
5897  const cmt_string action = (SetupScript == type ? "setup" : "cleanup");
5898  if (!current_use.get_strategy ("SetupScripts"))
5899    {
5900      for (int i = 0; i < modes; i++)
5901        {
5902          cmt_string old_file_name (action);
5903          //cmt_string old_file_name = "setup";
5904          old_file_name += ".";
5905          old_file_name += suffix[i];
5906          if (CmtSystem::test_file (old_file_name))
5907            {
5908              if (CmtMessage::active (Error))
5909                cerr << "Removing " + action + " script " + old_file_name << endl;
5910              //cerr << "Removing setup script " + old_file_name << endl;
5911              CmtSystem::remove_file (old_file_name);
5912            }
5913        }
5914      return;
5915    }
5916
5917  if (CmtMessage::active (Error))
5918    cerr << "Creating " + action + " scripts." << endl;
5919  //cerr << "Creating setup scripts." << endl;
5920 
5921  cmt_string no_cleanup_opt;
5922
5923  if (SetupScript == type)
5924    if (current_use.get_strategy ("SetupCleanup"))
5925      {
5926        no_cleanup_opt = " -no_cleanup";
5927      }
5928
5929  no_cleanup_opt = flags + no_cleanup_opt;
5930
5931  cmt_string version = Me.m_current_version;
5932  if (version == "v*") version = "";
5933  cmt_string mangled_package = CmtSystem::mangle (Me.m_current_package);
5934
5935  for (int i = 0; i < modes; i++)
5936    {
5937      cmt_string file_name = action;
5938      //cmt_string file_name = "setup";
5939      file_name += ".";
5940      file_name += suffix[i];
5941      file_name += ".";
5942      file_name += "new";
5943
5944      FILE* f = fopen (file_name.c_str (), "wb");
5945      if (f != NULL)
5946        {
5947          if (mode[i] == Csh)
5948            {
5949              //fprintf (f, "# echo \"Setting %s %s in %s\"\n",
5950              fprintf (f, "# echo \"%s %s %s in %s\"\n",
5951                       action.c_str (),
5952                       Me.m_current_package.c_str (),
5953                       version.c_str (),
5954                       Me.m_current_path.c_str ());
5955              fprintf (f, "\n");
5956
5957              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
5958              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
5959              fprintf (f, "endif\n");
5960              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
5961              fprintf (f, "set cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
5962              fprintf (f, "if $status != 0 then\n  set cmt%stempfile=/tmp/cmt.$$\nendif\n", mangled_package.c_str ());
5963              //fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
5964              fprintf (f, "${CMTROOT}/mgr/cmt %s -%s "
5965                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\n",
5966                       action.c_str (),
5967                       suffix[i].c_str (),
5968                       Me.m_current_package.c_str (),
5969                       version.c_str (),
5970                       Me.m_current_path.c_str (),
5971                       no_cleanup_opt.c_str (),
5972                       mangled_package.c_str ());
5973              fprintf (f,
5974                       "if ( $status != 0 ) then\n"
5975                       "  echo \"${CMTROOT}/mgr/cmt %s -%s "
5976                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\"\n"
5977                       "  set cmt%sstatus=2\n"
5978                       "  /bin/rm -f ${cmt%stempfile}\n"
5979                       "  unset cmt%stempfile\n"
5980                       "  exit $cmt%sstatus\n"
5981                       "endif\n"
5982                       "set cmt%sstatus=0\n"
5983                       "source ${cmt%stempfile}\n"
5984                       "if ( $status != 0 ) then\n"
5985                       "  set cmt%sstatus=2\n"
5986                       "endif\n"
5987                       "/bin/rm -f ${cmt%stempfile}\n"
5988                       "unset cmt%stempfile\n"
5989                       "exit $cmt%sstatus\n",
5990                       action.c_str (),
5991                       suffix[i].c_str (),
5992                       Me.m_current_package.c_str (),
5993                       version.c_str (),
5994                       Me.m_current_path.c_str (),
5995                       no_cleanup_opt.c_str (), mangled_package.c_str (),
5996                       action.c_str (),
5997                       mangled_package.c_str (),
5998                       mangled_package.c_str (),
5999                       action.c_str (),
6000                       action.c_str (),
6001                       mangled_package.c_str (),
6002                       action.c_str (),
6003                       mangled_package.c_str (),
6004                       mangled_package.c_str (),
6005                       action.c_str ());
6006            }
6007          else if (mode[i] == Sh)
6008            {
6009              //fprintf (f, "# echo \"Setting %s %s in %s\"\n",
6010              fprintf (f, "# echo \"%s %s %s in %s\"\n",
6011                       action.c_str (),
6012                       Me.m_current_package.c_str (),
6013                       version.c_str (),
6014                       Me.m_current_path.c_str ());
6015              fprintf (f, "\n");
6016
6017              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
6018              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
6019              fprintf (f, "fi\n");
6020              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
6021              fprintf (f, "cmt%stempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n", mangled_package.c_str ());
6022              fprintf (f, "if test ! $? = 0 ; then cmt%stempfile=/tmp/cmt.$$; fi\n", mangled_package.c_str ());
6023              //fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
6024              fprintf (f, "${CMTROOT}/mgr/cmt %s -%s "
6025                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\n",
6026                       action.c_str (),
6027                       suffix[i].c_str (),
6028                       Me.m_current_package.c_str (),
6029                       version.c_str (),
6030                       Me.m_current_path.c_str (),
6031                       no_cleanup_opt.c_str (),
6032                       mangled_package.c_str ());
6033              fprintf (f,
6034                       "if test $? != 0 ; then\n"
6035                       "  echo >&2 \"${CMTROOT}/mgr/cmt %s -%s "
6036                       "-pack=%s -version=%s -path=%s %s $* >${cmt%stempfile}\"\n"
6037                       "  cmt%sstatus=2\n"
6038                       "  /bin/rm -f ${cmt%stempfile}\n"
6039                       "  unset cmt%stempfile\n"
6040                       "  return $cmt%sstatus\n"
6041                       "fi\n"
6042                       "cmt%sstatus=0\n"
6043                       ". ${cmt%stempfile}\n"
6044                       "if test $? != 0 ; then\n"
6045                       "  cmt%sstatus=2\n"
6046                       "fi\n"
6047                       "/bin/rm -f ${cmt%stempfile}\n"
6048                       "unset cmt%stempfile\n"
6049                       "return $cmt%sstatus\n",
6050                       action.c_str (),
6051                       suffix[i].c_str (),
6052                       Me.m_current_package.c_str (),
6053                       version.c_str (),
6054                       Me.m_current_path.c_str (),
6055                       no_cleanup_opt.c_str (), mangled_package.c_str (),
6056                       action.c_str (),
6057                       mangled_package.c_str (),
6058                       mangled_package.c_str (),
6059                       action.c_str (),
6060                       action.c_str (),
6061                       mangled_package.c_str (),
6062                       action.c_str (),
6063                       mangled_package.c_str (),
6064                       mangled_package.c_str (),
6065                       action.c_str ());
6066            }
6067          else if (mode[i] == Bat)
6068            {
6069              //fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
6070              fprintf (f, "rem %s %s %s in %%~d0%%~p0\n",
6071                       action.c_str (),
6072                       Me.m_current_package.c_str (),
6073                       version.c_str ());
6074              dos_script_prefix (f, Me.m_cmt_root, 
6075                                 Me.m_current_package, mangled_package, version, Me.m_current_path,
6076                                 action, no_cleanup_opt);
6077              //"setup", no_cleanup_opt);
6078            }
6079
6080          fprintf (f, "\n");
6081
6082          CmtSystem::close_ostream (f, file_name);
6083          //          fclose (f);
6084
6085          cmt_string old_file_name = action;
6086          //cmt_string old_file_name = "setup";
6087          old_file_name += ".";
6088          old_file_name += suffix[i];
6089
6090          CmtSystem::compare_and_update_files (file_name, old_file_name);
6091        }
6092      else
6093        {
6094          CmtError::set (CmtError::file_access_error, file_name);
6095        }
6096    }
6097}
6098
6099//----------------------------------------------------------
6100void Cmt::install_native_version_file ()
6101{   
6102  Use& current_use        = Use::current ();
6103  cmt_string package_name = current_use.get_package_name();
6104  cmt_string macro_name   = package_name + "_native_version";
6105  Symbol* macro           = Symbol::find (macro_name);
6106  if (macro != 0)
6107    {
6108      cmt_string value = macro->resolve_macro_value ();
6109      if (value != "")
6110        {
6111          if (CmtMessage::active (Info))
6112            cerr << "Creating native_version file." << endl;   
6113
6114          cmt_string file_name ("new.native_version.cmt");
6115          FILE* f = fopen (file_name.c_str (), "wb");
6116          if (f != NULL)
6117            {
6118              fprintf (f, "%s\n", value.c_str ());
6119              CmtSystem::close_ostream (f, file_name);
6120              //          fclose (f);
6121             
6122              CmtSystem::compare_and_update_files ("new.native_version.cmt", "native_version.cmt");
6123            }     
6124          else
6125            {
6126              CmtError::set (CmtError::file_access_error, file_name);
6127            }
6128        } 
6129    }   
6130}
6131
6132/**
6133 *    load is only called from the Windows GUI which pretends to access directly
6134 *   the internal data model.
6135 *    This is considered to be rather unsafe, and should be replaced by query functions.
6136 */
6137//bool Cmt::load (const cmt_string& path,
6138bool Cmt::load (const ArgParser& ap,
6139                const cmt_string& path,
6140                const cmt_string& package,
6141                const cmt_string& version,
6142                const cmt_string& tag_name)
6143{
6144  clear ();
6145  //  configure ();
6146  configure (ap);
6147
6148  Me.m_action  = action_load;
6149  Me.m_recursive = true;
6150
6151  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
6152    {
6153      //
6154      //  Here we want to connect to a new package, or to the current package
6155      //  but with another tag.
6156      //
6157      //   the 'package' argument may include a directory offset. Thus 'path'
6158      //  is only expected to hold the base directory.
6159      //
6160      cmt_string offset;
6161      cmt_string package_name;
6162     
6163      CmtSystem::dirname (package, offset);
6164      CmtSystem::basename (package, package_name);
6165     
6166      if (offset != "")
6167        {
6168          Me.m_current_path = path;
6169          Me.m_current_path += CmtSystem::file_separator ();
6170          Me.m_current_path += offset;
6171        }
6172      else
6173        {
6174          Me.m_current_path = path;
6175        }
6176     
6177      Me.m_current_package = package_name;
6178      Me.m_current_version = version;
6179    }
6180
6181  if (tag_name != "")
6182    {
6183      Tag* tag;
6184
6185      Tag::unmark_all ();
6186      configure_version_tag ();
6187      configure_site_tag (0);
6188      configure_uname_tag ();
6189      configure_hosttype_tag ();
6190
6191      Me.m_current_tag = tag_name;
6192
6193      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
6194
6195      tag = Tag::add (tag_name, PriorityTag, "load", 0);
6196      tag->mark ("load");
6197    }
6198
6199  /*
6200    Set to developer mode if positioned into the package
6201    (which is detected since we were able to retreive the
6202    Version, Package and Path)
6203  */
6204
6205  if ((Me.m_current_path == "") ||
6206      (Me.m_current_package == "") ||
6207      (Me.m_current_version == ""))
6208    {
6209      Me.m_current_access = UserMode;
6210    }
6211  else
6212    {
6213      Me.m_current_access = DeveloperMode;
6214    }
6215
6216  use_cmt ();
6217
6218  cmt_string dir;
6219
6220  /*
6221    Try to access the package.
6222  */
6223
6224  if (Me.m_current_path != "")
6225    {
6226      dir = Me.m_current_path;
6227    }
6228  else
6229    {
6230      dir = Me.m_default_path;
6231    }
6232
6233  if (!CmtSystem::cd (Me.m_current_path))
6234    {
6235      CmtMessage::error ("Cannot reach the directory " + Me.m_current_path);
6236      /*
6237      if (!Me.m_quiet)
6238        {
6239          cerr << "#CMT> Cannot reach the directory " <<
6240            Me.m_current_path << endl;
6241        }
6242      */
6243      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
6244      CmtSystem::cd (Me.m_current_dir);
6245
6246      return (false);
6247    }
6248
6249  dir += CmtSystem::file_separator ();
6250  dir += Me.m_current_package;
6251
6252  if (!CmtSystem::cd (Me.m_current_package))
6253    {
6254      CmtMessage::error ("Cannot reach the package " + Me.m_current_package);
6255      /*
6256      if (!Me.m_quiet)
6257        {
6258          cerr << "#CMT::load> Cannot reach the package " <<
6259            Me.m_current_package << endl;
6260        }
6261      */
6262      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
6263      CmtSystem::cd (Me.m_current_dir);
6264
6265      return (false);
6266    }
6267
6268  dir += CmtSystem::file_separator ();
6269  dir += Me.m_current_version;
6270
6271  Me.m_current_style = none_style;
6272  Me.m_current_structuring_style = without_version_directory;
6273
6274  if (!CmtSystem::cd (Me.m_current_version))
6275    {
6276      if (!CmtSystem::test_directory ("cmt"))
6277        {
6278          CmtMessage::error ("Cannot reach the version " + Me.m_current_version);
6279          /*
6280          if (!Me.m_quiet)
6281            {
6282              cerr << "#CMT> Cannot reach the version " <<
6283                Me.m_current_version << endl;
6284            }
6285          */
6286          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
6287          CmtSystem::cd (Me.m_current_dir);
6288
6289          return (false);
6290        }
6291      else
6292        {
6293          Me.m_current_style = cmt_style;
6294          Me.m_current_structuring_style = without_version_directory;
6295          //          Me.m_current_style = no_version_style;
6296        }
6297    }
6298
6299  if (CmtSystem::cd ("cmt"))
6300    {
6301      dir += CmtSystem::file_separator ();
6302      dir += "cmt";
6303      if (Me.m_current_style == none_style)
6304        {
6305          Me.m_current_style = cmt_style;
6306          Me.m_current_structuring_style = with_version_directory;
6307        }
6308    }
6309  else
6310    {
6311      /*
6312        if (!Me.m_quiet)
6313        {
6314        cerr << "Cannot reach the cmt branch" << endl;
6315        }
6316      */
6317
6318      if (CmtSystem::cd ("mgr"))
6319        {
6320          dir += CmtSystem::file_separator ();
6321          dir += "mgr";
6322          if (Me.m_current_style == none_style)
6323            {
6324              Me.m_current_style = mgr_style;
6325              Me.m_current_structuring_style = with_version_directory;
6326            }
6327        }
6328      else
6329        {
6330          CmtMessage::error ("Cannot reach the mgr branch");
6331          /*
6332          if (!Me.m_quiet)
6333            {
6334              cerr << "#CMT> Cannot reach the mgr branch" << endl;
6335            }
6336          */
6337
6338          CmtError::set (CmtError::package_not_found,
6339                         "Load> Cannot reach the mgr/cmt directory");
6340          CmtSystem::cd (Me.m_current_dir);
6341
6342          return (false);
6343        }
6344    }
6345
6346  /*
6347    Check Tag is always set up
6348  */
6349
6350  if (Me.m_current_tag == "")
6351    {
6352      char* env;
6353
6354      env = getenv (Me.m_current_config.c_str ());
6355      if (env != 0)
6356        {
6357          Tag* tag;
6358
6359          tag = Tag::add (env, PriorityConfig, "load", 0);
6360          tag->mark ("load");
6361          Me.m_current_tag = env;
6362
6363          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
6364
6365        }
6366      else
6367        {
6368          Me.m_current_tag = Me.m_cmt_config;
6369
6370          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
6371
6372        }
6373    }
6374
6375  if (Me.m_debug)
6376    {
6377      cout << "pwd = " << CmtSystem::pwd () << endl;
6378    }
6379
6380  configure_current_dir ();
6381  build_prefix (Me.m_current_package, Me.m_current_prefix);
6382  build_config (Me.m_current_prefix, Me.m_current_config);
6383
6384  Use* use = &(Use::current());
6385  use->path    = Me.m_current_path;
6386  use->set_package_name (Me.m_current_package);
6387  use->version = Me.m_current_version;
6388  use->prefix  = Me.m_current_prefix;
6389  use->done    = false;
6390  use->style   = Me.m_current_style;
6391  use->structuring_style  = Me.m_current_structuring_style;
6392
6393  /*
6394    Work on the requirements file.
6395  */
6396
6397  dir += CmtSystem::file_separator ();
6398  dir += "requirements";
6399  SyntaxParser::parse_requirements (dir, use);
6400
6401  if (CmtError::has_pending_error ()) return (false);
6402
6403  /**
6404   * See reach_current_package for an explanation of this call
6405   */
6406  Pattern::apply_all_globals ();
6407
6408  /*
6409    Select all possible tags
6410  */
6411
6412  Tag::restore_tree ();
6413
6414  return (true);
6415}
6416
6417//----------------------------------------------------------
6418bool Cmt::need_prototypes ()
6419{
6420  Use& current_use = Use::current ();
6421
6422  if (current_use.get_strategy ("BuildPrototypes")) return (true);
6423  else return (false);
6424}
6425
6426//----------------------------------------------------------
6427void Cmt::parse_arguments (ArgParser& ap)
6428{
6429  /*
6430    Decoding arguments.
6431
6432    While decoding all arguments, no requirements analysis should
6433    occur. Every new option, or parameter should be saved and
6434    used later at actual analysis time.
6435  */
6436
6437  Me.m_action = action_none;
6438
6439  restore_all_tags (0);
6440
6441#ifdef WIN32
6442  Me.m_build_nmake = true;
6443#endif
6444
6445  ap.parse ();
6446}
6447
6448//----------------------------------------------------------
6449int Cmt::parser (const cmt_string& command_line)
6450{
6451  CmtSystem::cmt_string_vector v;
6452
6453  CmtSystem::split (command_line, " \t", v);
6454
6455  int argc = v.size ();
6456
6457  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
6458
6459  int i;
6460  for (i = 0; i < argc; i++)
6461    {
6462      argv[i] = (char*) v[i].c_str ();
6463    }
6464  argv[argc] = 0;
6465
6466  int status = parser (argc, argv);
6467
6468  free (argv);
6469
6470  return (status);
6471}
6472
6473//----------------------------------------------------------
6474int Cmt::parser (int argc, char* argv[])
6475{
6476  ArgParser ap (Me);
6477 
6478  ap.argc = argc;
6479  ap.argv = argv;
6480
6481  if (argc <= 1)
6482    {
6483      do_help (ap);
6484      return 2;
6485      //      exit (0);
6486    }
6487
6488  // save CMTFLAGS
6489  cmt_string cmtflags (get_cmt_flags ());
6490
6491  clear ();
6492
6493  //  configure ();
6494  configure (ap);
6495
6496  CmtError::clear ();
6497
6498  /*
6499    Set private if positioned inside the package
6500    (which is detected since we were able to retreive the
6501    Version, Package and Path)
6502  */
6503
6504  if ((Me.m_current_path.size () == 0) ||
6505      (Me.m_current_package.size () == 0) ||
6506      (Me.m_current_version.size () == 0))
6507    {
6508      Me.m_current_access = UserMode;
6509    }
6510  else
6511    {
6512      Me.m_current_access = DeveloperMode;
6513    }
6514 
6515  parse_arguments (ap);
6516 
6517  if (ap.help_action == action_help)
6518    {
6519      int code (0);
6520      if (CmtError::has_pending_error ())
6521        {
6522          code = CmtError::get_last_error_code ();
6523          CmtError::print ();
6524        }
6525      do_help (ap);
6526      return code;
6527    }
6528
6529  if (Me.m_debug)
6530    {
6531      cout << "After parse_argument> pack=" << Me.m_current_package
6532           << " Me.m_current_tag=" << Me.m_current_tag
6533           << " cwd=" << CmtSystem::pwd () 
6534           << " mode=" << Me.m_current_access
6535           << endl;
6536    }
6537
6538  if (Me.m_configure_error != "")
6539    {
6540      CmtMessage::error (Me.m_configure_error);
6541      //      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
6542      return (CmtError::execution_error);
6543    }
6544
6545  if (CmtError::has_pending_error ())
6546    {
6547      int code = CmtError::get_last_error_code ();
6548      CmtError::print ();
6549      //      if (!Me.m_quiet) CmtError::print ();
6550      clear ();
6551
6552      return (code);
6553    }
6554
6555  /*
6556    Now actual requirements analysis can take place.
6557
6558    Extra lines or files are analysed first.
6559  */
6560
6561  //  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
6562  //  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
6563
6564  //
6565  //  For some of the actions, the CMT package must be automatically
6566  //  included
6567  //
6568
6569  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
6570
6571//   if (ap.help_action == action_help)
6572//     {
6573//       do_help (ap);
6574//       int code (0);
6575//       if (CmtError::has_pending_error ())
6576//      {
6577//        code = CmtError::get_last_error_code ();
6578//        CmtError::print ();
6579//      }
6580//       return code;
6581//       //return (0);
6582//     }
6583
6584  switch (Me.m_action)
6585    {
6586      // case action_none :
6587    case action_awk :
6588    case action_broadcast :
6589    case action_build_constituent_makefile :
6590    case action_build_constituent_config :
6591    case action_build_constituents_makefile :
6592    case action_build_constituents_config :
6593    case action_build_broadcast_config :
6594    case action_build_dependencies :
6595    case action_build_library_links :
6596    case action_build_make_setup :
6597    case action_build_msdev :
6598    case action_build_CMT_pacman :
6599    case action_build_vsnet :     
6600    case action_build_os9_makefile :
6601      // case action_build_prototype :
6602    case action_build_readme :
6603    case action_build_tag_makefile :
6604      // case action_build_temporary_name :
6605    case action_build_triggers :
6606    case action_build_windefs :
6607    case action_check_configuration :
6608      // case action_check_files :
6609      // case action_check_version :
6610    case action_checkout :
6611    case action_cleanup :
6612    case action_config :
6613    case action_create :
6614      // case action_create_project :
6615    case action_cvsbranches :
6616    case action_cvssubpackages :
6617    case action_cvssubprojects :
6618    case action_cvstags :
6619    case action_do :
6620    case action_expand_model :
6621    case action_filter :
6622      // case action_help :
6623    case action_load :
6624    case action_lock :
6625    case action_relocate:
6626    case action_remove :
6627    case action_remove_library_links :
6628    case action_run :
6629    case action_run_sequence :
6630    case action_set_version :
6631    case action_set_versions :
6632    case action_setup :
6633    case action_show_action :
6634    case action_show_action_names :
6635    case action_show_action_value :
6636    case action_show_actions :
6637    case action_show_alias :
6638    case action_show_alias_names :
6639    case action_show_alias_value :
6640    case action_show_aliases :
6641    case action_show_all_tags :
6642    case action_show_applied_patterns :
6643      // case action_show_author :
6644      // case action_show_branches :
6645      // case action_show_clients :
6646    case action_show_cmtpath_patterns :
6647    case action_show_constituent :
6648    case action_show_constituent_names :
6649    case action_show_constituents :
6650    case action_show_container :
6651    case action_show_cycles :
6652    case action_show_fragment :
6653    case action_show_fragments :
6654    case action_show_groups :
6655    case action_show_include_dirs :
6656    case action_show_language :
6657    case action_show_languages :
6658    case action_show_macro :
6659    case action_show_macro_names :
6660    case action_show_macro_value :
6661    case action_show_macros :
6662      // case action_show_manager :
6663    case action_show_packages :
6664    case action_show_path :
6665    case action_show_pattern :
6666    case action_show_pattern_names :
6667    case action_show_patterns :
6668    case action_show_projects :
6669      // case action_show_pwd :
6670    case action_show_setup :
6671    case action_show_set :
6672    case action_show_set_names :
6673    case action_show_set_value :
6674    case action_show_sets :
6675    case action_show_strategies :
6676    case action_show_tags :
6677    case action_show_use_paths :
6678    case action_show_uses :
6679    case action_show_version :
6680      // case action_show_versions :
6681      // case action_system :
6682    case action_unlock :
6683    case action_version :
6684      if (Me.m_use_cmt)
6685        {
6686      use_cmt ();
6687        }
6688      //
6689      // Now parse the requirements file stored in ${CMTHOME}
6690      //
6691     
6692      use_home_requirements ();
6693
6694      configure_devenv_tag ();
6695
6696      break;
6697    default:
6698      break;
6699    }
6700
6701  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
6702
6703  //
6704  // Setting up recursive actions
6705  //
6706
6707  switch (Me.m_action)
6708    {
6709      // case action_none :
6710    case action_awk :
6711    case action_broadcast :
6712    case action_build_constituent_makefile :
6713    case action_build_constituent_config :
6714    case action_build_constituents_makefile :
6715    case action_build_constituents_config :
6716    case action_build_broadcast_config :
6717    case action_build_dependencies :
6718    case action_build_library_links :
6719    case action_build_make_setup :
6720    case action_build_msdev :
6721    case action_build_CMT_pacman :
6722    case action_build_vsnet :     
6723    case action_build_os9_makefile :
6724      // case action_build_prototype :
6725    case action_build_readme :
6726    case action_build_tag_makefile :
6727      // case action_build_temporary_name :
6728    case action_build_triggers :
6729    case action_build_windefs :
6730    case action_check_configuration :
6731      // case action_check_files :
6732      // case action_check_version :
6733      // case action_checkout :
6734    case action_cleanup :
6735    case action_config :
6736      // case action_create :
6737      // case action_create_project :
6738      // case action_cvsbranches :
6739      // case action_cvssubpackages :
6740      // case action_cvssubprojects :
6741      // case action_cvstags :
6742    case action_do :
6743    case action_expand_model :
6744    case action_filter :
6745      // case action_help :
6746    case action_load :
6747      // case action_lock :
6748      // case action_remove :
6749    case action_relocate:
6750    case action_remove_library_links :
6751    case action_run :
6752    case action_run_sequence :
6753      // case action_set_version :
6754    case action_set_versions :
6755    case action_setup :
6756    case action_show_action :
6757    case action_show_action_names :
6758    case action_show_action_value :
6759    case action_show_actions :
6760    case action_show_alias :
6761    case action_show_alias_names :
6762    case action_show_alias_value :
6763    case action_show_aliases :
6764    case action_show_all_tags :
6765    case action_show_applied_patterns :
6766      // case action_show_author :
6767      // case action_show_branches :
6768      // case action_show_clients :
6769    case action_show_cmtpath_patterns :
6770    case action_show_constituent :
6771    case action_show_constituent_names :
6772    case action_show_constituents :
6773    case action_show_container :
6774    case action_show_cycles :
6775    case action_show_fragment :
6776    case action_show_fragments :
6777    case action_show_groups :
6778    case action_show_include_dirs :
6779    case action_show_language :
6780    case action_show_languages :
6781    case action_show_macro :
6782    case action_show_macro_names :
6783    case action_show_macro_value :
6784    case action_show_macros :
6785      // case action_show_manager :
6786    case action_show_packages :
6787    case action_show_path :
6788    case action_show_pattern :
6789    case action_show_pattern_names :
6790    case action_show_patterns :
6791    case action_show_projects :
6792      // case action_show_pwd :
6793    case action_show_setup :
6794    case action_show_set :
6795    case action_show_set_names :
6796    case action_show_set_value :
6797    case action_show_sets :
6798    case action_show_strategies :
6799    case action_show_tags :
6800    case action_show_use_paths :
6801    case action_show_uses :
6802      // case action_show_version :
6803      // case action_show_versions :
6804      // case action_system :
6805      // case action_unlock :
6806      // case action_version :
6807      Me.m_recursive = true;
6808      break;
6809    default:
6810      Me.m_recursive = false;
6811      break;
6812    }
6813
6814  //
6815  //  Actions for which the context of the package is checked,
6816  //  and the requirements file is analysed.
6817  //
6818
6819  switch (Me.m_action)
6820    {
6821    case action_none :
6822    case action_awk :
6823    case action_broadcast :
6824    case action_build_constituent_makefile :
6825    case action_build_constituent_config :
6826    case action_build_constituents_makefile :
6827    case action_build_constituents_config :
6828    case action_build_broadcast_config :
6829    case action_build_dependencies :
6830    case action_build_library_links :
6831    case action_build_make_setup :
6832    case action_build_msdev :
6833    case action_build_CMT_pacman :
6834    case action_build_vsnet :     
6835    case action_build_os9_makefile :
6836      // case action_build_prototype :
6837    case action_build_readme :
6838    case action_build_tag_makefile :
6839      // case action_build_temporary_name :
6840    case action_build_triggers :
6841    case action_build_windefs :
6842    case action_check_configuration :
6843      // case action_check_files :
6844      // case action_check_version :
6845      // case action_checkout :
6846    case action_cleanup :
6847    case action_config :
6848      // case action_create :
6849      // case action_create_project :
6850      // case action_cvsbranches :
6851      // case action_cvssubpackages :
6852      // case action_cvssubprojects :
6853      // case action_cvstags :
6854    case action_do :
6855    case action_expand_model :
6856    case action_filter :
6857      // case action_help :
6858    case action_load :
6859    case action_lock :
6860      // case action_remove :
6861    case action_relocate :
6862    case action_remove_library_links :
6863    case action_run :
6864      // case action_run_sequence :
6865      // case action_set_version :
6866    case action_set_versions :
6867    case action_setup :
6868    case action_show_action :
6869    case action_show_action_names :
6870    case action_show_action_value :
6871    case action_show_actions :
6872    case action_show_alias :
6873    case action_show_alias_names :
6874    case action_show_alias_value :
6875    case action_show_aliases :
6876    case action_show_all_tags :
6877    case action_show_applied_patterns :
6878    case action_show_author :
6879    case action_show_branches :
6880      // case action_show_clients :
6881    case action_show_cmtpath_patterns :
6882    case action_show_constituent :
6883    case action_show_constituent_names :
6884    case action_show_constituents :
6885    case action_show_container :
6886    case action_show_cycles :
6887    case action_show_fragment :
6888    case action_show_fragments :
6889    case action_show_groups :
6890    case action_show_include_dirs :
6891    case action_show_language :
6892    case action_show_languages :
6893    case action_show_macro :
6894    case action_show_macro_names :
6895    case action_show_macro_value :
6896    case action_show_macros :
6897    case action_show_manager :
6898    case action_show_packages :
6899    case action_show_path :
6900    case action_show_pattern :
6901    case action_show_pattern_names :
6902    case action_show_patterns :
6903    case action_show_projects :
6904    case action_show_project_author :
6905    case action_show_pwd :
6906    case action_show_setup :
6907    case action_show_set :
6908    case action_show_set_names :
6909    case action_show_set_value :
6910    case action_show_sets :
6911    case action_show_strategies :
6912    case action_show_tags :
6913    case action_show_use_paths :
6914    case action_show_uses :
6915    case action_show_version :
6916      // case action_show_versions :
6917      // case action_system :
6918    case action_unlock :
6919      // case action_version :
6920      {
6921        bool w = Me.m_warnings;
6922        Me.m_warnings = false;
6923        if (strlen (ap.extra_file.c_str ()) == 0)
6924          reach_current_package ();
6925        else
6926          use_extra_file (ap.extra_file);
6927        use_user_context_requirements ();
6928        if (strlen (ap.extra_line.c_str ()) > 0)
6929          SyntaxParser::parse_requirements_text (ap.extra_line, "extra statement(s)", (Use*) 0);
6930        Me.m_warnings = w;
6931        //if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, &(Use::current ()));
6932      }
6933      break;
6934    default:
6935      break;
6936    }
6937
6938  //
6939  // Set auto_imports
6940  //
6941
6942  Use::UsePtrVector uses;
6943  Use* use (0);
6944  use = Use::find (CmtSystem::get_home_package ());
6945  if (use != 0 && !use->discarded && !use->m_hidden && use->located ())
6946    uses.push_back (use);
6947  uses.push_back (&(Use::current()));
6948  use = Use::find (CmtSystem::get_user_context_package ());
6949  if (use != 0 && !use->discarded && !use->m_hidden && use->located ())
6950    uses.push_back (use);
6951
6952  cmt_map <Use*, bool> visited;
6953  for (int i = 0; i < uses.size (); i++)
6954    //for (int i = uses.size () - 1; i >= 0; i--)
6955    {
6956      Use* use = uses[i];
6957      use->set_auto_imports (use->auto_imports, use->auto_imports, visited);
6958    }
6959
6960  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
6961
6962  //
6963  // Perform some actions even if there is an error
6964  //
6965
6966  if (CmtError::has_pending_error ())
6967    {
6968      int code = CmtError::get_last_error_code ();
6969      if (!Me.m_quiet) CmtError::print ();
6970
6971      switch (Me.m_action)
6972        {
6973          // case action_none :
6974          // case action_awk :
6975          // case action_broadcast :
6976        case action_build_constituent_makefile :
6977        case action_build_constituent_config :
6978        case action_build_constituents_makefile :
6979        case action_build_constituents_config :
6980        case action_build_broadcast_config :
6981        case action_build_dependencies :
6982        case action_build_library_links :
6983        case action_build_make_setup :
6984        case action_build_msdev :
6985        case action_build_CMT_pacman :
6986        case action_build_vsnet :     
6987        case action_build_os9_makefile :
6988        case action_build_prototype :
6989        case action_build_readme :
6990        case action_build_tag_makefile :
6991          // case action_build_temporary_name :
6992        case action_build_triggers :
6993        case action_build_windefs :
6994        case action_check_configuration :
6995          // case action_check_files :
6996          // case action_check_version :
6997          // case action_checkout :
6998        case action_cleanup :
6999          // case action_config :
7000          // case action_create :
7001          // case action_create_project :
7002          // case action_cvsbranches :
7003          // case action_cvssubpackages :
7004          // case action_cvssubprojects :
7005          // case action_cvstags :
7006          // case action_do :
7007          // case action_expand_model :
7008          // case action_filter :
7009          // case action_help :
7010        case action_load :
7011        case action_lock :
7012        case action_relocate :
7013        case action_remove :
7014        case action_remove_library_links :
7015          // case action_run :
7016        case action_run_sequence :
7017          // case action_set_version :
7018          // case action_set_versions :
7019        case action_setup :
7020          // case action_show_action :
7021          // case action_show_action_names :
7022          // case action_show_action_value :
7023          // case action_show_actions :
7024          // case action_show_alias :
7025          // case action_show_alias_names :
7026          // case action_show_alias_value :
7027          // case action_show_aliases :
7028          // case action_show_all_tags :
7029          // case action_show_applied_patterns :
7030          // case action_show_author :
7031          // case action_show_branches :
7032          // case action_show_clients :
7033          // case action_show_cmtpath_patterns :
7034          // case action_show_constituent :
7035          // case action_show_container :
7036          // case action_show_constituent_names :
7037          // case action_show_constituents :
7038          // case action_show_cycles :
7039          // case action_show_fragment :
7040          // case action_show_fragments :
7041          // case action_show_groups :
7042          // case action_show_include_dirs :
7043          // case action_show_language :
7044          // case action_show_languages :
7045          // case action_show_macro :
7046          // case action_show_macro_names :
7047          // case action_show_macro_value :
7048          // case action_show_macros :
7049          // case action_show_manager :
7050          // case action_show_packages :
7051          // case action_show_path :
7052          // case action_show_pattern :
7053          // case action_show_pattern_names :
7054          // case action_show_patterns :
7055          // case action_show_projects :
7056          // case action_show_pwd :
7057          // case action_show_setup :
7058          // case action_show_set :
7059          // case action_show_set_names :
7060          // case action_show_set_value :
7061          // case action_show_sets :
7062          // case action_show_strategies :
7063          // case action_show_tags :
7064          // case action_show_use_paths :
7065          // case action_show_uses :
7066          // case action_show_version :
7067          // case action_show_versions :
7068          // case action_system :
7069        case action_unlock :
7070          // case action_version :
7071          clear ();
7072          return (code);
7073        default:
7074          CmtError::clear ();
7075          break;
7076        }
7077    }
7078
7079  //
7080  // Perform actions
7081  //
7082
7083  if (!Me.m_simulation)
7084    {
7085      switch (Me.m_action)
7086        {
7087        case action_none :
7088          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
7089          break;
7090        case action_awk :
7091          do_awk (ap);
7092          break;
7093        case action_broadcast :
7094          do_broadcast (ap);
7095          break;
7096        case action_build_constituent_makefile :
7097          do_build_constituent_makefile (ap);
7098          break;
7099        case action_build_constituent_config :
7100          do_build_constituent_config (ap);
7101          break;
7102        case action_build_constituents_makefile :
7103          do_build_constituents_makefile (ap);
7104          break;
7105        case action_build_constituents_config :
7106          do_build_constituents_config (ap);
7107          break;
7108        case action_build_broadcast_config :
7109          do_build_broadcast_config (ap);
7110          break;
7111        case action_build_dependencies :
7112          do_build_dependencies (ap, argc, argv);
7113          break;
7114        case action_build_library_links :
7115          do_build_library_links (ap);
7116          break;
7117        case action_build_make_setup :
7118          do_build_make_setup (ap);
7119          break;
7120        case action_build_msdev :
7121          do_build_msdev (ap);
7122          break;
7123        case action_build_CMT_pacman :
7124          do_build_CMT_pacman (ap);
7125          break;
7126        case action_build_vsnet :     
7127          do_build_vsnet (ap);
7128          break;
7129        case action_build_os9_makefile :
7130          do_build_os9_makefile (ap);
7131          break;
7132        case action_build_prototype :
7133          do_build_prototype (ap);
7134          break;
7135        case action_build_readme :
7136          do_build_readme (ap);
7137          break;
7138        case action_build_tag_makefile :
7139          do_build_tag_makefile (ap);
7140          break;
7141        case action_build_temporary_name :
7142          do_build_temporary_name (ap);
7143          break;
7144        case action_build_triggers :
7145          do_build_triggers (ap);
7146          break;
7147        case action_build_windefs :
7148          do_build_windefs (ap);
7149          break;
7150        case action_check_configuration :
7151          do_check_configuration (ap);
7152          break;
7153        case action_check_files :
7154          do_check_files (ap);
7155          break;
7156        case action_check_version :
7157          do_check_version (ap);
7158          break;
7159        case action_checkout :
7160          do_checkout (ap);
7161          break;
7162        case action_cleanup :
7163          do_cleanup (ap);
7164          break;
7165        case action_config :
7166          do_config (ap);
7167          break;
7168        case action_create :
7169          do_create (ap);
7170          break;
7171        case action_create_project :
7172          do_create_project (ap);
7173          break;
7174        case action_cvsbranches :
7175          do_cvsbranches (ap);
7176          break;
7177        case action_cvssubpackages :
7178          do_cvssubpackages (ap);
7179          break;
7180        case action_cvssubprojects :
7181          do_cvssubprojects (ap);
7182          break;
7183        case action_cvstags :
7184          do_cvstags (ap);
7185          break;
7186        case action_do :
7187          do_do (ap);
7188          break;
7189        case action_expand_model :
7190          do_expand_model (ap);
7191          break;
7192        case action_filter :
7193          do_filter (ap);
7194          break;
7195        case action_help :
7196          do_help (ap);
7197          break;
7198        case action_load :
7199          CmtMessage::error ("action not implemented");
7200          //      cerr << "#CMT> action not implemented" << endl;
7201          break;
7202        case action_lock :
7203          do_lock (ap);
7204          break;
7205        case action_relocate :
7206          do_relocate (ap);
7207          break;
7208        case action_remove :
7209          do_remove (ap);
7210          break;
7211        case action_remove_library_links :
7212          do_remove_library_links (ap);
7213          break;
7214        case action_run :
7215          do_run (ap);
7216          break;
7217        case action_run_sequence :
7218          do_run_sequence (ap);
7219          break;
7220        case action_set_version :
7221          do_set_version (ap);
7222          break;
7223        case action_set_versions :
7224          do_set_versions (ap);
7225          break;
7226        case action_setup :
7227          do_setup (ap);
7228          break;
7229        case action_show_action :
7230          do_show_action (ap);
7231          break;
7232        case action_show_action_names :
7233          do_show_action_names (ap);
7234          break;
7235        case action_show_action_value :
7236          do_show_action_value (ap);
7237          break;
7238        case action_show_actions :
7239          do_show_actions (ap);
7240          break;
7241        case action_show_alias :
7242          do_show_alias (ap);
7243          break;
7244        case action_show_alias_names :
7245          do_show_alias_names (ap);
7246          break;
7247        case action_show_alias_value :
7248          do_show_alias_value (ap);
7249          break;
7250        case action_show_aliases :
7251          do_show_aliases (ap);
7252          break;
7253        case action_show_all_tags :
7254          do_show_all_tags (ap);
7255          break;
7256        case action_show_applied_patterns :
7257          do_show_applied_patterns (ap);
7258          break;
7259        case action_show_author :
7260          do_show_author (ap);
7261          break;
7262        case action_show_branches :
7263          do_show_branches (ap);
7264          break;
7265        case action_show_container :
7266          do_show_container (ap);
7267          break;
7268        case action_show_clients :
7269          do_show_clients (ap);
7270          break;
7271        case action_show_cmtpath_patterns :
7272          do_show_cmtpath_patterns (ap);
7273          break;
7274        case action_show_constituent :
7275          do_show_constituent (ap);
7276          break;
7277        case action_show_constituent_names :
7278          do_show_constituent_names (ap);
7279          break;
7280        case action_show_constituents :
7281          do_show_constituents (ap);
7282          break;
7283        case action_show_cycles :
7284          do_show_cycles (ap);
7285          break;
7286        case action_show_fragment :
7287          do_show_fragment (ap);
7288          break;
7289        case action_show_fragments :
7290          do_show_fragments (ap);
7291          break;
7292        case action_show_groups :
7293          do_show_groups (ap);
7294          break;
7295        case action_show_include_dirs :
7296          do_show_include_dirs (ap);
7297          break;
7298        case action_show_language :
7299          do_show_language (ap);
7300          break;
7301        case action_show_languages :
7302          do_show_languages (ap);
7303          break;
7304        case action_show_macro :
7305          do_show_macro (ap);
7306          break;
7307        case action_show_macro_names :
7308          do_show_macro_names (ap);
7309          break;
7310        case action_show_macro_value :
7311          do_show_macro_value (ap);
7312          break;
7313        case action_show_macros :
7314          do_show_macros (ap);
7315          break;
7316        case action_show_manager :
7317          do_show_manager (ap);
7318          break;
7319        case action_show_packages :
7320          do_show_packages (ap);
7321          break;
7322        case action_show_path :
7323          do_show_path (ap);
7324          break;
7325        case action_show_pattern :
7326          do_show_pattern (ap);
7327          break;
7328        case action_show_pattern_names :
7329          do_show_pattern_names (ap);
7330          break;
7331        case action_show_patterns :
7332          do_show_patterns (ap);
7333          break;
7334        case action_show_projects :
7335          do_show_projects (ap);
7336          break;
7337        case action_show_project_author :
7338          do_show_project_author (ap);
7339          break;
7340        case action_show_pwd :
7341          do_show_pwd (ap);
7342          break;
7343        case action_show_setup :
7344          do_show_setup (ap);
7345          break;
7346        case action_show_set :
7347          do_show_set (ap);
7348          break;
7349        case action_show_set_names :
7350          do_show_set_names (ap);
7351          break;
7352        case action_show_set_value :
7353          do_show_set_value (ap);
7354          break;
7355        case action_show_sets :
7356          do_show_sets (ap);
7357          break;
7358        case action_show_strategies :
7359          do_show_strategies (ap);
7360          break;
7361        case action_show_tags :
7362          do_show_tags (ap);
7363          break;
7364        case action_show_use_paths :
7365          do_show_use_paths (ap);
7366          break;
7367        case action_show_uses :
7368          do_show_uses (ap);
7369          break;
7370        case action_show_version :
7371          do_show_version (ap);
7372          break;
7373        case action_show_versions :
7374          do_show_versions (ap);
7375          break;
7376        case action_system :
7377          do_show_system (ap);
7378          break;
7379        case action_unlock :
7380          do_unlock (ap);
7381          break;
7382        case action_version :
7383          do_version (ap);
7384          break;
7385        default:
7386          CmtError::set (CmtError::syntax_error, "ParseArguments>");
7387          break;
7388        }
7389    }
7390
7391  // restore CMTFLAGS
7392  set_cmt_flags (cmtflags);
7393
7394  if (CmtError::has_pending_error ())
7395    {
7396      int code = CmtError::get_last_error_code ();     
7397      if (code == CmtError::execution_failed)
7398        {
7399          code = CmtError::get_last_execution_error();
7400        }   
7401     
7402      CmtError::print ();
7403      //      if (!Me.m_quiet) CmtError::print ();
7404      clear ();
7405      return (code);
7406    }
7407  else
7408    {
7409      clear ();
7410      return (0);
7411    }
7412}
7413
7414
7415/**
7416 * Format as one single line a set of 'setenv' statements
7417 * joined with semi-colons to form one shell command.
7418 */
7419void Cmt::print (PrintMode mode)
7420{
7421  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7422  Use& current_use = Use::current ();
7423
7424  cmt_string tag;
7425
7426  set_standard_macros ();
7427
7428  //cerr << "# current_tag=" << Me.m_current_tag << endl;
7429  //cerr << "# current_config=" << Me.m_current_config << endl;
7430
7431  if (Me.m_current_tag == "")
7432    {
7433      if (mode == Bat) tag = "%CMTCONFIG%";
7434      else tag = "${CMTCONFIG}";
7435    }
7436  else
7437    {
7438      tag = Me.m_current_tag;
7439    }
7440
7441  //
7442  //  Now check if all extra tags are still valid. Some of them
7443  //  may be discarded du to some conflict with highest priority
7444  //  tags, or with exclude statements
7445  //
7446
7447  {
7448    CmtSystem::cmt_string_vector words;
7449     
7450    cmt_string tags;
7451
7452    tags = Me.m_extra_tags;
7453     
7454    CmtSystem::split (tags, " \t,", words);
7455
7456    Me.m_extra_tags = ",";
7457     
7458    for (int i = 0; i < words.size (); i++)
7459      {
7460        Tag* tag;
7461        const cmt_string& a = words[i];
7462
7463        tag = Tag::find (a);
7464
7465        if ((tag != 0) && (tag->is_selected ()))
7466          {
7467            Me.m_extra_tags += a;
7468            Me.m_extra_tags += ",";
7469          }
7470      }
7471  }
7472
7473  if (mode == Requirements)
7474    {
7475      //do_show_tags (ap, cout);
7476      Tag::TagPtrVector tags = Tag::tags ();
7477      for (int index = 0; index < tags.size (); index++)
7478        {
7479          const Tag* tag = tags[index];
7480          if (tag != 0)
7481            {
7482              tag->show (true, cout, "apply_tag ");
7483            }
7484        }
7485    }
7486
7487  if (Me.m_debug)
7488    {
7489      cout << "Before all print contexts" << endl;
7490    }
7491
7492  if (Uses.size () > 0)
7493    {
7494      int number;
7495
7496      for (number = 0; number < Uses.size (); number++)
7497        {
7498          Use& use = *(Uses[number]);
7499
7500          if (use.discarded) continue;
7501          if (use.m_hidden) continue;
7502         
7503          print_context (use, mode, tag);
7504        }
7505    }
7506
7507  print_context (Use::current (), mode, tag);
7508
7509  if (Me.m_debug)
7510    {
7511      cout << "After all print contexts" << endl;
7512    }
7513
7514  Symbol::all_print (mode);
7515  // Script::all_print (mode);
7516
7517  if (Me.m_debug)
7518    {
7519      cout << "After all print" << endl;
7520    }
7521
7522  switch (mode)
7523    {
7524    case Xml :
7525      break;
7526    default :
7527  cout << endl;
7528      break;
7529    }
7530}
7531
7532
7533/**
7534 * Format as one single line a set of 'unsetenv' statements
7535 * joined with semi-colons to form one shell command.
7536 */
7537void Cmt::print_clean (PrintMode mode)
7538{
7539  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7540
7541  set_standard_macros ();
7542
7543  //Script::all_print_clean (mode);
7544  Symbol::all_print_clean (mode);
7545
7546  cmt_string prefix;
7547  if (0 != CmtSystem::mangle (Me.m_current_prefix, prefix))
7548    CmtMessage::verbose ("Replace " + Me.m_current_prefix + " with " + prefix);
7549
7550  switch (mode)
7551    {
7552    case Csh :
7553      if (Me.m_current_package != "CMT")
7554        {
7555          cout << "unsetenv " << prefix << "ROOT" << endl;
7556          cout << "unsetenv " << prefix << "CONFIG" << endl;
7557        }
7558      break;
7559    case Sh :
7560      if (Me.m_current_package != "CMT")
7561        {
7562          cout << "[ -z ${" << prefix << "ROOT+CMT} ] || unset " << prefix << "ROOT" << endl;
7563          cout << "[ -z ${" << prefix << "CONFIG+CMT} ] || unset " << prefix << "CONFIG" << endl;
7564          //          cout << "unset " << prefix << "ROOT" << endl;
7565          //          cout << "unset " << prefix << "CONFIG" << endl;
7566        }
7567      break;
7568    case Bat :
7569      if (Me.m_current_package != "CMT")
7570        {
7571          cout << "set " << prefix << "ROOT=" << endl;
7572          cout << "set " << prefix << "CONFIG=" << endl;
7573        }
7574      break;
7575    }
7576
7577  if (Uses.size () > 0)
7578    {
7579      int number;
7580
7581      for (number = 0; number < Uses.size (); number++)
7582        {
7583          Use* use = Uses[number];
7584
7585          if (use->discarded) continue;
7586          if (use->m_hidden) continue;
7587
7588          Package* p = use->get_package ();
7589          if (p->is_cmt ()) continue;
7590
7591
7592          if (0 != CmtSystem::mangle (use->prefix, prefix))
7593            CmtMessage::verbose ("Replace " + use->prefix + " with " + prefix);
7594
7595          switch (mode)
7596            {
7597            case Csh :
7598              cout << "unsetenv " << prefix << "ROOT" << endl;
7599              cout << "unsetenv " << prefix << "CONFIG" << endl;
7600              break;
7601            case Sh :
7602              cout << "[ -z ${" << prefix << "ROOT+CMT} ] || unset " << prefix << "ROOT" << endl;
7603              cout << "[ -z ${" << prefix << "CONFIG+CMT} ] || unset " << prefix << "CONFIG" << endl;
7604          //              cout << "unset " << prefix << "ROOT" << endl;
7605          //              cout << "unset " << prefix << "CONFIG" << endl;
7606              break;
7607            case Bat :
7608              cout << "set " << prefix << "ROOT=" << endl;
7609              cout << "set " << prefix << "CONFIG=" << endl;
7610              break;
7611            }
7612        }
7613    }
7614
7615  switch (mode)
7616    {
7617    case Csh :
7618      cout << "unsetenv CMTEXTRATAGS" << endl;
7619      break;
7620    case Sh :
7621      cout << "[ -z ${CMTEXTRATAGS+CMT} ] || unset CMTEXTRATAGS" << endl;
7622              //      cout << "unset CMTEXTRATAGS" << endl;
7623      break;
7624    case Bat :
7625      cout << "set CMTEXTRATAGS=" << endl;
7626      break;
7627    }
7628
7629  cout << endl;
7630}
7631
7632//----------------------------------------------------------
7633void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
7634{
7635  if (use.get_package_name () == "cmt_standalone") return;
7636
7637  cmt_string fs = CmtSystem::file_separator ();
7638
7639  use.real_path.replace_all (CmtSystem::file_separator (), fs);
7640
7641  cmt_string system = CmtSystem::get_cmt_config ();
7642
7643  bool do_config = use.get_strategy ("SetupConfig");
7644  bool do_root   = use.get_strategy ("SetupRoot");
7645   
7646  cmt_string prefix (use.prefix);
7647  switch (mode)
7648    {
7649    case Requirements :
7650      break;
7651    default:
7652      if (do_config || do_root)
7653        {
7654          if (0 != CmtSystem::mangle (use.prefix, prefix))
7655            CmtMessage::verbose ("Replace " + use.prefix + " with " + prefix);
7656        }
7657      break;
7658    }
7659 
7660  switch (mode)
7661    {
7662    case Csh :
7663      if (do_root)
7664        {
7665          cout << "setenv " << prefix << "ROOT \"" <<
7666            use.get_full_path () << "\"" << endl;
7667        }
7668
7669      if (use.get_package_name () == "CMT")
7670        {
7671          cout << "setenv CMTCONFIG " << system << endl;
7672        }
7673      else
7674        {
7675          if (do_config)
7676            {
7677              cout << "setenv " << prefix << "CONFIG \"" << tag << "\"" << endl;
7678            }
7679        }
7680       
7681      break;
7682    case Sh :
7683      if (do_root)
7684        {
7685          cout << prefix << "ROOT=\"" <<
7686            use.get_full_path () << "\"; export " <<
7687            prefix << "ROOT" << endl;
7688        }
7689
7690      if (use.get_package_name () == "CMT")
7691        {
7692          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
7693        }
7694      else
7695        {
7696          if (do_config)
7697            {
7698              cout << prefix << "CONFIG=\"" <<
7699                tag << "\"; export " <<
7700                prefix << "CONFIG" << endl;
7701            }
7702        }
7703       
7704      break;
7705    case Bat :
7706      if (do_root)
7707        {
7708          cout << "set " << prefix << "ROOT=" <<
7709            CmtSystem::quote (use.get_full_path (), " \t") << endl;
7710        }
7711
7712      if (use.get_package_name () == "CMT")
7713        {
7714          cout << "set CMTCONFIG=" << system << endl;
7715        }
7716      else
7717        {
7718          if (do_config)
7719            {
7720              cout << "set " << prefix << "CONFIG=" << CmtSystem::quote (tag, " \t") << endl;
7721            }
7722        }
7723       
7724      break;
7725    case Xml :
7726      if (do_root)
7727        {
7728          cout << "<variable><name>" << prefix << "ROOT</name>"
7729               << "<value>" << use.get_full_path () << "</value></variable>";
7730        }
7731
7732      if (use.get_package_name () == "CMT")
7733        {
7734          cout << "<variable><name>CMTCONFIG</name>"
7735               << "<value>" << system << "</value></variable>";
7736        }
7737      else
7738        {
7739          if (do_config)
7740            {
7741              cout << "<variable><name>" << prefix << "CONFIG</name>"
7742                   << "<value>" << tag << "</value></variable>";
7743            }
7744        }
7745       
7746      break;
7747    case Requirements :
7748      if (do_root &&
7749          use.get_package_name () != "CMT")
7750        {
7751          cout << "set " << use.prefix << "ROOT " <<
7752            CmtSystem::quote (use.get_full_path (), " \t") << endl;
7753
7754          cmt_string name (use.prefix + "ROOT");
7755          Symbol* symbol = Symbol::find (name);
7756          if (symbol != 0) 
7757            {
7758              symbol->printed = true;
7759            }
7760          if (symbol == 0 || symbol->type != Symbol::SymbolMacro)
7761            {
7762              CmtMessage::warning
7763                (CmtError::get_error_name (CmtError::symbol_not_found)
7764                 + ": macro " + name);
7765            }
7766        }
7767
7768      if (use.get_package_name () == "CMT")
7769        {
7770          cout << "set CMTCONFIG " << system << endl;
7771        }
7772      else
7773        {
7774          if (do_config)
7775            {
7776              cout << "set " << use.prefix << "CONFIG " << CmtSystem::quote (tag, " \t") << endl;
7777            }
7778        }
7779       
7780      break;
7781    }
7782}
7783
7784/**
7785 *  Format a set of make macro definitions (one per line)
7786 * Each macro value is provided enclosed in single quotes
7787 *
7788 *  Take the macro values from the macro statements found
7789 * in recursively read requirements files.
7790 */
7791void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
7792{
7793  int number;
7794
7795  set_standard_macros ();
7796
7797  cmt_regexp expression (pattern);
7798
7799  bool has_pattern = (pattern != "");
7800
7801  for (number = 0; number < Symbol::symbol_number (); number++)
7802    {
7803      Symbol& symbol = Symbol::symbol (number);
7804
7805      if (has_pattern)
7806        {
7807          if (!expression.match (symbol.name)) continue;
7808        }
7809
7810      if (Me.m_action == action_show_macro_names)
7811        {
7812          // Only keep macros.
7813          if ((symbol.type == Symbol::SymbolSet) ||
7814              (symbol.type == Symbol::SymbolAlias) ||
7815              (symbol.type == Symbol::SymbolPath) ||
7816              (symbol.type == Symbol::SymbolAction)) continue;
7817        }
7818      else if (Me.m_action == action_show_set_names)
7819        {
7820          // Exclude macros, actions.
7821          if ((symbol.type == Symbol::SymbolMacro) ||
7822              (symbol.type == Symbol::SymbolAction)) continue;
7823        }
7824      else if (Me.m_action == action_show_action_names)
7825        {
7826          // Only keep actions.
7827          if (symbol.type != Symbol::SymbolAction) continue;
7828        }
7829      else if (Me.m_action == action_show_alias_names)
7830        {
7831          // Only keep aliases.
7832          if (symbol.type != Symbol::SymbolAlias) continue;
7833        }
7834
7835      cout << symbol.name << endl;
7836    }
7837}
7838
7839/**
7840 *  Format a set of make macro definitions (one per line)
7841 * Each macro value is provided enclosed in single quotes
7842 *
7843 *  Take the macro values from the macro statements found
7844 * in recursively read requirements files.
7845 */
7846void Cmt::print_macros (PrintMode mode, const cmt_string& pattern, ostream& out)
7847//void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
7848{
7849  int number;
7850
7851  set_standard_macros ();
7852
7853  cmt_regexp expression (pattern);
7854
7855  bool has_pattern = (pattern != "");
7856
7857  for (number = 0; number < Symbol::symbol_number (); number++)
7858    {
7859      Symbol& symbol = Symbol::symbol (number);
7860
7861      if (has_pattern)
7862        {
7863          if (!expression.match (symbol.name)) continue;
7864        }
7865
7866      if (Me.m_action == action_show_macros)
7867        {
7868          // Only keep macros.
7869          if ((symbol.type == Symbol::SymbolSet) ||
7870              (symbol.type == Symbol::SymbolAlias) ||
7871              (symbol.type == Symbol::SymbolPath) ||
7872              (symbol.type == Symbol::SymbolAction)) continue;
7873        }
7874      else if (Me.m_action == action_show_sets)
7875        {
7876          // Exclude macros.
7877          if ((symbol.type == Symbol::SymbolMacro) ||
7878              (symbol.type == Symbol::SymbolAction)) continue;
7879        }
7880      else if ((Me.m_action == action_build_tag_makefile) ||
7881               (Me.m_action == action_build_constituents_config) ||
7882               (Me.m_action == action_build_constituent_config))
7883        {
7884          // Exclude scripts and actions
7885          if ((symbol.type == Symbol::SymbolSetupScript) ||
7886              (symbol.type == Symbol::SymbolCleanupScript) ||
7887              (symbol.type == Symbol::SymbolAction)) continue;
7888        }
7889      else if (Me.m_action == action_show_actions)
7890        {
7891          if (symbol.type != Symbol::SymbolAction) continue;
7892        }
7893      else if (Me.m_action == action_show_aliases)
7894        {
7895          if (symbol.type != Symbol::SymbolAlias) continue;
7896        }
7897
7898      if (symbol.value_lists.size () < 1) continue;
7899
7900      symbol.show_macro (mode, out);
7901      //      symbol.show_macro (mode);
7902    }
7903}
7904
7905//----------------------------------------------------------
7906void Cmt::print_tabs (int tabs)
7907{
7908  while (tabs > 0)
7909    {
7910      cout << "  ";
7911      tabs--;
7912    }
7913}
7914
7915//----------------------------------------------------------
7916void Cmt::print_xml_prolog (const cmt_string& root, ostream& out)
7917{
7918  out << "<?xml version=\"1.0\" standalone=\"no\"?>" << endl;
7919  cmt_string dtd_file (Me.m_cmt_root);
7920  dtd_file += CmtSystem::file_separator ();
7921  dtd_file += "mgr";
7922  dtd_file += CmtSystem::file_separator ();
7923  dtd_file += "CMT.dtd";
7924  out << "<!DOCTYPE " + root + " SYSTEM \"" + dtd_file + "\">" << endl;
7925}
7926
7927//----------------------------------------------------------
7928int Cmt::reach_current_package ()
7929{
7930  Use& use = Use::current ();
7931  cmt_string dir;
7932
7933  if (Me.m_debug)
7934    {
7935      cout << "Cmt::reach_current_package> pwd = " 
7936           << CmtSystem::pwd () 
7937           << " path=" << Me.m_current_path
7938           << " package=" << Me.m_current_package
7939           << endl;
7940    }
7941
7942  /*
7943    Try to access the package.
7944  */
7945
7946  if (Me.m_current_package == "cmt_standalone")
7947    {
7948      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
7949        {
7950          if (!CmtSystem::cd (Me.m_current_path))
7951            {
7952              CmtError::set (CmtError::package_not_found,
7953                             "ReachCurrentPackage> Cannot reach the path directory");
7954              return (0);
7955            }
7956        }
7957
7958      if (!CmtSystem::test_file ("requirements"))
7959        {
7960          return (0);
7961        }
7962
7963      Me.m_current_structuring_style = without_version_directory;
7964    }
7965  else if (Me.m_current_package != "")
7966    {
7967      if (!use.move_to () && !use.move_to ("", true))
7968        //      if (!use.move_to ())
7969        {
7970          CmtError::set (CmtError::package_not_found,
7971                         "ReachCurrentPackage> Cannot reach the path directory");
7972          return (0);
7973        }
7974
7975      Me.m_current_path = use.real_path;
7976    }
7977  else
7978    {
7979      //
7980      // The cmt command has been given without explicit search for
7981      // a package. Thus it is expected that we are in the context of a
7982      // true package.
7983      //
7984      //  This means that there should be a requirements file visible.
7985      //
7986      //  If this is not true, we'll make a try into ../cmt and then
7987      // a last try into ../mgr
7988      //
7989
7990      if (!CmtSystem::test_file ("requirements"))
7991        {
7992          if (CmtSystem::cd ("../cmt") && 
7993              CmtSystem::test_file ("requirements"))
7994            {
7995              Me.m_current_style = cmt_style;
7996            }
7997          else if (CmtSystem::cd ("../mgr") && 
7998                   CmtSystem::test_file ("requirements"))
7999            {
8000              Me.m_current_style = mgr_style;
8001            }
8002          else
8003            {
8004              CmtMessage::error ("Cannot reach the mgr branch");
8005              /*
8006              if (!Me.m_quiet)
8007                {
8008                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
8009                }
8010              */
8011             
8012              CmtError::set (CmtError::package_not_found,
8013                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
8014              return (0);
8015            }
8016        }
8017      else
8018        Me.m_current_style = none_style;
8019
8020      dir = CmtSystem::pwd ();
8021
8022      CmtSystem::dirname (dir, Me.m_current_path);
8023      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
8024
8025      if (CmtSystem::is_version_directory (Me.m_current_version))
8026        {
8027          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
8028          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
8029          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
8030          Me.m_current_structuring_style = with_version_directory;
8031        }
8032      else
8033        {
8034          Me.m_current_package = Me.m_current_version;
8035          Me.m_current_version = "";
8036          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
8037          Me.m_current_structuring_style = without_version_directory;
8038          //          Me.m_current_style = no_version_style;
8039        }
8040
8041      use.set_package_name (Me.m_current_package);
8042      use.version = Me.m_current_version;
8043      use.path    = Me.m_current_path;
8044      use.style   = Me.m_current_style;
8045      use.structuring_style = Me.m_current_structuring_style;
8046    }
8047
8048  configure_current_dir ();
8049  build_prefix (Me.m_current_package, Me.m_current_prefix);
8050  build_config (Me.m_current_prefix, Me.m_current_config);
8051
8052  /*
8053    Check Tag is always set up
8054  */
8055
8056  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
8057
8058  if (Me.m_current_tag == "")
8059    {
8060      cmt_string env;
8061
8062      env = CmtSystem::getenv (Me.m_current_config);
8063      if (env != "")
8064        {
8065          Tag* tag;
8066
8067          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
8068          tag->mark (use.get_package_name ());
8069          //Me.m_current_tag = env;
8070
8071          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
8072
8073        }
8074    }
8075
8076  if (Me.m_debug)
8077    {
8078      cout << "pwd = " << CmtSystem::pwd () << endl;
8079    }
8080
8081  /*
8082    Work on the requirements file.
8083  */
8084
8085  if (dir != "") dir += CmtSystem::file_separator ();
8086  dir += "requirements";
8087  SyntaxParser::parse_requirements (dir, &use);
8088
8089  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
8090
8091  /**
8092   *   It would be useful to change this mechanism. Instead of
8093   *  applying all global patterns at once to all use contexts, it
8094   *  would be much better to apply it at the end of each
8095   *  requirements file parsing, and only in the context the
8096   *  appropriate Use.
8097   *
8098   *   This would avoid the current flaw which is that when a global
8099   *  pattern specifies a "private" definition, it is actually
8100   *  applied in the scope context of the Current Use and not in
8101   *  each individual Use. Therefore the private is lost.
8102   *
8103   *   However, this induces problems since some pattern definitions
8104   *  are done AFTER the use statements, which will NOT receive the
8105   *  pattern aplications.
8106   *
8107   *   Therefore it is decided to leave this "bad" mechanism until
8108   *  everybody is aware of this constraint.
8109   *
8110   *
8111   */
8112  Pattern::apply_all_globals ();
8113
8114  /*
8115    Select all possible tags
8116  */
8117
8118  Tag::restore_tree ();
8119
8120  return (1);
8121}
8122
8123//----------------------------------------------------------
8124int Cmt::use_extra_file (const cmt_string& file)
8125{
8126  if (!CmtSystem::test_file (file))
8127    {
8128      CmtError::set (CmtError::path_not_found, file);
8129      return 0;
8130    }
8131
8132  // (almost) Cmt::reach_current_package ()
8133  Use& use = Use::current ();
8134  /*
8135    Try to access the package.
8136  */
8137
8138  if (Me.m_current_package == "cmt_standalone")
8139    {
8140      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
8141        {
8142          if (!CmtSystem::cd (Me.m_current_path))
8143            {
8144              CmtError::set (CmtError::package_not_found,
8145                             "ReachCurrentPackage> Cannot reach the path directory");
8146              return (0);
8147            }
8148        }
8149      /*
8150      if (!CmtSystem::test_file ("requirements"))
8151        {
8152          return (0);
8153        }
8154      */
8155      Me.m_current_structuring_style = without_version_directory;
8156    }
8157  else if (Me.m_current_package != "")
8158    {
8159      if (!use.move_to () && !use.move_to ("", true))
8160        //      if (!use.move_to ())
8161        {
8162          CmtError::set (CmtError::package_not_found,
8163                         "ReachCurrentPackage> Cannot reach the path directory");
8164          //          return -1;
8165          return (0);
8166        }
8167
8168      Me.m_current_path = use.real_path;
8169    }
8170  else
8171    {
8172      //
8173      // The cmt command has been given without explicit search for
8174      // a package. Thus it is expected that we are in the context of a
8175      // true package.
8176      //
8177      //  This means that there should be a requirements file visible.
8178      //
8179      //  If this is not true, we'll make a try into ../cmt and then
8180      // a last try into ../mgr
8181      //
8182
8183      //...
8184    }
8185
8186  configure_current_dir ();
8187  build_prefix (Me.m_current_package, Me.m_current_prefix);
8188  build_config (Me.m_current_prefix, Me.m_current_config);
8189
8190  /*
8191    Check Tag is always set up
8192  */
8193
8194  if (Me.m_debug) cout << "use_extra_file0> current_tag=" << Me.m_current_tag << endl;
8195
8196  if (Me.m_current_tag == "")
8197    {
8198      cmt_string env;
8199
8200      env = CmtSystem::getenv (Me.m_current_config);
8201      if (env != "")
8202        {
8203          Tag* tag;
8204
8205          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
8206          tag->mark (use.get_package_name ());
8207          //Me.m_current_tag = env;
8208
8209          //if (!Me.m_quiet) cerr << "use_extra_file1> current_tag=" << Me.m_current_tag << endl;
8210
8211        }
8212    }
8213
8214  if (Me.m_debug)
8215    {
8216      cout << "pwd = " << CmtSystem::pwd () << endl;
8217    }
8218
8219  /*
8220    Work on the requirements file.
8221  */
8222
8223  SyntaxParser::parse_requirements (file, &use);
8224
8225  if (Me.m_debug) cout << "use_extra_file2> current_tag=" << Me.m_current_tag << endl;
8226
8227  /**
8228   *   It would be useful to change this mechanism. Instead of
8229   *  applying all global patterns at once to all use contexts, it
8230   *  would be much better to apply it at the end of each
8231   *  requirements file parsing, and only in the context the
8232   *  appropriate Use.
8233   *
8234   *   This would avoid the current flaw which is that when a global
8235   *  pattern specifies a "private" definition, it is actually
8236   *  applied in the scope context of the Current Use and not in
8237   *  each individual Use. Therefore the private is lost.
8238   *
8239   *   However, this induces problems since some pattern definitions
8240   *  are done AFTER the use statements, which will NOT receive the
8241   *  pattern aplications.
8242   *
8243   *   Therefore it is decided to leave this "bad" mechanism until
8244   *  everybody is aware of this constraint.
8245   *
8246   *
8247   */
8248  Pattern::apply_all_globals ();
8249
8250  /*
8251    Select all possible tags
8252  */
8253
8254  Tag::restore_tree ();
8255
8256  return (1);
8257}
8258
8259//----------------------------------------------------------
8260static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
8261                                 const cmt_string& path)
8262{
8263  static cmt_string fs = CmtSystem::file_separator ();
8264  cmt_string result;
8265
8266  /*
8267  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
8268  {
8269  */
8270
8271  //
8272  //  If there is a common prefix between
8273  //  use->real_path and pwd
8274  //  we have
8275  //  use->real_path = /<prefix>/aaa
8276  //  pwd            = /<prefix>/bbb
8277  //
8278  //  Then use->real_path may be expressed as:
8279  //  ../..../../aaa
8280  //   where ../..../../ moves up to /<prefix>
8281  //
8282  //   Then we try to find the shortest between
8283  //
8284  //     /<prefix> and ../..../..
8285  //
8286  cmt_string a = path;
8287 
8288  CmtSystem::cmt_string_vector va;
8289 
8290  va.clear ();
8291 
8292  CmtSystem::split (a, fs, va);
8293 
8294  int m = va.size ();
8295  if (pwd.size () < m) m = pwd.size ();
8296 
8297  int i;
8298 
8299  for (i = 0; i < m; i++)
8300    {
8301      const cmt_string& fa = va[i];
8302      const cmt_string& fb = pwd[i];
8303     
8304      if (fa != fb) break;
8305    }
8306 
8307  cmt_string ups = "";
8308 
8309  if (i > 0)
8310    {
8311      // We have the prefix.
8312      // if we count what remains from pwd, then
8313      // we have the number of ../ required to
8314      // move to /<prefix>
8315      int j;
8316     
8317      for (j = i; j < pwd.size (); j++)
8318        {
8319          if (j > i) ups += fs;
8320          ups += "..";
8321        }
8322
8323      for (j = i; j < va.size (); j++)
8324        {
8325          ups += fs;
8326          ups += va[j];
8327        }
8328    }
8329 
8330  //
8331  // Here ups contains the ../..../../aaa form
8332  // for the use->real_path or is empty when there
8333  // were no common prefix.
8334  //
8335 
8336  //if (ups != "")
8337  if ((ups != "") &&
8338      (ups.size () < path.size ()))
8339    {
8340      result = ups;
8341    }
8342  else
8343    {
8344      result = path;
8345    }
8346
8347  return (result);
8348}
8349
8350/**
8351 *   This completely local class holds primitive actions for building
8352 *   standard macros.
8353 */
8354class StandardMacroBuilder
8355{
8356public:
8357
8358  /**
8359   *  CMTVERSION
8360   */
8361  void fill_for_CMTVERSION ()
8362  {
8363    buffer = "macro CMTVERSION \"";
8364    buffer += CMTVERSION;
8365    buffer += "\"";
8366    apply ();
8367  }
8368
8369  StandardMacroBuilder (const cmt_string& tag,
8370                        const cmt_string& package,
8371                        const cmt_string& version,
8372                        const cmt_string& prefix,
8373                        CmtDirStyle style)
8374  {
8375    fs = CmtSystem::file_separator ();
8376    buffer = "";
8377    //pwd = CmtSystem::pwd ();
8378    //CmtSystem::split (pwd, fs, vb);
8379    current_use = &(Use::current ());
8380    current_tag = tag;
8381    current_package = package;
8382    current_version = version;
8383    current_prefix = prefix;
8384    current_style = style;
8385  }
8386
8387  void apply ()
8388  {
8389    SyntaxParser::parse_requirements_line (buffer, current_use);
8390    buffer = "";
8391  }
8392
8393  /**
8394   *   tag
8395   */
8396  void fill_for_tag ()
8397  {
8398    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
8399
8400    if (!Symbol::is_selected ("tag"))
8401      {
8402        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
8403
8404        if (current_tag == "")
8405          {
8406            buffer = "macro tag \"$(CMTCONFIG)\"";
8407          }
8408        else
8409          {
8410            buffer = "macro tag \"";
8411            buffer += current_tag;
8412            buffer += "\"";
8413          }
8414       
8415        if (tag_debug) cerr << " define tag: " << buffer << endl;
8416       
8417        apply ();
8418      }
8419  }
8420
8421  /**
8422   *   PACKAGE_ROOT
8423   */
8424  void fill_for_package ()
8425  {
8426    buffer = "macro package \"";
8427    buffer += current_package;
8428    buffer += "\"";
8429    apply ();
8430
8431    buffer = "macro version \"";
8432    buffer += current_version;
8433    buffer += "\"";
8434    apply ();
8435
8436    if (!Symbol::is_selected ("PACKAGE_ROOT"))
8437      {
8438        buffer = "macro PACKAGE_ROOT \"$(";
8439        buffer += current_prefix;
8440        buffer += "ROOT";
8441        buffer += ")\"";
8442
8443        apply ();
8444      }
8445  }
8446
8447  /**
8448   *   srcdir
8449   *   src       =$(srcdir)/
8450   *   inc
8451   *   mgrdir
8452   *   mgr       =../$(mgrdir)/
8453   *   bin
8454   *   javabin
8455   *   doc
8456   *   version
8457   *   package
8458   *
8459   *   <package>_project
8460   *   <package>_cmtpath
8461   *   <package>_offset
8462   *   package_cmtpath
8463   *   package_offset
8464   *   project
8465   *
8466   */
8467  void fill_for_branches ()
8468  {
8469    /**
8470     *    Basic macros  (src, mgr, ...)
8471     */
8472   
8473    if (current_style == none_style)
8474      {
8475        if (!Symbol::is_selected ("srcdir"))
8476          {
8477            buffer = "macro srcdir \".";
8478            buffer += "\"";
8479            apply ();
8480          }
8481
8482        if (!Symbol::is_selected ("src"))
8483          {
8484            buffer = "macro src \".";
8485            buffer += fs;
8486            buffer += "\"";
8487            apply ();
8488          }
8489
8490        if (!Symbol::is_selected ("inc"))
8491          {
8492            buffer = "macro inc \".";
8493            buffer += fs;
8494            buffer += "\"";
8495            apply ();
8496          }
8497
8498        if (!Symbol::is_selected ("doc"))
8499          {
8500            buffer = "macro doc \".";
8501            buffer += fs;
8502            buffer += "\"";
8503            apply ();
8504          }
8505
8506        if (!Symbol::is_selected ("bin"))
8507          {
8508            buffer = "macro bin \".";
8509            buffer += fs;
8510            buffer += "\"";
8511            apply ();
8512          }
8513
8514        if (!Symbol::is_selected ("javabin"))
8515          {
8516            buffer = "macro javabin \".";
8517            buffer += fs;
8518            buffer += "\"";
8519            apply ();
8520          }
8521
8522        if (!Symbol::is_selected ("mgr"))
8523          {
8524            buffer = "macro mgr \".";
8525            buffer += fs;
8526            buffer += "\"";
8527            apply ();
8528          }
8529
8530        if (!Symbol::is_selected ("BIN"))
8531          {
8532            /*
8533            buffer = "macro BIN \"";
8534            buffer += pwd;
8535            buffer += fs;
8536            buffer += "\"";
8537            apply ();
8538            */
8539            cmt_string temp = "$(bin)";
8540            Symbol::expand (temp);
8541            int len (temp.size());
8542            cmt_string atemp;
8543            if (CmtSystem::absolute_path (temp))
8544              {
8545                CmtSystem::compress_path (temp, atemp);
8546              }
8547            else
8548              {
8549                atemp = "$(PACKAGE_ROOT)";
8550                Symbol::expand (atemp);
8551                atemp += fs + temp;
8552                //atemp = pwd + fs + temp;
8553                CmtSystem::compress_path (atemp);
8554              }
8555            buffer = "macro BIN \"";
8556            buffer += atemp;
8557            buffer += "\"";
8558            apply ();
8559            if (0 != len && fs != temp[len - 1])
8560              {
8561                buffer = "macro_append bin \"";
8562                buffer += fs;
8563                buffer += "\"";
8564                apply ();
8565
8566                buffer = "macro_append BIN \"";
8567                buffer += fs;
8568                buffer += "\"";
8569                apply ();
8570              }
8571          }
8572      }
8573    else
8574      {
8575        if (!Symbol::is_selected ("srcdir"))
8576          {
8577            buffer = "macro srcdir \"..";
8578            buffer += fs;
8579            buffer += "src";
8580            buffer += "\"";
8581            apply ();
8582          }
8583       
8584        if (!Symbol::is_selected ("src"))
8585          {
8586            buffer = "macro src \"..";
8587            buffer += fs;
8588            buffer += "src";
8589            buffer += fs;
8590            buffer += "\"";
8591            apply ();
8592          }
8593       
8594        if (!Symbol::is_selected ("inc"))
8595          {
8596            buffer = "macro inc \"..";
8597            buffer += fs;
8598            buffer += "src";
8599            buffer += fs;
8600            buffer += "\"";
8601            apply ();
8602          }
8603       
8604        if (!Symbol::is_selected ("doc"))
8605          {
8606            buffer = "macro doc \"..";
8607            buffer += fs;
8608            buffer += "doc";
8609            buffer += fs;
8610            buffer += "\"";
8611            apply ();
8612          }
8613       
8614        if (!Symbol::is_selected ("bin"))
8615          {
8616            cmt_string package_tag = current_package;
8617            package_tag += "_tag";
8618
8619            buffer = "macro bin \"..";
8620            buffer += fs;
8621            buffer += "$(";
8622            buffer += package_tag;
8623            buffer += ")";
8624            buffer += fs;
8625            buffer += "\"";
8626            apply ();
8627          }
8628
8629        if (!Symbol::is_selected ("javabin"))
8630          {
8631            buffer = "macro javabin \"..";
8632            buffer += fs;
8633            buffer += "classes";
8634            buffer += fs;
8635            buffer += "\"";
8636            apply ();
8637          }
8638       
8639        if (current_style == mgr_style)
8640          {
8641            buffer = "macro mgrdir \"mgr\"";
8642            apply ();
8643
8644            buffer = "macro mgr \"..";
8645            buffer += fs;
8646            buffer += "mgr";
8647            buffer += fs;
8648            buffer += "\"";
8649            apply ();
8650          }
8651        else
8652          {
8653            buffer = "macro mgrdir \"cmt\"";
8654            apply ();
8655
8656            buffer = "macro mgr \"..";
8657            buffer += fs;
8658            buffer += "cmt";
8659            buffer += fs;
8660            buffer += "\"";
8661            apply ();
8662          }
8663
8664        if (!Symbol::is_selected ("BIN"))
8665          {
8666            /*
8667            cmt_string pardir;
8668            CmtSystem::dirname (pwd, pardir);
8669            //            buffer = "macro BIN \"$(PACKAGE_ROOT)";
8670            buffer = "macro BIN \"";
8671            buffer += pardir;
8672            buffer += fs;
8673            buffer += "$(";
8674            buffer += package_tag;
8675            buffer += ")";
8676            buffer += fs;
8677            buffer += "\"";
8678            apply ();
8679            */
8680            cmt_string temp = "$(bin)";
8681            Symbol::expand (temp);
8682            int len (temp.size());
8683            cmt_string atemp;
8684            if (CmtSystem::absolute_path (temp))
8685              {
8686                CmtSystem::compress_path (temp, atemp);
8687              }
8688            else
8689              {
8690                atemp = "$(PACKAGE_ROOT)";
8691                atemp += fs + "$(mgrdir)";
8692                Symbol::expand (atemp);
8693                atemp += fs + temp;
8694                //atemp = pwd + fs + temp;
8695                CmtSystem::compress_path (atemp);
8696              }
8697            buffer = "macro BIN \"";
8698            buffer += atemp;
8699            buffer += "\"";
8700            apply ();
8701            if (0 != len && fs != temp[len - 1])
8702              {
8703                buffer = "macro_append bin \"";
8704                buffer += fs;
8705                buffer += "\"";
8706                apply ();
8707
8708                buffer = "macro_append BIN \"";
8709                buffer += fs;
8710                buffer += "\"";
8711                apply ();
8712              }
8713          }
8714
8715        Cmt::configure_current_cmtpath ();
8716      }
8717  }
8718
8719  /**
8720   *   project
8721   */
8722  void fill_for_project ()
8723  {
8724    if (current_style == none_style) return;
8725
8726    cmt_string project_name;
8727    Project* project = Project::get_current ();
8728    if (project != 0)
8729      {
8730        project_name = project->get_name ();
8731      }
8732
8733    buffer = "macro project \"";
8734    buffer += project_name;
8735    buffer += "\"";
8736    apply ();
8737  }
8738
8739  /**
8740   *   use_requirements
8741   */
8742  void fill_for_use_requirements ()
8743  {
8744    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8745
8746    if (Uses.size () == 0) return;
8747
8748    if (!Symbol::is_selected ("use_requirements"))
8749      {
8750        buffer  = "macro use_requirements \"";
8751        buffer += "requirements ";
8752       
8753        for (int number = 0; number < Uses.size (); number++)
8754          {
8755            Use* use = Uses[number];
8756           
8757            if (use->discarded) continue;
8758            if (use->m_hidden) continue;
8759           
8760            if (use->located ())
8761              {
8762                buffer += "$(";
8763                buffer += use->get_package_name ();
8764                buffer += "_root)";
8765//                 buffer += use->prefix;
8766//                 buffer += "ROOT)";
8767               
8768                if (use->style == cmt_style)
8769                  {
8770                    buffer += fs;
8771                    buffer += "cmt";
8772                  }
8773                else if (use->style == mgr_style)
8774                  {
8775                    buffer += fs;
8776                    buffer += "mgr";
8777                  }
8778                //                else buffer += "cmt";
8779               
8780                buffer += fs;
8781                buffer += "requirements ";
8782              }
8783          }
8784       
8785        buffer += "\"";
8786       
8787        apply ();
8788      }
8789  }
8790
8791  /**
8792   *   use_includes
8793   */
8794  void fill_for_use_includes ()
8795  {
8796    Include::parse_all (&(Use::current()));
8797
8798    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8799
8800    if (Uses.size () == 0) return;
8801
8802    if (!Symbol::is_selected ("use_includes"))
8803      {
8804        buffer = "macro_append use_includes \' ";
8805       
8806        for (int number = 0; number < Uses.size (); number++)
8807          {
8808            Use* use = Uses[number];
8809           
8810            if (use->discarded) continue;
8811            if (use->m_hidden) continue;
8812
8813            Package* p = use->get_package ();
8814            if (p->is_cmt ()) continue;
8815
8816            if (Cmt::get_debug ())
8817              {
8818                cout << "fill use_includes for " << use->get_package_name () 
8819                     << " discarded=" << use->discarded
8820                     << " auto_imports=" << use->auto_imports << endl;
8821              }
8822           
8823            if (use->auto_imports == Off) continue;
8824           
8825            Include::parse_all (use);
8826
8827            use->fill_includes_macro (buffer);
8828          }
8829       
8830        buffer += "\'";
8831       
8832        apply ();
8833      }
8834  }
8835
8836  /**
8837   *   use_fincludes
8838   */
8839  void fill_for_use_fincludes ()
8840  {
8841    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8842
8843    if (Uses.size () == 0) return;
8844
8845    if (!Symbol::is_selected ("use_fincludes"))
8846      {
8847        buffer = "macro_append use_fincludes \" $(use_includes)\"";
8848        apply ();
8849      }
8850  }
8851
8852  /**
8853   *   use_stamps
8854   */
8855  void fill_for_use_stamps ()
8856  {
8857    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8858
8859    if (Uses.size () == 0) return;
8860
8861    if (!Symbol::is_selected ("use_stamps"))
8862      {
8863        /*
8864        buffer = "macro use_stamps \"";
8865        (Use::current()).fill_macro (buffer, "stamps");
8866       
8867        for (int number = 0; number < Uses.size (); number++)
8868          {
8869            Use* use = Uses[number];
8870           
8871            if (use->discarded) continue;
8872            if (use->m_hidden) continue;
8873
8874            Package* p = use->get_package ();
8875            if (p->is_cmt ()) continue;
8876           
8877            use->fill_macro (buffer, "stamps");
8878          }
8879       
8880        buffer += "\"";
8881        */
8882        Use::fill_macro_all (buffer, "stamps");
8883        apply ();
8884      }
8885  }
8886
8887  /**
8888   *   use_cflags
8889   */
8890  void fill_for_use_cflags ()
8891  {
8892    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8893
8894    if (Uses.size () == 0) return;
8895
8896    if (!Symbol::is_selected ("use_cflags"))
8897      {
8898        Use::fill_macro_all (buffer, "cflags");
8899        apply ();
8900      }
8901  }
8902
8903  /**
8904   *   use_pp_cflags
8905   */
8906  void fill_for_use_pp_cflags ()
8907  {
8908    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8909
8910    if (Uses.size () == 0) return;
8911
8912    if (!Symbol::is_selected ("use_pp_cflags"))
8913      {
8914        Use::fill_macro_all (buffer, "pp_cflags");
8915        apply ();
8916      }
8917  }
8918
8919  /**
8920   *   use_cppflags
8921   */
8922  void fill_for_use_cppflags ()
8923  {
8924    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8925
8926    if (Uses.size () == 0) return;
8927
8928    if (!Symbol::is_selected ("use_cppflags"))
8929      {
8930        Use::fill_macro_all (buffer, "cppflags");
8931        apply ();
8932      }
8933  }
8934
8935  /**
8936   *   use_pp_cppflags
8937   */
8938  void fill_for_use_pp_cppflags ()
8939  {
8940    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8941
8942    if (Uses.size () == 0) return;
8943
8944    if (!Symbol::is_selected ("use_pp_cppflags"))
8945      {
8946        Use::fill_macro_all (buffer, "pp_cppflags");
8947        apply ();
8948      }
8949  }
8950
8951  /**
8952   *   use_fflags
8953   */
8954  void fill_for_use_fflags ()
8955  {
8956    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8957
8958    if (Uses.size () == 0) return;
8959
8960    if (!Symbol::is_selected ("use_fflags"))
8961      {
8962        Use::fill_macro_all (buffer, "fflags");
8963        apply ();
8964      }
8965  }
8966
8967  /**
8968   *   use_pp_fflags
8969   */
8970  void fill_for_use_pp_fflags ()
8971  {
8972    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8973
8974    if (Uses.size () == 0) return;
8975
8976    if (!Symbol::is_selected ("use_pp_fflags"))
8977      {
8978        Use::fill_macro_all (buffer, "pp_fflags");
8979        apply ();
8980      }
8981  }
8982
8983  /**
8984   *   use_linkopts
8985   */
8986  void fill_for_use_linkopts ()
8987  {
8988    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8989
8990    if (Uses.size () == 0) return;
8991
8992    if (!Symbol::is_selected ("use_linkopts"))
8993      {
8994        Use::fill_macro_all (buffer, "linkopts");
8995        apply ();
8996      }
8997  }
8998
8999  /**
9000   *   use_libraries
9001   */
9002  void fill_for_use_libraries ()
9003  {
9004    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9005
9006    if (Uses.size () == 0) return;
9007
9008    if (!Symbol::is_selected ("use_libraries"))
9009      {
9010        buffer  = "macro use_libraries \"";
9011
9012        for (int number = 0; number < Uses.size (); number++)
9013          {
9014            Use* use = Uses[number];
9015           
9016            if (use->discarded) continue;
9017            if (use->m_hidden) continue;
9018           
9019            Package* p = use->get_package ();
9020            if (p->is_cmt ()) continue;
9021
9022            use->fill_macro (buffer, "libraries");
9023          }
9024       
9025        buffer += "\"";
9026
9027        apply ();
9028      }
9029  }
9030
9031  /**
9032   *   includes
9033   */
9034  void fill_for_includes ()
9035  {
9036    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9037
9038    if (Uses.size () == 0) return;
9039
9040    if (!Symbol::is_selected ("includes"))
9041      {
9042        buffer = "macro_append includes \' ";
9043
9044        Use& use = Use::current();
9045
9046        if (use.include_path == "")
9047          {
9048            buffer += "$(ppcmd)\"$(srcdir)\" ";
9049          }
9050        else if (use.include_path != "none")
9051          {
9052            buffer += "$(ppcmd)\"";
9053            buffer += use.include_path;
9054            buffer += "\" ";
9055          }
9056
9057        for (int include_number = 0;
9058             include_number < use.includes.size ();
9059             include_number++)
9060          {
9061            Include& incl = use.includes[include_number];
9062
9063            if (incl.name == "") continue;
9064
9065            buffer += "$(ppcmd)\"";
9066            buffer += incl.name;
9067            buffer += "\" ";
9068          }
9069       
9070        buffer += "$(use_includes)\'";
9071       
9072        apply ();
9073      }
9074  }
9075
9076  /**
9077   *   fincludes
9078   */
9079  void fill_for_fincludes ()
9080  {
9081    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9082
9083    if (Uses.size () == 0) return;
9084
9085    if (!Symbol::is_selected ("fincludes"))
9086      {
9087        buffer = "macro_append fincludes \" $(includes)\"";
9088        apply ();
9089      }
9090  }
9091
9092  /**
9093   *  Macros specific to constituents.
9094   *  This includes the compiler flags
9095   *  and fills in these macros from uses packages. This takes care
9096   *  of -no_auto_imports and -import= directives
9097   *
9098   *    <constituent>_use_linkopts
9099   *    <prefix>_<constituent>_cflags
9100   *    <prefix>_<constituent>_pp_cflags
9101   *    <prefix>_<constituent>_cppflags
9102   *    <prefix>_<constituent>_pp_cppflags
9103   *    <prefix>_<constituent>_fflags
9104   *    <prefix>_<constituent>_pp_fflags
9105   *    <constituent>linkopts
9106   *    <constituent>_GUID
9107   *    <constituent>_stamps
9108   *
9109   */
9110  void fill_for_all_constituents ()
9111  {
9112    /// First, finish the parsing of constituent parameters.
9113    if (Cmt::get_debug ())
9114      {
9115        cout << "fill_for_all_constituents>" << endl;
9116      }
9117
9118    Constituent::parse_all ();
9119
9120    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9121   
9122    const Constituent::ConstituentVector& constituents =
9123      Constituent::constituents ();
9124
9125 
9126    // Prepare the auto_imports states in a vector
9127    cmt_vector<bool> base_auto_imports_states;
9128
9129    base_auto_imports_states.resize (Uses.size ());
9130
9131    int number;
9132   
9133    for (number = 0; number < Uses.size (); number++)
9134      {
9135        Use* use = Uses[number];
9136        base_auto_imports_states[number] = (use->auto_imports != Off);
9137      }
9138   
9139    // Now scan all constituents
9140       
9141    for (number = 0; number < constituents.size (); number++)
9142      {
9143        const Constituent& constituent = constituents[number];
9144       
9145        //==== GLAST addition for vs.net ==========
9146        buffer = "macro ";
9147        buffer += constituent.name;
9148        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
9149        apply ();
9150       
9151        if (Cmt::get_debug ())
9152          {
9153            cout << "Checking " << constituent.name  << " against imports requests" << endl;
9154          }
9155        Use::UsePtrVector imports;
9156        int i;
9157       
9158        /**
9159         *  Problem for imports in constituents.
9160         *
9161         *     1) use_xxx has holes due to the corresponding
9162         *         -no_auto_imports options attached to some
9163         *        use statements (including the transitive ones)
9164         *
9165         *     2) the -import=yyy options provided to a given constituent
9166         *        should restore the appropriate holes as well as
9167         *        all transitive ones.
9168         *
9169         *     3) for use_linkopts, missing pieces must be filled at
9170         *        the right position. (for others, order is not relevant
9171         *        while transitive access is required for all)
9172         *
9173         */
9174       
9175        if (constituent.type == Document)
9176          { 
9177            continue;
9178          }
9179       
9180        if (constituent.imports.size () == 0) 
9181          {
9182            buffer = "macro_append ";
9183            buffer += constituent.name;
9184            buffer += "_use_linkopts ";
9185            buffer += " \" ";
9186           
9187            current_use->fill_macro (buffer, "linkopts");
9188           
9189            for (i = 0; i < Uses.size (); i++)
9190              {
9191                if (base_auto_imports_states[i])
9192                  {
9193                    Use* u = Uses[i];
9194                   
9195                    if (u->discarded) continue;
9196                    if (u->m_hidden) continue;
9197                   
9198                    Package* p = u->get_package ();
9199                    if (p->is_cmt ()) continue;
9200                   
9201                    u->fill_macro (buffer, "linkopts");
9202                  }
9203              }
9204            buffer += "\"";
9205            apply ();
9206           
9207            /*
9208              buffer = "macro_append ";
9209              buffer += constituent.name;
9210              buffer += "_use_linkopts ";
9211             
9212              buffer += " \" $(use_linkopts)\"";
9213              apply ();
9214            */
9215           
9216            continue;
9217          }
9218       
9219        // From here on, the constituent HAS import options.
9220       
9221        /**
9222         * Create a private copy of the state vector. This private copy
9223         * will be updated according to -import=xxx modifiers for the
9224         * current constituent.
9225         */
9226        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
9227        Use::UsePtrVector uses;
9228
9229        for (i = 0; i < constituent.imports.size (); i++)
9230          {
9231            const cmt_string& import = constituent.imports[i];
9232           
9233            //
9234            // Resolve the imported uses
9235            //
9236           
9237            int use_index = Use::find_index (import, "", "");
9238           
9239            if (use_index >= 0)
9240              {
9241                Use* u = Uses[use_index];
9242               
9243                if (u->discarded) continue;
9244                if (u->m_hidden) continue;
9245               
9246                if (Cmt::get_debug ())
9247                  {
9248                    cout << constituent.name  << " has import request " << import
9249                         << " i=" << use_index << " package=" 
9250                         << u->get_package()->get_name()
9251                         << " auto_imports=" << u->auto_imports
9252                         << " (Off=" << Off
9253                         << " On=" << On << ")"
9254                         << endl;
9255                  }
9256               
9257                Package* p = u->get_package ();
9258                if (p->is_cmt ()) continue;
9259               
9260                uses.push_back (u);
9261                //u->set_auto_imports_state (auto_imports_states, visited);
9262                //if (u->auto_imports != Off) continue;
9263                //Use::set_auto_imports_state (use_index, auto_imports_states);
9264              }
9265            else
9266              {
9267                if ((!constituent.has_target_tag &&
9268                     Me.m_action == action_build_constituents_config)
9269                    ||
9270                    (constituent.has_target_tag &&
9271                     Me.m_action == action_build_constituent_config))
9272                  CmtMessage::warning
9273                    (CmtError::get_error_name (CmtError::configuration_error)
9274                     + ": package " + import
9275                     + " cannot be imported (requested for "
9276                     + (constituent.type == Application ?
9277                        "application " : "library ")
9278                     + constituent.name +")");
9279               
9280                if (Cmt::get_debug ())
9281                  {
9282                    cout << "import [" << i << "] "
9283                         << ("package " + import +
9284                             " cannot be imported (requested for " +
9285                             (constituent.type == Application ?
9286                              "application " : "library ") +
9287                             constituent.name +")")  << endl;
9288                  }
9289              }
9290          }
9291
9292        /*
9293        cmt_map <Use*, bool> visited;
9294        static bool yes (true);
9295        visited.add (&(Use::current()), yes);
9296        Use::set_auto_imports_state (uses, auto_imports_states, visited);
9297        */     
9298        Use::set_auto_imports_state (uses, auto_imports_states);
9299
9300        /**
9301         *   Find all newly exposed packages and precompute this list inside
9302         *   a vector.
9303         */
9304        for (i = 0; i < base_auto_imports_states.size (); i++)
9305          {
9306            //      if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
9307            if (base_auto_imports_states[i] || !auto_imports_states[i]) continue;
9308            //if (base_auto_imports_states[i] == On || auto_imports_states[i] == Off) continue;
9309            /**
9310             *  Consider the package (i) for import only if it is:
9311             *   o not imported yet (i.e., base_auto_imports_states[i] != true)
9312             *   o requested for import according to -import=xxx modifiers for
9313             *     the current constituent (i.e., auto_imports_states[i] != false)
9314             */
9315            Use* u = Uses[i];
9316           
9317            if (u->discarded) continue;
9318            if (u->m_hidden)  continue;
9319           
9320            Package* p = u->get_package ();
9321            if (p->is_cmt ()) continue;
9322
9323            imports.push_back (u);
9324          }
9325       
9326        if (Cmt::get_debug ())
9327          {
9328            if (imports.size () == 0)
9329              {
9330                cout << constituent.name  << " needs no imports" << endl;
9331              }
9332            else
9333              {
9334                cout << constituent.name  << " has imports" << endl;
9335                for (int i = 0; i < imports.size (); i++)
9336                  {
9337                    cout << constituent.name  << " has import "
9338                         << imports[i]->get_package_name () << endl;
9339                  }
9340              }
9341          }
9342
9343        /**
9344         *  Only for linkopts we take care of the order. This means
9345         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
9346         *
9347         *  (see the application fragments)
9348         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
9349         */
9350        buffer = "macro_append ";
9351        buffer += constituent.name;
9352        buffer += "_use_linkopts ";
9353        buffer += " \" ";
9354       
9355        current_use->fill_macro (buffer, "linkopts");
9356       
9357        for (i = 0; i < Uses.size (); i++)
9358          {
9359            if (auto_imports_states[i])
9360              {
9361                Use* u = Uses[i];
9362               
9363                if (u->discarded) continue;
9364                if (u->m_hidden) continue;
9365               
9366                Package* p = u->get_package ();
9367                if (p->is_cmt ()) continue;
9368               
9369                u->fill_macro (buffer, "linkopts");
9370              }
9371          }
9372        buffer += "\"";
9373        apply ();
9374       
9375        if (imports.size () == 0) continue;
9376       
9377        cmt_string prefix;
9378       
9379        //
9380        // Documents are not considered
9381        //
9382        switch (constituent.type)
9383          {
9384          case Application:
9385            prefix = "app_";
9386            break;
9387          case Library:
9388            prefix = "lib_";
9389            break;
9390          }
9391       
9392        buffer = "macro_append ";
9393        buffer += prefix;
9394        buffer += constituent.name;
9395        buffer += "_cflags ";
9396        buffer += " \' ";
9397        for (i = 0; i < imports.size (); i++)
9398          {
9399            Use* u = imports[i];
9400           
9401            Include::parse_all (u);
9402
9403            u->fill_includes_macro (buffer);
9404            u->fill_macro (buffer, "cflags");
9405          }
9406        buffer += "\'";
9407        apply ();
9408       
9409        buffer = "macro_append ";
9410        buffer += prefix;
9411        buffer += constituent.name;
9412        buffer += "_pp_cflags ";
9413        buffer += " \" ";
9414        for (i = 0; i < imports.size (); i++)
9415          {
9416            Use* u = imports[i];
9417           
9418            u->fill_macro (buffer, "pp_cflags");
9419          }
9420        buffer += "\"";
9421        apply ();
9422       
9423        buffer = "macro_append ";
9424        buffer += prefix;
9425        buffer += constituent.name;
9426        buffer += "_cppflags ";
9427        buffer += " \' ";
9428        for (i = 0; i < imports.size (); i++)
9429          {
9430            Use* u = imports[i];
9431           
9432            u->fill_includes_macro (buffer);
9433            u->fill_macro (buffer, "cppflags");
9434          }
9435        buffer += "\'";
9436        apply ();
9437       
9438        buffer = "macro_append ";
9439        buffer += prefix;
9440        buffer += constituent.name;
9441        buffer += "_pp_cppflags ";
9442        buffer += " \" ";
9443        for (i = 0; i < imports.size (); i++)
9444          {
9445            Use* u = imports[i];
9446           
9447            u->fill_macro (buffer, "pp_cppflags");
9448          }
9449        buffer += "\"";
9450        apply ();
9451       
9452        buffer = "macro_append ";
9453        buffer += prefix;
9454        buffer += constituent.name;
9455        buffer += "_fflags ";
9456        buffer += " \' ";
9457        for (i = 0; i < imports.size (); i++)
9458          {
9459            Use* u = imports[i];
9460           
9461            u->fill_includes_macro (buffer);
9462            u->fill_macro (buffer, "fflags");
9463          }
9464        buffer += "\'";
9465        apply ();
9466       
9467        buffer = "macro_append ";
9468        buffer += prefix;
9469        buffer += constituent.name;
9470        buffer += "_pp_fflags ";
9471        buffer += " \" ";
9472        for (i = 0; i < imports.size (); i++)
9473          {
9474            Use* u = imports[i];
9475           
9476            u->fill_macro (buffer, "pp_fflags");
9477          }
9478        buffer += "\"";
9479        apply ();
9480
9481        buffer = "macro_append ";
9482        buffer += constituent.name;
9483        buffer += "_stamps ";
9484        buffer += " \" ";
9485        for (i = 0; i < imports.size (); i++)
9486          {
9487            Use* u = imports[i];
9488           
9489            u->fill_macro (buffer, "stamps");
9490          }
9491        buffer += "\"";
9492        apply ();
9493
9494        /**
9495         *  Setting ${CONSTITUENT}linkopts is a temporary solution
9496         *  until the backward compatibility solution for a proper
9497         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
9498         *  is acheived.
9499         *
9500         */
9501        /**
9502        buffer = "macro_append ";
9503        buffer += constituent.name;
9504        buffer += "linkopts ";
9505        buffer += " \" ";
9506        for (i = 0; i < imports.size (); i++)
9507          {
9508            Use* u = imports[i];
9509           
9510            u->fill_macro (buffer, "linkopts");
9511          }
9512        buffer += "\"";
9513        apply ();
9514        */
9515      }
9516  }
9517 
9518  /**
9519   *   Macros implied or required to manage constituents.
9520   */
9521  void fill_for_constituent_macros ()
9522  {
9523    int number;
9524    cmt_string temp;
9525
9526    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
9527 
9528    if (!Symbol::is_selected ("constituents"))
9529      {
9530        temp = "macro_append constituents \" ";
9531       
9532        for (number = 0; number < constituents.size (); number++)
9533          {
9534            const Constituent& constituent = constituents[number];
9535           
9536            if (constituent.group == 0)
9537              {
9538                temp += constituent.name;
9539                temp += " ";
9540              }
9541          }
9542       
9543        temp += "\"";
9544       
9545        SyntaxParser::parse_requirements_line (temp, current_use);
9546      }
9547   
9548    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
9549                                           current_use);
9550   
9551    if (!Symbol::is_selected ("constituentsclean"))
9552      {
9553        temp = "macro_append constituentsclean \" ";
9554       
9555        for (number = constituents.size () - 1; number >= 0 ; number--)
9556          {
9557            const Constituent& constituent = constituents[number];
9558           
9559            if (constituent.group == 0)
9560              {
9561                temp += constituent.name;
9562                temp += "clean ";
9563              }
9564          }
9565       
9566        temp += "\"";
9567       
9568        SyntaxParser::parse_requirements_line (temp, current_use);
9569      }
9570   
9571    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
9572                                           current_use);
9573   
9574    const Group::GroupVector& groups = Group::groups ();
9575   
9576    for (number = 0; number < groups.size (); number++)
9577      {
9578        const Group& group = groups[number];
9579       
9580        temp = "macro_append ";
9581        temp += group.name ();
9582        temp += "_constituents \" ";
9583       
9584        int i;
9585       
9586        for (i = 0; i < constituents.size (); i++)
9587          {
9588            const Constituent& constituent = constituents[i];
9589           
9590            if ((constituent.group != 0) && 
9591                (group.name () == constituent.group->name ()))
9592              {
9593                temp += constituent.name;
9594                temp += " ";
9595              }
9596          }
9597       
9598        temp += "\"";
9599       
9600        SyntaxParser::parse_requirements_line (temp, current_use);
9601       
9602        temp = "macro_append ";
9603        temp += group.name ();
9604        temp += "_constituentsclean \" ";
9605       
9606        for (i = constituents.size () - 1; i >= 0 ; i--)
9607          {
9608            const Constituent& constituent = constituents[i];
9609           
9610            if ((constituent.group != 0) && 
9611                (group.name () == constituent.group->name ()))
9612              {
9613                temp += constituent.name;
9614                temp += "clean ";
9615              }
9616          }
9617       
9618        temp += "\"";
9619       
9620        SyntaxParser::parse_requirements_line (temp, current_use);
9621      }
9622  }
9623
9624  /**
9625   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
9626   */
9627  void fill_for_install_area ()
9628  {
9629    CmtPathPattern::apply_all ();
9630
9631    const Use& current_use = Use::current ();
9632
9633    if (current_use.get_strategy ("InstallArea"))
9634      {
9635        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
9636       
9637        ia_mgr.setup ();
9638      }
9639  }
9640
9641  /**
9642   * Macros to be defined once current_package is known
9643   * and even before reading its requirements file.
9644   */
9645  void fill_for_current_package ()
9646  {
9647    fill_for_tag ();
9648    fill_for_package ();
9649  }
9650
9651private:
9652  cmt_string fs;
9653  cmt_string buffer;
9654  //CmtSystem::cmt_string_vector vb;
9655  //cmt_string pwd;
9656  Use* current_use;
9657  cmt_string current_tag; 
9658  cmt_string current_package; 
9659  cmt_string current_version; 
9660  cmt_string current_prefix; 
9661  CmtDirStyle current_style;
9662};
9663
9664//----------------------------------------------------------
9665void Cmt::set_current_access (AccessMode mode)
9666{
9667  Me.m_current_access = mode;
9668}
9669
9670//----------------------------------------------------------
9671void Cmt::set_recursive (bool mode)
9672{
9673  Me.m_recursive = mode;
9674}
9675
9676//----------------------------------------------------------
9677void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
9678{
9679  Me.m_scope_filtering_mode = mode;
9680}
9681
9682//----------------------------------------------------------
9683void Cmt::set_standard_macros ()
9684{
9685  if (Me.m_standard_macros_done) return;
9686
9687  Me.m_standard_macros_done = true;
9688
9689  //  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9690  Use& current_use = Use::current ();
9691
9692  cmt_string fs = CmtSystem::file_separator ();
9693
9694  cmt_string pwd = CmtSystem::pwd ();
9695
9696  /**
9697   * This is a check for package names
9698   */
9699  if (CmtMessage::active (Verbose))
9700    {
9701      Use::UsePtrVector uses (Use::get_ordered_uses ());
9702      uses.push_back (&current_use);
9703      for (int i = uses.size () - 1; i >= 0; i--)
9704        {
9705          Use* use = uses[i];
9706          if (use->discarded) continue;
9707          if (use->m_hidden) continue;
9708          if (!use->located ()) continue;
9709          for (int j = i - 1; j >= 0; j--)
9710            {
9711              Use* use2 = uses[j];
9712              if (use2->discarded) continue;
9713              if (use2->m_hidden) continue;
9714              if (!use2->located ()) continue;
9715              if (use->prefix == use2->prefix)
9716                {
9717                  CmtMessage::warning (use->prefix + "ROOT, "
9718                                       + use->prefix + "VERSION ill-defined: "
9719                                       + use->get_package_name () + " and "
9720                                       + use2->get_package_name ()
9721                                       + " package name conflict");
9722                }
9723            }
9724        }
9725    }
9726  /**
9727   * This is already done in
9728   void Cmt::configure_current_package ()
9729
9730  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
9731  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
9732  else Me.m_current_style = none_style;
9733
9734  {
9735    cmt_string v;
9736    CmtSystem::dirname (pwd, v);
9737    CmtSystem::basename (v, v);
9738    if (!CmtSystem::is_version_directory (v))
9739      {
9740        Me.m_current_style = no_version_style;
9741      }
9742  }
9743  */
9744
9745  // Prepare computation of the best form for relative path from current directory
9746  // to package directories.
9747  CmtSystem::cmt_string_vector vb;
9748  CmtSystem::split (pwd, fs, vb);
9749
9750
9751  /**
9752   *    TAG management
9753   */
9754
9755  static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
9756
9757  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
9758
9759  if (Me.m_current_tag != "")
9760    {
9761      // this is when some -tag= argument was used.
9762      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
9763    }
9764  else if (Symbol::is_selected ("CMTCONFIG"))
9765    {
9766      // This is when CMTCONFIG has been set from some requirements file
9767      Symbol* macro = Symbol::find ("CMTCONFIG");
9768      if (macro != 0)
9769        {
9770          Me.m_current_tag = macro->build_macro_value ();
9771          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
9772        }
9773    }
9774  else
9775    {
9776      // this is when no -tag= argument was used.
9777      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
9778      if (current_use.get_package_name () == "CMT")
9779        {
9780          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
9781        }
9782      else
9783        {
9784          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
9785        }
9786
9787      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
9788    }
9789
9790  if (Me.m_debug)
9791    {
9792      cout << "set_standard_macro3>" << endl;
9793    }
9794
9795  StandardMacroBuilder builder (Me.m_current_tag,
9796                                current_use.get_package_name (),//Me.m_current_package,
9797                                current_use.version,//Me.m_current_version,
9798                                current_use.prefix,//Me.m_current_prefix,
9799                                current_use.style);//Me.m_current_style);
9800
9801  builder.fill_for_current_package ();
9802
9803  builder.fill_for_branches ();
9804  builder.fill_for_project ();
9805
9806  builder.fill_for_install_area ();
9807
9808  builder.fill_for_use_requirements ();
9809  builder.fill_for_use_includes ();
9810  builder.fill_for_use_fincludes ();
9811  builder.fill_for_use_stamps ();
9812  builder.fill_for_use_cflags ();
9813  builder.fill_for_use_pp_cflags ();
9814  builder.fill_for_use_cppflags ();
9815  builder.fill_for_use_pp_cppflags ();
9816  builder.fill_for_use_fflags ();
9817  builder.fill_for_use_pp_fflags ();
9818  builder.fill_for_use_linkopts ();
9819  builder.fill_for_use_libraries ();
9820  builder.fill_for_includes ();
9821  builder.fill_for_fincludes ();
9822  builder.fill_for_all_constituents ();
9823  builder.fill_for_constituent_macros ();
9824}
9825
9826void Cmt::set_all_sets_done ()
9827{
9828  Me.m_all_sets_done = true;
9829}
9830
9831void Cmt::reset_all_sets_done ()
9832{
9833  Me.m_all_sets_done = false;
9834}
9835
9836//----------------------------------------------------------
9837void Cmt::use_cmt ()
9838{
9839  UseRef use;
9840  bool recursive_copy = Me.m_recursive;
9841  bool debug_copy = Me.m_debug;
9842
9843  if (Me.m_default_path.size () <= 0) return;
9844  if (Me.m_current_package == "CMT") return;
9845
9846  Me.m_recursive = true;
9847  //Me.m_debug = false;
9848  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
9849  Me.m_recursive = recursive_copy;
9850  Me.m_debug = debug_copy;
9851}
9852
9853//----------------------------------------------------------
9854void Cmt::use_home_requirements ()
9855{
9856  use_special_requirements (Me.m_cmt_home, 
9857                            CmtSystem::get_home_package (), 
9858                            "requirements");
9859}
9860
9861//----------------------------------------------------------
9862void Cmt::use_user_context_requirements ()
9863{
9864  use_special_requirements (Me.m_cmt_user_context, 
9865                            CmtSystem::get_user_context_package (), 
9866                            "requirements");
9867}
9868
9869//----------------------------------------------------------
9870void Cmt::use_special_requirements (const cmt_string& path, 
9871                                    const cmt_string& name, 
9872                                    const cmt_string& file_name)
9873{
9874  if (path == "") 
9875    {
9876      return;
9877    }
9878
9879  UseRef use;
9880  bool recursive_copy = Me.m_recursive;
9881
9882  if (Me.m_default_path.size () <= 0) return;
9883  if (Me.m_current_package == "CMT") return;
9884
9885  Me.m_recursive = true;
9886
9887  use = Use::add (path, name, "v0", "", "", "", 0);
9888
9889  cmt_string f = path;
9890  f += CmtSystem::file_separator ();
9891  f += file_name;
9892  if (CmtSystem::test_file (f))
9893    {
9894      use->m_located = true;
9895    }
9896  SyntaxParser::parse_requirements (f, use);
9897
9898  Me.m_recursive = recursive_copy;
9899}
9900
9901//-------------------------------------------------
9902void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
9903                            const cmt_string& separator,
9904                            cmt_string& result)
9905{
9906  result.erase (0);
9907
9908  for (int i = 0; i < v.size (); i++)
9909    {
9910      const cmt_string& s = v[i];
9911      if (s == "") continue;
9912
9913      if (result.size () != 0) result += separator;
9914      //if (i > 0) result += separator;
9915      result += v[i];
9916    }
9917}
9918
9919//-------------------------------------------------
9920cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
9921{
9922  cmt_string result;
9923
9924  vector_to_string (v, " ", result);
9925
9926  return (result);
9927}
Note: See TracBrowser for help on using the repository browser.