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

Last change on this file since 568 was 568, checked in by rybkin, 13 years ago

See C.L. 451

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