source: CMT/v1r20p20070517/source/cmt_parser.cxx

Last change on this file was 411, checked in by arnault, 17 years ago

Management of the -quiet option
Bug fixing in cmt_cvs.cxx
CL 329

  • Property svn:eol-style set to native
File size: 186.2 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_lock.h"
27#include "cmt_triggers.h"
28#include "cmt_model.h"
29#include "cmt_awk.h"
30#include "cmt_syntax.h"
31#include "cmt_install_area.h"
32#include "cmt_cmtpath_pattern.h"
33#include "cmt_sequence.h"
34#include "cmt_map.h"
35#include "cmt_project.h"
36#include "cmt_log.h"
37#include "cmt_commands.h"
38
39//----------------------------------------------------------
40//
41//  Static object definitions for the CmtContext class.
42//
43
44static CmtContext Me;
45
46CmtContext::CmtContext ()
47{
48  clear ();
49}
50
51CmtContext::~CmtContext ()
52{
53}
54
55void CmtContext::clear ()
56{
57  m_action         = action_none;
58  m_build_nmake    = false;
59  m_cmt_config     = "";
60  //m_cmt_path.clear ();
61  //m_cmt_path_pwds.clear ();
62  //m_cmt_path_sources.clear ();
63  m_cmt_root       = "";
64  m_cmt_version    = "";
65  m_current_dir     = "";
66  m_current_file_path = "";
67  m_current_package = "";
68  m_current_config  = "";
69  m_current_path    = "";
70  m_current_prefix  = "";
71  m_current_cmtpath = "";
72  m_current_offset  = "";
73
74  m_current_access   = DeveloperMode;
75
76  m_current_tag      = "";
77  m_current_target   = "";
78  m_current_version  = "";
79  m_default_path     = "";
80
81  //m_quiet            = false;
82
83  m_disable_warnings = false;
84  m_warnings         = false;
85  m_recursive        = false;
86
87  m_scope_filtering_mode = default_filtering_mode;
88  m_simulation       = false;
89
90  m_standard_macros_done = false;
91  m_current_access = UserMode;
92  m_current_style = cmt_style;
93  m_current_structuring_style = default_structuring_style;
94  m_all_sets_done = false;
95  m_autoconfigure_cmtpath = false;
96  m_debug = false;
97  if (getenv ("CMTDEBUG") != 0) m_debug = true;
98}
99
100//----------------------------------------------------------
101
102
103//----------------------------------------------------------
104//
105//   Utility classes
106//
107//----------------------------------------------------------
108
109/**
110 *  This PathScanner actor simply displays the package name/version/path
111 *  It is used by the cmt show packages operation
112 */
113class PackageViewer : public PathScanner::actor
114{
115public:
116  void run (const cmt_string& package,
117            const cmt_string& version,
118            const cmt_string& path,
119            const bool without_version_directory=false);
120};
121
122
123/**
124 *  This PathScanner actor accumulates all found packages into a cmt_string_vector
125 *  It is used by the broadcast operation
126 */
127class PackageSelector : public PathScanner::actor
128{
129public:
130  PackageSelector (CmtSystem::cmt_string_vector& uses);
131  void run (const cmt_string& package,
132            const cmt_string& version,
133            const cmt_string& path,
134            const bool without_version_directory=false);
135private:
136  CmtSystem::cmt_string_vector& m_uses;
137};
138
139
140
141/**
142 *  This PathScanner actor collects all packages clients of the specified one
143 *  It is used by the cmt show clients operation
144 */
145class ClientCollector : public PathScanner::actor
146{
147public:
148  ClientCollector (const cmt_string& package,
149                   const cmt_string& version);
150  void run (const cmt_string& package,
151            const cmt_string& version,
152            const cmt_string& path,
153            const bool without_version_directory=false);
154  int count ();
155
156private:
157  const cmt_string& m_package;
158  const cmt_string& m_version;
159  int m_count;
160};
161
162//----------------------------------------------------------
163void PackageViewer::run (const cmt_string& package,
164                         const cmt_string& version,
165                         const cmt_string& path,
166                         const bool without_version_directory)
167{
168  cout << package << " " << version << " " << path << endl;
169}
170
171//----------------------------------------------------------
172PackageSelector::PackageSelector (CmtSystem::cmt_string_vector& uses) : m_uses(uses)
173{
174}
175
176//----------------------------------------------------------
177void PackageSelector::run (const cmt_string& package,
178                           const cmt_string& version,
179                           const cmt_string& path,
180                           const bool without_version_directory)
181{
182  //
183  // this might be called on a package with no version directory.
184  // then simply the version argument is empty.
185  //
186
187  cmt_string r = CmtSystem::file_separator ();
188  r += "requirements";
189
190  cmt_string temp;
191
192  if (version == "")
193    {
194      temp = path;
195      //temp += CmtSystem::file_separator ();
196      //temp += package;
197      temp += CmtSystem::file_separator ();
198      temp += "cmt";
199      temp += r;
200     
201      if (!CmtSystem::test_file (temp)) return;
202    }
203  else
204    {
205      temp = path;
206      //temp += CmtSystem::file_separator ();
207      //temp += package;
208      temp += CmtSystem::file_separator ();
209      temp += version;
210      temp += CmtSystem::file_separator ();
211      temp += "cmt";
212      temp += r;
213     
214      if (!CmtSystem::test_file (temp))
215        {
216          temp = path;
217          //temp += CmtSystem::file_separator ();
218          //temp += package;
219          temp += CmtSystem::file_separator ();
220          temp += version;
221          temp += CmtSystem::file_separator ();
222          temp += "mgr";
223          temp += r;
224         
225          if (!CmtSystem::test_file (temp))
226            {
227              return;
228            }
229        }
230    }
231
232  temp.replace (r.c_str(), "");
233  cmt_string& use = m_uses.add ();
234  use = temp;
235}
236
237//----------------------------------------------------------
238ClientCollector::ClientCollector (const cmt_string& package,
239                                  const cmt_string& version) :
240  m_package (package), m_version (version), m_count (0)
241{
242}
243
244//----------------------------------------------------------
245void ClientCollector::run (const cmt_string& package,
246                           const cmt_string& version,
247                           const cmt_string& path,
248                           const bool without_version_directory)
249{
250  cmt_string dir = path;
251  dir += CmtSystem::file_separator ();
252  dir += package;
253  dir += CmtSystem::file_separator ();     
254  if (version != "" && ! without_version_directory)
255    {
256      dir += version;
257      dir += CmtSystem::file_separator ();
258    }
259
260  cmt_string req;
261 
262  req  = dir;
263  req += "cmt";
264  req += CmtSystem::file_separator ();
265  req += "requirements";
266
267  cmt_string requirements;
268  cmt_string line;
269  CmtSystem::cmt_string_vector words;
270
271  if (CmtSystem::test_file (req))
272    {
273      requirements.read (req);
274    }
275  else
276    {
277      req = dir;
278      req += "mgr";
279      req += CmtSystem::file_separator ();
280      req += "requirements";
281      if (CmtSystem::test_file (req))
282        {
283          requirements.read (req);
284        }
285    }
286
287  if (requirements != "")
288    {
289      int pos = 0;
290      int max_pos = requirements.size ();
291
292      while (pos < max_pos)
293        {
294          int cr = requirements.find (pos, "\r\n");
295          int nl = requirements.find (pos, '\n');
296          int first = nl;
297          int length = 1;
298               
299          if (cr != cmt_string::npos)
300            {
301              if (nl == cmt_string::npos)
302                {
303                  first = cr;
304                  length = 2;
305                }
306              else
307                {
308                  first = (nl < cr) ? nl : cr;
309                  length = (nl < cr) ? 1 : 2;
310                }
311            }
312               
313          if (first == cmt_string::npos)
314            {
315              requirements.substr (pos, line);
316              pos = max_pos;
317            }
318          else if (first > pos)
319            {
320              requirements.substr (pos, first - pos, line);
321              pos = first + length;
322            }
323          else
324            {
325              line.erase (0);
326              pos += length;
327            }
328
329          CmtSystem::split (line, " \t", words);
330
331          if ((words.size () >= 2) && (words[0] == "use")) 
332            {
333              if ((words[1] == m_package) && 
334                  ( (m_version == "") || (words[2] == m_version)))
335                {
336                  cout << "# " << package << " " << version << " " << path;
337                  if (m_version == "" && words.size () > 2)
338                    {
339                      cout << " (use version " << words[2] << ")";
340                    }
341                  cout << endl;
342                  m_count++;
343                }
344            }
345        }
346    }
347}
348
349//----------------------------------------------------------
350int ClientCollector::count ()
351{
352  return (m_count);
353}
354
355
356
357
358//----------------------------------------------------------
359//
360//   The Cmt methods
361//
362//----------------------------------------------------------
363
364
365
366/**
367 *   Append "CONFIG" to the prefix
368 */
369void Cmt::build_config (const cmt_string& prefix,
370                        cmt_string& config)
371{
372  /*
373    Building the config from <prefix>
374  */
375
376  config = prefix;
377  config += "CONFIG";
378}
379
380//----------------------------------------------------------
381void Cmt::build_makefile (const cmt_string& target)
382{
383  Constituent* constituent = 0;
384
385  if (target.size () > 0)
386    {
387      /*
388        Do genmake for one specific target.
389      */
390      constituent = Constituent::find (target);
391      if (constituent != 0)
392        {
393          constituent->build_makefile (Me.m_simulation);
394        }
395    }
396  else
397    {
398      /*
399        Do genmake for all possible targets.
400      */
401      Constituent::build_all_makefiles (Me.m_simulation);
402    }
403}
404
405//----------------------------------------------------------
406void Cmt::build_msdev_file (const cmt_string& target)
407{
408  Constituent* constituent = 0;
409
410  set_standard_macros ();
411
412  if (target != "")
413    {
414      /*
415        Do genmsdev for one specific target.
416      */
417      constituent = Constituent::find (target);
418      if (constituent != 0)
419        {
420          constituent->build_msdev_file (Me.m_simulation);
421        }
422    }
423  else
424    {
425      /*
426        Do genmsdev for all possible targets.
427      */
428      Constituent::build_all_msdev_files (Me.m_simulation);
429    }
430}
431
432/**
433   Visual Studio.net Support                                 
434*/
435void Cmt::build_vsnet_file (const cmt_string& target)       
436{                                                           
437  Constituent* constituent = 0;                             
438                                                             
439  set_standard_macros ();                                   
440                                                             
441  if (target != "")                                         
442    {                                                       
443      /*                                                     
444                                                             Do genvsnet for one specific target.                 
445      */                                                     
446      constituent = Constituent::find (target);             
447      if (constituent != 0)                                 
448        {                                                   
449          constituent->build_vsnet_file (Me.m_simulation);       
450        }                                                   
451    }                                                       
452  else                                                       
453    {                                                       
454      /*                                                     
455                                                             Do genvsnet for all possible targets.               
456      */                                                     
457      Constituent::build_all_vsnet_files (Me.m_simulation);       
458    }                                                       
459}                                                           
460
461//----------------------------------------------------------
462bool Cmt::build_nmake ()
463{
464  return (Me.m_build_nmake);
465}
466
467//----------------------------------------------------------
468void Cmt::build_OS9_makefile (const cmt_string& target)
469{
470  build_makefile (target);
471}
472
473/**
474 *   Convert a package name to its upper case copy
475 */
476void Cmt::build_prefix (const cmt_string& package, cmt_string& prefix)
477{
478  int pos;
479  char c;
480
481  /*
482    Building the prefix from <package>
483  */
484
485  prefix = package;
486
487  for (pos = 0; pos < package.size (); pos++)
488    {
489      c = package[pos];
490      prefix[pos] = toupper (c);
491    }
492}
493
494//----------------------------------------------------------
495void Cmt::clear ()
496{
497  Me.m_quiet = false;
498  Me.clear ();
499
500  Database::clear ();
501  Include::clear_all ();
502  Script::clear_all ();
503  CmtError::clear ();
504}
505
506//----------------------------------------------------------
507void Cmt::configure ()
508{
509  Log;
510  static bool configured = false;
511
512  if (configured) return;
513
514  Me.clear ();
515
516  log << "configure_default_path" << log_endl;
517  configure_default_path ();
518  log << "configure_version_tag" << log_endl;
519  configure_version_tag ();
520  log << "configure_uname_tag" << log_endl;
521  configure_uname_tag ();
522  log << "configure_hosttype_tag" << log_endl;
523  configure_hosttype_tag ();
524  log << "configure_config_tag" << log_endl;
525  configure_config_tag ();
526  log << "configure_site_tag" << log_endl;
527  configure_site_tag (0);
528  log << "configure_home" << log_endl;
529  // CMTHOME, CMTUSERCONTEXT and CMTPATH
530  configure_home (0);
531  log << "configure_current_dir" << log_endl;
532
533
534  bool save_quiet = Me.m_quiet;
535  Me.m_quiet = true;
536
537  Me.m_autoconfigure_cmtpath = true;
538  configure_cmt_path (0);
539  Me.m_autoconfigure_cmtpath = false;
540
541  Me.m_quiet = save_quiet;
542
543  configure_current_dir ();
544
545  log << "configure_current_package" << log_endl;
546  configure_current_package ();
547
548  log << "configure_current_structuring_style" << log_endl;
549  configure_current_structuring_style ();
550
551  Use& use = Use::current();
552
553  use.set (Me.m_current_package,
554           Me.m_current_version,
555           Me.m_current_path,
556           "",
557           "");
558
559  use.style = Me.m_current_style;
560
561  use.change_path (Me.m_current_path);
562
563  guess_current_project ();
564
565  if (CmtError::has_pending_error ()) 
566    {
567      Me.m_configure_error = CmtError::get_last_error ();
568    }
569}
570
571//----------------------------------------------------------
572void Cmt::configure_cmt_path (Use* use)
573{
574  if (!Me.m_autoconfigure_cmtpath) return;
575
576  cmt_string s;
577
578  s = Symbol::get_env_value ("CMTPATH");
579
580  {
581    bool q = Me.m_quiet;
582    Me.m_quiet = true; 
583
584    Symbol::filter_path_value ("CMTPATH", s);
585
586    Me.m_quiet = q;
587  }
588
589  IProjectFactory& factory = ProjectFactory::instance ();
590  factory.reset ();
591
592  CmtSystem::get_cmt_paths (factory, s, Me.m_cmt_user_context, Me.m_cmt_home);
593}
594
595//----------------------------------------------------------
596void Cmt::configure_config_tag ()
597{
598  Me.m_cmt_config = CmtSystem::get_cmt_config ();
599  if (Me.m_cmt_config != "")
600    {
601      Tag* tag;
602
603      tag = Tag::add (Me.m_cmt_config, PriorityConfig, "CMTCONFIG", 0);
604      tag->mark ();
605    }
606}
607
608//----------------------------------------------------------
609void Cmt::configure_current_cmtpath ()
610{
611  Use& current_use = Use::current ();
612
613  Me.m_current_cmtpath = "";
614  Me.m_current_offset = "";
615
616  Me.m_current_cmtpath = Project::find_in_cmt_paths (current_use.path);
617
618  if (Me.m_current_cmtpath != "")
619    {
620      static const cmt_string empty_string;
621      static const cmt_string fs = CmtSystem::file_separator ();
622
623      Me.m_current_offset = current_use.path;
624
625      /**
626         try to remove this current CMTPATH entry from path.  This
627         has a meaning when the specified path already contains an
628         absolute path.
629      */
630     
631      Me.m_current_offset.replace (Me.m_current_cmtpath, empty_string);
632      if (Me.m_current_offset[0] == CmtSystem::file_separator ())
633        {
634          // Just in case there is a part left after removing the cmtpath entry
635         
636          Me.m_current_offset.replace (fs, empty_string);
637        }
638    }
639}
640
641class CmtMountFilterParser : public FAwk
642{
643public:
644
645  CmtMountFilterParser ()
646  {
647    reset ();
648  }
649
650  void reset ()
651  {
652    m_current_dir = CmtSystem::pwd ();
653
654    m_done = false;
655    m_prefix = "";
656  }
657
658  bool is_done () const
659  {
660    return (m_done);
661  }
662
663  const cmt_string& get_current_dir () const
664  {
665    return (m_current_dir);
666  }
667
668  void set_prefix (const cmt_string& prefix)
669  {
670    m_prefix = prefix;
671  }
672
673  void filter (const cmt_string& line)
674  {
675    if (m_done) 
676      {
677        stop ();
678        return;
679      }
680
681    CmtSystem::cmt_string_vector words;
682
683    CmtSystem::split (line, " \t", words);
684
685    int requested = 2;
686
687    if (m_prefix != "")
688      {
689        requested++;
690      }
691
692    if (words.size () < requested) return;
693
694    int n = 0;
695
696    if (m_prefix != "")
697      {
698        if (words[n] != m_prefix) return;
699        n++;
700      }
701
702    cmt_string& path_name = words[n];
703    cmt_string& replacement = words[n+1];
704   
705    if (m_current_dir.find (path_name) != cmt_string::npos)
706      {
707        m_current_dir.replace (path_name, replacement);
708        m_done = true;
709        stop ();
710      }
711  }
712
713private:
714  bool m_done;
715  cmt_string m_prefix;
716  cmt_string m_current_dir;
717};
718
719//----------------------------------------------------------
720void Cmt::configure_current_dir ()
721{
722  cmt_string file_name;
723
724  /*
725    Building current_dir :
726
727    o we first get the physical value (using getwd)
728    o then this value is possibly filtered using the
729    cmt_mount_filter file.
730  */
731
732  CmtMountFilterParser mount_filter;
733
734  /**
735     First try with ${CMTROOT}/mgr/cmt_mount_filter
736     with no prefix on lines
737  */
738
739  file_name = Me.m_default_path;
740  if (file_name != "")
741    {
742      file_name += CmtSystem::file_separator ();
743      file_name += "CMT";
744      file_name += CmtSystem::file_separator ();
745      file_name += Me.m_cmt_version;
746      file_name += CmtSystem::file_separator ();
747      file_name += "mgr";
748      file_name += CmtSystem::file_separator ();
749    }
750
751  file_name += "cmt_mount_filter";
752
753  mount_filter.run (file_name);
754
755  /**
756     Now try with .cmtrc
757     with "mount_filter" keyword
758  */
759
760  mount_filter.set_prefix ("mount_filter");
761
762  mount_filter.run (".cmtrc");
763
764  /**
765     Now try with ${HOME}/.cmtrc
766     with "mount_filter" keyword
767  */
768
769  if (CmtSystem::get_home_directory (file_name))
770    {
771      file_name += CmtSystem::file_separator ();
772      file_name += ".cmtrc";
773      mount_filter.run (file_name);
774    }
775
776  Me.m_current_dir = mount_filter.get_current_dir ();
777  Me.m_current_file_path = mount_filter.get_current_dir ();
778
779  cmt_string t = Me.m_current_file_path;
780}
781
782//----------------------------------------------------------
783void Cmt::configure_current_package ()
784{
785  /*
786    Build current_package and current_prefix.
787
788    This is only possible if we are within the cmt/mgr branch of a
789    standard directory tree (i.e. <package>/<version>/cmt or mgr)
790  */
791
792  cmt_string req = "..";
793  req += CmtSystem::file_separator ();
794  req += "cmt";
795  req += CmtSystem::file_separator ();
796  req += "requirements";
797
798  if (CmtSystem::test_file (req))
799    {
800      Me.m_current_style = cmt_style;
801    }
802  else
803    {
804      cmt_string req = "..";
805      req += CmtSystem::file_separator ();
806      req += "mgr";
807      req += CmtSystem::file_separator ();
808      req += "requirements";
809
810      if (CmtSystem::test_file (req))
811        {
812          Me.m_current_style = mgr_style;
813        }
814      else
815        {
816          // This package is probably a standalone one
817          Me.m_current_style = none_style;
818        }
819    }
820
821
822  if (Me.m_current_style != none_style)
823    {
824      //
825      //  Here there is a ../cmt or ../mgr branch in front of us
826      //  and there is a requirements file there
827      //
828
829      cmt_string up_dir;
830      cmt_string up_branch;
831
832      CmtSystem::dirname (Me.m_current_dir, up_dir);
833      CmtSystem::basename (up_dir, up_branch);
834
835      cmt_string version_file = "..";
836      version_file += CmtSystem::file_separator ();
837      version_file += "cmt";
838      version_file += CmtSystem::file_separator ();
839      version_file += "version.cmt";
840
841      if (CmtSystem::test_file (version_file))
842        {
843          //
844          // There is an explicit version descriptor. This one takes precedence
845          // and forces the structuring style to no directory
846          //
847
848          Me.m_current_package = up_branch;
849          CmtSystem::dirname (up_dir, Me.m_current_path);
850
851          if (Me.m_current_version.read (version_file))
852            {
853              int pos;
854
855              pos = Me.m_current_version.find ('\n');
856              if (pos != cmt_string::npos) Me.m_current_version.erase (pos);
857              pos = Me.m_current_version.find ('\r');
858              if (pos != cmt_string::npos) Me.m_current_version.erase (pos);
859            }
860          else
861            {
862              Me.m_current_version = "v*";
863            }
864
865          if (Me.m_debug)
866            {
867              cout << "Cmt::configure_current_package>" << endl
868                   << " m_current_package " << Me.m_current_package << endl
869                   << " m_current_version " << Me.m_current_version << endl
870                   << " m_current_dir " << Me.m_current_dir << endl
871                   << " pwd " << CmtSystem::pwd ()
872                   << endl;
873            }
874
875          Me.m_current_style = no_version_style;
876        }
877      else if (CmtSystem::is_version_directory (up_branch))
878        {
879          // The up branch IS a version directory.
880
881          Me.m_current_version = up_branch;
882          CmtSystem::dirname (up_dir, up_dir);
883          CmtSystem::basename (up_dir, Me.m_current_package);
884          CmtSystem::dirname (up_dir, Me.m_current_path);
885        }
886      else
887        {
888          // No version descriptor
889          // No version directory. The version is defaulted to v*
890 
891          CmtSystem::basename (up_dir, Me.m_current_package);
892          Me.m_current_version = "v*";
893          CmtSystem::dirname (up_dir, Me.m_current_path);
894
895          Me.m_current_style = no_version_style;
896        }
897
898      build_prefix (Me.m_current_package, Me.m_current_prefix);
899      build_config (Me.m_current_prefix, Me.m_current_config);
900    }
901  else
902    {
903      Me.m_current_package = "cmt_standalone";
904      Me.m_current_version = "";
905      Me.m_current_path = Me.m_current_dir;
906      build_prefix (Me.m_current_package, Me.m_current_prefix);
907      build_config (Me.m_current_prefix, Me.m_current_config);
908      Me.m_current_style = none_style;
909    }
910}
911
912//----------------------------------------------------------
913void Cmt::configure_current_structuring_style ()
914{
915  cmt_string s;
916
917  s = CmtSystem::getenv ("CMTSTRUCTURINGSTYLE");
918  if (s == "without_version_directory")
919    {
920      Me.m_current_structuring_style = without_version_directory;
921    }
922  else if (s == "with_version_directory")
923    {
924      Me.m_current_structuring_style = with_version_directory;
925    } 
926}
927
928//----------------------------------------------------------
929void Cmt::configure_default_path ()
930{
931  Me.m_default_path = CmtSystem::get_cmt_root ();
932  CmtSystem::get_cmt_version (Me.m_cmt_version);
933  Me.m_cmt_root = Me.m_default_path;
934  Me.m_cmt_root += CmtSystem::file_separator ();
935  Me.m_cmt_root += "CMT";
936  Me.m_cmt_root += CmtSystem::file_separator ();
937  Me.m_cmt_root += Me.m_cmt_version;
938}
939
940//----------------------------------------------------------
941void Cmt::configure_home (Use* use)
942{
943  Me.m_cmt_home = "";
944
945  Symbol* symbol = Symbol::find ("CMTHOME");
946  if (symbol != 0)
947    {
948      Me.m_cmt_home = symbol->build_macro_value ();
949      Symbol::expand (Me.m_cmt_home);
950    }
951  else if (CmtSystem::testenv ("CMTHOME"))
952    {
953      Me.m_cmt_home = CmtSystem::getenv ("CMTHOME");
954    }
955
956  if ((Me.m_cmt_home != "") && !CmtSystem::test_directory (Me.m_cmt_home))
957    {
958      Me.m_cmt_home = "";
959    }
960
961  configure_user_context (0);
962}
963
964//----------------------------------------------------------
965void Cmt::configure_user_context (Use* use)
966{
967  Me.m_cmt_user_context = "";
968
969  Symbol* symbol = Symbol::find ("CMTUSERCONTEXT");
970  if (symbol != 0)
971    {
972      Me.m_cmt_user_context = symbol->build_macro_value ();
973      Symbol::expand (Me.m_cmt_user_context);
974    }
975  else if (CmtSystem::testenv ("CMTUSERCONTEXT"))
976    {
977      Me.m_cmt_user_context = CmtSystem::getenv ("CMTUSERCONTEXT");
978    }
979
980  if ((Me.m_cmt_user_context != "") && !CmtSystem::test_directory (Me.m_cmt_user_context))
981    {
982      Me.m_cmt_user_context = "";
983    }
984
985  if (Me.m_debug) cout << "configure_user_context> user_context=" << Me.m_cmt_user_context << endl;
986
987  configure_cmt_path (0);
988}
989
990//----------------------------------------------------------
991void Cmt::configure_hosttype_tag ()
992{
993  cmt_string hosttype;
994
995  CmtSystem::get_hosttype (hosttype);
996
997  if (hosttype != "")
998    {
999      Tag* tag;
1000
1001      tag = Tag::add (hosttype, PriorityUname, "HOSTTYPE", 0);
1002      tag->mark ();
1003    }
1004}
1005
1006//----------------------------------------------------------
1007void Cmt::configure_site_tag (Use* use)
1008{
1009  Symbol* symbol = Symbol::find ("CMTSITE");
1010  if (symbol != 0)
1011    {
1012      Me.m_cmt_site = symbol->build_macro_value ();
1013      Symbol::expand (Me.m_cmt_site);
1014    }
1015  else
1016    {
1017      Me.m_cmt_site = CmtSystem::get_cmt_site ();
1018    }
1019
1020  if (Me.m_cmt_site != "")
1021    {
1022      cmt_string s = "CMTSITE";
1023
1024      if (use != 0)
1025        {
1026          s += " in ";
1027        }
1028
1029      Tag* tag;
1030
1031      tag = Tag::add (Me.m_cmt_site, PrioritySite, s, use);
1032      tag->mark ();
1033    }
1034}
1035
1036//----------------------------------------------------------
1037void Cmt::restore_all_tags (Use* use)
1038{
1039  //cerr << "restore_all_tags" << endl;
1040
1041  Cmt::configure_tags (use);
1042
1043  /*
1044    Then get existing extra tags
1045  */
1046
1047  if (CmtSystem::testenv ("CMTEXTRATAGS"))
1048    {
1049      cmt_string s = "CMTEXTRATAGS";
1050
1051      if (use != 0)
1052        {
1053          s += " in ";
1054        }
1055
1056      Tag* tag;
1057      CmtSystem::cmt_string_vector words;
1058     
1059      cmt_string tags = CmtSystem::getenv ("CMTEXTRATAGS");
1060     
1061      CmtSystem::split (tags, " \t,", words);
1062
1063      Me.m_extra_tags = ",";
1064     
1065      for (int i = 0; i < words.size (); i++)
1066        {
1067          const cmt_string& a = words[i];
1068
1069          Me.m_extra_tags += a;
1070          Me.m_extra_tags += ",";
1071         
1072          tag = Tag::add (a, PriorityUserTag, s, use);
1073         
1074          tag->mark ();
1075        }
1076    }
1077}
1078
1079//----------------------------------------------------------
1080void Cmt::configure_tags (Use* use)
1081{
1082  cmt_string config_tag;
1083
1084  Log;
1085
1086  log << "current_tag=" << Me.m_current_tag << log_endl;
1087
1088  Symbol* symbol = Symbol::find ("CMTCONFIG");
1089  if (symbol != 0)
1090    {
1091      bool show_set_hidden = false;
1092
1093      if (Me.m_action == action_show_set)
1094        {
1095          show_set_hidden = true;
1096          Me.m_action = action_none;
1097        }
1098
1099      config_tag = symbol->build_macro_value ();
1100      Symbol::expand (config_tag);
1101
1102      if (show_set_hidden)
1103        {
1104          show_set_hidden = false;
1105          Me.m_action = action_show_set;
1106        }
1107    }
1108  else if (CmtSystem::testenv ("CMTCONFIG"))
1109    {
1110      config_tag = CmtSystem::getenv ("CMTCONFIG");
1111    }
1112  else if (CmtSystem::testenv ("CMTBIN"))
1113    {
1114      config_tag = CmtSystem::getenv ("CMTBIN");
1115    }
1116
1117  if (config_tag == "")
1118    {
1119      CmtSystem::get_uname (config_tag);
1120    }
1121
1122  log << "current_tag=" << Me.m_current_tag << log_endl;
1123
1124  cmt_string s = "CMTCONFIG";
1125
1126  if (use != 0)
1127    {
1128      s += " in ";
1129    }
1130
1131  Tag* tag;
1132
1133  tag = Tag::add (config_tag, PriorityConfig, s, use);
1134  tag->mark ();
1135
1136  //Me.m_current_tag = config_tag;
1137}
1138
1139//----------------------------------------------------------
1140void Cmt::configure_uname_tag ()
1141{
1142  cmt_string uname;
1143
1144  CmtSystem::get_uname (uname);
1145
1146  if (uname != "")
1147    {
1148      Tag* tag;
1149
1150      tag = Tag::add (uname, PriorityUname, "uname", 0);
1151      tag->mark ();
1152    }
1153}
1154
1155//----------------------------------------------------------
1156void Cmt::configure_version_tag ()
1157{
1158  int v = 0;
1159  int r = 0;
1160  int p = 0;
1161
1162  CmtSystem::is_version_directory (CMTVERSION, v, r, p);
1163
1164  Tag* tag;
1165
1166  static char temp[80];
1167
1168  sprintf (temp, "CMTv%d", v);
1169
1170  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1171  tag->mark ();
1172
1173  sprintf (temp, "CMTr%d", r);
1174
1175  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1176  tag->mark ();
1177
1178  sprintf (temp, "CMTp%d", p);
1179
1180  tag = Tag::add (temp, PriorityVersion, "CMTVERSION", 0);
1181  tag->mark ();
1182
1183}
1184
1185//----------------------------------------------------------
1186//
1187//   Actions
1188//
1189//----------------------------------------------------------
1190
1191class AwkActor : public Awk
1192{
1193public:
1194
1195  void filter (const cmt_string& line)
1196  {
1197    cout << line << endl;
1198  }
1199};
1200
1201//----------------------------------------------------------
1202void Cmt::do_awk (const ArgParser& ap)
1203{
1204  if (ap.arguments.size () < 1)
1205    {
1206      cerr << "#CMT> cmt awk <file> <pattern>" << endl;
1207      return;
1208    }
1209
1210  const cmt_string& file = ap.arguments[0];
1211  const cmt_string& pattern = ap.arguments[1];
1212  cmt_string text;
1213
1214  text.read (file);
1215
1216  static AwkActor a;
1217
1218  cmt_regexp exp (pattern);
1219
1220  a.run (text, exp);
1221}
1222
1223//----------------------------------------------------------
1224void Cmt::do_broadcast (const ArgParser& ap)
1225{
1226  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
1227
1228  CmtSystem::cmt_string_vector uses;
1229  CmtSystem::cmt_string_vector packages;
1230  CmtSystem::cmt_string_vector versions;
1231  CmtSystem::cmt_string_vector path_selections;
1232  CmtSystem::cmt_string_vector selections;
1233  CmtSystem::cmt_string_vector exclusions;
1234  cmt_string begin;
1235  cmt_string command;
1236  bool is_cmt = false;
1237  int first = 0;
1238  int i;
1239  bool ignore_errors = false;
1240  bool all_packages = false;
1241
1242  bool local = true;
1243
1244  for (i = 0; i < ap.arguments.size (); i++)
1245    {
1246      const cmt_string& w = ap.arguments[i];
1247
1248      //cerr << "broadcast: arg=[" << w << "]" << endl;
1249
1250      if (command == "")
1251        {
1252          if (w.substr (0, 13) == "-all_packages")
1253            {
1254              local = false;
1255              all_packages = true;
1256            }
1257          else if (w.substr (0, 7) == "-depth=")
1258            {
1259              local = false;
1260
1261              cmt_string depth_str;
1262              int depth_value = 0;
1263                         
1264              w.substr (7, depth_str);
1265              if ((sscanf (depth_str.c_str (), "%d", &depth_value) < 1) ||
1266                  (depth_value < 1))
1267                {
1268                  // Syntax error
1269                  //  We shall restrict to packages found within
1270                  // the <depth_value> first elements of CMTPATH.
1271                  //  If CMTPATH is empty, nothing is selected.
1272                  // depth=1 is equivalent to local
1273                }
1274
1275              Project::fill_selection (depth_value, path_selections);
1276            }
1277          else if (w.substr (0, 9) == "-exclude=")
1278            {
1279              cmt_string exclusion;
1280
1281              w.substr (9, exclusion);
1282
1283              int size = exclusion.size ();
1284             
1285              if (size >= 2)
1286                {
1287                  if (((exclusion[0] == '"') && (exclusion[size - 1] == '"')) ||
1288                      ((exclusion[0] == '\'') && (exclusion[size - 1] == '\'')))
1289                    {
1290                      exclusion.erase (size - 1);
1291                      exclusion.erase (0, 1);
1292                    }
1293
1294                  CmtSystem::split (exclusion, " \t", exclusions);
1295                }
1296            }
1297          else if (w.substr (0, 7) == "-global")
1298            {
1299              path_selections.clear ();
1300
1301              local = false;
1302            }
1303          else if (w.substr (0, 6) == "-local")
1304            {
1305              local = true;
1306            }
1307          else if (w.substr (0, 8) == "-select=")
1308            {
1309              cmt_string selection;
1310
1311              w.substr (8, selection);
1312
1313              //cerr << "Select=[" << selection << "]" << endl;
1314
1315              int size = selection.size ();
1316             
1317              if (size >= 2)
1318                {
1319                  if (((selection[0] == '"') && (selection[size - 1] == '"')) ||
1320                      ((selection[0] == '\'') && (selection[size - 1] == '\'')))
1321                    {
1322                      selection.erase (size - 1);
1323                      selection.erase (0, 1);
1324                    }
1325                }
1326
1327              CmtSystem::split (selection, " \t", selections);
1328
1329              //cerr << "Selections.size () = " << selections.size () << endl;
1330            }
1331          else if (w.substr (0, 7) == "-begin=")
1332            {
1333              w.substr (7, begin);
1334            }
1335          else
1336            {
1337              command = w;
1338            }
1339        }
1340      else
1341        {
1342          command += " ";
1343          command += w;
1344        }
1345
1346    }
1347
1348  if (local)
1349    {
1350      Project::fill_selection (1, path_selections);
1351    }
1352
1353  if (command[0] == '-')
1354    {
1355      ignore_errors = true;
1356      command.erase (0, 1);
1357    }
1358
1359  //if (command.substr (0, 3) == "cmt") is_cmt = true;
1360
1361  if (all_packages)
1362    {
1363      PackageSelector selector (uses);
1364      PathScanner scanner;
1365      Project::scan_paths (scanner, selector);
1366    }
1367  else
1368    {
1369      for (i = Uses.size () - 1; i >= 0; i--)
1370        {
1371          Use* use = Uses[i];
1372                 
1373          if (use->discarded) continue;
1374          if (use->m_hidden) continue;
1375
1376          if (!use->located ())
1377            {
1378              if (!Me.m_quiet)
1379                {
1380                  cerr << "#CMT> package " << use->get_package_name () <<
1381                    " " << use->version << " " << use->path <<
1382                    " not found" <<
1383                    endl;
1384                }
1385            }
1386          else
1387            {
1388              if (use->get_package_name () != "CMT")
1389                {
1390                  cmt_string& s = uses.add ();
1391
1392                  use->get_full_path (s);
1393
1394                  s += CmtSystem::file_separator ();
1395                  if (use->style == mgr_style) s += "mgr";
1396                  else s += "cmt";
1397
1398                  cmt_string& v = versions.add ();
1399                  v = use->version;
1400
1401                  cmt_string& p = packages.add ();
1402                  p = use->get_package_name ();
1403                }
1404            }
1405        }
1406         
1407      {
1408        cmt_string& s = uses.add ();
1409                 
1410        Use* use = &(Use::current ());
1411
1412        if (use->get_package_name ().find ("cmt_standalone") != cmt_string::npos)
1413          {
1414            s = CmtSystem::pwd ();
1415          }
1416        else
1417          {
1418            use->get_full_path (s);
1419
1420            s += CmtSystem::file_separator ();
1421                 
1422            if (use->style == mgr_style) s += "mgr";
1423            else s += "cmt";
1424          }
1425
1426        cmt_string& v = versions.add ();
1427        v = use->version;
1428
1429        cmt_string& p = packages.add ();
1430        p = use->get_package_name ();
1431      }
1432    }
1433
1434  bool started = false;
1435
1436  if (begin == "") started = true;
1437
1438  set_standard_macros ();
1439  Cmt::reset_all_sets_done ();
1440  Symbol::all_set ();
1441
1442  for (i = 0; i < uses.size (); i++)
1443    {
1444      const cmt_string& s = uses[i];
1445      const cmt_string& v = versions[i];
1446      const cmt_string& p = packages[i];
1447      cmt_string cmtpath;
1448
1449      bool ok = true;
1450      bool selected = true;
1451      bool excluded = false;
1452
1453      if (path_selections.size () > 0)
1454        {
1455          selected = false;
1456
1457          for (int j = 0; j < path_selections.size (); j++)
1458            {
1459              const cmt_string& sel = path_selections[j];
1460             
1461              if (s.find (sel) != cmt_string::npos) 
1462                {
1463                  cmtpath = sel;
1464                  selected = true;
1465                  break;
1466                }
1467            }
1468
1469          ok = selected;
1470        }
1471
1472      if (ok)
1473        {
1474          if (selections.size () > 0)
1475            {
1476              selected = false;
1477             
1478              for (int j = 0; j < selections.size (); j++)
1479                {
1480                  const cmt_string& sel = selections[j];
1481                 
1482                  if (s.find (sel) != cmt_string::npos) 
1483                    {
1484                      selected = true;
1485                      break;
1486                    }
1487                }
1488             
1489              ok = selected;
1490            }
1491        }
1492
1493      if (ok && !started)
1494        {
1495          if (s.find (begin) != cmt_string::npos)
1496            {
1497              started = true;
1498              ok = true;
1499            }
1500          else
1501            {
1502              ok = false;
1503            }
1504        }
1505
1506
1507      if (ok)
1508        {
1509          excluded = false;
1510
1511          for (int j = 0; j < exclusions.size (); j++)
1512            {
1513              const cmt_string& exc = exclusions[j];
1514             
1515              if (s.find (exc) != cmt_string::npos) 
1516                {
1517                  excluded = true;
1518                  break;
1519                }
1520            }
1521
1522          if (excluded) ok = false;
1523        }
1524
1525      if (!ok) 
1526        {
1527          continue;
1528        }
1529
1530
1531
1532      if (!CmtSystem::cd (s))
1533        {
1534          if (s.find ("cmt_standalone") != cmt_string::npos)
1535            {
1536              cerr << "#CMT> Currently not in a CMT package" << endl;
1537            }
1538          else
1539            {
1540              cerr << "#CMT> Cannot move to the package in " << s << " (" << i+1 << "/" 
1541                   << uses.size () << ")"<< endl;
1542            }
1543
1544          if (!ignore_errors) break;
1545
1546          continue;
1547        }
1548
1549      if (CmtLock::check () == CmtLock::locked_by_another_user)
1550        {
1551          cerr << "#CMT> Ignore locked package in " << s << " (" << i+1 << "/" 
1552               << uses.size () << ")" << endl;
1553          continue;
1554        }
1555
1556      if (cmtpath == "")
1557        {
1558          cmt_string sel = CmtSystem::pwd ();
1559          cmtpath = Project::find_in_cmt_paths (sel);
1560        }
1561
1562      cmt_string cmd = command;
1563      static const cmt_string version_template = "<version>";
1564      cmd.replace_all (version_template, v);
1565
1566      static const cmt_string package_template = "<package>";
1567      cmd.replace_all (package_template, p);
1568
1569      static const cmt_string cmtpath_template = "<package_cmtpath>";
1570      cmd.replace_all (cmtpath_template, cmtpath);
1571
1572      static const cmt_string offset_template = "<package_offset>";
1573
1574      static const cmt_string empty_string;
1575      static const cmt_string fs = CmtSystem::file_separator ();
1576      cmt_string offset = s;
1577      offset.replace (cmtpath, empty_string);
1578      if (offset[0] == CmtSystem::file_separator ())
1579        {
1580          offset.replace (fs, empty_string);
1581        }
1582      CmtSystem::dirname (offset, offset);
1583
1584      cmt_string n;
1585      CmtSystem::basename (offset, n);
1586      if (n == p)
1587        {
1588          CmtSystem::dirname (offset, offset);
1589        }
1590      else
1591        {
1592          CmtSystem::dirname (offset, offset);
1593          CmtSystem::dirname (offset, offset);
1594        }
1595
1596      cmd.replace_all (offset_template, offset);
1597
1598
1599      cout << "#--------------------------------------------------------------" << endl;
1600      cout << "# Now trying [" << cmd << "] in " << s << " (" << i+1 << "/" << uses.size () 
1601           << ")" << endl;
1602      cout << "#--------------------------------------------------------------" << endl;
1603
1604      if (is_cmt)
1605        {
1606          //
1607          //  There is a bug in the recursive use of the parser. Macros are not set correctly.
1608          //  Thus the recursive optimization is now discarded.
1609          //
1610          if (parser (cmd) != 0)
1611            {
1612              CmtError::set (CmtError::execution_error, cmd);
1613              break;
1614            }
1615        }
1616      else
1617        {
1618          int status = CmtSystem::execute (cmd);
1619
1620          //cerr << "do_broadcast> status=" << status << " ignore_errors=" << ignore_errors << endl;
1621
1622          if ((status != 0) && !ignore_errors)
1623            //if ((status != 0) && !ignore_errors)
1624            {
1625              if (status != 2) CmtError::set (CmtError::execution_error, cmd);
1626              break;
1627            }
1628        }
1629    }
1630}
1631
1632//----------------------------------------------------------
1633void Cmt::do_build_constituent_makefile (const ArgParser& ap)
1634{
1635  if (CmtLock::check () == CmtLock::locked_by_another_user)
1636    {
1637      CmtError::set (CmtError::conflicting_lock, "build_constituent_makefile>");
1638      return;
1639    }
1640  if (ap.arguments.size () > 0) 
1641    {
1642      set_standard_macros ();
1643      Generator::build_constituent_makefile (ap.arguments[0]);
1644    }
1645}
1646
1647//----------------------------------------------------------
1648void Cmt::do_build_constituents_makefile (const ArgParser& ap)
1649{
1650  if (CmtLock::check () == CmtLock::locked_by_another_user)
1651    {
1652      CmtError::set (CmtError::conflicting_lock, "build_constituents_makefile>");
1653      return;
1654    }
1655  set_standard_macros ();
1656
1657  Generator::build_constituents_makefile (Me.m_current_package, ap.arguments);
1658}
1659
1660//----------------------------------------------------------
1661void Cmt::do_build_dependencies (const ArgParser& ap,
1662                                 int argc,
1663                                 char* argv[])
1664{
1665  if (CmtLock::check () == CmtLock::locked_by_another_user)
1666    {
1667      CmtError::set (CmtError::conflicting_lock, "build_dependencies>");
1668      return;
1669    }
1670  if (ap.arguments.size () > 0)
1671    {
1672      set_standard_macros ();
1673
1674      Generator::build_dependencies (ap.arguments);
1675    }
1676}
1677
1678//----------------------------------------------------------
1679void Cmt::do_build_library_links (const ArgParser& ap)
1680{
1681  cmt_string cmtinstallarea = "";
1682  cmt_string tag = "";
1683  cmt_string shlibsuffix;
1684  cmt_string symlinkcmd;
1685
1686  if (CmtLock::check () == CmtLock::locked_by_another_user)
1687    {
1688      CmtError::set (CmtError::conflicting_lock, "build_library_links>");
1689      return;
1690    }
1691
1692  set_standard_macros ();
1693
1694  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
1695  Use& current_use = Use::current ();
1696  int i;
1697
1698  {
1699    Symbol* macro = Symbol::find ("shlibsuffix");
1700    if (macro == 0) return;
1701    shlibsuffix = macro->build_macro_value ();
1702    Symbol::expand (shlibsuffix);
1703  }
1704
1705  {
1706    Symbol* macro = Symbol::find ("library_install_command");
1707    if (macro != 0)
1708      {
1709        symlinkcmd = macro->build_macro_value ();
1710        Symbol::expand (symlinkcmd);
1711      }
1712  }
1713
1714  if (current_use.get_strategy ("InstallArea"))
1715    {
1716      const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
1717     
1718      cmt_string s1 = ia_mgr.get_installarea ();
1719
1720      {
1721        Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
1722        if (symbol != 0)
1723          {
1724            s1 = symbol->build_macro_value ();
1725            Symbol::expand (s1);
1726          }
1727      }
1728
1729      cmtinstallarea = s1;
1730                 
1731      cmt_string s2;
1732
1733      {
1734        Symbol* macro = Symbol::find ("tag");
1735        if (macro != 0)
1736          {
1737            s2 = macro->build_macro_value ();
1738            Symbol::expand (s2);
1739          }
1740      }
1741
1742      tag = s2;
1743
1744      cmt_string s = s1;
1745      s += CmtSystem::file_separator ();
1746      s += s2;
1747      s += CmtSystem::file_separator ();
1748      s += "lib";
1749
1750      CmtSystem::mkdir (s);
1751    }
1752
1753  current_use.build_library_links (cmtinstallarea, tag, shlibsuffix, symlinkcmd);
1754
1755  for (i = 0; i < Uses.size (); i++)
1756    {
1757      Use* use = Uses[i];
1758
1759      if (use == 0) continue;
1760      if (use->discarded) continue;
1761      if (use->m_hidden) continue;
1762
1763      if (use->get_package_name () == "CMT") continue;
1764      if (use->get_package_name () == current_use.get_package_name ()) continue;
1765
1766      use->build_library_links (cmtinstallarea, tag, shlibsuffix, symlinkcmd);
1767    }
1768}
1769
1770//----------------------------------------------------------
1771void Cmt::do_build_make_setup (const ArgParser& ap)
1772{
1773  if (CmtLock::check () == CmtLock::locked_by_another_user)
1774    {
1775      CmtError::set (CmtError::conflicting_lock, "build_make_setup>");
1776      return;
1777    }
1778  set_standard_macros ();
1779  Generator::build_make_setup (Me.m_current_package);
1780}
1781
1782//----------------------------------------------------------
1783void Cmt::do_build_msdev (const ArgParser& ap)
1784{
1785  if (CmtLock::check () == CmtLock::locked_by_another_user)
1786    {
1787      CmtError::set (CmtError::conflicting_lock, "build_msdev>");
1788      return;
1789    }
1790
1791  if (true)
1792    {
1793      set_standard_macros ();
1794      if (ap.arguments.size () > 0) build_msdev_file (ap.arguments[0]);
1795      else build_msdev_file ("");
1796    }
1797}
1798
1799void Cmt::do_build_CMT_pacman (const ArgParser& ap)
1800{
1801  cmt_string pacman_file;
1802
1803  pacman_file = Me.m_cmt_root;
1804  pacman_file += CmtSystem::file_separator ();
1805  pacman_file += "mgr";
1806  pacman_file += CmtSystem::file_separator ();
1807  pacman_file += "CMT.pacman";
1808
1809  cmt_string pacman;
1810  cmt_string pattern = "<version>";
1811  cmt_string replacement = CMTVERSION;
1812
1813  pacman.read (pacman_file);
1814
1815  pacman.replace_all (pattern, replacement);
1816
1817  cout << pacman << endl;
1818}
1819
1820// Visual Studio.net Support                                                 
1821//----------------------------------------------------------                 
1822void Cmt::do_build_vsnet (const ArgParser& ap)     
1823{                                                                           
1824  if (CmtLock::check () == CmtLock::locked_by_another_user)                 
1825    {                                                                       
1826      CmtError::set (CmtError::conflicting_lock, "build_vsnet>");           
1827      return;                                                               
1828    }                                                                       
1829                                                                             
1830  if (true)                                                                 
1831    {                                                                       
1832      set_standard_macros ();                                               
1833      if (ap.arguments.size () > 0) build_vsnet_file (ap.arguments[0]);           
1834      else build_vsnet_file ("");                                           
1835    }                                                                       
1836}                                                                           
1837
1838//----------------------------------------------------------
1839void Cmt::do_build_os9_makefile (const ArgParser& ap)
1840{
1841  if (CmtLock::check () == CmtLock::locked_by_another_user)
1842    {
1843      CmtError::set (CmtError::conflicting_lock, "build_os9_makefile>");
1844      return;
1845    }
1846
1847  if (ap.arguments.size () > 0) 
1848    {
1849      set_standard_macros ();
1850      build_OS9_makefile (ap.arguments[0]);
1851    }
1852}
1853
1854//----------------------------------------------------------
1855void Cmt::do_build_prototype (const ArgParser& ap)
1856{
1857  if (CmtLock::check () == CmtLock::locked_by_another_user)
1858    {
1859      CmtError::set (CmtError::conflicting_lock, "build_prototype>");
1860      return;
1861    }
1862
1863  if (ap.arguments.size () > 0) 
1864    {
1865      set_standard_macros ();
1866      Generator::build_prototype (ap.arguments[0]);
1867    }
1868}
1869
1870//----------------------------------------------------------
1871void Cmt::do_build_readme (const ArgParser& ap)
1872{
1873  if (CmtLock::check () == CmtLock::locked_by_another_user)
1874    {
1875      CmtError::set (CmtError::conflicting_lock, "build_readme>");
1876      return;
1877    }
1878
1879  set_standard_macros ();
1880  Generator::build_readme (ap.arguments);
1881}
1882
1883//----------------------------------------------------------
1884void Cmt::do_build_tag_makefile (const ArgParser& ap)
1885{
1886  if (CmtLock::check () == CmtLock::locked_by_another_user)
1887    {
1888      CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
1889      return;
1890    }
1891
1892  print_macros (Make);
1893}
1894
1895//----------------------------------------------------------
1896void Cmt::do_build_temporary_name (const ArgParser& ap)
1897{
1898  cmt_string name = CmtSystem::get_temporary_name ();
1899  cout << name << endl;
1900}
1901
1902//----------------------------------------------------------
1903void Cmt::do_build_triggers (const ArgParser& ap)
1904{
1905  if (CmtLock::check () == CmtLock::locked_by_another_user)
1906    {
1907      CmtError::set (CmtError::conflicting_lock, "build_tag_makefile>");
1908      return;
1909    }
1910
1911  if (ap.arguments.size () > 0) 
1912    {
1913      set_standard_macros ();
1914      TriggerGenerator::run (ap.arguments[0]);
1915    }
1916}
1917
1918//----------------------------------------------------------
1919void Cmt::do_build_windefs (const ArgParser& ap)
1920{
1921  if (CmtLock::check () == CmtLock::locked_by_another_user)
1922    {
1923      CmtError::set (CmtError::conflicting_lock, "build_windefs>");
1924      return;
1925    }
1926
1927  if (ap.arguments.size () > 0) 
1928    {
1929      set_standard_macros ();
1930      Generator::build_windefs (ap.arguments[0]);
1931    }
1932}
1933
1934//----------------------------------------------------------
1935void Cmt::do_check_configuration (const ArgParser& ap)
1936{
1937  cmt_string env;
1938  Tag* tag;
1939
1940  set_standard_macros ();
1941
1942  static CmtSystem::cmt_string_vector tags;
1943
1944  CmtSystem::split (Me.m_extra_tags, " \t,", tags);
1945
1946  for (int i = 0; i < tags.size (); i++)
1947    {
1948      const cmt_string& t = tags[i];
1949
1950      tag = Tag::find (t);
1951      if (tag == 0) continue;
1952
1953      if (!Tag::check_tag_used (tag) && !Symbol::check_tag_used (tag)) 
1954        {
1955          cerr << "#CMT> The tag " << t << " is not used in any tag expression. Please check spelling" << endl;
1956        }
1957    }
1958
1959  Symbol::check_all_paths ();
1960
1961  env = CmtSystem::getenv ("CMTSITE");
1962  if (env == "") 
1963    {
1964      return;
1965    }
1966
1967  tag = Tag::find (env);
1968  if (tag == 0) 
1969    {
1970      return;
1971    }
1972
1973  if (!Tag::check_tag_used (tag) && !Symbol::check_tag_used (tag) && Cmt::get_warnings ()) 
1974    {
1975      cerr << "#CMT> The CMTSITE value " << env << " is not used in any tag expression. Please check spelling" << endl;
1976    }
1977
1978}
1979
1980//----------------------------------------------------------
1981void Cmt::do_check_files (const ArgParser& ap)
1982{
1983  if (ap.arguments.size () >= 2) 
1984    {
1985      cmt_string first_file = ap.arguments[0];
1986      cmt_string second_file = ap.arguments[1];
1987         
1988      if (first_file == "") return;
1989      if (second_file == "") return;
1990         
1991      CmtSystem::compare_and_update_files (first_file, second_file);
1992    }
1993}
1994
1995//----------------------------------------------------------
1996void Cmt::do_check_version (const ArgParser& ap)
1997{
1998  if (ap.arguments.size () > 0)
1999    {
2000      cmt_string name = ap.arguments[0];
2001         
2002      if (name == "") return;
2003      int v = 0;
2004      int r = 0;
2005      int p = 0;
2006         
2007      bool ok = CmtSystem::is_version_directory (name, v, r, p);
2008         
2009      if (ok)
2010        {
2011          cout << "# " << name << " is version " << v << " release " << r << " patch " << p << endl;
2012        }
2013      else
2014        {
2015          cout << "# " << name << " is not a version tag" << endl;
2016        }
2017    }
2018}
2019
2020//----------------------------------------------------------
2021void Cmt::do_checkout (const ArgParser& ap)
2022{
2023  Cvs::checkout (ap.arguments);
2024}
2025
2026//----------------------------------------------------------
2027void Cmt::do_cleanup (const ArgParser& ap)
2028{
2029  print_clean (ap.mode);
2030}
2031
2032//----------------------------------------------------------
2033void Cmt::do_config (const ArgParser& ap)
2034{
2035  if (CmtLock::check () == CmtLock::locked_by_another_user)
2036    {
2037      CmtError::set (CmtError::conflicting_lock, "config>");
2038      return;
2039    }
2040
2041  //Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2042
2043  Use& current_use = Use::current ();
2044
2045  if (Me.m_debug)
2046    {
2047      cout << "Cmt::do_config> " << endl;
2048      cout << "pwd " << CmtSystem::pwd () << endl;
2049      cout << "current_dir " << Me.m_current_dir << endl;
2050      cout << "default_path " << Me.m_default_path << endl;
2051      cout << "cmt config " <<
2052        Me.m_current_package << " " <<
2053        Me.m_current_version << " " <<
2054        Me.m_current_path << endl;
2055    }
2056
2057  if (Me.m_current_package == "CMT") return;
2058  if (Me.m_current_package == "methods") return;
2059
2060  cmt_string branch;
2061
2062  CmtSystem::basename (Me.m_current_dir, branch);
2063
2064  if ((branch != "mgr") && (branch != "cmt"))
2065    {
2066
2067      //
2068      // Here we are in a standalone package (ie completely unstructured)
2069      //
2070
2071      if (CmtSystem::test_file ("requirements"))
2072        {
2073          cout << "------------------------------------------" << endl;
2074          cout << "Configuring environment for standalone package." << endl;
2075          cout << "CMT version " << Me.m_cmt_version << "." << endl;
2076          cout << "System is " << Me.m_cmt_config << endl;
2077          cout << "------------------------------------------" << endl;
2078
2079          install_test_setup_scripts ();
2080          install_test_cleanup_scripts ();
2081
2082          Generator::build_default_makefile ();
2083        }
2084      else
2085        {
2086          cout << "==============================================" << endl;
2087          cout << "cmt config must be operated either upon "
2088            "an existing package" << endl;
2089          cout << " (ie. when a requirements file already exists)" << endl;
2090          cout << "   > cd ..." << endl;
2091          cout << "   > cmt config" << endl;
2092          cout << "or to create a new package" << endl;
2093          cout << "   > cmt config <package> <version> [<path>]" << endl;
2094          cout << "==============================================" << endl;
2095        }
2096
2097      return;
2098    }
2099
2100  configure_current_package ();
2101
2102  Generator::build_default_makefile ();
2103
2104  CmtSystem::cmt_string_vector makes;
2105  cmt_regexp expression ("[.]n?make(sav)?$");
2106
2107  CmtSystem::scan_dir (".", expression, makes);
2108 
2109  if (makes.size () > 0)
2110    {
2111      cout << "Removing all previous make fragments from " << branch << endl;
2112
2113      for (int i = 0; i < makes.size (); i++)
2114        {
2115          const cmt_string& s = makes[i];
2116          CmtSystem::cmt_string_vector words;
2117          CmtSystem::split (s, '.', words);
2118          if (words.size()>=2)
2119            if (CmtSystem::get_makefile_suffix () == "nmake" && words[1] == "nmake")
2120              CmtSystem::remove_file (s);
2121            else if (CmtSystem::get_makefile_suffix () == "make" && words[1] == "make")
2122              CmtSystem::remove_file (s);
2123        }
2124    }
2125 
2126
2127  CmtSystem::cd ("..");
2128
2129  CmtSystem::scan_dir (Me.m_cmt_config, expression, makes); 
2130   
2131  if (makes.size () > 0) 
2132    {
2133      cout << "Removing all previous make fragments from "
2134           << Me.m_cmt_config << endl; 
2135
2136      for (int i = 0; i < makes.size (); i++) 
2137        { 
2138          const cmt_string& s = makes[i];
2139          CmtSystem::cmt_string_vector words;
2140          CmtSystem::split (s, '.', words);
2141          if (words.size()>=2)
2142            if (CmtSystem::get_makefile_suffix () == "nmake" && words[1] == "nmake")
2143              CmtSystem::remove_file (s);
2144            else if (CmtSystem::get_makefile_suffix () == "make" && words[1] == "make")
2145              CmtSystem::remove_file (s);
2146        }   
2147    } 
2148
2149  CmtSystem::cd (branch); 
2150
2151  Use& use = Use::current ();
2152
2153  use.set (Me.m_current_package,
2154           Me.m_current_version,
2155           Me.m_current_path,
2156           "",
2157           "");
2158
2159  use.change_path (Me.m_current_path);
2160  use.style     = Me.m_current_style;
2161
2162  Me.m_quiet = true;
2163
2164  if (!reach_current_package ())
2165    {
2166      cout << "Cannot read the requirements file" << endl;
2167      return;
2168    }
2169
2170  install_setup_scripts ();
2171  install_cleanup_scripts ();
2172  install_native_version_file ();
2173
2174  CmtSystem::cd ("..");
2175
2176  Branch::BranchVector& branches = Branch::branches ();
2177
2178  int i;
2179
2180  for (i = 0; i < branches.size (); i++)
2181    {
2182      const Branch& branch = branches[i];
2183      const cmt_string& branch_name = branch.name ();
2184
2185      if (!CmtSystem::test_directory (branch_name))
2186        {
2187          if (!CmtSystem::mkdir (branch_name))
2188            {
2189              cout << "Cannot create the " << branch_name <<" branch" << endl;
2190            }
2191          else
2192            {
2193              cout << "Installing the " << branch_name << " directory" << endl;
2194            }
2195        }
2196      else
2197        {
2198          cout << branch_name << " directory already installed" << endl;
2199        }
2200    }
2201}
2202
2203
2204//----------------------------------------------------------
2205void Cmt::do_relocate (const ArgParser& ap)
2206{
2207  if (CmtLock::check () == CmtLock::locked_by_another_user)
2208    {
2209      CmtError::set (CmtError::conflicting_lock, "relocate>");
2210      return;
2211    }
2212
2213  Use& current_use = Use::current ();
2214
2215  if (Me.m_debug)
2216    {
2217      cout << "Cmt::do_relocate> " << endl;
2218      cout << "pwd "          << CmtSystem::pwd () << endl;
2219      cout << "current_dir "  << Me.m_current_dir << endl;
2220      cout << "default_path " << Me.m_default_path << endl;
2221      cout << "cmt config "   <<
2222        Me.m_current_package << " " <<
2223        Me.m_current_version << " " <<
2224        Me.m_current_path << endl;
2225    }
2226
2227  if (Me.m_current_package == "CMT")     return;
2228  if (Me.m_current_package == "methods") return;
2229
2230  cmt_string branch;
2231
2232  CmtSystem::basename (Me.m_current_dir, branch);
2233
2234  if ((branch != "mgr") && (branch != "cmt"))
2235    {
2236
2237      //
2238      // Here we are in a standalone package (ie completely unstructured)
2239      //
2240
2241      if (CmtSystem::test_file ("requirements"))
2242        {
2243          cout << "------------------------------------------" << endl;
2244          cout << "Configuring environment for standalone package." << endl;
2245          cout << "CMT version " << Me.m_cmt_version << "." << endl;
2246          cout << "System is "   << Me.m_cmt_config << endl;
2247          cout << "------------------------------------------" << endl;
2248
2249          install_test_setup_scripts ();
2250          install_test_cleanup_scripts ();
2251
2252          Generator::build_default_makefile ();
2253        }
2254      else
2255        {
2256          cout << "==============================================" << endl;
2257          cout << "cmt relocate must be operated either upon "
2258            "an existing package" << endl;
2259          cout << " (ie. when a requirements file already exists)" << endl;
2260          cout << "   > cd ..." << endl;
2261          cout << "   > cmt relocate" << endl;
2262          cout << "or to create a new package" << endl;
2263          cout << "   > cmt relocate <package> <version> [<path>]" << endl;
2264          cout << "==============================================" << endl;
2265        }
2266
2267      return;
2268    }
2269
2270  configure_current_package ();
2271
2272  Generator::build_default_makefile ();
2273 
2274  CmtSystem::cd ("..");   
2275  CmtSystem::cd (branch); 
2276
2277  Use& use = Use::current ();
2278
2279  use.set (Me.m_current_package,
2280           Me.m_current_version,
2281           Me.m_current_path,
2282           "",
2283           "");
2284
2285  use.change_path (Me.m_current_path);
2286  use.style     = Me.m_current_style;
2287
2288  Me.m_quiet = true;
2289   
2290  if (!reach_current_package ())
2291    {
2292      cout << "Cannot read the requirements file" << endl;
2293      return;
2294    }
2295
2296  install_setup_scripts ();
2297  install_cleanup_scripts ();
2298
2299  CmtSystem::cd ("..");
2300
2301  Branch::BranchVector& branches = Branch::branches ();
2302
2303  int i;
2304
2305  for (i = 0; i < branches.size (); i++)
2306    {
2307      const Branch& branch = branches[i];
2308      const cmt_string& branch_name = branch.name ();
2309
2310      if (!CmtSystem::test_directory (branch_name))
2311        {
2312          if (!CmtSystem::mkdir (branch_name))
2313            {
2314              cout << "Cannot create the " << branch_name <<" branch" << endl;
2315            }
2316          else
2317            {
2318              cout << "Installing the " << branch_name << " directory" << endl;
2319            }
2320        }
2321      else
2322        {
2323          cout << branch_name << " directory already installed" << endl;
2324        }
2325    }
2326}
2327
2328//----------------------------------------------------------
2329void Cmt::do_create (const ArgParser& ap)
2330{
2331  if (ap.arguments.size () < 2) return;
2332
2333  const cmt_string& package = ap.arguments[0];
2334  const cmt_string& version = ap.arguments[1];
2335  cmt_string offset;
2336  if (ap.arguments.size () >= 3) offset = ap.arguments[2];
2337
2338  if (Me.m_debug)
2339    {
2340      cout << "do_create>Me.m_current_package=" << Me.m_current_package << endl;
2341      cout << "do_create>package=" << package << endl;
2342    }
2343
2344  //if (Me.m_current_package == "CMT") return;
2345  //if (Me.m_current_package == "methods") return;
2346
2347  cmt_string the_path;
2348
2349  the_path = CmtSystem::pwd ();
2350
2351  if (offset != "")
2352    {
2353      if (!CmtSystem::absolute_path (offset))
2354        {
2355          // offset is really a relative offset
2356          the_path += CmtSystem::file_separator ();
2357          the_path += offset;
2358        }
2359      else // absolute path
2360        {
2361          the_path = offset;
2362        }
2363    }
2364
2365  CmtSystem::compress_path (the_path);
2366
2367  // Now 'the_path' contains the complete path where the package will be created
2368
2369  cout << "------------------------------------------" << endl;
2370  cout << "Configuring environment for package " << package <<
2371    " version " << version << "." << endl;
2372  cout << "CMT version " << Me.m_cmt_version << "." << endl;
2373  cout << "Root set to " << the_path << "." << endl;
2374  cout << "System is " << Me.m_cmt_config << endl;
2375  cout << "------------------------------------------" << endl;
2376
2377  if (!CmtSystem::test_directory (the_path))
2378    {
2379      if (!CmtSystem::mkdir (the_path))
2380        {
2381          cout << "Cannot create the path directory" << endl;
2382          return;
2383        }
2384      else
2385        {
2386          cout << "Installing the path directory" << endl;
2387        }
2388    }
2389
2390  CmtSystem::cd (the_path);
2391
2392  if (!CmtSystem::test_directory (package))
2393    {
2394      if (!CmtSystem::mkdir (package))
2395        {
2396          cout << "Cannot create the package directory" << endl;
2397          return;
2398        }
2399      else
2400        {
2401          cout << "Installing the package directory" << endl;
2402        }
2403    }
2404  else
2405    {
2406      cout << "Package directory already installed" << endl;
2407    }
2408
2409  CmtSystem::cd (package);
2410
2411  Use& current_use = Use::current ();
2412
2413  bool with_version_dir = current_use.get_strategy ("VersionDirectory");
2414
2415  CmtStructuringStyle style = get_current_structuring_style ();
2416
2417  if (style != default_structuring_style)
2418    {
2419      if (with_version_dir)
2420        {
2421          if (style == without_version_directory)
2422            {
2423              with_version_dir = false;
2424            }
2425        }
2426      else
2427        {
2428          if (style == with_version_directory)
2429            {
2430              with_version_dir = true;
2431            }
2432        }
2433    }
2434
2435  if (with_version_dir)
2436    {
2437      if (!CmtSystem::test_directory (version))
2438        {
2439          if (!CmtSystem::mkdir (version))
2440            {
2441              cout << "Cannot create the version directory" << endl;
2442              return;
2443            }
2444          else
2445            {
2446              cout << "Installing the version directory" << endl;
2447            }
2448        }
2449      else
2450        {
2451          cout << "Version directory already installed" << endl;
2452        }
2453
2454      CmtSystem::cd (version);
2455    }
2456  else
2457    {
2458      cout << "Version directory will not be created due to structuring style" << endl;
2459    }
2460
2461  if (!CmtSystem::test_directory ("cmt"))
2462    {
2463      if (!CmtSystem::test_directory ("mgr"))
2464        {
2465          if (!CmtSystem::mkdir ("cmt"))
2466            {
2467              cout << "Cannot create the cmt directory" << endl;
2468              return;
2469            }
2470          else
2471            {
2472              if (with_version_dir)
2473                {
2474                  Me.m_current_style = cmt_style;
2475                }
2476              else
2477                {
2478                  Me.m_current_style = no_version_style;
2479                }
2480
2481              cout << "Installing the cmt directory" << endl;
2482            }
2483        }
2484      else
2485        {
2486          if (with_version_dir)
2487            {
2488              Me.m_current_style = mgr_style;
2489            }
2490          else
2491            {
2492              Me.m_current_style = no_version_style;
2493            }
2494         
2495          cout << "Mgr directory already installed" << endl;
2496        }
2497    }
2498  else
2499    {
2500      if (with_version_dir)
2501        {
2502          Me.m_current_style = cmt_style;
2503        }
2504      else
2505        {
2506          Me.m_current_style = no_version_style;
2507        }
2508
2509      cout << "Cmt directory already installed" << endl;
2510    }
2511
2512  if (!CmtSystem::test_directory ("src"))
2513    {
2514      if (!CmtSystem::mkdir ("src"))
2515        {
2516          cout << "Cannot create the src directory" << endl;
2517          return;
2518        }
2519      else
2520        {
2521          cout << "Installing the src directory" << endl;
2522        }
2523    }
2524  else
2525    {
2526      cout << "src directory already installed" << endl;
2527    }
2528
2529  switch (Me.m_current_style)
2530    {
2531    case cmt_style:
2532    case no_version_style:
2533      CmtSystem::cd ("cmt");
2534      break;
2535    case mgr_style:
2536      CmtSystem::cd ("mgr");
2537      break;
2538    }
2539
2540  Generator::build_default_makefile ();
2541
2542  if (!CmtSystem::test_file ("requirements"))
2543    {
2544      // create an empty requirement file.
2545      ofstream f ("requirements");
2546      if (f)
2547        {
2548          f << "package " << package << endl;
2549          f << endl;
2550          f.close ();
2551        }
2552    }
2553
2554  if (!with_version_dir)
2555    {
2556      ofstream f ("version.cmt");
2557      if (f)
2558        {
2559          f << version << endl;
2560          f.close ();
2561        }
2562    }
2563
2564  Me.m_current_package = package;
2565  Me.m_current_version = version;
2566  Me.m_current_path    = the_path;
2567  Me.m_current_dir     = CmtSystem::pwd ();
2568
2569  do_config (ap);
2570}
2571
2572//----------------------------------------------------------
2573void Cmt::do_create_project (const ArgParser& ap)
2574{
2575  int argc = ap.arguments.size ();
2576  int arg = 0;
2577
2578  if (argc < 1) return;
2579
2580  cmt_string project;
2581  cmt_string release;
2582  cmt_string path;
2583
2584  project = ap.arguments[arg]; argc--; arg++;
2585
2586  if (argc > 0)
2587    {
2588      release = ap.arguments[arg];
2589
2590      if (release[0] != '-')
2591        {
2592          argc--; 
2593          arg++;
2594          if (argc > 0)
2595            {
2596              path = ap.arguments[arg];
2597              if (path[0] != '-')
2598                {
2599                  argc--; arg++;
2600                }
2601              else
2602                {
2603                  path = "";
2604                }
2605            }
2606        }
2607      else
2608        {
2609          release = "";
2610        }
2611    }
2612
2613  if (Project::create (project, release, path))
2614    {
2615      while (argc > 0)
2616        {
2617          const cmt_string& argument = ap.arguments[arg]; argc--; arg++;
2618         
2619          if (argument.substr (0, 5) == "-use=")
2620            {
2621              cmt_string use;
2622
2623              argument.substr (5, use);
2624
2625              CmtSystem::cmt_string_vector words;
2626              CmtSystem::split (use, ":", words);
2627
2628              ofstream f (Project::get_project_file_name (), ios_base::app);
2629              if (f)
2630                {
2631                  f << "use " << words[0] << " " << words[1] << " " << words[2] << endl;
2632                  f << endl;
2633                  f.close ();
2634                }
2635            }
2636        }
2637    }
2638}
2639
2640//----------------------------------------------------------
2641void Cmt::do_cvsbranches (const ArgParser& ap)
2642{
2643  Cvs::branches (ap.arguments[0]);
2644}
2645
2646//----------------------------------------------------------
2647void Cmt::do_cvssubpackages (const ArgParser& ap)
2648{
2649  Cvs::subpackages (ap.arguments[0]);
2650}
2651
2652//----------------------------------------------------------
2653void Cmt::do_cvssubprojects (const ArgParser& ap)
2654{
2655  Cvs::subprojects (ap.arguments[0]);
2656}
2657
2658//----------------------------------------------------------
2659void Cmt::do_cvstags (const ArgParser& ap)
2660{
2661  Cvs::tags (ap.arguments);
2662}
2663
2664//----------------------------------------------------------
2665void Cmt::do_do (const ArgParser& ap)
2666{
2667  if (ap.arguments.size () > 0) 
2668    {
2669      set_standard_macros ();
2670      Cmt::reset_all_sets_done ();
2671      Symbol::all_set ();
2672      Generator::build_default_makefile ();
2673
2674      Symbol* symbol = Symbol::find (ap.arguments[0]);
2675
2676      if (symbol == 0)
2677        {
2678          Me.m_action = action_show_action_names;
2679          /*
2680            if (!Me.m_quiet)
2681            {
2682            cerr << "Existing actions:" << endl;
2683            print_symbol_names (ap.mode);
2684            }
2685          */
2686          CmtError::set (CmtError::unknown_command, ap.arguments[0]);
2687          return;
2688        }
2689
2690      /*
2691        We convert extra arguments into the standard macro cmt_args
2692      */
2693
2694      cmt_string args;
2695
2696      for (int i = 1; i < ap.arguments.size (); i++)
2697        {
2698          cmt_string s = ap.arguments[i];
2699          if (i > 1) args += " ";
2700          args += s;
2701        }
2702
2703      cmt_string r = "macro cmt_args \"";
2704      r += args;
2705      r += "\"";
2706
2707      Use* current_use = &(Use::current ());
2708     
2709      SyntaxParser::parse_requirements_line (r, current_use);
2710
2711      cmt_string cmd = symbol->build_macro_value ();
2712      Symbol::expand (cmd);
2713
2714      cerr << "Execute action " << ap.arguments[0] << " => " << cmd << endl;
2715
2716      int status = CmtSystem::execute (cmd);
2717      if (status != 0)
2718        {
2719          CmtError::set (CmtError::execution_failed, ap.arguments[0], status);
2720        }
2721    }
2722}
2723
2724//----------------------------------------------------------
2725void Cmt::do_expand_model (const ArgParser& ap)
2726{
2727  set_standard_macros ();
2728
2729  if ((ap.arguments[0] == "-strict") && (ap.arguments.size () > 1))
2730    {
2731      CmtModel::strict_expand (ap.arguments[1]);
2732    }
2733  else if ((ap.arguments[0] == "-test") && (ap.arguments.size () > 2))
2734    {
2735      CmtModel::test_regexp (ap.arguments[1], ap.arguments[2]);
2736    }
2737  else if (ap.arguments.size () > 0)
2738    {
2739      CmtModel::expand (ap.arguments[0]);
2740    }
2741}
2742
2743/**
2744 *  Handle free filtering of text files containing $(xxx) or ${xxx} patterns
2745 *
2746 *  Substitution is performed against CMT macros and environment variables.
2747 *
2748 *  Arguments:
2749 *
2750 *    cmt filter input-file-name output-file-name
2751 *
2752 */
2753void Cmt::do_filter (const ArgParser& ap)
2754{
2755  if (ap.arguments.size () < 2) return;
2756
2757  cmt_string& input = ap.arguments[0];
2758  cmt_string& output = ap.arguments[1];
2759
2760  if (!CmtSystem::test_file (input))
2761    {
2762      cerr << "#CMT> File " << input << " not found" << endl;
2763      return;
2764    }
2765
2766  cmt_string text;
2767
2768  text.read (input);
2769
2770  set_standard_macros ();
2771
2772  Symbol::expand (text);
2773
2774  FILE* file = fopen (output, "wb");
2775  if (file == NULL)
2776    {
2777      cerr << "#CMT> Cannot write filtered file " << output << endl;
2778    }
2779  else
2780    {
2781      text.write (file);
2782      fclose (file);
2783    }
2784}
2785
2786//----------------------------------------------------------
2787void Cmt::do_help (const ArgParser& ap)
2788{
2789  //cerr << "ap.help_action=" << ap.help_action << " Me.m_action=" << Me.m_action << endl;
2790  if (Me.m_action == action_none)
2791    {
2792      CommandHelp::show_all ();
2793    }
2794  else
2795    {
2796      CommandHelp::show (Me.m_action);
2797    }
2798}
2799
2800//----------------------------------------------------------
2801void Cmt::do_lock (const ArgParser& ap)
2802{
2803  const cmt_string& package = Me.m_current_package;
2804  const cmt_string& version = Me.m_current_version;
2805  const cmt_string& path    = Me.m_current_path;
2806
2807  //(unsused) Use& use = Use::current();
2808
2809  cerr << "try to lock package " << package << " in " << CmtSystem::pwd () << endl;
2810
2811  set_standard_macros ();
2812
2813  CmtLock::status status = CmtLock::lock ();
2814}
2815
2816//----------------------------------------------------------
2817void Cmt::do_remove (const ArgParser& ap)
2818{
2819  const cmt_string& package = Me.m_current_package;
2820  const cmt_string& version = Me.m_current_version;
2821  const cmt_string& path    = Me.m_current_path;
2822
2823  //Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2824
2825  if (Me.m_current_package == "CMT") return;
2826  if (Me.m_current_package == "methods") return;
2827
2828  cmt_string the_path;
2829
2830  //the_path = Me.m_default_path;
2831  the_path = CmtSystem::pwd ();
2832
2833  if (path != "")
2834    {
2835      if (!CmtSystem::absolute_path (path))
2836        {
2837          // path is just a suffix
2838          the_path += CmtSystem::file_separator ();
2839          the_path += path;
2840        }
2841      else // absolute path
2842        {
2843          the_path = path;
2844        }
2845    }
2846
2847  CmtSystem::compress_path (the_path);
2848
2849  cout << "------------------------------------------" << endl;
2850  cout << "Removing package " << package <<
2851    " version " << version << "." << endl;
2852  cout << "CMT version " << Me.m_cmt_version << "." << endl;
2853  cout << "Root set to " << the_path << "." << endl;
2854  cout << "System is " << Me.m_cmt_config << endl;
2855  cout << "------------------------------------------" << endl;
2856
2857  the_path += CmtSystem::file_separator ();
2858  the_path += package;
2859
2860  if (!CmtSystem::cd (the_path))
2861    {
2862      cerr << "Path " << the_path << " not reachable" << endl;
2863      return;
2864    }
2865
2866  if (CmtSystem::test_directory (version))
2867    {
2868      if (CmtSystem::remove_directory (version))
2869        {
2870          cerr << "Version " << version << " has been removed from " << the_path << endl;
2871          CmtSystem::cmt_string_vector contents;
2872          CmtSystem::scan_dir (".", contents);
2873          if (contents.size () == 0)
2874            {
2875              CmtSystem::cd ("..");
2876              if (CmtSystem::remove_directory (package))
2877                {
2878                  cerr << "Package " << package << " has no more versions. Thus it has been removed."<< endl;
2879                }
2880            }
2881        }
2882      else
2883        {
2884          cerr << "Impossible to remove version " << version << " from " << the_path << endl;
2885        }
2886    }
2887  else if (CmtSystem::test_directory ("cmt"))
2888    {
2889      CmtSystem::cd ("cmt");
2890
2891      cmt_string v;
2892
2893      v.read ("version.cmt");
2894      if (v == version)
2895        {
2896          CmtSystem::cd ("..");
2897          if (!CmtSystem::remove_directory ("cmt"))
2898            {
2899              cerr << "Unstructured version " << version
2900                   << " has been removed from " << the_path << endl;
2901            }
2902          else
2903            {
2904              cerr << "Impossible to remove unstructured version " << version
2905                   << " from " << the_path << endl;
2906            }
2907        }
2908      else
2909        {
2910          cerr << "Version " << version << " not found" << endl;
2911        }
2912    }
2913  else
2914    {
2915      cerr << "Version " << version << " not found" << endl;
2916    }
2917}
2918
2919//----------------------------------------------------------
2920void Cmt::do_remove_library_links (const ArgParser& ap)
2921{
2922  if (CmtLock::check () == CmtLock::locked_by_another_user)
2923    {
2924      CmtError::set (CmtError::conflicting_lock, "remove_library_links>");
2925      return;
2926    }
2927
2928  set_standard_macros ();
2929
2930  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
2931  Use& current_use = Use::current ();
2932  int i;
2933  cmt_string shlibsuffix;
2934  cmt_string symunlink;
2935
2936  {
2937    Symbol* macro = Symbol::find ("shlibsuffix");
2938    if (macro == 0) return;
2939    shlibsuffix = macro->build_macro_value ();
2940    Symbol::expand (shlibsuffix);
2941  }
2942
2943  {
2944    Symbol* macro = Symbol::find ("symunlink");
2945    if (macro == 0) return;
2946    symunlink = macro->build_macro_value ();
2947    Symbol::expand (symunlink);
2948  }
2949
2950  for (i = 0; i < Uses.size (); i++)
2951    {
2952      Use* use = Uses[i];
2953
2954      if (use->discarded) continue;
2955      if (use->m_hidden) continue;
2956
2957      if (!use->located ())
2958        {
2959          if (!Me.m_quiet)
2960            {
2961              cerr << "#CMT> package " << use->get_package_name () <<
2962                " " << use->version << " " << use->path << 
2963                " not found" <<
2964                endl;
2965            }
2966        }
2967      else
2968        {
2969          if (use->get_package_name () == "CMT") continue;
2970          if (use->get_package_name () == current_use.get_package_name ()) continue;
2971
2972          cmt_string s;
2973
2974          s = use->get_package_name ();
2975          s += "_libraries";
2976
2977          Symbol* libraries_macro = Symbol::find (s);
2978
2979          if (libraries_macro == 0) continue;
2980
2981          cmt_string libraries = libraries_macro->build_macro_value ();
2982          Symbol::expand (libraries);
2983
2984          static CmtSystem::cmt_string_vector values;
2985
2986          CmtSystem::split (libraries, " \t", values);
2987
2988          for (int j = 0; j < values.size (); j++)
2989            {
2990              const cmt_string& library = values[j];
2991
2992              static cmt_string libname;
2993              static cmt_string name;
2994
2995              // Is it a simple name or a complete path?
2996
2997              libname = library;
2998              Symbol::expand (libname);
2999
3000              if (CmtSystem::absolute_path (libname))
3001                {
3002                  /**
3003                   *   We assume here that "library" contains a complete path.
3004                   *   (including the complete syntax libxxx.so)
3005                   */
3006
3007                  cmt_string suffix;
3008                  CmtSystem::basename (library, name);
3009                }
3010              else
3011                {
3012                  /**
3013                   *   Here we expect that only the base name of the library
3014                   *   is given : ie it should not contain the "lib" prefix,
3015                   *   nor the suffix .so, nor any path prefix.
3016                   *    This of course should generally correspond to a constituent name.
3017                   */
3018
3019                  name = "lib";
3020                  name += libname;
3021                  name += ".";
3022                  name += shlibsuffix;
3023                }
3024
3025              Symbol::expand (libname);
3026
3027              if (current_use.get_strategy ("InstallArea"))
3028                {
3029                  const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
3030
3031                  cmt_string s1 = ia_mgr.get_installarea ();
3032
3033                  {
3034                    Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
3035                    if (symbol != 0)
3036                      {
3037                        s1 = symbol->build_macro_value ();
3038                        Symbol::expand (s1);
3039                      }
3040                  }
3041                 
3042                  cmt_string s2;
3043
3044                  {
3045                    Symbol* macro = Symbol::find ("tag");
3046                    if (macro != 0)
3047                      {
3048                        s2 = macro->build_macro_value ();
3049                        Symbol::expand (s2);
3050                      }
3051                  }
3052
3053                  // Now deleting the reference file
3054
3055                  s = symunlink;
3056                  s += " ";
3057                  s += s1;
3058                  s += CmtSystem::file_separator ();
3059                  s += s2;
3060                  s += CmtSystem::file_separator ();
3061                  s += "lib";
3062                  s += CmtSystem::file_separator ();
3063                  s += name;
3064                  s += ".cmtref";
3065                  s += " ";
3066                  s += s1;
3067                  s += CmtSystem::file_separator ();
3068                  s += s2;
3069                  s += CmtSystem::file_separator ();
3070                  s += "lib";
3071                  s += CmtSystem::file_separator ();
3072                  s += name;
3073                }
3074              else
3075                {
3076                  s = symunlink;
3077                  s += " ../$(";
3078                  s += current_use.get_package_name ();
3079                  s += "_tag)/";
3080                  s += name;
3081                }
3082
3083              Symbol::expand (s);
3084
3085              if (!Me.m_quiet) cerr << s << endl;
3086
3087              int status = CmtSystem::execute (s);
3088
3089              if (status != 0)
3090                {
3091                  if (status != 2) CmtError::set (CmtError::execution_error, s);
3092
3093                  cerr << "#CMT> Cannot remove the symbolic link " << s << endl;
3094
3095                  break;
3096                }
3097            }
3098        }
3099    }
3100}
3101
3102//----------------------------------------------------------
3103void Cmt::do_run (const ArgParser& ap)
3104{
3105  if (ap.arguments.size () > 0) 
3106    {
3107      set_standard_macros ();
3108      Cmt::reset_all_sets_done ();
3109      Symbol::all_set ();
3110
3111      cmt_string cmd;
3112
3113      for (int i = 0; i < ap.arguments.size (); i++)
3114        {
3115          cmd += ap.arguments[i];
3116          cmd += " ";
3117        }
3118
3119      CmtSystem::execute (cmd);
3120    }
3121}
3122
3123//----------------------------------------------------------
3124void Cmt::do_run_sequence (const ArgParser& ap)
3125{
3126  if (ap.arguments.size () == 0) cerr << "#CMT> run_sequence: no sequence specified" << endl;
3127
3128  SequenceRunner runner;
3129
3130  cerr << "# cmt run_sequence: sequence " << ap.arguments[0] << endl;
3131
3132  runner.run (ap.arguments[0]);
3133}
3134
3135//----------------------------------------------------------
3136void Cmt::do_set_version (const ArgParser& ap)
3137{
3138  if (ap.arguments.size () == 0) cerr << "#CMT> set version: no version specified" << endl;
3139
3140  const cmt_string& version = ap.arguments[0];
3141
3142  int v, r, p;
3143
3144  if (!CmtSystem::is_version_directory (version, v, r, p))
3145    {
3146      cerr << "#CMT> set version " << version << " is not a correct version syntax" << endl;
3147      return;
3148    }
3149
3150  if ((v == -1) || (r == -1) || (p == -1))
3151    {
3152      cerr << "#CMT> set version " << version
3153           << " You cannot use wild card to set a version" << endl;
3154      return;
3155    }
3156
3157  // We want to install the version.cmt file
3158
3159  // We first check we are in a cmt branch
3160  cmt_string h = CmtSystem::pwd ();
3161  cmt_string branch;
3162  CmtSystem::basename (h, branch);
3163
3164  if (branch != "cmt")
3165    {
3166      cerr << "#CMT> set version " << version << " must be applied in a cmt directory" 
3167           << endl;
3168      return;
3169    }
3170
3171  CmtSystem::dirname (h, h);
3172  CmtSystem::basename (h, branch);
3173
3174  if (branch == version)
3175    {
3176      cerr << "#CMT> set version " << version << " is already available as a version directory" 
3177           << endl;
3178      return;
3179    }
3180
3181  cerr << "Writing version file : " << version << endl;
3182
3183  version.write ("version.cmt");
3184}
3185
3186//----------------------------------------------------------
3187void Cmt::do_set_versions (const ArgParser& ap)
3188{
3189  CmtSystem::cmt_string_vector args;
3190
3191  args = ap.arguments;
3192  {
3193    cmt_string& s = args.add ();
3194    s = "cmt";
3195  }
3196  {
3197    cmt_string& s = args.add ();
3198    s = "set";
3199  }
3200  {
3201    cmt_string& s = args.add ();
3202    s = "version";
3203  }
3204  {
3205    cmt_string& s = args.add ();
3206    s = "<version>";
3207  }
3208
3209  Me.m_action = action_broadcast;
3210
3211  do_broadcast (ap);
3212}
3213
3214//----------------------------------------------------------
3215void Cmt::do_setup (const ArgParser& ap)
3216{
3217  Use& current_use = Use::current ();
3218
3219  do_check_configuration (ap);
3220
3221  print (ap.mode);
3222
3223  //
3224  //  Try a cleanup of the installation area
3225  //
3226  if (current_use.get_strategy ("InstallArea"))
3227    {
3228      CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
3229
3230      ia_mgr.setup ();
3231    }
3232}
3233
3234//----------------------------------------------------------
3235void Cmt::do_show_action (const ArgParser& ap)
3236{
3237  cmt_string target;
3238
3239  if (ap.arguments.size () > 0) target = ap.arguments[0];
3240
3241  Symbol* symbol;
3242
3243  set_standard_macros ();
3244
3245  symbol = Symbol::find (target);
3246
3247  if (symbol == 0) 
3248    {
3249      cmt_string t = " ";
3250      t += target;
3251      t += " is not defined ";
3252
3253      CmtError::set (CmtError::symbol_not_found, t);
3254
3255      return;
3256    }
3257  else
3258    {
3259      cmt_string t = target;
3260      t += " is a ";
3261
3262      if ((Me.m_action == action_show_action) ||
3263          (Me.m_action == action_show_action_value))
3264        {
3265          if (symbol->type != Symbol::SymbolAction)
3266            {
3267              if (symbol->type == Symbol::SymbolMacro)
3268                {
3269                  t += "macro";
3270                }
3271              else if (symbol->type == Symbol::SymbolSet)
3272                {
3273                  t += "set";
3274                }
3275              else if (symbol->type == Symbol::SymbolPath)
3276                {
3277                  t += "path";
3278                }
3279              else if (symbol->type == Symbol::SymbolAlias)
3280                {
3281                  t += "alias";
3282                }
3283
3284              CmtError::set (CmtError::warning, t);
3285            }
3286        }
3287    }
3288
3289  if (symbol->value_lists.size () < 1) return;
3290
3291  symbol->show_macro (ap.mode);
3292}
3293
3294//----------------------------------------------------------
3295void Cmt::do_show_action_names (const ArgParser& ap)
3296{
3297  if (ap.arguments.size () > 0)
3298    {
3299      const cmt_string& pattern = ap.arguments[0];
3300      print_symbol_names (ap.mode, pattern);
3301    }
3302  else
3303    {
3304      print_symbol_names (ap.mode);
3305    }
3306}
3307
3308//----------------------------------------------------------
3309void Cmt::do_show_action_value (const ArgParser& ap)
3310{
3311  do_show_macro (ap);
3312}
3313
3314//----------------------------------------------------------
3315void Cmt::do_show_actions (const ArgParser& ap)
3316{
3317  if (ap.arguments.size () > 0)
3318    {
3319      const cmt_string& pattern = ap.arguments[0];
3320      print_macros (ap.mode, pattern);
3321    }
3322  else
3323    {
3324      print_macros (ap.mode);
3325    }
3326}
3327
3328//----------------------------------------------------------
3329void Cmt::do_show_all_tags (const ArgParser& /*ap*/)
3330{
3331  Tag::TagPtrVector tags = Tag::tags ();
3332  int index;
3333
3334  set_standard_macros ();
3335
3336  for (index = 0; index < tags.size (); index++)
3337    {
3338      const Tag* tag = tags[index];
3339      if (tag != 0)
3340        {
3341          tag->show_definition (true);
3342        }
3343    }
3344}
3345
3346//----------------------------------------------------------
3347void Cmt::do_show_applied_patterns (const ArgParser& /*ap*/)
3348{
3349  Pattern::show_all_applied_patterns ();
3350}
3351
3352//----------------------------------------------------------
3353void Cmt::do_show_author (const ArgParser& /*ap*/)
3354{
3355  Use& use = Use::current();
3356
3357  cout << use.author << endl;
3358 
3359}
3360//----------------------------------------------------------
3361void Cmt::do_show_project_author (const ArgParser& /*ap*/)
3362{
3363  cmt_string cmtpath;
3364  cmt_string offset;
3365
3366  Use& use = Use::current();   
3367  use.get_cmtpath_and_offset (cmtpath, offset);
3368
3369  Project* p = Project::find_by_cmtpath (cmtpath);
3370
3371  cout << p->get_author () << endl;
3372}
3373
3374//----------------------------------------------------------
3375void Cmt::do_show_branches (const ArgParser& ap)
3376{
3377  Branch::print_all (ap.mode);
3378}
3379
3380//----------------------------------------------------------
3381void Cmt::do_show_clients (const ArgParser& ap)
3382{
3383  cmt_string package   = "";
3384  cmt_string version   = "";
3385  cmt_string path_name = "";
3386
3387  if (ap.arguments.size () >= 1) package  = ap.arguments[0];
3388  if (ap.arguments.size () >= 2) version  = ap.arguments[1];
3389  if (ap.arguments.size () >= 3) path_name = ap.arguments[2];
3390
3391  PathScanner scanner;
3392  ClientCollector collector (package, version);
3393
3394  clear     ();
3395  configure ();
3396
3397  cout << "# ----------- Clients of " << package <<
3398    " " << version <<
3399    " " << path_name <<
3400    endl;
3401
3402  if (path_name == "")
3403    {
3404      Project::scan_paths (scanner, collector);
3405    }
3406  else
3407    {
3408      scanner.scan_path (path_name, collector);
3409    }
3410
3411  cout << "# ----------- " << collector.count () << " clients found." << endl;
3412}
3413
3414//----------------------------------------------------------
3415void Cmt::do_show_cmtpath_patterns (const ArgParser& /*ap*/)
3416{
3417  set_standard_macros ();
3418  CmtPathPattern::show_all ();
3419}
3420
3421//----------------------------------------------------------
3422void Cmt::do_show_constituent (const ArgParser& ap)
3423{
3424  if (ap.arguments.size () > 0) 
3425    {
3426      set_standard_macros ();
3427
3428      Constituent* c = Constituent::find (ap.arguments[0]);
3429      if (c != 0)
3430        {
3431          c->show ();
3432        }
3433    }
3434}
3435
3436//----------------------------------------------------------
3437void Cmt::do_show_constituent_names (const ArgParser& /*ap*/)
3438{
3439  set_standard_macros ();
3440  Constituent::show_names ();
3441}
3442
3443//----------------------------------------------------------
3444void Cmt::do_show_constituents (const ArgParser& /*ap*/)
3445{
3446  set_standard_macros ();
3447  Constituent::show_all ();
3448}
3449
3450//----------------------------------------------------------
3451void Cmt::do_show_cycles (const ArgParser& /*ap*/)
3452{
3453  set_standard_macros ();
3454  Use& use = Use::current();
3455
3456  use.show_cycles ();
3457}
3458
3459//----------------------------------------------------------
3460void Cmt::do_show_fragment (const ArgParser& ap)
3461{
3462  if (ap.arguments.size () > 0) Fragment::show (ap.arguments[0]);
3463}
3464
3465//----------------------------------------------------------
3466void Cmt::do_show_fragments (const ArgParser& /*ap*/)
3467{
3468  Fragment::show_all ();
3469}
3470
3471//----------------------------------------------------------
3472void Cmt::do_show_groups (const ArgParser& /*ap*/)
3473{
3474  Group::show_all ();
3475}
3476
3477//----------------------------------------------------------
3478void Cmt::do_show_include_dirs (const ArgParser& /*ap*/)
3479{
3480  cmt_string temp;
3481
3482  Use& use = Use::current();
3483
3484  set_standard_macros ();
3485
3486  if (use.include_path == "")
3487    {
3488      temp += "$(src) ";
3489    }
3490  else if (use.include_path != "none")
3491    {
3492      temp += use.include_path;
3493      temp += " ";
3494    }
3495
3496  for (int include_number = 0;
3497       include_number < use.includes.size ();
3498       include_number++)
3499    {
3500      Include& incl = use.includes[include_number];
3501
3502      if (incl.name == "") continue;
3503
3504      temp += incl.name;
3505      temp += " ";
3506    }
3507
3508  cout << temp << endl;
3509}
3510
3511//----------------------------------------------------------
3512void Cmt::do_show_language (const ArgParser& ap)
3513{
3514  if (ap.arguments.size () > 0) 
3515    {
3516      set_standard_macros ();
3517      Language::show (ap.arguments[0]);
3518    }
3519}
3520
3521//----------------------------------------------------------
3522void Cmt::do_show_languages (const ArgParser& /*ap*/)
3523{
3524  set_standard_macros ();
3525  Language::show_all ();
3526}
3527
3528//----------------------------------------------------------
3529void Cmt::do_show_macro (const ArgParser& ap)
3530{
3531  cmt_string target;
3532
3533  if (ap.arguments.size () > 0) target = ap.arguments[0];
3534
3535  Symbol* symbol;
3536
3537  set_standard_macros ();
3538
3539  symbol = Symbol::find (target);
3540
3541  if (symbol == 0) 
3542    {
3543      cmt_string t = " ";
3544      t += target;
3545      t += " is not defined ";
3546
3547      CmtError::set (CmtError::symbol_not_found, t);
3548
3549      return;
3550    }
3551  else
3552    {
3553      cmt_string t = target;
3554      t += " is a ";
3555
3556      if ((Me.m_action == action_show_macro) ||
3557          (Me.m_action == action_show_macro_value))
3558        {
3559          if (symbol->type != Symbol::SymbolMacro)
3560            {
3561              if (symbol->type == Symbol::SymbolAction)
3562                {
3563                  t += "action";
3564                }
3565              else if (symbol->type == Symbol::SymbolSet)
3566                {
3567                  t += "set";
3568                }
3569              else if (symbol->type == Symbol::SymbolPath)
3570                {
3571                  t += "path";
3572                }
3573              else if (symbol->type == Symbol::SymbolAlias)
3574                {
3575                  t += "alias";
3576                }
3577
3578              CmtError::set (CmtError::warning, t);
3579            }
3580        }
3581      else if ((Me.m_action == action_show_set) ||
3582               (Me.m_action == action_show_set_value))
3583        {
3584          if ((symbol->type != Symbol::SymbolSet) &&
3585              (symbol->type != Symbol::SymbolPath) &&
3586              (symbol->type != Symbol::SymbolAction) &&
3587              (symbol->type != Symbol::SymbolAlias))
3588            {
3589              t += "macro";
3590
3591              CmtError::set (CmtError::warning, t);
3592            }
3593        }
3594    }
3595
3596  if (symbol->value_lists.size () < 1) return;
3597
3598  symbol->show_macro (ap.mode);
3599}
3600
3601//----------------------------------------------------------
3602void Cmt::do_show_macro_names (const ArgParser& ap)
3603{
3604  if (ap.arguments.size () > 0)
3605    {
3606      const cmt_string& pattern = ap.arguments[0];
3607      print_symbol_names (ap.mode, pattern);
3608    }
3609  else
3610    {
3611      print_symbol_names (ap.mode);
3612    }
3613}
3614
3615//----------------------------------------------------------
3616void Cmt::do_show_macro_value (const ArgParser& ap)
3617{
3618  do_show_macro (ap);
3619}
3620
3621//----------------------------------------------------------
3622void Cmt::do_show_macros (const ArgParser& ap)
3623{
3624  if (ap.arguments.size () > 0)
3625    {
3626      const cmt_string& pattern = ap.arguments[0];
3627      print_macros (ap.mode, pattern);
3628    }
3629  else
3630    {
3631      print_macros (ap.mode);
3632    }
3633}
3634
3635//----------------------------------------------------------
3636void Cmt::do_show_manager (const ArgParser& /*ap*/)
3637{
3638  Use& use = Use::current();
3639
3640  cout << use.manager << endl;
3641}
3642
3643//----------------------------------------------------------
3644void Cmt::do_show_packages (const ArgParser& ap)
3645{
3646  cmt_string path_name;
3647
3648  if (ap.arguments.size () > 0) path_name = ap.arguments[0];
3649
3650  PathScanner   scanner;
3651  PackageViewer viewer;
3652
3653  if (path_name == "")
3654    {
3655      Project::scan_paths (scanner, viewer);
3656    }
3657  else
3658    {
3659      scanner.scan_path (path_name, viewer);
3660    }
3661}
3662
3663//----------------------------------------------------------
3664void Cmt::do_show_path (const ArgParser& /*ap*/)
3665{
3666  Project::show_paths ();
3667}
3668
3669//----------------------------------------------------------
3670void Cmt::do_show_pattern (const ArgParser& ap)
3671{
3672  cmt_string name;
3673  if (ap.arguments.size () > 0) name = ap.arguments[0];
3674  Pattern::show (name);
3675}
3676
3677//----------------------------------------------------------
3678void Cmt::do_show_pattern_names (const ArgParser& /*ap*/)
3679{
3680  Pattern::show_all_names ();
3681}
3682
3683//----------------------------------------------------------
3684void Cmt::do_show_patterns (const ArgParser& /*ap*/)
3685{
3686  Pattern::show_all ();
3687}
3688
3689//----------------------------------------------------------
3690void Cmt::do_show_projects (const ArgParser& /*ap*/)
3691{
3692  Project::show_all ();
3693}
3694
3695//----------------------------------------------------------
3696void Cmt::do_show_pwd (const ArgParser& /*ap*/)
3697{
3698  cout << Me.m_current_dir << endl;
3699}
3700
3701//----------------------------------------------------------
3702void Cmt::do_show_setup (const ArgParser& ap)
3703{
3704  cout << "----------> uses" << endl;
3705  do_show_uses (ap);
3706
3707  cout << "----------> tags" << endl;
3708  do_show_tags (ap);
3709
3710  cout << "----------> CMTPATH" << endl;
3711  do_show_path (ap);
3712}
3713
3714//----------------------------------------------------------
3715void Cmt::do_show_set (const ArgParser& ap)
3716{
3717  do_show_macro (ap);
3718}
3719
3720//----------------------------------------------------------
3721void Cmt::do_show_set_names (const ArgParser& ap)
3722{
3723  if (ap.arguments.size () > 0)
3724    {
3725      const cmt_string& pattern = ap.arguments[0];
3726      print_symbol_names (ap.mode, pattern);
3727    }
3728  else
3729    {
3730      print_symbol_names (ap.mode);
3731    }
3732}
3733
3734//----------------------------------------------------------
3735void Cmt::do_show_set_value (const ArgParser& ap)
3736{
3737  do_show_macro (ap);
3738}
3739
3740//----------------------------------------------------------
3741void Cmt::do_show_sets (const ArgParser& ap)
3742{
3743  if (ap.arguments.size () > 0)
3744    {
3745      const cmt_string& pattern = ap.arguments[0];
3746      print_macros (ap.mode, pattern);
3747    }
3748  else
3749    {
3750      print_macros (ap.mode);
3751    }
3752}
3753
3754//----------------------------------------------------------
3755void Cmt::do_show_strategies (const ArgParser& /*ap*/)
3756{
3757  Use& current_use = Use::current ();
3758
3759  Project::show_specified_strategies_for_all ();
3760
3761  Project* p = Project::get_current ();
3762
3763  /*
3764    if (p != 0) p->show ();
3765    else cout << "No current project" << endl;
3766  */
3767
3768  cout << "Build strategy     : ";
3769
3770  if (current_use.get_strategy ("BuildPrototypes"))
3771    {
3772      cout << "prototypes";
3773    }
3774  else
3775    {
3776      cout << "no_prototypes";
3777    }
3778 
3779  if (current_use.get_strategy ("InstallArea"))
3780    {
3781      cout << " with_installarea";
3782    }
3783  else
3784    {
3785      cout << " without_installarea";
3786    }
3787 
3788  cout << endl;
3789
3790  cout << "Setup strategy     : ";
3791 
3792  if (current_use.get_strategy ("SetupConfig"))
3793    {
3794      cout << "config";
3795    }
3796  else
3797    {
3798      cout << "no_config";
3799    }
3800 
3801  if (current_use.get_strategy ("SetupRoot"))
3802    {
3803      cout << " root";
3804    }
3805  else
3806    {
3807      cout << " no_root";
3808    }
3809 
3810  if (current_use.get_strategy ("SetupCleanup"))
3811    {
3812      cout << " cleanup";
3813    }
3814  else
3815    {
3816      cout << " no_cleanup";
3817    }
3818
3819  cout << endl;
3820 
3821  cout << "Structure strategy : ";
3822 
3823  if (current_use.get_strategy ("VersionDirectory"))
3824    {
3825      cout << "with_version_directory";
3826    }
3827  else
3828    {
3829      cout << "without_version_directory";
3830    }
3831 
3832  cout << endl;
3833
3834  if (Me.m_current_structuring_style != default_structuring_style)
3835    {
3836      cout << "Structuring style  : ";
3837
3838      switch (Me.m_current_structuring_style)
3839        {
3840        case without_version_directory:
3841          cout << "without_version_directory";
3842          break;
3843        case with_version_directory:
3844          cout << "with_version_directory";
3845          break;
3846        }
3847
3848      cout << endl;
3849    }
3850}
3851
3852//----------------------------------------------------------
3853void Cmt::do_show_tags (const ArgParser& /*ap*/)
3854{
3855  Tag::TagPtrVector tags = Tag::tags ();
3856  int index;
3857
3858  set_standard_macros ();
3859
3860  for (index = 0; index < tags.size (); index++)
3861    {
3862      const Tag* tag = tags[index];
3863      if (tag != 0)
3864        {
3865          tag->show (Me.m_quiet);
3866        }
3867    }
3868}
3869
3870//----------------------------------------------------------
3871void Cmt::do_show_use_paths (const ArgParser& ap)
3872{
3873  const cmt_string& to_name = ap.arguments[0];
3874
3875  Use* current = &(Use::current());
3876
3877  current->get_all_clients (to_name);
3878}
3879
3880//----------------------------------------------------------
3881void Cmt::do_show_uses (const ArgParser& /*ap*/)
3882{
3883  Use::show_all ();
3884}
3885
3886//----------------------------------------------------------
3887void Cmt::do_show_version (const ArgParser& /*ap*/)
3888{
3889  cout << Me.m_current_version << endl;
3890}
3891
3892//----------------------------------------------------------
3893void Cmt::do_show_versions (const ArgParser& ap)
3894{
3895  cmt_string package_name;
3896
3897  if (ap.arguments.size () > 0) package_name = ap.arguments[0];
3898
3899  PathScanner scanner;
3900
3901  Project::scan_paths_for_package (scanner, package_name);
3902}
3903
3904//----------------------------------------------------------
3905void Cmt::do_show_system (const ArgParser& /*ap*/)
3906{
3907  cout << CmtSystem::get_cmt_config () << endl;
3908}
3909
3910//----------------------------------------------------------
3911void Cmt::do_unlock (const ArgParser& /*ap*/)
3912{
3913  const cmt_string& package = Me.m_current_package;
3914  const cmt_string& version = Me.m_current_version;
3915  const cmt_string& path    = Me.m_current_path;
3916
3917  // (unused??) Use& use = Use::current();
3918
3919  cerr << "try to unlock package " << package << " in " << CmtSystem::pwd () << endl;
3920
3921  set_standard_macros ();
3922
3923  CmtLock::status status = CmtLock::unlock ();
3924}
3925
3926//----------------------------------------------------------
3927void Cmt::do_version (const ArgParser& /*ap*/)
3928{
3929  cout << CMTVERSION << endl;
3930}
3931
3932
3933
3934//----------------------------------------------------------
3935ActionType Cmt::get_action ()
3936{
3937  return (Me.m_action);
3938}
3939
3940/*
3941  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path ()
3942  {
3943  return (Me.m_cmt_path);
3944  }
3945
3946  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_pwds ()
3947  {
3948  return (Me.m_cmt_path_pwds);
3949  }
3950
3951  const CmtSystem::cmt_string_vector& Cmt::get_cmt_path_sources ()
3952  {
3953  return (Me.m_cmt_path_sources);
3954  }
3955*/
3956
3957const cmt_string& Cmt::get_cmt_home ()
3958{
3959  return (Me.m_cmt_home);
3960}
3961
3962const cmt_string& Cmt::get_cmt_user_context ()
3963{
3964  return (Me.m_cmt_user_context);
3965}
3966
3967const cmt_string& Cmt::get_cmt_version ()
3968{
3969  return (Me.m_cmt_version);
3970}
3971
3972const cmt_string& Cmt::get_current_dir ()
3973{
3974  return (Me.m_current_dir);
3975}
3976
3977const cmt_string& Cmt::get_current_package ()
3978{
3979  return (Me.m_current_package);
3980}
3981
3982const cmt_string& Cmt::get_current_cmtpath ()
3983{
3984  return (Me.m_current_cmtpath);
3985}
3986
3987const cmt_string& Cmt::get_current_offset ()
3988{
3989  return (Me.m_current_offset);
3990}
3991
3992AccessMode Cmt::get_current_access ()
3993{
3994  return (Me.m_current_access);
3995}
3996
3997CmtStructuringStyle Cmt::get_current_structuring_style ()
3998{
3999  return (Me.m_current_structuring_style);
4000}
4001
4002CmtDirStyle Cmt::get_current_style ()
4003{
4004  return (Me.m_current_style);
4005}
4006
4007const cmt_string& Cmt::get_current_version ()
4008{
4009  return (Me.m_current_version);
4010}
4011
4012const cmt_string& Cmt::get_current_target ()
4013{
4014  return (Me.m_current_target);
4015}
4016
4017bool Cmt::get_debug ()
4018{
4019  return (Me.m_debug);
4020}
4021
4022bool Cmt::get_quiet ()
4023{
4024  return (Me.m_quiet);
4025}
4026
4027bool Cmt::get_disable_warnings ()
4028{
4029  return (Me.m_disable_warnings);
4030}
4031
4032bool Cmt::get_warnings ()
4033{
4034  return (Me.m_warnings);
4035}
4036
4037bool Cmt::get_recursive ()
4038{
4039  return (Me.m_recursive);
4040}
4041
4042CmtScopeFilteringMode Cmt::get_scope_filtering_mode ()
4043{
4044  if (Me.m_scope_filtering_mode == default_filtering_mode)
4045    {
4046      return (block_private_uses);
4047    }
4048  else
4049    {
4050      return (Me.m_scope_filtering_mode);
4051    }
4052}
4053
4054//----------------------------------------------------------
4055bool Cmt::get_all_sets_done ()
4056{
4057  return (Me.m_all_sets_done);
4058}
4059
4060/**---------------------------------------------------------
4061   guess_current_project
4062
4063   if current directory is in one of the CMTPATHs, do nothing.
4064
4065   Otherwise, we want to guess the current project
4066
4067   move up in directories until cmt/project.cmt is found
4068
4069   for (;;)
4070   {
4071   if test -f ./cmt/project.cmt
4072   ok:
4073   this directory should become the first entry of the CMTPATH
4074   break
4075
4076   if (at top) break;
4077
4078   move up
4079   }
4080*/
4081void Cmt::guess_current_project ()
4082{
4083  Log;
4084
4085  log << "guess_current_project" << log_endl;
4086
4087  cmt_string here = CmtSystem::pwd ();
4088
4089  if (Project::find_in_cmt_paths (Me.m_current_dir) == "")
4090    {
4091      cmt_string project_file = "cmt";
4092      project_file += CmtSystem::file_separator ();
4093      project_file += Project::get_project_file_name ();
4094
4095      cmt_string pwd;
4096
4097      for (;;)
4098        {
4099          pwd = CmtSystem::pwd ();
4100          if (CmtSystem::test_file (project_file))
4101            {
4102              //this directory should become the first entry of the CMTPATH
4103
4104              IProjectFactory& factory = ProjectFactory::instance ();
4105              factory.create_project ("", pwd, "CurrentProject", 0);
4106
4107              break;
4108            }
4109
4110          log << "pwd=" << CmtSystem::pwd () << log_endl;
4111         
4112          if (!CmtSystem::cd (".."))
4113            {
4114              break;
4115            }
4116
4117          if (CmtSystem::pwd () == pwd)
4118            {
4119              break;
4120            }
4121        }
4122
4123      CmtSystem::cd (Me.m_current_dir);
4124    }
4125
4126  //cmt_string buffer = "path CMTPATH \n";
4127  cmt_string buffer;
4128  Project::fill_cmtpaths (buffer);
4129  //cerr << "buffer = " << buffer << endl;
4130  Use& use = Use::current();
4131
4132  bool save_quiet = Me.m_quiet;
4133  Me.m_quiet = true;
4134
4135  SyntaxParser::parse_requirements_text (buffer, "", &use);
4136
4137  Me.m_quiet = save_quiet;
4138
4139  Me.m_autoconfigure_cmtpath = true;
4140
4141  CmtSystem::cd (here);
4142}
4143
4144//----------------------------------------------------------
4145const cmt_string& Cmt::filter_dir (const cmt_string& dir)
4146{
4147  static cmt_string newdir;
4148
4149  CmtSystem::compress_path (dir, newdir);
4150
4151  return (newdir);
4152}
4153
4154//----------------------------------------------------------
4155static void dos_script_prefix (FILE* f, 
4156                               const cmt_string& cmt_root, 
4157                               const cmt_string& package, 
4158                               const cmt_string& version, 
4159                               const cmt_string& path, 
4160                               const cmt_string& action, 
4161                               const cmt_string& option = "")
4162{
4163  cmt_string no_device = path;
4164
4165  if (CmtSystem::absolute_path (path)) 
4166    {
4167      if (path[1] == ':')
4168        {
4169          no_device = path.substr (2);
4170        }
4171    }
4172
4173  if (package == "cmt_standalone")
4174    {
4175      no_device = "";
4176    }
4177  else
4178    {
4179      no_device = "..\\..\\..";
4180      if (Cmt::get_current_style () == no_version_style)
4181        {
4182          no_device = "..\\..";
4183        }
4184    }
4185
4186
4187  fprintf (f, "@echo off\n");
4188  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 ());
4189  fprintf (f, "\n");
4190  fprintf (f, "set cmttempfile=\"%%TEMP%%\\tmpsetup.bat\"\n");
4191  fprintf (f, "%%CMTROOT%%\\%%CMTBIN%%\\cmt.exe %s -bat "
4192           " -pack=%s -version=%s -path=\"%%~d0%%~p0%s\" "
4193           " %s "
4194           "%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >%%cmttempfile%%\n",
4195           action.c_str (),
4196           package.c_str (),
4197           version.c_str (),
4198           no_device.c_str (),
4199           option.c_str ());
4200  fprintf (f, "if exist %%cmttempfile%% call %%cmttempfile%%\n");
4201  fprintf (f, "if exist %%cmttempfile%% del %%cmttempfile%%\n");
4202  fprintf (f, "set cmttempfile=\n");
4203}
4204
4205//----------------------------------------------------------
4206void Cmt::install_cleanup_scripts ()
4207{
4208#ifdef WIN32
4209  static const int modes = 1;
4210  static const cmt_string suffix[1]   = {"bat"};
4211  static const PrintMode  mode[1]     = {Bat};
4212#else
4213  static const int modes = 2;
4214  static const cmt_string suffix[2]   = {"csh", "sh"};
4215  static const PrintMode  mode[2]     = {Csh, Sh};
4216#endif
4217
4218  cerr << "Creating cleanup scripts." << endl;
4219
4220  cmt_string temp;
4221  int i;
4222
4223  cmt_string version = Me.m_current_version;
4224  if (version == "v*") version = "";
4225
4226  for (i = 0; i < modes; i++)
4227    {
4228      cmt_string file_name = "cleanup";
4229      file_name += ".";
4230      file_name += suffix[i];
4231      file_name += ".";
4232      file_name += "new";
4233
4234      FILE* f = fopen (file_name.c_str (), "wb");
4235      if (f != NULL)
4236        {
4237          if (mode[i] == Csh)
4238            {
4239              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4240              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4241              fprintf (f, "endif\n");
4242              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4243              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4244              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4245              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4246                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4247                       "source ${tempfile}\n",
4248                       suffix[i].c_str (),
4249                       Me.m_current_package.c_str (),
4250                       version.c_str (),
4251                       Me.m_current_path.c_str ());
4252              fprintf (f, "/bin/rm -f ${tempfile}\n");
4253            }
4254          else if (mode[i] == Sh)
4255            {
4256              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4257              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4258              fprintf (f, "fi\n");
4259              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4260              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4261              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4262              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s "
4263                       "-pack=%s -version=%s -path=%s $* >${tempfile}; "
4264                       ". ${tempfile}\n",
4265                       suffix[i].c_str (),
4266                       Me.m_current_package.c_str (),
4267                       version.c_str (),
4268                       Me.m_current_path.c_str ());
4269              fprintf (f, "/bin/rm -f ${tempfile}\n");
4270            }
4271          else if (mode[i] == Bat)
4272            {
4273              dos_script_prefix (f, Me.m_cmt_root, 
4274                                 Me.m_current_package, version, Me.m_current_path,
4275                                 "cleanup");
4276            }
4277
4278          fprintf (f, "\n");
4279
4280          fclose (f);
4281
4282          cmt_string old_file_name = "cleanup";
4283          old_file_name += ".";
4284          old_file_name += suffix[i];
4285
4286          CmtSystem::compare_and_update_files (file_name, old_file_name);
4287        }
4288    }
4289}
4290
4291//----------------------------------------------------------
4292void Cmt::install_setup_scripts ()
4293{
4294#ifdef WIN32
4295  static const int modes = 1;
4296  static const cmt_string suffix[1]   = {"bat"};
4297  static const PrintMode  mode[1]     = {Bat};
4298#else
4299  static const int modes = 2;
4300  static const cmt_string suffix[2]   = {"csh", "sh"};
4301  static const PrintMode  mode[2]     = {Csh, Sh};
4302#endif
4303
4304  cerr << "Creating setup scripts." << endl;
4305
4306  Use& current_use = Use::current ();
4307 
4308  cmt_string no_cleanup_opt;
4309
4310  if (current_use.get_strategy ("SetupCleanup"))
4311    {
4312      no_cleanup_opt = " -no_cleanup";
4313    }
4314
4315  cmt_string temp;
4316  int i;
4317
4318  cmt_string version = Me.m_current_version;
4319  if (version == "v*") version = "";
4320
4321  for (i = 0; i < modes; i++)
4322    {
4323      cmt_string file_name = "setup";
4324      file_name += ".";
4325      file_name += suffix[i];
4326      file_name += ".";
4327      file_name += "new";
4328
4329      FILE* f = fopen (file_name.c_str (), "wb");
4330      if (f != NULL)
4331        {
4332          if (mode[i] == Csh)
4333            {
4334              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4335                       Me.m_current_package.c_str (),
4336                       version.c_str (),
4337                       Me.m_current_path.c_str ());
4338              fprintf (f, "\n");
4339
4340              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4341              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4342              fprintf (f, "endif\n");
4343              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4344              fprintf (f, "\n");
4345              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4346              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4347              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4348                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4349                       "source ${tempfile}\n",
4350                       suffix[i].c_str (),
4351                       Me.m_current_package.c_str (),
4352                       version.c_str (),
4353                       Me.m_current_path.c_str (),
4354                       no_cleanup_opt.c_str ());
4355              fprintf (f, "/bin/rm -f ${tempfile}\n");
4356            }
4357          else if (mode[i] == Sh)
4358            {
4359              fprintf (f, "# echo \"Setting %s %s in %s\"\n",
4360                       Me.m_current_package.c_str (),
4361                       version.c_str (),
4362                       Me.m_current_path.c_str ());
4363              fprintf (f, "\n");
4364
4365              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4366              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4367              fprintf (f, "fi\n");
4368              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4369              fprintf (f, "\n");
4370              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4371              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4372              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s "
4373                       "-pack=%s -version=%s -path=%s %s $* >${tempfile}; "
4374                       ". ${tempfile}\n",
4375                       suffix[i].c_str (),
4376                       Me.m_current_package.c_str (),
4377                       version.c_str (),
4378                       Me.m_current_path.c_str (),
4379                       no_cleanup_opt.c_str ());
4380              fprintf (f, "/bin/rm -f ${tempfile}\n");
4381            }
4382          else if (mode[i] == Bat)
4383            {
4384              fprintf (f, "rem Setting %s %s in %%~d0%%~p0\n",
4385                       Me.m_current_package.c_str (),
4386                       version.c_str ());
4387              dos_script_prefix (f, Me.m_cmt_root, 
4388                                 Me.m_current_package, version, Me.m_current_path,
4389                                 "setup", no_cleanup_opt);
4390            }
4391
4392          fprintf (f, "\n");
4393
4394          fclose (f);
4395
4396          cmt_string old_file_name = "setup";
4397          old_file_name += ".";
4398          old_file_name += suffix[i];
4399
4400          CmtSystem::compare_and_update_files (file_name, old_file_name);
4401        }
4402    }
4403}
4404
4405//----------------------------------------------------------
4406void Cmt::install_test_cleanup_scripts ()
4407{
4408#ifdef WIN32
4409  static const int modes = 1;
4410  static const cmt_string suffix[1]   = {"bat"};
4411  static const PrintMode  mode[1]     = {Bat};
4412#else
4413  static const int modes = 2;
4414  static const cmt_string suffix[2]   = {"csh", "sh"};
4415  static const PrintMode  mode[2]     = {Csh, Sh};
4416#endif
4417
4418  cerr << "Creating cleanup scripts." << endl;
4419
4420  cmt_string temp;
4421  int i;
4422
4423  cmt_string version = Me.m_current_version;
4424  if (version == "v*") version = "";
4425
4426  for (i = 0; i < modes; i++)
4427    {
4428      cmt_string file_name = "cleanup";
4429      file_name += ".";
4430      file_name += suffix[i];
4431      file_name += ".";
4432      file_name += "new";
4433
4434      FILE* f = fopen (file_name.c_str (), "wb");
4435      if (f != NULL)
4436        {
4437          if (mode[i] == Csh)
4438            {
4439              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4440              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4441              fprintf (f, "endif\n");
4442              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4443              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4444              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4445              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4446                       "source ${tempfile}\n",
4447                       suffix[i].c_str (),
4448                       Me.m_current_path.c_str ());
4449              fprintf (f, "/bin/rm -f ${tempfile}\n");
4450            }
4451          else if (mode[i] == Sh)
4452            {
4453              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4454              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4455              fprintf (f, "fi\n");
4456              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4457              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4458              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4459              fprintf (f, "${CMTROOT}/mgr/cmt cleanup -%s -pack=cmt_standalone -path=%s $* >${tempfile}; "
4460                       ". ${tempfile}\n",
4461                       suffix[i].c_str (),
4462                       Me.m_current_path.c_str ());
4463              fprintf (f, "/bin/rm -f ${tempfile}\n");
4464            }
4465          else
4466            {
4467              dos_script_prefix (f, Me.m_cmt_root, 
4468                                 "cmt_standalone", "", Me.m_current_path, 
4469                                 "cleanup");
4470            }
4471
4472          fprintf (f, "\n");
4473
4474          fclose (f);
4475
4476          cmt_string old_file_name = "cleanup";
4477          old_file_name += ".";
4478          old_file_name += suffix[i];
4479
4480          CmtSystem::compare_and_update_files (file_name, old_file_name);
4481        }
4482    }
4483}
4484
4485//----------------------------------------------------------
4486void Cmt::install_native_version_file ()
4487{   
4488  Use& current_use        = Use::current ();
4489  cmt_string package_name = current_use.get_package_name();
4490  cmt_string macro_name   = package_name + "_native_version";
4491  Symbol* macro           = Symbol::find (macro_name);
4492  if (macro != 0)
4493    {
4494      cmt_string value = macro->resolve_macro_value ();
4495      if (value != "")
4496        {
4497          cerr << "Creating native_version file." << endl;   
4498
4499          FILE* f = fopen ("new.native_version.cmt", "wb");
4500
4501          if (f != NULL)
4502            {
4503              fprintf (f, "%s\n", value.c_str ());
4504            }     
4505
4506          fclose (f);
4507
4508          CmtSystem::compare_and_update_files ("new.native_version.cmt", "native_version.cmt");
4509        } 
4510    }   
4511}
4512//----------------------------------------------------------
4513void Cmt::install_test_setup_scripts ()
4514{
4515#ifdef WIN32
4516  static const int modes = 1;
4517  static const cmt_string suffix[1]   = {"bat"};
4518  static const PrintMode  mode[1]     = {Bat};
4519#else
4520  static const int modes = 2;
4521  static const cmt_string suffix[2]   = {"csh", "sh"};
4522  static const PrintMode  mode[2]     = {Csh, Sh};
4523#endif
4524
4525  cerr << "Creating setup scripts." << endl;
4526
4527  Use& current_use = Use::current ();
4528
4529  cmt_string no_cleanup_opt;
4530
4531  if (current_use.get_strategy ("SetupCleanup"))
4532    {
4533      no_cleanup_opt = " -no_cleanup";
4534    }
4535
4536  cmt_string temp;
4537  int i;
4538
4539  for (i = 0; i < modes; i++)
4540    {
4541      cmt_string file_name = "setup";
4542      file_name += ".";
4543      file_name += suffix[i];
4544      file_name += ".";
4545      file_name += "new";
4546
4547      FILE* f = fopen (file_name.c_str (), "wb");
4548      if (f != NULL)
4549        {
4550          if (mode[i] == Csh)
4551            {
4552              fprintf (f, "# echo \"Setting standalone package\"\n");
4553              fprintf (f, "\n");
4554
4555              fprintf (f, "if ( $?CMTROOT == 0 ) then\n");
4556              fprintf (f, "  setenv CMTROOT %s\n", Me.m_cmt_root.c_str ());
4557              fprintf (f, "endif\n");
4558              fprintf (f, "source ${CMTROOT}/mgr/setup.csh\n");
4559              fprintf (f, "set tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4560              fprintf (f, "if $status != 0 then\n  set tempfile=/tmp/cmt.$$\nendif\n");
4561              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4562                       "source ${tempfile}\n",
4563                       suffix[i].c_str (),
4564                       Me.m_current_path.c_str (),
4565                       no_cleanup_opt.c_str ());
4566              fprintf (f, "/bin/rm -f ${tempfile}\n");
4567            }
4568          else if (mode[i] == Sh)
4569            {
4570              fprintf (f, "# echo \"Setting standalone package\"\n");
4571              fprintf (f, "\n");
4572
4573              fprintf (f, "if test \"${CMTROOT}\" = \"\"; then\n");
4574              fprintf (f, "  CMTROOT=%s; export CMTROOT\n", Me.m_cmt_root.c_str ());
4575              fprintf (f, "fi\n");
4576              fprintf (f, ". ${CMTROOT}/mgr/setup.sh\n");
4577              fprintf (f, "\n");
4578              fprintf (f, "tempfile=`${CMTROOT}/mgr/cmt -quiet build temporary_name`\n");
4579              fprintf (f, "if test ! $? = 0 ; then tempfile=/tmp/cmt.$$; fi\n");
4580              fprintf (f, "${CMTROOT}/mgr/cmt setup -%s -pack=cmt_standalone -path=%s %s $* >${tempfile}; "
4581                       ". ${tempfile}\n",
4582                       suffix[i].c_str (),
4583                       Me.m_current_path.c_str (),
4584                       no_cleanup_opt.c_str ());
4585              fprintf (f, "/bin/rm -f ${tempfile}\n");
4586            }
4587          else
4588            {
4589              fprintf (f, "rem Setting standalone package\n");
4590              dos_script_prefix (f, Me.m_cmt_root, 
4591                                 "cmt_standalone", "", Me.m_current_path, 
4592                                 "setup", no_cleanup_opt);
4593            }
4594
4595          fprintf (f, "\n");
4596
4597          fclose (f);
4598
4599          cmt_string old_file_name = "setup";
4600          old_file_name += ".";
4601          old_file_name += suffix[i];
4602
4603          CmtSystem::compare_and_update_files (file_name, old_file_name);
4604        }
4605    }
4606}
4607
4608/**
4609 *    load is only called from the Windows GUI which pretends to access directly
4610 *   the internal data model.
4611 *    This is considered to be rather unsafe, and should be replaced by query functions.
4612 */
4613bool Cmt::load (const cmt_string& path,
4614                const cmt_string& package,
4615                const cmt_string& version,
4616                const cmt_string& tag_name)
4617{
4618  clear ();
4619  configure ();
4620
4621  Me.m_action  = action_load;
4622  Me.m_recursive = true;
4623
4624  if (((package != "") && (version != "")) || (Me.m_current_package == ""))
4625    {
4626      //
4627      //  Here we want to connect to a new package, or to the current package
4628      //  but with another tag.
4629      //
4630      //   the 'package' argument may include a directory offset. Thus 'path'
4631      //  is only expected to hold the base directory.
4632      //
4633      cmt_string offset;
4634      cmt_string package_name;
4635     
4636      CmtSystem::dirname (package, offset);
4637      CmtSystem::basename (package, package_name);
4638     
4639      if (offset != "")
4640        {
4641          Me.m_current_path = path;
4642          Me.m_current_path += CmtSystem::file_separator ();
4643          Me.m_current_path += offset;
4644        }
4645      else
4646        {
4647          Me.m_current_path = path;
4648        }
4649     
4650      Me.m_current_package = package_name;
4651      Me.m_current_version = version;
4652    }
4653
4654  if (tag_name != "")
4655    {
4656      Tag* tag;
4657
4658      Tag::unmark_all ();
4659      configure_version_tag ();
4660      configure_site_tag (0);
4661      configure_uname_tag ();
4662      configure_hosttype_tag ();
4663
4664      Me.m_current_tag = tag_name;
4665
4666      //if (!Me.m_quiet) cerr << "load1> current_tag=" << Me.m_current_tag << endl;
4667
4668      tag = Tag::add (tag_name, PriorityTag, "load", 0);
4669      tag->mark ();
4670    }
4671
4672  /*
4673    Set to developer mode if positioned into the package
4674    (which is detected since we were able to retreive the
4675    Version, Package and Path)
4676  */
4677
4678  if ((Me.m_current_path == "") ||
4679      (Me.m_current_package == "") ||
4680      (Me.m_current_version == ""))
4681    {
4682      Me.m_current_access = UserMode;
4683    }
4684  else
4685    {
4686      Me.m_current_access = DeveloperMode;
4687    }
4688
4689  use_cmt ();
4690
4691  cmt_string dir;
4692
4693  /*
4694    Try to access the package.
4695  */
4696
4697  if (Me.m_current_path != "")
4698    {
4699      dir = Me.m_current_path;
4700    }
4701  else
4702    {
4703      dir = Me.m_default_path;
4704    }
4705
4706  if (!CmtSystem::cd (Me.m_current_path))
4707    {
4708      if (!Me.m_quiet)
4709        {
4710          cerr << "#CMT> Cannot reach the directory " <<
4711            Me.m_current_path << endl;
4712        }
4713      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the path directory");
4714      CmtSystem::cd (Me.m_current_dir);
4715
4716      return (false);
4717    }
4718
4719  dir += CmtSystem::file_separator ();
4720  dir += Me.m_current_package;
4721
4722  if (!CmtSystem::cd (Me.m_current_package))
4723    {
4724      if (!Me.m_quiet)
4725        {
4726          cerr << "#CMT::load> Cannot reach the package " <<
4727            Me.m_current_package << endl;
4728        }
4729      CmtError::set (CmtError::package_not_found, "Load> Cannot reach the package directory");
4730      CmtSystem::cd (Me.m_current_dir);
4731
4732      return (false);
4733    }
4734
4735  dir += CmtSystem::file_separator ();
4736  dir += Me.m_current_version;
4737
4738  Me.m_current_style = none_style;
4739
4740  if (!CmtSystem::cd (Me.m_current_version))
4741    {
4742      if (!CmtSystem::test_directory ("cmt"))
4743        {
4744          if (!Me.m_quiet)
4745            {
4746              cerr << "#CMT> Cannot reach the version " <<
4747                Me.m_current_version << endl;
4748            }
4749          CmtError::set (CmtError::package_not_found, "Load> Cannot reach the version directory");
4750          CmtSystem::cd (Me.m_current_dir);
4751
4752          return (false);
4753        }
4754      else
4755        {
4756          Me.m_current_style = no_version_style;
4757        }
4758    }
4759
4760  if (CmtSystem::cd ("cmt"))
4761    {
4762      dir += CmtSystem::file_separator ();
4763      dir += "cmt";
4764      if (Me.m_current_style == none_style) Me.m_current_style = cmt_style;
4765    }
4766  else
4767    {
4768      /*
4769        if (!Me.m_quiet)
4770        {
4771        cerr << "Cannot reach the cmt branch" << endl;
4772        }
4773      */
4774
4775      if (CmtSystem::cd ("mgr"))
4776        {
4777          dir += CmtSystem::file_separator ();
4778          dir += "mgr";
4779          if (Me.m_current_style == none_style) Me.m_current_style = mgr_style;
4780        }
4781      else
4782        {
4783          if (!Me.m_quiet)
4784            {
4785              cerr << "#CMT> Cannot reach the mgr branch" << endl;
4786            }
4787
4788          CmtError::set (CmtError::package_not_found,
4789                         "Load> Cannot reach the mgr/cmt directory");
4790          CmtSystem::cd (Me.m_current_dir);
4791
4792          return (false);
4793        }
4794    }
4795
4796  /*
4797    Check Tag is always set up
4798  */
4799
4800  if (Me.m_current_tag == "")
4801    {
4802      char* env;
4803
4804      env = getenv (Me.m_current_config.c_str ());
4805      if (env != 0)
4806        {
4807          Tag* tag;
4808
4809          tag = Tag::add (env, PriorityConfig, "load", 0);
4810          tag->mark ();
4811          Me.m_current_tag = env;
4812
4813          //if (!Me.m_quiet) cerr << "load2> current_tag=" << Me.m_current_tag << endl;
4814
4815        }
4816      else
4817        {
4818          Me.m_current_tag = Me.m_cmt_config;
4819
4820          //if (!Me.m_quiet) cerr << "load3> current_tag=" << Me.m_current_tag << endl;
4821
4822        }
4823    }
4824
4825  if (Me.m_debug)
4826    {
4827      cout << "pwd = " << CmtSystem::pwd () << endl;
4828    }
4829
4830  configure_current_dir ();
4831  build_prefix (Me.m_current_package, Me.m_current_prefix);
4832  build_config (Me.m_current_prefix, Me.m_current_config);
4833
4834  Use* use = &(Use::current());
4835  use->path    = Me.m_current_path;
4836  use->set_package_name (Me.m_current_package);
4837  use->version = Me.m_current_version;
4838  use->prefix  = Me.m_current_prefix;
4839  use->done    = false;
4840  use->style   = Me.m_current_style;
4841
4842  /*
4843    Work on the requirements file.
4844  */
4845
4846  dir += CmtSystem::file_separator ();
4847  dir += "requirements";
4848  SyntaxParser::parse_requirements (dir, use);
4849
4850  if (CmtError::has_pending_error ()) return (false);
4851
4852  /**
4853   * See reach_current_package for an explanation of this call
4854   */
4855  Pattern::apply_all_globals ();
4856
4857  /*
4858    Select all possible tags
4859  */
4860
4861  Tag::restore_tree ();
4862
4863  return (true);
4864}
4865
4866//----------------------------------------------------------
4867bool Cmt::need_prototypes ()
4868{
4869  Use& current_use = Use::current ();
4870
4871  if (current_use.get_strategy ("BuildPrototypes")) return (true);
4872  else return (false);
4873}
4874
4875//----------------------------------------------------------
4876void Cmt::parse_arguments (ArgParser& ap)
4877{
4878  /*
4879    Decoding arguments.
4880
4881    While decoding all arguments, no requirements analysis should
4882    occur. Every new option, or parameter should be saved and
4883    used later at actual analysis time.
4884  */
4885
4886  Me.m_action = action_none;
4887
4888  restore_all_tags (0);
4889
4890#ifdef WIN32
4891  Me.m_build_nmake = true;
4892#endif
4893
4894  ap.parse ();
4895}
4896
4897//----------------------------------------------------------
4898int Cmt::parser (const cmt_string& command_line)
4899{
4900  CmtSystem::cmt_string_vector v;
4901
4902  CmtSystem::split (command_line, " \t", v);
4903
4904  int argc = v.size ();
4905
4906  char** argv = (char**) malloc ((argc + 1) * sizeof (char*));
4907
4908  int i;
4909  for (i = 0; i < argc; i++)
4910    {
4911      argv[i] = (char*) v[i].c_str ();
4912    }
4913  argv[argc] = 0;
4914
4915  int status = parser (argc, argv);
4916
4917  free (argv);
4918
4919  return (status);
4920}
4921
4922//----------------------------------------------------------
4923int Cmt::parser (int argc, char* argv[])
4924{
4925  ArgParser ap (Me);
4926 
4927  ap.argc = argc;
4928  ap.argv = argv;
4929
4930  if (argc <= 1)
4931    {
4932      do_help (ap);
4933      exit (0);
4934    }
4935
4936  clear ();
4937
4938  configure ();
4939
4940  CmtError::clear ();
4941
4942  /*
4943    Set private if positioned inside the package
4944    (which is detected since we were able to retreive the
4945    Version, Package and Path)
4946  */
4947
4948  if ((Me.m_current_path.size () == 0) ||
4949      (Me.m_current_package.size () == 0) ||
4950      (Me.m_current_version.size () == 0))
4951    {
4952      Me.m_current_access = UserMode;
4953    }
4954  else
4955    {
4956      Me.m_current_access = DeveloperMode;
4957    }
4958 
4959  parse_arguments (ap);
4960 
4961  if (Me.m_debug)
4962    {
4963      cout << "After parse_argument> pack=" << Me.m_current_package
4964           << " Me.m_current_tag=" << Me.m_current_tag
4965           << " cwd=" << CmtSystem::pwd () 
4966           << " mode=" << Me.m_current_access
4967           << endl;
4968    }
4969
4970  if (Me.m_configure_error != "")
4971    {
4972      if (!Me.m_quiet) cerr << "#CMT> Error: " << Me.m_configure_error << endl;
4973      return (CmtError::execution_error);
4974    }
4975
4976  if (CmtError::has_pending_error ())
4977    {
4978      int code = CmtError::get_last_error_code ();
4979      if (!Me.m_quiet) CmtError::print ();
4980      clear ();
4981
4982      return (code);
4983    }
4984
4985  /*
4986    Now actual requirements analysis can take place.
4987
4988    Extra lines or files are analysed first.
4989  */
4990
4991  if (strlen (ap.extra_file.c_str ()) > 0) SyntaxParser::parse_requirements (ap.extra_file, (Use*) 0);
4992  if (strlen (ap.extra_line.c_str ()) > 0) SyntaxParser::parse_requirements_line (ap.extra_line, (Use*) 0);
4993
4994  //
4995  //  For some of the actions, the CMT package must be automatically
4996  //  included
4997  //
4998
4999  if (Me.m_debug) cout << "parser1> current_tag=" << Me.m_current_tag << endl;
5000
5001  if (ap.help_action == action_help)
5002    {
5003      do_help (ap);
5004      return (0);
5005    }
5006
5007  switch (Me.m_action)
5008    {
5009      // case action_none :
5010    case action_awk :
5011    case action_broadcast :
5012    case action_build_constituent_makefile :
5013    case action_build_constituents_makefile :
5014    case action_build_dependencies :
5015    case action_build_library_links :
5016    case action_build_make_setup :
5017    case action_build_msdev :
5018    case action_build_CMT_pacman :
5019    case action_build_vsnet :     
5020    case action_build_os9_makefile :
5021      // case action_build_prototype :
5022    case action_build_readme :
5023    case action_build_tag_makefile :
5024      // case action_build_temporary_name :
5025    case action_build_triggers :
5026    case action_build_windefs :
5027    case action_check_configuration :
5028      // case action_check_files :
5029      // case action_check_version :
5030    case action_checkout :
5031    case action_cleanup :
5032    case action_config :
5033    case action_create :
5034      // case action_create_project :
5035    case action_cvsbranches :
5036    case action_cvssubpackages :
5037    case action_cvssubprojects :
5038    case action_cvstags :
5039    case action_do :
5040    case action_expand_model :
5041    case action_filter :
5042      // case action_help :
5043    case action_load :
5044    case action_lock :
5045    case action_relocate:
5046    case action_remove :
5047    case action_remove_library_links :
5048    case action_run :
5049    case action_run_sequence :
5050    case action_set_version :
5051    case action_set_versions :
5052    case action_setup :
5053    case action_show_action :
5054    case action_show_action_names :
5055    case action_show_action_value :
5056    case action_show_actions :
5057    case action_show_all_tags :
5058    case action_show_applied_patterns :
5059      // case action_show_author :
5060      // case action_show_branches :
5061      // case action_show_clients :
5062    case action_show_cmtpath_patterns :
5063    case action_show_constituent :
5064    case action_show_constituent_names :
5065    case action_show_constituents :
5066    case action_show_cycles :
5067    case action_show_fragment :
5068    case action_show_fragments :
5069    case action_show_groups :
5070    case action_show_include_dirs :
5071    case action_show_language :
5072    case action_show_languages :
5073    case action_show_macro :
5074    case action_show_macro_names :
5075    case action_show_macro_value :
5076    case action_show_macros :
5077      // case action_show_manager :
5078    case action_show_packages :
5079    case action_show_path :
5080    case action_show_pattern :
5081    case action_show_pattern_names :
5082    case action_show_patterns :
5083    case action_show_projects :
5084      // case action_show_pwd :
5085    case action_show_setup :
5086    case action_show_set :
5087    case action_show_set_names :
5088    case action_show_set_value :
5089    case action_show_sets :
5090    case action_show_strategies :
5091    case action_show_tags :
5092    case action_show_use_paths :
5093    case action_show_uses :
5094    case action_show_version :
5095      // case action_show_versions :
5096      // case action_system :
5097    case action_unlock :
5098    case action_version :
5099      use_cmt ();
5100      //
5101      // Now parse the requirements file stored in ${CMTHOME}
5102      //
5103     
5104      use_home_requirements ();
5105
5106      break;
5107    default:
5108      break;
5109    }
5110
5111  if (Me.m_debug) cout << "parser2> current_tag=" << Me.m_current_tag << endl;
5112
5113  //
5114  // Setting up recursive actions
5115  //
5116
5117  switch (Me.m_action)
5118    {
5119      // case action_none :
5120    case action_awk :
5121    case action_broadcast :
5122    case action_build_constituent_makefile :
5123    case action_build_constituents_makefile :
5124    case action_build_dependencies :
5125    case action_build_library_links :
5126    case action_build_make_setup :
5127    case action_build_msdev :
5128    case action_build_CMT_pacman :
5129    case action_build_vsnet :     
5130    case action_build_os9_makefile :
5131      // case action_build_prototype :
5132    case action_build_readme :
5133    case action_build_tag_makefile :
5134      // case action_build_temporary_name :
5135    case action_build_triggers :
5136    case action_build_windefs :
5137    case action_check_configuration :
5138      // case action_check_files :
5139      // case action_check_version :
5140      // case action_checkout :
5141    case action_cleanup :
5142    case action_config :
5143      // case action_create :
5144      // case action_create_project :
5145      // case action_cvsbranches :
5146      // case action_cvssubpackages :
5147      // case action_cvssubprojects :
5148      // case action_cvstags :
5149    case action_do :
5150    case action_expand_model :
5151    case action_filter :
5152      // case action_help :
5153    case action_load :
5154      // case action_lock :
5155      // case action_remove :
5156    case action_relocate:
5157    case action_remove_library_links :
5158    case action_run :
5159    case action_run_sequence :
5160      // case action_set_version :
5161    case action_set_versions :
5162    case action_setup :
5163    case action_show_action :
5164    case action_show_action_names :
5165    case action_show_action_value :
5166    case action_show_actions :
5167    case action_show_all_tags :
5168    case action_show_applied_patterns :
5169      // case action_show_author :
5170      // case action_show_branches :
5171      // case action_show_clients :
5172    case action_show_cmtpath_patterns :
5173    case action_show_constituent :
5174    case action_show_constituent_names :
5175    case action_show_constituents :
5176    case action_show_cycles :
5177    case action_show_fragment :
5178    case action_show_fragments :
5179    case action_show_groups :
5180    case action_show_include_dirs :
5181    case action_show_language :
5182    case action_show_languages :
5183    case action_show_macro :
5184    case action_show_macro_names :
5185    case action_show_macro_value :
5186    case action_show_macros :
5187      // case action_show_manager :
5188    case action_show_packages :
5189    case action_show_path :
5190    case action_show_pattern :
5191    case action_show_pattern_names :
5192    case action_show_patterns :
5193    case action_show_projects :
5194      // case action_show_pwd :
5195    case action_show_setup :
5196    case action_show_set :
5197    case action_show_set_names :
5198    case action_show_set_value :
5199    case action_show_sets :
5200    case action_show_strategies :
5201    case action_show_tags :
5202    case action_show_use_paths :
5203    case action_show_uses :
5204      // case action_show_version :
5205      // case action_show_versions :
5206      // case action_system :
5207      // case action_unlock :
5208      // case action_version :
5209      Me.m_recursive = true;
5210      break;
5211    default:
5212      Me.m_recursive = false;
5213      break;
5214    }
5215
5216  //
5217  //  Actions for which the context of the package is checked,
5218  //  and the requirements file is analysed.
5219  //
5220
5221  switch (Me.m_action)
5222    {
5223    case action_none :
5224    case action_awk :
5225    case action_broadcast :
5226    case action_build_constituent_makefile :
5227    case action_build_constituents_makefile :
5228    case action_build_dependencies :
5229    case action_build_library_links :
5230    case action_build_make_setup :
5231    case action_build_msdev :
5232    case action_build_CMT_pacman :
5233    case action_build_vsnet :     
5234    case action_build_os9_makefile :
5235      // case action_build_prototype :
5236    case action_build_readme :
5237    case action_build_tag_makefile :
5238      // case action_build_temporary_name :
5239    case action_build_triggers :
5240    case action_build_windefs :
5241    case action_check_configuration :
5242      // case action_check_files :
5243      // case action_check_version :
5244      // case action_checkout :
5245    case action_cleanup :
5246    case action_config :
5247      // case action_create :
5248      // case action_create_project :
5249      // case action_cvsbranches :
5250      // case action_cvssubpackages :
5251      // case action_cvssubprojects :
5252      // case action_cvstags :
5253    case action_do :
5254    case action_expand_model :
5255    case action_filter :
5256      // case action_help :
5257    case action_load :
5258    case action_lock :
5259      // case action_remove :
5260    case action_relocate :
5261    case action_remove_library_links :
5262    case action_run :
5263      // case action_run_sequence :
5264      // case action_set_version :
5265    case action_set_versions :
5266    case action_setup :
5267    case action_show_action :
5268    case action_show_action_names :
5269    case action_show_action_value :
5270    case action_show_actions :
5271    case action_show_all_tags :
5272    case action_show_applied_patterns :
5273    case action_show_author :
5274    case action_show_branches :
5275      // case action_show_clients :
5276    case action_show_cmtpath_patterns :
5277    case action_show_constituent :
5278    case action_show_constituent_names :
5279    case action_show_constituents :
5280    case action_show_cycles :
5281    case action_show_fragment :
5282    case action_show_fragments :
5283    case action_show_groups :
5284    case action_show_include_dirs :
5285    case action_show_language :
5286    case action_show_languages :
5287    case action_show_macro :
5288    case action_show_macro_names :
5289    case action_show_macro_value :
5290    case action_show_macros :
5291    case action_show_manager :
5292    case action_show_packages :
5293    case action_show_path :
5294    case action_show_pattern :
5295    case action_show_pattern_names :
5296    case action_show_patterns :
5297    case action_show_projects :
5298    case action_show_project_author :
5299    case action_show_pwd :
5300    case action_show_setup :
5301    case action_show_set :
5302    case action_show_set_names :
5303    case action_show_set_value :
5304    case action_show_sets :
5305    case action_show_strategies :
5306    case action_show_tags :
5307    case action_show_use_paths :
5308    case action_show_uses :
5309    case action_show_version :
5310      // case action_show_versions :
5311      // case action_system :
5312    case action_unlock :
5313      // case action_version :
5314      {
5315        bool w = Me.m_warnings;
5316        Me.m_warnings = false;
5317        reach_current_package ();
5318        use_user_context_requirements ();
5319        Me.m_warnings = w;
5320      }
5321      break;
5322    default:
5323      break;
5324    }
5325
5326  if (Me.m_debug) cout << "parser3> current_tag=" << Me.m_current_tag << endl;
5327
5328  //
5329  // Perform some actions even if there is an error
5330  //
5331
5332  if (CmtError::has_pending_error ())
5333    {
5334      int code = CmtError::get_last_error_code ();
5335      if (!Me.m_quiet) CmtError::print ();
5336
5337      switch (Me.m_action)
5338        {
5339          // case action_none :
5340          // case action_awk :
5341          // case action_broadcast :
5342        case action_build_constituent_makefile :
5343        case action_build_constituents_makefile :
5344        case action_build_dependencies :
5345        case action_build_library_links :
5346        case action_build_make_setup :
5347        case action_build_msdev :
5348        case action_build_CMT_pacman :
5349        case action_build_vsnet :     
5350        case action_build_os9_makefile :
5351        case action_build_prototype :
5352        case action_build_readme :
5353        case action_build_tag_makefile :
5354          // case action_build_temporary_name :
5355        case action_build_triggers :
5356        case action_build_windefs :
5357        case action_check_configuration :
5358          // case action_check_files :
5359          // case action_check_version :
5360          // case action_checkout :
5361        case action_cleanup :
5362          // case action_config :
5363          // case action_create :
5364          // case action_create_project :
5365          // case action_cvsbranches :
5366          // case action_cvssubpackages :
5367          // case action_cvssubprojects :
5368          // case action_cvstags :
5369          // case action_do :
5370          // case action_expand_model :
5371          // case action_filter :
5372          // case action_help :
5373        case action_load :
5374        case action_lock :
5375        case action_relocate :
5376        case action_remove :
5377        case action_remove_library_links :
5378          // case action_run :
5379        case action_run_sequence :
5380          // case action_set_version :
5381          // case action_set_versions :
5382        case action_setup :
5383          // case action_show_action :
5384          // case action_show_action_names :
5385          // case action_show_action_value :
5386          // case action_show_actions :
5387          // case action_show_all_tags :
5388          // case action_show_applied_patterns :
5389          // case action_show_author :
5390          // case action_show_branches :
5391          // case action_show_clients :
5392          // case action_show_cmtpath_patterns :
5393          // case action_show_constituent :
5394          // case action_show_constituent_names :
5395          // case action_show_constituents :
5396          // case action_show_cycles :
5397          // case action_show_fragment :
5398          // case action_show_fragments :
5399          // case action_show_groups :
5400          // case action_show_include_dirs :
5401          // case action_show_language :
5402          // case action_show_languages :
5403          // case action_show_macro :
5404          // case action_show_macro_names :
5405          // case action_show_macro_value :
5406          // case action_show_macros :
5407          // case action_show_manager :
5408          // case action_show_packages :
5409          // case action_show_path :
5410          // case action_show_pattern :
5411          // case action_show_pattern_names :
5412          // case action_show_patterns :
5413          // case action_show_projects :
5414          // case action_show_pwd :
5415          // case action_show_setup :
5416          // case action_show_set :
5417          // case action_show_set_names :
5418          // case action_show_set_value :
5419          // case action_show_sets :
5420          // case action_show_strategies :
5421          // case action_show_tags :
5422          // case action_show_use_paths :
5423          // case action_show_uses :
5424          // case action_show_version :
5425          // case action_show_versions :
5426          // case action_system :
5427        case action_unlock :
5428          // case action_version :
5429          clear ();
5430          return (code);
5431        default:
5432          CmtError::clear ();
5433          break;
5434        }
5435    }
5436
5437  //
5438  // Perform actions
5439  //
5440
5441  if (!Me.m_simulation)
5442    {
5443      switch (Me.m_action)
5444        {
5445        case action_none :
5446          //CmtError::set (CmtError::syntax_error, "ParseArguments> ");
5447          break;
5448        case action_awk :
5449          do_awk (ap);
5450          break;
5451        case action_broadcast :
5452          do_broadcast (ap);
5453          break;
5454        case action_build_constituent_makefile :
5455          do_build_constituent_makefile (ap);
5456          break;
5457        case action_build_constituents_makefile :
5458          do_build_constituents_makefile (ap);
5459          break;
5460        case action_build_dependencies :
5461          do_build_dependencies (ap, argc, argv);
5462          break;
5463        case action_build_library_links :
5464          do_build_library_links (ap);
5465          break;
5466        case action_build_make_setup :
5467          do_build_make_setup (ap);
5468          break;
5469        case action_build_msdev :
5470          do_build_msdev (ap);
5471          break;
5472        case action_build_CMT_pacman :
5473          do_build_CMT_pacman (ap);
5474          break;
5475        case action_build_vsnet :     
5476          do_build_vsnet (ap);
5477          break;
5478        case action_build_os9_makefile :
5479          do_build_os9_makefile (ap);
5480          break;
5481        case action_build_prototype :
5482          do_build_prototype (ap);
5483          break;
5484        case action_build_readme :
5485          do_build_readme (ap);
5486          break;
5487        case action_build_tag_makefile :
5488          do_build_tag_makefile (ap);
5489          break;
5490        case action_build_temporary_name :
5491          do_build_temporary_name (ap);
5492          break;
5493        case action_build_triggers :
5494          do_build_triggers (ap);
5495          break;
5496        case action_build_windefs :
5497          do_build_windefs (ap);
5498          break;
5499        case action_check_configuration :
5500          do_check_configuration (ap);
5501          break;
5502        case action_check_files :
5503          do_check_files (ap);
5504          break;
5505        case action_check_version :
5506          do_check_version (ap);
5507          break;
5508        case action_checkout :
5509          do_checkout (ap);
5510          break;
5511        case action_cleanup :
5512          do_cleanup (ap);
5513          break;
5514        case action_config :
5515          do_config (ap);
5516          break;
5517        case action_create :
5518          do_create (ap);
5519          break;
5520        case action_create_project :
5521          do_create_project (ap);
5522          break;
5523        case action_cvsbranches :
5524          do_cvsbranches (ap);
5525          break;
5526        case action_cvssubpackages :
5527          do_cvssubpackages (ap);
5528          break;
5529        case action_cvssubprojects :
5530          do_cvssubprojects (ap);
5531          break;
5532        case action_cvstags :
5533          do_cvstags (ap);
5534          break;
5535        case action_do :
5536          do_do (ap);
5537          break;
5538        case action_expand_model :
5539          do_expand_model (ap);
5540          break;
5541        case action_filter :
5542          do_filter (ap);
5543          break;
5544        case action_help :
5545          do_help (ap);
5546          break;
5547        case action_load :
5548          cerr << "#CMT> action not implemented" << endl;
5549          break;
5550        case action_lock :
5551          do_lock (ap);
5552          break;
5553        case action_relocate :
5554          do_relocate (ap);
5555          break;
5556        case action_remove :
5557          do_remove (ap);
5558          break;
5559        case action_remove_library_links :
5560          do_remove_library_links (ap);
5561          break;
5562        case action_run :
5563          do_run (ap);
5564          break;
5565        case action_run_sequence :
5566          do_run_sequence (ap);
5567          break;
5568        case action_set_version :
5569          do_set_version (ap);
5570          break;
5571        case action_set_versions :
5572          do_set_versions (ap);
5573          break;
5574        case action_setup :
5575          do_setup (ap);
5576          break;
5577        case action_show_action :
5578          do_show_action (ap);
5579          break;
5580        case action_show_action_names :
5581          do_show_action_names (ap);
5582          break;
5583        case action_show_action_value :
5584          do_show_action_value (ap);
5585          break;
5586        case action_show_actions :
5587          do_show_actions (ap);
5588          break;
5589        case action_show_all_tags :
5590          do_show_all_tags (ap);
5591          break;
5592        case action_show_applied_patterns :
5593          do_show_applied_patterns (ap);
5594          break;
5595        case action_show_author :
5596          do_show_author (ap);
5597          break;
5598        case action_show_branches :
5599          do_show_branches (ap);
5600          break;
5601        case action_show_clients :
5602          do_show_clients (ap);
5603          break;
5604        case action_show_cmtpath_patterns :
5605          do_show_cmtpath_patterns (ap);
5606          break;
5607        case action_show_constituent :
5608          do_show_constituent (ap);
5609          break;
5610        case action_show_constituent_names :
5611          do_show_constituent_names (ap);
5612          break;
5613        case action_show_constituents :
5614          do_show_constituents (ap);
5615          break;
5616        case action_show_cycles :
5617          do_show_cycles (ap);
5618          break;
5619        case action_show_fragment :
5620          do_show_fragment (ap);
5621          break;
5622        case action_show_fragments :
5623          do_show_fragments (ap);
5624          break;
5625        case action_show_groups :
5626          do_show_groups (ap);
5627          break;
5628        case action_show_include_dirs :
5629          do_show_include_dirs (ap);
5630          break;
5631        case action_show_language :
5632          do_show_language (ap);
5633          break;
5634        case action_show_languages :
5635          do_show_languages (ap);
5636          break;
5637        case action_show_macro :
5638          do_show_macro (ap);
5639          break;
5640        case action_show_macro_names :
5641          do_show_macro_names (ap);
5642          break;
5643        case action_show_macro_value :
5644          do_show_macro_value (ap);
5645          break;
5646        case action_show_macros :
5647          do_show_macros (ap);
5648          break;
5649        case action_show_manager :
5650          do_show_manager (ap);
5651          break;
5652        case action_show_packages :
5653          do_show_packages (ap);
5654          break;
5655        case action_show_path :
5656          do_show_path (ap);
5657          break;
5658        case action_show_pattern :
5659          do_show_pattern (ap);
5660          break;
5661        case action_show_pattern_names :
5662          do_show_pattern_names (ap);
5663          break;
5664        case action_show_patterns :
5665          do_show_patterns (ap);
5666          break;
5667        case action_show_projects :
5668          do_show_projects (ap);
5669          break;
5670        case action_show_project_author :
5671          do_show_project_author (ap);
5672          break;
5673        case action_show_pwd :
5674          do_show_pwd (ap);
5675          break;
5676        case action_show_setup :
5677          do_show_setup (ap);
5678          break;
5679        case action_show_set :
5680          do_show_set (ap);
5681          break;
5682        case action_show_set_names :
5683          do_show_set_names (ap);
5684          break;
5685        case action_show_set_value :
5686          do_show_set_value (ap);
5687          break;
5688        case action_show_sets :
5689          do_show_sets (ap);
5690          break;
5691        case action_show_strategies :
5692          do_show_strategies (ap);
5693          break;
5694        case action_show_tags :
5695          do_show_tags (ap);
5696          break;
5697        case action_show_use_paths :
5698          do_show_use_paths (ap);
5699          break;
5700        case action_show_uses :
5701          do_show_uses (ap);
5702          break;
5703        case action_show_version :
5704          do_show_version (ap);
5705          break;
5706        case action_show_versions :
5707          do_show_versions (ap);
5708          break;
5709        case action_system :
5710          do_show_system (ap);
5711          break;
5712        case action_unlock :
5713          do_unlock (ap);
5714          break;
5715        case action_version :
5716          do_version (ap);
5717          break;
5718        default:
5719          CmtError::set (CmtError::syntax_error, "ParseArguments>");
5720          break;
5721        }
5722    }
5723
5724  if (CmtError::has_pending_error ())
5725    {
5726      int code = CmtError::get_last_error_code ();     
5727      if (code == CmtError::execution_failed)
5728        {
5729          code = CmtError::get_last_execution_error();
5730        }   
5731     
5732      if (!Me.m_quiet) CmtError::print ();
5733      clear ();
5734      return (code);
5735    }
5736  else
5737    {
5738      clear ();
5739      return (0);
5740    }
5741}
5742
5743
5744/**
5745 * Format as one single line a set of 'setenv' statements
5746 * joined with semi-colons to form one shell command.
5747 */
5748void Cmt::print (PrintMode mode)
5749{
5750  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5751  Use& current_use = Use::current ();
5752
5753  cmt_string tag;
5754
5755  set_standard_macros ();
5756
5757  //cerr << "# current_tag=" << Me.m_current_tag << endl;
5758  //cerr << "# current_config=" << Me.m_current_config << endl;
5759
5760  if (Me.m_current_tag == "")
5761    {
5762      if (mode == Bat) tag = "%CMTCONFIG%";
5763      else tag = "${CMTCONFIG}";
5764    }
5765  else
5766    {
5767      tag = Me.m_current_tag;
5768    }
5769
5770  //
5771  //  Now check if all extra tags are still valid. Some of them
5772  //  may be discarded du to some conflict with highest priority
5773  //  tags, or with exclude statements
5774  //
5775
5776  {
5777    CmtSystem::cmt_string_vector words;
5778     
5779    cmt_string tags;
5780
5781    tags = Me.m_extra_tags;
5782     
5783    CmtSystem::split (tags, " \t,", words);
5784
5785    Me.m_extra_tags = ",";
5786     
5787    for (int i = 0; i < words.size (); i++)
5788      {
5789        Tag* tag;
5790        const cmt_string& a = words[i];
5791
5792        tag = Tag::find (a);
5793
5794        if ((tag != 0) && (tag->is_selected ()))
5795          {
5796            Me.m_extra_tags += a;
5797            Me.m_extra_tags += ",";
5798          }
5799      }
5800  }
5801
5802  if (Me.m_debug)
5803    {
5804      cout << "Before all print contexts" << endl;
5805    }
5806
5807  if (Uses.size () > 0)
5808    {
5809      int number;
5810
5811      for (number = 0; number < Uses.size (); number++)
5812        {
5813          Use& use = *(Uses[number]);
5814
5815          if (use.discarded) continue;
5816          if (use.m_hidden) continue;
5817         
5818          print_context (use, mode, tag);
5819        }
5820    }
5821
5822  print_context (Use::current (), mode, tag);
5823
5824  if (Me.m_debug)
5825    {
5826      cout << "After all print contexts" << endl;
5827    }
5828
5829  Symbol::all_print (mode);
5830  // Script::all_print (mode);
5831
5832  if (Me.m_debug)
5833    {
5834      cout << "After all print" << endl;
5835    }
5836
5837  cout << endl;
5838}
5839
5840
5841/**
5842 * Format as one single line a set of 'unsetenv' statements
5843 * joined with semi-colons to form one shell command.
5844 */
5845void Cmt::print_clean (PrintMode mode)
5846{
5847  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
5848
5849  set_standard_macros ();
5850
5851  Script::all_print_clean (mode);
5852  Symbol::all_print_clean (mode);
5853
5854  switch (mode)
5855    {
5856    case Csh :
5857      if (Me.m_current_package != "CMT")
5858        {
5859          cout << "unsetenv " << Me.m_current_prefix << "ROOT" << endl;
5860          cout << "unsetenv " << Me.m_current_prefix << "CONFIG" << endl;
5861        }
5862      break;
5863    case Sh :
5864      if (Me.m_current_package != "CMT")
5865        {
5866          cout << "unset " << Me.m_current_prefix << "ROOT" << endl;
5867          cout << "unset " << Me.m_current_prefix << "CONFIG" << endl;
5868        }
5869      break;
5870    case Bat :
5871      if (Me.m_current_package != "CMT")
5872        {
5873          cout << "set " << Me.m_current_prefix << "ROOT=" << endl;
5874          cout << "set " << Me.m_current_prefix << "CONFIG=" << endl;
5875        }
5876      break;
5877    }
5878
5879  if (Uses.size () > 0)
5880    {
5881      int number;
5882
5883      for (number = 0; number < Uses.size (); number++)
5884        {
5885          Use* use = Uses[number];
5886
5887          if (use->discarded) continue;
5888          if (use->m_hidden) continue;
5889
5890          Package* p = use->get_package ();
5891          if (p->is_cmt ()) continue;
5892
5893
5894          switch (mode)
5895            {
5896            case Csh :
5897              cout << "unsetenv " << use->prefix << "ROOT" << endl;
5898              cout << "unsetenv " << use->prefix << "CONFIG" << endl;
5899              break;
5900            case Sh :
5901              cout << "unset " << use->prefix << "ROOT" << endl;
5902              cout << "unset " << use->prefix << "CONFIG" << endl;
5903              break;
5904            case Bat :
5905              cout << "set " << use->prefix << "ROOT=" << endl;
5906              cout << "set " << use->prefix << "CONFIG" << endl;
5907              break;
5908            }
5909        }
5910    }
5911
5912  switch (mode)
5913    {
5914    case Csh :
5915      cout << "unsetenv CMTEXTRATAGS" << endl;
5916      break;
5917    case Sh :
5918      cout << "unset CMTEXTRATAGS" << endl;
5919      break;
5920    case Bat :
5921      cout << "set CMTEXTRATAGS=" << endl;
5922      break;
5923    }
5924
5925  cout << endl;
5926}
5927
5928//----------------------------------------------------------
5929void Cmt::print_context (Use& use, PrintMode mode, const cmt_string& tag)
5930{
5931  if (use.get_package_name () == "cmt_standalone") return;
5932
5933  cmt_string fs = CmtSystem::file_separator ();
5934
5935  use.real_path.replace_all (CmtSystem::file_separator (), fs);
5936
5937  cmt_string system = CmtSystem::get_cmt_config ();
5938
5939  bool do_config = use.get_strategy ("SetupConfig");
5940  bool do_root   = use.get_strategy ("SetupRoot");
5941   
5942 
5943  switch (mode)
5944    {
5945    case Csh :
5946      if (do_root)
5947        {
5948          cout << "setenv " << use.prefix << "ROOT \"" <<
5949            use.get_full_path () << "\"" << endl;
5950        }
5951
5952      if (use.get_package_name () == "CMT")
5953        {
5954          cout << "setenv CMTCONFIG " << system << endl;
5955        }
5956      else
5957        {
5958          if (do_config)
5959            {
5960              cout << "setenv " << use.prefix << "CONFIG \"" << tag << "\"" << endl;
5961            }
5962        }
5963       
5964      break;
5965    case Sh :
5966      if (do_root)
5967        {
5968          cout << use.prefix << "ROOT=\"" <<
5969            use.get_full_path () << "\"; export " <<
5970            use.prefix << "ROOT" << endl;
5971        }
5972
5973      if (use.get_package_name () == "CMT")
5974        {
5975          cout << "CMTCONFIG=" << system << "; export CMTCONFIG" << endl;
5976        }
5977      else
5978        {
5979          if (do_config)
5980            {
5981              cout << use.prefix << "CONFIG=\"" <<
5982                tag << "\"; export " <<
5983                use.prefix << "CONFIG" << endl;
5984            }
5985        }
5986       
5987      break;
5988    case Bat :
5989      if (do_root)
5990        {
5991          cout << "set " << use.prefix << "ROOT=" <<
5992            use.get_full_path () << endl;
5993        }
5994
5995      if (use.get_package_name () == "CMT")
5996        {
5997          cout << "set CMTCONFIG=" << system << endl;
5998        }
5999      else
6000        {
6001          if (do_config)
6002            {
6003              cout << "set " << use.prefix << "CONFIG=" << tag << endl;
6004            }
6005        }
6006       
6007      break;
6008    }
6009}
6010
6011/**
6012 *  Format a set of make macro definitions (one per line)
6013 * Each macro value is provided enclosed in single quotes
6014 *
6015 *  Take the macro values from the macro statements found
6016 * in recursively read requirements files.
6017 */
6018void Cmt::print_symbol_names (PrintMode mode, const cmt_string& pattern)
6019{
6020  int number;
6021
6022  set_standard_macros ();
6023
6024  cmt_regexp expression (pattern);
6025
6026  bool has_pattern = (pattern != "");
6027
6028  for (number = 0; number < Symbol::symbol_number (); number++)
6029    {
6030      Symbol& symbol = Symbol::symbol (number);
6031
6032      if (has_pattern)
6033        {
6034          if (!expression.match (symbol.name)) continue;
6035        }
6036
6037      if (Me.m_action == action_show_macro_names)
6038        {
6039          // Only keep macros.
6040          if ((symbol.type == Symbol::SymbolSet) ||
6041              (symbol.type == Symbol::SymbolAlias) ||
6042              (symbol.type == Symbol::SymbolPath) ||
6043              (symbol.type == Symbol::SymbolAction)) continue;
6044        }
6045      else if (Me.m_action == action_show_set_names)
6046        {
6047          // Exclude macros.
6048          if ((symbol.type == Symbol::SymbolMacro) ||
6049              (symbol.type == Symbol::SymbolAction)) continue;
6050        }
6051      else if (Me.m_action == action_show_action_names)
6052        {
6053          // Exclude macros.
6054          if (symbol.type != Symbol::SymbolAction) continue;
6055        }
6056
6057      cout << symbol.name << endl;
6058    }
6059}
6060
6061/**
6062 *  Format a set of make macro definitions (one per line)
6063 * Each macro value is provided enclosed in single quotes
6064 *
6065 *  Take the macro values from the macro statements found
6066 * in recursively read requirements files.
6067 */
6068void Cmt::print_macros (PrintMode mode, const cmt_string& pattern)
6069{
6070  int number;
6071
6072  set_standard_macros ();
6073
6074  cmt_regexp expression (pattern);
6075
6076  bool has_pattern = (pattern != "");
6077
6078  for (number = 0; number < Symbol::symbol_number (); number++)
6079    {
6080      Symbol& symbol = Symbol::symbol (number);
6081
6082      if (has_pattern)
6083        {
6084          if (!expression.match (symbol.name)) continue;
6085        }
6086
6087      if (Me.m_action == action_show_macros)
6088        {
6089          // Only keep macros.
6090          if ((symbol.type == Symbol::SymbolSet) ||
6091              (symbol.type == Symbol::SymbolAlias) ||
6092              (symbol.type == Symbol::SymbolPath) ||
6093              (symbol.type == Symbol::SymbolAction)) continue;
6094        }
6095      else if (Me.m_action == action_show_sets)
6096        {
6097          // Exclude macros.
6098          if ((symbol.type == Symbol::SymbolMacro) ||
6099              (symbol.type == Symbol::SymbolAction)) continue;
6100        }
6101      else if (Me.m_action == action_build_tag_makefile)
6102        {
6103          // Exclude scripts and actions
6104          if ((symbol.type == Symbol::SymbolSetupScript) ||
6105              (symbol.type == Symbol::SymbolCleanupScript) ||
6106              (symbol.type == Symbol::SymbolAction)) continue;
6107        }
6108      else if (Me.m_action == action_show_actions)
6109        {
6110          if (symbol.type != Symbol::SymbolAction) continue;
6111        }
6112
6113      if (symbol.value_lists.size () < 1) continue;
6114
6115      symbol.show_macro (mode);
6116    }
6117}
6118
6119//----------------------------------------------------------
6120void Cmt::print_tabs (int tabs)
6121{
6122  while (tabs > 0)
6123    {
6124      cout << "  ";
6125      tabs--;
6126    }
6127}
6128
6129//----------------------------------------------------------
6130int Cmt::reach_current_package ()
6131{
6132  Use& use = Use::current ();
6133  cmt_string dir;
6134
6135  if (Me.m_debug)
6136    {
6137      cout << "Cmt::reach_current_package> pwd = " 
6138           << CmtSystem::pwd () 
6139           << " path=" << Me.m_current_path
6140           << " package=" << Me.m_current_package
6141           << endl;
6142    }
6143
6144  /*
6145    Try to access the package.
6146  */
6147
6148  if (Me.m_current_package == "cmt_standalone")
6149    {
6150      if ((Me.m_current_path != "") && (Me.m_current_path != CmtSystem::pwd ()))
6151        {
6152          if (!CmtSystem::cd (Me.m_current_path))
6153            {
6154              CmtError::set (CmtError::package_not_found,
6155                             "ReachCurrentPackage> Cannot reach the path directory");
6156              return (0);
6157            }
6158        }
6159
6160      if (!CmtSystem::test_file ("requirements"))
6161        {
6162          return (0);
6163        }
6164    }
6165  else if (Me.m_current_package != "")
6166    {
6167      if (!use.move_to ())
6168        {
6169          CmtError::set (CmtError::package_not_found,
6170                         "ReachCurrentPackage> Cannot reach the path directory");
6171          return (0);
6172        }
6173
6174      Me.m_current_path = use.real_path;
6175    }
6176  else
6177    {
6178      //
6179      // The cmt command has been given without explicit search for
6180      // a package. Thus it is expected that we are in the context of a
6181      // true package.
6182      //
6183      //  This means that there should be a requirements file visible.
6184      //
6185      //  If this is not true, we'll make a try into ../cmt and then
6186      // a last try into ../mgr
6187      //
6188
6189      if (!CmtSystem::test_file ("requirements"))
6190        {
6191          if (CmtSystem::cd ("../cmt") && 
6192              CmtSystem::test_file ("requirements"))
6193            {
6194              Me.m_current_style = cmt_style;
6195            }
6196          else if (CmtSystem::cd ("../mgr") && 
6197                   CmtSystem::test_file ("requirements"))
6198            {
6199              Me.m_current_style = mgr_style;
6200            }
6201          else
6202            {
6203              if (!Me.m_quiet)
6204                {
6205                  cerr << "#CMT> Cannot reach the mgr branch" << endl;
6206                }
6207             
6208              CmtError::set (CmtError::package_not_found,
6209                             "ReachCurrentPackage> Cannot reach the mgr/cmt directory");
6210              return (0);
6211            }
6212        }
6213
6214      dir = CmtSystem::pwd ();
6215
6216      CmtSystem::dirname (dir, Me.m_current_path);
6217      CmtSystem::basename (Me.m_current_path, Me.m_current_version);
6218
6219      if (CmtSystem::is_version_directory (Me.m_current_version))
6220        {
6221          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6222          CmtSystem::basename (Me.m_current_path, Me.m_current_package);
6223          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6224        }
6225      else
6226        {
6227          Me.m_current_package = Me.m_current_version;
6228          Me.m_current_version = "";
6229          CmtSystem::dirname (Me.m_current_path, Me.m_current_path);
6230
6231          Me.m_current_style = no_version_style;
6232        }
6233
6234      use.set_package_name (Me.m_current_package);
6235      use.version = Me.m_current_version;
6236      use.path    = Me.m_current_path;
6237      use.style   = Me.m_current_style;
6238    }
6239
6240  configure_current_dir ();
6241  build_prefix (Me.m_current_package, Me.m_current_prefix);
6242  build_config (Me.m_current_prefix, Me.m_current_config);
6243
6244  /*
6245    Check Tag is always set up
6246  */
6247
6248  if (Me.m_debug) cout << "reach_current_package0> current_tag=" << Me.m_current_tag << endl;
6249
6250  if (Me.m_current_tag == "")
6251    {
6252      cmt_string env;
6253
6254      env = CmtSystem::getenv (Me.m_current_config);
6255      if (env != "")
6256        {
6257          Tag* tag;
6258
6259          tag = Tag::add (env, PriorityConfig, "reach current package", 0);
6260          tag->mark ();
6261          //Me.m_current_tag = env;
6262
6263          //if (!Me.m_quiet) cerr << "reach_current_package1> current_tag=" << Me.m_current_tag << endl;
6264
6265        }
6266    }
6267
6268  if (Me.m_debug)
6269    {
6270      cout << "pwd = " << CmtSystem::pwd () << endl;
6271    }
6272
6273  /*
6274    Work on the requirements file.
6275  */
6276
6277  if (dir != "") dir += CmtSystem::file_separator ();
6278  dir += "requirements";
6279  SyntaxParser::parse_requirements (dir, &use);
6280
6281  if (Me.m_debug) cout << "reach_current_package2> current_tag=" << Me.m_current_tag << endl;
6282
6283  /**
6284   *   It would be useful to change this mechanism. Instead of
6285   *  applying all global patterns at once to all use contexts, it
6286   *  would be much better to apply it at the end of each
6287   *  requirements file parsing, and only in the context the
6288   *  appropriate Use.
6289   *
6290   *   This would avoid the current flaw which is that when a global
6291   *  pattern specifies a "private" definition, it is actually
6292   *  applied in the scope context of the Current Use and not in
6293   *  each individual Use. Therefore the private is lost.
6294   *
6295   *   However, this induces problems since some pattern definitions
6296   *  are done AFTER the use statements, which will NOT receive the
6297   *  pattern aplications.
6298   *
6299   *   Therefore it is decided to leave this "bad" mechanism until
6300   *  everybody is aware of this constraint.
6301   *
6302   *
6303   */
6304  Pattern::apply_all_globals ();
6305
6306  /*
6307    Select all possible tags
6308  */
6309
6310  Tag::restore_tree ();
6311
6312  return (1);
6313}
6314
6315static cmt_string get_best_form (const CmtSystem::cmt_string_vector& pwd,
6316                                 const cmt_string& path)
6317{
6318  static cmt_string fs = CmtSystem::file_separator ();
6319  cmt_string result;
6320
6321  /*
6322  //if (CmtSystem::getenv ("CMTTESTPREFIX") != "")
6323  {
6324  */
6325
6326  //
6327  //  If there is a common prefix between
6328  //  use->real_path and pwd
6329  //  we have
6330  //  use->real_path = /<prefix>/aaa
6331  //  pwd            = /<prefix>/bbb
6332  //
6333  //  Then use->real_path may be expressed as:
6334  //  ../..../../aaa
6335  //   where ../..../../ moves up to /<prefix>
6336  //
6337  //   Then we try to find the shortest between
6338  //
6339  //     /<prefix> and ../..../..
6340  //
6341  cmt_string a = path;
6342 
6343  CmtSystem::cmt_string_vector va;
6344 
6345  va.clear ();
6346 
6347  CmtSystem::split (a, fs, va);
6348 
6349  int m = va.size ();
6350  if (pwd.size () < m) m = pwd.size ();
6351 
6352  int i;
6353 
6354  for (i = 0; i < m; i++)
6355    {
6356      const cmt_string& fa = va[i];
6357      const cmt_string& fb = pwd[i];
6358     
6359      if (fa != fb) break;
6360    }
6361 
6362  cmt_string ups = "";
6363 
6364  if (i > 0)
6365    {
6366      // We have the prefix.
6367      // if we count what remains from pwd, then
6368      // we have the number of ../ required to
6369      // move to /<prefix>
6370      int j;
6371     
6372      for (j = i; j < pwd.size (); j++)
6373        {
6374          if (j > i) ups += fs;
6375          ups += "..";
6376        }
6377
6378      for (j = i; j < va.size (); j++)
6379        {
6380          ups += fs;
6381          ups += va[j];
6382        }
6383    }
6384 
6385  //
6386  // Here ups contains the ../..../../aaa form
6387  // for the use->real_path or is empty when there
6388  // were no common prefix.
6389  //
6390 
6391  //if (ups != "")
6392  if ((ups != "") &&
6393      (ups.size () < path.size ()))
6394    {
6395      result = ups;
6396    }
6397  else
6398    {
6399      result = path;
6400    }
6401
6402  return (result);
6403}
6404
6405/**
6406 *   This completely local class holds primitive actions for building
6407 *   standard macros.
6408 */
6409class StandardMacroBuilder
6410{
6411public:
6412
6413  /**
6414   *  CMTVERSION
6415   */
6416  void fill_for_CMTVERSION ()
6417  {
6418    buffer = "macro CMTVERSION \"";
6419    buffer += CMTVERSION;
6420    buffer += "\"";
6421    apply ();
6422  }
6423
6424  StandardMacroBuilder (const cmt_string& tag,
6425                        const cmt_string& package,
6426                        const cmt_string& version,
6427                        const cmt_string& prefix,
6428                        CmtDirStyle style)
6429  {
6430    fs = CmtSystem::file_separator ();
6431    buffer = "";
6432    pwd = CmtSystem::pwd ();
6433    CmtSystem::split (pwd, fs, vb);
6434    current_use = &(Use::current ());
6435    current_tag = tag;
6436    current_package = package;
6437    current_version = version;
6438    current_prefix = prefix;
6439    current_style = style;
6440  }
6441
6442  void apply ()
6443  {
6444    SyntaxParser::parse_requirements_line (buffer, current_use);
6445    buffer = "";
6446  }
6447
6448  /**
6449   *   tag
6450   */
6451  void fill_for_tag ()
6452  {
6453    static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
6454
6455    if (!Symbol::is_selected ("tag"))
6456      {
6457        if (tag_debug) cerr << "set_standard_macro2.1> current_tag=" << current_tag << endl;
6458
6459        if (current_tag == "")
6460          {
6461            buffer = "macro tag \"$(CMTCONFIG)\"";
6462          }
6463        else
6464          {
6465            buffer = "macro tag \"";
6466            buffer += current_tag;
6467            buffer += "\"";
6468          }
6469       
6470        if (tag_debug) cerr << " define tag: " << buffer << endl;
6471       
6472        apply ();
6473      }
6474  }
6475
6476  /**
6477   *   PACKAGE_ROOT
6478   */
6479  void fill_for_package (const cmt_string& current_dir)
6480  {
6481    buffer = "macro package \"";
6482    buffer += current_package;
6483    buffer += "\"";
6484    apply ();
6485
6486    buffer = "macro version \"";
6487    buffer += current_version;
6488    buffer += "\"";
6489    apply ();
6490
6491    if (!Symbol::is_selected ("PACKAGE_ROOT"))
6492      {
6493        buffer = "macro PACKAGE_ROOT \"$(";
6494        buffer += current_prefix;
6495        buffer += "ROOT";
6496        buffer += ")\"";
6497
6498        apply ();
6499      }
6500  }
6501
6502  /**
6503   *   srcdir
6504   *   src       =$(srcdir)/
6505   *   inc
6506   *   mgrdir
6507   *   mgr       =../$(mgrdir)/
6508   *   bin
6509   *   javabin
6510   *   doc
6511   *   version
6512   *   package
6513   *
6514   *   <package>_project
6515   *   <package>_cmtpath
6516   *   <package>_offset
6517   *   package_cmtpath
6518   *   package_offset
6519   *   project
6520   *
6521   */
6522  void fill_for_branches ()
6523  {
6524    /**
6525     *    Basic macros  (src, mgr, ...)
6526     */
6527   
6528    if (current_style == none_style)
6529      {
6530        buffer = "macro srcdir \".";
6531        buffer += "\"";
6532        apply ();
6533
6534        buffer = "macro src \".";
6535        buffer += fs;
6536        buffer += "\"";
6537        apply ();
6538
6539        buffer = "macro inc \".";
6540        buffer += fs;
6541        buffer += "\"";
6542        apply ();
6543
6544        buffer = "macro mgr \".";
6545        buffer += fs;
6546        buffer += "\"";
6547        apply ();
6548
6549        buffer = "macro bin \".";
6550        buffer += fs;
6551        buffer += "\"";
6552        apply ();
6553
6554        buffer = "macro javabin \".";
6555        buffer += fs;
6556        buffer += "\"";
6557        apply ();
6558
6559        buffer = "macro doc \".";
6560        buffer += fs;
6561        buffer += "\"";
6562        apply ();
6563      }
6564    else
6565      {
6566        if (!Symbol::is_selected ("srcdir"))
6567          {
6568            buffer = "macro srcdir \"..";
6569            buffer += fs;
6570            buffer += "src";
6571            buffer += "\"";
6572            apply ();
6573          }
6574       
6575        if (!Symbol::is_selected ("src"))
6576          {
6577            buffer = "macro src \"..";
6578            buffer += fs;
6579            buffer += "src";
6580            buffer += fs;
6581            buffer += "\"";
6582            apply ();
6583          }
6584       
6585        if (!Symbol::is_selected ("inc"))
6586          {
6587            buffer = "macro inc \"..";
6588            buffer += fs;
6589            buffer += "src";
6590            buffer += fs;
6591            buffer += "\"";
6592            apply ();
6593          }
6594       
6595        if (!Symbol::is_selected ("doc"))
6596          {
6597            buffer = "macro doc \"..";
6598            buffer += fs;
6599            buffer += "doc";
6600            buffer += fs;
6601            buffer += "\"";
6602            apply ();
6603          }
6604       
6605        if (!Symbol::is_selected ("bin"))
6606          {
6607            cmt_string package_tag = current_package;
6608            package_tag += "_tag";
6609
6610            buffer = "macro bin \"..";
6611            buffer += fs;
6612            buffer += "$(";
6613            buffer += package_tag;
6614            buffer += ")";
6615            buffer += fs;
6616            buffer += "\"";
6617            apply ();
6618          }
6619
6620        if (!Symbol::is_selected ("javabin"))
6621          {
6622            buffer = "macro javabin \"..";
6623            buffer += fs;
6624            buffer += "classes";
6625            buffer += fs;
6626            buffer += "\"";
6627            apply ();
6628          }
6629       
6630        if (current_style == mgr_style)
6631          {
6632            buffer = "macro mgrdir \"mgr\"";
6633            apply ();
6634
6635            buffer = "macro mgr \"..";
6636            buffer += fs;
6637            buffer += "mgr";
6638            buffer += fs;
6639            buffer += "\"";
6640            apply ();
6641          }
6642        else
6643          {
6644            buffer = "macro mgrdir \"cmt\"";
6645            apply ();
6646
6647            buffer = "macro mgr \"..";
6648            buffer += fs;
6649            buffer += "cmt";
6650            buffer += fs;
6651            buffer += "\"";
6652            apply ();
6653          }
6654
6655        Cmt::configure_current_cmtpath ();
6656      }
6657  }
6658
6659  /**
6660   *   project
6661   */
6662  void fill_for_project ()
6663  {
6664    if (current_style == none_style) return;
6665
6666    cmt_string project_name;
6667    Project* project = Project::get_current ();
6668    if (project != 0)
6669      {
6670        project_name = project->get_name ();
6671      }
6672
6673    buffer = "macro project \"";
6674    buffer += project_name;
6675    buffer += "\"";
6676    apply ();
6677  }
6678
6679  /**
6680   *   use_requirements
6681   */
6682  void fill_for_use_requirements ()
6683  {
6684    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6685
6686    if (Uses.size () == 0) return;
6687
6688    if (!Symbol::is_selected ("use_requirements"))
6689      {
6690        buffer  = "macro use_requirements \"";
6691        buffer += "requirements ";
6692       
6693        for (int number = 0; number < Uses.size (); number++)
6694          {
6695            Use* use = Uses[number];
6696           
6697            if (use->discarded) continue;
6698            if (use->m_hidden) continue;
6699           
6700            if (use->located ())
6701              {
6702                buffer += "$(";
6703                buffer += use->prefix;
6704                buffer += "ROOT)";
6705                buffer += fs;
6706               
6707                if (use->style == mgr_style) buffer += "mgr";
6708                else buffer += "cmt";
6709               
6710                buffer += fs;
6711                buffer += "requirements ";
6712              }
6713          }
6714       
6715        buffer += "\"";
6716       
6717        apply ();
6718      }
6719  }
6720
6721  /**
6722   *   use_includes
6723   */
6724  void fill_for_use_includes ()
6725  {
6726    Include::parse_all (&(Use::current()));
6727
6728    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6729
6730    if (Uses.size () == 0) return;
6731
6732    if (!Symbol::is_selected ("use_includes"))
6733      {
6734        buffer = "macro_append use_includes \' ";
6735       
6736        for (int number = 0; number < Uses.size (); number++)
6737          {
6738            Use* use = Uses[number];
6739           
6740            if (use->discarded) continue;
6741            if (use->m_hidden) continue;
6742
6743            Package* p = use->get_package ();
6744            if (p->is_cmt ()) continue;
6745
6746            if (Cmt::get_debug ())
6747              {
6748                cout << "fill use_includes for " << use->get_package_name () 
6749                     << " discarded=" << use->discarded
6750                     << " auto_imports=" << use->auto_imports << endl;
6751              }
6752           
6753            if (use->auto_imports == Off) continue;
6754           
6755            Include::parse_all (use);
6756
6757            use->fill_includes_macro (buffer);
6758          }
6759       
6760        buffer += "\'";
6761       
6762        apply ();
6763      }
6764  }
6765
6766  /**
6767   *   use_fincludes
6768   */
6769  void fill_for_use_fincludes ()
6770  {
6771    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6772
6773    if (Uses.size () == 0) return;
6774
6775    if (!Symbol::is_selected ("use_fincludes"))
6776      {
6777        buffer = "macro_append use_fincludes \" $(use_includes)\"";
6778        apply ();
6779      }
6780  }
6781
6782  /**
6783   *   use_stamps
6784   */
6785  void fill_for_use_stamps ()
6786  {
6787    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6788
6789    if (Uses.size () == 0) return;
6790
6791    if (!Symbol::is_selected ("use_stamps"))
6792      {
6793        buffer = "macro use_stamps \"";
6794        (Use::current()).fill_macro (buffer, "stamps");
6795       
6796        for (int number = 0; number < Uses.size (); number++)
6797          {
6798            Use* use = Uses[number];
6799           
6800            if (use->discarded) continue;
6801            if (use->m_hidden) continue;
6802
6803            Package* p = use->get_package ();
6804            if (p->is_cmt ()) continue;
6805           
6806            use->fill_macro (buffer, "stamps");
6807          }
6808       
6809        buffer += "\"";
6810       
6811        apply ();
6812      }
6813  }
6814
6815  /**
6816   *   use_cflags
6817   */
6818  void fill_for_use_cflags ()
6819  {
6820    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6821
6822    if (Uses.size () == 0) return;
6823
6824    if (!Symbol::is_selected ("use_cflags"))
6825      {
6826        Use::fill_macro_all (buffer, "cflags");
6827        apply ();
6828      }
6829  }
6830
6831  /**
6832   *   use_pp_cflags
6833   */
6834  void fill_for_use_pp_cflags ()
6835  {
6836    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6837
6838    if (Uses.size () == 0) return;
6839
6840    if (!Symbol::is_selected ("use_pp_cflags"))
6841      {
6842        Use::fill_macro_all (buffer, "pp_cflags");
6843        apply ();
6844      }
6845  }
6846
6847  /**
6848   *   use_cppflags
6849   */
6850  void fill_for_use_cppflags ()
6851  {
6852    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6853
6854    if (Uses.size () == 0) return;
6855
6856    if (!Symbol::is_selected ("use_cppflags"))
6857      {
6858        Use::fill_macro_all (buffer, "cppflags");
6859        apply ();
6860      }
6861  }
6862
6863  /**
6864   *   use_pp_cppflags
6865   */
6866  void fill_for_use_pp_cppflags ()
6867  {
6868    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6869
6870    if (Uses.size () == 0) return;
6871
6872    if (!Symbol::is_selected ("use_pp_cppflags"))
6873      {
6874        Use::fill_macro_all (buffer, "pp_cppflags");
6875        apply ();
6876      }
6877  }
6878
6879  /**
6880   *   use_fflags
6881   */
6882  void fill_for_use_fflags ()
6883  {
6884    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6885
6886    if (Uses.size () == 0) return;
6887
6888    if (!Symbol::is_selected ("use_fflags"))
6889      {
6890        Use::fill_macro_all (buffer, "fflags");
6891        apply ();
6892      }
6893  }
6894
6895  /**
6896   *   use_pp_fflags
6897   */
6898  void fill_for_use_pp_fflags ()
6899  {
6900    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6901
6902    if (Uses.size () == 0) return;
6903
6904    if (!Symbol::is_selected ("use_pp_fflags"))
6905      {
6906        Use::fill_macro_all (buffer, "pp_fflags");
6907        apply ();
6908      }
6909  }
6910
6911  /**
6912   *   use_linkopts
6913   */
6914  void fill_for_use_linkopts ()
6915  {
6916    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6917
6918    if (Uses.size () == 0) return;
6919
6920    if (!Symbol::is_selected ("use_linkopts"))
6921      {
6922        Use::fill_macro_all (buffer, "linkopts");
6923        apply ();
6924      }
6925  }
6926
6927  /**
6928   *   use_libraries
6929   */
6930  void fill_for_use_libraries ()
6931  {
6932    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6933
6934    if (Uses.size () == 0) return;
6935
6936    if (!Symbol::is_selected ("use_libraries"))
6937      {
6938        buffer  = "macro use_libraries \"";
6939
6940        for (int number = 0; number < Uses.size (); number++)
6941          {
6942            Use* use = Uses[number];
6943           
6944            if (use->discarded) continue;
6945            if (use->m_hidden) continue;
6946           
6947            Package* p = use->get_package ();
6948            if (p->is_cmt ()) continue;
6949
6950            use->fill_macro (buffer, "libraries");
6951          }
6952       
6953        buffer += "\"";
6954       
6955        apply ();
6956      }
6957  }
6958
6959  /**
6960   *   includes
6961   */
6962  void fill_for_includes ()
6963  {
6964    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
6965
6966    if (Uses.size () == 0) return;
6967
6968    if (!Symbol::is_selected ("includes"))
6969      {
6970        buffer = "macro_append includes \' ";
6971
6972        Use& use = Use::current();
6973
6974        if (use.include_path == "")
6975          {
6976            buffer += "$(ppcmd)\"$(srcdir)\" ";
6977          }
6978        else if (use.include_path != "none")
6979          {
6980            buffer += "$(ppcmd)\"";
6981            buffer += use.include_path;
6982            buffer += "\" ";
6983          }
6984
6985        for (int include_number = 0;
6986             include_number < use.includes.size ();
6987             include_number++)
6988          {
6989            Include& incl = use.includes[include_number];
6990
6991            if (incl.name == "") continue;
6992
6993            buffer += "$(ppcmd)\"";
6994            buffer += incl.name;
6995            buffer += "\" ";
6996          }
6997       
6998        buffer += "$(use_includes)\'";
6999       
7000        apply ();
7001      }
7002  }
7003
7004  /**
7005   *   fincludes
7006   */
7007  void fill_for_fincludes ()
7008  {
7009    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7010
7011    if (Uses.size () == 0) return;
7012
7013    if (!Symbol::is_selected ("fincludes"))
7014      {
7015        buffer = "macro_append fincludes \" $(includes)\"";
7016        apply ();
7017      }
7018  }
7019
7020  /**
7021   *  Macros specific to constituents.
7022   *  This includes the compiler flags
7023   *  and fills in these macros from uses packages. This takes care
7024   *  of -no_auto_imports and -import= directives
7025   *
7026   *    <constituent>_use_linkopts
7027   *    <prefix>_<constituent>_cflags
7028   *    <prefix>_<constituent>_pp_cflags
7029   *    <prefix>_<constituent>_cppflags
7030   *    <prefix>_<constituent>_pp_cppflags
7031   *    <prefix>_<constituent>_fflags
7032   *    <prefix>_<constituent>_pp_fflags
7033   *    <constituent>linkopts
7034   *    <constituent>_GUID
7035   *
7036   */
7037  void fill_for_all_constituents ()
7038  {
7039    /// First, finish the parsing of constituent parameters.
7040    if (Cmt::get_debug ())
7041      {
7042        cout << "fill_for_all_constituents>" << endl;
7043      }
7044
7045    Constituent::parse_all ();
7046
7047    Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7048   
7049    const Constituent::ConstituentVector& constituents =
7050      Constituent::constituents ();
7051
7052 
7053    // Prepare the auto_imports states in a vector
7054    cmt_vector<bool> base_auto_imports_states;
7055
7056    base_auto_imports_states.resize (Uses.size ());
7057
7058    int number;
7059   
7060    for (number = 0; number < Uses.size (); number++)
7061      {
7062        Use* use = Uses[number];
7063        base_auto_imports_states[number] = (use->auto_imports != Off);
7064      }
7065   
7066    // Now scan all constituents
7067       
7068    for (number = 0; number < constituents.size (); number++)
7069      {
7070        const Constituent& constituent = constituents[number];
7071       
7072        if (Cmt::get_debug ())
7073          {
7074            cout << "Checking " << constituent.name  << " against imports requests" << endl;
7075          }
7076        Use::UsePtrVector imports;
7077        int i;
7078       
7079        /**
7080         *  Problem for imports in constituents.
7081         *
7082         *     1) use_xxx has holes due to the corresponding
7083         *         -no_auto_imports options attached to some
7084         *        use statements (including the transitive ones)
7085         *
7086         *     2) the -import=yyy options provided to a given constituent
7087         *        should restore the appropriate holes as well as
7088         *        all transitive ones.
7089         *
7090         *     3) for use_linkopts, missing pieces must be filled at
7091         *        the right position. (for others, order is not relevant
7092         *        while transitive access is required for all)
7093         *
7094         */
7095       
7096        if (constituent.type == Document)
7097          { 
7098            continue;
7099          }
7100       
7101        if (constituent.imports.size () == 0) 
7102          {
7103            buffer = "macro_append ";
7104            buffer += constituent.name;
7105            buffer += "_use_linkopts ";
7106            buffer += " \" ";
7107           
7108            current_use->fill_macro (buffer, "linkopts");
7109           
7110            for (i = 0; i < Uses.size (); i++)
7111              {
7112                if (base_auto_imports_states[i])
7113                  {
7114                    Use* u = Uses[i];
7115                   
7116                    if (u->discarded) continue;
7117                    if (u->m_hidden) continue;
7118                   
7119                    Package* p = u->get_package ();
7120                    if (p->is_cmt ()) continue;
7121                   
7122                    u->fill_macro (buffer, "linkopts");
7123                  }
7124              }
7125            buffer += "\"";
7126            apply ();
7127           
7128            /*
7129              buffer = "macro_append ";
7130              buffer += constituent.name;
7131              buffer += "_use_linkopts ";
7132             
7133              buffer += " \" $(use_linkopts)\"";
7134              apply ();
7135            */
7136           
7137            continue;
7138          }
7139       
7140        // From here on, the constituent HAS import options.
7141       
7142        /**
7143         * Create a private copy of the state vector. This private copy
7144         * will be updated according to -import=xxx modifiers for the
7145         * current constituent.
7146         */
7147        cmt_vector<bool> auto_imports_states (base_auto_imports_states);
7148       
7149        for (i = 0; i < constituent.imports.size (); i++)
7150          {
7151            const cmt_string& import = constituent.imports[i];
7152           
7153            //
7154            // Resolve the imported uses
7155            //
7156           
7157            int use_index = Use::find_index (import, "", "");
7158           
7159            if (use_index >= 0)
7160              {
7161                Use* u = Uses[use_index];
7162               
7163                if (u->discarded) continue;
7164                if (u->m_hidden) continue;
7165               
7166                if (Cmt::get_debug ())
7167                  {
7168                    cout << constituent.name  << " needs imports " << import << " "
7169                         << use_index << " " 
7170                         << u->get_package()->get_name() << " "
7171                         << " u->auto_imports=" << u->auto_imports
7172                         << " Off=" << Off
7173                         << " On=" << On
7174                         << endl;
7175                  }
7176               
7177                Package* p = u->get_package ();
7178                if (p->is_cmt ()) continue;
7179               
7180                if (u->auto_imports != Off) continue;
7181               
7182                Use::set_auto_imports_state (use_index, auto_imports_states);
7183              }
7184          }
7185       
7186        if (Cmt::get_debug ())
7187          {
7188            cout << constituent.name  << " has imports " << endl;
7189          }
7190       
7191       
7192        /**
7193         *   Find all newly exposed packages and precompute this list inside
7194         *   a vector.
7195         */
7196        for (i = 0; i < base_auto_imports_states.size (); i++)
7197          {
7198            if (base_auto_imports_states[i]== On && auto_imports_states[i] == Off) continue;
7199           
7200            Use* u = Uses[i];
7201           
7202            if (u->discarded) continue;
7203            if (u->m_hidden)  continue;
7204           
7205            Package* p = u->get_package ();
7206            if (p->is_cmt ()) continue;
7207           
7208            if (Cmt::get_debug ())
7209              {
7210                cout << constituent.name  << " has import " << p->get_name () << endl;
7211              }
7212           
7213            imports.push_back (u);
7214          }
7215       
7216        if (imports.size () == 0) continue;
7217       
7218        cmt_string prefix;
7219       
7220        //
7221        // Documents are not considered
7222        //
7223        switch (constituent.type)
7224          {
7225          case Application:
7226            prefix = "app_";
7227            break;
7228          case Library:
7229            prefix = "lib_";
7230            break;
7231          }
7232       
7233        buffer = "macro_append ";
7234        buffer += prefix;
7235        buffer += constituent.name;
7236        buffer += "_cflags ";
7237        buffer += " \' ";
7238        for (i = 0; i < imports.size (); i++)
7239          {
7240            Use* u = imports[i];
7241           
7242            u->fill_includes_macro (buffer);
7243            u->fill_macro (buffer, "cflags");
7244          }
7245        buffer += "\'";
7246        apply ();
7247       
7248        buffer = "macro_append ";
7249        buffer += prefix;
7250        buffer += constituent.name;
7251        buffer += "_pp_cflags ";
7252        buffer += " \" ";
7253        for (i = 0; i < imports.size (); i++)
7254          {
7255            Use* u = imports[i];
7256           
7257            u->fill_macro (buffer, "pp_cflags");
7258          }
7259        buffer += "\"";
7260        apply ();
7261       
7262        buffer = "macro_append ";
7263        buffer += prefix;
7264        buffer += constituent.name;
7265        buffer += "_cppflags ";
7266        buffer += " \' ";
7267        for (i = 0; i < imports.size (); i++)
7268          {
7269            Use* u = imports[i];
7270           
7271            u->fill_includes_macro (buffer);
7272            u->fill_macro (buffer, "cppflags");
7273          }
7274        buffer += "\'";
7275        apply ();
7276       
7277        buffer = "macro_append ";
7278        buffer += prefix;
7279        buffer += constituent.name;
7280        buffer += "_pp_cppflags ";
7281        buffer += " \" ";
7282        for (i = 0; i < imports.size (); i++)
7283          {
7284            Use* u = imports[i];
7285           
7286            u->fill_macro (buffer, "pp_cppflags");
7287          }
7288        buffer += "\"";
7289        apply ();
7290       
7291        buffer = "macro_append ";
7292        buffer += prefix;
7293        buffer += constituent.name;
7294        buffer += "_fflags ";
7295        buffer += " \' ";
7296        for (i = 0; i < imports.size (); i++)
7297          {
7298            Use* u = imports[i];
7299           
7300            u->fill_includes_macro (buffer);
7301            u->fill_macro (buffer, "fflags");
7302          }
7303        buffer += "\'";
7304        apply ();
7305       
7306        buffer = "macro_append ";
7307        buffer += prefix;
7308        buffer += constituent.name;
7309        buffer += "_pp_fflags ";
7310        buffer += " \" ";
7311        for (i = 0; i < imports.size (); i++)
7312          {
7313            Use* u = imports[i];
7314           
7315            u->fill_macro (buffer, "pp_fflags");
7316          }
7317        buffer += "\"";
7318        apply ();
7319       
7320        /**
7321         *  Setting ${CONSTITUENT}linkopts is a temporary solution
7322         *  until the backward compatibility solution for a proper
7323         *  replacement of use_linkopts by ${CONSTITUENT}_use_linkopts
7324         *  is acheived.
7325         *
7326         */
7327        buffer = "macro_append ";
7328        buffer += constituent.name;
7329        buffer += "linkopts ";
7330        buffer += " \" ";
7331        for (i = 0; i < imports.size (); i++)
7332          {
7333            Use* u = imports[i];
7334           
7335            u->fill_macro (buffer, "linkopts");
7336          }
7337        buffer += "\"";
7338        apply ();
7339       
7340        /**
7341         *  Only for linkopts we take care of the order. This means
7342         *  that ${CONSTITUENT}_use_linkopts should be used in place of use_linkopts.
7343         *
7344         *  (see the application fragments)
7345         *  that ${CONSTITUENT}_use_linkopts will be used in place of use_linkopts.
7346         */
7347        buffer = "macro_append ";
7348        buffer += constituent.name;
7349        buffer += "_use_linkopts ";
7350        buffer += " \" ";
7351       
7352        current_use->fill_macro (buffer, "linkopts");
7353       
7354        for (i = 0; i < Uses.size (); i++)
7355          {
7356            if (auto_imports_states[i])
7357              {
7358                Use* u = Uses[i];
7359               
7360                if (u->discarded) continue;
7361                if (u->m_hidden) continue;
7362               
7363                Package* p = u->get_package ();
7364                if (p->is_cmt ()) continue;
7365               
7366                u->fill_macro (buffer, "linkopts");
7367              }
7368          }
7369        buffer += "\"";
7370        apply ();
7371       
7372        //==== GLAST addition for vs.net ==========
7373        buffer = "macro ";
7374        buffer += constituent.name;
7375        buffer += "_GUID \"{88BF15AB-5A2D-4bea-B64F-02752C2A1F4F}\" ";
7376        apply ();
7377      }
7378  }
7379 
7380  /**
7381   *   Macros implied or required to manage constituents.
7382   */
7383  void fill_for_constituent_macros ()
7384  {
7385    int number;
7386    cmt_string temp;
7387
7388    const Constituent::ConstituentVector& constituents = Constituent::constituents ();
7389 
7390    if (!Symbol::is_selected ("constituents"))
7391      {
7392        temp = "macro_append constituents \" ";
7393       
7394        for (number = 0; number < constituents.size (); number++)
7395          {
7396            const Constituent& constituent = constituents[number];
7397           
7398            if (constituent.group == 0)
7399              {
7400                temp += constituent.name;
7401                temp += " ";
7402              }
7403          }
7404       
7405        temp += "\"";
7406       
7407        SyntaxParser::parse_requirements_line (temp, current_use);
7408      }
7409   
7410    SyntaxParser::parse_requirements_line ("macro_append all_constituents \" $(constituents)\"", 
7411                                           current_use);
7412   
7413    if (!Symbol::is_selected ("constituentsclean"))
7414      {
7415        temp = "macro_append constituentsclean \" ";
7416       
7417        for (number = constituents.size () - 1; number >= 0 ; number--)
7418          {
7419            const Constituent& constituent = constituents[number];
7420           
7421            if (constituent.group == 0)
7422              {
7423                temp += constituent.name;
7424                temp += "clean ";
7425              }
7426          }
7427       
7428        temp += "\"";
7429       
7430        SyntaxParser::parse_requirements_line (temp, current_use);
7431      }
7432   
7433    SyntaxParser::parse_requirements_line ("macro_append all_constituentsclean \" $(constituentsclean)\"", 
7434                                           current_use);
7435   
7436    const Group::GroupVector& groups = Group::groups ();
7437   
7438    for (number = 0; number < groups.size (); number++)
7439      {
7440        const Group& group = groups[number];
7441       
7442        temp = "macro_append ";
7443        temp += group.name ();
7444        temp += "_constituents \" ";
7445       
7446        int i;
7447       
7448        for (i = 0; i < constituents.size (); i++)
7449          {
7450            const Constituent& constituent = constituents[i];
7451           
7452            if ((constituent.group != 0) && 
7453                (group.name () == constituent.group->name ()))
7454              {
7455                temp += constituent.name;
7456                temp += " ";
7457              }
7458          }
7459       
7460        temp += "\"";
7461       
7462        SyntaxParser::parse_requirements_line (temp, current_use);
7463       
7464        temp = "macro_append ";
7465        temp += group.name ();
7466        temp += "_constituentsclean \" ";
7467       
7468        for (i = constituents.size () - 1; i >= 0 ; i--)
7469          {
7470            const Constituent& constituent = constituents[i];
7471           
7472            if ((constituent.group != 0) && 
7473                (group.name () == constituent.group->name ()))
7474              {
7475                temp += constituent.name;
7476                temp += "clean ";
7477              }
7478          }
7479       
7480        temp += "\"";
7481       
7482        SyntaxParser::parse_requirements_line (temp, current_use);
7483      }
7484  }
7485
7486  /**
7487   *  Definitions for installation area mechanisms. Apply all cmtpath patterns
7488   */
7489  void fill_for_install_area ()
7490  {
7491    CmtPathPattern::apply_all ();
7492
7493    const Use& current_use = Use::current ();
7494
7495    if (current_use.get_strategy ("InstallArea"))
7496      {
7497        CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
7498       
7499        ia_mgr.setup ();
7500      }
7501  }
7502
7503  /**
7504   * Macros to be defined once current_package is known
7505   * and even before reading its requirements file.
7506   */
7507  void fill_for_current_package (const cmt_string& current_dir)
7508  {
7509    fill_for_tag ();
7510    fill_for_package (current_dir);
7511  }
7512
7513private:
7514  cmt_string fs;
7515  cmt_string buffer;
7516  CmtSystem::cmt_string_vector vb;
7517  cmt_string pwd;
7518  Use* current_use;
7519  cmt_string current_tag; 
7520  cmt_string current_package; 
7521  cmt_string current_version; 
7522  cmt_string current_prefix; 
7523  CmtDirStyle current_style;
7524};
7525
7526//----------------------------------------------------------
7527void Cmt::set_current_access (AccessMode mode)
7528{
7529  Me.m_current_access = mode;
7530}
7531
7532//----------------------------------------------------------
7533void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
7534{
7535  Me.m_scope_filtering_mode = mode;
7536}
7537
7538//----------------------------------------------------------
7539void Cmt::set_standard_macros ()
7540{
7541  if (Me.m_standard_macros_done) return;
7542
7543  Me.m_standard_macros_done = true;
7544
7545  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
7546  Use& current_use = Use::current ();
7547
7548  cmt_string fs = CmtSystem::file_separator ();
7549
7550  cmt_string pwd = CmtSystem::pwd ();
7551
7552  if (CmtSystem::test_file ("../cmt/requirements")) Me.m_current_style = cmt_style;
7553  else if (CmtSystem::test_file ("../mgr/requirements")) Me.m_current_style = mgr_style;
7554  else Me.m_current_style = none_style;
7555
7556  {
7557    cmt_string v;
7558    CmtSystem::dirname (pwd, v);
7559    CmtSystem::basename (v, v);
7560    if (!CmtSystem::is_version_directory (v))
7561      {
7562        Me.m_current_style = no_version_style;
7563      }
7564  }
7565
7566  // Prepare computation of the best form for relative path from current directory
7567  // to package directories.
7568  CmtSystem::cmt_string_vector vb;
7569  CmtSystem::split (pwd, fs, vb);
7570
7571
7572  /**
7573   *    TAG management
7574   */
7575
7576  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
7577
7578  if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
7579
7580  if (Me.m_current_tag != "")
7581    {
7582      // this is when some -tag= argument was used.
7583      if (tag_debug) cerr << "set_standard_macro0.1> current_tag=" << Me.m_current_tag << endl;
7584    }
7585  else if (Symbol::is_selected ("CMTCONFIG"))
7586    {
7587      // This is when CMTCONFIG has been set from some requirements file
7588      Symbol* macro = Symbol::find ("CMTCONFIG");
7589      if (macro != 0)
7590        {
7591          Me.m_current_tag = macro->build_macro_value ();
7592          if (tag_debug) cerr << "set_standard_macro1> current_tag=" << Me.m_current_tag << endl;
7593        }
7594    }
7595  else
7596    {
7597      // this is when no -tag= argument was used.
7598      if (tag_debug) cerr << "set_standard_macro(before2)> current_tag=" << Me.m_current_tag << endl;
7599      if (current_use.get_package_name () == "CMT")
7600        {
7601          Me.m_current_tag = CmtSystem::getenv ("CMTBIN");
7602        }
7603      else
7604        {
7605          Me.m_current_tag = CmtSystem::getenv ("CMTCONFIG");
7606        }
7607
7608      if (tag_debug) cerr << "set_standard_macro2> current_tag=" << Me.m_current_tag << endl;
7609    }
7610
7611  if (Me.m_debug)
7612    {
7613      cout << "set_standard_macro3>" << endl;
7614    }
7615
7616  StandardMacroBuilder builder (Me.m_current_tag,
7617                                Me.m_current_package,
7618                                Me.m_current_version,
7619                                Me.m_current_prefix,
7620                                Me.m_current_style);
7621
7622
7623  builder.fill_for_current_package (Me.m_current_dir);
7624
7625  builder.fill_for_branches ();
7626  builder.fill_for_project ();
7627
7628  builder.fill_for_install_area ();
7629
7630  builder.fill_for_use_requirements ();
7631  builder.fill_for_use_includes ();
7632  builder.fill_for_use_fincludes ();
7633  builder.fill_for_use_stamps ();
7634  builder.fill_for_use_cflags ();
7635  builder.fill_for_use_pp_cflags ();
7636  builder.fill_for_use_cppflags ();
7637  builder.fill_for_use_pp_cppflags ();
7638  builder.fill_for_use_fflags ();
7639  builder.fill_for_use_pp_fflags ();
7640  builder.fill_for_use_linkopts ();
7641  builder.fill_for_use_libraries ();
7642  builder.fill_for_includes ();
7643  builder.fill_for_fincludes ();
7644  builder.fill_for_all_constituents ();
7645  builder.fill_for_constituent_macros ();
7646}
7647
7648void Cmt::set_all_sets_done ()
7649{
7650  Me.m_all_sets_done = true;
7651}
7652
7653void Cmt::reset_all_sets_done ()
7654{
7655  Me.m_all_sets_done = false;
7656}
7657
7658//----------------------------------------------------------
7659void Cmt::use_cmt ()
7660{
7661  UseRef use;
7662  bool recursive_copy = Me.m_recursive;
7663  bool debug_copy = Me.m_debug;
7664
7665  if (Me.m_default_path.size () <= 0) return;
7666  if (Me.m_current_package == "CMT") return;
7667
7668  Me.m_recursive = true;
7669  //Me.m_debug = false;
7670  use = Use::add (Me.m_default_path, "CMT", Me.m_cmt_version, "", "", "", 0);
7671  Me.m_recursive = recursive_copy;
7672  Me.m_debug = debug_copy;
7673}
7674
7675//----------------------------------------------------------
7676void Cmt::use_home_requirements ()
7677{
7678  use_special_requirements (Me.m_cmt_home, 
7679                            CmtSystem::get_home_package (), 
7680                            "requirements");
7681}
7682
7683//----------------------------------------------------------
7684void Cmt::use_user_context_requirements ()
7685{
7686  use_special_requirements (Me.m_cmt_user_context, 
7687                            CmtSystem::get_user_context_package (), 
7688                            "requirements");
7689}
7690
7691//----------------------------------------------------------
7692void Cmt::use_special_requirements (const cmt_string& path, 
7693                                    const cmt_string& name, 
7694                                    const cmt_string& file_name)
7695{
7696  if (path == "") 
7697    {
7698      return;
7699    }
7700
7701  UseRef use;
7702  bool recursive_copy = Me.m_recursive;
7703
7704  if (Me.m_default_path.size () <= 0) return;
7705  if (Me.m_current_package == "CMT") return;
7706
7707  Me.m_recursive = true;
7708
7709  use = Use::add (path, name, "v0", "", "", "", 0);
7710
7711  cmt_string f = Me.m_cmt_user_context;
7712  f += CmtSystem::file_separator ();
7713  f += file_name;
7714  SyntaxParser::parse_requirements (f, use);
7715
7716  Me.m_recursive = recursive_copy;
7717}
7718
7719//-------------------------------------------------
7720void Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v,
7721                            const cmt_string& separator,
7722                            cmt_string& result)
7723{
7724  result.erase (0);
7725
7726  for (int i = 0; i < v.size (); i++)
7727    {
7728      const cmt_string& s = v[i];
7729      if (s == "") continue;
7730
7731      if (i > 0) result += separator;
7732      result += v[i];
7733    }
7734}
7735
7736//-------------------------------------------------
7737cmt_string Cmt::vector_to_string (const CmtSystem::cmt_string_vector& v)
7738{
7739  cmt_string result;
7740
7741  vector_to_string (v, " ", result);
7742
7743  return (result);
7744}
Note: See TracBrowser for help on using the repository browser.