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

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

Various bug fixes - see CL# 273 274

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