source: CMT/v1r19p20061114/source/cmt_parser.cxx

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

remove print by warnings

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