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

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

See C.L. 405

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