summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2009-03-17 13:02:54 +0100
committerMichael Schroeder <mls@suse.de>2009-03-17 13:02:54 +0100
commit6f7d6f2fd07b10ada507d60e81248deccbbcec34 (patch)
tree460241b8b83a4be60350dacd8a414d53b0f19c03
parent5492f5e083e03304bf7ba49004608f5a9225c0b7 (diff)
downloadlibsolv-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.c3
-rw-r--r--src/pool.h1
-rw-r--r--src/poolvendor.c15
-rw-r--r--src/solvable.c26
-rw-r--r--src/solver.c705
-rw-r--r--src/solver.h63
-rw-r--r--src/solverdebug.c40
-rw-r--r--tools/installcheck.c121
8 files changed, 513 insertions, 461 deletions
diff --git a/src/pool.c b/src/pool.c
index 25dced4..10ab817 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -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)
diff --git a/src/pool.h b/src/pool.h
index 8570324..cdf4fcb 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -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;
}
}
}