00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <map>
00023 #include <sstream>
00024
00025 #include "zypp/solver/detail/ResolverInfo.h"
00026 #include "zypp/Repository.h"
00027 #include "zypp/Capability.h"
00028 #include "zypp/base/String.h"
00029 #include "zypp/base/Gettext.h"
00030 #include "zypp/base/Logger.h"
00031
00033 namespace zypp
00034 {
00035
00036 namespace solver
00037 {
00038
00039 namespace detail
00040 {
00041
00042 using namespace std;
00043
00044 IMPL_PTR_TYPE(ResolverInfo);
00045
00046
00047
00048 #define RIT(x) RESOLVER_INFO_TYPE_ ## x, #x
00049 static struct {
00050 ResolverInfoType type;
00051 const char *typestr;
00052 const char *str;
00053 } type_str_table[] = {
00054 { RIT(NEEDED_BY), "needed_by" },
00055 { RIT(CONFLICTS_WITH), "conflicts_with" },
00056 { RIT(OBSOLETES), "obsoletes" },
00057 { RIT(DEPENDS_ON), "depended_on" },
00058 { RIT(CHILD_OF), "child_of" },
00059 { RIT(MISSING_REQ), "missing_req" },
00060
00061 { RIT(INVALID_SOLUTION), "Marking this resolution attempt as invalid" },
00062 { RIT(UNINSTALLABLE), "Marking p as uninstallable" },
00063 { RIT(REJECT_INSTALL), "p is scheduled to be installed, but this is not possible because of dependency problems." },
00064 { RIT(INSTALL_TO_BE_UNINSTALLED), "Can't install p since it is already marked as needing to be uninstalled" },
00065 { RIT(INSTALL_UNNEEDED), "Can't install p since it is does not apply to this system." },
00066 { RIT(INSTALL_PARALLEL), "Can't install p, since a resolvable of the same name is already marked as needing to be installed." },
00067 { RIT(INCOMPLETES), "This would invalidate p" },
00068
00069 { RIT(ESTABLISHING), "Establishing p" },
00070
00071 { RIT(INSTALLING), "Installing p" },
00072 { RIT(UPDATING), "Updating p" },
00073 { RIT(SKIPPING), "Skipping p, already installed" },
00074
00075 { RIT(NO_OTHER_PROVIDER), "There are no alternative installed providers of c [for p]" },
00076 { RIT(NO_PROVIDER), "There are no installable providers of c [for p]" },
00077 { RIT(NO_UPGRADE), "Upgrade to q to avoid removing p is not possible." },
00078 { RIT(UNINSTALL_PROVIDER), "p provides c but is scheduled to be uninstalled" },
00079 { RIT(KEEP_PROVIDER), "p provides c but is scheduled to be kept" },
00080 { RIT(PARALLEL_PROVIDER), "p provides c but another version is already installed" },
00081 { RIT(NOT_INSTALLABLE_PROVIDER), "p provides c but is uninstallable" },
00082 { RIT(LOCKED_PROVIDER), "p provides c but is locked" },
00083 { RIT(OTHER_ARCH_PROVIDER), "p provides c but has other architecture" },
00084 { RIT(OTHER_VENDOR_PROVIDER), "p provides c but has other vendor" },
00085 { RIT(CANT_SATISFY), "Can't satisfy requirement c" },
00086
00087 { RIT(UNINSTALL_TO_BE_INSTALLED), "p is to-be-installed, so it won't be unlinked." },
00088 { RIT(UNINSTALL_INSTALLED), "p is required by installed, so it won't be unlinked." },
00089 { RIT(UNINSTALL_LOCKED), "cant uninstall, its locked" },
00090
00091 { RIT(CONFLICT_CANT_INSTALL), "to-be-installed p conflicts with q due to c" },
00092 { RIT(CONFLICT_UNINSTALLABLE), "uninstalled p is marked uninstallable it conflicts [with q] due to c" },
00093 { RIT(INVALID), "invalid" },
00094 { RIT(INVALID), NULL }
00095 };
00096 #undef RIT
00097
00098 static const char *
00099 info_type_to_string (ResolverInfoType type)
00100 {
00101 int i;
00102
00103 for (i = 0; type_str_table[i].str != NULL; ++i) {
00104 if (type == type_str_table[i].type)
00105 return type_str_table[i].typestr;
00106 }
00107
00108 return "?ResolverInfoType?";
00109 }
00110
00111
00112 static const char *
00113 info_type_to_message (ResolverInfoType type)
00114 {
00115 int i;
00116
00117 for (i = 0; type_str_table[i].str != NULL; ++i) {
00118 if (type == type_str_table[i].type)
00119 return type_str_table[i].str;
00120 }
00121
00122 return "?ResolverInfoType?";
00123 }
00124
00125
00126 ResolverInfoType
00127 resolver_info_type_from_string (const char *str)
00128 {
00129 int i;
00130
00131 if (str == NULL) return RESOLVER_INFO_TYPE_INVALID;
00132
00133 for (i = 0; type_str_table[i].str != NULL; ++i) {
00134 if (strcasecmp (str, type_str_table[i].str) == 0)
00135 return type_str_table[i].type;
00136 }
00137
00138 return RESOLVER_INFO_TYPE_INVALID;
00139 }
00140
00141 string
00142 ResolverInfo::toString (PoolItem_Ref item, bool shortVersion)
00143 {
00144 ostringstream os;
00145 if (!item) return "";
00146
00147 if (item->kind() != ResTraits<zypp::Package>::kind)
00148 os << item->kind() << ':';
00149 os << item->name();
00150 if (!shortVersion) {
00151 os << '-' << item->edition();
00152 if (item->arch() != "") {
00153 os << '.' << item->arch();
00154 }
00155 Repository s = item->repository();
00156 if (s) {
00157 string alias = s.info().alias();
00158 if (!alias.empty()
00159 && alias != "@system")
00160 {
00161 os << '[' << s.info().alias() << ']';
00162 }
00163 }
00164 }
00165 return os.str();
00166 }
00167
00168
00169 string
00170 ResolverInfo::toString (const Capability & capability)
00171 {
00172 ostringstream os;
00173 os << capability.asString();
00174 return os.str();
00175 }
00176
00177 string
00178 ResolverInfo::message( ) const
00179 {
00180 return string(info_type_to_message(_type)) + " " + toString(_affected);
00181 }
00182
00183
00184 std::ostream &
00185 ResolverInfo::dumpOn( std::ostream & os ) const
00186 {
00187 os << "ResolverInfo<";
00188 os << info_type_to_string (_type);
00189 os << "> ";
00190
00191 if (_affected) {
00192 os << toString (_affected);
00193 }
00194
00195 if (_error) os << " " << _(" Error!");
00196 if (_important) os << " " << _(" Important!");
00197
00198 return os;
00199 }
00200
00201
00202
00203 ResolverInfo::ResolverInfo (ResolverInfoType type, PoolItem_Ref item, int priority)
00204 : _type (type)
00205 , _affected (item)
00206 , _priority (priority)
00207 , _error (false)
00208 , _important (false)
00209 {
00210 _XDEBUG(*this);
00211 }
00212
00213
00214 ResolverInfo::~ResolverInfo()
00215 {
00216 }
00217
00218
00219
00220 bool
00221 ResolverInfo::merge (ResolverInfo_Ptr to_be_merged)
00222 {
00223 if (to_be_merged == NULL) return false;
00224
00225 if (_type != to_be_merged->_type
00226 || _affected != to_be_merged->_affected
00227 || _error != to_be_merged->_error) {
00228 return false;
00229 }
00230
00231 return true;
00232 }
00233
00234 void
00235 ResolverInfo::copy (ResolverInfo_constPtr from)
00236 {
00237 _error = from->_error;
00238 _important = from->_important;
00239 }
00240
00241
00242 ResolverInfo_Ptr
00243 ResolverInfo::copy (void) const
00244 {
00245 ResolverInfo_Ptr cpy = new ResolverInfo(_type, _affected, _priority);
00246
00247 cpy->copy (this);
00248
00249 return cpy;
00250 }
00251
00252
00253
00254
00255 bool
00256 ResolverInfo::isAbout (PoolItem_Ref item) const
00257 {
00258 if (!_affected)
00259 return false;
00260
00261 return _affected->name() == item->name() && _affected->kind() == item->kind();
00262 }
00263
00265 };
00268 };
00271 };
00273