diff options
author | Michael Schroeder <mls@suse.de> | 2009-03-17 13:02:54 +0100 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2009-03-17 13:02:54 +0100 |
commit | 6f7d6f2fd07b10ada507d60e81248deccbbcec34 (patch) | |
tree | 460241b8b83a4be60350dacd8a414d53b0f19c03 | |
parent | 5492f5e083e03304bf7ba49004608f5a9225c0b7 (diff) | |
download | libsolv-6f7d6f2fd07b10ada507d60e81248deccbbcec34.tar.gz libsolv-6f7d6f2fd07b10ada507d60e81248deccbbcec34.tar.bz2 libsolv-6f7d6f2fd07b10ada507d60e81248deccbbcec34.zip |
- replace old solver_problemruleinfo with new solver_ruleinfo function
- add solvable_selfprovidedep() function (used in buddy deps)
- add noinfarchcheck solver option
- clone job queue to make the code more flexible
-rw-r--r-- | src/pool.c | 3 | ||||
-rw-r--r-- | src/pool.h | 1 | ||||
-rw-r--r-- | src/poolvendor.c | 15 | ||||
-rw-r--r-- | src/solvable.c | 26 | ||||
-rw-r--r-- | src/solver.c | 705 | ||||
-rw-r--r-- | src/solver.h | 63 | ||||
-rw-r--r-- | src/solverdebug.c | 40 | ||||
-rw-r--r-- | tools/installcheck.c | 121 |
8 files changed, 513 insertions, 461 deletions
@@ -362,7 +362,8 @@ pool_createwhatprovides(Pool *pool) /* * free all of our whatprovides data - * be careful, everything internalized with pool_queuetowhatprovides is gone, too + * be careful, everything internalized with pool_queuetowhatprovides is + * gone, too */ void pool_freewhatprovides(Pool *pool) @@ -194,6 +194,7 @@ char * solvable_get_location(Solvable *s, unsigned int *medianrp); const unsigned char *solvable_lookup_bin_checksum(Solvable *s, Id keyname, Id *typep); const char *solvable_lookup_checksum(Solvable *s, Id keyname, Id *typep); int solvable_identical(Solvable *s1, Solvable *s2); +Id solvable_selfprovidedep(Solvable *s); int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap); int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed); diff --git a/src/poolvendor.c b/src/poolvendor.c index f173c08..35ffb50 100644 --- a/src/poolvendor.c +++ b/src/poolvendor.c @@ -22,6 +22,7 @@ #include "util.h" const char *vendors[] = { + "!openSUSE Build Service*", "SUSE*", "openSUSE*", "SGI*", @@ -39,7 +40,7 @@ Id pool_vendor2mask(Pool *pool, Id vendor) const char *vstr; int i; Id mask, m; - const char **v; + const char **v, *vs; if (vendor == 0) return 0; @@ -51,19 +52,21 @@ Id pool_vendor2mask(Pool *pool, Id vendor) mask = 0; for (v = vendors; ; v++) { - if (*v == 0) + vs = *v; + if (vs == 0) /* end of block? */ { v++; if (*v == 0) break; if (m == (1 << 31)) break; - m <<= 1; + m <<= 1; /* next vendor equivalence class */ } - if (fnmatch(*v, vstr, FNM_CASEFOLD) == 0) + if (fnmatch(*vs == '!' ? vs + 1 : vs, vstr, FNM_CASEFOLD) == 0) { - mask |= m; - while (v[1]) + if (*vs != '!') + mask |= m; + while (v[1]) /* forward to next block */ v++; } } diff --git a/src/solvable.c b/src/solvable.c index 722b82d..68a3855 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -512,3 +512,29 @@ solvable_identical(Solvable *s1, Solvable *s2) } return 1; } + +/* return the self provide dependency of a solvable */ +Id +solvable_selfprovidedep(Solvable *s) +{ + Pool *pool; + Reldep *rd; + Id prov, *provp; + + if (!s->repo) + return s->name; + pool = s->repo->pool; + if (s->provides) + { + provp = s->repo->idarraydata + s->provides; + while ((prov = *provp++) != 0) + { + if (!ISRELDEP(prov)) + continue; + rd = GETRELDEP(pool, prov); + if (rd->name == s->name && rd->evr == s->evr && rd->flags == REL_EQ) + return prov; + } + } + return rel2id(pool, s->name, s->evr, REL_EQ, 1); +} diff --git a/src/solver.c b/src/solver.c index 0174833..7d586e1 100644 --- a/src/solver.c +++ b/src/solver.c @@ -28,6 +28,7 @@ #define RULES_BLOCK 63 static void reenablepolicyrules(Solver *solv, Queue *job, int jobidx); +static void addrpmruleinfo(Solver *solv, Id p, Id d, int type, Id dep); /******************************************************************** * @@ -806,7 +807,7 @@ makeruledecisions(Solver *solv) v = ri; disableproblem(solv, v); if (v < 0) - reenablepolicyrules(solv, solv->job, -(v + 1)); + reenablepolicyrules(solv, &solv->job, -(v + 1)); } POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- makeruledecisions end; size decisionq: %d -----\n",solv->decisionq.count); @@ -1247,6 +1248,14 @@ makemultiversionconflict(Solver *solv, Id n, Id con) return pool_queuetowhatprovides(pool, &q); } +static inline void +addrpmrule(Solver *solv, Id p, Id d, int type, Id dep) +{ + if (!solv->ruleinfoq) + addrule(solv, p, d); + else + addrpmruleinfo(solv, p, d, type, dep); +} /*------------------------------------------------------------------- * @@ -1292,12 +1301,9 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) Id obs, *obsp; Id rec, *recp; Id sug, *sugp; - /* var and ptr for loops */ - Id p, pp; - /* ptr to 'whatprovides' */ - Id *dp; - /* Id for current solvable 's' */ - Id n; + Id p, pp; /* whatprovides loops */ + Id *dp; /* ptr to 'whatprovides' */ + Id n; /* Id for current solvable 's' */ POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforsolvable -----\n"); @@ -1312,20 +1318,23 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) * s: Pointer to solvable */ - n = queue_shift(&workq); /* 'pop' next solvable to work on from queue */ - if (MAPTST(m, n)) /* continue if already visited */ - continue; + n = queue_shift(&workq); /* 'pop' next solvable to work on from queue */ + if (m) + { + if (MAPTST(m, n)) /* continue if already visited */ + continue; + MAPSET(m, n); /* mark as visited */ + } - MAPSET(m, n); /* mark as visited */ - s = pool->solvables + n; /* s = Solvable in question */ + s = pool->solvables + n; /* s = Solvable in question */ dontfix = 0; - if (installed /* Installed system available */ - && !solv->fixsystem /* NOT repair errors in rpm dependency graph */ - && s->repo == installed) /* solvable is installed? */ - { - dontfix = 1; /* dont care about broken rpm deps */ - } + if (installed /* Installed system available */ + && !solv->fixsystem /* NOT repair errors in rpm dependency graph */ + && s->repo == installed) /* solvable is installed? */ + { + dontfix = 1; /* dont care about broken rpm deps */ + } if (!dontfix && s->arch != ARCH_SRC @@ -1333,7 +1342,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) && !pool_installable(pool, s)) { POOL_DEBUG(SAT_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", solvable2str(pool, s), (Id)(s - pool->solvables)); - addrule(solv, -n, 0); /* uninstallable */ + addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOT_INSTALLABLE, 0); } /* yet another SUSE hack, sigh */ @@ -1342,9 +1351,9 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) Id buddy = pool->nscallback(pool, pool->nscallbackdata, NAMESPACE_PRODUCTBUDDY, n); if (buddy > 0 && buddy != SYSTEMSOLVABLE && buddy != n && buddy < pool->nsolvables) { - addrule(solv, n, -buddy); - addrule(solv, buddy, -n); - if (!MAPTST(m, buddy)) + addrpmrule(solv, n, -buddy, SOLVER_RULE_RPM_PACKAGE_REQUIRES, solvable_selfprovidedep(pool->solvables + n)); + addrpmrule(solv, buddy, -n, SOLVER_RULE_RPM_PACKAGE_REQUIRES, solvable_selfprovidedep(pool->solvables + buddy)); + if (m && !MAPTST(m, buddy)) queue_push(&workq, buddy); } } @@ -1392,7 +1401,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) { /* nothing provides req! */ POOL_DEBUG(SAT_DEBUG_RULE_CREATION, "package %s [%d] is not installable (%s)\n", solvable2str(pool, s), (Id)(s - pool->solvables), dep2str(pool, req)); - addrule(solv, -n, 0); /* mark requestor as uninstallable */ + addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, req); continue; } @@ -1405,14 +1414,17 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) /* add 'requires' dependency */ /* rule: (-requestor|provider1|provider2|...|providerN) */ - addrule(solv, -n, dp - pool->whatprovidesdata); + addrpmrule(solv, -n, dp - pool->whatprovidesdata, SOLVER_RULE_RPM_PACKAGE_REQUIRES, req); /* descend the dependency tree push all non-visited providers on the work queue */ - for (; *dp; dp++) + if (m) { - if (!MAPTST(m, *dp)) - queue_push(&workq, *dp); + for (; *dp; dp++) + { + if (!MAPTST(m, *dp)) + queue_push(&workq, *dp); + } } } /* while, requirements of n */ @@ -1468,7 +1480,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) p = -makemultiversionconflict(solv, p, con); } /* rule: -n|-p: either solvable _or_ provider of conflict */ - addrule(solv, -n, -p); + addrpmrule(solv, -n, -p, p ? SOLVER_RULE_RPM_PACKAGE_CONFLICT : SOLVER_RULE_RPM_SELF_CONFLICT, con); } } } @@ -1492,7 +1504,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) if (!solv->obsoleteusesprovides /* obsoletes are matched names, not provides */ && !pool_match_nevr(pool, pool->solvables + p, obs)) continue; - addrule(solv, -n, -p); + addrpmrule(solv, -n, -p, SOLVER_RULE_RPM_PACKAGE_OBSOLETES, obs); } } } @@ -1505,14 +1517,17 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) continue; if (!solv->implicitobsoleteusesprovides && s->name != ps->name) continue; - addrule(solv, -n, -p); + if (s->name == ps->name) + addrpmrule(solv, -n, -p, SOLVER_RULE_RPM_SAME_NAME, 0); + else + addrpmrule(solv, -n, -p, SOLVER_RULE_RPM_IMPLICIT_OBSOLETES, s->name); } } /*----------------------------------------- * add recommends to the work queue */ - if (s->recommends) + if (s->recommends && m) { recp = s->repo->idarraydata + s->recommends; while ((rec = *recp++) != 0) @@ -1522,7 +1537,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) queue_push(&workq, p); } } - if (s->suggests) + if (s->suggests && m) { sugp = s->repo->idarraydata + s->suggests; while ((sug = *sugp++) != 0) @@ -1557,13 +1572,13 @@ addrpmrulesforweak(Solver *solv, Map *m) /* foreach solvable in pool */ for (i = n = 1; n < pool->nsolvables; i++, n++) { - if (i == pool->nsolvables) /* wrap i */ + if (i == pool->nsolvables) /* wrap i */ i = 1; - if (MAPTST(m, i)) /* been there */ + if (MAPTST(m, i)) /* been there */ continue; s = pool->solvables + i; - if (!pool_installable(pool, s)) /* only look at installable ones */ + if (!pool_installable(pool, s)) /* only look at installable ones */ continue; sup = 0; @@ -1576,7 +1591,7 @@ addrpmrulesforweak(Solver *solv, Map *m) break; } - /* if nothing found, check for enhances */ + /* if nothing found, check for enhances */ if (!sup && s->enhances) { supp = s->repo->idarraydata + s->enhances; @@ -1584,11 +1599,11 @@ addrpmrulesforweak(Solver *solv, Map *m) if (dep_possible(solv, sup, m)) break; } - /* if nothing found, goto next solvables */ + /* if nothing found, goto next solvables */ if (!sup) continue; addrpmrulesforsolvable(solv, s, m); - n = 0; + n = 0; /* check all solvables again */ } POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforweak end -----\n"); } @@ -2347,7 +2362,7 @@ analyze_unsolvable(Solver *solv, Rule *cr, int disablerules) solver_printruleclass(solv, SAT_DEBUG_UNSOLVABLE, solv->rules + lastweak); disableproblem(solv, v); if (v < 0) - reenablepolicyrules(solv, solv->job, -(v + 1)); + reenablepolicyrules(solv, &solv->job, -(v + 1)); reset_solver(solv); return 1; } @@ -3861,337 +3876,6 @@ solver_next_solutionelement(Solver *solv, Id problem, Id solution, Id element, I /*------------------------------------------------------------------- * - * Retrieve information about a problematic rule - * - * this is basically the reverse of addrpmrulesforsolvable - */ - -SolverProbleminfo -solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, Id *targetp) -{ - Pool *pool = solv->pool; - Repo *installed = solv->installed; - Rule *r; - Solvable *s; - int dontfix = 0; - Id p, d, w2, pp, req, *reqp, con, *conp, obs, *obsp, *dp; - - assert(rid > 0); - if (rid >= solv->infarchrules && rid < solv->infarchrules_end) - { - r = solv->rules + rid; - *depp = r->p < 0 ? pool->solvables[-r->p].name : 0; - *sourcep = r->p < 0 ? -r->p : 0; - *targetp = 0; - return SOLVER_PROBLEM_INFARCH_RULE; - } - if (rid >= solv->duprules && rid < solv->duprules_end) - { - r = solv->rules + rid; - *depp = r->p < 0 ? pool->solvables[-r->p].name : 0; - *sourcep = r->p < 0 ? -r->p : 0; - *targetp = 0; - return SOLVER_PROBLEM_DISTUPGRADE_RULE; - } - if (rid >= solv->jobrules && rid < solv->jobrules_end) - { - - r = solv->rules + rid; - p = solv->ruletojob.elements[rid - solv->jobrules]; - *depp = job->elements[p + 1]; - *sourcep = p; - *targetp = job->elements[p]; - d = r->d < 0 ? -r->d - 1 : r->d; - if (d == 0 && r->w2 == 0 && r->p == -SYSTEMSOLVABLE && (job->elements[p] & SOLVER_SELECTMASK) != SOLVER_SOLVABLE_ONE_OF) - return SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP; - return SOLVER_PROBLEM_JOB_RULE; - } - if (rid >= solv->updaterules && rid < solv->updaterules_end) - { - *depp = 0; - *sourcep = solv->installed->start + (rid - solv->updaterules); - *targetp = 0; - return SOLVER_PROBLEM_UPDATE_RULE; - } - assert(rid < solv->rpmrules_end); - r = solv->rules + rid; - assert(r->p < 0); - d = r->d < 0 ? -r->d - 1 : r->d; - if (d == 0 && r->w2 == 0) - { - /* a rpm rule assertion */ - s = pool->solvables - r->p; - if (installed && !solv->fixsystem && s->repo == installed) - dontfix = 1; - assert(!dontfix); /* dontfix packages never have a neg assertion */ - *sourcep = -r->p; - *targetp = 0; - /* see why the package is not installable */ - if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC && !pool_installable(pool, s)) - { - *depp = 0; - return SOLVER_PROBLEM_NOT_INSTALLABLE; - } - /* check requires */ - if (s->requires) - { - reqp = s->repo->idarraydata + s->requires; - while ((req = *reqp++) != 0) - { - if (req == SOLVABLE_PREREQMARKER) - continue; - dp = pool_whatprovides_ptr(pool, req); - if (*dp == 0) - break; - } - if (req) - { - *depp = req; - return SOLVER_PROBLEM_NOTHING_PROVIDES_DEP; - } - } - if (!solv->allowselfconflicts && s->conflicts) - { - conp = s->repo->idarraydata + s->conflicts; - while ((con = *conp++) != 0) - FOR_PROVIDES(p, pp, con) - if (p == -r->p) - { - *depp = con; - return SOLVER_PROBLEM_SELF_CONFLICT; - } - } - /* should never happen */ - *depp = 0; - return SOLVER_PROBLEM_RPM_RULE; - } - s = pool->solvables - r->p; - if (installed && !solv->fixsystem && s->repo == installed) - dontfix = 1; - w2 = r->w2; - if (d && pool->whatprovidesdata[d] < 0) - { - /* rule looks like -p|-c|x|x|x..., we only create this for patches with multiversion */ - /* reduce it to -p|-c case */ - d = 0; - w2 = pool->whatprovidesdata[d]; - } - if (d == 0 && w2 < 0) - { - /* a package conflict */ - Solvable *s2 = pool->solvables - w2; - int dontfix2 = 0; - - if (installed && !solv->fixsystem && s2->repo == installed) - dontfix2 = 1; - - /* if both packages have the same name and at least one of them - * is not installed, they conflict */ - if (s->name == s2->name && !(installed && s->repo == installed && s2->repo == installed)) - { - /* also check noobsoletes map */ - if ((s->evr == s2->evr && s->arch == s2->arch) || !solv->noobsoletes.size - || ((!installed || s->repo != installed) && !MAPTST(&solv->noobsoletes, -r->p)) - || ((!installed || s2->repo != installed) && !MAPTST(&solv->noobsoletes, -w2))) - { - *depp = 0; - *sourcep = -r->p; - *targetp = -w2; - return SOLVER_PROBLEM_SAME_NAME; - } - } - - /* check conflicts in both directions */ - if (s->conflicts) - { - conp = s->repo->idarraydata + s->conflicts; - while ((con = *conp++) != 0) - { - FOR_PROVIDES(p, pp, con) - { - if (dontfix && pool->solvables[p].repo == installed) - continue; - if (p != -w2) - continue; - *depp = con; - *sourcep = -r->p; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_CONFLICT; - } - } - } - if (s2->conflicts) - { - conp = s2->repo->idarraydata + s2->conflicts; - while ((con = *conp++) != 0) - { - FOR_PROVIDES(p, pp, con) - { - if (dontfix2 && pool->solvables[p].repo == installed) - continue; - if (p != -r->p) - continue; - *depp = con; - *sourcep = -w2; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_CONFLICT; - } - } - } - /* check obsoletes in both directions */ - if ((!installed || s->repo != installed) && s->obsoletes && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->p))) - { - obsp = s->repo->idarraydata + s->obsoletes; - while ((obs = *obsp++) != 0) - { - FOR_PROVIDES(p, pp, obs) - { - if (p != -w2) - continue; - if (!solv->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p, obs)) - continue; - *depp = obs; - *sourcep = -r->p; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_OBSOLETES; - } - } - } - if ((!installed || s2->repo != installed) && s2->obsoletes && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -w2))) - { - obsp = s2->repo->idarraydata + s2->obsoletes; - while ((obs = *obsp++) != 0) - { - FOR_PROVIDES(p, pp, obs) - { - if (p != -r->p) - continue; - if (!solv->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p, obs)) - continue; - *depp = obs; - *sourcep = -w2; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_OBSOLETES; - } - } - } - if (solv->implicitobsoleteusesprovides && (!installed || s->repo != installed) && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->p))) - { - FOR_PROVIDES(p, pp, s->name) - { - if (p != -w2) - continue; - *depp = s->name; - *sourcep = -r->p; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_OBSOLETES; - } - } - if (solv->implicitobsoleteusesprovides && (!installed || s2->repo != installed) && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -w2))) - { - FOR_PROVIDES(p, pp, s2->name) - { - if (p != -r->p) - continue; - *depp = s2->name; - *sourcep = -w2; - *targetp = p; - return SOLVER_PROBLEM_PACKAGE_OBSOLETES; - } - } - /* all cases checked, can't happen */ - *depp = 0; - *sourcep = -r->p; - *targetp = 0; - return SOLVER_PROBLEM_RPM_RULE; - } - /* simple requires */ - if (s->requires) - { - reqp = s->repo->idarraydata + s->requires; - while ((req = *reqp++) != 0) - { - if (req == SOLVABLE_PREREQMARKER) - continue; - dp = pool_whatprovides_ptr(pool, req); - if (d == 0) - { - if (*dp == r->w2 && dp[1] == 0) - break; - } - else if (dp - pool->whatprovidesdata == d) - break; - } - if (req) - { - *depp = req; - *sourcep = -r->p; - *targetp = 0; - return SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE; - } - } - - /* check for product buddy requires */ - if (d == 0 && w2 > 0 && pool->nscallback) - { - Id buddy = 0; - s = pool->solvables - r->p; - if (!strncmp("product:", id2str(pool, s->name), 8)) - { - buddy = pool->nscallback(pool, pool->nscallbackdata, NAMESPACE_PRODUCTBUDDY, -r->p); - if (buddy != w2) - buddy = 0; - } - if (!buddy) - { - s = pool->solvables + w2; - if (!strncmp("product:", id2str(pool, s->name), 8)) - { - buddy = pool->nscallback(pool, pool->nscallbackdata, NAMESPACE_PRODUCTBUDDY, w2); - if (buddy != -r->p) - buddy = 0; - } - } - if (buddy) - { - /* have buddy relation, now fake requires */ - s = pool->solvables + w2; - Reldep *rd; - if (s->repo && s->provides) - { - Id prov, *provp; - provp = s->repo->idarraydata + s->provides; - while ((prov = *provp++) != 0) - { - if (!ISRELDEP(prov)) - continue; - rd = GETRELDEP(pool, prov); - if (rd->name == s->name && rd->evr == s->evr && rd->flags == REL_EQ) - { - *depp = prov; - *sourcep = -r->p; - *targetp = 0; - return SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE; - } - } - } - *depp = s->name; - *sourcep = -r->p; - *targetp = 0; - return SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE; - } - } - - /* all cases checked, can't happen */ - *depp = 0; - *sourcep = -r->p; - *targetp = 0; - return SOLVER_PROBLEM_RPM_RULE; -} - - -/*------------------------------------------------------------------- - * * find problem rule */ @@ -4744,13 +4428,16 @@ solver_solve(Solver *solv, Queue *job) int hasdupjob = 0; solve_start = sat_timems(0); + + /* log solver options */ POOL_DEBUG(SAT_DEBUG_STATS, "solver started\n"); - POOL_DEBUG(SAT_DEBUG_STATS, "fixsystem=%d updatesystem=%d dosplitprovides=%d, noupdateprovide=%d\n", solv->fixsystem, solv->updatesystem, solv->dosplitprovides, solv->noupdateprovide); + POOL_DEBUG(SAT_DEBUG_STATS, "fixsystem=%d updatesystem=%d dosplitprovides=%d, noupdateprovide=%d noinfarchcheck=%d\n", solv->fixsystem, solv->updatesystem, solv->dosplitprovides, solv->noupdateprovide, solv->noinfarchcheck); POOL_DEBUG(SAT_DEBUG_STATS, "distupgrade=%d distupgrade_removeunsupported=%d\n", solv->distupgrade, solv->distupgrade_removeunsupported); POOL_DEBUG(SAT_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allowarchchange, solv->allowvendorchange); POOL_DEBUG(SAT_DEBUG_STATS, "promoteepoch=%d, allowvirtualconflicts=%d, allowselfconflicts=%d\n", pool->promoteepoch, solv->allowvirtualconflicts, solv->allowselfconflicts); POOL_DEBUG(SAT_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d\n", solv->obsoleteusesprovides, solv->implicitobsoleteusesprovides); POOL_DEBUG(SAT_DEBUG_STATS, "dontinstallrecommended=%d, ignorealreadyrecommended=%d, dontshowinstalledrecommended=%d\n", solv->dontinstallrecommended, solv->ignorealreadyrecommended, solv->dontshowinstalledrecommended); + /* create whatprovides if not already there */ if (!pool->whatprovides) pool_createwhatprovides(pool); @@ -4759,12 +4446,12 @@ solver_solve(Solver *solv, Queue *job) create_obsolete_index(solv); /* remember job */ - solv->job = job; + queue_free(&solv->job); + queue_clone(&solv->job, job); /* * create basic rule set of all involved packages * use addedmap bitmap to make sure we don't create rules twice - * */ /* create noobsolete map if needed */ @@ -4885,7 +4572,7 @@ solver_solve(Solver *solv, Queue *job) POOL_DEBUG(SAT_DEBUG_STATS, "decisions so far: %d\n", solv->decisionq.count); POOL_DEBUG(SAT_DEBUG_STATS, "rpm rule creation took %d ms\n", sat_timems(now)); - /* create dup maps if needed. We need the maps to create our + /* create dup maps if needed. We need the maps early to create our * update rules */ if (hasdupjob) createdupmaps(solv, job); @@ -5135,7 +4822,11 @@ solver_solve(Solver *solv, Queue *job) solv->jobrules_end = solv->nrules; /* now create infarch and dup rules */ - addinfarchrules(solv, &addedmap); + if (!solv->noinfarchcheck) + addinfarchrules(solv, &addedmap); + else + solv->infarchrules = solv->infarchrules_end = solv->nrules; + if (hasdupjob) { addduprules(solv, &addedmap); @@ -5144,6 +4835,7 @@ solver_solve(Solver *solv, Queue *job) else solv->duprules = solv->duprules_end = solv->nrules; + /* all rules created * -------------------------------------------------------------- * prepare for solving @@ -5381,7 +5073,6 @@ solver_solve(Solver *solv, Queue *job) queue_free(&redoq); POOL_DEBUG(SAT_DEBUG_STATS, "final solver statistics: %d learned rules, %d unsolvable\n", solv->stats_learned, solv->stats_unsolvable); POOL_DEBUG(SAT_DEBUG_STATS, "solver_solve took %d ms\n", sat_timems(solve_start)); - solv->job = 0; } /***********************************************************************/ @@ -5661,4 +5352,266 @@ solver_find_involved(Solver *solv, Queue *installedq, Solvable *ts, Queue *q) queue_free(&installedq_internal); } + +static void +addrpmruleinfo(Solver *solv, Id p, Id d, int type, Id dep) +{ + Pool *pool = solv->pool; + Rule *r; + Id w2, op, od, ow2; + + /* check if this creates the rule we're searching for */ + r = solv->rules + solv->ruleinfoq->elements[0]; + op = r->p; + od = r->d < 0 ? -r->d - 1 : r->d; + ow2 = 0; + + /* normalize */ + w2 = d > 0 ? 0 : d; + if (p < 0 && d > 0 && (!pool->whatprovidesdata[d] || !pool->whatprovidesdata[d + 1])) + { + w2 = pool->whatprovidesdata[d]; + d = 0; + + } + if (p > 0 && d < 0) /* this hack is used for buddy deps */ + { + w2 = p; + p = d; + } + + if (d > 0) + { + if (p != op && !od) + return; + if (d != od) + { + Id *dp = pool->whatprovidesdata + d; + Id *odp = pool->whatprovidesdata + od; + while (*dp) + if (*dp++ != *odp++) + return; + if (*odp) + return; + } + w2 = 0; + /* handle multiversion conflict rules */ + if (p < 0 && pool->whatprovidesdata[d] < 0) + { + w2 = pool->whatprovidesdata[d]; + /* XXX: free memory */ + } + } + else + { + if (od) + return; + ow2 = r->w2; + if (p > w2) + { + if (w2 != op || p != ow2) + return; + } + else + { + if (p != op || w2 != ow2) + return; + } + } + /* yep, rule matches. record info */ + queue_push(solv->ruleinfoq, type); + if (type == SOLVER_RULE_RPM_SAME_NAME) + { + /* we normalize same name order */ + queue_push(solv->ruleinfoq, op < 0 ? -op : 0); + queue_push(solv->ruleinfoq, ow2 < 0 ? -ow2 : 0); + } + else + { + queue_push(solv->ruleinfoq, p < 0 ? -p : 0); + queue_push(solv->ruleinfoq, w2 < 0 ? -w2 : 0); + } + queue_push(solv->ruleinfoq, dep); +} + +static int +solver_allruleinfos_cmp(const void *ap, const void *bp) +{ + const Id *a = ap, *b = bp; + int r; + + r = a[0] - b[0]; + if (r) + return r; + r = a[1] - b[1]; + if (r) + return r; + r = a[2] - b[2]; + if (r) + return r; + r = a[3] - b[3]; + if (r) + return r; + return 0; +} + +int +solver_allruleinfos(Solver *solv, Id rid, Queue *rq) +{ + Pool *pool = solv->pool; + Rule *r = solv->rules + rid; + int i, j; + + queue_empty(rq); + if (rid <= 0 || rid >= solv->rpmrules_end) + { + Id type, from, to, dep; + type = solver_ruleinfo(solv, rid, &from, &to, &dep); + queue_push(rq, type); + queue_push(rq, from); + queue_push(rq, to); + queue_push(rq, dep); + return 1; + } + if (r->p >= 0) + return 0; + queue_push(rq, rid); + solv->ruleinfoq = rq; + addrpmrulesforsolvable(solv, pool->solvables - r->p, 0); + /* also try reverse direction for conflicts */ + if ((r->d == 0 || r->d == -1) && r->w2 < 0) + addrpmrulesforsolvable(solv, pool->solvables - r->w2, 0); + solv->ruleinfoq = 0; + queue_shift(rq); + /* now sort & unify em */ + if (!rq->count) + return 0; + qsort(rq->elements, rq->count / 4, 4 * sizeof(Id), solver_allruleinfos_cmp); + /* throw out identical entries */ + for (i = j = 0; i < rq->count; i += 4) + { + if (j) + { + if (rq->elements[i] == rq->elements[j - 4] && + rq->elements[i + 1] == rq->elements[j - 3] && + rq->elements[i + 2] == rq->elements[j - 2] && + rq->elements[i + 3] == rq->elements[j - 1]) + continue; + } + rq->elements[j++] = rq->elements[i]; + rq->elements[j++] = rq->elements[i + 1]; + rq->elements[j++] = rq->elements[i + 2]; + rq->elements[j++] = rq->elements[i + 3]; + } + rq->count = j; + return j / 4; +} + +SolverRuleinfo +solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp) +{ + Pool *pool = solv->pool; + Rule *r = solv->rules + rid; + SolverRuleinfo type = SOLVER_RULE_UNKNOWN; + + if (fromp) + *fromp = 0; + if (top) + *top = 0; + if (depp) + *depp = 0; + if (rid > 0 && rid < solv->rpmrules_end) + { + Queue rq; + int i; + + if (r->p >= 0) + return SOLVER_RULE_RPM; + if (fromp) + *fromp = -r->p; + queue_init(&rq); + queue_push(&rq, rid); + solv->ruleinfoq = &rq; + addrpmrulesforsolvable(solv, pool->solvables - r->p, 0); + /* also try reverse direction for conflicts */ + if ((r->d == 0 || r->d == -1) && r->w2 < 0) + addrpmrulesforsolvable(solv, pool->solvables - r->w2, 0); + solv->ruleinfoq = 0; + type = SOLVER_RULE_RPM; + for (i = 1; i < rq.count; i += 4) + { + Id qt, qo, qp, qd; + qt = rq.elements[i]; + qp = rq.elements[i + 1]; + qo = rq.elements[i + 2]; + qd = rq.elements[i + 3]; + if (type == SOLVER_RULE_RPM || type > qt) + { + type = qt; + if (fromp) + *fromp = qp; + if (top) + *top = qo; + if (depp) + *depp = qd; + } + } + queue_free(&rq); + return type; + } + if (rid >= solv->jobrules && rid < solv->jobrules_end) + { + Id jidx = solv->ruletojob.elements[rid - solv->jobrules]; + if (fromp) + *fromp = jidx; + if (top) + *top = solv->job.elements[jidx]; + if (depp) + *depp = solv->job.elements[jidx + 1]; + if ((r->d == 0 || r->d == -1) && r->w2 == 0 && r->p == -SYSTEMSOLVABLE && (solv->job.elements[jidx] & SOLVER_SELECTMASK) != SOLVER_SOLVABLE_ONE_OF) + return SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP; + return SOLVER_RULE_JOB; + } + if (rid >= solv->updaterules && rid < solv->updaterules_end) + { + if (fromp) + *fromp = solv->installed->start + (rid - solv->updaterules); + return SOLVER_RULE_UPDATE; + } + if (rid >= solv->featurerules && rid < solv->featurerules_end) + { + if (fromp) + *fromp = solv->installed->start + (rid - solv->featurerules); + return SOLVER_RULE_FEATURE; + } + if (rid >= solv->duprules && rid < solv->duprules_end) + { + if (fromp) + *fromp = -r->p; + if (depp) + *depp = pool->solvables[-r->p].name; + return SOLVER_RULE_DISTUPGRADE; + } + if (rid >= solv->infarchrules && rid < solv->infarchrules_end) + { + if (fromp) + *fromp = -r->p; + if (depp) + *depp = pool->solvables[-r->p].name; + return SOLVER_RULE_INFARCH; + } + if (rid >= solv->learntrules) + { + return SOLVER_RULE_LEARNT; + } + return SOLVER_RULE_UNKNOWN; +} + +/* obsolete function */ +SolverRuleinfo +solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, Id *targetp) +{ + return solver_ruleinfo(solv, rid, sourcep, targetp, depp); +} + /* EOF */ diff --git a/src/solver.h b/src/solver.h index 817848e..8f220da 100644 --- a/src/solver.h +++ b/src/solver.h @@ -61,7 +61,9 @@ struct solver; typedef struct solver { Pool *pool; - Repo *installed; + Queue job; /* copy of the job we're solving */ + + Repo *installed; /* copy of pool->installed */ /* list of rules, ordered * rpm rules first, then features, updates, jobs, learnt @@ -84,6 +86,12 @@ typedef struct solver { Id jobrules; /* user rules */ Id jobrules_end; + + Id infarchrules; /* inferior arch rules */ + Id infarchrules_end; + + Id duprules; /* dist upgrade rules */ + Id duprules_end; Id learntrules; /* learnt rules, (end == nrules) */ @@ -92,6 +100,7 @@ typedef struct solver { Map noobsoletes; /* ignore obsoletes for these (multiinstall) */ + Map updatemap; /* bring those packages to the newest version */ Queue weakruleq; /* index into 'rules' for weak ones */ Map weakrulemap; /* map rule# to '1' for weak rules, 1..learntrules */ @@ -163,6 +172,8 @@ typedef struct solver { int distupgrade; int distupgrade_removeunsupported; + int noinfarchcheck; /* true: do not forbid inferior architectures */ + /* Callbacks for defining the bahaviour of the SAT solver */ /* Finding best candidate @@ -207,14 +218,10 @@ typedef struct solver { Queue covenantq; /* Covenants honored by this solver (generic locks) */ - Queue *job; /* tmp store for job we're working on */ - Id infarchrules; /* inferior arch rules */ - Id infarchrules_end; - Id duprules; /* dist upgrade rules */ - Id duprules_end; - Map updatemap; /* bring those packages to the newest version */ Map dupmap; /* packages from dup repos */ Map dupinvolvedmap; /* packages involved in dup process */ + + Queue *ruleinfoq; /* tmp space for solver_ruleinfo() */ } Solver; /* @@ -274,6 +281,44 @@ typedef enum { SOLVER_PROBLEM_INFARCH_RULE } SolverProbleminfo; +typedef enum { + SOLVER_RULE_UNKNOWN = 0, + SOLVER_RULE_RPM = 0x100, + SOLVER_RULE_RPM_NOT_INSTALLABLE, + SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, + SOLVER_RULE_RPM_PACKAGE_REQUIRES, + SOLVER_RULE_RPM_SELF_CONFLICT, + SOLVER_RULE_RPM_PACKAGE_CONFLICT, + SOLVER_RULE_RPM_SAME_NAME, + SOLVER_RULE_RPM_PACKAGE_OBSOLETES, + SOLVER_RULE_RPM_IMPLICIT_OBSOLETES, + SOLVER_RULE_UPDATE = 0x200, + SOLVER_RULE_FEATURE = 0x300, + SOLVER_RULE_JOB = 0x400, + SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP, + SOLVER_RULE_DISTUPGRADE = 0x500, + SOLVER_RULE_INFARCH = 0x600, + SOLVER_RULE_LEARNT = 0x700 +} SolverRuleinfo; + +#define SOLVER_RULE_TYPEMASK 0xff00 + +/* backward compatibility */ +#define SOLVER_PROBLEM_UPDATE_RULE SOLVER_RULE_UPDATE +#define SOLVER_PROBLEM_JOB_RULE SOLVER_RULE_JOB +#define SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP +#define SOLVER_PROBLEM_NOT_INSTALLABLE SOLVER_RULE_RPM_NOT_INSTALLABLE +#define SOLVER_PROBLEM_NOTHING_PROVIDES_DEP SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP +#define SOLVER_PROBLEM_SAME_NAME SOLVER_RULE_RPM_SAME_NAME +#define SOLVER_PROBLEM_PACKAGE_CONFLICT SOLVER_RULE_RPM_PACKAGE_CONFLICT +#define SOLVER_PROBLEM_PACKAGE_OBSOLETES SOLVER_RULE_RPM_PACKAGE_OBSOLETES +#define SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE SOLVER_RULE_RPM_PACKAGE_REQUIRES +#define SOLVER_PROBLEM_SELF_CONFLICT SOLVER_RULE_RPM_SELF_CONFLICT +#define SOLVER_PROBLEM_RPM_RULE SOLVER_RULE_RPM +#define SOLVER_PROBLEM_DISTUPGRADE_RULE SOLVER_RULE_DISTUPGRADE +#define SOLVER_PROBLEM_INFARCH_RULE SOLVER_RULE_INFARCH + + #define SOLVER_SOLUTION_JOB (0) #define SOLVER_SOLUTION_DISTUPGRADE (-1) #define SOLVER_SOLUTION_INFARCH (-2) @@ -290,7 +335,9 @@ extern Id solver_next_solutionelement(Solver *solv, Id problem, Id solution, Id extern Id solver_findproblemrule(Solver *solv, Id problem); extern void solver_findallproblemrules(Solver *solv, Id problem, Queue *rules); -extern SolverProbleminfo solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, Id *targetp); +extern SolverRuleinfo solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, Id *targetp); +extern SolverRuleinfo solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp); +extern int solver_allruleinfos(Solver *solv, Id rid, Queue *rq); /* XXX: why is this not static? */ Id *solver_create_decisions_obsoletesmap(Solver *solv); diff --git a/src/solverdebug.c b/src/solverdebug.c index 5baafc6..3da35d8 100644 --- a/src/solverdebug.c +++ b/src/solverdebug.c @@ -393,58 +393,68 @@ solver_printprobleminfo(Solver *solv, Queue *job, Id problem) probr = solver_findproblemrule(solv, problem); switch (solver_problemruleinfo(solv, job, probr, &dep, &source, &target)) { - case SOLVER_PROBLEM_DISTUPGRADE_RULE: + case SOLVER_RULE_DISTUPGRADE: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "%s does not belong to a distupgrade repository\n", solvable2str(pool, s)); return; - case SOLVER_PROBLEM_INFARCH_RULE: + case SOLVER_RULE_INFARCH: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "%s has inferior architecture\n", solvable2str(pool, s)); return; - case SOLVER_PROBLEM_UPDATE_RULE: + case SOLVER_RULE_UPDATE: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "problem with installed package %s\n", solvable2str(pool, s)); return; - case SOLVER_PROBLEM_JOB_RULE: + case SOLVER_RULE_JOB: POOL_DEBUG(SAT_DEBUG_RESULT, "conflicting requests\n"); return; - case SOLVER_PROBLEM_RPM_RULE: - POOL_DEBUG(SAT_DEBUG_RESULT, "some dependency problem\n"); - return; - case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP: + case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: POOL_DEBUG(SAT_DEBUG_RESULT, "nothing provides requested %s\n", dep2str(pool, dep)); return; - case SOLVER_PROBLEM_NOT_INSTALLABLE: + case SOLVER_RULE_RPM: + POOL_DEBUG(SAT_DEBUG_RESULT, "some dependency problem\n"); + return; + case SOLVER_RULE_RPM_NOT_INSTALLABLE: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "package %s is not installable\n", solvable2str(pool, s)); return; - case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP: + case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "nothing provides %s needed by %s\n", dep2str(pool, dep), solvable2str(pool, s)); return; - case SOLVER_PROBLEM_SAME_NAME: + case SOLVER_RULE_RPM_SAME_NAME: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); POOL_DEBUG(SAT_DEBUG_RESULT, "cannot install both %s and %s\n", solvable2str(pool, s), solvable2str(pool, s2)); return; - case SOLVER_PROBLEM_PACKAGE_CONFLICT: + case SOLVER_RULE_RPM_PACKAGE_CONFLICT: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); POOL_DEBUG(SAT_DEBUG_RESULT, "package %s conflicts with %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); return; - case SOLVER_PROBLEM_PACKAGE_OBSOLETES: + case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); POOL_DEBUG(SAT_DEBUG_RESULT, "package %s obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); return; - case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE: + case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES: + s = pool_id2solvable(pool, source); + s2 = pool_id2solvable(pool, target); + POOL_DEBUG(SAT_DEBUG_RESULT, "package %s implicitely obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); + return; + case SOLVER_RULE_RPM_PACKAGE_REQUIRES: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "package %s requires %s, but none of the providers can be installed\n", solvable2str(pool, s), dep2str(pool, dep)); return; - case SOLVER_PROBLEM_SELF_CONFLICT: + case SOLVER_RULE_RPM_SELF_CONFLICT: s = pool_id2solvable(pool, source); POOL_DEBUG(SAT_DEBUG_RESULT, "package %s conflicts with %s provided by itself\n", solvable2str(pool, s), dep2str(pool, dep)); return; + case SOLVER_RULE_UNKNOWN: + case SOLVER_RULE_FEATURE: + case SOLVER_RULE_LEARNT: + POOL_DEBUG(SAT_DEBUG_RESULT, "bad rule type\n"); + return; } } diff --git a/tools/installcheck.c b/tools/installcheck.c index 1545212..4306252 100644 --- a/tools/installcheck.c +++ b/tools/installcheck.c @@ -241,66 +241,77 @@ main(int argc, char **argv) for (j = 0; j < rids.count; j++) { Id probr = rids.elements[j]; - Id dep, source, target; - switch (solver_problemruleinfo(solv, &job, probr, &dep, &source, &target)) + int k; + Queue rinfo; + queue_init(&rinfo); + + solver_allruleinfos(solv, probr, &rinfo); + for (k = 0; k < rinfo.count; k += 4) { - case SOLVER_PROBLEM_DISTUPGRADE_RULE: - break; - case SOLVER_PROBLEM_INFARCH_RULE: - s = pool_id2solvable(pool, source); - printf(" %s has inferior architecture\n", solvable2str(pool, s)); - break; - case SOLVER_PROBLEM_UPDATE_RULE: - break; - case SOLVER_PROBLEM_JOB_RULE: - break; - case SOLVER_PROBLEM_RPM_RULE: - printf(" some dependency problem\n"); - break; - case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP: - printf(" nothing provides requested %s\n", dep2str(pool, dep)); - break; - case SOLVER_PROBLEM_NOT_INSTALLABLE: - s = pool_id2solvable(pool, source); - printf(" package %s is not installable\n", solvable2str(pool, s)); - break; - case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP: - s = pool_id2solvable(pool, source); - printf(" nothing provides %s needed by %s\n", dep2str(pool, dep), solvable2str(pool, s)); - if (ISRELDEP(dep)) + Id dep, source, target; + source = rinfo.elements[k + 1]; + target = rinfo.elements[k + 2]; + dep = rinfo.elements[k + 3]; + switch (rinfo.elements[k]) { - Reldep *rd = GETRELDEP(pool, dep); - if (!ISRELDEP(rd->name)) + case SOLVER_PROBLEM_DISTUPGRADE_RULE: + break; + case SOLVER_PROBLEM_INFARCH_RULE: + s = pool_id2solvable(pool, source); + printf(" %s has inferior architecture\n", solvable2str(pool, s)); + break; + case SOLVER_PROBLEM_UPDATE_RULE: + break; + case SOLVER_PROBLEM_JOB_RULE: + break; + case SOLVER_PROBLEM_RPM_RULE: + printf(" some dependency problem\n"); + break; + case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP: + printf(" nothing provides requested %s\n", dep2str(pool, dep)); + break; + case SOLVER_PROBLEM_NOT_INSTALLABLE: + s = pool_id2solvable(pool, source); + printf(" package %s is not installable\n", solvable2str(pool, s)); + break; + case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP: + s = pool_id2solvable(pool, source); + printf(" nothing provides %s needed by %s\n", dep2str(pool, dep), solvable2str(pool, s)); + if (ISRELDEP(dep)) { - Id rp, rpp; - FOR_PROVIDES(rp, rpp, rd->name) - printf(" (we have %s)\n", solvable2str(pool, pool->solvables + rp)); + Reldep *rd = GETRELDEP(pool, dep); + if (!ISRELDEP(rd->name)) + { + Id rp, rpp; + FOR_PROVIDES(rp, rpp, rd->name) + printf(" (we have %s)\n", solvable2str(pool, pool->solvables + rp)); + } } + break; + case SOLVER_PROBLEM_SAME_NAME: + s = pool_id2solvable(pool, source); + s2 = pool_id2solvable(pool, target); + printf(" cannot install both %s and %s\n", solvable2str(pool, s), solvable2str(pool, s2)); + break; + case SOLVER_PROBLEM_PACKAGE_CONFLICT: + s = pool_id2solvable(pool, source); + s2 = pool_id2solvable(pool, target); + printf(" package %s conflicts with %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); + break; + case SOLVER_PROBLEM_PACKAGE_OBSOLETES: + s = pool_id2solvable(pool, source); + s2 = pool_id2solvable(pool, target); + printf(" package %s obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); + break; + case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE: + s = pool_id2solvable(pool, source); + printf(" package %s requires %s, but none of the providers can be installed\n", solvable2str(pool, s), dep2str(pool, dep)); + break; + case SOLVER_PROBLEM_SELF_CONFLICT: + s = pool_id2solvable(pool, source); + printf(" package %s conflicts with %s provided by itself\n", solvable2str(pool, s), dep2str(pool, dep)); + break; } - break; - case SOLVER_PROBLEM_SAME_NAME: - s = pool_id2solvable(pool, source); - s2 = pool_id2solvable(pool, target); - printf(" cannot install both %s and %s\n", solvable2str(pool, s), solvable2str(pool, s2)); - break; - case SOLVER_PROBLEM_PACKAGE_CONFLICT: - s = pool_id2solvable(pool, source); - s2 = pool_id2solvable(pool, target); - printf(" package %s conflicts with %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); - break; - case SOLVER_PROBLEM_PACKAGE_OBSOLETES: - s = pool_id2solvable(pool, source); - s2 = pool_id2solvable(pool, target); - printf(" package %s obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); - break; - case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE: - s = pool_id2solvable(pool, source); - printf(" package %s requires %s, but none of the providers can be installed\n", solvable2str(pool, s), dep2str(pool, dep)); - break; - case SOLVER_PROBLEM_SELF_CONFLICT: - s = pool_id2solvable(pool, source); - printf(" package %s conflicts with %s provided by itself\n", solvable2str(pool, s), dep2str(pool, dep)); - break; } } } |