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 (Cmt::get_debug ())
00367 {
00368 cout << "before adding " << package <<"> auto_imports=" << auto_imports
00369 << " (current AI was " << UseContext::get_current_auto_imports () << ")"
00370 << " (current scope was " << UseContext::get_current_scope () << ")"
00371 << " (Cmt::scope=" << Cmt::get_scope () << ")"
00372 << " (parent=" << parent->package << ")"
00373 << endl;
00374 }
00375
00376 bool hidden_by_scope = false;
00377
00378 if ((Cmt::get_scope () == ScopePrivate) || (UseContext::get_current_scope () == ScopePrivate))
00379 {
00380 hidden_by_scope = true;
00381
00382
00383 if ((parent == 0) || (parent->package == cu.package)) hidden_by_scope = false;
00384
00385
00386 if ((action == action_broadcast) ||
00387 (action == action_show_uses)) hidden_by_scope = false;
00388 }
00389
00390 if (hidden_by_scope)
00391 {
00392 return (0);
00393 }
00394
00395
00396
00397 UseContext save = UseContext::current ();
00398
00403 switch (auto_imports)
00404 {
00405 case Unspecified:
00406
00407
00408
00409 UseContext::set_current (UseContext::get_current_auto_imports ());
00410 break;
00411 case Off:
00412
00413
00414
00415 UseContext::set_current (Off);
00416 break;
00417 case On:
00418
00419
00420
00421
00422 if (UseContext::get_current_auto_imports () != Off)
00423 {
00424 UseContext::set_current (On);
00425 }
00426 break;
00427 }
00428
00429 if (hidden_by_scope)
00430 {
00431 UseContext::set_current (Cmt::get_scope ());
00432 }
00433
00435 Use* new_use = Use::add (path, package, version,
00436 version_alias, path_alias, parent,
00437 auto_imports);
00438
00439 if (new_use != 0)
00440 {
00441 if (Cmt::get_debug ())
00442 {
00443 cout << "after adding1 " << package << "> auto_imports=" << new_use->auto_imports << endl;
00444 }
00445
00446 switch (new_use->auto_imports)
00447 {
00448 case Unspecified:
00449 new_use->auto_imports = UseContext::get_current_auto_imports ();
00450 break;
00451 case On:
00452 break;
00453 case Off:
00454 if (UseContext::get_current_auto_imports () == On)
00455 {
00467 new_use->set_auto_imports (On);
00468 }
00469 break;
00470 }
00471
00472
00473 if (Cmt::get_debug ())
00474 {
00475 cout << "after adding2 " << package << "> auto_imports=" << new_use->auto_imports << endl;
00476 }
00477
00478 UseContext& c = UseContext::current ();
00479 c = save;
00480
00481 Use::reorder (new_use, parent);
00482
00483 if (Cmt::get_debug ())
00484 {
00485 int i;
00486
00487 cout << "use::action2> current=" << parent->package
00488 << " package=" << package << " ";
00489
00490 for (i = 0; i < Uses.size (); i++)
00491 {
00492 Use* u = Uses[i];
00493 cout << u->package << " ";
00494 }
00495
00496 cout << endl;
00497 }
00498 }
00499
00500 return (new_use);
00501 }
00502
00503 private:
00504
00505 enum
00506 {
00507 need_package,
00508 need_version,
00509 need_path,
00510 need_version_alias,
00511 need_path_alias,
00512 finished
00513 } state;
00514
00515 State auto_imports;
00516
00517 cmt_string package;
00518 cmt_string version;
00519 cmt_string path;
00520 cmt_string version_alias;
00521 cmt_string path_alias;
00522 };
00523
00524
00525 Use* Use::action (const CmtSystem::cmt_string_vector& words, Use* parent)
00526 {
00527 Use* new_use;
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 if (words.size () < 2) return (0);
00540
00541 use_action_iterator it;
00542
00543 for (int i = 1; i < words.size (); i++)
00544 {
00545 const cmt_string& w = words[i];
00546 cmt_string ew = w;
00547
00548 Symbol::expand (ew);
00549 if (ew != w)
00550 {
00551 CmtSystem::cmt_string_vector ws;
00552
00553 CmtSystem::split (ew, " ", ws);
00554
00555 for (int j = 0; j < ws.size (); ++j)
00556 {
00557 const cmt_string& ww = ws[j];
00558 it.set (ww);
00559 }
00560 }
00561 else
00562 {
00563 it.set (ew);
00564 }
00565 }
00566
00567 if (!it.ok ()) return (0);
00568
00569 static int level = 0;
00570
00571 level++;
00572 new_use = it.get_use (parent);
00573 level--;
00574
00575 return (new_use);
00576 }
00577
00578
00579 void Use::author_action (const CmtSystem::cmt_string_vector& words)
00580 {
00581 if (author != "") author += "\n";
00582 for (int i = 1; i < words.size (); i++)
00583 {
00584 const cmt_string& w = words[i];
00585
00586 if (i > 1) author += " ";
00587 author += w;
00588 }
00589 }
00590
00591
00592 void Use::manager_action (const CmtSystem::cmt_string_vector& words)
00593 {
00594 if (manager != "") manager += "\n";
00595 for (int i = 1; i < words.size (); i++)
00596 {
00597 const cmt_string& w = words[i];
00598
00599 if (i > 1) manager += " ";
00600 manager += w;
00601 }
00602 }
00603
00604
00605 Use* Use::find (const cmt_string& package,
00606 const cmt_string& version,
00607 const cmt_string& path)
00608 {
00609 static UsePtrVector& Uses = uses ();
00610 static UseVector& AllUses = all_uses ();
00611
00612 int use_index;
00613
00614 if (AllUses.size () == 0) return (0);
00615
00616 for (use_index = 0; use_index < Uses.size (); use_index++)
00617 {
00618 Use& use = (*Uses[use_index]);
00619
00620 if (use.package == package)
00621 {
00622
00623
00624 if (version == "") return (&use);
00625
00626
00627
00628
00629
00630
00631
00632 if (use.specified_version == version) return (&use);
00633 }
00634 }
00635
00636 return (0);
00637 }
00638
00639
00640 int Use::find_index (const cmt_string& package,
00641 const cmt_string& version,
00642 const cmt_string& path)
00643 {
00644 static UsePtrVector& Uses = uses ();
00645 static UseVector& AllUses = all_uses ();
00646
00647 int use_index;
00648
00649 if (AllUses.size () == 0) return (-1);
00650
00651 for (use_index = 0; use_index < Uses.size (); use_index++)
00652 {
00653 Use& use = (*Uses[use_index]);
00654
00655 if (use.package == package)
00656 {
00657
00658
00659 if (version == "") return (use_index);
00660
00661
00662
00663
00664
00665
00666
00667 if (use.specified_version == version) return (use_index);
00668 }
00669 }
00670
00671 return (-1);
00672 }
00673
00682 void Use::set_auto_imports_state (int use_index,
00683 cmt_vector<bool>& auto_imports_states)
00684 {
00685
00686 if (auto_imports_states[use_index]) return;
00687
00688 Use::UsePtrVector& Uses = Use::uses ();
00689 Use* use = Uses[use_index];
00690
00691
00692
00693 if (use->auto_imports != Off) return;
00694
00705 auto_imports_states[use_index] = true;
00706
00707 for (int i = 0; i < use->sub_uses.size (); i++)
00708 {
00709 Use* u = use->sub_uses[i];
00710
00711 if (u->sub_use_auto_imports[i] == Off)
00712 {
00713 int j;
00714
00715
00716
00717 for (j = 0; j < Uses.size(); j++)
00718 {
00719 if (u == Uses[j]) break;
00720 }
00721
00722 set_auto_imports_state (j, auto_imports_states);
00723 }
00724 }
00725 }
00726
00727
00728
00729
00730
00731
00732 void Use::move (Use* use1)
00733 {
00734 static UsePtrVector& Uses = uses ();
00735
00736 int use_index;
00737 Use* use;
00738 int found = 0;
00739
00740 if (Uses.size () == 0) return;
00741 if (use1 == 0) return;
00742
00743
00744
00745
00746 for (use_index = 0; use_index < Uses.size (); use_index++)
00747 {
00748 use = Uses[use_index];
00749
00750 if (use == use1)
00751 {
00752 found = 1;
00753 break;
00754 }
00755 }
00756
00757 if (!found) return;
00758
00759
00760
00761
00762 for (use_index++;
00763 use_index < Uses.size ();
00764 use_index++)
00765 {
00766 Uses[use_index - 1] = Uses[use_index];
00767 }
00768
00769
00770
00771
00772 {
00773 Uses[Uses.size () - 1] = use1;
00774 }
00775 }
00776
00782 void Use::reorder (Use* use1, Use* use2)
00783 {
00784 static UsePtrVector& Uses = uses ();
00785
00786 int use_index;
00787 int index1 = -1;
00788 int index2 = -1;
00789 Use* use;
00790
00791 if (Uses.size () == 0) return;
00792 if (use1 == use2) return;
00793
00794
00795
00796
00797
00798 for (use_index = 0; use_index < Uses.size (); use_index++)
00799 {
00800 use = (Use*) Uses[use_index];
00801
00802 if (use == use1) index1 = use_index;
00803 if (use == use2) index2 = use_index;
00804 }
00805
00806 if (Cmt::get_debug ())
00807 {
00808 cout << "Use::reorder> 1=" << index1 << " 2=" << index2 << endl;
00809 }
00810
00811
00812
00813
00814 if (index1 == -1) return;
00815 if (index2 == -1) return;
00816
00817 if (index2 < index1)
00818 {
00819
00820
00821
00822 return;
00823 }
00824 else
00825 {
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 use = use2;
00840
00841 for (use_index = index2 - 1; use_index >= index1; use_index--)
00842 {
00843 Uses[use_index + 1] = Uses[use_index];
00844 }
00845
00846 Uses[index1] = use;
00847 }
00848 }
00849
00850
00851 void Use::clear_all ()
00852 {
00853 static UsePtrVector& Uses = uses ();
00854 static UseVector& AllUses = all_uses ();
00855
00856 int use_index;
00857
00858 for (use_index = 0; use_index < AllUses.size (); use_index++)
00859 {
00860 Use& use = AllUses[use_index];
00861 use.clear ();
00862 }
00863
00864 Uses.clear ();
00865 AllUses.clear ();
00866 }
00867
00868
00869 void Use::unselect_all ()
00870 {
00871 static UsePtrVector& Uses = uses ();
00872
00873 int use_index;
00874
00875 if (Uses.size () == 0) return;
00876
00877 for (use_index = 0; use_index < Uses.size (); use_index++)
00878 {
00879 Use* use = Uses[use_index];
00880
00881 if (use != 0)
00882 {
00883 use->unselect ();
00884 }
00885 }
00886 }
00887
00888
00889 void Use::undiscard_all ()
00890 {
00891 static UsePtrVector& Uses = uses ();
00892
00893 int use_index;
00894
00895 if (Uses.size () == 0) return;
00896
00897 for (use_index = 0; use_index < Uses.size (); use_index++)
00898 {
00899 Use* use = Uses[use_index];
00900
00901 if (use != 0)
00902 {
00903 use->undiscard ();
00904 }
00905 }
00906 }
00907
00908
00909 void Use::fill_macro_all (cmt_string& buffer, const cmt_string& suffix)
00910 {
00911 UsePtrVector& Uses = uses ();
00912
00913 buffer = "macro_append use_";
00914 buffer += suffix;
00915 buffer += " \" ";
00916 (Use::current()).fill_macro (buffer, suffix);
00917
00918 for (int number = 0; number < Uses.size (); number++)
00919 {
00920 Use* use = Uses[number];
00921
00922 if (use->package == "CMT") continue;
00923 if (use->package == "methods") continue;
00924 if (use->discarded) continue;
00925 if (use->auto_imports == Off) continue;
00926
00927 use->fill_macro (buffer, suffix);
00928 }
00929
00930 buffer += "\"";
00931 }
00932
00933
00934 Use::Use ()
00935 {
00936 done = false;
00937 discarded = false;
00938 auto_imports = Unspecified;
00939
00940 clear ();
00941 }
00942
00943
00944 Use::Use (const cmt_string& new_package,
00945 const cmt_string& new_version,
00946 const cmt_string& new_path)
00947 {
00948 auto_imports = Unspecified;
00949 m_located = false;
00950 set (new_package, new_version, new_path);
00951 }
00952
00953
00954 Use::~Use ()
00955 {
00956 clear ();
00957 }
00958
00959
00960 void Use::clear ()
00961 {
00962 specified_path = "";
00963 path = "";
00964 package = "";
00965 version = "";
00966 author = "";
00967 manager = "";
00968 real_path = "";
00969
00970 prefix = "";
00971 style = mgr_style;
00972 scope = Cmt::get_scope ();
00973 done = false;
00974 discarded = false;
00975 selected = false;
00976 auto_imports = Unspecified;
00977
00978 includes.clear ();
00979 include_path = "";
00980 scripts.clear ();
00981 apply_patterns.clear ();
00982 ignore_patterns.clear ();
00983
00984 sub_uses.clear ();
00985 sub_use_scopes.clear ();
00986 sub_use_auto_imports.clear ();
00987
00988 alternate_versions.clear ();
00989 alternate_paths.clear ();
00990
00991 version_alias = "";
00992 path_alias = "";
00993
00994 m_located = false;
00995 m_has_native_version = false;
00996 }
00997
00998
00999 void Use::set (const cmt_string& new_package,
01000 const cmt_string& new_version,
01001 const cmt_string& new_path,
01002 const cmt_string& new_version_alias,
01003 const cmt_string& new_path_alias)
01004 {
01005 clear ();
01006
01007 package = new_package;
01008 specified_path = new_path;
01009
01010
01011 specified_version = new_version;
01012 version = new_version;
01013 path = specified_path;
01014 Symbol::expand (path);
01015 real_path = "";
01016 style = mgr_style;
01017 scope = Cmt::get_scope ();
01018 done = false;
01019 discarded = false;
01020 Cmt::build_prefix (new_package, prefix);
01021
01022 version_alias = new_version_alias;
01023 path_alias = new_path_alias;
01024 }
01025
01026
01027 void Use::change_path (const cmt_string& new_path)
01028 {
01029
01030
01031
01032
01033
01034 real_path = "";
01035
01036 if (new_path != "")
01037 {
01038 if ((path.size () > 0) &&
01039 (!CmtSystem::absolute_path (path)))
01040 {
01041 real_path = new_path;
01042 real_path += CmtSystem::file_separator ();
01043 real_path += path;
01044 }
01045 else
01046 {
01047 real_path = new_path;
01048 }
01049
01050 }
01051
01052 m_located = true;
01053 }
01054
01055
01056 int Use::reach_package (const cmt_string& from_path)
01057 {
01058
01059
01060
01061
01062
01063
01064
01065 if ((from_path != "") && !CmtSystem::cd (from_path)) return (0);
01066
01067
01068 if (from_path != real_path)
01069 {
01070
01071 if ((path.size () > 0) && (!CmtSystem::absolute_path (path)))
01072 {
01073 if (!CmtSystem::cd (path))
01074 {
01075 return (0);
01076 }
01077 }
01078 }
01079
01080
01081 if (package == CmtSystem::get_home_package ())
01082 {
01083 discarded = 1;
01084 if (!CmtSystem::test_file ("requirements"))
01085 {
01086 return (0);
01087 }
01088 else
01089 {
01090 return (1);
01091 }
01092 }
01093
01094
01095 if (package == CmtSystem::get_user_context_package ())
01096 {
01097 discarded = 1;
01098 if (!CmtSystem::test_file ("requirements"))
01099 {
01100 return (0);
01101 }
01102 else
01103 {
01104 return (1);
01105 }
01106 }
01107
01108
01109 if (!CmtSystem::cd (package))
01110 {
01111 return (0);
01112 }
01113
01114 if (!CmtSystem::cd (version))
01115 {
01116
01117
01118
01119
01120 if ((version == "") ||
01121 (version.find ("*") != cmt_string::npos))
01122 {
01123 static CmtSystem::cmt_string_vector versions;
01124 static cmt_string name;
01125
01126 name = ".";
01127 name += CmtSystem::file_separator ();
01128 if (version == "") name += "*";
01129 else name += version;
01130
01131 CmtSystem::scan_dir (name, versions);
01132
01133 int i;
01134 bool found = false;
01135
01136 for (i = 0; i < versions.size (); i++)
01137 {
01138 const cmt_string& vers = versions[i];
01139
01140 if (Cmt::get_debug ())
01141 {
01142 cout << " ... version " << vers << " exists" << endl;
01143 }
01144
01145 CmtSystem::basename (vers, name);
01146
01147 int v;
01148 int r;
01149 int p;
01150
01151 if (CmtSystem::is_version_directory (name, v, r, p))
01152 {
01153
01154
01155
01156
01157
01158
01159 cmt_string req;
01160
01161 req = name;
01162 req += CmtSystem::file_separator ();
01163 req += "mgr";
01164 req += CmtSystem::file_separator ();
01165 req += "requirements";
01166
01167 if (!CmtSystem::test_file (req))
01168 {
01169 req = name;
01170 req += CmtSystem::file_separator ();
01171 req += "cmt";
01172 req += CmtSystem::file_separator ();
01173 req += "requirements";
01174
01175 if (!CmtSystem::test_file (req)) continue;
01176 }
01177
01178 cmt_string& new_v = alternate_versions.add ();
01179 new_v = name;
01180 cmt_string& new_p = alternate_paths.add ();
01181 new_p = from_path;
01182
01183 found = true;
01184 }
01185 }
01186 }
01187
01188 if (Cmt::get_debug ())
01189 {
01190 cout << " ... end of version scan" << endl;
01191 }
01192
01193
01194
01195
01196
01197
01198 return (0);
01199 }
01200
01201
01202
01203
01204 if (!CmtSystem::test_file ("cmt/requirements"))
01205 {
01206 if (!CmtSystem::test_file ("mgr/requirements"))
01207 {
01208 return (0);
01209 }
01210 else
01211 {
01212 CmtSystem::cd ("mgr");
01213 style = mgr_style;
01214 }
01215 }
01216 else
01217 {
01218 CmtSystem::cd ("cmt");
01219 style = cmt_style;
01220 }
01221
01222 return (1);
01223 }
01224
01225
01226 bool Use::move_to ()
01227 {
01228 if (m_located)
01229 {
01230
01231
01232
01233
01234
01235 if (Cmt::get_debug ())
01236 {
01237 cout << "move_to1> " << real_path << endl;
01238 }
01239
01240 reach_package (real_path);
01241
01242 return (true);
01243 }
01244
01245 cmt_string expanded_path = path;
01246
01247
01248
01249
01250 if (expanded_path == "")
01251 {
01252 if (reach_package (""))
01253 {
01254 if (Cmt::get_debug ())
01255 {
01256 cout << "move_to2> " << expanded_path << endl;
01257 }
01258
01259 change_path (expanded_path);
01260
01261 return (true);
01262 }
01263 else if (alternate_versions.size () > 0)
01264 {
01265 if (select_alternate ())
01266 {
01267 if (Cmt::get_debug ())
01268 {
01269 cout << "move_to5> " << real_path << endl;
01270 }
01271
01272 return (true);
01273 }
01274 }
01275 }
01276
01277
01278
01279
01280
01281 if (CmtSystem::absolute_path (expanded_path))
01282 {
01283 if (reach_package (expanded_path))
01284 {
01285 if (Cmt::get_debug ())
01286 {
01287 cout << "move_to3> " << expanded_path << endl;
01288 }
01289
01290 change_path (expanded_path);
01291
01292 return (true);
01293 }
01294 else if (alternate_versions.size () > 0)
01295 {
01296 if (select_alternate ())
01297 {
01298 if (Cmt::get_debug ())
01299 {
01300 cout << "move_to5> " << real_path << endl;
01301 }
01302
01303 return (true);
01304 }
01305 }
01306 }
01307
01308
01309
01310
01311
01312 static const CmtSystem::cmt_string_vector& search_path = Cmt::get_cmt_path ();
01313 int path_index = 0;
01314
01315 for (path_index = 0; path_index < search_path.size (); path_index++)
01316 {
01317 const cmt_string& next_path = search_path[path_index];
01318
01319 alternate_versions.clear ();
01320 alternate_paths.clear ();
01321
01322 if (reach_package (next_path))
01323 {
01324 if (Cmt::get_debug ())
01325 {
01326 cout << "move_to4> " << next_path << endl;
01327 }
01328
01329 change_path (next_path);
01330
01331 return (true);
01332 }
01333 else if (alternate_versions.size () > 0)
01334 {
01335 if (select_alternate ())
01336 {
01337 if (Cmt::get_debug ())
01338 {
01339 cout << "move_to5> " << real_path << endl;
01340 }
01341
01342 return (true);
01343 }
01344 }
01345 }
01346
01347
01348 return (false);
01349 }
01350
01351
01352 bool Use::select_alternate ()
01353 {
01354 int i;
01355
01356 int v0 = 0;
01357 int r0 = 0;
01358 int p0 = 0;
01359
01360 int v = 0;
01361 int r = 0;
01362 int p = 0;
01363
01364 int selected_index = -1;
01365
01366 for (i = 0; i < alternate_versions.size (); i++)
01367 {
01368 cmt_string& name = alternate_versions[i];
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 if (i == 0)
01381 {
01382 CmtSystem::is_version_directory (name, v0, r0, p0);
01383 selected_index = 0;
01384 }
01385 else
01386 {
01387 CmtSystem::is_version_directory (name, v, r, p);
01388
01389 if (v > v0)
01390 {
01391 selected_index = i;
01392 v0 = v;
01393 r0 = r;
01394 p0 = p;
01395 }
01396 else if (v == v0)
01397 {
01398 if (r > r0)
01399 {
01400 selected_index = i;
01401 r0 = r;
01402 p0 = p;
01403 }
01404 else if (r == r0)
01405 {
01406 if (p > p0)
01407 {
01408 selected_index = i;
01409 p0 = p;
01410 }
01411 }
01412 }
01413 }
01414 }
01415
01416 if (selected_index >= 0)
01417 {
01418 if (CmtSystem::cd (alternate_paths[selected_index]))
01419 {
01420 version = alternate_versions[selected_index];
01421 if (reach_package (alternate_paths[selected_index]))
01422 {
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 if (Cmt::get_debug ())
01433 {
01434 cout << "select_alternate> " << alternate_paths[selected_index] << endl;
01435 }
01436
01437 change_path (alternate_paths[selected_index]);
01438 return (true);
01439 }
01440 }
01441 }
01442
01443 return (false);
01444 }
01445
01446
01447 bool Use::need_new (const cmt_string& path,
01448 const cmt_string& package,
01449 const cmt_string& version,
01450 Use** old_use)
01451 {
01452 bool has_wild_card = (version.find ("*") != cmt_string::npos);
01453
01454 static UsePtrVector& Uses = uses ();
01455 static UseVector& AllUses = all_uses ();
01456
01457 bool result = true;
01458 Use* found = 0;
01459
01460 int use_index;
01461
01462 if (old_use != 0) *old_use = 0;
01463 if (AllUses.size () == 0) return (true);
01464
01465 for (use_index = 0; use_index < Uses.size (); use_index++)
01466 {
01467 Use& use = (*Uses[use_index]);
01468
01469 if (use.package != package) continue;
01470
01471 found = &use;
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481 bool use_has_wild_card = (use.specified_version.find ("*") != cmt_string::npos);
01482
01483 if (has_wild_card && !use_has_wild_card)
01484 {
01485
01486 result = false;
01487 break;
01488 }
01489
01490 if ((version == use.specified_version) &&
01491 (path == use.specified_path))
01492 {
01493
01494 result = false;
01495 break;
01496 }
01497
01498
01499
01500
01501 }
01502
01503 if (old_use != 0) *old_use = found;
01504 return (result);
01505 }
01506
01507
01508
01509
01510
01511
01512
01513 Use* Use::create (const cmt_string& path,
01514 const cmt_string& package,
01515 const cmt_string& version,
01516 const cmt_string& version_alias,
01517 const cmt_string& path_alias)
01518 {
01519 static UseVector& AllUses = all_uses ();
01520
01521
01522 for (int use_index = 0; use_index < AllUses.size (); use_index++)
01523 {
01524 Use& use = AllUses[use_index];
01525
01526 if (use.package == package)
01527 {
01528 if ((use.specified_version == version) &&
01529 (use.specified_path == path)) return (&use);
01530 }
01531 }
01532
01533
01534
01535 Use& use_object = AllUses.add ();
01536 use_object.set (package, version, path, version_alias, path_alias);
01537
01538 return (&use_object);
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548 Use* Use::add (const cmt_string& path,
01549 const cmt_string& package,
01550 const cmt_string& version,
01551 const cmt_string& version_alias,
01552 const cmt_string& path_alias,
01553 Use* context_use,
01554 State specified_auto_imports)
01555 {
01556 static UsePtrVector& Uses = uses ();
01557
01558 bool do_need_new = false;
01559
01560 Use* old_use = 0;
01561 Use* use = 0;
01562
01563 do_need_new = need_new (path, package, version, &old_use);
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 if (do_need_new)
01576 {
01577 use = create (path, package, version, version_alias, path_alias);
01578 }
01579 else
01580 {
01581
01582 use = old_use;
01583 old_use = 0;
01584 }
01585
01586 if (package == CmtSystem::get_home_package ())
01587 {
01588 return (use);
01589 }
01590
01591 if (package == CmtSystem::get_user_context_package ())
01592 {
01593 return (use);
01594 }
01595
01596 cmt_string here = CmtSystem::pwd ();
01597
01598
01599
01600
01601
01602 if (context_use != 0)
01603 {
01604 context_use->sub_uses.push_back (use);
01605 context_use->sub_use_scopes.push_back (Cmt::get_scope ());
01606 context_use->sub_use_auto_imports.push_back (specified_auto_imports);
01607
01608 if (Cmt::get_debug ())
01609 {
01610 cout << "Use::add context(" << context_use->package << ") "
01611 << "[u:" << package
01612 << " s:" << Cmt::get_scope ()
01613 << " ai:" << specified_auto_imports
01614 << "]" << endl;
01615 }
01616 }
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 bool found = use->move_to ();
01633
01634 if (Cmt::get_debug ())
01635 {
01636 cout << "add> use " << use->package
01637 << " " << use->version
01638 << " " << use->path
01639 << " found=" << found
01640 << endl;
01641 }
01642
01643 if (!found)
01644 {
01645 if (!Cmt::get_quiet ())
01646 {
01647 cerr << "#(Warning) package " << use->package <<
01648 " " << use->version << " " << use->path <<
01649 " not found" <<
01650 endl;
01651 }
01652
01653 CmtError::set (CmtError::package_not_found, use->package);
01654 use = 0;
01655 }
01656
01657 if ((old_use != 0) && (use != old_use))
01658 {
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675 if (!found)
01676 {
01677
01678
01679
01680
01681
01682 if (use != 0) use->discard ();
01683 use = old_use;
01684 found = use->move_to ();
01685 }
01686 else
01687 {
01688
01689
01690
01691
01692 VersionSelector& selector = VersionSelector::instance ();
01693 Use* selected_use = selector.operate (old_use, use);
01694
01695
01696
01697
01698
01699 if (use != selected_use)
01700 {
01701 use->discard ();
01702 }
01703
01704 use = selected_use;
01705
01706
01707
01708
01709 found = use->move_to ();
01710 }
01711 }
01712
01713
01714
01715
01716
01717
01718
01719 if (found)
01720 {
01721 bool registered = false;
01722 const Use& cu = Use::current ();
01723
01724
01725
01726
01727 if ((use != &cu) && (package == cu.package))
01728 {
01729
01730 registered = true;
01731 use->done = true;
01732 }
01733 else
01734 {
01735 for (int i = 0; i < Uses.size(); i++)
01736 {
01737 Use* u = Uses[i];
01738
01739 if (u->package == package)
01740 {
01741 registered = true;
01742 Uses[i] = use;
01743 break;
01744 }
01745 }
01746 }
01747
01748 if (!registered) Uses.push_back (use);
01749
01750 if (!use->done && Cmt::get_recursive ())
01751 {
01752 use->done = true;
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01777
01778
01779 if (Cmt::get_debug ())
01780 {
01781 cout << "Parsing requirements file at " << CmtSystem::pwd () << endl;
01782 }
01783
01784 Cmt::parse_requirements ("requirements", use);
01785 }
01786 }
01787
01788 CmtSystem::cd (here);
01789
01790 return (use);
01791 }
01792
01793
01794 void Use::discard ()
01795 {
01796 discarded = true;
01797 }
01798
01799
01800 void Use::undiscard ()
01801 {
01802 discarded = false;
01803 }
01804
01805
01806 void Use::select ()
01807 {
01808 selected = true;
01809 }
01810
01811
01812 void Use::unselect ()
01813 {
01814 selected = false;
01815 }
01816
01817
01818 bool Use::is_selected ()
01819 {
01820 return (selected);
01821 }
01822
01829 bool Use::is_client (const cmt_string& used_package,
01830 const cmt_string& used_version)
01831 {
01832
01833 if ((package == used_package) &&
01834 (version == used_version)) return (true);
01835
01836 if (discarded) return (false);
01837
01838 int i;
01839
01840 for (i = 0; i < sub_uses.size (); i++)
01841 {
01842 Use* use = sub_uses[i];
01843 if (use == 0) continue;
01844
01845 if ((use->package == used_package) &&
01846 (use->version == used_version)) return (true);
01847
01848
01849
01850
01851
01852
01853
01854 }
01855
01856 return (false);
01857 }
01858
01859
01860 void Use::apply_global_patterns ()
01861 {
01862 int i;
01863
01864 Pattern::PatternVector& vector = Pattern::patterns ();
01865
01866 for (i = 0; i < vector.size (); i++)
01867 {
01868 Pattern& p = vector[i];
01869
01870 if (p.global)
01871 {
01872 p.apply (this);
01873 }
01874 }
01875 }
01876
01877
01878 void Use::set_include_path (const cmt_string& new_path)
01879 {
01880 include_path = new_path;
01881 }
01882
01890 void Use::get_full_path (cmt_string& s) const
01891 {
01892 if (real_path == "") s = CmtSystem::pwd ();
01893 else s = real_path;
01894
01895 s += CmtSystem::file_separator ();
01896 s += package;
01897
01898 s += CmtSystem::file_separator ();
01899 s += version;
01900 }
01901
01906 cmt_string Use::get_full_path () const
01907 {
01908 cmt_string result;
01909
01910 get_full_path (result);
01911
01912 return (result);
01913 }
01914
01921 void Use::reduce_path (cmt_string& s) const
01922 {
01923 cmt_string pattern;
01924 get_full_path (pattern);
01925 pattern += CmtSystem::file_separator ();
01926
01927 cmt_string replacement = "${";
01928 replacement += prefix;
01929 replacement += "ROOT}";
01930
01931 s.replace (pattern, replacement);
01932 }
01933
01934
01935 void Use::fill_includes_macro (cmt_string& buffer) const
01936 {
01937 if (include_path == "")
01938 {
01939 buffer += "$(ppcmd)\"$(";
01940 buffer += package;
01941 buffer += "_root)";
01942 buffer += CmtSystem::file_separator ();
01943 buffer += "src\" ";
01944 }
01945 else if (include_path != "none")
01946 {
01947 buffer += "$(ppcmd)\"";
01948 buffer += include_path;
01949 buffer += "\" ";
01950 }
01951
01952 for (int i = 0; i < includes.size (); i++)
01953 {
01954 Include& incl = includes[i];
01955
01956 buffer += "$(ppcmd)\"";
01957 buffer += incl.name;
01958 buffer += "\" ";
01959 }
01960 }
01961
01962
01963 void Use::fill_macro (cmt_string& buffer, const cmt_string& suffix) const
01964 {
01965 buffer += " $(";
01966 buffer += package;
01967 buffer += "_";
01968 buffer += suffix;
01969 buffer += ") ";
01970 }
01971
01976 Use* Use::get_selected_version ()
01977 {
01978 static Use::UsePtrVector& Uses = uses ();
01979
01980
01981
01982 if (!discarded) return (this);
01983
01984 for (int i = 0; i < Uses.size (); i++)
01985 {
01986 Use* u = Uses[i];
01987 if (u == 0) continue;
01988 if (u->discarded) continue;
01989 if (u->package == package)
01990 {
01991
01992 return (u);
01993 }
01994 }
01995
01996 return (0);
01997 }
01998
01999 void Use::set_auto_imports (State new_state)
02000 {
02001 if (Cmt::get_debug ())
02002 {
02003 cout << "Use::set_auto_imports>(" << package << ") "
02004 << auto_imports << " -> " << new_state << endl;
02005 }
02006
02007 if (auto_imports == new_state) return;
02008
02009 State old_state = auto_imports;
02010
02011 auto_imports = new_state;
02012
02013
02014
02015 if ((old_state == Off) && (new_state == On))
02016 {
02017 cmt_string s;
02018 static const cmt_string state_text[] = {"Unspecified", "Off", "On"};
02019
02020 if (Cmt::get_debug ())
02021 {
02022 s = "Use::set_auto_imports>(";
02023 s += package;
02024 s += ") ";
02025
02026 cout << s << endl;
02027 }
02028
02029 for (int i = 0; i < sub_uses.size (); i++)
02030 {
02031 Use* u = sub_uses[i];
02032 State state = sub_use_auto_imports[i];
02033
02034 if (Cmt::get_debug ())
02035 {
02036 s += " ";
02037 s += u->package;
02038 s += "(";
02039 s += state_text[state];
02040 s += ")";
02041 }
02042
02043 if (state == Unspecified)
02044 {
02045 u->set_auto_imports (On);
02046 }
02047 }
02048
02049 if (Cmt::get_debug ())
02050 {
02051 cout << s << endl;
02052 }
02053 }
02054 }
02055
02056 void Use::set_native_version (bool state)
02057 {
02058 m_has_native_version = state;
02059 }
02060
02061 bool Use::has_native_version () const
02062 {
02063 return (m_has_native_version);
02064 }
02065
02066
02067 bool Use::get_paths (Use* to, UsePtrVector& list)
02068 {
02069 bool found = false;
02070 bool cycle = false;
02071
02072 static int level = 0;
02073 static UsePtrVector stack;
02074
02075 if (level == 0)
02076 {
02077 stack.clear ();
02078 }
02079
02080
02081 for (int k = 0; k < stack.size (); k++)
02082 {
02083 Use* u = stack[k];
02084 if (u == this)
02085 {
02086 if (Cmt::get_debug ())
02087 {
02088 cout << "Use::get_paths." << level << ">" << package << " cycle " << endl;
02089 }
02090
02091 return (false);
02092 }
02093 }
02094
02095
02096 if (stack.size () <= level)
02097 {
02098 stack.push_back (this);
02099 }
02100 else
02101 {
02102 stack[level] = this;
02103 }
02104
02105
02106
02107 if (Cmt::get_debug ())
02108 {
02109 cout << "Use::get_paths." << level << ">" << package << " to=" << to->package << " list[" << list.size () << "]" << endl;
02110 }
02111
02112 if (this == to)
02113 {
02114 found = true;
02115 }
02116 else
02117 {
02118 for (int n = 0; n < sub_uses.size (); n++)
02119 {
02120 Use* use = sub_uses[n];
02121
02122 if (use == 0) continue;
02123
02124 if (Cmt::get_debug ())
02125 {
02126 cout << " Use::get_paths." << level << "> try1 sub=" << use->package << endl;
02127 }
02128
02129 if (use->discarded)
02130 {
02131 Use* u;
02132
02133 u = use->get_selected_version ();
02134 if (u == 0) continue;
02135
02136 use = u;
02137 }
02138
02139 cycle = false;
02140
02141
02142
02143 for (int m = 0; m < list.size (); m++)
02144 {
02145 Use* u = list[m];
02146 if (u == use)
02147 {
02148 cycle = true;
02149 break;
02150 }
02151 }
02152
02153 if (cycle)
02154 {
02155 found = true;
02156 continue;
02157 }
02158
02159 if (Cmt::get_debug ())
02160 {
02161 cout << " Use::get_paths." << level << "> try2 sub=" << use->package << endl;
02162 }
02163
02164 level++;
02165 bool r = use->get_paths (to, list);
02166 level--;
02167
02168 if (r)
02169 {
02170 found = true;
02171 }
02172 }
02173 }
02174
02175 if (found)
02176 {
02177 cycle = false;
02178
02179 for (int m = 0; m < list.size (); m++)
02180 {
02181 Use* u = list[m];
02182 if (u == this)
02183 {
02184 cycle = true;
02185 break;
02186 }
02187 }
02188
02189 if (!cycle)
02190 {
02191 if (Cmt::get_debug ())
02192 {
02193 cout << "Use::get_paths." << level << "> push " << package << endl;
02194 }
02195 list.push_back (this);
02196 }
02197 }
02198
02199 return (found);
02200 }
02201
02202
02203 bool Use::located () const
02204 {
02205 return (m_located);
02206 }
02207
02208
02209 void Use::show_sub_uses (bool skip_discarded)
02210 {
02211 int n;
02212 Use* use;
02213 static int level = 0;
02214
02215 if (skip_discarded && discarded) return;
02216
02217 if (level > 0)
02218 {
02219 cout << "# ";
02220 for (n = 0; n < (level-1); n++) cout << " ";
02221
02222 cout << "use " << package << " " << specified_version;
02223
02224 if (specified_path != "") cout << " " << specified_path;
02225
02226 if (version_alias != "")
02227 {
02228 cout << " | " << version_alias << " " << path_alias;
02229 }
02230
02231 if (scope == ScopeUnspecified) cout << " unspecified";
02232 else if (scope != ScopePublic) cout << " (private)";
02233
02234
02235 if (auto_imports == Off) cout << " (no_auto_imports)";
02236
02237 if (m_has_native_version)
02238 {
02239 cmt_string n = package;
02240 n += "_native_version";
02241
02242 Symbol* s = Symbol::find (n);
02243 if (s != 0)
02244 {
02245 cmt_string value = s->resolve_macro_value ();
02246 cout << " (native_version=" << value << ")";
02247 }
02248 }
02249
02250 cout << endl;
02251 }
02252
02253 if (selected) return;
02254 selected = true;
02255
02256 level++;
02257 for (n = 0; n < sub_uses.size (); n++)
02258 {
02259 use = sub_uses[n];
02260 if (use == 0) continue;
02261
02262 ScopeType saved_scope = use->scope;
02263 State saved_state = use->auto_imports;
02264
02265 use->scope = sub_use_scopes[n];
02266 use->auto_imports = sub_use_auto_imports[n];
02267
02268 use->show_sub_uses (skip_discarded);
02269
02270 use->scope = saved_scope;
02271 use->auto_imports = saved_state;
02272 }
02273 level--;
02274 }
02275
02276
02277 Use& Use::current ()
02278 {
02279 static UseVector& AllUses = all_uses ();
02280 static Use* current_use = 0;
02281
02282 if ((current_use == 0) || (AllUses.size () == 0))
02283 {
02284 Use& use_object = AllUses.add ();
02285 current_use = &use_object;
02286 }
02287
02288 return (*current_use);
02289 }
02290
02291
02292 const Use& Use::const_current ()
02293 {
02294 const Use& use = Use::current ();
02295
02296 return (use);
02297 }
02298
02299
02300 Use::UseVector& Use::all_uses ()
02301 {
02302 static Database& db = Database::instance ();
02303 static UseVector& AllUses = db.all_uses ();
02304
02305 return (AllUses);
02306 }
02307
02308
02309 Use::UsePtrVector& Use::uses ()
02310 {
02311 static Database& db = Database::instance ();
02312 static UsePtrVector& Uses = db.uses ();
02313
02314 return (Uses);
02315 }
02316
02317
02318 VersionSelector& VersionSelector::instance ()
02319 {
02320 static BestFitSelector best_fit;
02321 static BestFitNoCheckSelector best_fit_no_check;
02322 static FirstChoiceSelector first_choice;
02323 static LastChoiceSelector last_choice;
02324 static KeepAllSelector keep_all;
02325
02326 switch (Cmt::get_current_strategy ())
02327 {
02328 case BestFit:
02329 return (best_fit);
02330 case BestFitNoCheck:
02331 return (best_fit_no_check);
02332 case FirstChoice:
02333 return (first_choice);
02334 case LastChoice:
02335 return (last_choice);
02336 case KeepAll:
02337 return (keep_all);
02338 default:
02339 return (best_fit);
02340 }
02341 }
02342
02343
02344
02345
02346
02347
02348
02349 Use* BestFitSelector::operate (Use* ref_use, Use* new_use)
02350 {
02351 Use* selected = ref_use;
02352
02353 int old_v = -1;
02354 int old_r = -1;
02355 int old_p = -1;
02356 cmt_string old_pp;
02357
02358 int new_v = -1;
02359 int new_r = -1;
02360 int new_p = -1;
02361 cmt_string new_pp;
02362
02363 int alias_v = -1;
02364 int alias_r = -1;
02365 int alias_p = -1;
02366 cmt_string alias_pp;
02367
02368 enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
02369
02370 CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
02371 old_pp = ref_use->path;
02372
02373 CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
02374 new_pp = new_use->path;
02375
02376 if (new_use->version_alias != "")
02377 {
02378 has_alias = new_has_alias;
02379 CmtSystem::is_version_directory (new_use->version_alias,
02380 alias_v, alias_r, alias_p);
02381 alias_pp = new_use->path_alias;
02382 }
02383 else if (ref_use->version_alias != "")
02384 {
02385 has_alias = ref_has_alias;
02386 CmtSystem::is_version_directory (ref_use->version_alias,
02387 alias_v, alias_r, alias_p);
02388 alias_pp = ref_use->path_alias;
02389 }
02390
02391 ref_use->undiscard ();
02392 new_use->undiscard ();
02393
02394 if (new_v != old_v)
02395 {
02396 if (has_alias != no_alias)
02397 {
02398 if (has_alias == new_has_alias)
02399 {
02400 new_v = alias_v;
02401 new_r = alias_r;
02402 new_p = alias_p;
02403 new_pp = alias_pp;
02404 }
02405 else if (has_alias == ref_has_alias)
02406 {
02407 old_v = alias_v;
02408 old_r = alias_r;
02409 old_p = alias_p;
02410 old_pp = alias_pp;
02411 }
02412 }
02413 }
02414
02415 if (new_v != old_v)
02416 {
02417 if (!Cmt::get_quiet ())
02418 cout << "# Required version " << new_use->version <<
02419 " of package " << ref_use->package <<
02420 " incompatible with selected version " << ref_use->version <<
02421 endl;
02422
02423 CmtError::set (CmtError::version_conflict, "BestFitSelector::operate> ");
02424
02425 if (ref_use != new_use) new_use->discard ();
02426 }
02427 else if (new_r < old_r)
02428 {
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439 bool new_is_wildcarded = false;
02440 bool ref_is_wildcarded = false;
02441
02442 if (new_use->specified_version.find ("*") != cmt_string::npos)
02443 {
02444 int nv = -1;
02445 int nr = -1;
02446 int np = -1;
02447
02448 CmtSystem::is_version_directory (new_use->specified_version, nv, nr, np);
02449 if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
02450 }
02451
02452 if (ref_use->specified_version.find ("*") != cmt_string::npos)
02453 {
02454 int nv = -1;
02455 int nr = -1;
02456 int np = -1;
02457
02458 CmtSystem::is_version_directory (ref_use->specified_version, nv, nr, np);
02459 if ((nv == -1) || (nr == -1)) new_is_wildcarded = true;
02460 }
02461
02462 if (!ref_is_wildcarded && new_is_wildcarded)
02463 {
02464 if (ref_use != new_use) ref_use->discard ();
02465 selected = new_use;
02466 selected->done = false;
02467 }
02468 else
02469 {
02470 if (!Cmt::get_quiet ())
02471 cout << "# keep release " << ref_use->version <<
02472 " of package " << ref_use->package <<
02473 " (ignore release " << new_use->version << ")" <<
02474 endl;
02475
02476 if (ref_use != new_use) new_use->discard ();
02477 }
02478 }
02479 else if (new_r > old_r)
02480 {
02481 if (!Cmt::get_quiet ())
02482 {
02483 cout << "# Select release " << new_use->version <<
02484 " of package " << ref_use->package <<
02485 " instead of existing " << ref_use->version <<
02486 endl;
02487 }
02488
02489 if (ref_use != new_use) ref_use->discard ();
02490 selected = new_use;
02491 selected->done = false;
02492 }
02493 else if (new_p > old_p)
02494 {
02495 if (!Cmt::get_quiet ())
02496 {
02497 cout << "# Select patch " << new_use->version <<
02498 " of package " << ref_use->package <<
02499 " instead of existing " << ref_use->version <<
02500 endl;
02501 }
02502
02503 if (ref_use != new_use) ref_use->discard ();
02504 selected = new_use;
02505 selected->done = false;
02506 }
02507 else if (new_pp != old_pp)
02508 {
02509 if (ref_use != new_use) ref_use->discard ();
02510 selected = new_use;
02511 selected->done = false;
02512 }
02513
02514 return (selected);
02515 }
02516
02517
02518
02519
02520
02521
02522
02523 Use* BestFitNoCheckSelector::operate (Use* ref_use, Use* new_use)
02524 {
02525 Use* selected = ref_use;
02526
02527 int old_v = -1;
02528 int old_r = -1;
02529 int old_p = -1;
02530 cmt_string old_pp;
02531
02532 int new_v = -1;
02533 int new_r = -1;
02534 int new_p = -1;
02535 cmt_string new_pp;
02536
02537 int alias_v = -1;
02538 int alias_r = -1;
02539 int alias_p = -1;
02540 cmt_string alias_pp;
02541
02542 enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias;
02543
02544 CmtSystem::is_version_directory (ref_use->version, old_v, old_r, old_p);
02545 old_pp = ref_use->path;
02546
02547 CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p);
02548 new_pp = new_use->path;
02549
02550 if (new_use->version_alias != "")
02551 {
02552 has_alias = new_has_alias;
02553 CmtSystem::is_version_directory (new_use->version_alias,
02554 alias_v, alias_r, alias_p);
02555 alias_pp = new_use->path_alias;
02556 }
02557 else if (ref_use->version_alias != "")
02558 {
02559 has_alias = ref_has_alias;
02560 CmtSystem::is_version_directory (ref_use->version_alias,
02561 alias_v, alias_r, alias_p);
02562 alias_pp = ref_use->path_alias;
02563 }
02564
02565 ref_use->undiscard ();
02566 new_use->undiscard ();
02567
02568 if (new_v != old_v)
02569 {
02570 if (has_alias != no_alias)
02571 {
02572 if (has_alias == new_has_alias)
02573 {
02574 new_v = alias_v;
02575 new_r = alias_r;
02576 new_p = alias_p;
02577 new_pp = alias_pp;
02578 }
02579 else if (has_alias == ref_has_alias)
02580 {
02581 old_v = alias_v;
02582 old_r = alias_r;
02583 old_p = alias_p;
02584 old_pp = alias_pp;
02585 }
02586 }
02587 }
02588
02589 if (new_v < old_v)
02590 {
02591 if (!Cmt::get_quiet ())
02592 {
02593 cout << "# Keep version " << ref_use->version <<
02594 " of package " << ref_use->package <<
02595 " (ignore version " << new_use->version << ")" <<
02596 endl;
02597 }
02598
02599 if (ref_use != new_use) new_use->discard ();
02600 }
02601 else if (new_v > old_v)
02602 {
02603 if (!Cmt::get_quiet ())
02604 {
02605 cout << "# Select version " << new_use->version <<
02606 " of package " << ref_use->package <<
02607 " instead of existing " << ref_use->version <<
02608 endl;
02609 }
02610
02611 if (ref_use != new_use) ref_use->discard ();
02612 selected = new_use;
02613 selected->done = false;
02614 }
02615 else if (new_r < old_r)
02616 {
02617 if (!Cmt::get_quiet ())
02618 {
02619 cout << "# keep release " << ref_use->version <<
02620 " of package " << ref_use->package <<
02621 " (ignore release " << new_use->version << ")" <<
02622 endl;
02623 }
02624
02625 if (ref_use != new_use) new_use->discard ();
02626 }
02627 else if (new_r > old_r)
02628 {
02629 if (!Cmt::get_quiet ())
02630 {
02631 cout << "# Select release " << new_use->version <<
02632 " of package " << ref_use->package <<
02633 " instead of existing " << ref_use->version <<
02634 endl;
02635 }
02636
02637 if (ref_use != new_use) ref_use->discard ();
02638 selected = new_use;
02639 selected->done = false;
02640 }
02641 else if (new_p > old_p)
02642 {
02643 if (!Cmt::get_quiet ())
02644 {
02645 cout << "# Select patch " << new_use->version <<
02646 " of package " << ref_use->package <<
02647 " instead of existing " << ref_use->version <<
02648 endl;
02649 }
02650
02651 if (ref_use != new_use) ref_use->discard ();
02652 selected = new_use;
02653 selected->done = false;
02654 }
02655 else if (new_pp != old_pp)
02656 {
02657 if (ref_use != new_use) ref_use->discard ();
02658 selected = new_use;
02659 selected->done = false;
02660 }
02661
02662 return (selected);
02663 }
02664
02665
02666 Use* FirstChoiceSelector::operate (Use* ref_use, Use* new_use)
02667 {
02668 ref_use->undiscard ();
02669 new_use->undiscard ();
02670
02671 new_use->done = false;
02672 if (ref_use != new_use) new_use->discard ();
02673 return (ref_use);
02674 }
02675
02676
02677 Use* LastChoiceSelector::operate (Use* ref_use, Use* new_use)
02678 {
02679 ref_use->undiscard ();
02680 new_use->undiscard ();
02681
02682 new_use->done = false;
02683 if (ref_use != new_use) ref_use->discard ();
02684 return (new_use);
02685 }
02686
02687
02688 Use* KeepAllSelector::operate (Use* ref_use, Use* new_use)
02689 {
02690 ref_use->undiscard ();
02691 new_use->undiscard ();
02692
02693 new_use->done = false;
02694 return (new_use);
02695 }