diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/chksum.c | 13 | ||||
-rw-r--r-- | src/chksum.h | 1 | ||||
-rw-r--r-- | src/cplxdeps.c | 170 | ||||
-rw-r--r-- | src/cplxdeps.h | 8 | ||||
-rw-r--r-- | src/libsolv.ver | 1 | ||||
-rw-r--r-- | src/pool.c | 22 | ||||
-rw-r--r-- | src/pool.h | 1 | ||||
-rw-r--r-- | src/poolarch.c | 3 | ||||
-rw-r--r-- | src/poolid.c | 2 | ||||
-rw-r--r-- | src/repodata.c | 19 | ||||
-rw-r--r-- | src/rules.c | 20 | ||||
-rw-r--r-- | src/solver.c | 23 | ||||
-rw-r--r-- | src/solver_private.h | 18 |
14 files changed, 256 insertions, 46 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f60853e..5d7190a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ ENDIF (DISABLE_SHARED) SET_TARGET_PROPERTIES(libsolv PROPERTIES OUTPUT_NAME "solv") SET_TARGET_PROPERTIES(libsolv PROPERTIES SOVERSION ${LIBSOLV_SOVERSION}) +SET_TARGET_PROPERTIES(libsolv PROPERTIES INSTALL_NAME_DIR ${LIB_INSTALL_DIR}) INSTALL (FILES ${libsolv_HEADERS} DESTINATION "${INCLUDE_INSTALL_DIR}/solv") INSTALL (TARGETS libsolv LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/chksum.c b/src/chksum.c index 2f27621..935aea8 100644 --- a/src/chksum.c +++ b/src/chksum.c @@ -259,3 +259,16 @@ solv_chksum_free(Chksum *chk, unsigned char *cp) return 0; } +int +solv_chksum_cmp(Chksum *chk, Chksum *chk2) +{ + int len; + const unsigned char *res1, *res2; + if (chk == chk2) + return 1; + if (!chk || !chk2 || chk->type != chk2->type) + return 0; + res1 = solv_chksum_get(chk, &len); + res2 = solv_chksum_get(chk2, 0); + return memcmp(res1, res2, len) == 0 ? 1 : 0; +} diff --git a/src/chksum.h b/src/chksum.h index 02f1504..479923a 100644 --- a/src/chksum.h +++ b/src/chksum.h @@ -28,6 +28,7 @@ void *solv_chksum_free(Chksum *chk, unsigned char *cp); const char *solv_chksum_type2str(Id type); Id solv_chksum_str2type(const char *str); int solv_chksum_len(Id type); +int solv_chksum_cmp(Chksum *chk, Chksum *chk2); #ifdef LIBSOLV_INTERNAL diff --git a/src/cplxdeps.c b/src/cplxdeps.c index 1be6868..aadbc48 100644 --- a/src/cplxdeps.c +++ b/src/cplxdeps.c @@ -96,10 +96,12 @@ print_depblocks(Pool *pool, Queue *bq, int start) #endif /* invert all literals in the blocks. note that this also turns DNF into CNF and vice versa */ -static void -invert_depblocks(Pool *pool, Queue *bq, int start) +static int +invert_depblocks(Pool *pool, Queue *bq, int start, int r) { int i, j, end; + if (r == 0 || r == 1) + return r ? 0 : 1; expand_simpledeps(pool, bq, start, 0); end = bq->count; for (i = j = start; i < end; i++) @@ -122,6 +124,7 @@ invert_depblocks(Pool *pool, Queue *bq, int start) } j = i + 1; } + return -1; } /* @@ -147,40 +150,129 @@ normalize_dep(Pool *pool, Id dep, Queue *bq, int flags) if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_COND) { int rdflags = rd->flags; + Id name = rd->name; + Id evr = rd->evr; int r, mode; - /* in inverted mode, COND means AND. otherwise it means OR NOT */ - if (rdflags == REL_COND && todnf) - rdflags = REL_AND; - mode = rdflags == REL_AND ? 0 : 1; + if (rdflags == REL_COND) + { + /* check for relly complex ELSE case */ + if (ISRELDEP(evr)) + { + Reldep *rd2 = GETRELDEP(pool, evr); + if (rd2->flags == REL_ELSE) + { + int r2; + /* really complex case */ + if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_AND_1) + { + /* A OR ~B */ + rdflags = REL_COND; + evr = rd2->name; + } + else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_AND_2) + { + /* C OR B */ + rdflags = REL_OR; + name = rd2->evr; + evr = rd2->name; + } + else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_1) + { + /* A AND B */ + rdflags = REL_AND; + evr = rd2->name; + } + else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_2) + { + /* A AND C */ + rdflags = REL_AND; + evr = rd2->evr; + } + else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_3) + { + /* C AND ~B */ + rdflags = REL_ELSE; + name = rd2->evr; + evr = rd2->name; + } + else if (!todnf) + { + /* we want AND: A IF (B ELSE C) -> (A OR ~B) AND (C OR B) */ + r = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_AND_1); + if (r == 0 && (flags & CPLXDEPS_DONTFIX) == 0) + return 0; + r2 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_AND_2); + if (r2 == 0 && (flags & CPLXDEPS_DONTFIX) == 0) + { + queue_truncate(bq, bqcnt); + return 0; + } + if (r == -1 || r2 == -1) + return -1; + return r == 1 || r2 == 1 ? 1 : 0; + } + else + { + int r2, r3; + /* we want OR: A IF (B ELSE C) -> (A AND B) OR (A AND C) OR (~B AND C) */ + r = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_1); + if (r == 1) + return 1; + r2 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_2); + if (r2 == 1) + { + queue_truncate(bq, bqcnt); + return 1; + } + r3 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_3); + if (r3 == 1) + { + queue_truncate(bq, bqcnt); + return 1; + } + if (r == -1 || r2 == -1 || r3 == -1) + return -1; + return 0; + } + } + } + } + mode = rdflags == REL_AND || rdflags == REL_ELSE ? 0 : 1; /* get blocks of first argument */ - r = normalize_dep(pool, rd->name, bq, flags); + r = normalize_dep(pool, name, bq, flags); if (r == 0) { + if (rdflags == REL_ELSE) + return 0; if (rdflags == REL_AND && (flags & CPLXDEPS_DONTFIX) == 0) return 0; if (rdflags == REL_COND) { - r = normalize_dep(pool, rd->evr, bq, (flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX); - if (r == 0 || r == 1) - return r == 0 ? 1 : 0; - invert_depblocks(pool, bq, bqcnt); /* invert block for COND */ - return r; + r = normalize_dep(pool, evr, bq, (flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX); + return invert_depblocks(pool, bq, bqcnt, r); /* invert block for COND */ } - return normalize_dep(pool, rd->evr, bq, flags); + return normalize_dep(pool, evr, bq, flags); } if (r == 1) { - if (rdflags != REL_AND) + if (rdflags == REL_ELSE) + { + r = normalize_dep(pool, evr, bq, (flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX); + return invert_depblocks(pool, bq, bqcnt, r); /* invert block for ELSE */ + } + if (rdflags == REL_OR || rdflags == REL_COND) return 1; - return normalize_dep(pool, rd->evr, bq, flags); + return normalize_dep(pool, evr, bq, flags); } /* get blocks of second argument */ bqcnt2 = bq->count; /* COND is OR with NEG on evr block, so we invert the todnf flag in that case */ - r = normalize_dep(pool, rd->evr, bq, rdflags == REL_COND ? ((flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX) : flags); + r = normalize_dep(pool, evr, bq, rdflags == REL_COND || rdflags == REL_ELSE ? ((flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX) : flags); + if (rdflags == REL_COND || rdflags == REL_ELSE) + r = invert_depblocks(pool, bq, bqcnt2, r); /* invert 2nd block */ if (r == 0) { if (rdflags == REL_OR) @@ -188,19 +280,17 @@ normalize_dep(Pool *pool, Id dep, Queue *bq, int flags) if (rdflags == REL_AND && (flags & CPLXDEPS_DONTFIX) != 0) return -1; queue_truncate(bq, bqcnt); - return rdflags == REL_COND ? 1 : 0; + return 0; } if (r == 1) { - if (rdflags == REL_OR) + if (rdflags == REL_COND || rdflags == REL_OR) { queue_truncate(bq, bqcnt); return 1; } return -1; } - if (rdflags == REL_COND) - invert_depblocks(pool, bq, bqcnt2); /* invert 2nd block */ if (mode == todnf) { /* simple case: just join em. nothing more to do here. */ @@ -315,12 +405,7 @@ pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags) expand_simpledeps(pool, bq, bqcnt, 0); } if ((flags & CPLXDEPS_INVERT) != 0) - { - if (i == 0 || i == 1) - i ^= 1; - else - invert_depblocks(pool, bq, bqcnt); - } + i = invert_depblocks(pool, bq, bqcnt, i); #ifdef CPLXDEBUG if (i == 0) printf("NONE\n"); @@ -332,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 b553305..798b485 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) @@ -34,5 +35,12 @@ extern int pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags); #define CPLXDEPS_NAME (1 << 3) #define CPLXDEPS_DONTFIX (1 << 4) +#define CPLXDEPS_ELSE_AND_1 (1 << 8) +#define CPLXDEPS_ELSE_AND_2 (1 << 9) +#define CPLXDEPS_ELSE_OR_1 (1 << 10) +#define CPLXDEPS_ELSE_OR_2 (1 << 11) +#define CPLXDEPS_ELSE_OR_3 (1 << 12) +#define CPLXDEPS_ELSE_MASK (0x1f00) + #endif diff --git a/src/libsolv.ver b/src/libsolv.ver index b8d9764..91186a7 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -248,6 +248,7 @@ SOLV_1.0 { solv_bin2hex; solv_calloc; solv_chksum_add; + solv_chksum_cmp; solv_chksum_create; solv_chksum_create_clone; solv_chksum_create_from_bin; @@ -421,7 +421,7 @@ pool_shrink_whatprovidesaux(Pool *pool) *wp++ = id; } newoff = wp - pool->whatprovidesauxdata; - solv_realloc(pool->whatprovidesauxdata, newoff * sizeof(Id)); + pool->whatprovidesauxdata = solv_realloc(pool->whatprovidesauxdata, newoff * sizeof(Id)); POOL_DEBUG(SOLV_DEBUG_STATS, "shrunk whatprovidesauxdata from %d to %d\n", pool->whatprovidesauxdataoff, newoff); pool->whatprovidesauxdataoff = newoff; } @@ -1014,10 +1014,21 @@ pool_addrelproviders(Pool *pool, Id d) case REL_AND: case REL_OR: + case REL_COND: + if (flags == REL_COND) + { + if (ISRELDEP(evr)) + { + Reldep *rd2 = GETRELDEP(pool, evr); + evr = rd2->flags == REL_ELSE ? rd2->evr : 0; + } + else + evr = 0; /* assume cond is true */ + } wp = pool_whatprovides(pool, name); if (!pool->whatprovidesdata[wp]) - wp = pool_whatprovides(pool, evr); - else + wp = evr ? pool_whatprovides(pool, evr) : 1; + else if (evr) { /* sorted merge */ pp2 = pool_whatprovides_ptr(pool, evr); @@ -1043,11 +1054,6 @@ pool_addrelproviders(Pool *pool, Id d) } break; - case REL_COND: - /* assume the condition is true */ - wp = pool_whatprovides(pool, name); - break; - case REL_NAMESPACE: if (name == NAMESPACE_OTHERPROVIDERS) { @@ -222,6 +222,7 @@ struct _Pool { #define REL_COMPAT 23 #define REL_KIND 24 /* for filters only */ #define REL_MULTIARCH 25 /* debian multiarch annotation */ +#define REL_ELSE 26 /* only as evr part of REL_COND */ #if !defined(__GNUC__) && !defined(__attribute__) # define __attribute__(x) diff --git a/src/poolarch.c b/src/poolarch.c index 79d3bd3..9408983 100644 --- a/src/poolarch.c +++ b/src/poolarch.c @@ -59,7 +59,10 @@ static const char *archpolicies[] = { "sparcv9", "sparcv9:sparcv8:sparc", "sparcv8", "sparcv8:sparc", "sparc", "sparc", + "mips", "mips", "mipsel", "mipsel", + "mips64", "mips64", + "mips64el", "mips64el", "m68k", "m68k", #ifdef FEDORA "ia32e", "ia32e:x86_64:athlon:i686:i586:i486:i386", diff --git a/src/poolid.c b/src/poolid.c index 7bcc1f6..2138c42 100644 --- a/src/poolid.c +++ b/src/poolid.c @@ -192,6 +192,8 @@ pool_id2rel(const Pool *pool, Id id) return " compat >= "; case REL_KIND: return " KIND "; + case REL_ELSE: + return " ELSE "; default: break; } diff --git a/src/repodata.c b/src/repodata.c index 4ba1345..c854262 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -1927,19 +1927,19 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid) return; } di->repoid = 0; - di->data = di->repo->repodata + di->pool->pos.repodataid; - di->repodataid = 0; - di->solvid = solvid; - di->state = di_enterrepo; - di->flags |= SEARCH_THISSOLVID; - return; + if (!di->pool->pos.repodataid && di->pool->pos.solvid == SOLVID_META) { + solvid = SOLVID_META; /* META pos hack */ + } else { + di->data = di->repo->repodata + di->pool->pos.repodataid; + di->repodataid = 0; + } } - if (solvid > 0) + else if (solvid > 0) { di->repo = di->pool->solvables[solvid].repo; di->repoid = 0; } - else if (di->repoid > 0) + if (di->repoid > 0) { if (!di->pool->urepos) { @@ -1949,7 +1949,8 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid) di->repoid = 1; di->repo = di->pool->repos[di->repoid]; } - di->repodataid = 1; + if (solvid != SOLVID_POS) + di->repodataid = 1; di->solvid = solvid; if (solvid) di->flags |= SEARCH_THISSOLVID; diff --git a/src/rules.c b/src/rules.c index 67de769..3264e9b 100644 --- a/src/rules.c +++ b/src/rules.c @@ -52,7 +52,9 @@ dep_possible(Solver *solv, Id dep, Map *m) Reldep *rd = GETRELDEP(pool, dep); if (rd->flags >= 8) { - if (rd->flags == REL_AND || rd->flags == REL_COND) + if (rd->flags == REL_COND) + return 1; + if (rd->flags == REL_AND) { if (!dep_possible(solv, rd->name, m)) return 0; @@ -966,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); @@ -983,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 f551731..b89e0d1 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); diff --git a/src/solver_private.h b/src/solver_private.h index f8df8c7..fe80881 100644 --- a/src/solver_private.h +++ b/src/solver_private.h @@ -27,7 +27,23 @@ solver_dep_fulfilled(Solver *solv, Id dep) if (ISRELDEP(dep)) { Reldep *rd = GETRELDEP(pool, dep); - if (rd->flags == REL_AND || rd->flags == REL_COND) + if (rd->flags == REL_COND) + { + if (ISRELDEP(rd->evr)) + { + Reldep *rd2 = GETRELDEP(pool, rd->evr); + if (rd2->flags == REL_ELSE) + { + if (solver_dep_fulfilled(solv, rd2->name)) + return solver_dep_fulfilled(solv, rd->name); + return solver_dep_fulfilled(solv, rd2->evr); + } + } + if (solver_dep_fulfilled(solv, rd->name)) + return 1; + return !solver_dep_fulfilled(solv, rd->evr); + } + if (rd->flags == REL_AND) { if (!solver_dep_fulfilled(solv, rd->name)) return 0; |