Public Member Functions | |
Use * | operate (Use *ref_use, Use *new_use) |
|
Definition at line 3834 of file cmt_use.cxx. References Use::discard(), Use::done, Use::get_package_name(), Cmt::get_quiet(), CmtSystem::getenv(), CmtSystem::is_version_directory(), Use::path, Use::path_alias, Use::real_path, Use::specified_version, Use::undiscard(), Use::version, and Use::version_alias. Referenced by Use::add().
03835 { 03836 Use* selected = ref_use; 03837 03838 int ref_v = -1; 03839 int ref_r = -1; 03840 int ref_p = -1; 03841 cmt_string ref_pp; 03842 03843 int new_v = -1; 03844 int new_r = -1; 03845 int new_p = -1; 03846 cmt_string new_pp; 03847 03848 int alias_v = -1; 03849 int alias_r = -1; 03850 int alias_p = -1; 03851 cmt_string alias_pp; 03852 03853 enum { no_alias, new_has_alias, ref_has_alias } has_alias = no_alias; 03854 03855 // First analyze specified versions 03856 cmt_string ref_version = ref_use->specified_version; 03857 cmt_string new_version = new_use->specified_version; 03858 03859 CmtSystem::is_version_directory (ref_version, ref_v, ref_r, ref_p); 03860 ref_pp = ref_use->path; 03861 03862 CmtSystem::is_version_directory (new_version, new_v, new_r, new_p); 03863 new_pp = new_use->path; 03864 03865 if (new_use->version_alias != "") 03866 { 03867 has_alias = new_has_alias; 03868 CmtSystem::is_version_directory (new_use->version_alias, 03869 alias_v, alias_r, alias_p); 03870 alias_pp = new_use->path_alias; 03871 } 03872 else if (ref_use->version_alias != "") 03873 { 03874 has_alias = ref_has_alias; 03875 CmtSystem::is_version_directory (ref_use->version_alias, 03876 alias_v, alias_r, alias_p); 03877 alias_pp = ref_use->path_alias; 03878 } 03879 03880 ref_use->undiscard (); 03881 new_use->undiscard (); 03882 03883 if (new_v != ref_v) 03884 { 03885 if (has_alias != no_alias) 03886 { 03887 if (has_alias == new_has_alias) 03888 { 03889 new_v = alias_v; 03890 new_r = alias_r; 03891 new_p = alias_p; 03892 new_pp = alias_pp; 03893 } 03894 else if (has_alias == ref_has_alias) 03895 { 03896 ref_v = alias_v; 03897 ref_r = alias_r; 03898 ref_p = alias_p; 03899 ref_pp = alias_pp; 03900 } 03901 } 03902 } 03903 03904 bool ref_v_wildcarded = ((ref_v) == -1); 03905 bool ref_r_wildcarded = ((ref_r) == -1); 03906 bool ref_p_wildcarded = ((ref_p) == -1); 03907 03908 bool ref_v_explicit = !ref_v_wildcarded; 03909 bool ref_r_explicit = !ref_r_wildcarded; 03910 bool ref_p_explicit = !ref_p_wildcarded; 03911 03912 bool new_v_wildcarded = ((new_v) == -1); 03913 bool new_r_wildcarded = ((new_r) == -1); 03914 bool new_p_wildcarded = ((new_p) == -1); 03915 03916 bool new_v_explicit = !new_v_wildcarded; 03917 bool new_r_explicit = !new_r_wildcarded; 03918 bool new_p_explicit = !new_p_wildcarded; 03919 03920 bool verbose = (CmtSystem::getenv ("CMTVERBOSE") != ""); 03921 03922 cmt_string ref_vc = ref_v_wildcarded ? "wildcarded" : "explicit"; 03923 cmt_string ref_rc = ref_r_wildcarded ? "wildcarded" : "explicit"; 03924 cmt_string ref_pc = ref_p_wildcarded ? "wildcarded" : "explicit"; 03925 03926 cmt_string new_vc = new_v_wildcarded ? "wildcarded" : "explicit"; 03927 cmt_string new_rc = new_r_wildcarded ? "wildcarded" : "explicit"; 03928 cmt_string new_pc = new_p_wildcarded ? "wildcarded" : "explicit"; 03929 03930 // Now compute effective version identifiers 03931 CmtSystem::is_version_directory (ref_use->version, ref_v, ref_r, ref_p); 03932 CmtSystem::is_version_directory (new_use->version, new_v, new_r, new_p); 03933 03934 cmt_string new_selected_version = new_use->version; 03935 03936 if (new_v_explicit && ref_v_explicit && (new_v != ref_v)) 03937 { 03938 /* 03939 if (verbose && !Cmt::get_quiet ()) 03940 { 03941 cerr << "# Required explicit version " << new_version 03942 << " of package " << ref_use->get_package_name () 03943 << " incompatible with selected explicit version " << ref_version 03944 << endl; 03945 } 03946 03947 CmtError::set (CmtError::version_conflict, "BestFitSelector::operate> "); 03948 03949 if (ref_use != new_use) new_use->discard (); 03950 */ 03951 03952 if (new_v > ref_v) 03953 { 03954 if (verbose && !Cmt::get_quiet ()) 03955 { 03956 cerr << "# Select " << new_vc << " version " << new_version 03957 << " of package " << ref_use->get_package_name () 03958 << " instead of existing " << ref_vc << " " << ref_version 03959 << endl; 03960 } 03961 03962 if (ref_use != new_use) ref_use->discard (); 03963 selected = new_use; 03964 selected->done = false; // Will read the new requirements 03965 } 03966 } 03967 else if (new_v_wildcarded || ref_v_wildcarded) 03968 { 03969 // at least one of ref or new is wildcarded 03970 03971 // 03972 // we plan to discard new_use, but if it was specified as explicit 03973 // and ref_use was wildcarded then new_use will win !! 03974 // 03975 // So then we'll have to understand where are the wild 03976 // cards... If they are on v or r, then we consider them. 03977 // 03978 // 03979 03980 if (ref_v_wildcarded && new_v_explicit) 03981 { 03982 if ((ref_use->real_path != new_use->real_path) || 03983 (ref_use->version != new_use->version)) 03984 { 03985 if (ref_use != new_use) ref_use->discard (); 03986 selected = new_use; 03987 selected->done = false; // Will read the new requirements 03988 03989 if (verbose && !Cmt::get_quiet ()) 03990 { 03991 cerr << "# Select explicit version " << new_version 03992 << "(" << new_use->version << ")" 03993 << " of package " << ref_use->get_package_name () 03994 << " instead of existing wildcarded " << ref_version 03995 << "(" << ref_use->version << ")" 03996 << endl; 03997 } 03998 } 03999 else 04000 { 04001 if (ref_use != new_use) new_use->discard (); 04002 //ref_use->version = new_selected_version; 04003 } 04004 } 04005 else 04006 { 04007 // ref is explicit or new is wildcarded 04008 04009 /* 04010 if (verbose && !Cmt::get_quiet ()) 04011 { 04012 cerr << "# keep " << ref_vc << " version " << ref_version 04013 << " of package " << ref_use->get_package_name () 04014 << " (ignore " << new_vc << " version " << new_version << ")" 04015 << endl; 04016 } 04017 */ 04018 04019 if (ref_use != new_use) new_use->discard (); 04020 } 04021 } 04022 else if (new_r_wildcarded || ref_r_wildcarded || (new_r < ref_r)) 04023 { 04024 // 04025 // we plan to discard new_use, but if it was specified as explicit 04026 // and ref_use was wildcarded then new_use will win !! 04027 // 04028 // So then we'll have to understand where are the wild 04029 // cards... If they are on v or r, then we consider them. 04030 // 04031 // 04032 04033 if (ref_r_wildcarded && new_r_explicit) 04034 { 04035 // ref has wild card and new has not => new wins 04036 04037 if ((ref_use->real_path != new_use->real_path) || 04038 (ref_use->version != new_use->version)) 04039 { 04040 if (ref_use != new_use) ref_use->discard (); 04041 selected = new_use; 04042 selected->done = false; // Will read the new requirements 04043 04044 if (verbose && !Cmt::get_quiet ()) 04045 { 04046 cerr << "# Select explicit release " << new_version 04047 << " of package " << ref_use->get_package_name () 04048 << " instead of existing wildcarded " << ref_version 04049 << endl; 04050 } 04051 } 04052 else 04053 { 04054 // Just adapt version with new one. 04055 04056 if (ref_use != new_use) new_use->discard (); 04057 //ref_use->version = new_selected_version; 04058 } 04059 } 04060 else 04061 { 04062 /* 04063 if (verbose &&!Cmt::get_quiet ()) 04064 { 04065 cerr << "# keep " << ref_rc << " release " << ref_version 04066 << " of package " << ref_use->get_package_name () 04067 << " (ignore " << new_rc << " release " << new_version << ")" 04068 << endl; 04069 } 04070 */ 04071 04072 if (ref_use != new_use) new_use->discard (); 04073 } 04074 } 04075 else if (new_r > ref_r) 04076 { 04077 if (verbose && !Cmt::get_quiet ()) 04078 { 04079 cerr << "# Select " << new_rc << " release " << new_version 04080 << " of package " << ref_use->get_package_name () 04081 << " instead of existing " << ref_rc << " " << ref_version 04082 << endl; 04083 } 04084 04085 if (ref_use != new_use) ref_use->discard (); 04086 selected = new_use; 04087 selected->done = false; // Will read the new requirements 04088 } 04089 else if (new_p_wildcarded || ref_p_wildcarded || (new_p < ref_p)) 04090 { 04091 // 04092 // we plan to discard new_use, but if it was specified as explicit 04093 // and ref_use was wildcarded then new_use will win !! 04094 // 04095 04096 if (ref_p_wildcarded && new_p_explicit) 04097 { 04098 if ((ref_use->real_path != new_use->real_path) || 04099 (ref_use->version != new_use->version)) 04100 { 04101 if (ref_use != new_use) ref_use->discard (); 04102 selected = new_use; 04103 selected->done = false; // Will read the new requirements 04104 04105 if (verbose && !Cmt::get_quiet ()) 04106 { 04107 cerr << "# Select explicit patch " << new_version 04108 << " of package " << ref_use->get_package_name () 04109 << " instead of existing wildcarded " << ref_version 04110 << endl; 04111 } 04112 } 04113 else 04114 { 04115 if (ref_use != new_use) new_use->discard (); 04116 ref_use->version = new_selected_version; 04117 } 04118 } 04119 else 04120 { 04121 /* 04122 if (verbose && !Cmt::get_quiet ()) 04123 { 04124 cerr << "# keep " << ref_pc << " patch " << ref_version 04125 << " [" << ref_use->specified_version << "]" 04126 << " of package " << ref_use->get_package_name () 04127 << " (ignore " << new_pc << " version " << new_version << ")" 04128 << " [" << new_use->specified_version << "]" 04129 << endl; 04130 } 04131 */ 04132 04133 if (ref_use != new_use) new_use->discard (); 04134 } 04135 } 04136 else if (new_p > ref_p) 04137 { 04138 if (verbose && !Cmt::get_quiet ()) 04139 { 04140 cerr << "# Select " << new_pc << " patch " << new_version 04141 << " of package " << ref_use->get_package_name () 04142 << " instead of existing " << ref_pc << " " << ref_version 04143 << endl; 04144 } 04145 04146 if (ref_use != new_use) ref_use->discard (); 04147 selected = new_use; 04148 selected->done = false; // Will read the new requirements 04149 } 04150 else if (new_pp != ref_pp) // same version-r-p but from different path 04151 { 04152 if (ref_use != new_use) ref_use->discard (); 04153 selected = new_use; 04154 selected->done = false; // Will read the new requirements 04155 } 04156 04157 return (selected); 04158 } |