00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 #include "cmt_use.h"
00006 #include "cmt_system.h"
00007 #include "cmt_symbol.h"
00008 #include "cmt_error.h"
00009 #include "cmt_database.h"
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 class UseContext
00027 {
00028 public:
00029
00030 static UseContext& current ()
00031 {
00032 static UseContext me;
00033
00034 return (me);
00035 }
00036
00037 UseContext ()
00038 {
00039 m_auto_imports = On;
00040 m_scope = ScopePublic;
00041 }
00042
00043 UseContext (const UseContext& other)
00044 {
00045 m_auto_imports = other.m_auto_imports;
00046 m_scope = other.m_scope;
00047 }
00048
00049 UseContext& operator = (const UseContext& other)
00050 {
00051 m_auto_imports = other.m_auto_imports;
00052 m_scope = other.m_scope;
00053
00054 return (*this);
00055 }
00056
00057 static void set_current (State auto_imports)
00058 {
00059 UseContext& c = current ();
00060
00061 c.m_auto_imports = auto_imports;
00062 }
00063
00064 static void set_current (ScopeType scope)
00065 {
00066 UseContext& c = current ();
00067
00068 c.m_scope = scope;
00069 }
00070
00071 static State get_current_auto_imports ()
00072 {
00073 UseContext& c = current ();
00074
00075 return (c.m_auto_imports);
00076 }
00077
00078 static ScopeType get_current_scope ()
00079 {
00080 UseContext& c = current ();
00081
00082 return (c.m_scope);
00083 }
00084
00085 private:
00086 State m_auto_imports;
00087 ScopeType m_scope;
00088 };
00089
00097 class VersionSelector
00098 {
00099 public:
00100 static VersionSelector& instance ();
00101
00102 virtual Use* operate (Use* ref_use, Use* new_use)
00103 {
00104 return (ref_use);
00105 }
00106 };
00107
00108 class BestFitSelector : public VersionSelector
00109 {
00110 public:
00111 Use* operate (Use* ref_use, Use* new_use);
00112 };
00113
00114 class BestFitNoCheckSelector : public VersionSelector
00115 {
00116 public:
00117 Use* operate (Use* ref_use, Use* new_use);
00118 };
00119
00120 class FirstChoiceSelector : public VersionSelector
00121 {
00122 public:
00123 Use* operate (Use* ref_use, Use* new_use);
00124 };
00125
00126 class LastChoiceSelector : public VersionSelector
00127 {
00128 public:
00129 Use* operate (Use* ref_use, Use* new_use);
00130 };
00131
00132 class KeepAllSelector : public VersionSelector
00133 {
00134 public:
00135 Use* operate (Use* ref_use, Use* new_use);
00136 };
00137
00138
00139
00140
00141
00142
00143
00144
00148 void Use::select_clients (const cmt_string& package,
00149 const cmt_string& version)
00150 {
00151 static UsePtrVector& Uses = uses ();
00152
00153 int number;
00154 Use* use = 0;
00155
00156 unselect_all ();
00157 undiscard_all ();
00158
00159 for (number = Uses.size () - 1; number >= 0; number--)
00160 {
00161 use = Uses[number];
00162 if (use == 0) continue;
00163 if (use->is_selected ()) continue;
00164 use->select ();
00165 if (!use->is_client (package, version)) use->discard ();
00166 }
00167 }
00168
00169
00170 void Use::show_all (bool skip_discarded)
00171 {
00172 show_all ("use ", skip_discarded);
00173 }
00174
00175
00176 void Use::show_all (const cmt_string& prefix, bool skip_discarded)
00177 {
00178 static UsePtrVector& Uses = uses ();
00179
00180 Use* use;
00181 int number;
00182
00183 unselect_all ();
00184
00185 use = &(current ());
00186 use->unselect ();
00187 if (!Cmt::get_quiet ()) use->show_sub_uses (skip_discarded);
00188
00189 if (Uses.size () > 0)
00190 {
00191 if (!Cmt::get_quiet ())
00192 {
00193 cout << "#\n";
00194 cout << "# Selection :\n";
00195 }
00196
00197
00198
00199
00200
00201 use = Use::find ("CMT");
00202 Use::move (use);
00203
00204 for (number = Uses.size () - 1; number >= 0; number--)
00205 {
00206 use = Uses[number];
00207
00208 if (use->discarded) continue;
00209
00210 if (!use->located ())
00211 {
00212 if (!Cmt::get_quiet ())
00213 {
00214 cout << "# package " << use->package <<
00215 " " << use->version << " " << use->path <<
00216 " not found" <<
00217 endl;
00218 }
00219 CmtError::set (CmtError::package_not_found, use->package);
00220 }
00221 else
00222 {
00223 static const cmt_string empty;
00224 cmt_string p = use->real_path;
00225 if (use->path != "")
00226 {
00227 p.replace (use->path, empty);
00228 }
00229
00230 cout << prefix << use->package <<
00231 " " << use->version <<
00232 " " << use->path;
00233
00234 if (!Cmt::get_quiet ())
00235 {
00236 if (p != "") cout << " (" << p << ")";
00237 if (use->auto_imports == Off) cout << " (no_auto_imports)";
00238 }
00239
00240 cout << endl;
00241 }
00242 }
00243
00244 if (Cmt::get_cmt_home () != "")
00245 {
00246 cout << prefix << CmtSystem::get_home_package () <<
00247 " " << Cmt::get_cmt_home () <<
00248 endl;
00249 }
00250
00251 if (Cmt::get_cmt_user_context () != "")
00252 {
00253 cout << prefix << CmtSystem::get_user_context_package () <<
00254 " " << Cmt::get_cmt_user_context () <<
00255 endl;
00256 }
00257 }
00258 }
00259
00266 class use_action_iterator
00267 {
00268 public:
00269
00270 use_action_iterator ()
00271 {
00272 state = need_package;
00273 auto_imports = Unspecified;
00274 }
00275
00276 void set (const cmt_string& w)
00277 {
00278 if (w == "-auto_imports")
00279 {
00280 auto_imports = On;
00281 }
00282 else if (w == "-no_auto_imports")
00283 {
00284 auto_imports = Off;
00285 }
00286 else if (w == "|")
00287 {
00288 state = need_version_alias;
00289 }
00290 else
00291 {
00292 switch (state)
00293 {
00294 case need_package:
00295 package = w;
00296 state = need_version;
00297 break;
00298 case need_version:
00299 version = w;
00300 state = need_path;
00301 break;
00302 case need_path:
00303 path = w;
00304 state = finished;
00305 break;
00306 case need_version_alias:
00307 version_alias = w;
00308 state = need_path_alias;
00309 break;
00310 case need_path_alias:
00311 path_alias = w;
00312 state = finished;
00313 break;
00314 }
00315 }
00316 }
00317
00318 bool ok ()
00319 {
00320 if (package == "") return (false);
00321 if (CmtSystem::is_home_package (package, version)) return (false);
00322 if (CmtSystem::is_user_context_package (package, version)) return (false);
00323
00324 return (true);
00325 }
00326
00332 Use* get_use (Use* parent)
00333 {
00334 static Use::UsePtrVector& Uses = Use::uses ();
00335
00336 if (version == "") version = "*";
00337
00338 if (Cmt::get_debug ())
00339 {
00340 int i;
00341
00342 cout << "use::action1> current=" << parent->package <<
00343 " package=" << package << " ";
00344
00345 for (i = 0; i < Uses.size (); i++)
00346 {
00347 Use* u = Uses[i];
00348 cout << u->package << " ";
00349 }
00350 cout << endl;
00351 }
00352
00353 const Use& cu = Use::current ();
00354
00364 ActionType action = Cmt::get_action ();
00365
00366 if ((parent != 0) &&
00367 (parent->package != cu.package) &&
00368 (Cmt::get_scope () == ScopePrivate) &&
00369 (action != action_broadcast) &&
00370 (action != action_show_uses))
00371 {
00372 return (0);
00373 }
00374
00375
00376
00377 UseContext save = UseContext::current ();
00378
00379 if (Cmt::get_debug ())
00380 {
00381 cout << "before adding " << package <<"> auto_imports=" << auto_imports
00382 << " (current was " << UseContext::get_current_auto_imports () << ")"
00383 << " (Cmt::scope=" << Cmt::get_scope () << ")"
00384 << endl;
00385 }
00386
00391 switch (auto_imports)
00392 {
00393 case Unspecified:
00394
00395
00396
00397 UseContext::set_current (UseContext::get_current_auto_imports ());
00398 break;
00399 case Off:
00400
00401
00402
00403 UseContext::set_current (Off);
00404 break;
00405 case On:
00406
00407
00408
00409
00410 if (UseContext::get_current_auto_imports () != Off)
00411 {
00412 UseContext::set_current (On);
00413 }
00414 break;
00415 }
00416
00417
00418 UseContext::set_current (Cmt::get_scope ());
00419
00421 Use* new_use = Use::add (path, package, version,
00422 version_alias, path_alias, parent,
00423 auto_imports);
00424
00425 if (new_use != 0)
00426 {
00427 if (Cmt::get_debug ())
00428 {
00429 cout << "after adding1 " << package << "> auto_imports=" << new_use->auto_imports << endl;
00430 }
00431
00432 switch (new_use->auto_imports)
00433 {
00434 case Unspecified:
00435 new_use->auto_imports = UseContext::get_current_auto_imports ();
00436 break;
00437 case On:
00438 break;
00439 case Off:
00440 if (UseContext::get_current_auto_imports () == On)
00441 {
00453
00454 new_use->set_auto_imports (On);
00455 }
00456 break;
00457 }
00458
00459
00460 if (Cmt::get_debug ())
00461 {
00462 cout << "after adding2 " << package << "> auto_imports=" << new_use->auto_imports << endl;
00463 }
00464
00465 UseContext& c = UseContext::current ();
00466 c = save;
00467
00468 Use::reorder (new_use, parent);
00469
00470 if (Cmt::get_debug ())
00471 {
00472 int i;
00473
00474 cout << "use::action2> current=" << parent->package
00475 << " package=" << package << " ";
00476
00477 for (i = 0; i < Uses.size (); i++)
00478 {
00479 Use* u = Uses[i];
00480 cout << u->package << " ";
00481 }
00482
00483 cout << endl;
00484 }
00485 }
00486
00487 return (new_use);
00488 }
00489
00490 private:
00491
00492 enum
00493 {
00494 need_package,
00495 need_version,
00496 need_path,
00497 need_version_alias,
00498 need_path_alias,
00499 finished
00500 } state;
00501
00502 State auto_imports;
00503
00504 cmt_string package;
00505 cmt_string version;
00506 cmt_string path;
00507 cmt_string version_alias;
00508 cmt_string path_alias;
00509 };
00510
00511
00512 Use* Use::action (const CmtSystem::cmt_string_vector& words, Use* parent)
00513 {
00514 Use* new_use;
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 if (words.size () < 2) return (0);
00527
00528 use_action_iterator it;
00529
00530 for (int i = 1; i < words.size (); i++)
00531 {
00532 const cmt_string& w = words[i];
00533 cmt_string ew = w;
00534
00535 Symbol::expand (ew);
00536 if (ew != w)
00537 {
00538 CmtSystem::cmt_string_vector ws;
00539
00540 CmtSystem::split (ew, " ", ws);
00541
00542 for (int j = 0; j < ws.size (); ++j)
00543 {
00544 const cmt_string& ww = ws[j];
00545 it.set (ww);
00546 }
00547 }
00548 else
00549 {
00550 it.set (ew);
00551 }
00552 }
00553
00554 if (!it.ok ()) return (0);
00555
00556 static int level = 0;
00557
00558 level++;
00559 new_use = it.get_use (parent);
00560 level--;
00561
00562 return (new_use);
00563 }
00564
00565
00566 void Use::author_action (const CmtSystem::cmt_string_vector& words)
00567 {
00568 if (author != "") author += "\n";
00569 for (int i = 1; i < words.size (); i++)
00570 {
00571 const cmt_string& w = words[i];
00572
00573 if (i > 1) author += " ";
00574 author += w;
00575 }
00576 }
00577
00578
00579 void Use::manager_action (const CmtSystem::cmt_string_vector& words)
00580 {
00581 if (manager != "") manager += "\n";
00582 for (int i = 1; i < words.size (); i++)
00583 {
00584 const cmt_string& w = words[i];
00585
00586 if (i > 1) manager += " ";
00587 manager += w;
00588 }
00589 }
00590
00591
00592 Use* Use::find (const cmt_string& package,
00593 const cmt_string& version,
00594 const cmt_string& path)
00595 {
00596 static UsePtrVector& Uses = uses ();
00597 static UseVector& AllUses = all_uses ();
00598
00599 int use_index;
00600
00601 if (AllUses.size () == 0) return (0);
00602
00603 for (use_index = 0; use_index < Uses.size (); use_index++)
00604 {
00605 Use& use = (*Uses[use_index]);
00606
00607 if (use.package == package)
00608 {
00609
00610
00611 if (version == "") return (&use);
00612
00613
00614
00615
00616
00617
00618
00619 if (use.specified_version == version) return (&use);
00620 }
00621 }
00622
00623 return (0);
00624 }
00625
00626
00627
00628
00629
00630
00631 void Use::move (Use* use1)
00632 {
00633 static UsePtrVector& Uses = uses ();
00634
00635 int use_index;
00636 Use* use;
00637 int found = 0;
00638
00639 if (Uses.size () == 0) return;
00640 if (use1 == 0) return;
00641
00642
00643
00644
00645 for (use_index = 0; use_index < Uses.size (); use_index++)
00646 {
00647 use = Uses[use_index];
00648
00649 if (use == use1)
00650 {
00651 found = 1;
00652 break;
00653 }
00654 }
00655
00656 if (!found) return;
00657
00658
00659
00660
00661 for (use_index++;
00662 use_index < Uses.size ();
00663 use_index++)
00664 {
00665 Uses[use_index - 1] = Uses[use_index];
00666 }
00667
00668
00669
00670
00671 {
00672 Uses[Uses.size () - 1] = use1;
00673 }
00674 }
00675
00681 void Use::reorder (Use* use1, Use* use2)
00682 {
00683 static UsePtrVector& Uses = uses ();
00684
00685 int use_index;
00686 int index1 = -1;
00687 int index2 = -1;
00688 Use* use;
00689
00690 if (Uses.size () == 0) return;
00691 if (use1 == use2) return;
00692
00693
00694
00695
00696
00697 for (use_index = 0; use_index < Uses.size (); use_index++)
00698 {
00699 use = (Use*) Uses[use_index];
00700
00701 if (use == use1) index1 = use_index;
00702 if (use == use2) index2 = use_index;
00703 }
00704
00705 if (Cmt::get_debug ())
00706 {
00707 cout << "Use::reorder> 1=" << index1 << " 2=" << index2 << endl;
00708 }
00709
00710
00711
00712
00713 if (index1 == -1) return;
00714 if (index2 == -1) return;
00715
00716 if (index2 < index1)
00717 {
00718
00719
00720
00721 return;
00722 }
00723 else
00724 {
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 use = use2;
00739
00740 for (use_index = index2 - 1; use_index >= index1; use_index--)
00741 {
00742 Uses[use_index + 1] = Uses[use_index];
00743 }
00744
00745 Uses[index1] = use;
00746 }
00747 }
00748
00749
00750 void Use::clear_all ()
00751 {
00752 static UsePtrVector& Uses = uses ();
00753 static UseVector& AllUses = all_uses ();
00754
00755 int use_index;
00756
00757 for (use_index = 0; use_index < AllUses.size (); use_index++)
00758 {
00759 Use& use = AllUses[use_index];
00760 use.clear ();
00761 }
00762
00763 Uses.clear ();
00764 AllUses.clear ();
00765 }
00766
00767
00768 void Use::unselect_all ()
00769 {
00770 static UsePtrVector& Uses = uses ();
00771
00772 int use_index;
00773
00774 if (Uses.size () == 0) return;
00775
00776 for (use_index = 0; use_index < Uses.size (); use_index++)
00777 {
00778 Use* use = Uses[use_index];
00779
00780 if (use != 0)
00781 {
00782 use->unselect ();
00783 }
00784 }
00785 }
00786
00787
00788 void Use::undiscard_all ()
00789 {
00790 static UsePtrVector& Uses = uses ();
00791
00792 int use_index;
00793
00794 if (Uses.size () == 0) return;
00795
00796 for (use_index = 0; use_index < Uses.size (); use_index++)
00797 {
00798 Use* use = Uses[use_index];
00799
00800 if (use != 0)
00801 {
00802 use->undiscard ();
00803 }
00804 }
00805 }
00806
00807
00808 void Use::fill_macro_all (cmt_string& buffer, const cmt_string& suffix)
00809 {
00810 UsePtrVector& Uses = uses ();
00811
00812 buffer = "macro_append use_";
00813 buffer += suffix;
00814 buffer += " \" ";
00815 (Use::current()).fill_macro (buffer, suffix);
00816
00817 for (int number = 0; number < Uses.size (); number++)
00818 {
00819 Use* use = Uses[number];
00820
00821 if (use->package == "CMT") continue;
00822 if (use->package == "methods") continue;
00823 if (use->discarded) continue;
00824 if (use->auto_imports == Off) continue;
00825
00826 use->fill_macro (buffer, suffix);
00827 }
00828
00829 buffer += "\"";
00830 }
00831
00832
00833 Use::Use ()
00834 {
00835 done = false;
00836 discarded = false;
00837 auto_imports = Unspecified;
00838
00839 clear ();
00840 }
00841
00842
00843 Use::Use (const cmt_string& new_package,
00844 const cmt_string& new_version,
00845 const cmt_string& new_path)
00846 {
00847 auto_imports = Unspecified;
00848 m_located = false;
00849 set (new_package, new_version, new_path);
00850 }
00851
00852
00853 Use::~Use ()
00854 {
00855 clear ();
00856 }
00857
00858
00859 void Use::clear ()
00860 {
00861 specified_path = "";
00862 path = "";
00863 package = "";
00864 version = "";
00865 author = "";
00866 manager = "";
00867 real_path = "";
00868
00869 prefix = "";
00870 style = mgr_style;
00871 scope = Cmt::get_scope ();
00872 done = false;
00873 discarded = false;
00874 selected = false;
00875 auto_imports = Unspecified;
00876
00877 includes.clear ();
00878 include_path = "";
00879 scripts.clear ();
00880 apply_patterns.clear ();
00881 ignore_patterns.clear ();
00882
00883 sub_uses.clear ();
00884 sub_use_scopes.clear ();
00885 sub_use_auto_imports.clear ();
00886
00887 alternate_versions.clear ();
00888 alternate_paths.clear ();
00889
00890 version_alias = "";
00891 path_alias = "";
00892
00893 m_located = false;
00894 m_has_native_version = false;
00895 }
00896
00897
00898 void Use::set (const cmt_string& new_package,
00899 const cmt_string& new_version,
00900 const cmt_string& new_path,
00901 const cmt_string& new_version_alias,
00902 const cmt_string& new_path_alias)
00903 {
00904 clear ();
00905
00906 package = new_package;
00907 specified_path = new_path;
00908
00909
00910 specified_version = new_version;
00911 version = new_version;
00912 path = specified_path;
00913 Symbol::expand (path);
00914 real_path = "";
00915 style = mgr_style;
00916 scope = Cmt::get_scope ();
00917 done = false;
00918 discarded = false;
00919 Cmt::build_prefix (new_package, prefix);
00920
00921 version_alias = new_version_alias;
00922 path_alias = new_path_alias;
00923 }
00924
00925
00926 void Use::change_path (const cmt_string& new_path)
00927 {
00928
00929
00930
00931
00932
00933 real_path = "";
00934
00935 if (new_path != "")
00936 {
00937 if ((path.size () > 0) &&
00938 (!CmtSystem::absolute_path (path)))
00939 {
00940 real_path = new_path;
00941 real_path += CmtSystem::file_separator ();
00942 real_path += path;
00943 }
00944 else
00945 {
00946 real_path = new_path;
00947 }
00948
00949 }
00950
00951 m_located = true;
00952 }
00953
00954
00955 int Use::reach_package (const cmt_string& from_path)
00956 {
00957
00958
00959
00960
00961
00962
00963
00964 if ((from_path != "") && !CmtSystem::cd (from_path)) return (0);
00965
00966
00967 if (from_path != real_path)
00968 {
00969
00970 if ((path.size () > 0) && (!CmtSystem::absolute_path (path)))
00971 {
00972 if (!CmtSystem::cd (path))
00973 {
00974 return (0);
00975 }
00976 }
00977 }
00978
00979
00980 if (package == CmtSystem::get_home_package ())
00981 {
00982 discarded = 1;
00983 if (!CmtSystem::test_file ("requirements"))
00984 {
00985 return (0);
00986 }
00987 else
00988 {
00989 return (1);
00990 }
00991 }
00992
00993
00994 if (package == CmtSystem::get_user_context_package ())
00995 {
00996 discarded = 1;
00997 if (!CmtSystem::test_file ("requirements"))
00998 {
00999 return (0);
01000 }
01001 else
01002 {
01003 return (1);
01004 }
01005 }
01006
01007
01008 if (!CmtSystem::cd (package))
01009 {
01010 return (0);
01011 }
01012
01013 if (!CmtSystem::cd (version))
01014 {
01015
01016
01017
01018
01019 if ((version == "") ||
01020 (version.find ("*") != cmt_string::npos))
01021 {
01022 static CmtSystem::cmt_string_vector versions;
01023 static cmt_string name;
01024
01025 name = ".";
01026 name += CmtSystem::file_separator ();
01027 if (version == "") name += "*";
01028 else name += version;
01029
01030 CmtSystem::scan_dir (name, versions);
01031
01032 int i;
01033
01034 for (i = 0; i < versions.size (); i++)
01035 {
01036 const cmt_string& vers = versions[i];
01037
01038 if (Cmt::get_debug ())
01039 {
01040 cout << " ... version " << vers << " exists" << endl;
01041 }
01042
01043 CmtSystem::basename (vers, name);
01044
01045 int v;
01046 int r;
01047 int p;
01048
01049 if (CmtSystem::is_version_directory (name, v, r, p))
01050 {
01051
01052
01053
01054
01055
01056
01057 cmt_string req;
01058
01059 req = name;
01060 req += CmtSystem::file_separator ();
01061 req += "mgr";
01062 req += CmtSystem::file_separator ();
01063 req += "requirements";
01064
01065 if (!CmtSystem::test_file (req))
01066 {
01067 req = name;
01068 req += CmtSystem::file_separator ();
01069 req += "cmt";
01070 req += CmtSystem::file_separator ();
01071 req += "requirements";
01072
01073 if (!CmtSystem::test_file (req)) continue;
01074 }
01075
01076 cmt_string& new_v = alternate_versions.add ();
01077 new_v = name;
01078 cmt_string& new_p = alternate_paths.add ();
01079 new_p = from_path;
01080 }
01081 }
01082 }
01083
01084 if (Cmt::get_debug ())
01085 {
01086 cout << " ... end of version scan" << endl;
01087 }
01088
01089
01090
01091
01092
01093
01094 return (0);
01095 }
01096
01097
01098
01099
01100 if (!CmtSystem::test_file ("cmt/requirements"))
01101 {
01102 if (!CmtSystem::test_file ("mgr/requirements"))
01103 {
01104 return (0);
01105 }
01106 else
01107 {
01108 CmtSystem::cd ("mgr");
01109 style = mgr_style;
01110 }
01111 }
01112 else
01113 {
01114 CmtSystem::cd ("cmt");
01115 style = cmt_style;
01116 }
01117
01118 return (1);
01119 }
01120
01121
01122 bool Use::move_to ()
01123 {
01124 if (m_located)
01125 {
01126
01127
01128
01129
01130
01131 if (Cmt::get_debug ())
01132 {
01133 cout << "move_to1> " << real_path << endl;
01134 }
01135
01136 reach_package (real_path);
01137
01138 return (true);
01139 }
01140
01141 cmt_string expanded_path = path;
01142
01143
01144
01145
01146 if (expanded_path == "")
01147 {
01148 if (reach_package (""))
01149 {
01150 if (Cmt::get_debug ())
01151 {
01152 cout << "move_to2> " << expanded_path << endl;
01153 }
01154
01155 change_path (expanded_path);
01156
01157 return (true);
01158 }
01159 else if (alternate_versions.size () > 0)
01160 {
01161 if (select_alternate ())
01162 {
01163 if (Cmt::get_debug ())
01164 {
01165 cout << "move_to5> " << real_path << endl;
01166 }
01167
01168 return (true);
01169 }
01170 }
01171 }
01172
01173
01174
01175
01176
01177 if (CmtSystem::absolute_path (expanded_path))
01178 {
01179 if (reach_package (expanded_path))
01180 {
01181 if (Cmt::get_debug ())
01182 {
01183 cout << "move_to3> " << expanded_path << endl;
01184 }
01185
01186 change_path (expanded_path);
01187
01188 return (true);
01189 }
01190 else if (alternate_versions.size () > 0)
01191 {
01192 if (select_alternate ())
01193 {
01194 if (Cmt::get_debug ())
01195 {
01196 cout << "move_to5> " << real_path << endl;
01197 }
01198
01199 return (true);
01200 }
01201 }
01202 }
01203
01204
01205
01206
01207
01208 static const CmtSystem::cmt_string_vector& search_path = Cmt::get_cmt_path ();
01209 int path_index = 0;
01210
01211 for (path_index = 0; path_index < search_path.size (); path_index++)
01212 {
01213 const cmt_string& next_path = search_path[path_index];
01214
01215 alternate_versions.clear ();
01216 alternate_paths.clear ();
01217
01218 if (reach_package (next_path))
01219 {
01220 if (Cmt::get_debug ())
01221 {
01222 cout << "move_to4> " << next_path << endl;
01223 }
01224
01225 change_path (next_path);
01226
01227 return (true);
01228 }
01229 else if (alternate_versions.size () > 0)
01230 {
01231 if (select_alternate ())
01232 {
01233 if (Cmt::get_debug ())
01234 {
01235 cout << "move_to5> " << real_path << endl;
01236 }
01237
01238 return (true);
01239 }
01240 }
01241 }
01242
01243
01244 return (false);
01245 }
01246
01247
01248 bool Use::select_alternate ()
01249 {
01250 int i;
01251
01252 int v0 = 0;
01253 int r0 = 0;
01254 int p0 = 0;
01255
01256 int v = 0;
01257 int r = 0;
01258 int p = 0;
01259
01260 int selected_index = -1;
01261
01262 for (i = 0; i < alternate_versions.size (); i++)
01263 {
01264 cmt_string& name = alternate_versions[i];
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 if (i == 0)
01277 {
01278 CmtSystem::is_version_directory (name, v0, r0, p0);
01279 selected_index = 0;
01280 }
01281 else
01282 {
01283 CmtSystem::is_version_directory (name, v, r, p);
01284
01285 if (v > v0)
01286 {
01287 selected_index = i;
01288 v0 = v;
01289 r0 = r;
01290 p0 = p;
01291 }
01292 else if (v == v0)
01293 {
01294 if (r > r0)
01295 {
01296 selected_index = i;
01297 r0 = r;
01298 p0 = p;
01299 }
01300 else if (r == r0)
01301 {
01302 if (p > p0)
01303 {
01304 selected_index = i;
01305 p0 = p;
01306 }
01307 }
01308 }
01309 }
01310 }
01311
01312 if (selected_index >= 0)
01313 {
01314 if (CmtSystem::cd (alternate_paths[selected_index]))
01315 {
01316 version = alternate_versions[selected_index];
01317 if (reach_package (alternate_paths[selected_index]))
01318 {
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 if (Cmt::get_debug ())
01329 {
01330 cout << "select_alternate> " << alternate_paths[selected_index] << endl;
01331 }
01332
01333 change_path (alternate_paths[selected_index]);
01334 return (true);
01335 }
01336 }
01337 }
01338
01339 return (false);
01340 }
01341
01342
01343 bool Use::need_new (const cmt_string& path,
01344 const cmt_string& package,
01345 const cmt_string& version,
01346 Use** old_use)
01347 {
01348 bool has_wild_card = (version.find ("*") != cmt_string::npos);
01349
01350 static UsePtrVector& Uses = uses ();
01351 static UseVector& AllUses = all_uses ();
01352
01353 bool result = true;
01354 Use* found = 0;
01355
01356 int use_index;
01357
01358 if (old_use != 0) *old_use = 0;
01359 if (AllUses.size () == 0) return (true);
01360
01361 for (use_index = 0; use_index < Uses.size (); use_index++)
01362 {
01363 Use& use = (*Uses[use_index]);
01364
01365 if (use.package != package) continue;
01366
01367 found = &use;
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377 bool use_has_wild_card = (use.specified_version.find ("*") != cmt_string::npos);
01378
01379 if (has_wild_card && !use_has_wild_card)
01380 {
01381
01382 result = false;
01383 break;
01384 }
01385
01386 if ((version == use.specified_version) &&
01387 (path == use.specified_path))
01388 {
01389
01390 result = false;
01391 break;
01392 }
01393
01394
01395
01396
01397 }
01398
01399 if (old_use != 0) *old_use = found;
01400 return (result);
01401 }
01402
01403
01404
01405
01406
01407
01408
01409 Use* Use::create (const cmt_string& path,
01410 const cmt_string& package,
01411 const cmt_string& version,
01412 const cmt_string& version_alias,
01413 const cmt_string& path_alias)
01414 {
01415 static UseVector& AllUses = all_uses ();
01416
01417
01418 for (int use_index = 0; use_index < AllUses.size (); use_index++)
01419 {
01420 Use& use = AllUses[use_index];
01421
01422 if (use.package == package)
01423 {
01424 if ((use.specified_version == version) &&
01425 (use.specified_path == path)) return (&use);
01426 }
01427 }
01428
01429
01430
01431 Use& use_object = AllUses.add ();
01432 use_object.set (package, version, path, version_alias, path_alias);
01433
01434 return (&use_object);
01435 }
01436
01437
01438
01439
01440
01441
01442
01443
01444 Use* Use::add (const cmt_string& path,
01445 const cmt_string& package,
01446 const cmt_string& version,
01447 const cmt_string& version_alias,
01448 const cmt_string& path_alias,
01449 Use* context_use,
01450 State specified_auto_imports)
01451 {
01452 static UsePtrVector& Uses = uses ();
01453
01454 bool do_need_new = false;
01455
01456 Use* old_use = 0;
01457 Use* use = 0;
01458
01459 do_need_new = need_new (path, package, version, &old_use);
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 if (do_need_new)
01472 {
01473 use = create (path, package, version, version_alias, path_alias);
01474 }
01475 else
01476 {
01477
01478 use = old_use;
01479 old_use = 0;
01480 }
01481
01482 if (package == CmtSystem::get_home_package ())
01483 {
01484 return (use);
01485 }
01486
01487 if (package == CmtSystem::get_user_context_package ())
01488 {
01489 return (use);
01490 }
01491
01492 cmt_string here = CmtSystem::pwd ();
01493
01494
01495
01496
01497
01498 if (context_use != 0)
01499 {
01500 context_use->sub_uses.push_back (use);
01501 context_use->sub_use_scopes.push_back (Cmt::get_scope ());
01502 context_use->sub_use_auto_imports.push_back (specified_auto_imports);
01503
01504 if (Cmt::get_debug ())
01505 {
01506 cout << "Use::add context(" << context_use->package << ") "
01507 << "[u:" << package
01508 << " s:" << Cmt::get_scope ()
01509 << " ai:" << specified_auto_imports
01510 << "]" << endl;
01511 }
01512 }
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528 bool found = use->move_to ();
01529
01530 if (Cmt::get_debug ())
01531 {
01532 cout << "add> use " << use->package
01533 << " " << use->version
01534 << " " << use->path
01535 << " found=" << found
01536 << endl;
01537 }
01538
01539 if (!found)
01540 {
01541 if (!Cmt::get_quiet ())
01542 {
01543 cerr << "#(Warning) package " << use->package <<
01544 " " << use->version << " " << use->path <<
01545 " not found" <<
01546 endl;
01547 }
01548
01549 CmtError::set (CmtError::package_not_found, use->package);
01550 use = 0;
01551 }
01552
01553 if ((old_use != 0) && (use != old_use))
01554 {
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571 if (!found)
01572 {
01573
01574
01575
01576
01577
01578 use->discard ();
01579 use = old_use;
01580 found = use->move_to ();
01581 }
01582 else
01583 {
01584
01585
01586
01587
01588 VersionSelector& selector = VersionSelector::instance ();
01589 Use* selected_use = selector.operate (old_use, use);
01590
01591
01592
01593
01594
01595 if (use != selected_use)
01596 {
01597 use->discard ();
01598 }
01599
01600 use = selected_use;
01601
01602
01603
01604
01605 found = use->move_to ();
01606 }
01607 }
01608
01609
01610
01611
01612
01613
01614
01615 if (found)
01616 {
01617 bool registered = false;
01618 const Use& cu = Use::current ();
01619
01620
01621
01622
01623 if ((use != &cu) && (package == cu.package))
01624 {
01625
01626 registered = true;
01627 use->done = true;
01628 }
01629 else
01630 {
01631 for (int i = 0; i < Uses.size(); i++)
01632 {
01633 Use* u = Uses[i];
01634
01635 if (u->package == package)
01636 {
01637 registered = true;
01638 Uses[i] = use;
01639 break;
01640 }
01641 }
01642 }
01643
01644 if (!registered) Uses.push_back (use);
01645
01646 if (!use->done && Cmt::get_recursive ())
01647 {
01648 use->done = true;
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01673
01674
01675 if (Cmt::get_debug ())
01676 {
01677 cout << "Parsing requirements file at " << CmtSystem::pwd () << endl;
01678 }
01679
01680 Cmt::parse_requirements ("requirements", use);
01681 }
01682 }
01683
01684 CmtSystem::cd (here);
01685
01686 return (use);
01687 }
01688
01689
01690 void Use::discard ()
01691 {
01692 discarded = true;
01693 }
01694
01695
01696 void Use::undiscard ()
01697 {
01698 discarded = false;
01699 }
01700
01701
01702 void Use::select ()
01703 {
01704 selected = true;
01705 }
01706
01707
01708 void Use::unselect ()
01709 {
01710 selected = false;
01711 }
01712
01713
01714 bool Use::is_selected ()
01715 {
01716 return (selected);
01717 }
01718
01725 bool Use::is_client (const cmt_string& used_package,
01726 const cmt_string& used_version)
01727 {
01728
01729 if ((package == used_package) &&
01730 (version == used_version)) return (true);
01731
01732 if (discarded) return (false);
01733
01734 int i;
01735
01736 for (i = 0; i < sub_uses.size (); i++)
01737 {
01738 Use* use = sub_uses[i];
01739 if (use == 0) continue;
01740
01741 if ((use->package == used_package) &&
01742 (use->version == used_version)) return (true);
01743
01744
01745
01746
01747
01748
01749
01750 }
01751
01752 return (false);
01753 }
01754
01755
01756 void Use::apply_global_patterns ()
01757 {
01758 int i;
01759
01760 Pattern::PatternVector& vector = Pattern::patterns ();
01761
01762 for (i = 0; i < vector.size (); i++)
01763 {
01764 Pattern& p = vector[i];
01765
01766 if (p.global)
01767 {
01768 p.apply (this);
01769 }
01770 }
01771 }
01772
01773
01774 void Use::set_include_path (const cmt_string& new_path)
01775 {
01776 include_path = new_path;
01777 }
01778
01779
01780 void Use::fill_includes_macro (cmt_string& buffer) const
01781 {
01782 if (include_path == "")
01783 {
01784 buffer += "$(ppcmd)\"$(";
01785 buffer += package;
01786 buffer += "_root)";
01787 buffer += CmtSystem::file_separator ();
01788 buffer += "src\" ";
01789 }
01790 else if (include_path != "none")
01791 {
01792 buffer += "$(ppcmd)\"";
01793 buffer += include_path;
01794 buffer += "\" ";
01795 }
01796
01797 for (int i = 0; i < includes.size (); i++)
01798 {
01799 Include& incl = includes[i];
01800
01801 buffer += "$(ppcmd)\"";
01802 buffer += incl.name;
01803 buffer += "\" ";
01804 }
01805 }
01806
01807
01808 void Use::fill_macro (cmt_string& buffer, const cmt_string& suffix) const
01809 {
01810 buffer += " $(";
01811 buffer += package;
01812 buffer += "_";
01813 buffer += suffix;
01814 buffer += ") ";
01815 }
01816
01821 Use* Use::get_selected_version ()
01822 {
01823 static Use::UsePtrVector& Uses = uses ();
01824
01825
01826
01827 if (!discarded) return (this);
01828
01829 for (int i = 0; i < Uses.size (); i++)
01830 {
01831 Use* u = Uses[i];
01832 if (u == 0) continue;
01833 if (u->discarded) continue;
01834 if (u->package == package)
01835 {
01836
01837 return (u);
01838 }
01839 }
01840
01841 return (0);
01842 }
01843
01844 void Use::set_auto_imports (State new_state)
01845 {
01846 if (Cmt::get_debug ())
01847 {
01848 cout << "Use::set_auto_imports>(" << package << ") "
01849 << auto_imports << " -> " << new_state << endl;
01850 }
01851
01852 if (auto_imports == new_state) return;
01853
01854 State old_state = auto_imports;
01855
01856 auto_imports = new_state;
01857
01858
01859
01860 if ((old_state == Off) && (new_state == On))
01861 {
01862 cmt_string s;
01863 static const cmt_string state_text[] = {"Unspecified", "Off", "On"};
01864
01865 if (Cmt::get_debug ())
01866 {
01867 s = "Use::set_auto_imports>(";
01868 s += package;
01869 s += ") ";
01870
01871 cout << s << endl;
01872 }
01873
01874 for (int i = 0; i < sub_uses.size (); i++)
01875 {
01876 Use* u = sub_uses[i];
01877 State state = sub_use_auto_imports[i];
01878
01879 if (Cmt::get_debug ())
01880 {
01881 s += " ";
01882 s += u->package;
01883 s += "(";
01884 s += state_text[state];
01885 s += ")";
01886 }
01887
01888 if (state == Unspecified)
01889 {
01890 u->set_auto_imports (On);
01891 }
01892 }
01893
01894 if (Cmt::get_debug ())
01895 {
01896 cout << s << endl;
01897 }
01898 }
01899 }
01900
01901 void Use::set_native_version (bool state)
01902 {
01903 m_has_native_version = state;
01904 }
01905
01906 bool Use::has_native_version () const
01907 {
01908 return (m_has_native_version);
01909 }
01910
01911
01912 bool Use::get_paths (Use* to, UsePtrVector& list)
01913 {
01914 bool found = false;
01915 bool cycle = false;
01916
01917 static int level = 0;
01918 static UsePtrVector stack;
01919
01920 if (level == 0)
01921 {
01922 stack.clear ();
01923 }
01924
01925 for (int k = 0; k < stack.size (); k++)
01926 {
01927 Use* u = stack[k];
01928 if (u == this) return (false);
01929 }
01930
01931 if (stack.size () <= level)
01932 {
01933 stack.push_back (this);
01934 }
01935 else
01936 {
01937 stack[level] = this;
01938 }
01939
01940
01941
01942 if (Cmt::get_debug ())
01943 {
01944 cout << "Use::get_paths." << level << ">" << package << " list[" << list.size () << "]" << endl;
01945 }
01946
01947 if (this == to)
01948 {
01949 found = true;
01950 }
01951 else
01952 {
01953 for (int n = 0; n < sub_uses.size (); n++)
01954 {
01955 Use* use = sub_uses[n];
01956
01957 if (use == 0) continue;
01958
01959 if (use->discarded)
01960 {
01961 Use* u;
01962
01963 u = use->get_selected_version ();
01964 if (u == 0) continue;
01965
01966 use = u;
01967 }
01968
01969 cycle = false;
01970
01971
01972
01973 for (int m = 0; m < list.size (); m++)
01974 {
01975 Use* u = list[m];
01976 if (u == use)
01977 {
01978 cycle = true;
01979 break;
01980 }
01981 }
01982
01983 if (cycle)
01984 {
01985 found = true;
01986 continue;
01987 }
01988
01989 level++;
01990 bool r = use->get_paths (to, list);
01991 level--;
01992
01993 if (r)
01994 {
01995 found = true;
01996 }
01997 }
01998 }
01999
02000 if (found)
02001 {
02002 cycle = false;
02003
02004 for (int m = 0; m < list.size (); m++)
02005 {
02006 Use* u = list[m];
02007 if (u == this)
02008 {
02009 cycle = true;
02010 break;
02011 }
02012 }
02013
02014 if (!cycle)
02015 {
02016 list.push_back (this);
02017 }
02018 }
02019
02020 return (found);
02021 }
02022
02023
02024 bool Use::located () const
02025 {
02026 return (m_located);
02027 }
02028
02029
02030 void Use::show_sub_uses (bool skip_discarded)
02031 {
02032 int n;
02033 Use* use;
02034 static int level = 0;
02035
02036 if (skip_discarded && discarded) return;
02037
02038 if (level > 0)
02039 {
02040 cout << "# ";
02041 for (n = 0; n < (level-1); n++) cout << " ";
02042
02043 cout << "use " << package << " " << specified_version;
02044
02045 if (specified_path != "") cout << " " << specified_path;
02046
02047 if (version_alias != "")
02048 {
02049 cout << " | " << version_alias << " " << path_alias;
02050 }
02051
02052 if (scope == ScopeUnspecified) cout << " unspecified";
02053 else if (scope != ScopePublic) cout << " (private)";
02054
02055
02056 if (auto_imports == Off) cout << " (no_auto_imports)";
02057
02058 if (m_has_native_version)
02059 {
02060 cmt_string n = package;
02061 n += "_native_version";
02062
02063 Symbol* s = Symbol::find (n);
02064 if (s != 0)
02065 {
02066 cmt_string value = s->resolve_macro_value ();
02067 cout << " (native_version=" << value << ")";
02068 }
02069 }
02070
02071 cout << endl;
02072 }
02073
02074 if (selected) return;
02075 selected = true;
02076
02077 level++;
02078 for (n = 0; n < sub_uses.size (); n++)
02079 {
02080 use = sub_uses[n];
02081 if (use == 0) continue;
02082
02083 ScopeType saved_scope = use->scope;
02084 State saved_state = use->auto_imports;
02085
02086 use->scope = sub_use_scopes[n];
02087 use->auto_imports = sub_use_auto_imports[n];
02088
02089 use->show_sub_uses (skip_discarded);
02090
02091 use->scope = saved_scope;
02092 use->auto_imports = saved_state;
02093 }
02094 level--;
02095 }
02096
02097
02098 Use& Use::current ()
02099 {
02100 static UseVector& AllUses = all_uses ();
02101 static Use* current_use = 0;
02102
02103 if ((current_use == 0) || (AllUses.size () == 0))
02104 {
02105 Use& use_object = AllUses.add ();
02106 current_use = &use_object;
02107 }
02108
02109 return (*current_use);
02110 }
02111
02112
02113 const Use& Use::const_current ()
02114 {
02115 const Use& use = Use::current ();
02116
02117 return (use);
02118 }
02119
02120
02121 Use::UseVector& Use::all_uses ()
02122 {
02123 static Database& db = Database::instance ();
02124 static UseVector& AllUses = db.all_uses ();
02125
02126 return (AllUses);
02127 }
02128
02129
02130 Use::UsePtrVector& Use::uses ()
02131 {
02132 static Database& db = Database::instance ();
02133 static UsePtrVector& Uses = db.uses ();
02134
02135 return (Uses);
02136 }
02137
02138
02139 VersionSelector& VersionSelector::instance ()
02140 {
02141 static BestFitSelector best_fit;
02142 static BestFitNoCheckSelector best_fit_no_check;
02143 static FirstChoiceSelector first_choice;
02144 static LastChoiceSelector last_choice;
02145 static KeepAllSelector keep_all;
02146
02147 switch (Cmt::get_current_strategy ())
02148 {
02149 case BestFit:
02150 return (best_fit);
02151 case BestFitNoCheck:
02152 return (best_fit_no_check);
02153 case FirstChoice:
02154 return (first_choice);
02155 case LastChoice:
02156 return (last_choice);
02157 case KeepAll:
02158 return (keep_all);
02159 default:
02160 return (best_fit);
02161 }
02162 }
02163
02164
02165
02166
02167
02168
02169
02170 Use* BestFitSelector::operate (Use* ref_use, Use* new_use)
02171 {
02172 Use* selected = ref_use;
02173
02174 int old_v = -1;
02175 int old_r = -1;
02176 int old_p = -1;
02177 cmt_string old_pp;
02178
02179 int new_v = -1;
02180 int new_r = -1;
02181 int new_p = -1;
02182 cmt_string new_pp;
02183
02184 int alias_v = -1;
02185 int alias_r = -1;
02186 int alias_p = -1;
02187 cmt_string alias_pp;
02188
02189 enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
02190
02191 CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
02192 old_pp = ref_use->path;
02193
02194 CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
02195 new_pp = new_use->path;
02196
02197 if (new_use->version_alias != "")
02198 {
02199 has_alias = new_has_alias;
02200 CmtSystem::is_version_directory (new_use->version_alias,
02201 alias_v, alias_r, alias_p);
02202 alias_pp = new_use->path_alias;
02203 }
02204 else if (ref_use->version_alias != "")
02205 {
02206 has_alias = ref_has_alias;
02207 CmtSystem::is_version_directory (ref_use->version_alias,
02208 alias_v, alias_r, alias_p);
02209 alias_pp = ref_use->path_alias;
02210 }
02211
02212 ref_use->undiscard ();
02213 new_use->undiscard ();
02214
02215 if (new_v != old_v)
02216 {
02217 if (has_alias != no_alias)
02218 {
02219 if (has_alias == new_has_alias)
02220 {
02221 new_v = alias_v;
02222 new_r = alias_r;
02223 new_p = alias_p;
02224 new_pp = alias_pp;
02225 }
02226 else if (has_alias == ref_has_alias)
02227 {
02228 old_v = alias_v;
02229 old_r = alias_r;
02230 old_p = alias_p;
02231 old_pp = alias_pp;
02232 }
02233 }
02234 }
02235
02236 if (new_v != old_v)
02237 {
02238 if (!Cmt::get_quiet ())
02239 cout << "# Required version " << new_use->version <<
02240 " of package " << ref_use->package <<
02241 " incompatible with selected version " << ref_use->version <<
02242 endl;
02243
02244 CmtError::set (CmtError::version_conflict, "BestFitSelector::operate> ");
02245
02246 if (ref_use != new_use) new_use->discard ();
02247 }
02248 else if (new_r < old_r)
02249 {
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260 bool new_is_wildcarded = false;
02261 bool ref_is_wildcarded = false;
02262
02263 if (new_use->specified_version.find ("*") != cmt_string::npos)
02264 {
02265 int nv = -1;
02266 int nr = -1;
02267 int np = -1;
02268
02269 CmtSystem::is_version_directory (new_use->specified_version, nv, nr, np);
02270 if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
02271 }
02272
02273 if (ref_use->specified_version.find ("*") != cmt_string::npos)
02274 {
02275 int nv = -1;
02276 int nr = -1;
02277 int np = -1;
02278
02279 CmtSystem::is_version_directory (ref_use->specified_version, nv, nr, np);
02280 if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
02281 }
02282
02283 if (!ref_is_wildcarded && new_is_wildcarded)
02284 {
02285 if (ref_use != new_use) ref_use->discard ();
02286 selected = new_use;
02287 selected->done = false;
02288 }
02289 else
02290 {
02291 if (!Cmt::get_quiet ())
02292 cout << "# keep release " << ref_use->version <<
02293 " of package " << ref_use->package <<
02294 " (ignore release " << new_use->version << ")" <<
02295 endl;
02296
02297 if (ref_use != new_use) new_use->discard ();
02298 }
02299 }
02300 else if (new_r > old_r)
02301 {
02302 if (!Cmt::get_quiet ())
02303 {
02304 cout << "# Select release " << new_use->version <<
02305 " of package " << ref_use->package <<
02306 " instead of existing " << ref_use->version <<
02307 endl;
02308 }
02309
02310 if (ref_use != new_use) ref_use->discard ();
02311 selected = new_use;
02312 selected->done = false;
02313 }
02314 else if (new_p > old_p)
02315 {
02316 if (!Cmt::get_quiet ())
02317 {
02318 cout << "# Select patch " << new_use->version <<
02319 " of package " << ref_use->package <<
02320 " instead of existing " << ref_use->version <<
02321 endl;
02322 }
02323
02324 if (ref_use != new_use) ref_use->discard ();
02325 selected = new_use;
02326 selected->done = false;
02327 }
02328 else if (new_pp != old_pp)
02329 {
02330 if (ref_use != new_use) ref_use->discard ();
02331 selected = new_use;
02332 selected->done = false;
02333 }
02334
02335 return (selected);
02336 }
02337
02338
02339
02340
02341
02342
02343
02344 Use* BestFitNoCheckSelector::operate (Use* ref_use, Use* new_use)
02345 {
02346 Use* selected = ref_use;
02347
02348 int old_v = -1;
02349 int old_r = -1;
02350 int old_p = -1;
02351 cmt_string old_pp;
02352
02353 int new_v = -1;
02354 int new_r = -1;
02355 int new_p = -1;
02356 cmt_string new_pp;
02357
02358 int alias_v = -1;
02359 int alias_r = -1;
02360 int alias_p = -1;
02361 cmt_string alias_pp;
02362
02363 enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
02364
02365 CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
02366 old_pp = ref_use->path;
02367
02368 CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
02369 new_pp = new_use->path;
02370
02371 if (new_use->version_alias != "")
02372 {
02373 has_alias = new_has_alias;
02374 CmtSystem::is_version_directory (new_use->version_alias,
02375 alias_v, alias_r, alias_p);
02376 alias_pp = new_use->path_alias;
02377 }
02378 else if (ref_use->version_alias != "")
02379 {
02380 has_alias = ref_has_alias;
02381 CmtSystem::is_version_directory (ref_use->version_alias,
02382 alias_v, alias_r, alias_p);
02383 alias_pp = ref_use->path_alias;
02384 }
02385
02386 ref_use->undiscard ();
02387 new_use->undiscard ();
02388
02389 if (new_v != old_v)
02390 {
02391 if (has_alias != no_alias)
02392 {
02393 if (has_alias == new_has_alias)
02394 {
02395 new_v = alias_v;
02396 new_r = alias_r;
02397 new_p = alias_p;
02398 new_pp = alias_pp;
02399 }
02400 else if (has_alias == ref_has_alias)
02401 {
02402 old_v = alias_v;
02403 old_r = alias_r;
02404 old_p = alias_p;
02405 old_pp = alias_pp;
02406 }
02407 }
02408 }
02409
02410 if (new_v < old_v)
02411 {
02412 if (!Cmt::get_quiet ())
02413 {
02414 cout << "# Keep version " << ref_use->version <<
02415 " of package " << ref_use->package <<
02416 " (ignore version " << new_use->version << ")" <<
02417 endl;
02418 }
02419
02420 if (ref_use != new_use) new_use->discard ();
02421 }
02422 else if (new_v > old_v)
02423 {
02424 if (!Cmt::get_quiet ())
02425 {
02426 cout << "# Select version " << new_use->version <<
02427 " of package " << ref_use->package <<
02428 " instead of existing " << ref_use->version <<
02429 endl;
02430 }
02431
02432 if (ref_use != new_use) ref_use->discard ();
02433 selected = new_use;
02434 selected->done = false;
02435 }
02436 else if (new_r < old_r)
02437 {
02438 if (!Cmt::get_quiet ())
02439 {
02440 cout << "# keep release " << ref_use->version <<
02441 " of package " << ref_use->package <<
02442 " (ignore release " << new_use->version << ")" <<
02443 endl;
02444 }
02445
02446 if (ref_use != new_use) new_use->discard ();
02447 }
02448 else if (new_r > old_r)
02449 {
02450 if (!Cmt::get_quiet ())
02451 {
02452 cout << "# Select release " << new_use->version <<
02453 " of package " << ref_use->package <<
02454 " instead of existing " << ref_use->version <<
02455 endl;
02456 }
02457
02458 if (ref_use != new_use) ref_use->discard ();
02459 selected = new_use;
02460 selected->done = false;
02461 }
02462 else if (new_p > old_p)
02463 {
02464 if (!Cmt::get_quiet ())
02465 {
02466 cout << "# Select patch " << new_use->version <<
02467 " of package " << ref_use->package <<
02468 " instead of existing " << ref_use->version <<
02469 endl;
02470 }
02471
02472 if (ref_use != new_use) ref_use->discard ();
02473 selected = new_use;
02474 selected->done = false;
02475 }
02476 else if (new_pp != old_pp)
02477 {
02478 if (ref_use != new_use) ref_use->discard ();
02479 selected = new_use;
02480 selected->done = false;
02481 }
02482
02483 return (selected);
02484 }
02485
02486
02487 Use* FirstChoiceSelector::operate (Use* ref_use, Use* new_use)
02488 {
02489 ref_use->undiscard ();
02490 new_use->undiscard ();
02491
02492 new_use->done = false;
02493 if (ref_use != new_use) new_use->discard ();
02494 return (ref_use);
02495 }
02496
02497
02498 Use* LastChoiceSelector::operate (Use* ref_use, Use* new_use)
02499 {
02500 ref_use->undiscard ();
02501 new_use->undiscard ();
02502
02503 new_use->done = false;
02504 if (ref_use != new_use) ref_use->discard ();
02505 return (new_use);
02506 }
02507
02508
02509 Use* KeepAllSelector::operate (Use* ref_use, Use* new_use)
02510 {
02511 ref_use->undiscard ();
02512 new_use->undiscard ();
02513
02514 new_use->done = false;
02515 return (new_use);
02516 }