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