source: CMT/v1r20p20070208/source/cmt_parser.cxx @ 612

Last change on this file since 612 was 371, checked in by garonne, 17 years ago

See C.L 323

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