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

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

See C.L. 472

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