source: CMT/HEAD/source/cmt_use.cxx @ 581

Last change on this file since 581 was 581, checked in by rybkin, 13 years ago

See C.L. 459

  • Property svn:eol-style set to native
File size: 127.8 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by garonne@lal.in2p3.fr
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "cmt_use.h"
13#include "cmt_system.h"
14#include "cmt_symbol.h"
15#include "cmt_error.h"
16#include "cmt_database.h"
17#include "cmt_syntax.h"
18#include "cmt_log.h"
19
20static void show_packages ();
21
22/*
23 *   Design.
24 *
25 *   There is one central database of all Use objects. This in the Database using:
26 *       Database::instance().get_instances ();
27 *
28 *   There is also a list of selected Use pointers available from
29 *       Database::instance().get_ordered_uses ();
30 *
31 *   A new Use object is created when a new use statement requires it:
32 *     o if the specified version is specified for the first time
33 *     o if the specified path is specified for the first time
34 *
35 */
36
37static bool add_request (const cmt_string& path,
38                         const cmt_string& package_name,
39                         const cmt_string& version)
40{
41  static cmt_map <cmt_string, bool> requests;
42
43  cmt_string request = package_name;
44  request += " ";
45  request += version;
46  request += " ";
47  request += path;
48  static bool b = true;
49
50  bool new_request = false;
51
52  if (!requests.has ((const cmt_string&) request))
53    {
54      new_request = true;
55      requests.add ((const cmt_string&) request, b);
56    }
57
58  return (new_request);
59}
60
61class UseContext
62{
63public:
64
65  static UseContext& current ()
66  {
67    static UseContext me;
68
69    return (me);
70  }
71
72  UseContext ()
73  {
74    m_auto_imports = Unspecified;
75    //m_auto_imports = On;
76  }
77
78  UseContext (const UseContext& other)
79  {
80    m_auto_imports = other.m_auto_imports;
81  }
82
83  UseContext& operator = (const UseContext& other)
84  {
85    m_auto_imports = other.m_auto_imports;
86
87    return (*this);
88  }
89
90  static void set_current (State auto_imports)
91  {
92    UseContext& c = current ();
93
94    c.m_auto_imports = auto_imports;
95  }
96
97  static State get_current_auto_imports ()
98  {
99    UseContext& c = current ();
100
101    return (c.m_auto_imports);
102  }
103
104  static State mask_auto_imports (State context_state, State auto_imports)
105  {
106    switch (auto_imports)
107      {
108      case Unspecified:
109        return context_state;
110        break;
111      case Off:
112        return Off;
113        break;
114      case On:
115        if (context_state != Off)
116          return On;
117        else
118          return context_state;
119        break;
120      }
121  }
122
123private:
124  State m_auto_imports;
125};
126
127
128class BestFitSelector
129{
130public:
131  Use* operate (Use* ref_use, Use* new_use);
132};
133
134//----------------------------------------------------------
135
136typedef enum
137  {
138    IdenticalIds,
139
140    IncompatibleMajorIds,
141    NewMajorIdGreaterThanOld,
142    OldMajorIdGreaterThanNew,
143    ExplicitOldMajorIdWinsAgainstWildarded,
144    ExplicitNewMajorIdWinsAgainstWildarded,
145
146    ExplicitOldMinorIdWinsAgainstWildarded,
147    ExplicitNewMinorIdWinsAgainstWildarded,
148    NewMinorIdGreaterThanOld,
149
150    ExplicitOldPatchIdWinsAgainstWildarded,
151    ExplicitNewPatchIdWinsAgainstWildarded,
152    NewPatchIdGreaterThanOld
153  } CompareStatus;
154
155static CompareStatus compare_versions (const cmt_string& ref_version, const cmt_string& new_version, bool match = false)
156{
157  CompareStatus result = IdenticalIds;
158
159  if (match)
160    {
161      if (ref_version == "" ||
162          ref_version == "*" ||
163          ref_version == "v*")
164        return IdenticalIds;
165
166      int wild_card = ref_version.find ('*');
167      if (wild_card != cmt_string::npos)
168        {
169          cmt_string ref_ver (ref_version.substr (0, wild_card));
170          if (ref_ver.size () > new_version.size ())
171            return IncompatibleMajorIds;
172          else if (strncmp (ref_ver.c_str (), new_version.c_str (), wild_card) == 0)
173            return IdenticalIds;
174          else
175            return IncompatibleMajorIds;
176        }
177      else if (ref_version == new_version)
178            return IdenticalIds;
179      else
180            return IncompatibleMajorIds;
181    }
182
183  int old_v = -1;
184  int old_r = -1;
185  int old_p = -1;
186
187  int new_v = -1;
188  int new_r = -1;
189  int new_p = -1;
190
191  CmtSystem::is_version_directory (ref_version, old_v, old_r, old_p);
192
193  CmtSystem::is_version_directory (new_version, new_v, new_r, new_p);
194
195  if ((new_v != -1) && (old_v != -1) && (new_v != old_v))
196    {
197      /*
198        if (!Cmt::get_quiet ())
199        {
200        cerr << "#1 Required version " << new_version <<
201        " incompatible with selected version " << ref_version <<
202        endl;
203        }
204      */
205
206      if (new_v > old_v)
207        {
208          result = NewMajorIdGreaterThanOld;
209        }
210      else
211        {
212          result = OldMajorIdGreaterThanNew;
213        }
214      //result = IncompatibleMajorIds;
215    }
216  else if ((new_v == -1) || (old_v == -1))
217    {
218      //
219      // we plan to discard new_use, but if it was specified as explicit
220      // and ref_use was wildcarded then new_use will win !!
221      //
222      // So then we'll have to understand where are the wild
223      // cards... If they are on v or r, then we consider them.
224      //
225      //
226
227
228      if ((old_v == -1) && (new_v != -1))
229        {
230          /*
231            if (!Cmt::get_quiet ())
232            {
233            cerr << "#2 Select version " << new_version <<
234            " instead of existing " << ref_version <<
235            endl;
236            }
237          */
238
239          result = ExplicitNewMajorIdWinsAgainstWildarded;
240        }
241      else
242        {
243          /*
244            if (!Cmt::get_quiet ())
245            cerr << "#3 keep version " << ref_version <<
246            " (ignore version " << new_version << ")" <<
247            endl;
248          */
249
250          result = ExplicitOldMajorIdWinsAgainstWildarded;
251        }
252    }
253  else if ((new_r == -1) || (old_r == -1) || (new_r < old_r))
254    {
255      //
256      // we plan to discard new_use, but if it was specified as explicit
257      // and ref_use was wildcarded then new_use will win !!
258      //
259      // So then we'll have to understand where are the wild
260      // cards... If they are on v or r, then we consider them.
261      //
262      //
263
264
265      if ((old_r == -1) && (new_r != -1))
266        {
267          // old has wild card and new has not => new wins
268
269          /*
270            if (!Cmt::get_quiet ())
271            {
272            cerr << "#4 Select release " << new_version
273            << " instead of existing " << ref_version
274            << endl;
275            }
276          */
277
278          result = ExplicitNewMinorIdWinsAgainstWildarded;
279        }
280      else
281        {
282          /*
283            if (!Cmt::get_quiet ())
284            cerr << "#5 keep release " << ref_version <<
285            " (ignore release " << new_version << ")" <<
286            endl;
287          */
288
289          result = ExplicitOldMinorIdWinsAgainstWildarded;
290        }
291    }
292  else if (new_r > old_r)
293    {
294      /*
295        if (!Cmt::get_quiet ())
296        {
297        cerr << "#6 Select release " << new_version <<
298        " instead of existing " << ref_version <<
299        endl;
300        }
301      */
302 
303      result = NewMinorIdGreaterThanOld;
304    }
305  else if ((new_p == -1) || (old_p == -1) || (new_p < old_p))
306    {
307      //
308      // we plan to discard new_use, but if it was specified as explicit
309      // and ref_use was wildcarded then new_use will win !!
310      //
311
312
313      if ((old_p == -1) && (new_p != -1))
314        {
315          /*
316            if (!Cmt::get_quiet ())
317            {
318            cerr << "#7 Select patch " << new_version <<
319            " instead of existing " << ref_version <<
320            endl;
321            }
322          */
323
324          result = ExplicitNewPatchIdWinsAgainstWildarded;
325        }
326      else
327        {
328          /*
329            if (!Cmt::get_quiet ())
330            cerr << "#8 keep patch " << ref_version <<
331            " (ignore version " << new_version << ")" <<
332            endl;
333          */
334
335          result = ExplicitOldPatchIdWinsAgainstWildarded;
336        }
337    }
338  else if (new_p > old_p)
339    {
340      /*
341        if (!Cmt::get_quiet ())
342        {
343        cerr << "#9 Select patch " << new_version <<
344        " instead of existing " << ref_version <<
345        endl;
346        }
347      */
348
349      result = NewPatchIdGreaterThanOld;
350    }
351
352  return (result);
353}
354
355//----------------------------------------------------------
356//
357//  Operations on Use
358//
359//----------------------------------------------------------
360
361/**
362 *  Mark all clients of the current package.
363 */
364void Use::select_clients (const cmt_string& package,
365                          const cmt_string& version)
366{
367  static UsePtrVector& uses = get_ordered_uses ();
368
369  int number;
370  Use* use = 0;
371
372  unselect_all ();
373  undiscard_all ();
374
375  for (number = uses.size () - 1; number >= 0; number--)
376    {
377      use = uses[number];
378      if (use == 0) continue;
379      if (use->is_selected ()) continue;
380      use->select ();
381      if (!use->is_client (package, version)) use->discard ();
382    }
383}
384
385//----------------------------------------------------------
386void Use::show_all (bool skip_discarded, ostream& out, PrintMode mode)
387//void Use::show_all (bool skip_discarded, ostream& out)
388//void Use::show_all (bool skip_discarded)
389{
390  show_all ("use ", skip_discarded, out, mode);
391  //  show_all ("use ", skip_discarded, out);
392}
393
394//----------------------------------------------------------
395void Use::show_cycles ()
396{
397  static int level = 0;
398  static UsePtrVector stack;
399  int size = 0;
400
401  if (level == 0)
402    {
403      unselect_all ();
404      unselect ();
405      stack.clear ();
406    }
407
408  //for (int i = 0; i < level; i++) cout << "  ";
409  //cout << "Use::show_cycles> " << level << " " << get_package_name () << endl;
410 
411  // Detect cycles.
412  for (int k = 0; k < level; k++)
413    {
414      Use* u = stack[k];
415      if (u == this) 
416        {
417          for (;k < level; k++)
418            {
419              u = stack[k];
420              cout << u->get_package_name () << " ";
421            }
422
423          cout << endl;
424
425          return;
426        }
427    }
428
429  // Save this to the stack.
430  if (stack.size () <= level)
431    {
432      stack.push_back (this);
433    }
434  else
435    {
436      stack[level] = this;
437    }
438
439  if (selected) return;
440  selected = true;
441
442  size = sub_uses.size ();
443  for (int n = 0; n < size; n++)
444    {
445      Use* use = sub_uses[n];
446     
447      if (use == 0) continue;
448     
449      //for (int i = 0; i < level; i++) cout << "  ";
450      //cout << "Use::show_cycles> " << get_package_name () << " uses " << use->get_package_name () << endl;
451
452      if (use->discarded)
453        {
454          Use* u;
455         
456          u = use->get_selected_version ();
457          if (u == 0) continue;
458         
459          use = u;
460        }
461     
462      level++;
463      use->show_cycles ();
464      level--;
465    }
466}
467
468//----------------------------------------------------------
469void Use::push_scope_section (ScopeType type)
470{
471  scope_sections.push_back (type);
472}
473
474//----------------------------------------------------------
475void Use::pop_scope_section ()
476{
477  scope_sections.pop_back ();
478}
479
480//----------------------------------------------------------
481void Use::close_scope_sections ()
482{
483  scope_sections.clear ();
484}
485
486//----------------------------------------------------------
487ScopeType Use::get_current_scope () const
488{
489  if (scope_sections.size () == 0) return (initial_scope);
490  const ScopeSection& s = scope_sections.back ();
491  return (s.get_scope ());
492}
493
494//----------------------------------------------------------
495void Use::show_all (const cmt_string& prefix, bool skip_discarded, ostream& out, PrintMode mode)
496//void Use::show_all (const cmt_string& prefix, bool skip_discarded, ostream& out)
497//void Use::show_all (const cmt_string& prefix, bool skip_discarded)
498{
499  static UsePtrVector& uses = get_ordered_uses ();
500
501  Use* use;
502  int number;
503
504  if (Cmt::get_debug ())
505    {
506      cout << "use::show_all-1> ";
507     
508      int i;
509     
510      for (i = 0; i < uses.size (); i++)
511        {
512          Use* u = uses[i];
513          cout << u->get_package_name () << "[" << u->get_index () << "]" << " ";
514        }
515     
516      cout << endl;
517    }
518
519  unselect_all ();
520
521  use = &(current ());
522  use->unselect ();
523  cmt_map <Use*, bool> visited;
524  if (!Cmt::get_quiet () && mode != Xml) use->show_sub_uses (visited, "", use->auto_imports, skip_discarded, out);
525
526  if (uses.size () > 0)
527    {
528      if (!Cmt::get_quiet () && mode != Xml)
529        {
530          out << "#\n";
531          out << "# Selection :\n";
532        }
533
534      //
535      //  First move the CMT package to the end of the use set.
536      //  (ie. used by everybody)
537      //
538      use = Use::find ("CMT");
539      Use::move (use);
540
541      switch (mode)
542        {
543        case Xml :
544          Cmt::print_xml_prolog ("uses", out);
545          out << "<uses>";
546          break;
547        }
548     
549      for (number = uses.size () - 1; number >= 0; number--)
550        {
551          use = uses[number];
552
553          if (use->discarded) continue;
554          if (use->m_hidden) continue;
555
556          if (!use->located ())
557            {
558              CmtMessage::warning ("package " + use->get_package_name ()
559                                   + " " + use->version + " " + use->path
560                                   + " not found");
561              /*
562              if (!Cmt::get_quiet ())
563                {
564                  out << "# package " << use->get_package_name () <<
565                    " " << use->version << " " << use->path <<
566                    " not found" <<
567                    endl;
568                }
569              */
570              CmtError::set (CmtError::package_not_found, use->get_package_name ());
571            }
572          else
573            {
574              switch (mode)
575                {
576                case Xml :
577                  Symbol* s;
578                  out << "<package"
579                      << (use->auto_imports == Off ? " auto_imports=\"no\"" : "")
580                      << ">";
581                  // out << "<order>" << use->get_index () << "</order>";
582                  out << "<name>" << use->get_package_name ()
583                      << "</name><version>" << use->version << "</version>";
584                  out << "<offset>" <<
585                    ( (s = Symbol::find (use->get_package_name () + "_offset"))
586                      ? s->build_macro_value ()
587                      : (CmtMessage::warning
588                         (CmtError::get_error_name (CmtError::symbol_not_found)
589                          + ": macro " + use->get_package_name () + "_offset")
590                         , "") )
591                      << "</offset>";
592                  out << "<cmtpath>" <<
593                    ( (s = Symbol::find (use->get_package_name () + "_cmtpath"))
594                      ? s->build_macro_value ()
595                      : (CmtMessage::warning
596                         (CmtError::get_error_name (CmtError::symbol_not_found)
597                          + ": macro " + use->get_package_name () + "_cmtpath")
598                         , "") )
599                      << "</cmtpath>";
600                  //out << "<offset>" << use->path << "</offset>";
601                  //out << "<cmtpath>" << p << "</cmtpath>";
602                  out << "<root>" << use->get_full_path () << "</root>";
603                  //if (use->auto_imports == Off)
604                  //out << "<no_auto_imports/>";
605                  out << "</package>";
606                  break;
607                default :
608              static const cmt_string empty;
609              cmt_string p = use->real_path;
610              if (use->path != "")
611                {
612                  int pos = p.find_last_of (use->path);
613                  if (pos != cmt_string::npos)
614                    {
615                      if (pos > 0 &&
616                          p[pos - 1] == CmtSystem::file_separator ())
617                        {
618                          // strip trailing file separator
619                          p.erase (pos - 1);
620                        }
621                      else
622                        p.erase (pos);
623                    }
624                }
625
626              out << prefix << use->get_package_name ()
627                   << " " << use->version;
628
629              if (CmtSystem::absolute_path (use->path))
630                {
631                  if (!Cmt::get_quiet ()) 
632                    {
633                      out << " (" << use->path << ")";
634                    }
635                }
636              else
637                {
638                  out << " " << use->path;
639                }
640
641              if (!Cmt::get_quiet ()) 
642                {
643                  if (p != "") out << " (" << p << ")";
644                  if (use->auto_imports == Off) out << " (no_auto_imports)";
645                }
646
647              out << endl;
648                  break;
649                }
650            }
651        }
652
653      Use* suse = Use::find (CmtSystem::get_home_package ());
654      if (suse != 0 && !suse->discarded && !suse->m_hidden && suse->located ())
655        {
656          switch (mode)
657            {
658            case Xml :
659              out << "<package>";
660              out << "<name>" << suse->get_package_name ()
661                  << "</name><version>" << suse->version << "</version>";
662              out << "<offset></offset>";
663              out << "<cmtpath>" << suse->path << "</cmtpath>";
664              out << "<root>" << suse->path << "</root>";
665              out << "</package>";
666              break;
667            default :
668          out << prefix << suse->get_package_name ()
669               << " " << suse->version;
670          if (!Cmt::get_quiet ()) 
671            {
672              out << " (" << suse->path << ")";
673            }
674          out << endl;
675              break;
676            }
677        }
678      suse = Use::find (CmtSystem::get_user_context_package ());
679      if (suse != 0 && !suse->discarded && !suse->m_hidden && suse->located ())
680        {
681          switch (mode)
682            {
683            case Xml :
684              out << "<package>";
685              out << "<name>" << suse->get_package_name ()
686                  << "</name><version>" << suse->version << "</version>";
687              out << "<offset></offset>";
688              out << "<cmtpath>" << suse->path << "</cmtpath>";
689              out << "<root>" << suse->path << "</root>";
690              out << "</package>";
691              break;
692            default :
693          out << prefix << suse->get_package_name ()
694               << " " << suse->version;
695          if (!Cmt::get_quiet ()) 
696            {
697              out << " (" << suse->path << ")";
698            }
699          out << endl;
700              break;
701            }
702        }
703
704      switch (mode)
705        {
706        case Xml :
707          out << "</uses>" << endl;
708          break;
709        }
710      /*
711      if (Cmt::get_cmt_home () != "")
712        {
713          out << prefix << CmtSystem::get_home_package () << " v0";
714          if (!Cmt::get_quiet ())
715            {
716              out << " (" << Cmt::get_cmt_home () << ")";
717            }
718          out << endl;
719        }
720
721      if (Cmt::get_cmt_user_context () != "")
722        {
723          out << prefix << CmtSystem::get_user_context_package () << " v0";
724          if (!Cmt::get_quiet ())
725            {
726              out << " (" << Cmt::get_cmt_user_context () << ")";
727            }
728          out << endl;
729        }
730      */
731    }
732 
733  const UseVector& instances = get_instances ();
734  for (int use_index = 0; use_index < instances.size (); use_index++)
735    {
736      Use* use = &(instances[use_index]);
737      //Use* use = uses[j];
738     
739      if (use->discarded) continue;
740      if (use->m_hidden) continue;
741     
742      if (!use->located ())
743        {
744          CmtError::set (CmtError::package_not_found, use->get_info ());
745        }
746      else
747        {
748          /*
749            CmtMessage::info ("package " +
750            use->get_package_name () +
751            " " + use->version +
752            (use->path != "" ? " " + use->path : "") +
753            " found");
754          */
755        }
756    }
757}
758
759/**
760 *   This private class parses the use statement after macro expansion
761 *   This is a finite state machine.
762 *    It maintains the results of the parsing in terms of a package name,
763 *   a version, a path, and state variables (no_auto_imports)
764 */
765class use_action_iterator
766{
767public:
768
769  use_action_iterator ()
770  {
771    state = need_package;
772    auto_imports = Unspecified;
773  }
774
775  void set (const cmt_string& w)
776  {
777    if (w.find (0, "-native_version=") != -1)
778      {
779        native_version = w.substr (16);
780      }
781    else if (w == "-auto_imports")
782      {
783        auto_imports = On;
784      }
785    else if (w == "-no_auto_imports")
786      {
787        auto_imports = Off;
788      }
789    else if (w == "|")
790      {
791        state = need_version_alias;
792      }
793    else
794      {
795        switch (state)
796          {
797          case need_package:
798            package = w;
799            state = need_version;
800            break;
801          case need_version:
802            version = w;
803            state = need_path;
804            break;
805          case need_path:
806            path = w;
807            while (path[path.size() - 1] == '/') path.erase (path.size() - 1);
808            while (path[path.size() - 1] == '\\') path.erase (path.size() - 1);
809            state = finished;
810            break;
811          case need_version_alias:
812            version_alias = w;
813            state = need_path_alias;
814            break;
815          case need_path_alias:
816            path_alias = w;
817            while (path_alias[path_alias.size() - 1] == '/') path_alias.erase (path_alias.size() - 1);
818            while (path_alias[path_alias.size() - 1] == '\\') path_alias.erase (path_alias.size() - 1);
819            state = finished;
820            break;
821          }
822      }
823  }
824
825  bool ok ()
826  {
827    if (package == "") return (false);
828    if (CmtSystem::is_home_package (package, version)) return (false);
829    if (CmtSystem::is_user_context_package (package, version)) return (false);
830    if (CmtSystem::is_project_package (package, version)) return (false);
831
832    return (true);
833  }
834
835  /**
836   *
837   *  Build or retreive the Use object corresponding to the parsed specification.
838   *
839   */
840  Use* get_use (Use* parent)
841  {
842    static Use::UsePtrVector& uses = Use::get_ordered_uses ();
843
844    if (version == "") version = "*";
845
846    if (Cmt::get_debug ())
847      {
848        int i;
849
850        cout << "use::action1> current=" << parent->get_package_name () <<
851          " package=" << package << "(" << version << ")" << " ";
852
853        for (i = 0; i < uses.size (); i++)
854          {
855            Use* u = uses[i];
856            cout << u->get_package_name () << " ";
857          }
858        cout << endl;
859      }
860
861    const Use& cu = Use::current ();
862
863    /**
864     *   Do not continue the operations for private uses
865     *  accessed from an external context.
866     *
867     *   Exceptions should be considered for
868     *     - cmt broadcast
869     *     - cmt show uses
870     */
871
872    ActionType action = Cmt::get_action ();
873
874    if (Cmt::get_debug ())
875      {
876        cout << "before adding " << package <<"> auto_imports=" << auto_imports
877             << " (current AI was " << UseContext::get_current_auto_imports () << ")" 
878             << " (Use::scope=" << parent->get_current_scope () << ")"
879             << " (parent=" << parent->get_package_name () << ")"
880             << endl;
881      }
882
883    bool hidden_by_scope = false;
884
885    if (parent->get_current_scope () == ScopePrivate)
886      {
887        hidden_by_scope = true;
888
889        // Do not hide immediate children of the current package.
890        if ((parent == 0) || 
891            (parent->get_package () == cu.get_package ())) hidden_by_scope = false;
892
893        // Override default rule according to the scope filtering mode.
894
895        if (Cmt::get_scope_filtering_mode () == reach_private_uses) hidden_by_scope = false;
896      }
897
898    if (hidden_by_scope)
899      {
900        return (0);
901      }
902
903    // Here the version may contain wild cards
904
905    //UseContext save = UseContext::current ();
906
907    /**
908     *  "auto_imports" is the state which is specified on the use statement
909     *  currently being parsed.
910     */
911    //UseContext::set_current (UseContext::mask_auto_imports (UseContext::get_current_auto_imports (), auto_imports));
912    /*
913    switch (auto_imports)
914      {
915      case Unspecified:
916
917        // unspecified => we forward the state saved in the current use context
918
919        //UseContext::set_current (UseContext::get_current_auto_imports ());
920        break;
921      case Off:
922
923        // off => the context becomes constrained to be off
924
925        UseContext::set_current (Off);
926        break;
927      case On:
928
929        // on => if current context is off it is kept off
930        //       otherwise it is forced to on
931
932        if (UseContext::get_current_auto_imports () != Off)
933          {
934            UseContext::set_current (On);
935          }
936        break;
937      }
938*/
939    if (Cmt::get_debug ())
940      {
941        cout << "about to add " << package << endl;
942        //show_packages ();
943      }
944
945    /// Now do create or retreive the Use object.
946        Use* new_use = Use::add (path, package, version, 
947                                 version_alias, path_alias, native_version,
948                                 parent, auto_imports);
949
950        if (new_use != 0)
951          {
952            if (Cmt::get_debug ())
953              {
954                cout << "after adding1 " << package
955                     << "> auto_imports=" << new_use->auto_imports << endl;
956
957                //show_packages ();
958              }
959            /*
960            if (&(Use::current()) == parent)
961              {
962                cmt_map <Use*, bool> visited;
963                static bool yes (true);
964                visited.add (&(Use::current()), yes);
965                new_use->set_auto_imports
966                  (UseContext::mask_auto_imports (Use::current().auto_imports,
967                                                  auto_imports),
968                   auto_imports, visited);
969              }
970            */
971            //new_use->set_auto_imports (UseContext::get_current_auto_imports (),
972            //                 auto_imports);
973            /*
974            switch (new_use->auto_imports)
975              {
976              case Unspecified:
977                new_use->auto_imports = UseContext::get_current_auto_imports ();
978                if (new_use->auto_imports == Unspecified)
979                  {
980                    new_use->auto_imports = On;
981                  }
982                break;
983              case On:
984                break;
985              case Off:
986                if (UseContext::get_current_auto_imports () != Off)
987                  //if (UseContext::get_current_auto_imports () == On)
988                  {
989            */
990                    /**
991                     *  Warning : this Use had been previously specified as -no_auto_imports
992                     *  Now this new specification tries to turn it to auto_imports.
993                     *  It will be required to propagate the change, according to the
994                     *  specifications:
995                     *
996                     *    for all sub_uses:
997                     *       if it is unspecified OR specified as auto_imports:
998                     *          turn it to auto_imports
999                     *
1000                     */
1001            /*
1002                    new_use->set_auto_imports (UseContext::get_current_auto_imports ());
1003                    //new_use->set_auto_imports (On);
1004                  }
1005                break;
1006              }
1007            */
1008
1009            if (Cmt::get_debug ())
1010              {
1011                cout << "after adding2 " << package
1012                     << "> auto_imports=" << new_use->auto_imports << " ";
1013                cout << endl;
1014              }
1015
1016            //UseContext& c = UseContext::current ();
1017            //c = save;
1018
1019            Use::reorder (new_use, parent);
1020           
1021            if (Cmt::get_debug ())
1022              {
1023                cout << "use::action2> current=" << parent->get_package_name ()
1024                     << " package=" << package << " ";
1025
1026                int i;
1027               
1028                for (i = 0; i < uses.size (); i++)
1029                  {
1030                    Use* u = uses[i];
1031                    cout << u->get_package_name () << "[" << u->get_index () << "]" << " ";
1032                  }
1033
1034                cout << endl;
1035              }
1036          }
1037        /*
1038        else // new_use == 0
1039          {
1040            cerr << "action: " << action << " new_use: " <<  new_use
1041                 << " package: " <<  package << endl;
1042
1043            CmtError::set (CmtError::package_not_found, package);
1044          }
1045        */
1046
1047        return (new_use);
1048  }
1049
1050private:
1051
1052  enum
1053    {
1054      need_package,
1055      need_version,
1056      need_path,
1057      need_version_alias,
1058      need_path_alias,
1059      finished
1060    } state;
1061 
1062  State auto_imports;
1063  cmt_string native_version;
1064  cmt_string package;
1065  cmt_string version;
1066  cmt_string path;
1067  cmt_string version_alias;
1068  cmt_string path_alias;
1069};
1070
1071//----------------------------------------------------------
1072Use* Use::action (const CmtSystem::cmt_string_vector& words, Use* parent)
1073{
1074  Use* new_use;
1075
1076  //
1077  // complete syntax : "use <package> <version> <path> <-native_version=<version>>" 
1078  // minimal syntax  : "use <package>"
1079  //
1080  //  o if <version> is omitted then take any version available
1081  //  o <version> can be specified using "v*" or "v<n>r*" or "v<n>r<m>p*"
1082  //
1083  //  o the notation "v*" is preferred to omission (particularly since
1084  //    omission does not permit <path>)
1085  //
1086  if (words.size () < 2) return (0);
1087
1088  use_action_iterator it;
1089
1090  for (int i = 1; i < words.size (); i++)
1091    {
1092      const cmt_string& w = words[i];
1093      cmt_string ew = w;
1094
1095      Symbol::expand (ew);
1096      if (ew != w)
1097        {
1098          CmtSystem::cmt_string_vector ws;
1099
1100          CmtSystem::split (ew, " ", ws);
1101
1102          for (int j = 0; j < ws.size (); ++j)
1103            {
1104              const cmt_string& ww = ws[j];
1105              it.set (ww);
1106            }
1107        }
1108      else
1109        {
1110          it.set (ew);
1111        }
1112    }
1113
1114  if (!it.ok ()) return (0);
1115
1116  static int level = 0;
1117
1118  level++;
1119  new_use = it.get_use (parent);
1120  level--;
1121
1122  return (new_use);
1123}
1124
1125//----------------------------------------------------------
1126void Use::author_action (const CmtSystem::cmt_string_vector& words)
1127{
1128  if (author != "") author += "\n";
1129  for (int i = 1; i < words.size (); i++)
1130    {
1131      const cmt_string& w = words[i];
1132     
1133      if (i > 1) author += " ";
1134      author += w;
1135    }
1136}
1137//----------------------------------------------------------
1138void Use::manager_action (const CmtSystem::cmt_string_vector& words)
1139{
1140  if (manager != "") manager += "\n";
1141  for (int i = 1; i < words.size (); i++)
1142    {
1143      const cmt_string& w = words[i];
1144     
1145      if (i > 1) manager += " ";
1146      manager += w;
1147    }
1148}
1149
1150//----------------------------------------------------------
1151Use* Use::find (const cmt_string& package, 
1152                const cmt_string& version, 
1153                const cmt_string& path)
1154{
1155  Package* p = Package::find (package);
1156  if (p == 0) return (0);
1157
1158  UsePtrVector& uses = p->get_uses ();
1159
1160  int use_index;
1161  int size = uses.size ();
1162
1163  for (use_index = 0; use_index < size; use_index++)
1164    {
1165      Use& use = (*uses[use_index]);
1166
1167      // If the version argument is omitted then
1168      // take the first registered version
1169      if (version == "") return (&use);
1170         
1171      // Otherwise compare against specified_version and path
1172      //if ((use.specified_version == version) &&
1173      //  (use.specified_path == path)) return (&use);
1174     
1175      // what about comparing wild cards?
1176
1177      if (use.specified_version == version) return (&use);
1178    }
1179
1180  return (0);
1181}
1182
1183//----------------------------------------------------------
1184int Use::find_index (const cmt_string& package_name, 
1185                     const cmt_string& version, 
1186                     const cmt_string& path)
1187{
1188  Package* package = Package::find (package_name);
1189  if (package == 0) return (-1);
1190
1191  UsePtrVector& uses = package->get_uses ();
1192
1193  int use_index;
1194  int size = uses.size ();
1195  for (use_index = 0; use_index < size; use_index++)
1196    {
1197      Use* use = uses[use_index];
1198
1199      if (Cmt::get_debug ())
1200        {
1201          cout << "Use::find_index> " << package_name
1202               << " " << use
1203               << " " << use->m_index
1204               << endl;
1205        }
1206
1207      // If the version argument is omitted then
1208      // take the first registered version
1209      if (version == "") return (use->m_index);
1210     
1211      // Otherwise compare against specified_version and path
1212      //if ((use.specified_version == version) &&
1213      //  (use.specified_path == path)) return (&use);
1214     
1215      // what about comparing wild cards?
1216     
1217      if (use->specified_version == version) return (use->m_index);
1218    }
1219
1220  return (-1);
1221}
1222
1223//----------------------------------------------------------
1224/**
1225 *    Find by @package@ Use-object that is
1226 *    o not discarded
1227 *    o in ordereded Uses list (i.e., has non-negative m_index)
1228 */
1229//----------------------------------------------------------
1230Use* Use::find_valid (const cmt_string& package)
1231{
1232  Package* p = Package::find (package);
1233  if (p == 0) return (0);
1234
1235  UsePtrVector& uses = p->get_uses ();
1236
1237  for (int use_index = 0; use_index < uses.size (); use_index++)
1238    {
1239      Use* use = uses[use_index];
1240
1241      if (use->discarded) continue;
1242      if (use->m_index < 0) continue;
1243      // take the first not discarded and ordered
1244      // there should not be more than one
1245      return use;
1246    }
1247
1248  return (0);
1249}
1250
1251//----------------------------------------------------------
1252void Use::set_auto_imports_state (const Use::UsePtrVector& uses,
1253                                  cmt_vector<bool>& auto_imports_states)
1254{
1255  if (0 == uses.size ()) return;
1256
1257  static int level (0);
1258  if (level == 0)
1259    {
1260      unselect_all ();
1261      Use::current().select ();
1262    }
1263
1264  if (Cmt::get_debug ())
1265    {
1266      cout << "Use::set_auto_imports_state>|";
1267      for (int i = level; i > 0; i--) cout << "-";
1268      for (int i = 0; i < uses.size (); i++)
1269      //for (int i = uses.size () - 1; i >= 0; i--)
1270        {
1271          cout << " " << uses[i]->get_package_name ()
1272               << "(" << uses[i]->auto_imports << ")";
1273        }
1274      cout << ">" << endl;
1275    }
1276
1277  for (int i = 0; i < uses.size (); i++)
1278  //for (int i = uses.size () - 1; i >= 0; i--)
1279    {
1280      const Use* use = uses[i];
1281      if (!auto_imports_states[use->m_index])
1282        auto_imports_states[use->m_index] = true;
1283    }
1284
1285  Use::UsePtrVector subuses;
1286  for (int k = 0; k < uses.size (); k++)
1287  //for (int i = uses.size () - 1; i >= 0; i--)
1288    {
1289      Use* use = uses[k];
1290      if (use->is_selected ()) continue;
1291      use->select ();
1292      for (int i = 0; i < use->sub_uses.size (); i++)
1293        {
1294          if (use->sub_uses[i]->m_index >= 0 && !use->sub_uses[i]->discarded)
1295            {
1296              if (use->sub_use_auto_imports[i] != Off
1297                  && !use->sub_uses[i]->is_selected ())
1298                {
1299                  subuses.push_back (use->sub_uses[i]);
1300                }
1301            }
1302          else
1303            {
1304              if (Cmt::get_debug ())
1305                {
1306                  cout << "Use::set_auto_imports_state> " << use->get_package_name ()
1307                       << " -> sub_use " << use->sub_uses[i]->get_package_name ()
1308                       << "[" << use->sub_uses[i] << ", discarded="
1309                       << use->sub_uses[i]->discarded << ", m_index="
1310                       << use->sub_uses[i]->m_index << " : invalid]" << endl;
1311                }
1312              Use* au (find_valid (use->sub_uses[i]->get_package_name ()));
1313              if (au)
1314                {
1315                  if (Cmt::get_debug ())
1316                    {
1317                      cout << "Use::set_auto_imports_state> " << use->get_package_name ()
1318                           << " -> sub_use " << au->get_package_name ()
1319                           << "[" << au << ", discarded="
1320                           << au->discarded << ", m_index="
1321                           << au->m_index << " : valid]" << endl;
1322                    }
1323                  if (use->sub_use_auto_imports[i] != Off
1324                      && !au->is_selected ())
1325                    {
1326                      subuses.push_back (au);
1327                    }
1328                }
1329              else
1330                {
1331                  use->sub_uses[i]->select ();
1332                }
1333            }
1334        }
1335    }
1336
1337  level++;
1338  Use::set_auto_imports_state (subuses, auto_imports_states);
1339  level--;
1340
1341  if (Cmt::get_debug ())
1342    {
1343      cout << "Use::set_auto_imports_state><";
1344      for (int i = level; i > 0; i--) cout << "-";
1345      for (int i = 0; i < uses.size (); i++)
1346      //for (int i = uses.size () - 1; i >= 0; i--)
1347        {
1348          cout << " " << uses[i]->get_package_name ()
1349               << "(" << (auto_imports_states[uses[i]->m_index] ? "+" : "-") << ")";
1350        }
1351      cout << "|" << endl;
1352    }
1353
1354  return;
1355}
1356
1357//----------------------------------------------------------
1358void Use::set_auto_imports_state (const Use::UsePtrVector& uses,
1359                                  cmt_vector<bool>& auto_imports_states,
1360                                  cmt_map <Use*, bool>& visited)
1361{
1362  if (0 == uses.size ()) return;
1363  static bool yes (true);
1364
1365  static int level (-1);
1366  level++;
1367  if (level == 0)
1368    {
1369      unselect_all ();
1370    }
1371
1372  if (Cmt::get_debug ())
1373    {
1374      cout << "Use::set_auto_imports_state>|";
1375      for (int i = level; i > 0; i--) cout << "-";
1376      for (int i = 0; i < uses.size (); i++)
1377      //for (int i = uses.size () - 1; i >= 0; i--)
1378        {
1379          cout << " " << uses[i]->get_package_name ()
1380               << "(" << uses[i]->auto_imports << ")";
1381        }
1382      cout << ">" << endl;
1383    }
1384
1385  for (int i = 0; i < uses.size (); i++)
1386  //for (int i = uses.size () - 1; i >= 0; i--)
1387    {
1388      Use* use = uses[i];
1389      if (visited.has (use) &&
1390          (0 != level || use->is_selected ()))
1391        // revisit uses specified explicitly with -import=<package> (level == 0)
1392        // encountered in constituent specification for the first time (selected == false)
1393        // to ensure <package> is imported
1394        {
1395          continue;
1396        }
1397
1398      visited.add (use, yes);
1399      if (0 == level) use->select ();
1400
1401      if (!auto_imports_states[use->m_index])
1402        auto_imports_states[use->m_index] = true;
1403      //if (0 == level && use->is_selected ()) continue;
1404
1405      Use::UsePtrVector subuses;
1406      for (int i = 0; i < use->sub_uses.size (); i++)
1407        {
1408          if (use->sub_uses[i]->m_index >= 0 && !use->sub_uses[i]->discarded)
1409            {
1410              if (use->sub_use_auto_imports[i] != Off)
1411                {
1412                  subuses.push_back (use->sub_uses[i]);
1413                }
1414              else
1415                {
1416                  visited.add (use->sub_uses[i], yes);
1417                }
1418            }
1419          else
1420            {
1421              if (Cmt::get_debug ())
1422                {
1423                  cout << "Use::set_auto_imports_state> " << use->get_package_name ()
1424                       << " -> sub_use " << use->sub_uses[i]->get_package_name ()
1425                       << "[" << use->sub_uses[i] << ", discarded="
1426                       << use->sub_uses[i]->discarded << ", m_index="
1427                       << use->sub_uses[i]->m_index << " : invalid]" << endl;
1428                }
1429              Use* au (find_valid (use->sub_uses[i]->get_package_name ()));
1430              if (au)
1431                {
1432                  if (Cmt::get_debug ())
1433                    {
1434                      cout << "Use::set_auto_imports_state> " << use->get_package_name ()
1435                           << " -> sub_use " << au->get_package_name ()
1436                           << "[" << au << ", discarded="
1437                           << au->discarded << ", m_index="
1438                           << au->m_index << " : valid]" << endl;
1439                    }
1440                  if (use->sub_use_auto_imports[i] != Off)
1441                    {
1442                      subuses.push_back (au);
1443                    }
1444                  else
1445                    {
1446                      visited.add (au, yes);
1447                    }
1448                }
1449              else
1450                {
1451                  visited.add (use->sub_uses[i], yes);
1452                }
1453            }
1454        }
1455      Use::set_auto_imports_state (subuses, auto_imports_states, visited);
1456    }
1457
1458  if (Cmt::get_debug ())
1459    {
1460      cout << "Use::set_auto_imports_state><";
1461      for (int i = level; i > 0; i--) cout << "-";
1462      for (int i = 0; i < uses.size (); i++)
1463      //for (int i = uses.size () - 1; i >= 0; i--)
1464        {
1465          cout << " " << uses[i]->get_package_name ()
1466               << "(" << (auto_imports_states[uses[i]->m_index] ? "+" : "-") << ")";
1467        }
1468      cout << "|" << endl;
1469    }
1470
1471  level--;
1472  return;
1473}
1474
1475/**
1476 *   1) Given a Use object identified by its index in the ordered_uses() array,
1477 *   2) Given a vector of states containing the auto_imports states of all uses,
1478 *
1479 *     we want to switch to 'On' the auto_imports states of all
1480 *     sub_uses of the argument that were Off.
1481 *
1482 */
1483 /*
1484void Use::set_auto_imports_state (int use_index,
1485                                  cmt_vector<bool>& auto_imports_states)
1486{
1487  // check boundaries (this should be an error when out bondaries)
1488  if ((use_index < 0) || (use_index >= auto_imports_states.size ())) return;
1489
1490  Use::UsePtrVector& uses = Use::get_ordered_uses ();
1491
1492  if (Cmt::get_debug ())
1493    {
1494      int i;
1495     
1496      cout << "Use::set_auto_imports_state> use_index=" << use_index << " ";
1497     
1498      for (i = 0; i < auto_imports_states.size (); i++)
1499        {
1500          cout << (auto_imports_states[i] ? "|" : "o");
1501        }
1502
1503      for (i = 0; i < auto_imports_states.size (); i++)
1504        {
1505          cout << " " << (uses[i])->get_package_name ();
1506        }
1507
1508      cout << endl;
1509    }
1510
1511  // check if this is already done (recursivity ending)
1512  if (auto_imports_states[use_index]) return;
1513  auto_imports_states[use_index] = true;
1514
1515  Use* use = uses[use_index];
1516
1517  // We only have to deal with Use objects that were
1518  // actually turned Off
1519  //  if (use->auto_imports != Off) return;
1520  */
1521  /**
1522   *  Here, use points to a Use object which had been declared as
1523   *  no_auto_imports. But we need to switch it On. Therefore,
1524   *
1525   *    1) the state in auto_imports_states has to be set On
1526   *    2) the operation has to be recursively propagated to all
1527   *         sub_uses which also had no_auto_imports. (only to those)
1528   * 
1529   */
1530 
1531  //  auto_imports_states[use_index] = true;
1532  /*
1533  cmt_string s;
1534  static const cmt_string state_text[] = {"Unspecified", "Off", "On"};
1535 
1536  if (Cmt::get_debug ())
1537    {
1538      s = "Use::set_auto_imports_state>(";
1539      s += use->get_package_name ();
1540      s += ")";
1541      //cout << s << endl;
1542    }
1543
1544  int size = use->sub_uses.size ();
1545  for (int i = 0; i < size; i++)
1546    {
1547      Use* u = use->sub_uses[i];
1548
1549      // first find the index of this use.
1550     
1551      int j = u->m_index;
1552
1553      if (Cmt::get_debug ())
1554        {
1555          char num[32]; sprintf (num, "%#x", u);
1556          s += " ";
1557          s += use->sub_uses[i]->get_package_name ();
1558          s += "(";
1559          s += state_text[use->sub_use_auto_imports[i] + 1];
1560          s += ")[p=";
1561          s += num;
1562          s += "]";
1563        }
1564     
1565      if (j >= 0)
1566        {
1567          if (use->sub_use_auto_imports[i] != Off)
1568            {
1569              set_auto_imports_state (j, auto_imports_states);
1570            }
1571  */
1572          /*
1573          if (u->sub_use_auto_imports[i] == Off)
1574            {
1575              set_auto_imports_state (j, auto_imports_states);
1576            }
1577          else
1578            {
1579              auto_imports_states[j] = true;
1580            }
1581            */
1582  /*
1583        }
1584      else
1585        {
1586          if (Cmt::get_debug ())
1587            {
1588              cout << "Use::set_auto_imports_state> " << use->get_package_name ()
1589                   << ": sub_use " << u->get_package_name () << "[" << u
1590                   << "] invalid" << endl;
1591            }
1592        }
1593    }
1594  if (Cmt::get_debug ())
1595    {
1596      cout << s << endl;
1597    }
1598}
1599  */
1600//----------------------------------------------------------
1601//
1602//  Move use to the end
1603//
1604//----------------------------------------------------------
1605void Use::move (Use* use)
1606{
1607  if (use == 0) return;
1608
1609  static UsePtrVector& uses = get_ordered_uses ();
1610
1611  int size = uses.size ();
1612
1613  if (size == 0) return;
1614
1615  //
1616  // On se positionne sur le pointeur.
1617  //
1618
1619  int use_index = use->m_index;
1620
1621  if (use_index < 0) return;
1622
1623  //
1624  // On deplace tous les pointeurs d'une case en arriere
1625  //
1626  for (use_index++; use_index < size; use_index++)
1627    {
1628      Use* u = uses[use_index];
1629      u->m_index--;
1630
1631      uses[use_index - 1] = uses[use_index];
1632    }
1633
1634  //
1635  // use est donc replace en derniere position
1636  //
1637
1638  use->m_index = size - 1;
1639  uses[size - 1] = use;
1640}
1641
1642/**
1643 *   Reorder provider versus client in the UsePtrVector list,
1644 *  so that the order reflects the fact that client makes use of provider.
1645 *   The result should be that provider appears before client in the list.
1646 */
1647void Use::reorder (Use* provider, Use* client)
1648{
1649  static UsePtrVector& uses = get_ordered_uses ();
1650
1651  int use_index;
1652
1653  int size = uses.size ();
1654
1655  if (size == 0) return;
1656  if (provider == client) return;
1657
1658  //
1659  // First locate the two use objects into the uses vector.
1660  //   -> provider_index and client_index
1661  //
1662
1663  int provider_index = -1;
1664  int client_index = -1;
1665
1666  provider_index = provider->m_index;
1667  client_index = client->m_index;
1668
1669  if (Cmt::get_debug ())
1670    {
1671      cout << "Use::reorder> provider=" << provider_index << " client=" << client_index << endl;
1672    }
1673
1674  //
1675  // Both objects must be installed in uses before acting.
1676  //
1677  if (provider_index == -1) return;
1678  if (client_index == -1) return;
1679
1680  if (client_index < provider_index)
1681    {
1682      //
1683      // client is already before provider so job is finished
1684      //
1685      return;
1686    }
1687
1688  //
1689  // before : <a a a P b b b C c c c>
1690  //                 ^       ^
1691  //                 ip      ic
1692  //
1693  //  1) move "P b b b" by one place to the right
1694  // thus :   <a a a P P b b b c c c>
1695  //
1696  //  2) move "C" to [ip]
1697  //
1698  // after  : <a a a C P b b b c c c>
1699  //
1700 
1701  for (use_index = client_index - 1; use_index >= provider_index; use_index--)
1702    {
1703      Use* use = uses[use_index];
1704      use->m_index++;
1705
1706      uses[use_index + 1] = uses[use_index];
1707    }
1708 
1709  uses[provider_index] = client;
1710  client->m_index = provider_index;
1711}
1712
1713//----------------------------------------------------------
1714void Use::clear_all ()
1715{
1716  static UsePtrVector& uses = get_ordered_uses ();
1717  static UseVector& instances = get_instances ();
1718
1719  int use_index;
1720
1721  for (use_index = 0; use_index < instances.size (); use_index++)
1722    {
1723      Use& use = instances[use_index];
1724      use.clear ();
1725    }
1726
1727  uses.clear ();
1728  instances.clear ();
1729}
1730
1731//----------------------------------------------------------
1732void Use::unselect_all ()
1733{
1734  static UsePtrVector& uses = get_ordered_uses ();
1735
1736  int use_index;
1737
1738  int size = uses.size ();
1739
1740  if (size == 0) return;
1741
1742  for (use_index = 0; use_index < size; use_index++)
1743    {
1744      Use* use = uses[use_index];
1745
1746      if (use != 0)
1747        {
1748          use->unselect ();
1749        }
1750    }
1751}
1752
1753//----------------------------------------------------------
1754void Use::undiscard_all ()
1755{
1756  static UsePtrVector& uses = get_ordered_uses ();
1757
1758  int use_index;
1759
1760  if (uses.size () == 0) return;
1761
1762  for (use_index = 0; use_index < uses.size (); use_index++)
1763    {
1764      Use* use = uses[use_index];
1765
1766      if (use != 0)
1767        {
1768          use->undiscard ();
1769        }
1770    }
1771}
1772
1773//----------------------------------------------------------
1774void Use::fill_macro_all (cmt_string& buffer, const cmt_string& suffix)
1775{
1776  UsePtrVector& uses = get_ordered_uses ();
1777
1778  buffer = "macro_append use_";
1779  buffer += suffix;
1780  buffer += " \" ";
1781  (Use::current()).fill_macro (buffer, suffix);
1782
1783  for (int number = 0; number < uses.size (); number++)
1784    {
1785      Use* use = uses[number];
1786     
1787      Package* p = use->get_package ();
1788      if (p->is_cmt ()) continue;
1789
1790      if (use->discarded) continue;
1791      if (use->auto_imports == Off) continue;
1792
1793      use->fill_macro (buffer, suffix);
1794    }
1795 
1796  buffer += "\"";
1797}
1798
1799//----------------------------------------------------------
1800Use::Use ()
1801{
1802  done = false;
1803  discarded = false;
1804  auto_imports = Unspecified;
1805  m_package = 0;
1806  m_index = -1;
1807  native_version = "";
1808
1809  clear ();
1810}
1811
1812//----------------------------------------------------------
1813Use::Use (const cmt_string& new_package,
1814          const cmt_string& new_version,
1815          const cmt_string& new_path)
1816{
1817  auto_imports = Unspecified;
1818  m_located = false;
1819  m_package = 0;
1820  m_index = -1;
1821
1822  set (new_package, new_version, new_path);
1823}
1824
1825//----------------------------------------------------------
1826Use::~Use ()
1827{
1828  clear ();
1829}
1830
1831//----------------------------------------------------------
1832void Use::clear ()
1833{
1834  specified_path = "";
1835  path      = "";
1836
1837  if (m_package != 0)
1838    {
1839      m_package->remove_use (this);
1840      m_package = 0;
1841    }
1842
1843  version   = "";
1844  author    = "";
1845  manager   = "";
1846  real_path = "";
1847
1848  prefix    = "";
1849  style     = mgr_style;
1850  initial_scope = ScopePublic;
1851  done      = false;
1852  discarded = false;
1853  selected  = false;
1854  m_hidden  = false;
1855  auto_imports = Unspecified;
1856
1857  includes.clear ();
1858  include_path = "";
1859  scripts.clear ();
1860  apply_patterns.clear ();
1861  ignore_patterns.clear ();
1862
1863  sub_uses.clear ();
1864  sub_use_scopes.clear ();
1865  sub_use_auto_imports.clear ();
1866
1867  requests.clear ();
1868
1869  alternate_versions.clear ();
1870  alternate_paths.clear ();
1871  alternate_is_head_versions.clear ();
1872
1873  m_head_version.clear (); 
1874
1875  version_alias = "";
1876  path_alias    = "";
1877
1878  m_located = false;
1879  m_has_native_version = false;
1880  m_index = -1;
1881}
1882
1883//----------------------------------------------------------
1884void Use::set (const cmt_string& new_package,
1885               const cmt_string& new_version,
1886               const cmt_string& new_path,
1887               const cmt_string& new_version_alias,
1888               const cmt_string& new_path_alias)
1889{
1890  clear ();
1891
1892  Package* p = Package::add (new_package);
1893
1894  m_package = p;
1895  p->add_use (this);
1896
1897  specified_path    = new_path;
1898  // specified_path.replace_all ("\\", "/");
1899
1900  specified_version = new_version;
1901  version           = new_version;
1902  path              = specified_path;
1903  Symbol::expand (path);
1904  real_path         = "";
1905  style             = mgr_style;
1906  initial_scope     = ScopePublic;
1907  done              = false;
1908  discarded         = false;
1909  Cmt::build_prefix (new_package, prefix);
1910
1911  version_alias = new_version_alias;
1912  path_alias    = new_path_alias;
1913}
1914
1915//----------------------------------------------------------
1916void Use::change_path (const cmt_string& new_path)
1917{
1918  //
1919  // This methods changes real_path after an actual location
1920  // where this package/version has been found.
1921  //
1922
1923  real_path = "";
1924
1925  if (new_path != "")
1926    {
1927      if ((path.size () > 0) &&
1928          (!CmtSystem::absolute_path (path)))
1929        {
1930          real_path = new_path;
1931          real_path += CmtSystem::file_separator ();
1932          real_path += path;
1933        }
1934      else
1935        {
1936          real_path = new_path;
1937        }
1938      // real_path.replace_all ("\\", "/");
1939
1940      CmtSystem::compress_path (real_path);
1941    }
1942 
1943  m_located = true;
1944}
1945
1946//----------------------------------------------------------
1947int Use::reach_package (const cmt_string& from_path, const cmt_string& n_version)
1948{
1949  if (Cmt::get_debug ())
1950    {
1951      cout << "Use::reach_package> " << get_package_name ()
1952           << "(" << version << ") from " << from_path << endl;
1953      cout << "Use::reach_package> native_version required "<<n_version<<endl;
1954    }
1955   
1956  //
1957  // We try to reach a package/version starting from from_path
1958  //
1959
1960  // check if from_path is at least real
1961  if ((from_path != "") && !CmtSystem::cd (from_path)) return (0);
1962
1963  if (Cmt::get_debug ())
1964    {
1965      cout << "Use::reach_package-2>" << endl;
1966    }
1967
1968  // check in case from_path is a new search path
1969  if (from_path != real_path)
1970    {
1971      // Move to that prefix only if it is a relative path.
1972      if ((path.size () > 0) && (!CmtSystem::absolute_path (path)))
1973        {
1974          if (!CmtSystem::cd (path))
1975            {
1976              return (0);
1977            }
1978        }
1979    }
1980
1981  if (Cmt::get_debug ())
1982    {
1983      cout << "Use::reach_package-3>" << endl;
1984    }
1985
1986  // Special treatment for CMTHOME package...
1987  if (get_package_name () == CmtSystem::get_home_package ())
1988    {
1989      discarded = 1;
1990      if (!CmtSystem::test_file ("requirements"))
1991        {
1992          return (0);
1993        }
1994      else
1995        {
1996          return (1);
1997        }
1998    }
1999
2000  if (Cmt::get_debug ())
2001    {
2002      cout << "Use::reach_package-4>" << endl;
2003    }
2004
2005  // Special treatment for CMTUSERCONTEXT package...
2006  if (get_package_name () == CmtSystem::get_user_context_package ())
2007    {
2008      discarded = 1;
2009      if (!CmtSystem::test_file ("requirements"))
2010        {
2011          return (0);
2012        }
2013      else
2014        {
2015          return (1);
2016        }
2017    }
2018
2019  // Special treatment for PROJECT package...
2020  if (get_package_name () == CmtSystem::get_project_package ())
2021    {
2022      discarded = 1;
2023      if (!CmtSystem::test_file ("project"))
2024        {
2025          return (0);
2026        }
2027      else
2028        {
2029          return (1);
2030        }
2031    }
2032
2033  if (Cmt::get_debug ())
2034    {
2035      cout << "Use::reach_package-5>" << endl;
2036    }
2037
2038  // Now from_path exists, try if the package exists there
2039  if (!CmtSystem::cd (get_package_name ()))
2040    {
2041      return (0);
2042    }
2043
2044  if (Cmt::get_debug ())
2045    {
2046      cout << "Use::reach_package-6>" << endl;
2047    }
2048
2049  if (CmtSystem::test_file ("cmt/requirements"))
2050    {
2051      //      CmtSystem::cd ("cmt");
2052
2053      //      style = no_version_style;
2054
2055      cmt_string v;
2056      //      if (Package::get_version (v))
2057      if (Package::get_version (v, "cmt"))
2058        {
2059          CompareStatus s = compare_versions (version, v, true);
2060          if (Cmt::get_debug ())
2061            {
2062              cout << "Use::reach_package-6.1> version=" << version << " v=" << v << " s=" << s << endl;
2063            }
2064
2065          switch (s)
2066            {
2067            case IdenticalIds:
2068            case ExplicitOldMajorIdWinsAgainstWildarded:
2069            case ExplicitOldMinorIdWinsAgainstWildarded:
2070            case ExplicitOldPatchIdWinsAgainstWildarded:
2071              break;
2072            case ExplicitNewMajorIdWinsAgainstWildarded:
2073            case ExplicitNewMinorIdWinsAgainstWildarded:
2074            case NewMinorIdGreaterThanOld:
2075            case ExplicitNewPatchIdWinsAgainstWildarded:
2076            case NewPatchIdGreaterThanOld:
2077              break;
2078            case OldMajorIdGreaterThanNew:
2079            case NewMajorIdGreaterThanOld:
2080              break;
2081            case IncompatibleMajorIds:
2082              if (!is_head_version (v))
2083                return (0);
2084              break;
2085            }
2086          version = v;
2087        }
2088      else if (version == "")
2089        {
2090          version = "v0";
2091        }
2092      CmtSystem::cd ("cmt");
2093      style = cmt_style;
2094      structuring_style = without_version_directory;
2095      return (1);
2096    }
2097  else if (!CmtSystem::cd (version) || (version == ""))
2098    //  else if (!CmtSystem::cd (version))
2099    {
2100      //
2101      // The specified version cannot be found per-se
2102      // There are alternate possibilities when it contains wild cards
2103      //
2104      if ((version.find ("*") != cmt_string::npos) || (version == ""))
2105      //      if ((version == "") || (version.find ("*") != cmt_string::npos))
2106      //      if (version.find ("*") != cmt_string::npos)
2107        {
2108          static CmtSystem::cmt_string_vector versions;
2109          static cmt_string name;
2110
2111          name = ".";
2112          name += CmtSystem::file_separator ();
2113          if (version != "") name += version;
2114          else name += "*";
2115          /*
2116          if (version == "") name += "*";
2117          else name += version;
2118          */
2119          //          name += version;
2120          CmtSystem::scan_dir (name, versions);
2121          if (n_version != "")
2122            {
2123              CmtSystem::cmt_string_vector native_versions;           
2124              for (int i = 0; i < versions.size (); i++)
2125                {
2126                  cmt_string path;
2127                  if (CmtSystem::test_directory (versions[i]))
2128                    {
2129                      path  = versions[i];
2130                      path += CmtSystem::file_separator ();
2131                      path += "cmt";
2132                    }
2133                  else
2134                    {
2135                      path = "cmt";
2136                    }
2137                  path += CmtSystem::file_separator ();
2138                  path += "native_version.cmt";       
2139                                 
2140                  if (CmtSystem::test_file (path))
2141                    {
2142                      cmt_string nv;
2143
2144                      nv.read (path);
2145                      int pos = nv.find ('\n');
2146                      if (pos != cmt_string::npos) nv.erase (pos);
2147
2148                      pos = nv.find ('\r');
2149                      if (pos != cmt_string::npos) nv.erase (pos);
2150
2151                      if (nv == n_version)
2152                        {
2153                          cmt_string& name_entry = native_versions.add ();
2154
2155                          // We have found at least one
2156                          // cout << "native_version :" << n_version << " ,version: " << versions[i] << endl;
2157                          this->native_version   = n_version;
2158                          name_entry            += versions[i];
2159                        }
2160                    }                   
2161                }
2162              versions = native_versions;
2163            }
2164         
2165          int i;
2166          bool found = false;
2167         
2168          for (i = 0; i < versions.size (); i++)
2169            {
2170              const cmt_string& vers = versions[i];
2171             
2172              if (Cmt::get_debug ())
2173                {
2174                  cout << "     ... version " << vers << " exists" << endl;
2175                }
2176
2177              CmtSystem::basename (vers, name);
2178             
2179              int v;
2180              int r;
2181              int p;
2182             
2183              if (CmtSystem::is_version_directory (name, v, r, p))
2184                {
2185                  /*
2186                    This check is not sufficient !! We need to check in addition
2187                    that the selected directory is really the start of a true CMT
2188                    package (ie with either cmt/requirements or mgr/requirements below)
2189                  */
2190
2191                  cmt_string req;
2192
2193                  req = name;
2194                  req += CmtSystem::file_separator ();
2195                  req += "cmt";
2196                  req += CmtSystem::file_separator ();
2197                  req += "requirements";
2198
2199                  if (!CmtSystem::test_file (req))
2200                    {
2201                      req = name;
2202                      req += CmtSystem::file_separator ();
2203                      req += "mgr";
2204                      req += CmtSystem::file_separator ();
2205                      req += "requirements";
2206
2207                      if (!CmtSystem::test_file (req)) continue;
2208                    }
2209
2210                  cmt_string& new_v = alternate_versions.add ();
2211                  new_v = name;
2212                  cmt_string& new_p = alternate_paths.add ();
2213                  new_p = from_path;
2214                  bool& new_i = alternate_is_head_versions.add ();
2215                  new_i = is_head_version (name);
2216
2217                  found = true;
2218                }
2219            }
2220
2221              /*
2222          if (!found)
2223            {
2224              if (CmtSystem::test_file ("cmt/requirements"))
2225                {
2226                  CmtSystem::cd ("cmt");
2227                  style = no_version_style;
2228                  return (1);
2229                }
2230            }
2231              */
2232        }
2233
2234      if (Cmt::get_debug ())
2235        {
2236          cout << "  ... end of version scan" << endl;
2237        }
2238
2239      //
2240      //  We have now the list of possible alternate versions. However
2241      // we return that the expected package/version was not found (yet).
2242      //
2243
2244      return (0);
2245    }
2246
2247  if (Cmt::get_debug ())
2248    {
2249      cout << "Use::reach_package-7>" << endl;
2250    }
2251
2252  //cerr << "  ... version " << version << " exists" << endl;
2253
2254  // Now we have met the exact specified version!
2255  if (CmtSystem::test_file ("cmt/requirements"))
2256    {
2257      CmtSystem::cd ("cmt");
2258      style = cmt_style;
2259      structuring_style = with_version_directory;
2260    }
2261  else if (CmtSystem::test_file ("mgr/requirements"))
2262    {
2263      CmtSystem::cd ("mgr");
2264      style = mgr_style;
2265      structuring_style = with_version_directory;
2266    }
2267  else
2268    {
2269      return (0);
2270    }
2271
2272  if (Cmt::get_debug ())
2273    {
2274      cout << "Use::reach_package-8>" << endl;
2275    }
2276
2277  return (1);
2278}
2279
2280class UseProjectAction : public IProjectAction
2281{
2282public:
2283  UseProjectAction (Use* use, cmt_string n_version="") : m_use (use), m_found (false), native_version(n_version)
2284  {
2285  }
2286
2287  bool found () const
2288  {
2289    return (m_found);
2290  }
2291
2292  bool run (const Project& project)
2293  {
2294    const cmt_string& path = project.get_cmtpath ();
2295     
2296    m_use->alternate_versions.clear ();
2297    m_use->alternate_paths.clear ();
2298    m_use->alternate_is_head_versions.clear ();
2299
2300    if (m_use->reach_package (path, this->native_version))
2301      {
2302        if (Cmt::get_debug ())
2303          {
2304            cout << "move_to4> " << path << endl;
2305          }
2306       
2307        m_use->change_path (path);
2308
2309        m_found = true;
2310
2311        return (false);
2312      }
2313    else if (m_use->alternate_versions.size () > 0)
2314      {
2315        if (m_use->select_alternate ()) 
2316          {
2317            if (Cmt::get_debug ())
2318              {
2319                cout << "move_to5> " << m_use->real_path << endl;
2320              }
2321
2322            m_found = true;
2323
2324            return (false);
2325          }
2326      }
2327   
2328    return (true);
2329  }
2330
2331private:
2332  Use* m_use;
2333  bool m_found;
2334  cmt_string native_version;
2335};
2336
2337//----------------------------------------------------------
2338bool Use::move_to (const cmt_string& native_version, bool curdir)
2339//bool Use::move_to (const cmt_string& native_version)
2340{
2341  if (m_located)
2342    {
2343      //
2344      // The real path where this version/package can be found
2345      // has already been resolved. We thus first go there.
2346      //
2347
2348      if (Cmt::get_debug ())
2349        {
2350          cout << "move_to1> " << real_path << endl;
2351        }
2352
2353      reach_package (real_path, native_version);
2354
2355      return (true);
2356    }
2357
2358  cmt_string expanded_path = path;
2359
2360  //
2361  // If the path specified in this use is a true absolute path,
2362  // then we search the package from there first.
2363  //
2364  if (CmtSystem::absolute_path (expanded_path))
2365    {
2366      if (reach_package (expanded_path,  native_version))
2367        {
2368          if (Cmt::get_debug ())
2369            {
2370              cout << "move_to3> " << expanded_path << endl;
2371            }
2372
2373          change_path (expanded_path);
2374
2375          return (true);
2376        }
2377      else if (alternate_versions.size () > 0)
2378        {
2379          if (select_alternate ()) 
2380            {
2381              if (Cmt::get_debug ())
2382                {
2383                  cout << "move_to5> " << real_path << endl;
2384                }             
2385
2386              return (true);
2387            }
2388        }
2389    }
2390
2391  //
2392  // Try here.
2393  //
2394  if (curdir)
2395    {
2396//   if (expanded_path == "")
2397//     {
2398//       if (reach_package ("", native_version))
2399
2400      cmt_string here = CmtSystem::pwd ();
2401
2402      if (reach_package (here,  native_version))
2403        {
2404          if (Cmt::get_debug ())
2405            {
2406              cout << "move_to2> " << expanded_path << endl;
2407            }
2408
2409          change_path (here);
2410
2411          return (true);
2412        }
2413      else if (alternate_versions.size () > 0)
2414        {
2415          if (select_alternate ()) 
2416            {
2417              if (Cmt::get_debug ())
2418                {
2419                  cout << "move_to5> " << real_path << endl;
2420                }
2421             
2422              return (true);
2423            }
2424        }
2425      return (false);
2426//     }
2427    } // end of curdir     
2428     
2429  //
2430  // Second try is among the CMTPATHs
2431  //
2432  UseProjectAction pa (this, native_version);
2433
2434  Project::broadcast (pa);
2435
2436  if (pa.found ()) return (true);
2437
2438  return (false);
2439}
2440
2441//----------------------------------------------------------
2442bool Use::select_alternate ()
2443{
2444  int i;
2445
2446  int v0 = 0;
2447  int r0 = 0;
2448  int p0 = 0;
2449
2450  int v = 0;
2451  int r = 0;
2452  int p = 0;
2453
2454  int selected_index = -1;
2455
2456  for (i = 0; i < alternate_versions.size (); i++)
2457    {
2458      cmt_string& name = alternate_versions[i];
2459
2460      if (i == 0)
2461        {
2462          CmtSystem::is_version_directory (name, v0, r0, p0);
2463          selected_index = 0;
2464        }
2465      else
2466        {
2467          if (alternate_is_head_versions[selected_index] &&
2468              alternate_is_head_versions[i])
2469            {
2470              if (strcmp(name.c_str (), alternate_versions[selected_index].c_str ()) > 0)
2471                {
2472                  selected_index = i;
2473                }
2474              continue;
2475            }
2476          else if (alternate_is_head_versions[selected_index])
2477            {
2478              continue;
2479            }
2480          else if (alternate_is_head_versions[i])
2481            {
2482              selected_index = i;
2483              continue;
2484            }
2485
2486          CmtSystem::is_version_directory (name, v, r, p);
2487
2488          if (v > v0)
2489            {
2490              selected_index = i;
2491              v0 = v;
2492              r0 = r;
2493              p0 = p;
2494            }
2495          else if (v == v0)
2496            {
2497              if (r > r0)
2498                {
2499                  selected_index = i;
2500                  r0 = r;
2501                  p0 = p;
2502                }
2503              else if (r == r0)
2504                {
2505                  if (p > p0)
2506                    {
2507                      selected_index = i;
2508                      p0 = p;
2509                    }
2510                }
2511            }
2512        }
2513    }
2514
2515  if (selected_index >= 0)
2516    {
2517      if (CmtSystem::cd (alternate_paths[selected_index]))
2518        {
2519          version = alternate_versions[selected_index];
2520          if (reach_package (alternate_paths[selected_index]))
2521            {
2522              if (Cmt::get_debug ())
2523                {
2524                  cout << "select_alternate> " << alternate_paths[selected_index] << endl;
2525                }
2526
2527              change_path (alternate_paths[selected_index]);
2528              return (true);
2529            }
2530        }
2531    }
2532
2533  return (false);
2534}
2535
2536//----------------------------------------------------------
2537bool Use::need_new (const cmt_string& path,
2538                    const cmt_string& package,
2539                    const cmt_string& version,
2540                    const cmt_string& n_version,
2541                    Use** old_use,
2542                    Use* context_use)
2543{
2544  bool new_request = add_request (path, package, version);
2545   
2546  Use& current_use = Use::current ();
2547
2548  if (package == current_use.get_package_name ())
2549    {
2550      if (Cmt::get_debug ())
2551        {
2552          cout << "  ... recursive use to current package" << endl;
2553        }
2554
2555      if (old_use != 0) *old_use = &current_use;
2556      return (false);
2557    }
2558
2559  Package* p = Package::add (package);
2560
2561  UsePtrVector& uses = p->get_uses ();
2562
2563  bool do_need_new = true;
2564  Use* found = 0;
2565  Use* registered = 0;
2566
2567  int req_v = -1;
2568  int req_r = -1;
2569  int req_p = -1;
2570
2571  CmtSystem::is_version_directory (version, req_v, req_r, req_p);
2572
2573  if (Cmt::get_debug ())
2574    {
2575      cout << "need_new> p=" << package << " v=" << version << " v=" << req_v << " r=" << req_r << " p=" << req_p << endl;
2576    }
2577
2578  bool has_wild_card = (req_v == -1) || (req_r == -1) || (req_p == -1);
2579
2580  int new_v = -1;
2581  int new_r = -1;
2582  int new_p = -1;
2583
2584  int use_index;
2585
2586  if (old_use != 0) *old_use = 0;
2587
2588  // Acquire the registered use.
2589  for (use_index = 0; use_index < uses.size (); use_index++)
2590    {
2591      Use& use = (*uses[use_index]);
2592
2593      if (use.m_index < 0) continue;
2594
2595      registered = &use;
2596
2597      break;
2598    }
2599
2600  // Make a first try with the registered use if it exists.
2601
2602  cmt_string decision;
2603
2604  if (registered != 0)
2605    {
2606      Use& use = (*registered);
2607
2608      found = &use;
2609
2610      CmtSystem::is_version_directory (use.specified_version, new_v, new_r, new_p);
2611
2612      bool use_has_wild_card = (new_v == -1) || (new_r == -1) || (new_p == -1);
2613
2614      if (has_wild_card && !use_has_wild_card)
2615        {
2616          if (Cmt::get_debug ())
2617            {
2618              cout << "  ... wildcarded request loses against existing explicit" << endl;
2619            }
2620         
2621          do_need_new = false; // We don't need a new one
2622        }
2623      else
2624        {
2625          // here either !has_wild_card or use_has_wild_card
2626
2627          if ((version == use.specified_version) &&
2628              (path == use.specified_path))
2629            {
2630             
2631              if (Cmt::get_debug ())
2632                {
2633                  cout << " ... exactly same version and path!" << endl;
2634                }             
2635              do_need_new = false; // We don't need a new one
2636              if (n_version != use.native_version)
2637                {
2638                  if (Cmt::get_debug ())
2639                    {
2640                      cout << " ... but native_version differs (" << n_version << "!=" << use.native_version << ") !" << endl; 
2641                    }
2642
2643                  do_need_new = true;   
2644                }             
2645            }
2646          else if (version != use.specified_version)
2647            {
2648              if (Cmt::get_debug ())
2649                {
2650                  cout << "requested explicit wins against existing wildcarded"
2651                       << endl;
2652                }
2653
2654              // The registered use loses against the request
2655            }
2656          else
2657            {
2658              if (Cmt::get_debug ())
2659                {
2660                  cout << "only paths differ, consider the new one."
2661                       << endl;
2662                }
2663
2664              // The registered use loses against the request
2665            }
2666        }
2667
2668
2669      //if (new_request && !Cmt::get_quiet () && (Cmt::get_action () == action_show_uses))
2670      if (new_request && !Cmt::get_quiet ())
2671        {
2672          if ((new_v != -1) && (req_v != -1) && (new_v != req_v))
2673            {
2674              cerr << "# Required version " << version
2675                   << " of package " << package;
2676
2677              if (context_use != 0)
2678                {
2679                  cerr << " [from " << context_use->get_package_name () << "]";
2680                }
2681
2682              cerr << " incompatible with selected version " << use.version;
2683
2684              if (use.version != use.specified_version)
2685                {
2686                  cerr << " (" << use.specified_version << ")" ;
2687                }
2688
2689              cerr << endl;
2690            }
2691        }
2692
2693      if (Cmt::get_debug ())
2694        {
2695          cout << "# " << package << " " << version;
2696
2697          if (context_use != 0)
2698            {
2699              cout << " [from " << context_use->get_package_name () << "]";
2700            }
2701
2702          if (do_need_new)
2703            {
2704              cout << " > ";
2705            }
2706          else
2707            {
2708              cout << " < ";
2709            }
2710
2711          cout << use.version;
2712          if (use.version != use.specified_version)
2713            {
2714              cout << " (" << use.specified_version << ")" ;
2715            }
2716
2717          cout << " (r) ";
2718
2719          cout << endl;
2720        }
2721    }
2722
2723  if (do_need_new)
2724    {
2725      // Now try unregistered uses, since the registered one is not appropriate.
2726      // to see is any other existing use could match
2727
2728      for (use_index = 0; use_index < uses.size (); use_index++)
2729        {
2730          Use& use = (*uses[use_index]);
2731         
2732          if (use.m_index >= 0) continue;
2733         
2734          // Always save the latest found.
2735         
2736          found = &use;
2737
2738          CmtSystem::is_version_directory (use.specified_version, new_v, new_r, new_p);
2739
2740          bool use_has_wild_card = (new_v == -1) || (new_r == -1) || (new_p == -1);
2741
2742          if (has_wild_card && !use_has_wild_card)
2743            {
2744              if (Cmt::get_debug ())
2745                {
2746                  cout << "  ... requested wildcarded loses against existing explicit" << endl;
2747                }
2748             
2749              do_need_new = false; // We don't need a new one
2750            }
2751          else
2752            {
2753              // here either !has_wild_card or use_has_wild_card
2754         
2755              if ((version == use.specified_version) &&
2756                  (path == use.specified_path))
2757                {
2758                  if (Cmt::get_debug ())
2759                    {
2760                      cout << " ... exactly same version and path!" << endl;
2761                    }
2762             
2763                  do_need_new = false; // We don't need a new one
2764                  if (n_version != use.native_version)
2765                    {
2766                      if (Cmt::get_debug ())
2767                        {
2768                          cout << " ... but native_version differs (" << n_version << "!=" << use.native_version << ") !" << endl;
2769                        }
2770
2771                      do_need_new = true;   
2772                    }
2773                 
2774                }
2775              else if (version != use.specified_version)
2776                {
2777                  if (Cmt::get_debug ())
2778                    {
2779                      cout << "requested explicit wins against existing wildcarded"
2780                           << endl;
2781                    }
2782
2783                  // This use loses against the request
2784                }
2785              else
2786                {
2787                  if (Cmt::get_debug ())
2788                    {
2789                      cout << "only paths differ, consider the new one."
2790                           << endl;
2791                    }
2792
2793                  // This use loses against the request
2794                }
2795            }
2796
2797          //if (new_request && !Cmt::get_quiet () && (Cmt::get_action () == action_show_uses))
2798          if (new_request && !Cmt::get_quiet ())
2799            {
2800              if ((new_v != -1) && (req_v != -1) && (new_v != req_v))
2801                {
2802                  cerr << "# Required version " << version
2803                       << " of package " << package;
2804
2805                  if (context_use != 0)
2806                    {
2807                      cerr << " [from " << context_use->get_package_name () << "]";
2808                    }
2809             
2810                  cerr << " incompatible with selected version " << use.version;
2811
2812                  if (use.version != use.specified_version)
2813                    {
2814                      cerr << " (" << use.specified_version << ")" ;
2815                    }
2816
2817                  cerr << endl;
2818                }
2819            }
2820
2821          if (Cmt::get_debug ())
2822            {
2823              cout << "# " << package << " " << version;
2824             
2825              if (context_use != 0)
2826                {
2827                  cout << " [from " << context_use->get_package_name () << "]";
2828                }
2829             
2830              if (do_need_new)
2831                {
2832                  cout << " > ";
2833                }
2834              else
2835                {
2836                  cout << " < ";
2837                }
2838             
2839              if ((new_v != -1) && (req_v != -1) && (new_v != req_v))
2840                {
2841                  cout << "(incompatible) ";
2842                }
2843
2844              cout << use.version;
2845              if (use.version != use.specified_version)
2846                {
2847                  cout << " (" << use.specified_version << ")" ;
2848                }
2849              cout << endl;
2850            }
2851        }
2852    }
2853
2854  if (old_use != 0)
2855    {
2856      if (registered != 0) *old_use = registered;
2857      else *old_use = found;
2858    }
2859
2860  return (do_need_new);
2861}
2862
2863//----------------------------------------------------------
2864//
2865//  Here the version which is provided here is the specified version.
2866// It may contain wild cards or it may be simply empty.
2867//
2868//----------------------------------------------------------
2869Use* Use::create (const cmt_string& path,
2870                  const cmt_string& package,
2871                  const cmt_string& version,
2872                  const cmt_string& version_alias,
2873                  const cmt_string& path_alias,
2874                  const cmt_string& n_version)
2875{
2876  Package* p = 0;
2877
2878  p = Package::add (package);
2879
2880  UsePtrVector& vector = p->get_uses ();
2881
2882  // We first look in the database.
2883  for (int use_index = 0; use_index < vector.size (); use_index++)
2884    {
2885      Use* use = vector[use_index];
2886
2887      if ((use->specified_version == version) && 
2888          (use->specified_path == path) && use->native_version==n_version) return (use);
2889    }
2890
2891  // We now really create a new Use entry.
2892
2893  static UseVector& instances = get_instances ();
2894
2895  Use& use_object = instances.add ();
2896
2897  use_object.set (package, version, path, version_alias, path_alias);
2898
2899  return (&use_object);
2900}
2901
2902//----------------------------------------------------------
2903//  Add a use request into the database.
2904//
2905//  o If a use request already exist in the database,
2906//    check the version compatibility
2907//
2908//----------------------------------------------------------
2909Use* Use::add (const cmt_string& path,
2910               const cmt_string& package_name,
2911               const cmt_string& version,
2912               const cmt_string& version_alias,
2913               const cmt_string& path_alias,
2914               const cmt_string& native_version,
2915               Use* context_use,
2916               const State specified_auto_imports)
2917{
2918  bool do_need_new = false;
2919
2920  Use* old_use = 0;
2921  Use* use = 0;
2922
2923  do_need_new = need_new (path, package_name, version, native_version, &old_use, context_use);
2924
2925  if (Cmt::get_debug ())
2926    {
2927      if (old_use != 0 && !do_need_new)
2928        {
2929          cout << "add> old_use " << old_use->get_package_name () <<
2930            " " << old_use->version <<
2931            " " << old_use->path <<
2932            endl;
2933        }
2934    }
2935
2936  if (do_need_new)
2937    {
2938      use = create (path, package_name, version, version_alias, path_alias, native_version);
2939    }
2940  else
2941    {
2942      // Since we don't need a new Use, it means that old_use exists !
2943
2944      use = old_use;
2945      old_use = 0;
2946    }
2947
2948  if (package_name == CmtSystem::get_home_package ())
2949    {
2950      return (use);
2951    }
2952
2953  if (package_name == CmtSystem::get_user_context_package ())
2954    {
2955      return (use);
2956    }
2957
2958  if (package_name == CmtSystem::get_project_package ())
2959    {
2960      return (use);
2961    }
2962
2963  cmt_string here = CmtSystem::pwd ();
2964
2965  //
2966  // Store the specified sub_uses. Some of them may become discarded
2967  // later on.
2968  //
2969  if (context_use != 0)
2970    {
2971      context_use->sub_uses.push_back (use);
2972
2973      context_use->sub_use_scopes.push_back (context_use->get_current_scope ());
2974
2975      context_use->sub_use_auto_imports.push_back (specified_auto_imports);
2976
2977      cmt_string& request = context_use->requests.add ();
2978
2979      request = package_name;
2980      request += " ";
2981      request += version;
2982      request += " ";
2983      request += path;
2984
2985
2986      if (Cmt::get_debug ())
2987        {
2988          cout << "Use::add context(" << context_use->get_package_name () << ") "
2989               << "[u:" << package_name
2990               << " s:" << context_use->get_current_scope ()
2991               << " ai:" << specified_auto_imports
2992               << "]" << endl;
2993        }
2994    }
2995
2996  if (use == &(Use::current ())) 
2997    {
2998      return (use);
2999    }
3000
3001  /*
3002   *   Now we have a Use object. If it is a new one, we have to
3003   *    1) understand if it exists physically
3004   *    2) it is better than the old ones.
3005   *
3006   *   Here, we may have :
3007   *    1) old_use = 0
3008   *         there was no Use object before for this package
3009   *         the existing one is fine
3010   *
3011   *    2) old_use != 0
3012   *         we have created a new Use (which has to be validated)
3013   */
3014  bool found = use->move_to (native_version);
3015
3016  if (Cmt::get_debug ())
3017    {
3018      cout << "add> use [" << use << "] " << use->get_package_name () 
3019           << " " << use->version
3020           << " " << use->path
3021           << " found=" << found
3022           << " done=" << use->done
3023           << endl;
3024
3025      show_packages ();
3026    }
3027     
3028  if (!found)
3029    {
3030      CmtMessage::warning (CmtError::get_error_name (CmtError::package_not_found)
3031                           + ": " + use->get_info ()
3032                           + ( (context_use != 0) ?
3033                               " (requested by " + context_use->get_package_name () + ")" :
3034                               "" )
3035                           );
3036      /*
3037      CmtMessage::warning ("package " + use->get_package_name ()
3038                           + " " + use->version + " " + use->path
3039                           + " not found"
3040                           + ( (context_use != 0) ?
3041                               " (requested by " + context_use->get_package_name () + ")" :
3042                               "" )
3043                           );
3044      */
3045      /*
3046      if (!Cmt::get_quiet ())
3047        {
3048          cerr << "#CMT> Warning: package " << use->get_package_name () <<
3049            " " << use->version << " " << use->path <<
3050            " not found";
3051
3052          if (context_use != 0)
3053            {
3054              cerr << " (requested by " << context_use->get_package_name () << ")";
3055            }
3056
3057          cerr << endl;
3058        }
3059      */
3060
3061      //CmtError::set (CmtError::package_not_found, use->get_package_name ());
3062      use->m_located = false;
3063      //use = 0;
3064    }
3065
3066  if ((old_use != 0) && (use != old_use))
3067    {
3068      if (Cmt::get_debug ())
3069        {
3070          cout << "There was another version of this Use. \n"
3071               << "But a new one was created due to some criteria. \n"
3072               << "Now we are going to apply the version strategy to make the final selection"
3073               << endl;
3074        }
3075
3076      /*
3077       *    There was another version of this Use.
3078       *    But a new one was created due to some criteria.
3079       *    Now we are going to apply the version strategy to make the final selection.
3080       */
3081
3082      if (Cmt::get_debug ())
3083        {
3084          cout << "select? [" << use << "] "<< use->version <<" vs old_use[" << old_use << "] "
3085               << old_use->get_package_name ()
3086               << " " << old_use->version
3087               << " " << old_use->path
3088               << endl;
3089        }
3090
3091      if (!found)
3092        {
3093          /*
3094           *  This new Use does not correspond to any physical package.
3095           *  let's simply discard it (and go back to old_use)
3096           */
3097
3098          //if (use != 0) use->discard ();
3099          use->discard ();
3100          use = old_use;
3101          if (context_use != 0)
3102            {
3103              context_use->sub_uses[context_use->sub_uses.size () - 1] = use;
3104            }
3105          found = use->move_to (native_version);
3106        }
3107      else
3108        {
3109          //
3110          //  This new version is different from the old one
3111          // thus we have to choose
3112          //
3113          bool old_use_is_head_version (use->is_head_version (old_use->version));
3114          bool use_is_head_version (use->is_head_version (use->version));
3115          Use* selected_use (old_use);
3116          if (old_use_is_head_version && use_is_head_version)
3117            {
3118              if (strcmp(use->version.c_str (), old_use->version.c_str ()) > 0)
3119                {
3120                  selected_use = use;
3121                  if (Cmt::get_debug ())
3122                    {
3123                      cout << "add> new head version " << use->version
3124                           << " wins old head version " << old_use->version
3125                           << endl;
3126                    }
3127                }
3128            }
3129          else if (old_use_is_head_version)
3130            {
3131            }
3132          else if (use_is_head_version)
3133            {
3134              selected_use = use;
3135              if (Cmt::get_debug ())
3136                {
3137                  cout << "add> new head version " << use->version
3138                       << " wins old version " << old_use->version
3139                       << endl;
3140                }
3141            }
3142          else
3143            {
3144              static BestFitSelector selector;
3145              selected_use = selector.operate (old_use, use);
3146              if (Cmt::get_debug ())
3147                {
3148                  cout << "add> operate on old version " << old_use->version
3149                       << " and new version " << use->version
3150                       << endl;
3151                }
3152            }
3153
3154          if (Cmt::get_debug ())
3155            {
3156              cout << "add> old=" << old_use << "i=" << old_use->m_index
3157                   << " new=" << use << "i=" << use->m_index
3158                   << " => selected=" << selected_use
3159                   << endl;
3160            }
3161
3162          //
3163          // Some situations managed by selector.operate happen
3164          // to fail discarding the rejected Use.
3165          //
3166          if (use != selected_use) 
3167            {
3168              use = use->set_selected_version (selected_use);
3169              if (context_use != 0)
3170                {
3171                  context_use->sub_uses[context_use->sub_uses.size () - 1] = use;
3172                }
3173            }
3174         
3175
3176          /*
3177           *   current directory is moved to the selected one
3178           */
3179          found = use->move_to (native_version);
3180        }
3181    }
3182
3183  //
3184  // The following statement is no longer considered as useful.
3185  // It is commented. But we should clarify why it was really needed!
3186  //
3187  //use->undiscard ();
3188
3189  if (found)
3190    {
3191      static UsePtrVector& uses = get_ordered_uses ();
3192
3193      bool registered = false;
3194      const Use& cu = Use::current ();
3195
3196      Package* package = Package::find (package_name);
3197
3198      //
3199      // A pointer to this new object is also added or replaced.
3200      //
3201      if ((use != &cu) && (package == cu.get_package ()))
3202        {
3203          // This is a recursive call to the current package!!
3204          registered = true;
3205          use->done = true;
3206          use->m_index = -1;
3207        }
3208      else
3209        {
3210          //
3211          // Now sort out the registration in ordered uses
3212          //
3213          //  cases:
3214          //
3215          //   use is not yet registered (m_index < 0)
3216          //     o if another use of the same package is registered,
3217          //       it must be substituted with the new one
3218          //     o otherwise create a new entry at the end (it will be sorted
3219          //       afterwards)
3220          //
3221          //   use is already registered (m_index >= 0)
3222          //     o if another use of the same package is registered,
3223          //       it must be discarded, but this may mean that
3224          //       two versions are simultaneously registered (bug?)
3225          //     o otherwise we keep it in place
3226          //
3227
3228          UsePtrVector& puses = package->get_uses ();
3229
3230          if (use->m_index >= 0) registered = true;
3231
3232          /*
3233            We look for all existing uses in that package.
3234          */
3235          for (int i = 0; i < puses.size(); i++)
3236            {
3237              Use* u = puses[i];
3238             
3239              if (Cmt::get_debug ())
3240                {
3241                  cout << "add> check registering between " << use
3242                       << ":" << use->get_package_name ()
3243                       << "(" << use->m_index << ")"
3244                       << " and " << u
3245                       << ":" << u->get_package_name () 
3246                       << "(" << u->m_index << ")"
3247                       << endl;
3248                }
3249
3250              if ((u != use) && (u->m_index >= 0))
3251                {
3252                  // Another use of that package is already registered
3253
3254                  if (Cmt::get_debug ())
3255                    {
3256                      cout << "add> Another use of that package is already registered " 
3257                           << " use(" << use->m_index << ")";
3258                      if (use->m_index >= 0)
3259                        {
3260                          cout << "[" << (uses[use->m_index])->get_package_name () << "]";
3261                        }
3262                      cout << " u(" << u->m_index << ")";
3263                      if (u->m_index >= 0)
3264                        {
3265                          cout << "[" << (uses[u->m_index])->get_package_name () << "]";
3266                        }
3267                      cout << endl;
3268                    }
3269
3270                  if (use->m_index < 0)
3271                    {
3272                      /*
3273                        the newly selected use (use) should replace the one which was registered (u)
3274                      */
3275
3276                      u->set_selected_version (use);
3277
3278                      registered = true;
3279                    }
3280                  else
3281                    {
3282                      // bug??
3283                      if (Cmt::get_debug ())
3284                        {
3285                          cout << "Duplicate entry in ordered uses" << endl;
3286                        }
3287                    }
3288                }
3289            }
3290
3291          if (Cmt::get_debug ())
3292            {
3293              cout << "add> registering completed" << endl;
3294              //show_packages ();
3295            }
3296        }
3297     
3298      if (!registered) 
3299        {
3300          if (Cmt::get_debug ())
3301            {
3302              cout << "add> We install use at the end the ordered list of uses" << endl;
3303            }
3304
3305          uses.push_back (use);
3306          use->m_index = uses.size () - 1;
3307        }
3308
3309      if (Cmt::get_debug ())
3310        {
3311          for (int use_index = 0; use_index < uses.size (); use_index++)
3312            {
3313              Use* u = (Use*) uses[use_index];
3314              cout << "  use[" << use_index << "] p=(" << u << ")" << u->get_package_name () 
3315                   << " v=" << u->version
3316                   << " discarded=" << u->discarded
3317                   << " selected=" << u->selected
3318                   << " done=" << u->done
3319                   << " index=" << u->m_index
3320                   << endl;
3321            }
3322         
3323        }
3324         
3325      if (!use->done && Cmt::get_recursive ())
3326        {
3327          use->done = true;
3328
3329          if (Cmt::get_debug ())
3330            {
3331              cout << "Parsing requirements file at " << CmtSystem::pwd () << endl;
3332            }
3333
3334          SyntaxParser::parse_requirements ("requirements", use);
3335        }
3336      else
3337        {
3338          if (Cmt::get_debug ())
3339            {
3340              cout << "Requirements file at " << CmtSystem::pwd () << " already parsed" << endl;
3341            }
3342        }
3343    }
3344
3345  CmtSystem::cd (here);
3346
3347  return (use);
3348}
3349
3350//----------------------------------------------------------
3351void Use::discard ()
3352{
3353  discarded = true;
3354}
3355
3356//----------------------------------------------------------
3357void Use::undiscard ()
3358{
3359  discarded = false;
3360}
3361
3362//----------------------------------------------------------
3363void Use::select ()
3364{
3365  selected = true;
3366}
3367
3368//----------------------------------------------------------
3369void Use::unselect ()
3370{
3371  selected = false;
3372}
3373
3374//----------------------------------------------------------
3375bool Use::is_selected ()
3376{
3377  return (selected);
3378}
3379
3380/**
3381 *    Check if the package makes use of the specified package/version
3382 *
3383 *    The seach only considers the first level of uses (thus it is
3384 *   NOT recursive)
3385 */
3386bool Use::is_client (const cmt_string& used_package,
3387                     const cmt_string& used_version)
3388{
3389  // A package is client of itself
3390
3391  Package* package = Package::find (used_package);
3392
3393  if ((get_package () == package) &&
3394      (version == used_version)) return (true);
3395
3396  if (discarded) return (false);
3397
3398  int i;
3399
3400  for (i = 0; i < sub_uses.size (); i++)
3401    {
3402      Use* use = sub_uses[i];
3403      if (use == 0) continue;
3404
3405      if ((use->get_package () == package) &&
3406          (use->version == used_version)) return (true);
3407
3408      /*
3409        if (use->is_client (used_package, used_version))
3410        {
3411        return (true);
3412        }
3413      */
3414    }
3415
3416  return (false);
3417}
3418
3419//----------------------------------------------------------
3420void Use::apply_global_patterns ()
3421{
3422  int i;
3423
3424  Pattern::PatternVector& vector = Pattern::patterns ();
3425
3426  for (i = 0; i < vector.size (); i++)
3427    {
3428      Pattern& p = vector[i];
3429
3430      if (p.global)
3431        {
3432          p.apply (this);
3433        }
3434    }
3435}
3436
3437//----------------------------------------------------------
3438void Use::set_include_path (const cmt_string& new_path)
3439{
3440  include_path = new_path;
3441}
3442
3443/**
3444 *   Compute the full real path of a found package.
3445 *   Takes the structuring style into account
3446 *
3447 *    Result is used to fill in the referenced string
3448 *    Result does NOT include the trailing file_separator
3449 */
3450void Use::get_full_path (cmt_string& s) const
3451{
3452  if (real_path == "") s = CmtSystem::pwd ();
3453  else s = real_path;
3454
3455  if (style != none_style)
3456    {
3457      s += CmtSystem::file_separator ();
3458      s += get_package_name ();
3459    }
3460 
3461  //  if (style != no_version_style)
3462  if (structuring_style == with_version_directory)
3463    {
3464      s += CmtSystem::file_separator ();
3465      s += version;
3466    }
3467}
3468
3469/**
3470 *   Compute the full real path of a found package.
3471 *   Takes the structuring style into account
3472 */
3473cmt_string Use::get_full_path () const
3474{
3475  cmt_string result;
3476
3477  get_full_path (result);
3478
3479  return (result);
3480}
3481
3482/**
3483 *   Considering a given path, try and reduce the part of it
3484 *  that corresponds to the full path of this package into its
3485 *  normal form ${<PACKAGE>ROOT}
3486 *   The argument is modified if the pattern is exactly found.
3487 */
3488void Use::reduce_path (cmt_string& s) const
3489{
3490  cmt_string pattern;
3491  get_full_path (pattern);
3492  pattern += CmtSystem::file_separator ();
3493 
3494  cmt_string replacement = "${";
3495  replacement += prefix;
3496  replacement += "ROOT}";
3497  replacement += CmtSystem::file_separator ();
3498
3499  s.replace (pattern, replacement);
3500}
3501
3502//----------------------------------------------------------
3503void Use::get_cmtpath_and_offset (cmt_string& cmtpath, cmt_string& offset) const
3504{
3505  if (get_package_name () == CmtSystem::get_project_package ())
3506    {
3507      offset = "";
3508      CmtSystem::dirname (path, cmtpath);
3509      return;
3510    }
3511  else if (get_package_name () == CmtSystem::get_home_package ())
3512    {
3513      offset = "";
3514      cmtpath = path;
3515      return;
3516    }
3517  else if (get_package_name () == CmtSystem::get_user_context_package ())
3518    {
3519      offset = "";
3520      cmtpath = path;
3521      return;
3522    }
3523
3524  cmtpath = "";
3525  offset = "";
3526
3527  cmtpath = Project::find_in_cmt_paths (real_path);
3528  Project* p = Project::find_by_cmtpath (cmtpath);
3529
3530  //  if (cmtpath != "")
3531  if (p != 0)
3532    {
3533      CmtSystem::compress_path (cmtpath);
3534
3535      static const cmt_string empty_string;
3536      static const cmt_string fs = CmtSystem::file_separator ();
3537     
3538      // In case there are symlinks
3539      //      offset = real_path;
3540      //      offset.replace (cmtpath, empty_string);
3541      //cerr << "realpath_: get_cmtpath_and_offset" << endl;
3542      CmtSystem::realpath_ (real_path, offset);
3543      offset.replace (p->get_cmtpath_real (), empty_string);
3544
3545      /**
3546         try to remove this current CMTPATH entry from path.  This
3547         has a meaning when the specified path already contains an
3548         absolute path.
3549      */
3550     
3551      if (offset[0] == CmtSystem::file_separator ())
3552        {
3553          // Just in case there is a part left after removing the cmtpath entry
3554               
3555          offset.replace (fs, empty_string);
3556        }
3557    }
3558  else
3559    {
3560      offset = real_path;
3561    }
3562}
3563
3564//------------------------------------------------------------
3565bool Use::get_strategy (const cmt_string& name) const
3566{
3567  const Project* p = Project::find_by_cmtpath (Project::find_in_cmt_paths (real_path));
3568
3569  bool strategy;
3570
3571  if (p == 0)
3572    {
3573      static const Project::ProjectPtrVector Ordered = Project::ordered_projects ();
3574      //static const Project::ProjectVector& projects = Project::projects ();
3575
3576      if (Ordered.size () == 0) strategy = StrategyMgr::get_default_strategy (name);
3577      //if (projects.size () == 0) strategy = StrategyMgr::get_default_strategy (name);
3578      else
3579        {
3580          p = Ordered[0];
3581          //p = &(projects[0]);
3582          strategy = p->get_strategy (name);
3583        }
3584    }
3585  else
3586    {
3587      strategy = p->get_strategy (name);
3588    }
3589
3590  return (strategy);
3591}
3592
3593//----------------------------------------------------------
3594void Use::fill_includes_macro (cmt_string& buffer) const
3595{
3596  if (include_path == "")
3597    {
3598      buffer += "$(ppcmd)\"$(";
3599      buffer += get_package_name ();
3600      buffer += "_root)";
3601      buffer += CmtSystem::file_separator ();
3602      buffer += "src\" ";
3603    }
3604  else if (include_path != "none")
3605    {
3606      buffer += "$(ppcmd)\"";
3607      buffer += include_path;
3608      buffer += "\" ";
3609    }
3610 
3611  for (int i = 0; i < includes.size (); i++)
3612    {
3613      Include& incl = includes[i];
3614
3615      if (incl.name == "") continue;
3616     
3617      buffer += "$(ppcmd)\"";
3618      buffer += incl.name;
3619      buffer += "\" ";
3620    }
3621}
3622
3623//----------------------------------------------------------
3624void Use::fill_macro (cmt_string& buffer, const cmt_string& suffix) const
3625{
3626  buffer += " $(";
3627  buffer += get_package_name ();
3628  buffer += "_";
3629  buffer += suffix;
3630  buffer += ") ";
3631}
3632
3633//----------------------------------------------------------
3634void Use::fill_standard_macros (cmt_string& buffer) const
3635{
3636  static cmt_string fs = CmtSystem::file_separator ();
3637
3638  buffer = "";
3639
3640  cmt_string package_name = get_package_name ();
3641
3642  buffer += "macro ";
3643  buffer += package_name;
3644  buffer += "_tag";
3645  buffer += " \"$(tag)\"";
3646  buffer += "\n";
3647
3648  if (located ())
3649    {
3650      buffer += "macro ";
3651      buffer += prefix;
3652      buffer += "ROOT";
3653      buffer += " \"";
3654      buffer += get_full_path ();
3655      buffer += "\"";
3656      buffer += "\n";
3657
3658      buffer += "macro ";
3659      buffer += package_name;
3660      buffer += "_root";
3661      buffer += " \"";
3662      buffer += real_path;
3663      if (style != none_style)
3664        {
3665          buffer += fs;
3666          buffer += package_name;
3667        }
3668      //      if (style != no_version_style)
3669      if (structuring_style == with_version_directory)
3670        {
3671          buffer += fs;
3672          buffer += version;
3673        }
3674      buffer += "\"";
3675      buffer += "\n";
3676    }
3677
3678  buffer += "macro ";
3679  buffer += prefix;
3680  buffer += "VERSION";
3681  buffer += " \"";
3682  buffer += version;
3683  buffer += "\"";
3684  buffer += "\n";
3685
3686  cmt_string cmtpath = "";
3687  cmt_string offset = "";
3688
3689  get_cmtpath_and_offset (cmtpath, offset);
3690
3691  buffer += "macro ";
3692  buffer += package_name;
3693  buffer += "_cmtpath";
3694  buffer += " \"";
3695  buffer += cmtpath;
3696  buffer += "\"";
3697  buffer += "\n";
3698
3699  buffer += "macro ";
3700  buffer += package_name;
3701  buffer += "_offset";
3702  buffer += " \"";
3703  buffer += offset;
3704  buffer += "\"";
3705  buffer += "\n";
3706 
3707  Project* p = Project::find_by_cmtpath (cmtpath);
3708
3709  buffer += "macro ";
3710  buffer += package_name;
3711  buffer += "_project";
3712  buffer += " \"";
3713  if (p != 0)
3714    {
3715      buffer += p->get_name ();
3716    }
3717  buffer += "\"";
3718  buffer += "\n";
3719
3720  buffer += "macro ";
3721  buffer += package_name;
3722  buffer += "_project_release";
3723  buffer += " \"";
3724  if (p != 0)
3725    {
3726      buffer += p->get_release ();
3727    }
3728  buffer += "\"";
3729}
3730
3731
3732//----------------------------------------------------------
3733static bool same_dirs (const cmt_string& d1, const cmt_string& d2)
3734{
3735  bool result = false;
3736
3737  cmt_string here = CmtSystem::pwd ();
3738
3739  cmt_string h1;
3740  if (CmtSystem::cd (d1)) h1 = CmtSystem::pwd ();
3741
3742  CmtSystem::cd (here);
3743
3744  cmt_string h2;
3745  if (CmtSystem::cd (d2)) h2 = CmtSystem::pwd ();
3746
3747  result = (h1 == h2);
3748
3749  CmtSystem::cd (here);
3750
3751  return (result);
3752}
3753
3754//----------------------------------------------------------
3755static bool install_library (const cmt_string& source_library_name, 
3756                             const cmt_string& dest_library_name, 
3757                             const cmt_string& cmtinstallarea, 
3758                             const cmt_string& tag, 
3759                             const cmt_string& symlinkcmd)
3760{
3761  cmt_string libname = source_library_name;
3762  cmt_string name = dest_library_name;
3763  cmt_string s;
3764  Use& current_use = Use::current ();
3765
3766  Symbol::expand (name);
3767  Symbol::expand (libname);
3768
3769  if (cmtinstallarea != "")
3770    {
3771      s = cmtinstallarea;
3772      s += CmtSystem::file_separator ();
3773      s += tag;
3774      s += CmtSystem::file_separator ();
3775      s += "lib";
3776      s += CmtSystem::file_separator ();
3777      s += name;
3778     
3779      // Now creating the reference file
3780
3781      cmt_string ref_file = s;
3782      ref_file += ".cmtref";
3783
3784      cmt_string text = libname;
3785      text += "\n";
3786
3787      Symbol::expand (ref_file);
3788      Symbol::expand (text);
3789
3790      if (CmtMessage::active (Info))
3791        cerr << "   Creating the reference file " << ref_file << endl;
3792          //      if (!Cmt::get_quiet ()) cerr << "   Creating the reference file " << ref_file << endl;
3793      text.write (ref_file);
3794    }
3795  else
3796    {
3797      if (current_use.style != none_style)
3798        {
3799          s = "../$(";
3800          s += current_use.get_package_name ();
3801          s += "_tag)/";
3802        }
3803      else
3804        {
3805          s = "./";
3806        }
3807      s += name;
3808    }
3809
3810  Symbol::expand (s);
3811
3812  cmt_string source;
3813  cmt_string dest;
3814
3815  CmtSystem::dirname (libname, source);
3816  CmtSystem::dirname (s, dest);
3817
3818  if (same_dirs (source, dest))
3819    {
3820      return (false);
3821    }
3822
3823  //if (!Cmt::get_quiet ())
3824  if (CmtMessage::active (Info))
3825    cerr << "   Symlinking " << libname << " to " << s << endl;
3826
3827  if (symlinkcmd == "")
3828    {
3829      if (!CmtSystem::create_symlink (libname, s))
3830        {
3831          CmtMessage::error ("Cannot create a symbolic link to " + libname);
3832          //      cerr << "#CMT> Cannot create a symbolic link to " << libname << endl;
3833          return (false);
3834        }
3835    }
3836  else
3837    {
3838      cmt_string cmd = symlinkcmd;
3839      cmd += " ";
3840      cmd += libname;
3841      cmd += " ";
3842      cmd += s;
3843     
3844      int status = CmtSystem::execute (cmd);
3845     
3846      if (status != 0)
3847        {
3848          CmtMessage::error ("Cannot create a symbolic link to " + libname);
3849          //      cerr << "#CMT> Cannot create a symbolic link to " << libname << endl;
3850          return (false);
3851        }
3852    }
3853
3854  return (true);
3855}
3856
3857
3858/**
3859   Centralize the construction of library links for this Use.
3860*/
3861void Use::build_library_links (const cmt_string& cmtinstallarea, 
3862                               const cmt_string& tag, 
3863                               const cmt_string& shlibsuffix, 
3864                               const cmt_string& symlinkcmd) const
3865{
3866  if (!located ())
3867    {
3868      CmtMessage::warning ("package " + get_package_name ()
3869                           + " " + version + " " + path
3870                           + " not found");
3871      /*
3872      if (!Cmt::get_quiet ())
3873        {
3874          cerr << "# package " << get_package_name () <<
3875            " " << version << " " << path <<
3876            " not found" <<
3877            endl;
3878        }
3879      */
3880      return;
3881    }
3882
3883  cmt_string s;
3884
3885  s = get_package_name ();
3886  s += "_libraries";
3887
3888  Symbol* libraries_macro = Symbol::find (s);
3889
3890  if (libraries_macro == 0) return;
3891
3892  cmt_string libraries = libraries_macro->build_macro_value ();
3893  Symbol::expand (libraries);
3894  static CmtSystem::cmt_string_vector values;
3895
3896  CmtSystem::split (libraries, " \t", values);
3897
3898  for (int j = 0; j < values.size (); j++)
3899    {
3900      const cmt_string& library = values[j];
3901
3902      static cmt_string libname;
3903      static cmt_string name;
3904
3905      // Is it a simple name or a complete path?
3906
3907      libname = library;
3908      Symbol::expand (libname);
3909
3910      bool is_absolute = false;
3911
3912      is_absolute = CmtSystem::absolute_path (libname);
3913
3914      if (is_absolute)
3915        {
3916          /**
3917           *   We assume here that "library" contains a complete path.
3918           *   (including the complete syntax libxxx.so)
3919           */
3920
3921          cmt_string suffix;
3922          CmtSystem::basename (library, name);
3923        }
3924      else
3925        {
3926          /**
3927           *   Here we expect that only the base name of the library
3928           *   is given : ie it should not contain the "lib" prefix,
3929           *   nor the suffix .so, nor any path prefix.
3930           *    This of course should generally correspond to a constituent name.
3931           */
3932         
3933          if (style != none_style)
3934            {
3935          libname = "${";
3936          libname += prefix;
3937          libname += "ROOT}/${";
3938          libname += get_package_name ();
3939          libname += "_tag}/";
3940            }
3941          else
3942            {
3943          libname = "${";
3944          libname += prefix;
3945          libname += "ROOT}/";
3946            }
3947          libname += "$(library_prefix)";
3948          libname += library;
3949          libname += "$(library_suffix)";
3950          libname += ".";
3951          libname += shlibsuffix;
3952
3953          name = "$(library_prefix)";
3954          name += library;
3955          name += "$(library_suffix)";
3956          name += ".";
3957          name += shlibsuffix;
3958        }
3959
3960      if (!install_library (libname, name, cmtinstallarea, tag, symlinkcmd))
3961        {
3962          continue;
3963        }
3964
3965#ifdef __APPLE__
3966      if (!is_absolute)
3967        {
3968          if (style != none_style)
3969            {
3970          libname = "${";
3971          libname += prefix;
3972          libname += "ROOT}/${";
3973          libname += get_package_name ();
3974          libname += "_tag}/";
3975            }
3976          else
3977            {
3978          libname = "${";
3979          libname += prefix;
3980          libname += "ROOT}/";
3981            }
3982          libname += library;
3983          libname += ".bundle";
3984
3985          name = library;
3986          name += ".bundle";
3987         
3988          if (!install_library (libname, name, cmtinstallarea, tag, symlinkcmd))
3989            {
3990              continue;
3991            }
3992        }
3993#endif
3994    }
3995}
3996
3997/**
3998 *   This function tries to get the replacement of a Use when it has
3999 *  been discarded by a better match to version constraints.
4000 */
4001Use* Use::get_selected_version ()
4002{
4003  if (!discarded) return (this);
4004
4005  Package* p = m_package;
4006
4007  Use::UsePtrVector& uses = p->get_uses ();
4008
4009  bool dbg = Cmt::get_debug ();
4010
4011  int size = uses.size ();
4012
4013  for (int i = 0; i < size; i++)
4014    {
4015      Use* u = uses[i];
4016      if (u == 0) continue;
4017      if (u->discarded) continue;
4018      if (dbg)
4019        {
4020          cout << "Use::get_selected_version> for package " << get_package_name ()
4021               << "  got a version " << u << endl;
4022        }
4023      return (u);
4024    }
4025
4026  return (0);
4027}
4028
4029/**
4030   Switching from one use to another one, (better wrt
4031   various criteria).
4032
4033   When switching, m_index and auto_imports are
4034   transfered from the un-selected to the newly selected.
4035*/
4036Use* Use::set_selected_version (Use* selected_use)
4037{
4038  if (this == selected_use) return (this);
4039
4040  static UsePtrVector& uses = get_ordered_uses ();
4041
4042  if (m_index >= 0)
4043    {
4044      // This discarded package was registered. We have to substitute
4045      // it with the new one.
4046
4047      if (Cmt::get_debug ())
4048        {
4049          cout << "set_selected_version> Replace "
4050               << get_package_name () << "(" << m_index << ")[" << this << "] with "
4051               << selected_use->get_package_name () << "(" << selected_use->m_index << ")[" << selected_use << "]" << endl;
4052        }
4053
4054      selected_use->m_index = m_index;
4055      selected_use->auto_imports = auto_imports;
4056
4057      selected_use->undiscard ();
4058
4059      m_index = -1;
4060
4061      uses[selected_use->m_index] = selected_use;
4062    }
4063
4064  discard ();
4065
4066  return (selected_use);
4067}
4068
4069//----------------------------------------------------------
4070void Use::set_auto_imports (State context_state, State specified_state,
4071                            cmt_map <Use*, bool>& visited)
4072{
4073  static int level (0);
4074  /*
4075  if (level == 0)
4076    {
4077      unselect_all ();
4078      selected = true;
4079    }
4080  */
4081  switch (context_state)
4082    {
4083    case Unspecified:
4084    case On:
4085      if (!visited.has (this) ||
4086          // revisit uses that may be turned into Off != auto_imports
4087          // via some other use(s)
4088          // policy being use has Off != auto_imports,
4089          // if it is (direct) sub-use without -no_auto_imports of
4090          // either current use or sub-use with Off != auto_imports
4091          (Off == auto_imports && Off != specified_state)
4092          )
4093        {
4094          auto_imports = specified_state;
4095          context_state = UseContext::mask_auto_imports (context_state, auto_imports);
4096        }
4097      else
4098        {
4099          return;
4100        }
4101      break;
4102    case Off:
4103      if (visited.has (this))
4104        {
4105          return;
4106        }
4107      auto_imports = context_state;
4108      break;
4109    }
4110
4111  if (Cmt::get_debug ())
4112    {
4113      cout << "Use::set_auto_imports>|";
4114      for (int i = level; i > 0; i--) cout << "-";
4115      cout << get_package_name () << "> " 
4116           << auto_imports << " -> " 
4117           << "(" << context_state << ")" << specified_state << endl;
4118    }
4119
4120  static bool yes (true);
4121  visited.add (this, yes);
4122
4123  cmt_string s;
4124  static const cmt_string state_text[] = {"Unspecified", "Off", "On"};
4125 
4126  if (Cmt::get_debug ())
4127    {
4128      s = "Use::set_auto_imports><";
4129      for (int i = level; i > 0; i--) s += "-";
4130      s += get_package_name ();
4131      s += "|";
4132      //cout << s << endl;
4133    }
4134 
4135  level++;
4136  for (int i = 0; i < sub_uses.size (); i++)
4137  //for (int i = sub_uses.size () - 1; i >= 0; i--)
4138    {
4139      State state = sub_use_auto_imports[i];
4140      if (Cmt::get_debug ())
4141        {
4142          s += " ";
4143          s += sub_uses[i]->get_package_name ();
4144          s += "(";
4145          s += state_text[state + 1];
4146          s += ")";
4147        }
4148      if (sub_uses[i]->m_index >= 0 && !sub_uses[i]->discarded)
4149        {
4150          sub_uses[i]->set_auto_imports (context_state, state, visited);
4151        }
4152      else
4153        {
4154          if (Cmt::get_debug ())
4155            {
4156              char num[32]; sprintf (num, "%p", sub_uses[i]);
4157              char index[32]; sprintf (index, "%d", sub_uses[i]->m_index);
4158              s += "[";
4159              s += num;
4160              s += ", discarded=";
4161              s += (sub_uses[i]->discarded ? "1" : "0");
4162              s += ", m_index=";
4163              s += index;
4164              s += " : invalid]";
4165            }
4166          Use* au (find_valid (sub_uses[i]->get_package_name ()));
4167          if (au)
4168            {
4169              if (Cmt::get_debug ())
4170                {
4171                  char num[32]; sprintf (num, "%p", au);
4172                  char index[32]; sprintf (index, "%d", au->m_index);
4173                  s += "[";
4174                  s += num;
4175                  s += ", discarded=";
4176                  s += (au->discarded ? "1" : "0");
4177                  s += ", m_index=";
4178                  s += index;
4179                  s += " : valid]";
4180                }
4181              au->set_auto_imports (context_state, state, visited);
4182            }
4183          else
4184            {
4185              visited.add (sub_uses[i], yes);
4186            }
4187        }
4188    }
4189  level--;
4190
4191  if (Cmt::get_debug ())
4192    {
4193      cout << s << endl;
4194    }
4195
4196  return;
4197}
4198/*
4199void Use::set_auto_imports (State new_state)
4200{
4201  if (Cmt::get_debug ())
4202    {
4203      cout << "Use::set_auto_imports>(" << get_package_name () << ") "
4204           << auto_imports << " -> " << new_state << endl;
4205    }
4206
4207  if (auto_imports == new_state) return;
4208 
4209  State old_state = auto_imports;
4210 
4211  auto_imports = new_state;
4212
4213  // We propagate only when we switch from Off to On
4214
4215  if ((old_state == Off) && (new_state == On))
4216    {
4217      cmt_string s;
4218      static const cmt_string state_text[] = {"Unspecified", "Off", "On"};
4219
4220      if (Cmt::get_debug ())
4221        {
4222          s = "Use::set_auto_imports>(";
4223          s += get_package_name ();
4224          s += ") ";
4225
4226          cout << s << endl;
4227        }
4228
4229      for (int i = 0; i < sub_uses.size (); i++)
4230        {
4231          Use* u = sub_uses[i];
4232          State state = sub_use_auto_imports[i];
4233         
4234          if (Cmt::get_debug ())
4235            {
4236              s += " ";
4237              s += u->get_package_name ();
4238              s += "(";
4239              s += state_text[state + 1];
4240              s += ")";
4241            }
4242
4243          if (state == Unspecified)
4244            {
4245              u->set_auto_imports (On);
4246            }
4247        }
4248         
4249      if (Cmt::get_debug ())
4250        {
4251          cout << s << endl;
4252        }
4253    }
4254}
4255*/
4256
4257//----------------------------------------------------------
4258void Use::set_native_version (bool state)
4259{
4260  m_has_native_version = state;
4261}
4262
4263bool Use::has_native_version () const
4264{
4265  return (m_has_native_version);
4266}
4267
4268Package* Use::get_package () const
4269{
4270  return (m_package);
4271}
4272
4273const cmt_string& Use::get_package_name () const
4274{
4275  static const cmt_string null = "";
4276
4277  Package* p = m_package;
4278  if (p == 0) return (null);
4279
4280  return (p->get_name ());
4281}
4282
4283void Use::set_package_name (const cmt_string& name)
4284{
4285  Package* p = Package::add (name);
4286
4287  m_package = p;
4288  p->add_use (this);
4289}
4290
4291int Use::get_index () const
4292{
4293  return (m_index);
4294}
4295
4296//----------------------------------------------------------
4297bool Use::get_all_clients (const cmt_string& to_name)
4298{
4299  Use::UsePtrVector& uses = Use::get_ordered_uses ();
4300
4301  Use* use = Use::find (to_name);
4302
4303  if (use == 0)
4304    {
4305      //      CmtMessage::warning ("No access to " + to_name);
4306      return (false);
4307    }
4308
4309  cmt_map <cmt_string, Use*> all_clients;
4310  cmt_map <cmt_string, Use*> all_clients_ok;
4311
4312  const cmt_string& name = get_package_name ();
4313
4314  Use* me = this;
4315
4316  all_clients.add (name, me);
4317  all_clients_ok.add (name, me);
4318
4319  bool status = get_all_clients (use, to_name, all_clients, all_clients_ok); 
4320
4321  return (status);
4322}
4323
4324//----------------------------------------------------------
4325bool Use::get_all_clients (Use* to, 
4326                           const cmt_string& result, 
4327                           cmt_map <cmt_string, Use*>& all_clients, 
4328                           cmt_map <cmt_string, Use*>& all_clients_ok)
4329{
4330  if (this == to)
4331    {
4332      cout << result << endl;
4333      return (true);
4334    }
4335
4336  const cmt_string& to_name = to->get_package_name ();
4337  const cmt_string& to_version = to->version;
4338
4339  //cout << "gac> from " << get_package_name () << " to " << to_name << " -> " << result << endl;
4340
4341  if (all_clients.has (to_name))
4342    {
4343      if (all_clients_ok.has (to_name))
4344        {
4345          cout << "   ..." << result << endl;
4346          return (true);
4347        }
4348      else
4349        {
4350          return (false);
4351        }
4352    }
4353
4354  all_clients.add (to_name, to);
4355
4356  bool status = false;
4357
4358  Use::UsePtrVector& uses = Use::get_ordered_uses ();
4359  Use* use = 0;
4360
4361  for (int n = 0; n < uses.size (); ++n)
4362    {
4363      use = uses[n];
4364
4365      if (use->discarded) continue;
4366      if (use->m_hidden) continue;
4367
4368      if (!use->located ()) continue;
4369
4370      if (use == to) continue;
4371
4372      if (use->is_client (to_name, to_version))
4373        {
4374          const cmt_string& n = use->get_package_name ();
4375
4376          cmt_string r;
4377
4378          if ((use->initial_scope != ScopeUnspecified) &&
4379              (use->initial_scope != ScopePublic)) 
4380            {
4381              r += "(private)";
4382            }
4383         
4384          if (use->auto_imports == Off) r += "(no_auto_imports)";
4385
4386          r += n;
4387          r += ".";
4388          r += result;
4389
4390          //cout << "gac> " << n << " is client of " << to_name << endl;
4391
4392          if (get_all_clients (use, r, all_clients, all_clients_ok))
4393            {
4394              all_clients_ok.add (n, use);
4395              status = true;
4396            }
4397        }
4398    }
4399
4400  use = this;
4401
4402  if (use->is_client (to_name, to_version))
4403    {
4404      const cmt_string& n = use->get_package_name ();
4405     
4406      cmt_string r;
4407
4408      if ((use->initial_scope != ScopeUnspecified) &&
4409          (use->initial_scope != ScopePublic)) 
4410        {
4411          r += "(private)";
4412        }
4413     
4414      if (use->auto_imports == Off) r += "(no_auto_imports)";
4415
4416      r += n;
4417      r += ".";
4418      r += result;
4419     
4420      //cout << "gac> " << n << " is client of " << to_name << endl;
4421     
4422      if (get_all_clients (use, r, all_clients, all_clients_ok))
4423        {
4424          all_clients_ok.add (n, use);
4425          status = true;
4426        }
4427    }
4428
4429  return (status);
4430}
4431
4432/**
4433   Let's consider two packages in the use graph "this" and "to"
4434   This function finds all packages that are reached in between
4435   following all possible paths between "this" and "to"
4436
4437   Result s accumulated into "list"
4438*/
4439bool Use::get_paths (Use* to, UsePtrVector& list)
4440{
4441  bool is_in_path = false;
4442  bool cycle = false;
4443  bool already_in_path = false;
4444  bool dbg = Cmt::get_debug ();
4445
4446  static int level = 0;
4447
4448  int size = 0;
4449
4450  if (level == 0)
4451    {
4452      unselect_all ();
4453      selected = false;
4454    }
4455
4456  if (selected) 
4457    {
4458      /**
4459         If this use is already in the list, we don't duplicate the entry.
4460         (protection duplicate paths in the graph)
4461      */
4462
4463      size = list.size ();
4464
4465      for (int m = 0; m < size; m++)
4466        {
4467          Use* u = list[m];
4468          if (u == this)
4469            {
4470              if (dbg)
4471                {
4472                  for (int lll = 0; lll < level; lll++) cout << "  ";
4473                  cout << "  Use::get_paths." << level << "> try1.2 sub="
4474                       << get_package_name () << " already_in_path " << endl;
4475                }
4476             
4477              return (true);
4478            }
4479        }
4480
4481      return (false);
4482    }
4483
4484  selected = true;
4485
4486  if (dbg)
4487    {
4488      for (int lll = 0; lll < level; lll++) cout << "  ";
4489      cout << "Use::get_paths." << level << ">" << get_package_name ()
4490           << " to=" << to->get_package_name () 
4491           << " list=[";
4492
4493      for (int m = 0; m < list.size (); m++)
4494        {
4495          Use* u = list[m];
4496          cout << u->get_package_name () << " ";
4497        }
4498
4499      cout << "]" << endl;
4500    }
4501
4502  /**
4503     Now "this" is a candidate new entry in the list
4504  */
4505
4506  // First figure out whether 'to' is used by 'this'.
4507
4508  if (this->get_package_name () == to->get_package_name ())
4509    {
4510      // We've reached the goal (for the first time)
4511      is_in_path = true;
4512    }
4513  else
4514    {
4515      /**
4516         Let's scan sub_uses now
4517      */
4518      size = sub_uses.size ();
4519
4520      if (dbg)
4521        {
4522          for (int lll = 0; lll < level; lll++) cout << "  ";
4523          cout << "  Use::get_paths." << level << "> size=" << size << endl;
4524        }
4525
4526      for (int n = 0; n < size; n++)
4527        {
4528          Use* use = sub_uses[n];
4529
4530          if (use == 0) continue;
4531
4532          if (dbg)
4533            {
4534              for (int lll = 0; lll < level; lll++) cout << "  ";
4535              cout << "  Use::get_paths." << level << "> try1 sub="
4536                   << use->get_package_name () << "(" << use << ") " << use->discarded << endl;
4537            }
4538
4539          if (use->discarded)
4540            {
4541              Use* u;
4542
4543              u = use->get_selected_version ();
4544              if (u == 0) 
4545                {
4546                  /**
4547                     No way to find a valid use for this used package.
4548                     Is that a bug?
4549                     Anyway we don't pursue on that branch.
4550                  */
4551                  continue;
4552                }
4553
4554              use = u;
4555            }
4556
4557          if (dbg)
4558            {
4559              for (int lll = 0; lll < level; lll++) cout << "  ";
4560              cout << "  Use::get_paths." << level << "> try2 sub="
4561                   << use->get_package_name () << " " << use->discarded << endl;
4562            }
4563
4564          level++;
4565          bool r = use->get_paths (to, list);
4566          level--;
4567
4568          if (r)
4569            {
4570              is_in_path = true;
4571            }
4572        }
4573    }
4574
4575  if (is_in_path)
4576    {
4577      if (dbg)
4578        {
4579          for (int lll = 0; lll < level; lll++) cout << "  ";
4580          cout << "Use::get_paths." << level << "> push " << get_package_name () << endl;
4581        }
4582      list.push_back (this);
4583    }
4584
4585  return (is_in_path);
4586}
4587
4588//----------------------------------------------------------
4589bool Use::located () const
4590{
4591  return (m_located);
4592}
4593
4594//----------------------------------------------------------
4595void Use::show_sub_uses (cmt_map <Use*, bool>& visited,
4596                         const cmt_string& request, State specified_state,
4597                         bool skip_discarded, ostream& out)
4598//void Use::show_sub_uses (const cmt_string& request, bool skip_discarded, ostream& out)
4599{
4600  if (skip_discarded && discarded) return;
4601  if (m_hidden) return;
4602
4603  Use* current = &(Use::current ());
4604  static State context_state (auto_imports);
4605  static int level (0);
4606
4607  if (level == 0)
4608    {
4609      unselect_all ();
4610      selected = false;
4611    }
4612
4613  if (level > 0)
4614    {
4615      out << "# ";
4616      for (int n = 0; n < (level-1); n++) out << "  ";
4617
4618      if (request == "")
4619        {
4620          out << "use " << get_package_name () << " " << specified_version;
4621
4622          if (this == current) 
4623            {
4624              out << " (current)";
4625            }
4626          else
4627            {
4628              if (specified_path != "") out << " " << specified_path;
4629            }
4630        }
4631      else
4632        {
4633          out << "use " << request;
4634        }
4635
4636      if (version_alias != "")
4637        {
4638          out << " | " << version_alias << " " << path_alias;
4639        }
4640
4641      if (initial_scope == ScopeUnspecified) out << " (unspecified)";
4642      else if (initial_scope != ScopePublic) out << " (private)";
4643
4644      if (specified_state == Off) out << " (no_auto_imports)";
4645      //      if (auto_imports == Off) out << " (no_auto_imports)";
4646
4647      if (structuring_style == without_version_directory) out << " (no_version_directory)";
4648
4649      if (m_has_native_version)
4650        {
4651          cmt_string n = get_package_name ();
4652          n += "_native_version";
4653
4654          Symbol* s = Symbol::find (n);
4655          if (s != 0)
4656            {
4657              cmt_string value = s->resolve_macro_value ();
4658              out << " (native_version=" << value << ")";
4659            }
4660        }
4661
4662      out << endl;
4663    }
4664
4665  //  if (selected) return;
4666  //  selected = true;
4667
4668  State saved_context_state (context_state);
4669
4670  switch (context_state)
4671    {
4672    case Unspecified:
4673    case On:
4674      if (!visited.has (this) ||
4675          !selected)
4676        // selected == true means that
4677        // this use has been shown with its actual auto_imports
4678        // either Off != auto_imports or Off == auto_imports,
4679        // mark selected not to consider use again and thus avoid looping this way
4680        {
4681          switch (specified_state)
4682            {
4683            case Unspecified:
4684            case On:
4685              if (Off != auto_imports)
4686                {
4687                  // this path to use is informative
4688                  // want to revisit sub-uses
4689                  // to possibly find Off != auto_imports paths to them
4690                  selected = true;
4691                }
4692              break;
4693            case Off:
4694              if (Off == auto_imports)
4695                {
4696                  // this path to use is informative
4697                  // no point in revisiting sub-uses
4698                  selected = true;
4699                  if (visited.has (this)) return;
4700                }
4701              else
4702                {
4703                  // this path to use is not informative
4704                  // no point in (re)visiting sub-uses
4705                  return;
4706                }
4707              break;
4708            }
4709          context_state = UseContext::mask_auto_imports (context_state, specified_state);
4710        }
4711      else
4712        {
4713          return;
4714        }
4715      break;
4716    case Off:
4717      if (!visited.has (this) ||
4718          !selected)
4719        {
4720          if (Off == auto_imports)
4721            {
4722              // this path to use is informative
4723              // no point in revisiting sub-uses
4724              selected = true;
4725              if (visited.has (this)) return;
4726            }
4727          else
4728            {
4729              // this path to use is not informative
4730              // no point in (re)visiting sub-uses
4731              return;
4732            }
4733        }
4734      else
4735        {
4736          return;
4737        }
4738      break;
4739    }
4740
4741  static bool yes (true);
4742  visited.add (this, yes);
4743
4744  level++;
4745  for (int i = 0; i < sub_uses.size (); i++)
4746    {
4747      //if (use == 0) continue;
4748      Use* use;
4749      if (sub_uses[i]->m_index >= 0 && !sub_uses[i]->discarded)
4750        {
4751          use = sub_uses[i];
4752        }
4753      else
4754        {
4755          Use* au (find_valid (sub_uses[i]->get_package_name ()));
4756          if (au)
4757            {
4758              use = au;
4759            }
4760          else
4761            {
4762              sub_uses[i]->select ();
4763              visited.add (sub_uses[i], yes);
4764              continue;
4765            }
4766        }
4767
4768      const cmt_string& request = requests[i];
4769
4770      ScopeType saved_scope = use->initial_scope;
4771      //      State saved_state = use->auto_imports;
4772
4773      use->initial_scope = sub_use_scopes[i];
4774      //      use->auto_imports = sub_use_auto_imports[i];
4775
4776      use->show_sub_uses (visited, request, sub_use_auto_imports[i], skip_discarded, out);
4777      //use->show_sub_uses (request, skip_discarded, out);
4778
4779      use->initial_scope = saved_scope;
4780      //      use->auto_imports = saved_state;
4781    }
4782  level--;
4783
4784  context_state = saved_context_state;
4785}
4786
4787//----------------------------------------------------------
4788Use& Use::current ()
4789{
4790  static UseVector& instances = get_instances ();
4791  static Use* current_use = 0;
4792
4793  if ((current_use == 0) || (instances.size () == 0))
4794    {
4795      Use& use_object = instances.add ();
4796      current_use = &use_object;
4797    }
4798
4799  return (*current_use);
4800}
4801
4802//----------------------------------------------------------
4803const Use& Use::const_current ()
4804{
4805  const Use& use = Use::current ();
4806
4807  return (use);
4808}
4809
4810//----------------------------------------------------------
4811Use::UseVector& Use::get_instances ()
4812{
4813  static Database& db = Database::instance ();
4814  static UseVector& instances = db.all_uses ();
4815
4816  return (instances);
4817}
4818
4819//----------------------------------------------------------
4820Use::UsePtrVector& Use::get_ordered_uses ()
4821{
4822  static Database& db = Database::instance ();
4823  static UsePtrVector& uses = db.uses ();
4824
4825  return (uses);
4826}
4827
4828//----------------------------------------------------------
4829
4830//----------------------------------------------------------
4831//
4832//  Check if the specified version is better than the
4833//  current one.
4834//
4835//----------------------------------------------------------
4836Use* BestFitSelector::operate (Use* ref_use, Use* new_use)
4837{
4838  Use* selected = ref_use;
4839
4840  int ref_v = -1;
4841  int ref_r = -1;
4842  int ref_p = -1;
4843  cmt_string ref_pp;
4844
4845  int new_v = -1;
4846  int new_r = -1;
4847  int new_p = -1;
4848  cmt_string new_pp;
4849
4850  int alias_v = -1;
4851  int alias_r = -1;
4852  int alias_p = -1;
4853  cmt_string alias_pp;
4854
4855  enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
4856
4857  // First analyze specified versions
4858  cmt_string ref_version = ref_use->specified_version;
4859  cmt_string new_version = new_use->specified_version;
4860
4861  CmtSystem::is_version_directory (ref_version, ref_v, ref_r, ref_p);
4862  ref_pp = ref_use->path;
4863
4864  CmtSystem::is_version_directory (new_version, new_v, new_r, new_p);
4865  new_pp = new_use->path;
4866
4867  if (new_use->version_alias != "")
4868    {
4869      has_alias = new_has_alias;
4870      CmtSystem::is_version_directory (new_use->version_alias, 
4871                                       alias_v, alias_r, alias_p);
4872      alias_pp = new_use->path_alias;
4873    }
4874  else if (ref_use->version_alias != "")
4875    {
4876      has_alias = ref_has_alias;
4877      CmtSystem::is_version_directory (ref_use->version_alias, 
4878                                       alias_v, alias_r, alias_p);
4879      alias_pp = ref_use->path_alias;
4880    }
4881
4882  ref_use->undiscard ();
4883  new_use->undiscard ();
4884
4885  if (new_v != ref_v)
4886    {
4887      if (has_alias != no_alias)
4888        {
4889          if (has_alias == new_has_alias)
4890            {
4891              new_v = alias_v;
4892              new_r = alias_r;
4893              new_p = alias_p;
4894              new_pp = alias_pp;
4895            }
4896          else if (has_alias == ref_has_alias)
4897            {
4898              ref_v = alias_v;
4899              ref_r = alias_r;
4900              ref_p = alias_p;
4901              ref_pp = alias_pp;
4902            }
4903        }
4904    }
4905
4906  bool ref_v_wildcarded = ((ref_v) == -1);
4907  bool ref_r_wildcarded = ((ref_r) == -1);
4908  bool ref_p_wildcarded = ((ref_p) == -1);
4909
4910  bool ref_v_explicit = !ref_v_wildcarded;
4911  bool ref_r_explicit = !ref_r_wildcarded;
4912  bool ref_p_explicit = !ref_p_wildcarded;
4913
4914  bool new_v_wildcarded = ((new_v) == -1);
4915  bool new_r_wildcarded = ((new_r) == -1);
4916  bool new_p_wildcarded = ((new_p) == -1);
4917
4918  bool new_v_explicit = !new_v_wildcarded;
4919  bool new_r_explicit = !new_r_wildcarded;
4920  bool new_p_explicit = !new_p_wildcarded;
4921
4922  bool verbose = (CmtSystem::getenv ("CMTVERBOSE") != "");
4923
4924  cmt_string ref_vc = ref_v_wildcarded ? "wildcarded" : "explicit";
4925  cmt_string ref_rc = ref_r_wildcarded ? "wildcarded" : "explicit";
4926  cmt_string ref_pc = ref_p_wildcarded ? "wildcarded" : "explicit";
4927 
4928  cmt_string new_vc = new_v_wildcarded ? "wildcarded" : "explicit";
4929  cmt_string new_rc = new_r_wildcarded ? "wildcarded" : "explicit";
4930  cmt_string new_pc = new_p_wildcarded ? "wildcarded" : "explicit";
4931
4932  // Now compute effective version identifiers
4933  CmtSystem::is_version_directory (ref_use->version, ref_v, ref_r, ref_p);
4934  CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
4935
4936  cmt_string new_selected_version = new_use->version;
4937
4938  if (new_v_explicit && ref_v_explicit && (new_v != ref_v))
4939    {
4940      /*
4941        if (verbose && !Cmt::get_quiet ())
4942        {
4943        cerr << "# Required explicit version " << new_version
4944        << " of package " << ref_use->get_package_name ()
4945        << " incompatible with selected explicit version " << ref_version
4946        << endl;
4947        }
4948
4949        CmtError::set (CmtError::version_conflict, "BestFitSelector::operate> ");
4950
4951        if (ref_use != new_use) new_use->discard ();
4952      */
4953
4954      if (new_v > ref_v)
4955        {
4956          if (verbose && !Cmt::get_quiet ())
4957            {
4958              cerr << "# Select " << new_vc << " version " << new_version
4959                   << " of package " << ref_use->get_package_name () 
4960                   << " instead of existing " << ref_vc << " " << ref_version
4961                   << endl;
4962            } 
4963         
4964          if (ref_use != new_use) ref_use->discard ();
4965          selected = new_use;
4966          selected->done = false; // Will read the new requirements
4967        }
4968    }
4969  else if (new_v_wildcarded || ref_v_wildcarded)
4970    {
4971      // at least one of ref or new is wildcarded
4972
4973      //
4974      // we plan to discard new_use, but if it was specified as explicit
4975      // and ref_use was wildcarded then new_use will win !!
4976      //
4977      // So then we'll have to understand where are the wild
4978      // cards... If they are on v or r, then we consider them.
4979      //
4980      //
4981
4982      if (ref_v_wildcarded && new_v_explicit)
4983        {
4984          if ((ref_use->real_path != new_use->real_path) ||
4985              (ref_use->version != new_use->version))
4986            {
4987              if (ref_use != new_use) ref_use->discard ();
4988              selected = new_use;
4989              selected->done = false; // Will read the new requirements
4990
4991              if (verbose && !Cmt::get_quiet ())
4992                {
4993                  cerr << "# Select explicit version " << new_version
4994                       << "(" << new_use->version << ")" 
4995                       << " of package " << ref_use->get_package_name () 
4996                       << " instead of existing wildcarded " << ref_version
4997                       << "(" << ref_use->version << ")" 
4998                       << endl;
4999                }
5000            }
5001          else
5002            {
5003              if (ref_use != new_use) new_use->discard ();
5004              //ref_use->version = new_selected_version;
5005            }
5006        }
5007      else
5008        {
5009          // ref is explicit or new is wildcarded
5010
5011          /*
5012            if (verbose && !Cmt::get_quiet ())
5013            {
5014            cerr << "# keep " << ref_vc << " version " << ref_version
5015            << " of package " << ref_use->get_package_name ()
5016            << " (ignore " << new_vc << " version " << new_version << ")"
5017            << endl;
5018            }
5019          */
5020
5021          if (ref_use != new_use) new_use->discard ();
5022        }
5023    }
5024  else if (new_r_wildcarded || ref_r_wildcarded || (new_r < ref_r))
5025    {
5026      //
5027      // we plan to discard new_use, but if it was specified as explicit
5028      // and ref_use was wildcarded then new_use will win !!
5029      //
5030      // So then we'll have to understand where are the wild
5031      // cards... If they are on v or r, then we consider them.
5032      //
5033      //
5034
5035      if (ref_r_wildcarded && new_r_explicit)
5036        {
5037          // ref has wild card and new has not => new wins
5038
5039          if ((ref_use->real_path != new_use->real_path) ||
5040              (ref_use->version != new_use->version))
5041            {
5042              if (ref_use != new_use) ref_use->discard ();
5043              selected = new_use;
5044              selected->done = false; // Will read the new requirements
5045
5046              if (verbose && !Cmt::get_quiet ())
5047                {
5048                  cerr << "# Select explicit release " << new_version
5049                       << " of package " << ref_use->get_package_name ()
5050                       << " instead of existing wildcarded " << ref_version
5051                       << endl;
5052                } 
5053            }
5054          else
5055            {
5056              // Just adapt version with new one.
5057
5058              if (ref_use != new_use) new_use->discard ();
5059              //ref_use->version = new_selected_version;
5060            }
5061        }
5062      else
5063        {
5064          /*
5065            if (verbose &&!Cmt::get_quiet ())
5066            {
5067            cerr << "# keep " << ref_rc << " release " << ref_version
5068            << " of package " << ref_use->get_package_name ()
5069            << " (ignore " << new_rc << " release " << new_version << ")"
5070            << endl;
5071            }
5072          */
5073
5074          if (ref_use != new_use) new_use->discard ();
5075        }
5076    }
5077  else if (new_r > ref_r)
5078    {
5079      if (verbose && !Cmt::get_quiet ())
5080        {
5081          cerr << "# Select " << new_rc << " release " << new_version
5082               << " of package " << ref_use->get_package_name () 
5083               << " instead of existing " << ref_rc << " " << ref_version
5084               << endl;
5085        } 
5086
5087      if (ref_use != new_use) ref_use->discard ();
5088      selected = new_use;
5089      selected->done = false; // Will read the new requirements
5090    }
5091  else if (new_p_wildcarded || ref_p_wildcarded || (new_p < ref_p))
5092    {
5093      //
5094      // we plan to discard new_use, but if it was specified as explicit
5095      // and ref_use was wildcarded then new_use will win !!
5096      //
5097
5098      if (ref_p_wildcarded && new_p_explicit)
5099        {
5100          if ((ref_use->real_path != new_use->real_path) ||
5101              (ref_use->version != new_use->version))
5102            {
5103              if (ref_use != new_use) ref_use->discard ();
5104              selected = new_use;
5105              selected->done = false; // Will read the new requirements
5106
5107              if (verbose && !Cmt::get_quiet ())
5108                {
5109                  cerr << "# Select explicit patch " << new_version
5110                       << " of package " << ref_use->get_package_name () 
5111                       << " instead of existing wildcarded " << ref_version
5112                       << endl;
5113                }
5114            }
5115          else
5116            {
5117              if (ref_use != new_use) new_use->discard ();
5118              ref_use->version = new_selected_version;
5119            }
5120        }
5121      else
5122        {
5123          /*
5124            if (verbose && !Cmt::get_quiet ())
5125            {
5126            cerr << "# keep " << ref_pc << " patch " << ref_version
5127            << " [" << ref_use->specified_version << "]"
5128            << " of package " << ref_use->get_package_name ()
5129            << " (ignore " << new_pc << " version " << new_version << ")"
5130            << " [" << new_use->specified_version << "]"
5131            << endl;
5132            }
5133          */
5134
5135          if (ref_use != new_use) new_use->discard ();
5136        }
5137    }
5138  else if (new_p > ref_p)
5139    {
5140      if (verbose && !Cmt::get_quiet ())
5141        {
5142          cerr << "# Select " << new_pc << " patch " << new_version
5143               << " of package " << ref_use->get_package_name () 
5144               << " instead of existing " << ref_pc << " " << ref_version
5145               << endl;
5146        }
5147
5148      if (ref_use != new_use) ref_use->discard ();
5149      selected = new_use;
5150      selected->done = false; // Will read the new requirements
5151    }
5152  else if (new_pp != ref_pp) // same version-r-p but from different path
5153    {
5154      if (ref_use != new_use) ref_use->discard ();
5155      selected = new_use;
5156      selected->done = false; // Will read the new requirements
5157    }
5158
5159  return (selected);
5160}
5161
5162
5163//----------------------------------------------------------
5164class VersionReader : public Awk
5165{
5166public:
5167
5168  VersionReader ()
5169  {
5170  }
5171 
5172  const cmt_string& get_version () const
5173  {
5174    return (m_version);
5175  }
5176 
5177  void filter (const cmt_string& line)
5178  {
5179    CmtSystem::cmt_string_vector words;
5180    CmtSystem::split (line, " \t", words);
5181    if (words[0] == "version")
5182      {
5183        m_version = words[1];
5184      }
5185  }
5186 
5187private:
5188  cmt_string m_version;
5189};
5190
5191//----------------------------------------------------------
5192class PackageReader : public Awk
5193{
5194public:
5195
5196  PackageReader ()
5197  {
5198  }
5199 
5200  const cmt_string& get_package () const
5201  {
5202    return (m_package);
5203  }
5204 
5205  void filter (const cmt_string& line)
5206  {
5207    CmtSystem::cmt_string_vector words;
5208    CmtSystem::split (line, " \t", words);
5209    if (words[0] == "package")
5210      {
5211        m_package = words[1];
5212      }
5213  }
5214 
5215private:
5216  cmt_string m_package;
5217};
5218
5219//----------------------------------------------------------
5220Package* Package::find (const cmt_string& name)
5221{
5222  static PackageMap& PackageMap = package_map ();
5223
5224  Package* result = 0;
5225
5226  result = PackageMap.find (name);
5227
5228  return (result);
5229}
5230
5231//----------------------------------------------------------
5232Package* Package::add (const cmt_string& name)
5233{
5234  static PackageVector& Packages = packages ();
5235  static PackageMap& PackageMap = package_map ();
5236
5237  {
5238    Package* package;
5239
5240    package = find (name);
5241    if (package != 0) return (package);
5242  }
5243
5244  Package& package = Packages.add ();
5245  PackageMap.add (name, package);
5246
5247  package.m_name = name;
5248
5249  if (name == "CMT")
5250    {
5251      package.m_is_cmt = true;
5252    }
5253  else if (name == "methods")
5254    {
5255      package.m_is_cmt = true;
5256    }
5257
5258  if (Cmt::get_debug ())
5259    {
5260      cout << "Package::add (" << name << ")" << endl;
5261    }
5262
5263  return (&package);
5264}
5265
5266//----------------------------------------------------------
5267Package::PackageVector& Package::packages ()
5268{
5269  static Database& db = Database::instance ();
5270  static PackageVector& Packages = db.packages ();
5271
5272  return (Packages);
5273}
5274
5275//----------------------------------------------------------
5276Package::PackageMap& Package::package_map ()
5277{
5278  static Database& db = Database::instance ();
5279  static PackageMap& PackageMap = db.package_map ();
5280
5281  return (PackageMap);
5282}
5283
5284//----------------------------------------------------------
5285void Package::clear_all ()
5286{
5287  static PackageVector& Packages = packages ();
5288  static PackageMap& PackageMap = package_map ();
5289
5290  PackageMap.clear ();
5291  Packages.clear ();
5292}
5293
5294//----------------------------------------------------------
5295bool Package::get_version (cmt_string& version, const cmt_string& path)
5296{
5297  cmt_string version_file = path;
5298  version_file += CmtSystem::file_separator ();
5299  version_file += get_version_file_name ();
5300  if (CmtSystem::test_file (version_file))
5301    {
5302      cmt_string v;
5303      if (v.read (version_file))
5304        {
5305          int pos;
5306          pos = v.find ('\n');
5307          if (pos != cmt_string::npos) v.erase (pos);
5308          pos = v.find ('\r');
5309          if (pos != cmt_string::npos) v.erase (pos);
5310          if (v != "")
5311            {
5312              version = v;
5313              return true;
5314            }
5315        }
5316      else
5317        {
5318          CmtMessage::warning ("Could not read `" + version_file + "'.");
5319        }
5320    }
5321
5322  version_file = path;
5323  version_file += CmtSystem::file_separator ();
5324  version_file += "requirements";
5325  cmt_string text;
5326  if (text.read (version_file))
5327    {
5328      VersionReader reader;
5329      reader.run (text);
5330      cmt_string v = reader.get_version ();
5331      if (v != "")
5332        {
5333          version = v;
5334          return true;
5335        }
5336    }
5337  else
5338    {
5339      CmtMessage::warning ("Could not read `" + version_file + "'.");
5340    }
5341
5342  return false;
5343}
5344
5345//----------------------------------------------------------
5346const cmt_string& Package::get_version_file_name ()
5347{
5348  static const cmt_string name = "version.cmt";
5349
5350  return (name);
5351}
5352
5353//----------------------------------------------------------
5354bool Package::get_name (cmt_string& name, const cmt_string& path)
5355{
5356  cmt_string name_file = path;
5357  name_file += CmtSystem::file_separator ();
5358  name_file += "requirements";
5359  cmt_string text;
5360  if (text.read (name_file))
5361    {
5362      PackageReader reader;
5363      reader.run (text);
5364      cmt_string v = reader.get_package ();
5365      if (v != "")
5366        {
5367          name = v;
5368          return true;
5369        }
5370    }
5371  else
5372    {
5373      CmtMessage::warning ("Could not read `" + name_file + "'.");
5374    }
5375
5376  return false;
5377}
5378
5379//----------------------------------------------------------
5380Package::Package () : m_is_cmt (false)
5381{
5382  if (Cmt::get_debug ())
5383    {
5384      cout << "Package::Package" << endl;
5385    }
5386}
5387
5388//----------------------------------------------------------
5389Package::~Package ()
5390{
5391  m_name = "";
5392}
5393
5394//----------------------------------------------------------
5395const cmt_string& Package::get_name () const
5396{
5397  return (m_name);
5398}
5399
5400//----------------------------------------------------------
5401void Package::add_use (Use* use)
5402{
5403  for (int i = 0; i < m_uses.size (); i++)
5404    {
5405      Use* u = m_uses[i];
5406      if (u == use) return;
5407    }
5408
5409  m_uses.push_back (use);
5410}
5411
5412//----------------------------------------------------------
5413void Package::remove_use (Use* use)
5414{
5415  if (Cmt::get_debug ())
5416    {
5417      cout << "Package::remove_use (" << use->get_package_name () << ")" << endl;
5418      cout << "  name=" << m_name
5419           << " uses=" << m_uses.size () << endl;
5420    }
5421
5422  Use::UsePtrVector temp;
5423
5424  temp = m_uses;
5425
5426  m_uses.clear ();
5427
5428  for (int i = 0; i < temp.size (); i++)
5429    {
5430      Use* u = temp[i];
5431      if (u != use)
5432        {
5433          m_uses.push_back (u);
5434        }
5435    }
5436}
5437
5438//----------------------------------------------------------
5439Use::UsePtrVector& Package::get_uses ()
5440{
5441  return (m_uses);
5442}
5443
5444//----------------------------------------------------------
5445bool Package::is_cmt ()
5446{
5447  return (m_is_cmt);
5448}
5449
5450//----------------------------------------------------------
5451static void show_packages ()
5452{
5453  Package::PackageVector& vector = Package::packages ();
5454
5455  int i;
5456  int j;
5457
5458  cout << "### Packages: ";
5459  for (i = 0; i < vector.size (); i++)
5460    {
5461      Package& p = vector[i];
5462      cout << p.get_name () << "[";
5463      Use::UsePtrVector& uses = p.get_uses ();
5464      for (j = 0; j < uses.size (); j++)
5465        {
5466          Use* u = uses[j];
5467          cout << u << ",";
5468        }
5469
5470      cout << "] ";
5471    }
5472  cout << endl;
5473
5474  {
5475    static Use::UsePtrVector& uses = Use::get_ordered_uses ();
5476
5477    cout << "### Uses: ";
5478    for (i = 0; i < uses.size (); i++)
5479      {
5480        Use* u = uses[i];
5481        cout << "[" << u << "]" << u->get_package_name () << " ";
5482      }
5483  }
5484
5485  cout << endl;
5486}
5487
5488//----------------------------------------------------------
5489Project* Use::get_project ()
5490{   
5491  Project* p;
5492  cmt_string cmtpath = "";
5493  cmt_string offset  = "";   
5494  get_cmtpath_and_offset (cmtpath, offset);
5495  p = Project::find_by_cmtpath (cmtpath);
5496  return p;   
5497}
5498
5499//----------------------------------------------------------
5500cmt_string Use::get_info () const
5501{   
5502  return get_package_name () + " " + (version != "" ? version : "*") +
5503    (path != "" ? " " + path : "") ;
5504  //  return get_package_name () + " " + version + (path != "" ? " " + path : "") ;
5505}
5506
5507//----------------------------------------------------------
5508/**
5509 *    Check whether @version@
5510 *    is head version as specified by CMTHEADVERSION symbol/environment variable
5511 *    or equals HEAD|head
5512 */
5513//----------------------------------------------------------
5514bool Use::is_head_version (const cmt_string& version)
5515{
5516  if (!m_head_version.is_valid ())
5517    {
5518      cmt_string s (Symbol::get_env_value ("CMTHEADVERSION"));
5519      static const cmt_string package_template = "<package>";
5520      s.replace_all (package_template, get_package_name ());
5521      static const cmt_string PACKAGE_template = "<PACKAGE>";
5522      s.replace_all (PACKAGE_template, prefix);
5523      static const cmt_string revision_template = "<revision>";
5524      s.replace_all (revision_template.c_str (), "[0-9]*");
5525      if (0 != s.size ())
5526        {
5527          if ('^' != s[0]) s = "^" + s;
5528          if ('$' != s[s.size () - 1]) s = s + "$";
5529        }
5530      else
5531        {
5532          s = "^(HEAD|head)$";
5533        }
5534      m_head_version.set (s);
5535      if (!m_head_version.is_valid ())
5536        {
5537          CmtMessage::warning
5538            (CmtError::get_error_name (CmtError::configuration_error)
5539             + ": CMTHEADVERSION regular expression invalid `" + s + "'");
5540        }
5541    }
5542
5543  return m_head_version.match (version);
5544}
Note: See TracBrowser for help on using the repository browser.