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

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

Import all tags

File size: 51.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "cmt_use.h"
6#include "cmt_system.h"
7#include "cmt_symbol.h"
8#include "cmt_error.h"
9#include "cmt_database.h"
10
11static Use* CurrentUse = 0;
12
13//----------------------------------------------------------
14class VersionSelector
15{
16public:
17  static VersionSelector& instance ();
18
19  virtual Use* operate (Use* ref_use, Use* new_use)
20  {
21    return (ref_use);
22  }
23};
24
25class BestFitSelector : public VersionSelector
26{
27public:
28  Use* operate (Use* ref_use, Use* new_use);
29};
30
31class BestFitNoCheckSelector : public VersionSelector
32{
33public:
34  Use* operate (Use* ref_use, Use* new_use);
35};
36
37class FirstChoiceSelector : public VersionSelector
38{
39public:
40  Use* operate (Use* ref_use, Use* new_use);
41};
42
43class LastChoiceSelector : public VersionSelector
44{
45public:
46  Use* operate (Use* ref_use, Use* new_use);
47};
48
49class KeepAllSelector : public VersionSelector
50{
51public:
52  Use* operate (Use* ref_use, Use* new_use);
53};
54//----------------------------------------------------------
55
56//----------------------------------------------------------
57//
58//  Operations on Use
59//
60//----------------------------------------------------------
61
62//----------------------------------------------------------
63void Use::select_clients (const cmt_string& package,
64                          const cmt_string& version)
65{
66  static UsePtrVector& Uses = uses ();
67
68  int number;
69  Use* use = 0;
70
71  unselect_all ();
72  undiscard_all ();
73
74  for (number = Uses.size () - 1; number >= 0; number--)
75    {
76      use = Uses[number];
77      if (use == 0) continue;
78      if (use->is_selected ()) continue;
79      use->select ();
80      if (!use->is_client (package, version)) use->discard ();
81    }
82}
83
84//----------------------------------------------------------
85void Use::show_all (bool skip_discarded)
86{
87  show_all ("use ", skip_discarded);
88}
89
90//----------------------------------------------------------
91void Use::show_all (const cmt_string& prefix, bool skip_discarded)
92{
93  static UsePtrVector& Uses = uses ();
94
95  Use* use;
96  int number;
97
98  unselect_all ();
99
100  use = &(current ());
101  use->unselect ();
102  if (!Cmt::quiet) use->show_sub_uses (skip_discarded);
103
104  if (Uses.size () > 0)
105    {
106      if (!Cmt::quiet)
107        {
108          cout << "#\n";
109          cout << "# Selection :\n";
110        }
111
112      //
113      //  First move the CMT package to the end of the use set.
114      //  (ie. used by everybody)
115      //
116      use = Use::find ("CMT");
117      Use::move (use);
118
119      for (number = Uses.size () - 1; number >= 0; number--)
120        {
121          use = Uses[number];
122
123          if (use->discarded) continue;
124
125          if (use->real_path == "")
126            {
127              if (!Cmt::quiet)
128                {
129                  cout << "# package " << use->package <<
130                      " " << use->version << " " << use->path << 
131                      " not found" <<
132                      endl;
133                }
134              CmtError::set (CmtError::package_not_found, use->package);
135            }
136          else
137            {
138              cout << prefix << use->package <<
139                " " << use->version <<
140                " " << use->real_path <<
141                endl;
142            }
143        }
144
145      if (Cmt::cmt_home != "")
146        {
147          cout << prefix << CmtSystem::get_home_package () <<
148              " " << Cmt::cmt_home <<
149              endl;
150        }
151
152      if (Cmt::cmt_user_context != "")
153        {
154          cout << prefix << CmtSystem::get_user_context_package () <<
155              " " << Cmt::cmt_user_context <<
156              endl;
157        }
158    }
159}
160
161class use_action_iterator
162{
163public:
164
165  use_action_iterator ()
166      {
167        state = need_package;
168        auto_imports = request_auto_imports;
169      }
170
171  void set (const cmt_string& w)
172      {
173        if (w == "-auto_imports")
174          {
175            auto_imports = request_auto_imports;
176          }
177        else if (w == "-no_auto_imports")
178          {
179            auto_imports = no_auto_imports;
180          }
181        else if (w == "|")
182          {
183            state = need_version_alias;
184          }
185        else
186          {
187            switch (state)
188              {
189                case need_package:
190                  package = w;
191                  state = need_version;
192                  break;
193                case need_version:
194                  version = w;
195                  state = need_path;
196                  break;
197                case need_path:
198                  path = w;
199                  state = finished;
200                  break;
201                case need_version_alias:
202                  version_alias = w;
203                  state = need_path_alias;
204                  break;
205                case need_path_alias:
206                  path_alias = w;
207                  state = finished;
208                  break;
209              }
210          }
211      }
212
213  bool ok ()
214      {
215        if (package == "") return (false);
216        if (CmtSystem::is_home_package (package, version)) return (false);
217        if (CmtSystem::is_user_context_package (package, version)) return (false);
218
219        return (true);
220      }
221
222  Use* get_use (Use* use)
223      {
224        static Use::UsePtrVector& Uses = Use::uses ();
225
226        if (version == "") version = "*";
227
228        if (Cmt::debug)
229          {
230            int i;
231
232            cout << "use::action1> current=" << use->package <<
233                " package=" << package << " ";
234
235            for (i = 0; i < Uses.size (); i++)
236              {
237                Use* use = Uses[i];
238                cout << use->package << " ";
239              }
240            cout << endl;
241          }
242
243        const Use& cu = Use::current ();
244
245        if ((use != 0) && 
246            (use->package != cu.package) &&
247            (Cmt::scope == ScopePrivate))
248          {
249            return (0);
250          }
251
252
253          // Here the version may contain wild cards
254        Use* new_use = Use::add (path, package, version, 
255                                 version_alias, path_alias, use);
256
257        switch (auto_imports)
258          {
259            case keep_auto_imports:
260              break;
261            case request_auto_imports:
262              new_use->auto_imports = true;
263              break;
264            case no_auto_imports:
265              new_use->auto_imports = false;
266              break;
267          }
268
269        Use::reorder (new_use, use);
270
271        if (Cmt::debug)
272          {
273            int i;
274           
275            cout << "use::action2> current=" << use->package <<
276                " package=" << package << " ";
277            for (i = 0; i < Uses.size (); i++)
278              {
279                Use* use = Uses[i];
280                cout << use->package << " ";
281              }
282            cout << endl;
283          }
284
285        return (new_use);
286      }
287
288private:
289
290  enum
291  {
292    need_package,
293    need_version,
294    need_path,
295    need_version_alias,
296    need_path_alias,
297    finished
298  } state;
299 
300  enum
301  {
302    keep_auto_imports,
303    request_auto_imports,
304    no_auto_imports
305  } auto_imports;
306
307  cmt_string package;
308  cmt_string version;
309  cmt_string path;
310  cmt_string version_alias;
311  cmt_string path_alias;
312};
313
314//----------------------------------------------------------
315Use* Use::action (const CmtSystem::cmt_string_vector& words, Use* use)
316{
317  Use* new_use;
318
319  //
320  // complete syntax : "use <package> <version> <path>"
321  // minimal syntax  : "use <package>"
322  //
323  //  o if <version> is omitted then take any version available
324  //  o <version> can be specified using "v*" or "v<n>r*" or "v<n>r<m>p*"
325  //
326  //  o the notation "v*" is preferred to omission (particularly since
327  //    omission does not permit <path>)
328  //
329  if (words.size () < 2) return (0);
330
331  use_action_iterator it;
332
333  for (int i = 1; i < words.size (); i++)
334    {
335      const cmt_string& w = words[i];
336      cmt_string ew = w;
337
338      Symbol::expand (ew);
339      if (ew != w)
340        {
341          CmtSystem::cmt_string_vector ws;
342
343          CmtSystem::split (ew, " ", ws);
344
345          for (int j = 0; j < ws.size (); ++j)
346            {
347              const cmt_string& ww = ws[j];
348              it.set (ww);
349            }
350        }
351      else
352        {
353          it.set (ew);
354        }
355    }
356
357  if (!it.ok ()) return (0);
358
359  static int level = 0;
360
361  level++;
362  new_use = it.get_use (use);
363  level--;
364
365  return (new_use);
366}
367
368//----------------------------------------------------------
369void Use::author_action (const CmtSystem::cmt_string_vector& words)
370{
371  if (author != "") author += "\n";
372  for (int i = 1; i < words.size (); i++)
373    {
374      const cmt_string& w = words[i];
375     
376      if (i > 1) author += " ";
377      author += w;
378    }
379}
380
381//----------------------------------------------------------
382void Use::manager_action (const CmtSystem::cmt_string_vector& words)
383{
384  if (manager != "") manager += "\n";
385  for (int i = 1; i < words.size (); i++)
386    {
387      const cmt_string& w = words[i];
388     
389      if (i > 1) manager += " ";
390      manager += w;
391    }
392}
393
394//----------------------------------------------------------
395Use* Use::find (const cmt_string& package, const cmt_string& version, const cmt_string& path)
396{
397  static UsePtrVector& Uses = uses ();
398  static UseVector& AllUses = all_uses ();
399
400  int use_index;
401
402  if (AllUses.size () == 0) return (0);
403
404  for (use_index = 0; use_index < Uses.size (); use_index++)
405    {
406      Use& use = (*Uses[use_index]);
407
408      if (use.package == package)
409        {
410            // If the version argument is omitted then
411            // take the first registered version
412          if (version == "") return (&use);
413         
414            // Otherwise compare against specified_version and path
415            //if ((use.specified_version == version) &&
416            //  (use.specified_path == path)) return (&use);
417         
418            // what about comparing wild cards?
419
420          if (use.specified_version == version) return (&use);
421        }
422    }
423
424  return (0);
425}
426
427//----------------------------------------------------------
428//
429//  Move use to the end
430//
431//----------------------------------------------------------
432void Use::move (Use* use1)
433{
434  static UsePtrVector& Uses = uses ();
435
436  int use_index;
437  Use* use;
438  int found = 0;
439
440  if (Uses.size () == 0) return;
441  if (use1 == 0) return;
442
443  //
444  // On se positionne sur le pointeur.
445  //
446  for (use_index = 0; use_index < Uses.size (); use_index++)
447    {
448      use = Uses[use_index];
449
450      if (use == use1)
451        {
452          found = 1;
453          break;
454        }
455    }
456
457  if (!found) return;
458
459  //
460  // On deplace tous les pointeurs d'une case en arriere
461  //
462  for (use_index++;
463       use_index < Uses.size ();
464       use_index++)
465    {
466      Uses[use_index - 1] = Uses[use_index];
467    }
468
469  //
470  // use1 est donc replace en derniere position
471  //
472  {
473    Uses[Uses.size () - 1] = use1;
474  }
475}
476
477//----------------------------------------------------------
478void Use::reorder (Use* use1, Use* use2)
479{
480  static UsePtrVector& Uses = uses ();
481
482  int use_index;
483  int index1 = -1;
484  int index2 = -1;
485  Use* use;
486
487  if (Uses.size () == 0) return;
488  if (use1 == use2) return;
489
490  //
491  // First locate the two use objects into the Uses vector.
492  //   -> index1 and index 2
493  //
494  for (use_index = 0; use_index < Uses.size (); use_index++)
495    {
496      use = (Use*) Uses[use_index];
497
498      if (use == use1) index1 = use_index;
499      if (use == use2) index2 = use_index;
500    }
501
502  if (Cmt::debug)
503    {
504      cout << "Use::reorder> 1=" << index1 << " 2=" << index2 << endl;
505    }
506
507  //
508  // Both objects must be installed in Uses before acting.
509  //
510  if (index1 == -1) return;
511  if (index2 == -1) return;
512
513  if (index2 < index1)
514    {
515      //
516      // 2 is already before 1 so job is finished
517      //
518      return;
519    }
520  else
521    {
522      //
523      // before : <aaa 1 bbbb 2 ccc>
524      //
525      //  o move "1 bbbb" by one place to the right
526      // thus : <aaa 1 1 bbbb ccc>
527      //
528      //  o move "2" to [1]
529      //
530      // after  : <aaa 2 1 bbbb ccc>
531      //
532
533      use = use2;
534
535      for (use_index = index2 - 1; use_index >= index1; use_index--)
536        {
537          Uses[use_index + 1] = Uses[use_index];
538        }
539
540      Uses[index1] = use;
541    }
542}
543
544//----------------------------------------------------------
545void Use::clear_all ()
546{
547  static UsePtrVector& Uses = uses ();
548  static UseVector& AllUses = all_uses ();
549
550  int use_index;
551
552  for (use_index = 0; use_index < AllUses.size (); use_index++)
553    {
554      Use& use = AllUses[use_index];
555      use.clear ();
556    }
557
558  Uses.clear ();
559  AllUses.clear ();
560  CurrentUse = 0;
561}
562
563//----------------------------------------------------------
564void Use::unselect_all ()
565{
566  static UsePtrVector& Uses = uses ();
567
568  int use_index;
569
570  if (Uses.size () == 0) return;
571
572  for (use_index = 0; use_index < Uses.size (); use_index++)
573    {
574      Use* use = Uses[use_index];
575
576      if (use != 0)
577        {
578          use->unselect ();
579        }
580    }
581}
582
583//----------------------------------------------------------
584void Use::undiscard_all ()
585{
586  static UsePtrVector& Uses = uses ();
587
588  int use_index;
589
590  if (Uses.size () == 0) return;
591
592  for (use_index = 0; use_index < Uses.size (); use_index++)
593    {
594      Use* use = Uses[use_index];
595
596      if (use != 0)
597        {
598          use->undiscard ();
599        }
600    }
601}
602
603//----------------------------------------------------------
604void Use::fill_macro_all (cmt_string& buffer, const cmt_string& suffix)
605{
606  UsePtrVector& Uses = uses ();
607
608  buffer = "macro_append use_";
609  buffer += suffix;
610  buffer += " \" ";
611  (Use::current()).fill_macro (buffer, suffix);
612
613  for (int number = 0; number < Uses.size (); number++)
614    {
615      Use* use = Uses[number];
616     
617      if (use->package == "CMT") continue;
618      if (use->package == "methods") continue;
619      if (use->discarded) continue;
620      if (!use->auto_imports) continue;
621     
622      use->fill_macro (buffer, suffix);
623    }
624 
625  buffer += "\"";
626}
627
628//----------------------------------------------------------
629Use::Use ()
630{
631  done = false;
632  discarded = false;
633  auto_imports = true;
634
635  clear ();
636}
637
638//----------------------------------------------------------
639Use::Use (const cmt_string& new_package,
640          const cmt_string& new_version,
641          const cmt_string& new_path)
642{
643  auto_imports = true;
644  set (new_package, new_version, new_path);
645}
646
647//----------------------------------------------------------
648Use::~Use ()
649{
650  clear ();
651}
652
653//----------------------------------------------------------
654void Use::clear ()
655{
656  specified_path = "";
657  path      = "";
658  package   = "";
659  version   = "";
660  author    = "";
661  manager   = "";
662  real_path = "";
663
664  prefix    = "";
665  style     = mgr_style;
666  cmt_scope = Cmt::scope;
667  scope     = Cmt::scope;
668  done      = false;
669  discarded = false;
670  selected  = false;
671  auto_imports = true;
672
673  includes.clear ();
674  include_path = "";
675  scripts.clear ();
676  apply_patterns.clear ();
677  ignore_patterns.clear ();
678
679  sub_uses.clear ();
680  alternate_versions.clear ();
681  alternate_paths.clear ();
682
683  version_alias = "";
684  path_alias    = "";
685}
686
687//----------------------------------------------------------
688void Use::set (const cmt_string& new_package,
689               const cmt_string& new_version,
690               const cmt_string& new_path,
691               const cmt_string& new_version_alias,
692               const cmt_string& new_path_alias)
693{
694  clear ();
695
696  package           = new_package;
697  specified_path    = new_path;
698  // specified_path.replace_all ("\\", "/");
699
700  specified_version = new_version;
701  version           = new_version;
702  path              = specified_path;
703  Symbol::expand (path);
704  real_path         = "";
705  style             = mgr_style;
706  cmt_scope         = Cmt::scope;
707  scope             = Cmt::scope;
708  done              = false;
709  discarded         = false;
710  Cmt::build_prefix (new_package, prefix);
711
712  version_alias = new_version_alias;
713  path_alias    = new_path_alias;
714}
715
716//----------------------------------------------------------
717void Use::change_path (const cmt_string& new_path)
718{
719  //
720  // This methods changes real_path after an actual location
721  // where this package/version has been found.
722  //
723
724  real_path = "";
725
726  if (new_path != "")
727    {
728      if ((path.size () > 0) &&
729          (!CmtSystem::absolute_path (path)))
730        {
731          real_path = new_path;
732          real_path += CmtSystem::file_separator ();
733          real_path += path;
734        }
735      else
736        {
737          real_path = new_path;
738        }
739      // real_path.replace_all ("\\", "/");
740    }
741}
742
743//----------------------------------------------------------
744int Use::reach_package (const cmt_string& from_path)
745{
746  //cerr << "Use::reach_package> (" << package << " " << version << ")from " << from_path << endl;
747
748  //
749  // We try to reach a package/version starting from from_path
750  //
751
752  // check if from_path is at least real
753  if ((from_path != "") && !CmtSystem::cd (from_path)) return (0);
754
755  // check in case from_path is a new search path
756  if (from_path != real_path)
757    {
758      // Move to that prefix only if it is a relative path.
759      if ((path.size () > 0) && (!CmtSystem::absolute_path (path)))
760        {
761          if (!CmtSystem::cd (path))
762            {
763              return (0);
764            }
765        }
766    }
767
768  // Special treatment for HOME package...
769  if (package == CmtSystem::get_home_package ())
770    {
771      discarded = 1;
772      if (!CmtSystem::test_file ("requirements"))
773        {
774          return (0);
775        }
776      else
777        {
778          return (1);
779        }
780    }
781
782  // Special treatment for USERCONTEXT package...
783  if (package == CmtSystem::get_user_context_package ())
784    {
785      discarded = 1;
786      if (!CmtSystem::test_file ("requirements"))
787        {
788          return (0);
789        }
790      else
791        {
792          return (1);
793        }
794    }
795
796  // Now from_path exists, try if the package exists there
797  if (!CmtSystem::cd (package))
798    {
799      return (0);
800    }
801
802  if (!CmtSystem::cd (version))
803    {
804      //
805      // The specified version cannot be found per-se
806      // There are alternate possibilities when it contains wild cards
807      //
808      if ((version == "") ||
809          (version.find ("*") != cmt_string::npos))
810        {
811          static CmtSystem::cmt_string_vector versions;
812          static cmt_string name;
813
814          name = ".";
815          name += CmtSystem::file_separator ();
816          if (version == "") name += "*";
817          else name += version;
818
819          CmtSystem::scan_dir (name, versions);
820         
821          int i;
822         
823          for (i = 0; i < versions.size (); i++)
824            {
825              const cmt_string& vers = versions[i];
826             
827              if (Cmt::debug)
828                {
829                  cout << "     ... version " << vers << " exists" << endl;
830                }
831
832              CmtSystem::basename (vers, name);
833             
834              int v;
835              int r;
836              int p;
837             
838              if (CmtSystem::is_version_directory (name, v, r, p))
839                {
840                  /*
841                    This check is not sufficient !! We need to check in addition
842                    that the selected directory is really the start of a true CMT
843                    package (ie with either /mgr/requirements or /cmt/requirements below)
844                  */
845
846                  cmt_string req;
847
848                  req = name;
849                  req += CmtSystem::file_separator ();
850                  req += "mgr";
851                  req += CmtSystem::file_separator ();
852                  req += "requirements";
853
854                  if (!CmtSystem::test_file (req))
855                    {
856                      req = name;
857                      req += CmtSystem::file_separator ();
858                      req += "cmt";
859                      req += CmtSystem::file_separator ();
860                      req += "requirements";
861
862                      if (!CmtSystem::test_file (req)) continue;
863                    }
864
865                  cmt_string& new_v = alternate_versions.add ();
866                  new_v = name;
867                  cmt_string& new_p = alternate_paths.add ();
868                  new_p = from_path;
869                }
870            }
871        }
872
873      //cerr << "  ... end of version scan" << endl;
874
875        //
876        //  We have now the list of possible alternate versions. However
877        // we return that the expected package/version was not found (yet).
878        //
879
880      return (0);
881    }
882
883  //cerr << "  ... version " << version << " exists" << endl;
884
885  // Now we have met the exact specified version!
886  if (!CmtSystem::test_file ("cmt/requirements"))
887    {
888      if (!CmtSystem::test_file ("mgr/requirements"))
889        {
890          return (0);
891        }
892      else
893        {
894          CmtSystem::cd ("mgr");
895          style = mgr_style;
896        }
897    }
898  else
899    {
900      CmtSystem::cd ("cmt");
901      style = cmt_style;
902    }
903
904  return (1);
905}
906
907//----------------------------------------------------------
908bool Use::move_to ()
909{
910  if (real_path != "")
911    {
912      //
913      // The real path where this version/package can be found
914      // has already been resolved. We thus first go there.
915      //
916
917      if (Cmt::debug)
918        {
919          cout << "move_to1> " << real_path << endl;
920        }
921
922      reach_package (real_path);
923      return (true);
924    }
925
926  cmt_string expanded_path = path;
927
928  //
929  // Try here.
930  //
931  if (expanded_path == "")
932    {
933      if (reach_package (""))
934        {
935          if (Cmt::debug)
936            {
937              cout << "move_to2> " << expanded_path << endl;
938            }
939
940          change_path (expanded_path);
941          return (true);
942        }
943    }
944     
945  //
946  // If the path specified in this use is a true absolute path,
947  // then we search the package from there first.
948  //
949  if (CmtSystem::absolute_path (expanded_path))
950    {
951      if (reach_package (expanded_path))
952        {
953          if (Cmt::debug)
954            {
955              cout << "move_to3> " << expanded_path << endl;
956            }
957
958          change_path (expanded_path);
959          return (true);
960        }
961    }
962     
963  //
964  // Second try is among the CMTPATHs
965  //
966     
967  static const CmtSystem::cmt_string_vector& search_path = Cmt::cmt_path;
968  int path_index = 0;
969     
970  for (path_index = 0; path_index < search_path.size (); path_index++)
971    {
972      const cmt_string& next_path = search_path[path_index];
973     
974      if (reach_package (next_path))
975        {
976          if (Cmt::debug)
977            {
978              cout << "move_to4> " << next_path << endl;
979            }
980
981          change_path (next_path);
982          return (true);
983        }
984    }
985 
986  if (select_alternate ()) 
987    {
988      if (Cmt::debug)
989        {
990          cout << "move_to5> " << real_path << endl;
991        }
992
993      return (true);
994    }
995
996  return (false);
997}
998
999//----------------------------------------------------------
1000bool Use::select_alternate ()
1001{
1002  int i;
1003
1004  int v0 = 0;
1005  int r0 = 0;
1006  int p0 = 0;
1007
1008  int v = 0;
1009  int r = 0;
1010  int p = 0;
1011
1012  int selected_index = -1;
1013
1014  for (i = 0; i < alternate_versions.size (); i++)
1015    {
1016      cmt_string& name = alternate_versions[i];
1017
1018        /*
1019      if (CmtSystem::getenv ("CMTTESTUSEWILDCARDS") != "")
1020        {
1021          cout << "select_alternate[" << this << "]> package " << package <<
1022              " sv=" << specified_version <<
1023              " v=" << version <<
1024              " av[" << i << "]=" << name << endl;
1025        }
1026        */
1027
1028      if (i == 0)
1029        {
1030          CmtSystem::is_version_directory (name, v0, r0, p0);
1031          selected_index = 0;
1032        }
1033      else
1034        {
1035          CmtSystem::is_version_directory (name, v, r, p);
1036
1037          if (v > v0)
1038            {
1039              selected_index = i;
1040              v0 = v;
1041              r0 = r;
1042              p0 = p;
1043            }
1044          else if (v == v0)
1045            {
1046              if (r > r0)
1047                {
1048                  selected_index = i;
1049                  r0 = r;
1050                  p0 = p;
1051                }
1052              else if (r == r0)
1053                {
1054                  if (p > p0)
1055                    {
1056                      selected_index = i;
1057                      p0 = p;
1058                    }
1059                }
1060            }
1061        }
1062    }
1063
1064  if (selected_index >= 0)
1065    {
1066      if (CmtSystem::cd (alternate_paths[selected_index]))
1067        {
1068          version = alternate_versions[selected_index];
1069          if (reach_package (alternate_paths[selected_index]))
1070            {
1071                /*
1072              if (CmtSystem::getenv ("CMTTESTUSEWILDCARDS") != "")
1073                {
1074                  cout << "select_alternate2> package " << package <<
1075                      " sv=" << specified_version <<
1076                      " v=" << version << endl;
1077                }
1078                */
1079
1080              if (Cmt::debug)
1081                {
1082                  cout << "select_alternate> " << alternate_paths[selected_index] << endl;
1083                }
1084
1085              change_path (alternate_paths[selected_index]);
1086              return (true);
1087            }
1088        }
1089    }
1090
1091  return (false);
1092}
1093
1094//----------------------------------------------------------
1095bool Use::need_new (const cmt_string& path,
1096                    const cmt_string& package,
1097                    const cmt_string& version,
1098                    Use** old_use)
1099{
1100  Use* use;
1101
1102  // find any possible existing version for that package
1103  use = find (package);
1104  if (old_use != 0) *old_use = use;
1105
1106  if (use == 0)
1107    {
1108      // No version was not found at all
1109      return (true);
1110    }
1111
1112  //cerr << "Use::need_new> (" << package << ") requested version=" << version << " vs existing=" << use->version << " (specified as " << use->specified_version << ")" << endl;
1113
1114  // There was a version. We want to install a priority to the
1115  // explicit specifications over wildcarded ones.
1116  //  So we say that :
1117  //
1118  //    - if the existing spec. was specified as explicit, and the new
1119  //      request is wildcarded, then the new one is discarded.
1120  //
1121  //    - if the existing spec. was specified as wildcarded and the new
1122  //      request is explicit, then the new one wins.
1123  //
1124
1125  if ((version.find ("*") != cmt_string::npos) &&
1126      (use->specified_version.find ("*") == cmt_string::npos))
1127    {
1128      //cerr << "  ... wild card loses against existing specific" << endl;
1129      return (false);
1130    }
1131
1132  if ((version.find ("*") == cmt_string::npos) &&
1133      (use->specified_version.find ("*") != cmt_string::npos))
1134    {
1135      //cerr << "  ... specific should win against existing wildcarded" << endl;
1136      return (true);
1137    }
1138
1139  if (version == use->specified_version)
1140    {
1141      if (path == use->specified_path)
1142        {
1143            // exactly same version and path!
1144          return (false);
1145        }
1146      else
1147        {
1148            // same version but different path.
1149          return (true);
1150        }
1151    }
1152
1153  // at least one version has been found (different from what is requested),
1154  // can we find the exact match ?
1155
1156  use = find (package, version, path);
1157
1158  if (use == 0)
1159    {
1160      // The required version was not found
1161      return (true);
1162    }
1163
1164  if (path != use->specified_path)
1165    {
1166      // The required version was found but on another path
1167      return (true);
1168    }
1169
1170  // The required version was exactly found
1171
1172  return (false);
1173}
1174
1175//----------------------------------------------------------
1176//
1177//  Here the version which is provided here is the specified version.
1178// It may contain wild cards or it may be simply empty.
1179//
1180//----------------------------------------------------------
1181Use* Use::create (const cmt_string& path,
1182                  const cmt_string& package,
1183                  const cmt_string& version,
1184                  const cmt_string& version_alias,
1185                  const cmt_string& path_alias)
1186{
1187  static UseVector& AllUses = all_uses ();
1188
1189  // We first look in the database.
1190  for (int use_index = 0; use_index < AllUses.size (); use_index++)
1191    {
1192      Use& use = AllUses[use_index];
1193
1194      if (use.package == package)
1195        {
1196          if ((use.specified_version == version) && 
1197              (use.specified_path == path)) return (&use);
1198        }
1199    }
1200
1201  // We now really create a new Use entry.
1202
1203  Use& use_object = AllUses.add ();
1204  use_object.set (package, version, path, version_alias, path_alias);
1205
1206  return (&use_object);
1207}
1208
1209//----------------------------------------------------------
1210//  Add a use request into the database.
1211//
1212//  o If a use request already exist in the database,
1213//    check the version compatibility
1214//
1215//----------------------------------------------------------
1216Use* Use::add (const cmt_string& path,
1217               const cmt_string& package,
1218               const cmt_string& version,
1219               const cmt_string& version_alias,
1220               const cmt_string& path_alias,
1221               Use* context_use)
1222{
1223  static UsePtrVector& Uses = uses ();
1224
1225  bool do_need_new = false;
1226
1227  Use* old_use = 0;
1228  Use* use = 0;
1229
1230  do_need_new = need_new (path, package, version, &old_use);
1231
1232  /*
1233    if (old_use != 0)
1234    {
1235    cout << "add> old_use " << old_use->package <<
1236    " " << old_use->version <<
1237    " " << old_use->path <<
1238    endl;
1239    }
1240  */
1241
1242  if (do_need_new)
1243    {
1244      use = create (path, package, version, version_alias, path_alias);
1245    }
1246  else
1247    {
1248      // Since we don't need a new Use, it means that old_use exists !
1249      use = old_use;
1250      old_use = 0;
1251    }
1252
1253  if (package == CmtSystem::get_home_package ())
1254    {
1255      return (use);
1256    }
1257
1258  if (package == CmtSystem::get_user_context_package ())
1259    {
1260      return (use);
1261    }
1262
1263  cmt_string here = CmtSystem::pwd ();
1264
1265    //
1266    // Store the specified sub_uses. Some of them may become discarded
1267    // later on.
1268    //
1269  if (context_use != 0)
1270    {
1271      context_use->sub_uses.push_back (use);
1272    }
1273
1274  bool found = use->move_to ();
1275
1276  if (Cmt::debug)
1277    {
1278      cout << "add> use " << use->package <<
1279          " " << use->version <<
1280          " " << use->path <<
1281          " found=" << found <<
1282          endl;
1283    }
1284     
1285  if (old_use != 0)
1286    {
1287        /*
1288      if (CmtSystem::getenv ("CMTTESTUSEWILDCARDS") != "")
1289      {
1290      cout << "select? [" << use << "] vs old_use[" << old_use << "] " << old_use->package <<
1291      " " << old_use->version <<
1292      " " << old_use->path <<
1293      endl;
1294      }
1295        */
1296
1297      if (use != old_use)
1298        {
1299            //
1300            //  This new version is different from the old one
1301            // thus we have to choose
1302            //
1303          VersionSelector& selector = VersionSelector::instance ();
1304          Use* selected_use = selector.operate (old_use, use);
1305
1306            //
1307            // Some situations managed by selector.operate happen
1308            // to fail discarding the rejected Use.
1309            //
1310          if (use != selected_use) 
1311            {
1312              use->discard ();
1313            }
1314         
1315          use = selected_use;
1316         
1317          found = use->move_to ();
1318        }
1319    }
1320
1321  {
1322    bool registered = false;
1323
1324      //
1325      // A pointer to this new object is also added or replaced.
1326      //
1327    for (int i = 0; i < Uses.size(); i++)
1328      {
1329        Use* u = Uses[i];
1330       
1331        if (u->package == package)
1332          {
1333            registered = true;
1334            Uses[i] = use;
1335            break;
1336          }
1337      }
1338   
1339    if (!registered) Uses.push_back (use);
1340  }
1341
1342    //
1343    // The following statement is no longer considered as useful.
1344    // It is commented. But we should clarify why it was really needed!
1345    //
1346    //use->undiscard ();
1347
1348  if (!found)
1349    {
1350      if (!Cmt::quiet)
1351        {
1352          cout << "# package " << use->package <<
1353              " " << use->version << " " << use->path << 
1354              " not found" <<
1355              endl;
1356        }
1357      CmtError::set (CmtError::package_not_found, use->package);
1358    }
1359 
1360  if (found && !use->done && Cmt::recursive)
1361    {
1362      use->done = true;
1363
1364        /*
1365      if (CmtSystem::getenv ("CMTTESTUSEWILDCARDS") != "")
1366        {
1367          for (int use_index = 0; use_index < Uses.size (); use_index++)
1368            {
1369              Use* u = (Use*) Uses[use_index];
1370              cout << "  use[" << use_index << "] p=" << u->package <<
1371                  " v=" << u->version <<
1372                  " discarded=" << u->discarded <<
1373                  " selected=" << u->selected <<
1374                  endl;
1375            }
1376
1377          cout << "parsing at " << CmtSystem::pwd () << endl;
1378        }
1379        */
1380
1381        /**
1382           Get the previous set of effective use statements
1383           that might have been obtained in a previous build.
1384           This is stored in uses.log. Ignored if file does not exist.
1385        */
1386
1387      //Cmt::parse_requirements ("uses.log", use);
1388
1389      if (Cmt::debug)
1390        {
1391          cout << "Parsing requirements file at " << CmtSystem::pwd () << endl;
1392        }
1393
1394      Cmt::parse_requirements ("requirements", use);
1395    }
1396
1397  CmtSystem::cd (here);
1398
1399  return (use);
1400}
1401
1402//----------------------------------------------------------
1403void Use::discard ()
1404{
1405  discarded = true;
1406}
1407
1408//----------------------------------------------------------
1409void Use::undiscard ()
1410{
1411  discarded = false;
1412}
1413
1414//----------------------------------------------------------
1415void Use::select ()
1416{
1417  selected = true;
1418}
1419
1420//----------------------------------------------------------
1421void Use::unselect ()
1422{
1423  selected = false;
1424}
1425
1426//----------------------------------------------------------
1427bool Use::is_selected ()
1428{
1429  return (selected);
1430}
1431
1432//----------------------------------------------------------
1433bool Use::is_client (const cmt_string& used_package,
1434                     const cmt_string& used_version)
1435{
1436  if ((package == used_package) &&
1437      (version == used_version)) return (true);
1438
1439  if (discarded) return (false);
1440
1441  int i;
1442
1443  for (i = 0; i < sub_uses.size (); i++)
1444    {
1445      Use* use = sub_uses[i];
1446      if (use == 0) continue;
1447
1448      if ((use->package == used_package) &&
1449          (use->version == used_version)) return (true);
1450
1451      /*
1452        if (use->is_client (used_package, used_version))
1453        {
1454        return (true);
1455        }
1456      */
1457    }
1458
1459  return (false);
1460}
1461
1462//----------------------------------------------------------
1463void Use::apply_global_patterns ()
1464{
1465  int i;
1466
1467  Pattern::PatternVector& vector = Pattern::patterns ();
1468
1469  for (i = 0; i < vector.size (); i++)
1470    {
1471      Pattern& p = vector[i];
1472
1473      if (p.global)
1474        {
1475          p.apply (this);
1476        }
1477    }
1478}
1479
1480//----------------------------------------------------------
1481void Use::set_include_path (const cmt_string& new_path)
1482{
1483  include_path = new_path;
1484}
1485
1486//----------------------------------------------------------
1487void Use::fill_includes_macro (cmt_string& buffer) const
1488{
1489  if (include_path == "")
1490    {
1491      buffer += "$(ppcmd)\"$(";
1492      buffer += package;
1493      buffer += "_root)";
1494      buffer += CmtSystem::file_separator ();
1495      buffer += "src\" ";
1496    }
1497  else if (include_path != "none")
1498    {
1499      buffer += "$(ppcmd)\"";
1500      buffer += include_path;
1501      buffer += "\" ";
1502    }
1503 
1504  for (int i = 0; i < includes.size (); i++)
1505    {
1506      Include& incl = includes[i];
1507     
1508      buffer += "$(ppcmd)\"";
1509      buffer += incl.name;
1510      buffer += "\" ";
1511    }
1512}
1513
1514//----------------------------------------------------------
1515void Use::fill_macro (cmt_string& buffer, const cmt_string& suffix) const
1516{
1517  buffer += " $(";
1518  buffer += package;
1519  buffer += "_";
1520  buffer += suffix;
1521  buffer += ") ";
1522}
1523
1524/**
1525 *   This function tries to get the replacement of a Use when it has
1526 *  been discarded by a better match to version constraints.
1527 */
1528Use* Use::get_selected_version ()
1529{
1530  static Use::UsePtrVector& Uses = uses ();
1531
1532    //cout << "get_selected_version for package " << package << endl;
1533
1534  if (!discarded) return (this);
1535
1536  for (int i = 0; i < Uses.size (); i++)
1537    {
1538      Use* u = Uses[i];
1539      if (u == 0) continue;
1540      if (u->discarded) continue;
1541      if (u->package == package) 
1542        {
1543            //cout << "  got a version" << endl;
1544          return (u);
1545        }
1546    }
1547
1548  return (0);
1549}
1550
1551//----------------------------------------------------------
1552bool Use::get_paths (Use* to, UsePtrVector& list)
1553{
1554  bool found = false;
1555  bool cycle = false;
1556
1557  static int level = 0;
1558  static UsePtrVector stack;
1559
1560  if (level == 0)
1561    {
1562      stack.clear ();
1563    }
1564
1565  for (int k = 0; k < stack.size (); k++)
1566    {
1567      Use* u = stack[k];
1568      if (u == this) return (false);
1569    }
1570
1571  if (stack.size () <= level)
1572    {
1573      stack.push_back (this);
1574    }
1575  else
1576    {
1577      stack[level] = this;
1578    }
1579
1580    // First figure out whether 'to' is used by 'this'.
1581
1582  if (Cmt::debug)
1583    {
1584      cout << "Use::get_paths." << level << ">" << package << " list[" << list.size () << "]" << endl;
1585    }
1586
1587  if (this == to)
1588    {
1589      found = true;
1590    }
1591  else
1592    {
1593      for (int n = 0; n < sub_uses.size (); n++)
1594        {
1595          Use* use = sub_uses[n];
1596
1597          if (use == 0) continue;
1598
1599          if (use->discarded)
1600            {
1601              Use* u;
1602
1603              u = use->get_selected_version ();
1604              if (u == 0) continue;
1605
1606              use = u;
1607            }
1608
1609          cycle = false;
1610     
1611            // This use must not be already in the list (protection against cycles)
1612
1613          for (int m = 0; m < list.size (); m++)
1614            {
1615              Use* u = list[m];
1616              if (u == use)
1617                {
1618                  cycle = true;
1619                  break;
1620                }
1621            }
1622
1623          if (cycle) 
1624            {
1625              found = true;
1626              continue;
1627            }
1628
1629          level++;
1630          bool r = use->get_paths (to, list);
1631          level--;
1632
1633          if (r)
1634            {
1635              found = true;
1636            }
1637        }
1638    }
1639
1640  if (found)
1641    {
1642      cycle = false;
1643
1644      for (int m = 0; m < list.size (); m++)
1645        {
1646          Use* u = list[m];
1647          if (u == this)
1648            {
1649              cycle = true;
1650              break;
1651            }
1652        }
1653
1654      if (!cycle)
1655        {
1656          list.push_back (this);
1657        }
1658    }
1659
1660  return (found); 
1661}
1662
1663//----------------------------------------------------------
1664void Use::show_sub_uses (bool skip_discarded)
1665{
1666  int n;
1667  Use* use;
1668  static int level = 0;
1669
1670  if (skip_discarded && discarded) return;
1671
1672  if (level > 0)
1673    {
1674      cout << "# ";
1675      for (n = 0; n < (level-1); n++) cout << "  ";
1676      cout << "use " << package << " " << specified_version;
1677      if (specified_path != "") cout << " " << specified_path;
1678      if (version_alias != "")
1679        {
1680          cout << " | " << version_alias << " " << path_alias;
1681        }
1682      if (scope == ScopeUnspecified) cout << " unspecified";
1683      else if (scope == ScopePublic) cout << " public";
1684      else cout << " private";
1685      cout << endl;
1686    }
1687
1688  if (selected) return;
1689  selected = true;
1690
1691  level++;
1692  for (n = 0; n < sub_uses.size (); n++)
1693    {
1694      use = sub_uses[n];
1695      if (use != 0) use->show_sub_uses (skip_discarded);
1696    }
1697  level--;
1698}
1699
1700//----------------------------------------------------------
1701Use& Use::current ()
1702{
1703  static UseVector& AllUses = all_uses ();
1704
1705  if (CurrentUse == 0)
1706    {
1707      Use& use_object = AllUses.add ();
1708      CurrentUse = &use_object;
1709    }
1710
1711  return (*CurrentUse);
1712}
1713
1714//----------------------------------------------------------
1715const Use& Use::const_current ()
1716{
1717  static UseVector& AllUses = all_uses ();
1718
1719  if (CurrentUse == 0)
1720    {
1721      Use& use_object = AllUses.add ();
1722      CurrentUse = &use_object;
1723    }
1724
1725  const Use& use = *CurrentUse;
1726
1727  return (use);
1728}
1729
1730//----------------------------------------------------------
1731Use::UseVector& Use::all_uses ()
1732{
1733  static Database& db = Database::instance ();
1734  static UseVector& AllUses = db.all_uses ();
1735
1736  return (AllUses);
1737}
1738
1739//----------------------------------------------------------
1740Use::UsePtrVector& Use::uses ()
1741{
1742  static Database& db = Database::instance ();
1743  static UsePtrVector& Uses = db.uses ();
1744
1745  return (Uses);
1746}
1747
1748//----------------------------------------------------------
1749VersionSelector& VersionSelector::instance ()
1750{
1751  static BestFitSelector best_fit;
1752  static BestFitNoCheckSelector best_fit_no_check;
1753  static FirstChoiceSelector first_choice;
1754  static LastChoiceSelector last_choice;
1755  static KeepAllSelector keep_all;
1756
1757  switch (Cmt::current_strategy)
1758    {
1759    case BestFit:
1760      return (best_fit);
1761    case BestFitNoCheck:
1762      return (best_fit_no_check);
1763    case FirstChoice:
1764      return (first_choice);
1765    case LastChoice:
1766      return (last_choice);
1767    case KeepAll:
1768      return (keep_all);
1769    default:
1770      return (best_fit);
1771    }
1772}
1773
1774//----------------------------------------------------------
1775//
1776//  Check if the specified version is better than the
1777//  current one.
1778//
1779//----------------------------------------------------------
1780Use* BestFitSelector::operate (Use* ref_use, Use* new_use)
1781{
1782  Use* selected = ref_use;
1783
1784  int old_v = -1;
1785  int old_r = -1;
1786  int old_p = -1;
1787  cmt_string old_pp;
1788
1789  int new_v = -1;
1790  int new_r = -1;
1791  int new_p = -1;
1792  cmt_string new_pp;
1793
1794  int alias_v = -1;
1795  int alias_r = -1;
1796  int alias_p = -1;
1797  cmt_string alias_pp;
1798
1799  enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
1800
1801  CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
1802  old_pp = ref_use->path;
1803
1804  CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
1805  new_pp = new_use->path;
1806
1807  if (new_use->version_alias != "")
1808    {
1809      has_alias = new_has_alias;
1810      CmtSystem::is_version_directory (new_use->version_alias, 
1811                                       alias_v, alias_r, alias_p);
1812      alias_pp = new_use->path_alias;
1813    }
1814  else if (ref_use->version_alias != "")
1815    {
1816      has_alias = ref_has_alias;
1817      CmtSystem::is_version_directory (ref_use->version_alias, 
1818                                       alias_v, alias_r, alias_p);
1819      alias_pp = ref_use->path_alias;
1820    }
1821
1822  ref_use->undiscard ();
1823  new_use->undiscard ();
1824
1825  if (new_v != old_v)
1826    {
1827      if (has_alias != no_alias)
1828        {
1829          if (has_alias == new_has_alias)
1830            {
1831              new_v = alias_v;
1832              new_r = alias_r;
1833              new_p = alias_p;
1834              new_pp = alias_pp;
1835            }
1836          else if (has_alias == ref_has_alias)
1837            {
1838              old_v = alias_v;
1839              old_r = alias_r;
1840              old_p = alias_p;
1841              old_pp = alias_pp;
1842            }
1843        }
1844    }
1845
1846  if (new_v != old_v)
1847    {
1848      if (!Cmt::quiet)
1849        cout << "# Required version " << new_use->version <<
1850          " of package " << ref_use->package <<
1851          " incompatible with selected version " << ref_use->version <<
1852          endl;
1853
1854      CmtError::set (CmtError::version_conflict, "BestFitSelector::operate> ");
1855
1856      if (ref_use != new_use) new_use->discard ();
1857    }
1858  else if (new_r < old_r)
1859    {
1860      //
1861      // we plan to discard new_use, but if it was specified as explicit
1862      // and ref_use was wildcarded then new_use will win !!
1863      //
1864      // So then we'll have to understand where are the wild
1865      // cards... If they are on v or r, then we consider them.
1866      //
1867      //
1868
1869
1870      bool new_is_wildcarded = false;
1871      bool ref_is_wildcarded = false;
1872
1873      if (new_use->specified_version.find ("*") != cmt_string::npos)
1874        {
1875          int nv = -1;
1876          int nr = -1;
1877          int np = -1;
1878
1879          CmtSystem::is_version_directory (new_use->specified_version, nv, nr, np);
1880          if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
1881        }
1882
1883      if (ref_use->specified_version.find ("*") != cmt_string::npos)
1884        {
1885          int nv = -1;
1886          int nr = -1;
1887          int np = -1;
1888
1889          CmtSystem::is_version_directory (ref_use->specified_version, nv, nr, np);
1890          if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
1891        }
1892
1893      if (!ref_is_wildcarded && new_is_wildcarded)
1894        {
1895          if (ref_use != new_use) ref_use->discard ();
1896          selected = new_use;
1897          selected->done = false; // Will read the new requirements
1898        }
1899      else
1900        {
1901          if (!Cmt::quiet)
1902            cout << "# keep release " << ref_use->version <<
1903              " of package " << ref_use->package <<
1904              " (ignore release " << new_use->version << ")" <<
1905              endl;
1906
1907          if (ref_use != new_use) new_use->discard ();
1908        }
1909    }
1910  else if (new_r > old_r)
1911    {
1912      if (!Cmt::quiet)
1913        {
1914          cout << "# Select release " << new_use->version <<
1915            " of package " << ref_use->package <<
1916            " instead of existing " << ref_use->version <<
1917            endl;
1918        }
1919
1920      if (ref_use != new_use) ref_use->discard ();
1921      selected = new_use;
1922      selected->done = false; // Will read the new requirements
1923    }
1924  else if (new_p > old_p)
1925    {
1926      if (!Cmt::quiet)
1927        {
1928          cout << "# Select patch " << new_use->version <<
1929            " of package " << ref_use->package <<
1930            " instead of existing " << ref_use->version <<
1931            endl;
1932        }
1933
1934      if (ref_use != new_use) ref_use->discard ();
1935      selected = new_use;
1936      selected->done = false; // Will read the new requirements
1937    }
1938  else if (new_pp != old_pp) // same version-r-p but from different path
1939    {
1940      if (ref_use != new_use) ref_use->discard ();
1941      selected = new_use;
1942      selected->done = false; // Will read the new requirements
1943    }
1944
1945  return (selected);
1946}
1947
1948//----------------------------------------------------------
1949//
1950//  Check if the specified version is better than the
1951//  current one. We don't check major ids incompatibilities
1952//
1953//----------------------------------------------------------
1954Use* BestFitNoCheckSelector::operate (Use* ref_use, Use* new_use)
1955{
1956  Use* selected = ref_use;
1957
1958  int old_v = -1;
1959  int old_r = -1;
1960  int old_p = -1;
1961  cmt_string old_pp;
1962
1963  int new_v = -1;
1964  int new_r = -1;
1965  int new_p = -1;
1966  cmt_string new_pp;
1967
1968  int alias_v = -1;
1969  int alias_r = -1;
1970  int alias_p = -1;
1971  cmt_string alias_pp;
1972
1973  enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
1974
1975  CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
1976  old_pp = ref_use->path;
1977
1978  CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
1979  new_pp = new_use->path;
1980
1981  if (new_use->version_alias != "")
1982    {
1983      has_alias = new_has_alias;
1984      CmtSystem::is_version_directory (new_use->version_alias, 
1985                                       alias_v, alias_r, alias_p);
1986      alias_pp = new_use->path_alias;
1987    }
1988  else if (ref_use->version_alias != "")
1989    {
1990      has_alias = ref_has_alias;
1991      CmtSystem::is_version_directory (ref_use->version_alias, 
1992                                       alias_v, alias_r, alias_p);
1993      alias_pp = ref_use->path_alias;
1994    }
1995
1996  ref_use->undiscard ();
1997  new_use->undiscard ();
1998
1999  if (new_v != old_v)
2000    {
2001      if (has_alias != no_alias)
2002        {
2003          if (has_alias == new_has_alias)
2004            {
2005              new_v = alias_v;
2006              new_r = alias_r;
2007              new_p = alias_p;
2008              new_pp = alias_pp;
2009            }
2010          else if (has_alias == ref_has_alias)
2011            {
2012              old_v = alias_v;
2013              old_r = alias_r;
2014              old_p = alias_p;
2015              old_pp = alias_pp;
2016            }
2017        }
2018    }
2019
2020  if (new_v < old_v)
2021    {
2022      if (!Cmt::quiet)
2023        {
2024          cout << "# Keep version " << ref_use->version <<
2025            " of package " << ref_use->package <<
2026            " (ignore version " << new_use->version << ")" <<
2027            endl;
2028        }
2029
2030      if (ref_use != new_use) new_use->discard ();
2031    }
2032  else if (new_v > old_v)
2033    {
2034      if (!Cmt::quiet)
2035        {
2036          cout << "# Select version " << new_use->version <<
2037            " of package " << ref_use->package <<
2038            " instead of existing " << ref_use->version <<
2039            endl;
2040        }
2041
2042      if (ref_use != new_use) ref_use->discard ();
2043      selected = new_use;
2044      selected->done = false; // Will read the new requirements
2045    }
2046  else if (new_r < old_r)
2047    {
2048      if (!Cmt::quiet)
2049        {
2050          cout << "# keep release " << ref_use->version <<
2051            " of package " << ref_use->package <<
2052            " (ignore release " << new_use->version << ")" <<
2053            endl;
2054        }
2055
2056      if (ref_use != new_use) new_use->discard ();
2057    }
2058  else if (new_r > old_r)
2059    {
2060      if (!Cmt::quiet)
2061        {
2062          cout << "# Select release " << new_use->version <<
2063            " of package " << ref_use->package <<
2064            " instead of existing " << ref_use->version <<
2065            endl;
2066        }
2067
2068      if (ref_use != new_use) ref_use->discard ();
2069      selected = new_use;
2070      selected->done = false; // Will read the new requirements
2071    }
2072  else if (new_p > old_p)
2073    {
2074      if (!Cmt::quiet)
2075        {
2076          cout << "# Select patch " << new_use->version <<
2077            " of package " << ref_use->package <<
2078            " instead of existing " << ref_use->version <<
2079            endl;
2080        }
2081
2082      if (ref_use != new_use) ref_use->discard ();
2083      selected = new_use;
2084      selected->done = false; // Will read the new requirements
2085    }
2086  else if (new_pp != old_pp) // same version-r-p but from different path
2087    {
2088      if (ref_use != new_use) ref_use->discard ();
2089      selected = new_use;
2090      selected->done = false; // Will read the new requirements
2091    }
2092
2093  return (selected);
2094}
2095
2096//----------------------------------------------------------
2097Use* FirstChoiceSelector::operate (Use* ref_use, Use* new_use)
2098{
2099  ref_use->undiscard ();
2100  new_use->undiscard ();
2101
2102  new_use->done = false; // Will read the new requirements
2103  if (ref_use != new_use) new_use->discard ();
2104  return (ref_use);
2105}
2106
2107//----------------------------------------------------------
2108Use* LastChoiceSelector::operate (Use* ref_use, Use* new_use)
2109{
2110  ref_use->undiscard ();
2111  new_use->undiscard ();
2112
2113  new_use->done = false; // Will read the new requirements
2114  if (ref_use != new_use) ref_use->discard ();
2115  return (new_use);
2116}
2117
2118//----------------------------------------------------------
2119Use* KeepAllSelector::operate (Use* ref_use, Use* new_use)
2120{
2121  ref_use->undiscard ();
2122  new_use->undiscard ();
2123
2124  new_use->done = false; // Will read the new requirements
2125  return (new_use);
2126}
Note: See TracBrowser for help on using the repository browser.