source: CMT/v1r22/source/cmt_parser.cxx @ 615

Last change on this file since 615 was 555, checked in by rybkin, 14 years ago

See C.L. 440

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