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

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

See C.L. 445

  • Property svn:eol-style set to native
File size: 241.3 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  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
6732
6733  //
6734  // Perform some actions even if there is an error
6735  //
6736
6737  if (CmtError::has_pending_error ())
6738    {
6739      int code = CmtError::get_last_error_code ();
6740      if (!Me.m_quiet) CmtError::print ();
6741
6742      switch (Me.m_action)
6743        {
6744          // case action_none :
6745          // case action_awk :
6746          // case action_broadcast :
6747        case action_build_constituent_makefile :
6748        case action_build_constituent_config :
6749        case action_build_constituents_makefile :
6750        case action_build_constituents_config :
6751        case action_build_dependencies :
6752        case action_build_library_links :
6753        case action_build_make_setup :
6754        case action_build_msdev :
6755        case action_build_CMT_pacman :
6756        case action_build_vsnet :     
6757        case action_build_os9_makefile :
6758        case action_build_prototype :
6759        case action_build_readme :
6760        case action_build_tag_makefile :
6761          // case action_build_temporary_name :
6762        case action_build_triggers :
6763        case action_build_windefs :
6764        case action_check_configuration :
6765          // case action_check_files :
6766          // case action_check_version :
6767          // case action_checkout :
6768        case action_cleanup :
6769          // case action_config :
6770          // case action_create :
6771          // case action_create_project :
6772          // case action_cvsbranches :
6773          // case action_cvssubpackages :
6774          // case action_cvssubprojects :
6775          // case action_cvstags :
6776          // case action_do :
6777          // case action_expand_model :
6778          // case action_filter :
6779          // case action_help :
6780        case action_load :
6781        case action_lock :
6782        case action_relocate :
6783        case action_remove :
6784        case action_remove_library_links :
6785          // case action_run :
6786        case action_run_sequence :
6787          // case action_set_version :
6788          // case action_set_versions :
6789        case action_setup :
6790          // case action_show_action :
6791          // case action_show_action_names :
6792          // case action_show_action_value :
6793          // case action_show_actions :
6794          // case action_show_all_tags :
6795          // case action_show_applied_patterns :
6796          // case action_show_author :
6797          // case action_show_branches :
6798          // case action_show_clients :
6799          // case action_show_cmtpath_patterns :
6800          // case action_show_constituent :
6801          // case action_show_container :
6802          // case action_show_constituent_names :
6803          // case action_show_constituents :
6804          // case action_show_cycles :
6805          // case action_show_fragment :
6806          // case action_show_fragments :
6807          // case action_show_groups :
6808          // case action_show_include_dirs :
6809          // case action_show_language :
6810          // case action_show_languages :
6811          // case action_show_macro :
6812          // case action_show_macro_names :
6813          // case action_show_macro_value :
6814          // case action_show_macros :
6815          // case action_show_manager :
6816          // case action_show_packages :
6817          // case action_show_path :
6818          // case action_show_pattern :
6819          // case action_show_pattern_names :
6820          // case action_show_patterns :
6821          // case action_show_projects :
6822          // case action_show_pwd :
6823          // case action_show_setup :
6824          // case action_show_set :
6825          // case action_show_set_names :
6826          // case action_show_set_value :
6827          // case action_show_sets :
6828          // case action_show_strategies :
6829          // case action_show_tags :
6830          // case action_show_use_paths :
6831          // case action_show_uses :
6832          // case action_show_version :
6833          // case action_show_versions :
6834          // case action_system :
6835        case action_unlock :
6836          // case action_version :
6837          clear ();
6838          return (code);
6839        default:
6840          CmtError::clear ();
6841          break;
6842        }
6843    }
6844
6845  //
6846  // Perform actions
6847  //
6848
6849  if (!Me.m_simulation)
6850    {
6851      switch (Me.m_action)
6852        {
6853        case action_none :
6854          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
6855          break;
6856        case action_awk :
6857          do_awk (ap);
6858          break;
6859        case action_broadcast :
6860          do_broadcast (ap);
6861          break;
6862        case action_build_constituent_makefile :
6863          do_build_constituent_makefile (ap);
6864          break;
6865        case action_build_constituent_config :
6866          do_build_constituent_config (ap);
6867          break;
6868        case action_build_constituents_makefile :
6869          do_build_constituents_makefile (ap);
6870          break;
6871        case action_build_constituents_config :
6872          do_build_constituents_config (ap);
6873          break;
6874        case action_build_dependencies :
6875          do_build_dependencies (ap, argc, argv);
6876          break;
6877        case action_build_library_links :
6878          do_build_library_links (ap);
6879          break;
6880        case action_build_make_setup :
6881          do_build_make_setup (ap);
6882          break;
6883        case action_build_msdev :
6884          do_build_msdev (ap);
6885          break;
6886        case action_build_CMT_pacman :
6887          do_build_CMT_pacman (ap);
6888          break;
6889        case action_build_vsnet :     
6890          do_build_vsnet (ap);
6891          break;
6892        case action_build_os9_makefile :
6893          do_build_os9_makefile (ap);
6894          break;
6895        case action_build_prototype :
6896          do_build_prototype (ap);
6897          break;
6898        case action_build_readme :
6899          do_build_readme (ap);
6900          break;
6901        case action_build_tag_makefile :
6902          do_build_tag_makefile (ap);
6903          break;
6904        case action_build_temporary_name :
6905          do_build_temporary_name (ap);
6906          break;
6907        case action_build_triggers :
6908          do_build_triggers (ap);
6909          break;
6910        case action_build_windefs :
6911          do_build_windefs (ap);
6912          break;
6913        case action_check_configuration :
6914          do_check_configuration (ap);
6915          break;
6916        case action_check_files :
6917          do_check_files (ap);
6918          break;
6919        case action_check_version :
6920          do_check_version (ap);
6921          break;
6922        case action_checkout :
6923          do_checkout (ap);
6924          break;
6925        case action_cleanup :
6926          do_cleanup (ap);
6927          break;
6928        case action_config :
6929          do_config (ap);
6930          break;
6931        case action_create :
6932          do_create (ap);
6933          break;
6934        case action_create_project :
6935          do_create_project (ap);
6936          break;
6937        case action_cvsbranches :
6938          do_cvsbranches (ap);
6939          break;
6940        case action_cvssubpackages :
6941          do_cvssubpackages (ap);
6942          break;
6943        case action_cvssubprojects :
6944          do_cvssubprojects (ap);
6945          break;
6946        case action_cvstags :
6947          do_cvstags (ap);
6948          break;
6949        case action_do :
6950          do_do (ap);
6951          break;
6952        case action_expand_model :
6953          do_expand_model (ap);
6954          break;
6955        case action_filter :
6956          do_filter (ap);
6957          break;
6958        case action_help :
6959          do_help (ap);
6960          break;
6961        case action_load :
6962          CmtMessage::error ("action not implemented");
6963          //      cerr << "#CMT> action not implemented" << endl;
6964          break;
6965        case action_lock :
6966          do_lock (ap);
6967          break;
6968        case action_relocate :
6969          do_relocate (ap);
6970          break;
6971        case action_remove :
6972          do_remove (ap);
6973          break;
6974        case action_remove_library_links :
6975          do_remove_library_links (ap);
6976          break;
6977        case action_run :
6978          do_run (ap);
6979          break;
6980        case action_run_sequence :
6981          do_run_sequence (ap);
6982          break;
6983        case action_set_version :
6984          do_set_version (ap);
6985          break;
6986        case action_set_versions :
6987          do_set_versions (ap);
6988          break;
6989        case action_setup :
6990          do_setup (ap);
6991          break;
6992        case action_show_action :
6993          do_show_action (ap);
6994          break;
6995        case action_show_action_names :
6996          do_show_action_names (ap);
6997          break;
6998        case action_show_action_value :
6999          do_show_action_value (ap);
7000          break;
7001        case action_show_actions :
7002          do_show_actions (ap);
7003          break;
7004        case action_show_all_tags :
7005          do_show_all_tags (ap);
7006          break;
7007        case action_show_applied_patterns :
7008          do_show_applied_patterns (ap);
7009          break;
7010        case action_show_author :
7011          do_show_author (ap);
7012          break;
7013        case action_show_branches :
7014          do_show_branches (ap);
7015          break;
7016        case action_show_container :
7017          do_show_container (ap);
7018          break;
7019        case action_show_clients :
7020          do_show_clients (ap);
7021          break;
7022        case action_show_cmtpath_patterns :
7023          do_show_cmtpath_patterns (ap);
7024          break;
7025        case action_show_constituent :
7026          do_show_constituent (ap);
7027          break;
7028        case action_show_constituent_names :
7029          do_show_constituent_names (ap);
7030          break;
7031        case action_show_constituents :
7032          do_show_constituents (ap);
7033          break;
7034        case action_show_cycles :
7035          do_show_cycles (ap);
7036          break;
7037        case action_show_fragment :
7038          do_show_fragment (ap);
7039          break;
7040        case action_show_fragments :
7041          do_show_fragments (ap);
7042          break;
7043        case action_show_groups :
7044          do_show_groups (ap);
7045          break;
7046        case action_show_include_dirs :
7047          do_show_include_dirs (ap);
7048          break;
7049        case action_show_language :
7050          do_show_language (ap);
7051          break;
7052        case action_show_languages :
7053          do_show_languages (ap);
7054          break;
7055        case action_show_macro :
7056          do_show_macro (ap);
7057          break;
7058        case action_show_macro_names :
7059          do_show_macro_names (ap);
7060          break;
7061        case action_show_macro_value :
7062          do_show_macro_value (ap);
7063          break;
7064        case action_show_macros :
7065          do_show_macros (ap);
7066          break;
7067        case action_show_manager :
7068          do_show_manager (ap);
7069          break;
7070        case action_show_packages :
7071          do_show_packages (ap);
7072          break;
7073        case action_show_path :
7074          do_show_path (ap);
7075          break;
7076        case action_show_pattern :
7077          do_show_pattern (ap);
7078          break;
7079        case action_show_pattern_names :
7080          do_show_pattern_names (ap);
7081          break;
7082        case action_show_patterns :
7083          do_show_patterns (ap);
7084          break;
7085        case action_show_projects :
7086          do_show_projects (ap);
7087          break;
7088        case action_show_project_author :
7089          do_show_project_author (ap);
7090          break;
7091        case action_show_pwd :
7092          do_show_pwd (ap);
7093          break;
7094        case action_show_setup :
7095          do_show_setup (ap);
7096          break;
7097        case action_show_set :
7098          do_show_set (ap);
7099          break;
7100        case action_show_set_names :
7101          do_show_set_names (ap);
7102          break;
7103        case action_show_set_value :
7104          do_show_set_value (ap);
7105          break;
7106        case action_show_sets :
7107          do_show_sets (ap);
7108          break;
7109        case action_show_strategies :
7110          do_show_strategies (ap);
7111          break;
7112        case action_show_tags :
7113          do_show_tags (ap);
7114          break;
7115        case action_show_use_paths :
7116          do_show_use_paths (ap);
7117          break;
7118        case action_show_uses :
7119          do_show_uses (ap);
7120          break;
7121        case action_show_version :
7122          do_show_version (ap);
7123          break;
7124        case action_show_versions :
7125          do_show_versions (ap);
7126          break;
7127        case action_system :
7128          do_show_system (ap);
7129          break;
7130        case action_unlock :
7131          do_unlock (ap);
7132          break;
7133        case action_version :
7134          do_version (ap);
7135          break;
7136        default:
7137          CmtError::set (CmtError::syntax_error, "ParseArguments>");
7138          break;
7139        }
7140    }
7141
7142  // restore CMTFLAGS
7143  set_cmt_flags (cmtflags);
7144
7145  if (CmtError::has_pending_error ())
7146    {
7147      int code = CmtError::get_last_error_code ();     
7148      if (code == CmtError::execution_failed)
7149        {
7150          code = CmtError::get_last_execution_error();
7151        }   
7152     
7153      CmtError::print ();
7154      //      if (!Me.m_quiet) CmtError::print ();
7155      clear ();
7156      return (code);
7157    }
7158  else
7159    {
7160      clear ();
7161      return (0);
7162    }
7163}
7164
7165
7166/**
7167 * Format as one single line a set of 'setenv' statements
7168 * joined with semi-colons to form one shell command.
7169 */
7170void Cmt::print (PrintMode mode)
7171{
7172  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7173  Use& current_use = Use::current ();
7174
7175  cmt_string tag;
7176
7177  set_standard_macros ();
7178
7179  //cerr << "# current_tag=" << Me.m_current_tag << endl;
7180  //cerr << "# current_config=" << Me.m_current_config << endl;
7181
7182  if (Me.m_current_tag == "")
7183    {
7184      if (mode == Bat) tag = "%CMTCONFIG%";
7185      else tag = "${CMTCONFIG}";
7186    }
7187  else
7188    {
7189      tag = Me.m_current_tag;
7190    }
7191
7192  //
7193  //  Now check if all extra tags are still valid. Some of them
7194  //  may be discarded du to some conflict with highest priority
7195  //  tags, or with exclude statements
7196  //
7197
7198  {
7199    CmtSystem::cmt_string_vector words;
7200     
7201    cmt_string tags;
7202
7203    tags = Me.m_extra_tags;
7204     
7205    CmtSystem::split (tags, " \t,", words);
7206
7207    Me.m_extra_tags = ",";
7208     
7209    for (int i = 0; i < words.size (); i++)
7210      {
7211        Tag* tag;
7212        const cmt_string& a = words[i];
7213
7214        tag = Tag::find (a);
7215
7216        if ((tag != 0) && (tag->is_selected ()))
7217          {
7218            Me.m_extra_tags += a;
7219            Me.m_extra_tags += ",";
7220          }
7221      }
7222  }
7223
7224  if (mode == Requirements)
7225    {
7226      //do_show_tags (ap, cout);
7227      Tag::TagPtrVector tags = Tag::tags ();
7228      for (int index = 0; index < tags.size (); index++)
7229        {
7230          const Tag* tag = tags[index];
7231          if (tag != 0)
7232            {
7233              tag->show (true, cout, "apply_tag ");
7234            }
7235        }
7236    }
7237
7238  if (Me.m_debug)
7239    {
7240      cout << "Before all print contexts" << endl;
7241    }
7242
7243  if (Uses.size () > 0)
7244    {
7245      int number;
7246
7247      for (number = 0; number < Uses.size (); number++)
7248        {
7249          Use& use = *(Uses[number]);
7250
7251          if (use.discarded) continue;
7252          if (use.m_hidden) continue;
7253         
7254          print_context (use, mode, tag);
7255        }
7256    }
7257
7258  print_context (Use::current (), mode, tag);
7259
7260  if (Me.m_debug)
7261    {
7262      cout << "After all print contexts" << endl;
7263    }
7264
7265  Symbol::all_print (mode);
7266  // Script::all_print (mode);
7267
7268  if (Me.m_debug)
7269    {
7270      cout << "After all print" << endl;
7271    }
7272
7273  switch (mode)
7274    {
7275    case Xml :
7276      break;
7277    default :
7278  cout << endl;
7279      break;
7280    }
7281}
7282
7283
7284/**
7285 * Format as one single line a set of 'unsetenv' statements
7286 * joined with semi-colons to form one shell command.
7287 */
7288void Cmt::print_clean (PrintMode mode)
7289{
7290  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7291
7292  set_standard_macros ();
7293
7294  Script::all_print_clean (mode);
7295  Symbol::all_print_clean (mode);
7296
7297  switch (mode)
7298    {
7299    case Csh :
7300      if (Me.m_current_package != "CMT")
7301        {
7302          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
7303          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
7304        }
7305      break;
7306    case Sh :
7307      if (Me.m_current_package != "CMT")
7308        {
7309          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
7310          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
7311        }
7312      break;
7313    case Bat :
7314      if (Me.m_current_package != "CMT")
7315        {
7316          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
7317          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
7318        }
7319      break;
7320    }
7321
7322  if (Uses.size () > 0)
7323    {
7324      int number;
7325
7326      for (number = 0; number < Uses.size (); number++)
7327        {
7328          Use* use = Uses[number];
7329
7330          if (use->discarded) continue;
7331          if (use->m_hidden) continue;
7332
7333          Package* p = use->get_package ();
7334          if (p->is_cmt ()) continue;
7335
7336
7337          switch (mode)
7338            {
7339            case Csh :
7340              cout << "unsetenv " << use->prefix << "ROOT" << endl;
7341              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
7342              break;
7343            case Sh :
7344              cout << "unset " << use->prefix << "ROOT" << endl;
7345              cout << "unset " << use->prefix << "CONFIG" << endl;
7346              break;
7347            case Bat :
7348              cout << "set " << use->prefix << "ROOT=" << endl;
7349              cout << "set " << use->prefix << "CONFIG=" << endl;
7350              break;
7351            }
7352        }
7353    }
7354
7355  switch (mode)
7356    {
7357    case Csh :
7358      cout << "unsetenv CMTEXTRATAGS" << endl;
7359      break;
7360    case Sh :
7361      cout << "unset CMTEXTRATAGS" << endl;
7362      break;
7363    case Bat :
7364      cout << "set CMTEXTRATAGS=" << endl;
7365      break;
7366    }
7367
7368  cout << endl;
7369}
7370
7371//----------------------------------------------------------
7372void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
7373{
7374  if (use.get_package_name () == "cmt_standalone") return;
7375
7376  cmt_string fs = CmtSystem::file_separator ();
7377
7378  use.real_path.replace_all (CmtSystem::file_separator (), fs);
7379
7380  cmt_string system = CmtSystem::get_cmt_config ();
7381
7382  bool do_config = use.get_strategy ("SetupConfig");
7383  bool do_root   = use.get_strategy ("SetupRoot");
7384   
7385 
7386  switch (mode)
7387    {
7388    case Csh :
7389      if (do_root)
7390        {
7391          cout << "setenv " << use.prefix << "ROOT \"" <<
7392            use.get_full_path () << "\"" << endl;
7393        }
7394
7395      if (use.get_package_name () == "CMT")
7396        {
7397          cout << "setenv CMTCONFIG " << system << endl;
7398        }
7399      else
7400        {
7401          if (do_config)
7402            {
7403              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
7404            }
7405        }
7406       
7407      break;
7408    case Sh :
7409      if (do_root)
7410        {
7411          cout << use.prefix << "ROOT=\"" <<
7412            use.get_full_path () << "\"; export " <<
7413            use.prefix << "ROOT" << endl;
7414        }
7415
7416      if (use.get_package_name () == "CMT")
7417        {
7418          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
7419        }
7420      else
7421        {
7422          if (do_config)
7423            {
7424              cout << use.prefix << "CONFIG=\"" <<
7425                tag << "\"; export " <<
7426                use.prefix << "CONFIG" << endl;
7427            }
7428        }
7429       
7430      break;
7431    case Bat :
7432      if (do_root)
7433        {
7434          cout << "set " << use.prefix << "ROOT=" <<
7435            use.get_full_path () << endl;
7436        }
7437
7438      if (use.get_package_name () == "CMT")
7439        {
7440          cout << "set CMTCONFIG=" << system << endl;
7441        }
7442      else
7443        {
7444          if (do_config)
7445            {
7446              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
7447            }
7448        }
7449       
7450      break;
7451    case Xml :
7452      if (do_root)
7453        {
7454          cout << "<variable><name>" << use.prefix << "ROOT</name>"
7455               << "<value>" << use.get_full_path () << "</value></variable>";
7456        }
7457
7458      if (use.get_package_name () == "CMT")
7459        {
7460          cout << "<variable><name>CMTCONFIG</name>"
7461               << "<value>" << system << "</value></variable>";
7462        }
7463      else
7464        {
7465          if (do_config)
7466            {
7467              cout << "<variable><name>" << use.prefix << "CONFIG</name>"
7468                   << "<value>" << tag << "</value></variable>";
7469            }
7470        }
7471       
7472      break;
7473    case Requirements :
7474      if (do_root &&
7475          use.get_package_name () != "CMT")
7476        {
7477          cout << "set " << use.prefix << "ROOT \"" <<
7478            use.get_full_path () << "\"" << endl;
7479
7480          cmt_string name (use.prefix + "ROOT");
7481          Symbol* symbol = Symbol::find (name);
7482          if (symbol != 0) 
7483            {
7484              symbol->printed = true;
7485            }
7486          if (symbol == 0 || symbol->type != Symbol::SymbolMacro)
7487            {
7488              CmtMessage::warning
7489                (CmtError::get_error_name (CmtError::symbol_not_found)
7490                 + ": macro " + name);
7491            }
7492        }
7493
7494      if (use.get_package_name () == "CMT")
7495        {
7496          cout << "set CMTCONFIG \"" << system << "\"" << endl;
7497        }
7498      else
7499        {
7500          if (do_config)
7501            {
7502              cout << "set " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
7503            }
7504        }
7505       
7506      break;
7507    }
7508}
7509
7510/**
7511 *  Format a set of make macro definitions (one per line)
7512 * Each macro value is provided enclosed in single quotes
7513 *
7514 *  Take the macro values from the macro statements found
7515 * in recursively read requirements files.
7516 */
7517void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
7518{
7519  int number;
7520
7521  set_standard_macros ();
7522
7523  cmt_regexp expression (pattern);
7524
7525  bool has_pattern = (pattern != "");
7526
7527  for (number = 0; number < Symbol::symbol_number (); number++)
7528    {
7529      Symbol& symbol = Symbol::symbol (number);
7530
7531      if (has_pattern)
7532        {
7533          if (!expression.match (symbol.name)) continue;
7534        }
7535
7536      if (Me.m_action == action_show_macro_names)
7537        {
7538          // Only keep macros.
7539          if ((symbol.type == Symbol::SymbolSet) ||
7540              (symbol.type == Symbol::SymbolAlias) ||
7541              (symbol.type == Symbol::SymbolPath) ||
7542              (symbol.type == Symbol::SymbolAction)) continue;
7543        }
7544      else if (Me.m_action == action_show_set_names)
7545        {
7546          // Exclude macros.
7547          if ((symbol.type == Symbol::SymbolMacro) ||
7548              (symbol.type == Symbol::SymbolAction)) continue;
7549        }
7550      else if (Me.m_action == action_show_action_names)
7551        {
7552          // Exclude macros.
7553          if (symbol.type != Symbol::SymbolAction) continue;
7554        }
7555
7556      cout << symbol.name << endl;
7557    }
7558}
7559
7560/**
7561 *  Format a set of make macro definitions (one per line)
7562 * Each macro value is provided enclosed in single quotes
7563 *
7564 *  Take the macro values from the macro statements found
7565 * in recursively read requirements files.
7566 */
7567void Cmt::print_macros (PrintMode mode, const cmt_string& pattern, ostream& out)
7568//void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
7569{
7570  int number;
7571
7572  set_standard_macros ();
7573
7574  cmt_regexp expression (pattern);
7575
7576  bool has_pattern = (pattern != "");
7577
7578  for (number = 0; number < Symbol::symbol_number (); number++)
7579    {
7580      Symbol& symbol = Symbol::symbol (number);
7581
7582      if (has_pattern)
7583        {
7584          if (!expression.match (symbol.name)) continue;
7585        }
7586
7587      if (Me.m_action == action_show_macros)
7588        {
7589          // Only keep macros.
7590          if ((symbol.type == Symbol::SymbolSet) ||
7591              (symbol.type == Symbol::SymbolAlias) ||
7592              (symbol.type == Symbol::SymbolPath) ||
7593              (symbol.type == Symbol::SymbolAction)) continue;
7594        }
7595      else if (Me.m_action == action_show_sets)
7596        {
7597          // Exclude macros.
7598          if ((symbol.type == Symbol::SymbolMacro) ||
7599              (symbol.type == Symbol::SymbolAction)) continue;
7600        }
7601      else if ((Me.m_action == action_build_tag_makefile) ||
7602               (Me.m_action == action_build_constituents_config) ||
7603               (Me.m_action == action_build_constituent_config))
7604        {
7605          // Exclude scripts and actions
7606          if ((symbol.type == Symbol::SymbolSetupScript) ||
7607              (symbol.type == Symbol::SymbolCleanupScript) ||
7608              (symbol.type == Symbol::SymbolAction)) continue;
7609        }
7610      else if (Me.m_action == action_show_actions)
7611        {
7612          if (symbol.type != Symbol::SymbolAction) continue;
7613        }
7614
7615      if (symbol.value_lists.size () < 1) continue;
7616
7617      symbol.show_macro (mode, out);
7618      //      symbol.show_macro (mode);
7619    }
7620}
7621
7622//----------------------------------------------------------
7623void Cmt::print_tabs (int tabs)
7624{
7625  while (tabs > 0)
7626    {
7627      cout << "  ";
7628      tabs--;
7629    }
7630}
7631
7632//----------------------------------------------------------
7633void Cmt::print_xml_prolog (const cmt_string& root, ostream& out)
7634{
7635  out << "<?xml version=\"1.0\" standalone=\"no\"?>" << endl;
7636  cmt_string dtd_file (Me.m_cmt_root);
7637  dtd_file += CmtSystem::file_separator ();
7638  dtd_file += "mgr";
7639  dtd_file += CmtSystem::file_separator ();
7640  dtd_file += "CMT.dtd";
7641  out << "<!DOCTYPE " + root + " SYSTEM \"" + dtd_file + "\">" << endl;
7642}
7643
7644//----------------------------------------------------------
7645int Cmt::reach_current_package ()
7646{
7647  Use& use = Use::current ();
7648  cmt_string dir;
7649
7650  if (Me.m_debug)
7651    {
7652      cout << "Cmt::reach_current_package> pwd = " 
7653           << CmtSystem::pwd () 
7654           << " path=" << Me.m_current_path
7655           << " package=" << Me.m_current_package
7656           << endl;
7657    }
7658
7659  /*
7660    Try to access the package.
7661  */
7662
7663  if (Me.m_current_package == "cmt_standalone")
7664    {
7665      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
7666        {
7667          if (!CmtSystem::cd (Me.m_current_path))
7668            {
7669              CmtError::set (CmtError::package_not_found,
7670                             "ReachCurrentPackage> Cannot reach the path directory");
7671              return (0);
7672            }
7673        }
7674
7675      if (!CmtSystem::test_file ("requirements"))
7676        {
7677          return (0);
7678        }
7679
7680      Me.m_current_structuring_style = without_version_directory;
7681    }
7682  else if (Me.m_current_package != "")
7683    {
7684      if (!use.move_to () && !use.move_to ("", true))
7685        //      if (!use.move_to ())
7686        {
7687          CmtError::set (CmtError::package_not_found,
7688                         "ReachCurrentPackage> Cannot reach the path directory");
7689          return (0);
7690        }
7691
7692      Me.m_current_path = use.real_path;
7693    }
7694  else
7695    {
7696      //
7697      // The cmt command has been given without explicit search for
7698      // a package. Thus it is expected that we are in the context of a
7699      // true package.
7700      //
7701      //  This means that there should be a requirements file visible.
7702      //
7703      //  If this is not true, we'll make a try into ../cmt and then
7704      // a last try into ../mgr
7705      //
7706
7707      if (!CmtSystem::test_file ("requirements"))
7708        {
7709          if (CmtSystem::cd ("../cmt") && 
7710              CmtSystem::test_file ("requirements"))
7711            {
7712              Me.m_current_style = cmt_style;
7713            }
7714          else if (CmtSystem::cd ("../mgr") && 
7715                   CmtSystem::test_file ("requirements"))
7716            {
7717              Me.m_current_style = mgr_style;
7718            }
7719          else
7720            {
7721              CmtMessage::error ("Cannot reach the mgr branch");
7722              /*
7723              if (!Me.m_quiet)
7724                {
7725                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
7726                }
7727              */
7728             
7729              CmtError::set (CmtError::package_not_found,
7730                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
7731              return (0);
7732            }
7733        }
7734      else
7735        Me.m_current_style = none_style;
7736
7737      dir = CmtSystem::pwd ();
7738
7739      CmtSystem::dirname (dir, Me.m_current_path);
7740      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
7741
7742      if (CmtSystem::is_version_directory (Me.m_current_version))
7743        {
7744          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7745          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
7746          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7747          Me.m_current_structuring_style = with_version_directory;
7748        }
7749      else
7750        {
7751          Me.m_current_package = Me.m_current_version;
7752          Me.m_current_version = "";
7753          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
7754          Me.m_current_structuring_style = without_version_directory;
7755          //          Me.m_current_style = no_version_style;
7756        }
7757
7758      use.set_package_name (Me.m_current_package);
7759      use.version = Me.m_current_version;
7760      use.path    = Me.m_current_path;
7761      use.style   = Me.m_current_style;
7762      use.structuring_style = Me.m_current_structuring_style;
7763    }
7764
7765  configure_current_dir ();
7766  build_prefix (Me.m_current_package, Me.m_current_prefix);
7767  build_config (Me.m_current_prefix, Me.m_current_config);
7768
7769  /*
7770    Check Tag is always set up
7771  */
7772
7773  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
7774
7775  if (Me.m_current_tag == "")
7776    {
7777      cmt_string env;
7778
7779      env = CmtSystem::getenv (Me.m_current_config);
7780      if (env != "")
7781        {
7782          Tag* tag;
7783
7784          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
7785          tag->mark ();
7786          //Me.m_current_tag = env;
7787
7788          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
7789
7790        }
7791    }
7792
7793  if (Me.m_debug)
7794    {
7795      cout << "pwd = " << CmtSystem::pwd () << endl;
7796    }
7797
7798  /*
7799    Work on the requirements file.
7800  */
7801
7802  if (dir != "") dir += CmtSystem::file_separator ();
7803  dir += "requirements";
7804  SyntaxParser::parse_requirements (dir, &use);
7805
7806  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
7807
7808  /**
7809   *   It would be useful to change this mechanism. Instead of
7810   *  applying all global patterns at once to all use contexts, it
7811   *  would be much better to apply it at the end of each
7812   *  requirements file parsing, and only in the context the
7813   *  appropriate Use.
7814   *
7815   *   This would avoid the current flaw which is that when a global
7816   *  pattern specifies a "private" definition, it is actually
7817   *  applied in the scope context of the Current Use and not in
7818   *  each individual Use. Therefore the private is lost.
7819   *
7820   *   However, this induces problems since some pattern definitions
7821   *  are done AFTER the use statements, which will NOT receive the
7822   *  pattern aplications.
7823   *
7824   *   Therefore it is decided to leave this "bad" mechanism until
7825   *  everybody is aware of this constraint.
7826   *
7827   *
7828   */
7829  Pattern::apply_all_globals ();
7830
7831  /*
7832    Select all possible tags
7833  */
7834
7835  Tag::restore_tree ();
7836
7837  return (1);
7838}
7839
7840//----------------------------------------------------------
7841int Cmt::use_extra_file (const cmt_string& file)
7842{
7843  if (!CmtSystem::test_file (file))
7844    {
7845      CmtError::set (CmtError::path_not_found, file);
7846      return 0;
7847    }
7848
7849  // (almost) Cmt::reach_current_package ()
7850  Use& use = Use::current ();
7851  /*
7852    Try to access the package.
7853  */
7854
7855  if (Me.m_current_package == "cmt_standalone")
7856    {
7857      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
7858        {
7859          if (!CmtSystem::cd (Me.m_current_path))
7860            {
7861              CmtError::set (CmtError::package_not_found,
7862                             "ReachCurrentPackage> Cannot reach the path directory");
7863              return (0);
7864            }
7865        }
7866      /*
7867      if (!CmtSystem::test_file ("requirements"))
7868        {
7869          return (0);
7870        }
7871      */
7872      Me.m_current_structuring_style = without_version_directory;
7873    }
7874  else if (Me.m_current_package != "")
7875    {
7876      if (!use.move_to () && !use.move_to ("", true))
7877        //      if (!use.move_to ())
7878        {
7879          CmtError::set (CmtError::package_not_found,
7880                         "ReachCurrentPackage> Cannot reach the path directory");
7881          //          return -1;
7882          return (0);
7883        }
7884
7885      Me.m_current_path = use.real_path;
7886    }
7887  else
7888    {
7889      //
7890      // The cmt command has been given without explicit search for
7891      // a package. Thus it is expected that we are in the context of a
7892      // true package.
7893      //
7894      //  This means that there should be a requirements file visible.
7895      //
7896      //  If this is not true, we'll make a try into ../cmt and then
7897      // a last try into ../mgr
7898      //
7899
7900      //...
7901    }
7902
7903  configure_current_dir ();
7904  build_prefix (Me.m_current_package, Me.m_current_prefix);
7905  build_config (Me.m_current_prefix, Me.m_current_config);
7906
7907  /*
7908    Check Tag is always set up
7909  */
7910
7911  if (Me.m_debug) cout << "use_extra_file0> current_tag=" << Me.m_current_tag << endl;
7912
7913  if (Me.m_current_tag == "")
7914    {
7915      cmt_string env;
7916
7917      env = CmtSystem::getenv (Me.m_current_config);
7918      if (env != "")
7919        {
7920          Tag* tag;
7921
7922          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
7923          tag->mark ();
7924          //Me.m_current_tag = env;
7925
7926          //if (!Me.m_quiet) cerr << "use_extra_file1> current_tag=" << Me.m_current_tag << endl;
7927
7928        }
7929    }
7930
7931  if (Me.m_debug)
7932    {
7933      cout << "pwd = " << CmtSystem::pwd () << endl;
7934    }
7935
7936  /*
7937    Work on the requirements file.
7938  */
7939
7940  SyntaxParser::parse_requirements (file, &use);
7941
7942  if (Me.m_debug) cout << "use_extra_file2> current_tag=" << Me.m_current_tag << endl;
7943
7944  /**
7945   *   It would be useful to change this mechanism. Instead of
7946   *  applying all global patterns at once to all use contexts, it
7947   *  would be much better to apply it at the end of each
7948   *  requirements file parsing, and only in the context the
7949   *  appropriate Use.
7950   *
7951   *   This would avoid the current flaw which is that when a global
7952   *  pattern specifies a "private" definition, it is actually
7953   *  applied in the scope context of the Current Use and not in
7954   *  each individual Use. Therefore the private is lost.
7955   *
7956   *   However, this induces problems since some pattern definitions
7957   *  are done AFTER the use statements, which will NOT receive the
7958   *  pattern aplications.
7959   *
7960   *   Therefore it is decided to leave this "bad" mechanism until
7961   *  everybody is aware of this constraint.
7962   *
7963   *
7964   */
7965  Pattern::apply_all_globals ();
7966
7967  /*
7968    Select all possible tags
7969  */
7970
7971  Tag::restore_tree ();
7972
7973  return (1);
7974}
7975
7976//----------------------------------------------------------
7977static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
7978                                 const cmt_string& path)
7979{
7980  static cmt_string fs = CmtSystem::file_separator ();
7981  cmt_string result;
7982
7983  /*
7984  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
7985  {
7986  */
7987
7988  //
7989  //  If there is a common prefix between
7990  //  use->real_path and pwd
7991  //  we have
7992  //  use->real_path = /<prefix>/aaa
7993  //  pwd            = /<prefix>/bbb
7994  //
7995  //  Then use->real_path may be expressed as:
7996  //  ../..../../aaa
7997  //   where ../..../../ moves up to /<prefix>
7998  //
7999  //   Then we try to find the shortest between
8000  //
8001  //     /<prefix> and ../..../..
8002  //
8003  cmt_string a = path;
8004 
8005  CmtSystem::cmt_string_vector va;
8006 
8007  va.clear ();
8008 
8009  CmtSystem::split (a, fs, va);
8010 
8011  int m = va.size ();
8012  if (pwd.size () < m) m = pwd.size ();
8013 
8014  int i;
8015 
8016  for (i = 0; i < m; i++)
8017    {
8018      const cmt_string& fa = va[i];
8019      const cmt_string& fb = pwd[i];
8020     
8021      if (fa != fb) break;
8022    }
8023 
8024  cmt_string ups = "";
8025 
8026  if (i > 0)
8027    {
8028      // We have the prefix.
8029      // if we count what remains from pwd, then
8030      // we have the number of ../ required to
8031      // move to /<prefix>
8032      int j;
8033     
8034      for (j = i; j < pwd.size (); j++)
8035        {
8036          if (j > i) ups += fs;
8037          ups += "..";
8038        }
8039
8040      for (j = i; j < va.size (); j++)
8041        {
8042          ups += fs;
8043          ups += va[j];
8044        }
8045    }
8046 
8047  //
8048  // Here ups contains the ../..../../aaa form
8049  // for the use->real_path or is empty when there
8050  // were no common prefix.
8051  //
8052 
8053  //if (ups != "")
8054  if ((ups != "") &&
8055      (ups.size () < path.size ()))
8056    {
8057      result = ups;
8058    }
8059  else
8060    {
8061      result = path;
8062    }
8063
8064  return (result);
8065}
8066
8067/**
8068 *   This completely local class holds primitive actions for building
8069 *   standard macros.
8070 */
8071class StandardMacroBuilder
8072{
8073public:
8074
8075  /**
8076   *  CMTVERSION
8077   */
8078  void fill_for_CMTVERSION ()
8079  {
8080    buffer = "macro CMTVERSION \"";
8081    buffer += CMTVERSION;
8082    buffer += "\"";
8083    apply ();
8084  }
8085
8086  StandardMacroBuilder (const cmt_string& tag,
8087                        const cmt_string& package,
8088                        const cmt_string& version,
8089                        const cmt_string& prefix,
8090                        CmtDirStyle style)
8091  {
8092    fs = CmtSystem::file_separator ();
8093    buffer = "";
8094    pwd = CmtSystem::pwd ();
8095    CmtSystem::split (pwd, fs, vb);
8096    current_use = &(Use::current ());
8097    current_tag = tag;
8098    current_package = package;
8099    current_version = version;
8100    current_prefix = prefix;
8101    current_style = style;
8102  }
8103
8104  void apply ()
8105  {
8106    SyntaxParser::parse_requirements_line (buffer, current_use);
8107    buffer = "";
8108  }
8109
8110  /**
8111   *   tag
8112   */
8113  void fill_for_tag ()
8114  {
8115    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
8116
8117    if (!Symbol::is_selected ("tag"))
8118      {
8119        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
8120
8121        if (current_tag == "")
8122          {
8123            buffer = "macro tag \"$(CMTCONFIG)\"";
8124          }
8125        else
8126          {
8127            buffer = "macro tag \"";
8128            buffer += current_tag;
8129            buffer += "\"";
8130          }
8131       
8132        if (tag_debug) cerr << " define tag: " << buffer << endl;
8133       
8134        apply ();
8135      }
8136  }
8137
8138  /**
8139   *   PACKAGE_ROOT
8140   */
8141  void fill_for_package (const cmt_string& current_dir)
8142  {
8143    buffer = "macro package \"";
8144    buffer += current_package;
8145    buffer += "\"";
8146    apply ();
8147
8148    buffer = "macro version \"";
8149    buffer += current_version;
8150    buffer += "\"";
8151    apply ();
8152
8153    if (!Symbol::is_selected ("PACKAGE_ROOT"))
8154      {
8155        buffer = "macro PACKAGE_ROOT \"$(";
8156        buffer += current_prefix;
8157        buffer += "ROOT";
8158        buffer += ")\"";
8159
8160        apply ();
8161      }
8162  }
8163
8164  /**
8165   *   srcdir
8166   *   src       =$(srcdir)/
8167   *   inc
8168   *   mgrdir
8169   *   mgr       =../$(mgrdir)/
8170   *   bin
8171   *   javabin
8172   *   doc
8173   *   version
8174   *   package
8175   *
8176   *   <package>_project
8177   *   <package>_cmtpath
8178   *   <package>_offset
8179   *   package_cmtpath
8180   *   package_offset
8181   *   project
8182   *
8183   */
8184  void fill_for_branches ()
8185  {
8186    /**
8187     *    Basic macros  (src, mgr, ...)
8188     */
8189   
8190    if (current_style == none_style)
8191      {
8192        if (!Symbol::is_selected ("srcdir"))
8193          {
8194            buffer = "macro srcdir \".";
8195            buffer += "\"";
8196            apply ();
8197          }
8198
8199        if (!Symbol::is_selected ("src"))
8200          {
8201            buffer = "macro src \".";
8202            buffer += fs;
8203            buffer += "\"";
8204            apply ();
8205          }
8206
8207        if (!Symbol::is_selected ("inc"))
8208          {
8209            buffer = "macro inc \".";
8210            buffer += fs;
8211            buffer += "\"";
8212            apply ();
8213          }
8214
8215        if (!Symbol::is_selected ("doc"))
8216          {
8217            buffer = "macro doc \".";
8218            buffer += fs;
8219            buffer += "\"";
8220            apply ();
8221          }
8222
8223        if (!Symbol::is_selected ("bin"))
8224          {
8225            buffer = "macro bin \".";
8226            buffer += fs;
8227            buffer += "\"";
8228            apply ();
8229          }
8230
8231        if (!Symbol::is_selected ("BIN"))
8232          {
8233            /*
8234            buffer = "macro BIN \"";
8235            buffer += pwd;
8236            buffer += fs;
8237            buffer += "\"";
8238            apply ();
8239            */
8240            cmt_string temp = "$(bin)";
8241            Symbol::expand (temp);
8242            int len (temp.size());
8243            cmt_string atemp;
8244            if (CmtSystem::absolute_path (temp))
8245              {
8246                CmtSystem::compress_path (temp, atemp);
8247              }
8248            else
8249              {
8250                atemp = pwd + fs + temp;
8251                CmtSystem::compress_path (atemp);
8252              }
8253            buffer = "macro BIN \"";
8254            buffer += atemp;
8255            buffer += "\"";
8256            apply ();
8257            if (0 != len && fs != temp[len - 1])
8258              {
8259                buffer = "macro_append bin \"";
8260                buffer += fs;
8261                buffer += "\"";
8262                apply ();
8263
8264                buffer = "macro_append BIN \"";
8265                buffer += fs;
8266                buffer += "\"";
8267                apply ();
8268              }
8269          }
8270
8271        if (!Symbol::is_selected ("javabin"))
8272          {
8273            buffer = "macro javabin \".";
8274            buffer += fs;
8275            buffer += "\"";
8276            apply ();
8277          }
8278
8279        if (!Symbol::is_selected ("mgr"))
8280          {
8281            buffer = "macro mgr \".";
8282            buffer += fs;
8283            buffer += "\"";
8284            apply ();
8285          }
8286      }
8287    else
8288      {
8289        if (!Symbol::is_selected ("srcdir"))
8290          {
8291            buffer = "macro srcdir \"..";
8292            buffer += fs;
8293            buffer += "src";
8294            buffer += "\"";
8295            apply ();
8296          }
8297       
8298        if (!Symbol::is_selected ("src"))
8299          {
8300            buffer = "macro src \"..";
8301            buffer += fs;
8302            buffer += "src";
8303            buffer += fs;
8304            buffer += "\"";
8305            apply ();
8306          }
8307       
8308        if (!Symbol::is_selected ("inc"))
8309          {
8310            buffer = "macro inc \"..";
8311            buffer += fs;
8312            buffer += "src";
8313            buffer += fs;
8314            buffer += "\"";
8315            apply ();
8316          }
8317       
8318        if (!Symbol::is_selected ("doc"))
8319          {
8320            buffer = "macro doc \"..";
8321            buffer += fs;
8322            buffer += "doc";
8323            buffer += fs;
8324            buffer += "\"";
8325            apply ();
8326          }
8327       
8328        if (!Symbol::is_selected ("bin"))
8329          {
8330            cmt_string package_tag = current_package;
8331            package_tag += "_tag";
8332
8333            buffer = "macro bin \"..";
8334            buffer += fs;
8335            buffer += "$(";
8336            buffer += package_tag;
8337            buffer += ")";
8338            buffer += fs;
8339            buffer += "\"";
8340            apply ();
8341          }
8342
8343        if (!Symbol::is_selected ("BIN"))
8344          {
8345            /*
8346            cmt_string pardir;
8347            CmtSystem::dirname (pwd, pardir);
8348            //            buffer = "macro BIN \"$(PACKAGE_ROOT)";
8349            buffer = "macro BIN \"";
8350            buffer += pardir;
8351            buffer += fs;
8352            buffer += "$(";
8353            buffer += package_tag;
8354            buffer += ")";
8355            buffer += fs;
8356            buffer += "\"";
8357            apply ();
8358            */
8359            cmt_string temp = "$(bin)";
8360            Symbol::expand (temp);
8361            int len (temp.size());
8362            cmt_string atemp;
8363            if (CmtSystem::absolute_path (temp))
8364              {
8365                CmtSystem::compress_path (temp, atemp);
8366              }
8367            else
8368              {
8369                atemp = pwd + fs + temp;
8370                CmtSystem::compress_path (atemp);
8371              }
8372            buffer = "macro BIN \"";
8373            buffer += atemp;
8374            buffer += "\"";
8375            apply ();
8376            if (0 != len && fs != temp[len - 1])
8377              {
8378                buffer = "macro_append bin \"";
8379                buffer += fs;
8380                buffer += "\"";
8381                apply ();
8382
8383                buffer = "macro_append BIN \"";
8384                buffer += fs;
8385                buffer += "\"";
8386                apply ();
8387              }
8388          }
8389
8390        if (!Symbol::is_selected ("javabin"))
8391          {
8392            buffer = "macro javabin \"..";
8393            buffer += fs;
8394            buffer += "classes";
8395            buffer += fs;
8396            buffer += "\"";
8397            apply ();
8398          }
8399       
8400        if (current_style == mgr_style)
8401          {
8402            buffer = "macro mgrdir \"mgr\"";
8403            apply ();
8404
8405            buffer = "macro mgr \"..";
8406            buffer += fs;
8407            buffer += "mgr";
8408            buffer += fs;
8409            buffer += "\"";
8410            apply ();
8411          }
8412        else
8413          {
8414            buffer = "macro mgrdir \"cmt\"";
8415            apply ();
8416
8417            buffer = "macro mgr \"..";
8418            buffer += fs;
8419            buffer += "cmt";
8420            buffer += fs;
8421            buffer += "\"";
8422            apply ();
8423          }
8424
8425        Cmt::configure_current_cmtpath ();
8426      }
8427  }
8428
8429  /**
8430   *   project
8431   */
8432  void fill_for_project ()
8433  {
8434    if (current_style == none_style) return;
8435
8436    cmt_string project_name;
8437    Project* project = Project::get_current ();
8438    if (project != 0)
8439      {
8440        project_name = project->get_name ();
8441      }
8442
8443    buffer = "macro project \"";
8444    buffer += project_name;
8445    buffer += "\"";
8446    apply ();
8447  }
8448
8449  /**
8450   *   use_requirements
8451   */
8452  void fill_for_use_requirements ()
8453  {
8454    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8455
8456    if (Uses.size () == 0) return;
8457
8458    if (!Symbol::is_selected ("use_requirements"))
8459      {
8460        buffer  = "macro use_requirements \"";
8461        buffer += "requirements ";
8462       
8463        for (int number = 0; number < Uses.size (); number++)
8464          {
8465            Use* use = Uses[number];
8466           
8467            if (use->discarded) continue;
8468            if (use->m_hidden) continue;
8469           
8470            if (use->located ())
8471              {
8472                buffer += "$(";
8473                buffer += use->get_package_name ();
8474                buffer += "_root)";
8475//                 buffer += use->prefix;
8476//                 buffer += "ROOT)";
8477               
8478                if (use->style == cmt_style)
8479                  {
8480                    buffer += fs;
8481                    buffer += "cmt";
8482                  }
8483                else if (use->style == mgr_style)
8484                  {
8485                    buffer += fs;
8486                    buffer += "mgr";
8487                  }
8488                //                else buffer += "cmt";
8489               
8490                buffer += fs;
8491                buffer += "requirements ";
8492              }
8493          }
8494       
8495        buffer += "\"";
8496       
8497        apply ();
8498      }
8499  }
8500
8501  /**
8502   *   use_includes
8503   */
8504  void fill_for_use_includes ()
8505  {
8506    Include::parse_all (&(Use::current()));
8507
8508    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8509
8510    if (Uses.size () == 0) return;
8511
8512    if (!Symbol::is_selected ("use_includes"))
8513      {
8514        buffer = "macro_append use_includes \' ";
8515       
8516        for (int number = 0; number < Uses.size (); number++)
8517          {
8518            Use* use = Uses[number];
8519           
8520            if (use->discarded) continue;
8521            if (use->m_hidden) continue;
8522
8523            Package* p = use->get_package ();
8524            if (p->is_cmt ()) continue;
8525
8526            if (Cmt::get_debug ())
8527              {
8528                cout << "fill use_includes for " << use->get_package_name () 
8529                     << " discarded=" << use->discarded
8530                     << " auto_imports=" << use->auto_imports << endl;
8531              }
8532           
8533            if (use->auto_imports == Off) continue;
8534           
8535            Include::parse_all (use);
8536
8537            use->fill_includes_macro (buffer);
8538          }
8539       
8540        buffer += "\'";
8541       
8542        apply ();
8543      }
8544  }
8545
8546  /**
8547   *   use_fincludes
8548   */
8549  void fill_for_use_fincludes ()
8550  {
8551    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8552
8553    if (Uses.size () == 0) return;
8554
8555    if (!Symbol::is_selected ("use_fincludes"))
8556      {
8557        buffer = "macro_append use_fincludes \" $(use_includes)\"";
8558        apply ();
8559      }
8560  }
8561
8562  /**
8563   *   use_stamps
8564   */
8565  void fill_for_use_stamps ()
8566  {
8567    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8568
8569    if (Uses.size () == 0) return;
8570
8571    if (!Symbol::is_selected ("use_stamps"))
8572      {
8573        /*
8574        buffer = "macro use_stamps \"";
8575        (Use::current()).fill_macro (buffer, "stamps");
8576       
8577        for (int number = 0; number < Uses.size (); number++)
8578          {
8579            Use* use = Uses[number];
8580           
8581            if (use->discarded) continue;
8582            if (use->m_hidden) continue;
8583
8584            Package* p = use->get_package ();
8585            if (p->is_cmt ()) continue;
8586           
8587            use->fill_macro (buffer, "stamps");
8588          }
8589       
8590        buffer += "\"";
8591        */
8592        Use::fill_macro_all (buffer, "stamps");
8593        apply ();
8594      }
8595  }
8596
8597  /**
8598   *   use_cflags
8599   */
8600  void fill_for_use_cflags ()
8601  {
8602    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8603
8604    if (Uses.size () == 0) return;
8605
8606    if (!Symbol::is_selected ("use_cflags"))
8607      {
8608        Use::fill_macro_all (buffer, "cflags");
8609        apply ();
8610      }
8611  }
8612
8613  /**
8614   *   use_pp_cflags
8615   */
8616  void fill_for_use_pp_cflags ()
8617  {
8618    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8619
8620    if (Uses.size () == 0) return;
8621
8622    if (!Symbol::is_selected ("use_pp_cflags"))
8623      {
8624        Use::fill_macro_all (buffer, "pp_cflags");
8625        apply ();
8626      }
8627  }
8628
8629  /**
8630   *   use_cppflags
8631   */
8632  void fill_for_use_cppflags ()
8633  {
8634    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8635
8636    if (Uses.size () == 0) return;
8637
8638    if (!Symbol::is_selected ("use_cppflags"))
8639      {
8640        Use::fill_macro_all (buffer, "cppflags");
8641        apply ();
8642      }
8643  }
8644
8645  /**
8646   *   use_pp_cppflags
8647   */
8648  void fill_for_use_pp_cppflags ()
8649  {
8650    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8651
8652    if (Uses.size () == 0) return;
8653
8654    if (!Symbol::is_selected ("use_pp_cppflags"))
8655      {
8656        Use::fill_macro_all (buffer, "pp_cppflags");
8657        apply ();
8658      }
8659  }
8660
8661  /**
8662   *   use_fflags
8663   */
8664  void fill_for_use_fflags ()
8665  {
8666    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8667
8668    if (Uses.size () == 0) return;
8669
8670    if (!Symbol::is_selected ("use_fflags"))
8671      {
8672        Use::fill_macro_all (buffer, "fflags");
8673        apply ();
8674      }
8675  }
8676
8677  /**
8678   *   use_pp_fflags
8679   */
8680  void fill_for_use_pp_fflags ()
8681  {
8682    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8683
8684    if (Uses.size () == 0) return;
8685
8686    if (!Symbol::is_selected ("use_pp_fflags"))
8687      {
8688        Use::fill_macro_all (buffer, "pp_fflags");
8689        apply ();
8690      }
8691  }
8692
8693  /**
8694   *   use_linkopts
8695   */
8696  void fill_for_use_linkopts ()
8697  {
8698    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8699
8700    if (Uses.size () == 0) return;
8701
8702    if (!Symbol::is_selected ("use_linkopts"))
8703      {
8704        Use::fill_macro_all (buffer, "linkopts");
8705        apply ();
8706      }
8707  }
8708
8709  /**
8710   *   use_libraries
8711   */
8712  void fill_for_use_libraries ()
8713  {
8714    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8715
8716    if (Uses.size () == 0) return;
8717
8718    if (!Symbol::is_selected ("use_libraries"))
8719      {
8720        buffer  = "macro use_libraries \"";
8721
8722        for (int number = 0; number < Uses.size (); number++)
8723          {
8724            Use* use = Uses[number];
8725           
8726            if (use->discarded) continue;
8727            if (use->m_hidden) continue;
8728           
8729            Package* p = use->get_package ();
8730            if (p->is_cmt ()) continue;
8731
8732            use->fill_macro (buffer, "libraries");
8733          }
8734       
8735        buffer += "\"";
8736
8737        apply ();
8738      }
8739  }
8740
8741  /**
8742   *   includes
8743   */
8744  void fill_for_includes ()
8745  {
8746    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8747
8748    if (Uses.size () == 0) return;
8749
8750    if (!Symbol::is_selected ("includes"))
8751      {
8752        buffer = "macro_append includes \' ";
8753
8754        Use& use = Use::current();
8755
8756        if (use.include_path == "")
8757          {
8758            buffer += "$(ppcmd)\"$(srcdir)\" ";
8759          }
8760        else if (use.include_path != "none")
8761          {
8762            buffer += "$(ppcmd)\"";
8763            buffer += use.include_path;
8764            buffer += "\" ";
8765          }
8766
8767        for (int include_number = 0;
8768             include_number < use.includes.size ();
8769             include_number++)
8770          {
8771            Include& incl = use.includes[include_number];
8772
8773            if (incl.name == "") continue;
8774
8775            buffer += "$(ppcmd)\"";
8776            buffer += incl.name;
8777            buffer += "\" ";
8778          }
8779       
8780        buffer += "$(use_includes)\'";
8781       
8782        apply ();
8783      }
8784  }
8785
8786  /**
8787   *   fincludes
8788   */
8789  void fill_for_fincludes ()
8790  {
8791    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8792
8793    if (Uses.size () == 0) return;
8794
8795    if (!Symbol::is_selected ("fincludes"))
8796      {
8797        buffer = "macro_append fincludes \" $(includes)\"";
8798        apply ();
8799      }
8800  }
8801
8802  /**
8803   *  Macros specific to constituents.
8804   *  This includes the compiler flags
8805   *  and fills in these macros from uses packages. This takes care
8806   *  of -no_auto_imports and -import= directives
8807   *
8808   *    <constituent>_use_linkopts
8809   *    <prefix>_<constituent>_cflags
8810   *    <prefix>_<constituent>_pp_cflags
8811   *    <prefix>_<constituent>_cppflags
8812   *    <prefix>_<constituent>_pp_cppflags
8813   *    <prefix>_<constituent>_fflags
8814   *    <prefix>_<constituent>_pp_fflags
8815   *    <constituent>linkopts
8816   *    <constituent>_GUID
8817   *    <constituent>_stamps
8818   *
8819   */
8820  void fill_for_all_constituents ()
8821  {
8822    /// First, finish the parsing of constituent parameters.
8823    if (Cmt::get_debug ())
8824      {
8825        cout << "fill_for_all_constituents>" << endl;
8826      }
8827
8828    Constituent::parse_all ();
8829
8830    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
8831   
8832    const Constituent::ConstituentVector& constituents =
8833      Constituent::constituents ();
8834
8835 
8836    // Prepare the auto_imports states in a vector
8837    cmt_vector<bool> base_auto_imports_states;
8838
8839    base_auto_imports_states.resize (Uses.size ());
8840
8841    int number;
8842   
8843    for (number = 0; number < Uses.size (); number++)
8844      {
8845        Use* use = Uses[number];
8846        base_auto_imports_states[number] = (use->auto_imports != Off);
8847      }
8848   
8849    // Now scan all constituents
8850       
8851    for (number = 0; number < constituents.size (); number++)
8852      {
8853        const Constituent& constituent = constituents[number];
8854       
8855        //==== GLAST addition for vs.net ==========
8856        buffer = "macro ";
8857        buffer += constituent.name;
8858        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
8859        apply ();
8860       
8861        if (Cmt::get_debug ())
8862          {
8863            cout << "Checking " << constituent.name  << " against imports requests" << endl;
8864          }
8865        Use::UsePtrVector imports;
8866        int i;
8867       
8868        /**
8869         *  Problem for imports in constituents.
8870         *
8871         *     1) use_xxx has holes due to the corresponding
8872         *         -no_auto_imports options attached to some
8873         *        use statements (including the transitive ones)
8874         *
8875         *     2) the -import=yyy options provided to a given constituent
8876         *        should restore the appropriate holes as well as
8877         *        all transitive ones.
8878         *
8879         *     3) for use_linkopts, missing pieces must be filled at
8880         *        the right position. (for others, order is not relevant
8881         *        while transitive access is required for all)
8882         *
8883         */
8884       
8885        if (constituent.type == Document)
8886          { 
8887            continue;
8888          }
8889       
8890        if (constituent.imports.size () == 0) 
8891          {
8892            buffer = "macro_append ";
8893            buffer += constituent.name;
8894            buffer += "_use_linkopts ";
8895            buffer += " \" ";
8896           
8897            current_use->fill_macro (buffer, "linkopts");
8898           
8899            for (i = 0; i < Uses.size (); i++)
8900              {
8901                if (base_auto_imports_states[i])
8902                  {
8903                    Use* u = Uses[i];
8904                   
8905                    if (u->discarded) continue;
8906                    if (u->m_hidden) continue;
8907                   
8908                    Package* p = u->get_package ();
8909                    if (p->is_cmt ()) continue;
8910                   
8911                    u->fill_macro (buffer, "linkopts");
8912                  }
8913              }
8914            buffer += "\"";
8915            apply ();
8916           
8917            /*
8918              buffer = "macro_append ";
8919              buffer += constituent.name;
8920              buffer += "_use_linkopts ";
8921             
8922              buffer += " \" $(use_linkopts)\"";
8923              apply ();
8924            */
8925           
8926            continue;
8927          }
8928       
8929        // From here on, the constituent HAS import options.
8930       
8931        /**
8932         * Create a private copy of the state vector. This private copy
8933         * will be updated according to -import=xxx modifiers for the
8934         * current constituent.
8935         */
8936        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
8937       
8938        for (i = 0; i < constituent.imports.size (); i++)
8939          {
8940            const cmt_string& import = constituent.imports[i];
8941           
8942            //
8943            // Resolve the imported uses
8944            //
8945           
8946            int use_index = Use::find_index (import, "", "");
8947           
8948            if (use_index >= 0)
8949              {
8950                Use* u = Uses[use_index];
8951               
8952                if (u->discarded) continue;
8953                if (u->m_hidden) continue;
8954               
8955                if (Cmt::get_debug ())
8956                  {
8957                    cout << constituent.name  << " needs imports " << import << " "
8958                         << use_index << " " 
8959                         << u->get_package()->get_name() << " "
8960                         << " u->auto_imports=" << u->auto_imports
8961                         << " Off=" << Off
8962                         << " On=" << On
8963                         << endl;
8964                  }
8965               
8966                Package* p = u->get_package ();
8967                if (p->is_cmt ()) continue;
8968               
8969                if (u->auto_imports != Off) continue;
8970               
8971                Use::set_auto_imports_state (use_index, auto_imports_states);
8972              }
8973            else
8974              {
8975                if (Me.m_action == action_build_constituents_makefile ||
8976                    Me.m_action == action_build_constituents_config)
8977                  CmtMessage::warning ("package " + import +
8978                                       " cannot be imported (requested for " +
8979                                       constituent.name +")");
8980              }
8981          }
8982       
8983        if (Cmt::get_debug ())
8984          {
8985            cout << constituent.name  << " has imports " << endl;
8986          }
8987       
8988       
8989        /**
8990         *   Find all newly exposed packages and precompute this list inside
8991         *   a vector.
8992         */
8993        for (i = 0; i < base_auto_imports_states.size (); i++)
8994          {
8995            //      if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
8996            if (base_auto_imports_states[i] == On || auto_imports_states[i] == Off) continue;
8997            /**
8998             *  Consider the package (i) for import only if it is:
8999             *   o not imported yet (i.e., base_auto_imports_states[i] != On)
9000             *   o requested for import according to -import=xxx modifiers for
9001             *     the current constituent (i.e., auto_imports_states[i] != Off)
9002             */
9003            Use* u = Uses[i];
9004           
9005            if (u->discarded) continue;
9006            if (u->m_hidden)  continue;
9007           
9008            Package* p = u->get_package ();
9009            if (p->is_cmt ()) continue;
9010           
9011            if (Cmt::get_debug ())
9012              {
9013                cout << constituent.name  << " has import " << p->get_name () << endl;
9014              }
9015           
9016            imports.push_back (u);
9017          }
9018       
9019        /**
9020         *  Only for linkopts we take care of the order. This means
9021         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
9022         *
9023         *  (see the application fragments)
9024         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
9025         */
9026        buffer = "macro_append ";
9027        buffer += constituent.name;
9028        buffer += "_use_linkopts ";
9029        buffer += " \" ";
9030       
9031        current_use->fill_macro (buffer, "linkopts");
9032       
9033        for (i = 0; i < Uses.size (); i++)
9034          {
9035            if (auto_imports_states[i])
9036              {
9037                Use* u = Uses[i];
9038               
9039                if (u->discarded) continue;
9040                if (u->m_hidden) continue;
9041               
9042                Package* p = u->get_package ();
9043                if (p->is_cmt ()) continue;
9044               
9045                u->fill_macro (buffer, "linkopts");
9046              }
9047          }
9048        buffer += "\"";
9049        apply ();
9050       
9051        if (imports.size () == 0) continue;
9052       
9053        cmt_string prefix;
9054       
9055        //
9056        // Documents are not considered
9057        //
9058        switch (constituent.type)
9059          {
9060          case Application:
9061            prefix = "app_";
9062            break;
9063          case Library:
9064            prefix = "lib_";
9065            break;
9066          }
9067       
9068        buffer = "macro_append ";
9069        buffer += prefix;
9070        buffer += constituent.name;
9071        buffer += "_cflags ";
9072        buffer += " \' ";
9073        for (i = 0; i < imports.size (); i++)
9074          {
9075            Use* u = imports[i];
9076           
9077            u->fill_includes_macro (buffer);
9078            u->fill_macro (buffer, "cflags");
9079          }
9080        buffer += "\'";
9081        apply ();
9082       
9083        buffer = "macro_append ";
9084        buffer += prefix;
9085        buffer += constituent.name;
9086        buffer += "_pp_cflags ";
9087        buffer += " \" ";
9088        for (i = 0; i < imports.size (); i++)
9089          {
9090            Use* u = imports[i];
9091           
9092            u->fill_macro (buffer, "pp_cflags");
9093          }
9094        buffer += "\"";
9095        apply ();
9096       
9097        buffer = "macro_append ";
9098        buffer += prefix;
9099        buffer += constituent.name;
9100        buffer += "_cppflags ";
9101        buffer += " \' ";
9102        for (i = 0; i < imports.size (); i++)
9103          {
9104            Use* u = imports[i];
9105           
9106            u->fill_includes_macro (buffer);
9107            u->fill_macro (buffer, "cppflags");
9108          }
9109        buffer += "\'";
9110        apply ();
9111       
9112        buffer = "macro_append ";
9113        buffer += prefix;
9114        buffer += constituent.name;
9115        buffer += "_pp_cppflags ";
9116        buffer += " \" ";
9117        for (i = 0; i < imports.size (); i++)
9118          {
9119            Use* u = imports[i];
9120           
9121            u->fill_macro (buffer, "pp_cppflags");
9122          }
9123        buffer += "\"";
9124        apply ();
9125       
9126        buffer = "macro_append ";
9127        buffer += prefix;
9128        buffer += constituent.name;
9129        buffer += "_fflags ";
9130        buffer += " \' ";
9131        for (i = 0; i < imports.size (); i++)
9132          {
9133            Use* u = imports[i];
9134           
9135            u->fill_includes_macro (buffer);
9136            u->fill_macro (buffer, "fflags");
9137          }
9138        buffer += "\'";
9139        apply ();
9140       
9141        buffer = "macro_append ";
9142        buffer += prefix;
9143        buffer += constituent.name;
9144        buffer += "_pp_fflags ";
9145        buffer += " \" ";
9146        for (i = 0; i < imports.size (); i++)
9147          {
9148            Use* u = imports[i];
9149           
9150            u->fill_macro (buffer, "pp_fflags");
9151          }
9152        buffer += "\"";
9153        apply ();
9154
9155        buffer = "macro_append ";
9156        buffer += constituent.name;
9157        buffer += "_stamps ";
9158        buffer += " \" ";
9159        for (i = 0; i < imports.size (); i++)
9160          {
9161            Use* u = imports[i];
9162           
9163            u->fill_macro (buffer, "stamps");
9164          }
9165        buffer += "\"";
9166        apply ();
9167
9168        /**
9169         *  Setting ${CONSTITUENT}linkopts is a temporary solution
9170         *  until the backward compatibility solution for a proper
9171         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
9172         *  is acheived.
9173         *
9174         */
9175        /**
9176        buffer = "macro_append ";
9177        buffer += constituent.name;
9178        buffer += "linkopts ";
9179        buffer += " \" ";
9180        for (i = 0; i < imports.size (); i++)
9181          {
9182            Use* u = imports[i];
9183           
9184            u->fill_macro (buffer, "linkopts");
9185          }
9186        buffer += "\"";
9187        apply ();
9188        */
9189      }
9190  }
9191 
9192  /**
9193   *   Macros implied or required to manage constituents.
9194   */
9195  void fill_for_constituent_macros ()
9196  {
9197    int number;
9198    cmt_string temp;
9199
9200    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
9201 
9202    if (!Symbol::is_selected ("constituents"))
9203      {
9204        temp = "macro_append constituents \" ";
9205       
9206        for (number = 0; number < constituents.size (); number++)
9207          {
9208            const Constituent& constituent = constituents[number];
9209           
9210            if (constituent.group == 0)
9211              {
9212                temp += constituent.name;
9213                temp += " ";
9214              }
9215          }
9216       
9217        temp += "\"";
9218       
9219        SyntaxParser::parse_requirements_line (temp, current_use);
9220      }
9221   
9222    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
9223                                           current_use);
9224   
9225    if (!Symbol::is_selected ("constituentsclean"))
9226      {
9227        temp = "macro_append constituentsclean \" ";
9228       
9229        for (number = constituents.size () - 1; number >= 0 ; number--)
9230          {
9231            const Constituent& constituent = constituents[number];
9232           
9233            if (constituent.group == 0)
9234              {
9235                temp += constituent.name;
9236                temp += "clean ";
9237              }
9238          }
9239       
9240        temp += "\"";
9241       
9242        SyntaxParser::parse_requirements_line (temp, current_use);
9243      }
9244   
9245    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
9246                                           current_use);
9247   
9248    const Group::GroupVector& groups = Group::groups ();
9249   
9250    for (number = 0; number < groups.size (); number++)
9251      {
9252        const Group& group = groups[number];
9253       
9254        temp = "macro_append ";
9255        temp += group.name ();
9256        temp += "_constituents \" ";
9257       
9258        int i;
9259       
9260        for (i = 0; i < constituents.size (); i++)
9261          {
9262            const Constituent& constituent = constituents[i];
9263           
9264            if ((constituent.group != 0) && 
9265                (group.name () == constituent.group->name ()))
9266              {
9267                temp += constituent.name;
9268                temp += " ";
9269              }
9270          }
9271       
9272        temp += "\"";
9273       
9274        SyntaxParser::parse_requirements_line (temp, current_use);
9275       
9276        temp = "macro_append ";
9277        temp += group.name ();
9278        temp += "_constituentsclean \" ";
9279       
9280        for (i = constituents.size () - 1; i >= 0 ; i--)
9281          {
9282            const Constituent& constituent = constituents[i];
9283           
9284            if ((constituent.group != 0) && 
9285                (group.name () == constituent.group->name ()))
9286              {
9287                temp += constituent.name;
9288                temp += "clean ";
9289              }
9290          }
9291       
9292        temp += "\"";
9293       
9294        SyntaxParser::parse_requirements_line (temp, current_use);
9295      }
9296  }
9297
9298  /**
9299   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
9300   */
9301  void fill_for_install_area ()
9302  {
9303    CmtPathPattern::apply_all ();
9304
9305    const Use& current_use = Use::current ();
9306
9307    if (current_use.get_strategy ("InstallArea"))
9308      {
9309        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
9310       
9311        ia_mgr.setup ();
9312      }
9313  }
9314
9315  /**
9316   * Macros to be defined once current_package is known
9317   * and even before reading its requirements file.
9318   */
9319  void fill_for_current_package (const cmt_string& current_dir)
9320  {
9321    fill_for_tag ();
9322    fill_for_package (current_dir);
9323  }
9324
9325private:
9326  cmt_string fs;
9327  cmt_string buffer;
9328  CmtSystem::cmt_string_vector vb;
9329  cmt_string pwd;
9330  Use* current_use;
9331  cmt_string current_tag; 
9332  cmt_string current_package; 
9333  cmt_string current_version; 
9334  cmt_string current_prefix; 
9335  CmtDirStyle current_style;
9336};
9337
9338//----------------------------------------------------------
9339void Cmt::set_current_access (AccessMode mode)
9340{
9341  Me.m_current_access = mode;
9342}
9343
9344//----------------------------------------------------------
9345void Cmt::set_recursive (bool mode)
9346{
9347  Me.m_recursive = mode;
9348}
9349
9350//----------------------------------------------------------
9351void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
9352{
9353  Me.m_scope_filtering_mode = mode;
9354}
9355
9356//----------------------------------------------------------
9357void Cmt::set_standard_macros ()
9358{
9359  if (Me.m_standard_macros_done) return;
9360
9361  Me.m_standard_macros_done = true;
9362
9363  //  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
9364  Use& current_use = Use::current ();
9365
9366  cmt_string fs = CmtSystem::file_separator ();
9367
9368  cmt_string pwd = CmtSystem::pwd ();
9369
9370  /**
9371   * This is a check for package names
9372   */
9373  if (CmtMessage::active (Verbose))
9374    {
9375      Use::UsePtrVector uses (Use::get_ordered_uses ());
9376      uses.push_back (&current_use);
9377      for (int i = uses.size () - 1; i >= 0; i--)
9378        {
9379          Use* use = uses[i];
9380          if (use->discarded) continue;
9381          if (use->m_hidden) continue;
9382          if (!use->located ()) continue;
9383          for (int j = i - 1; j >= 0; j--)
9384            {
9385              Use* use2 = uses[j];
9386              if (use2->discarded) continue;
9387              if (use2->m_hidden) continue;
9388              if (!use2->located ()) continue;
9389              if (use->prefix == use2->prefix)
9390                {
9391                  CmtMessage::warning (use->prefix + "ROOT, "
9392                                       + use->prefix + "VERSION ill-defined: "
9393                                       + use->get_package_name () + " and "
9394                                       + use2->get_package_name ()
9395                                       + " package name conflict");
9396                }
9397            }
9398        }
9399    }
9400  /**
9401   * This is already done in
9402   void Cmt::configure_current_package ()
9403
9404  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
9405  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
9406  else Me.m_current_style = none_style;
9407
9408  {
9409    cmt_string v;
9410    CmtSystem::dirname (pwd, v);
9411    CmtSystem::basename (v, v);
9412    if (!CmtSystem::is_version_directory (v))
9413      {
9414        Me.m_current_style = no_version_style;
9415      }
9416  }
9417  */
9418
9419  // Prepare computation of the best form for relative path from current directory
9420  // to package directories.
9421  CmtSystem::cmt_string_vector vb;
9422  CmtSystem::split (pwd, fs, vb);
9423
9424
9425  /**
9426   *    TAG management
9427   */
9428
9429  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
9430
9431  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
9432
9433  if (Me.m_current_tag != "")
9434    {
9435      // this is when some -tag= argument was used.
9436      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
9437    }
9438  else if (Symbol::is_selected ("CMTCONFIG"))
9439    {
9440      // This is when CMTCONFIG has been set from some requirements file
9441      Symbol* macro = Symbol::find ("CMTCONFIG");
9442      if (macro != 0)
9443        {
9444          Me.m_current_tag = macro->build_macro_value ();
9445          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
9446        }
9447    }
9448  else
9449    {
9450      // this is when no -tag= argument was used.
9451      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
9452      if (current_use.get_package_name () == "CMT")
9453        {
9454          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
9455        }
9456      else
9457        {
9458          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
9459        }
9460
9461      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
9462    }
9463
9464  if (Me.m_debug)
9465    {
9466      cout << "set_standard_macro3>" << endl;
9467    }
9468
9469  StandardMacroBuilder builder (Me.m_current_tag,
9470                                Me.m_current_package,
9471                                Me.m_current_version,
9472                                Me.m_current_prefix,
9473                                Me.m_current_style);
9474
9475
9476  builder.fill_for_current_package (Me.m_current_dir);
9477
9478  builder.fill_for_branches ();
9479  builder.fill_for_project ();
9480
9481  builder.fill_for_install_area ();
9482
9483  builder.fill_for_use_requirements ();
9484  builder.fill_for_use_includes ();
9485  builder.fill_for_use_fincludes ();
9486  builder.fill_for_use_stamps ();
9487  builder.fill_for_use_cflags ();
9488  builder.fill_for_use_pp_cflags ();
9489  builder.fill_for_use_cppflags ();
9490  builder.fill_for_use_pp_cppflags ();
9491  builder.fill_for_use_fflags ();
9492  builder.fill_for_use_pp_fflags ();
9493  builder.fill_for_use_linkopts ();
9494  builder.fill_for_use_libraries ();
9495  builder.fill_for_includes ();
9496  builder.fill_for_fincludes ();
9497  builder.fill_for_all_constituents ();
9498  builder.fill_for_constituent_macros ();
9499}
9500
9501void Cmt::set_all_sets_done ()
9502{
9503  Me.m_all_sets_done = true;
9504}
9505
9506void Cmt::reset_all_sets_done ()
9507{
9508  Me.m_all_sets_done = false;
9509}
9510
9511//----------------------------------------------------------
9512void Cmt::use_cmt ()
9513{
9514  UseRef use;
9515  bool recursive_copy = Me.m_recursive;
9516  bool debug_copy = Me.m_debug;
9517
9518  if (Me.m_default_path.size () <= 0) return;
9519  if (Me.m_current_package == "CMT") return;
9520
9521  Me.m_recursive = true;
9522  //Me.m_debug = false;
9523  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
9524  Me.m_recursive = recursive_copy;
9525  Me.m_debug = debug_copy;
9526}
9527
9528//----------------------------------------------------------
9529void Cmt::use_home_requirements ()
9530{
9531  use_special_requirements (Me.m_cmt_home, 
9532                            CmtSystem::get_home_package (), 
9533                            "requirements");
9534}
9535
9536//----------------------------------------------------------
9537void Cmt::use_user_context_requirements ()
9538{
9539  use_special_requirements (Me.m_cmt_user_context, 
9540                            CmtSystem::get_user_context_package (), 
9541                            "requirements");
9542}
9543
9544//----------------------------------------------------------
9545void Cmt::use_special_requirements (const cmt_string& path, 
9546                                    const cmt_string& name, 
9547                                    const cmt_string& file_name)
9548{
9549  if (path == "") 
9550    {
9551      return;
9552    }
9553
9554  UseRef use;
9555  bool recursive_copy = Me.m_recursive;
9556
9557  if (Me.m_default_path.size () <= 0) return;
9558  if (Me.m_current_package == "CMT") return;
9559
9560  Me.m_recursive = true;
9561
9562  use = Use::add (path, name, "v0", "", "", "", 0);
9563
9564  cmt_string f = path;
9565  f += CmtSystem::file_separator ();
9566  f += file_name;
9567  if (CmtSystem::test_file (f))
9568    {
9569      use->m_located = true;
9570    }
9571  SyntaxParser::parse_requirements (f, use);
9572
9573  Me.m_recursive = recursive_copy;
9574}
9575
9576//-------------------------------------------------
9577void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
9578                            const cmt_string& separator,
9579                            cmt_string& result)
9580{
9581  result.erase (0);
9582
9583  for (int i = 0; i < v.size (); i++)
9584    {
9585      const cmt_string& s = v[i];
9586      if (s == "") continue;
9587
9588      if (i > 0) result += separator;
9589      result += v[i];
9590    }
9591}
9592
9593//-------------------------------------------------
9594cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
9595{
9596  cmt_string result;
9597
9598  vector_to_string (v, " ", result);
9599
9600  return (result);
9601}
Note: See TracBrowser for help on using the repository browser.