source: CMT/v1r19/source/cmt_parser.cxx @ 1

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

Import all tags

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