source: CMT/v1r18p20051108/source/cmt_parser.cxx

Last change on this file was 109, checked in by arnault, 19 years ago

First implementation of a -warnings option.

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