summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/chksum.c13
-rw-r--r--src/chksum.h1
-rw-r--r--src/cplxdeps.c170
-rw-r--r--src/cplxdeps.h8
-rw-r--r--src/libsolv.ver1
-rw-r--r--src/pool.c22
-rw-r--r--src/pool.h1
-rw-r--r--src/poolarch.c3
-rw-r--r--src/poolid.c2
-rw-r--r--src/repodata.c19
-rw-r--r--src/rules.c20
-rw-r--r--src/solver.c23
-rw-r--r--src/solver_private.h18
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;
diff --git a/src/pool.c b/src/pool.c
index f78f71a..33293b5 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -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)
{
diff --git a/src/pool.h b/src/pool.h
index 6b98efc..4a2089d 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -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;