diff options
Diffstat (limited to 'src/solver_util.c')
-rw-r--r-- | src/solver_util.c | 178 |
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 |