summaryrefslogtreecommitdiff
path: root/src/solver_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/solver_util.c')
-rw-r--r--src/solver_util.c178
1 files changed, 115 insertions, 63 deletions
diff --git a/src/solver_util.c b/src/solver_util.c
index bd5d4b4..fb17bf4 100644
--- a/src/solver_util.c
+++ b/src/solver_util.c
@@ -181,84 +181,91 @@ solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd)
return 0;
}
-
-/* mirrors solver_dep_fulfilled, but returns 2 if a new package
- * was involved */
static int
-solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+solver_dep_fulfilled_complex_func(Solver *solv, Reldep *rd, int (*dep_fullfilled)(Solver *, Id))
{
Pool *pool = solv->pool;
- Id p, pp;
- int r;
-
- if (ISRELDEP(dep))
+ int r1, r2;
+ if (rd->flags == REL_COND)
{
- Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags == REL_COND)
+ if (ISRELDEP(rd->evr))
{
- int r1, r2;
- if (ISRELDEP(rd->evr))
+ Reldep *rd2 = GETRELDEP(pool, rd->evr);
+ if (rd2->flags == REL_ELSE)
{
- Reldep *rd2 = GETRELDEP(pool, rd->evr);
- if (rd2->flags == REL_ELSE)
+ r1 = dep_fullfilled(solv, rd2->name);
+ if (r1)
{
- r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
- if (r1)
- {
- r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
- return r2 && r1 == 2 ? 2 : r2;
- }
- return solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
+ r2 = dep_fullfilled(solv, rd->name);
+ return r2 && r1 == 2 ? 2 : r2;
}
+ return dep_fullfilled(solv, rd2->evr);
}
- r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
- r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
- if (!r1 && !r2)
- return 0;
- return r1 == 2 ? 2 : 1;
}
- if (rd->flags == REL_UNLESS)
+ r1 = dep_fullfilled(solv, rd->name);
+ r2 = !dep_fullfilled(solv, rd->evr);
+ if (!r1 && !r2)
+ return 0;
+ return r1 == 2 ? 2 : 1;
+ }
+ if (rd->flags == REL_UNLESS)
+ {
+ if (ISRELDEP(rd->evr))
{
- int r1, r2;
- if (ISRELDEP(rd->evr))
+ Reldep *rd2 = GETRELDEP(pool, rd->evr);
+ if (rd2->flags == REL_ELSE)
{
- Reldep *rd2 = GETRELDEP(pool, rd->evr);
- if (rd2->flags == REL_ELSE)
+ r1 = dep_fullfilled(solv, rd2->name);
+ if (r1)
{
- r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
- if (r1)
- {
- r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
- return r2 && r1 == 2 ? 2 : r2;
- }
- return solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+ r2 = dep_fullfilled(solv, rd2->evr);
+ return r2 && r1 == 2 ? 2 : r2;
}
+ return dep_fullfilled(solv, rd->name);
}
- /* A AND NOT(B) */
- r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
- r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
- if (!r1 || !r2)
- return 0;
- return r1 == 2 ? 2 : 1;
- }
- if (rd->flags == REL_AND)
- {
- int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
- if (!r1)
- return 0;
- r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
- if (!r2)
- return 0;
- return r1 == 2 || r2 == 2 ? 2 : 1;
- }
- if (rd->flags == REL_OR)
- {
- int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
- r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
- if (!r1 && !r2)
- return 0;
- return r1 == 2 || r2 == 2 ? 2 : 1;
}
+ /* A AND NOT(B) */
+ r1 = dep_fullfilled(solv, rd->name);
+ r2 = !dep_fullfilled(solv, rd->evr);
+ if (!r1 || !r2)
+ return 0;
+ return r1 == 2 ? 2 : 1;
+ }
+ if (rd->flags == REL_AND)
+ {
+ r1 = dep_fullfilled(solv, rd->name);
+ if (!r1)
+ return 0;
+ r2 = dep_fullfilled(solv, rd->evr);
+ if (!r2)
+ return 0;
+ return r1 == 2 || r2 == 2 ? 2 : 1;
+ }
+ if (rd->flags == REL_OR)
+ {
+ r1 = dep_fullfilled(solv, rd->name);
+ r2 = dep_fullfilled(solv, rd->evr);
+ if (!r1 && !r2)
+ return 0;
+ return r1 == 2 || r2 == 2 ? 2 : 1;
+ }
+ return 0;
+}
+
+/* mirrors solver_dep_fulfilled, but returns 2 if a new package
+ * was involved */
+static int
+solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+{
+ Pool *pool = solv->pool;
+ Id p, pp;
+ int r;
+
+ if (ISRELDEP(dep))
+ {
+ Reldep *rd = GETRELDEP(pool, dep);
+ if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
+ return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_alreadyinstalled);
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
if (rd->flags == REL_NAMESPACE && solv->installsuppdepq)
@@ -282,16 +289,61 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
return r;
}
+static int
+solver_dep_fulfilled_namespace(Solver *solv, Id dep)
+{
+ Pool *pool = solv->pool;
+ Id p, pp;
+ int r = 1;
+
+ if (ISRELDEP(dep))
+ {
+ Reldep *rd = GETRELDEP(pool, dep);
+ if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
+ return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_namespace);
+ if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
+ return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
+ if (rd->flags == REL_NAMESPACE)
+ r = 2;
+ }
+ FOR_PROVIDES(p, pp, dep)
+ if (solv->decisionmap[p] > 0)
+ return r;
+ return 0;
+}
+
int
solver_is_supplementing_alreadyinstalled(Solver *solv, Solvable *s)
{
Id sup, *supp;
supp = s->repo->idarraydata + s->supplements;
while ((sup = *supp++) != 0)
- if (solver_dep_fulfilled_alreadyinstalled(solv, sup) == 2)
+ {
+ if (!solv->addalreadyrecommended && solver_dep_fulfilled_alreadyinstalled(solv, sup) != 2)
+ continue;
+ if (solv->only_namespace_recommended && solver_dep_fulfilled_namespace(solv, sup) != 2)
+ continue;
return 1;
+ }
return 0;
}
+
+int
+solver_is_namespace_dep_slow(Solver *solv, Reldep *rd)
+{
+ Pool *pool = solv->pool;
+ for (;;)
+ {
+ if (rd->flags == REL_NAMESPACE)
+ return 1;
+ if (ISRELDEP(rd->name) && solver_is_namespace_dep_slow(solv, GETRELDEP(pool, rd->name)))
+ return 1;
+ if (!ISRELDEP(rd->evr))
+ return 0;
+ rd = GETRELDEP(pool, rd->evr);
+ }
+}
+
/*
* add all installed packages that package p obsoletes to Queue q.
* Package p is not installed. Also, we know that if