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

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

See C.L. 447

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