source: CMT/v1r18p20060606/source/cmt_parser.cxx

Last change on this file was 181, checked in by garonne, 18 years ago

add the cmt relocate command

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