From: Michael Schroeder Date: Tue, 25 Aug 2015 10:48:05 +0000 (+0200) Subject: Fix REL_COND for weak deps corner cases X-Git-Tag: 0.6.12~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=348e68e31c3175baadcc913b07305bbc61d2b8d1;p=thirdparty%2Flibsolv.git Fix REL_COND for weak deps corner cases --- diff --git a/src/cplxdeps.c b/src/cplxdeps.c index 2248b8b8..aadbc48e 100644 --- a/src/cplxdeps.c +++ b/src/cplxdeps.c @@ -417,5 +417,38 @@ pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags) return i; } +void +pool_add_pos_literals_complex_dep(Pool *pool, Id dep, Queue *q, Map *m, int neg) +{ + while (ISRELDEP(dep)) + { + Reldep *rd = GETRELDEP(pool, dep); + if (rd->flags != REL_AND && rd->flags != REL_OR && rd->flags != REL_COND) + break; + pool_add_pos_literals_complex_dep(pool, rd->name, q, m, neg); + dep = rd->evr; + if (rd->flags == REL_COND) + { + neg = !neg; + if (ISRELDEP(dep)) + { + Reldep *rd2 = GETRELDEP(pool, rd->evr); + if (rd2->flags == REL_ELSE) + { + pool_add_pos_literals_complex_dep(pool, rd2->evr, q, m, !neg); + dep = rd2->name; + } + } + } + } + if (!neg) + { + Id p, pp; + FOR_PROVIDES(p, pp, dep) + if (!MAPTST(m, p)) + queue_push(q, p); + } +} + #endif /* ENABLE_COMPLEX_DEPS */ diff --git a/src/cplxdeps.h b/src/cplxdeps.h index 1cda760e..798b485a 100644 --- a/src/cplxdeps.h +++ b/src/cplxdeps.h @@ -27,6 +27,7 @@ pool_is_complex_dep(Pool *pool, Id dep) } extern int pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags); +extern void pool_add_pos_literals_complex_dep(Pool *pool, Id dep, Queue *q, Map *m, int neg); #define CPLXDEPS_TODNF (1 << 0) #define CPLXDEPS_EXPAND (1 << 1) diff --git a/src/rules.c b/src/rules.c index 7a6d7fde..3264e9b8 100644 --- a/src/rules.c +++ b/src/rules.c @@ -968,13 +968,20 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m) } /*----------------------------------------- - * add recommends to the work queue + * add recommends/suggests to the work queue */ if (s->recommends && m) { recp = s->repo->idarraydata + s->recommends; while ((rec = *recp++) != 0) { +#ifdef ENABLE_COMPLEX_DEPS + if (pool_is_complex_dep(pool, rec)) + { + pool_add_pos_literals_complex_dep(pool, rec, &workq, m, 0); + continue; + } +#endif FOR_PROVIDES(p, pp, rec) if (!MAPTST(m, p)) queue_push(&workq, p); @@ -985,6 +992,13 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m) sugp = s->repo->idarraydata + s->suggests; while ((sug = *sugp++) != 0) { +#ifdef ENABLE_COMPLEX_DEPS + if (pool_is_complex_dep(pool, sug)) + { + pool_add_pos_literals_complex_dep(pool, sug, &workq, m, 0); + continue; + } +#endif FOR_PROVIDES(p, pp, sug) if (!MAPTST(m, p)) queue_push(&workq, p); diff --git a/src/solver.c b/src/solver.c index f5517311..b89e0d17 100644 --- a/src/solver.c +++ b/src/solver.c @@ -117,6 +117,29 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep) if (ISRELDEP(dep)) { Reldep *rd = GETRELDEP(pool, dep); + if (rd->flags == REL_COND) + { + int r1, r2; + if (ISRELDEP(rd->evr)) + { + Reldep *rd2 = GETRELDEP(pool, rd->evr); + if (rd2->flags == REL_ELSE) + { + 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); + } + } + 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);