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

Last change on this file since 521 was 521, checked in by rybkin, 15 years ago

See C.L. 408

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