source: CMT/v1r20b1/source/cmt_parser.cxx @ 324

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

format code

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