source: CMT/v1r10p20011126/src/cmt_parser.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

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