summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-27 14:58:05 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-27 14:58:05 +0900
commitf458102388250c8a1cbbfa8f18d27baa204c696c (patch)
tree447d75c1ae4449828e094d36a2f97f9b46b455ef /src
parent8fcc0d8e03716077d1f2c2ca79fc622880a32196 (diff)
downloadlibsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.tar.gz
libsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.tar.bz2
libsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.zip
Imported Upstream version 0.6.23upstream/0.6.23
Change-Id: Idc1e282dc113b7350d8e123283f1a36097b76857 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/libsolv.ver1
-rw-r--r--src/pool.c218
-rw-r--r--src/pool.h36
-rw-r--r--src/repo.c224
-rw-r--r--src/repo.h7
-rw-r--r--src/rules.c43
-rw-r--r--src/solvable.c297
-rw-r--r--src/solvable.h7
-rw-r--r--src/solver.c23
-rw-r--r--src/solver.h4
-rw-r--r--src/solverdebug.c33
-rw-r--r--src/solverdebug.h4
-rw-r--r--src/solvversion.h.in24
-rw-r--r--src/suse.c748
-rw-r--r--src/transaction.c8
16 files changed, 862 insertions, 817 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 241890d..0109755 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,7 +19,7 @@ SET (libsolv_SRCS
queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c
transaction.c order.c rules.c problems.c linkedpkg.c cplxdeps.c
chksum.c md5.c sha1.c sha2.c solvversion.c selection.c
- fileprovides.c diskusage.c)
+ fileprovides.c diskusage.c suse.c)
SET (libsolv_HEADERS
bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h
diff --git a/src/libsolv.ver b/src/libsolv.ver
index a5efd6a..dd1596e 100644
--- a/src/libsolv.ver
+++ b/src/libsolv.ver
@@ -167,6 +167,7 @@ SOLV_1.0 {
repo_lookup_void;
repo_matchvalue;
repo_reserve_ids;
+ repo_rewrite_suse_deps;
repo_search;
repo_set_deparray;
repo_set_id;
diff --git a/src/pool.c b/src/pool.c
index c51c62e..72e22f8 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -1681,224 +1681,6 @@ pool_bin2hex(Pool *pool, const unsigned char *buf, int len)
return s;
}
-/* map:
- * 1: installed
- * 2: conflicts with installed
- * 8: interesting (only true if installed)
- * 16: undecided
- */
-
-static inline Id dep2name(Pool *pool, Id dep)
-{
- while (ISRELDEP(dep))
- {
- Reldep *rd = GETRELDEP(pool, dep);
- dep = rd->name;
- }
- return dep;
-}
-
-static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id con)
-{
- Id p, pp;
- Solvable *sn = pool->solvables + n;
-
- FOR_PROVIDES(p, pp, sn->name)
- {
- Solvable *s = pool->solvables + p;
- if (s->name != sn->name || s->arch != sn->arch)
- continue;
- if ((map[p] & 9) != 9)
- continue;
- if (pool_match_nevr(pool, pool->solvables + p, con))
- continue;
- return 1; /* found installed package that doesn't conflict */
- }
- return 0;
-}
-
-static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep, int ispatch, Map *multiversionmap)
-{
- Id p, pp;
- int r = 0;
- FOR_PROVIDES(p, pp, dep)
- {
- if (p == SYSTEMSOLVABLE)
- return 1; /* always boring, as never constraining */
- if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
- continue;
- if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
- if (providedbyinstalled_multiversion(pool, map, p, dep))
- continue;
- if ((map[p] & 9) == 9)
- return 9;
- r |= map[p] & 17;
- }
- return r;
-}
-
-/*
- * pool_trivial_installable - calculate if a set of solvables is
- * trivial installable without any other installs/deinstalls of
- * packages not belonging to the set.
- *
- * the state is returned in the result queue:
- * 1: solvable is installable without any other package changes
- * 0: solvable is not installable
- * -1: solvable is installable, but doesn't constrain any installed packages
- */
-
-void
-pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap)
-{
- int i, r, m, did;
- Id p, *dp, con, *conp, req, *reqp;
- unsigned char *map;
- Solvable *s;
-
- map = solv_calloc(pool->nsolvables, 1);
- for (p = 1; p < pool->nsolvables; p++)
- {
- if (!MAPTST(installedmap, p))
- continue;
- map[p] |= 9;
- s = pool->solvables + p;
- if (!s->conflicts)
- continue;
- conp = s->repo->idarraydata + s->conflicts;
- while ((con = *conp++) != 0)
- {
- dp = pool_whatprovides_ptr(pool, con);
- for (; *dp; dp++)
- map[p] |= 2; /* XXX: self conflict ? */
- }
- }
- for (i = 0; i < pkgs->count; i++)
- map[pkgs->elements[i]] = 16;
-
- for (i = 0, did = 0; did < pkgs->count; i++, did++)
- {
- if (i == pkgs->count)
- i = 0;
- p = pkgs->elements[i];
- if ((map[p] & 16) == 0)
- continue;
- if ((map[p] & 2) != 0)
- {
- map[p] = 2;
- continue;
- }
- s = pool->solvables + p;
- m = 1;
- if (s->requires)
- {
- reqp = s->repo->idarraydata + s->requires;
- while ((req = *reqp++) != 0)
- {
- if (req == SOLVABLE_PREREQMARKER)
- continue;
- r = providedbyinstalled(pool, map, req, 0, 0);
- if (!r)
- {
- /* decided and miss */
- map[p] = 2;
- did = 0;
- break;
- }
- if (r == 16)
- break; /* undecided */
- m |= r; /* 1 | 9 | 17 */
- }
- if (req)
- continue;
- if ((m & 9) == 9)
- m = 9;
- }
- if (s->conflicts)
- {
- int ispatch = 0; /* see solver.c patch handling */
-
- if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
- ispatch = 1;
- conp = s->repo->idarraydata + s->conflicts;
- while ((con = *conp++) != 0)
- {
- if ((providedbyinstalled(pool, map, con, ispatch, multiversionmap) & 1) != 0)
- {
- map[p] = 2;
- did = 0;
- break;
- }
- if ((m == 1 || m == 17) && ISRELDEP(con))
- {
- con = dep2name(pool, con);
- if ((providedbyinstalled(pool, map, con, ispatch, multiversionmap) & 1) != 0)
- m = 9;
- }
- }
- if (con)
- continue; /* found a conflict */
- }
-#if 0
- if (s->repo && s->repo != oldinstalled)
- {
- Id p2, obs, *obsp, *pp;
- Solvable *s2;
- if (s->obsoletes)
- {
- obsp = s->repo->idarraydata + s->obsoletes;
- while ((obs = *obsp++) != 0)
- {
- if ((providedbyinstalled(pool, map, obs, 0, 0) & 1) != 0)
- {
- map[p] = 2;
- break;
- }
- }
- if (obs)
- continue;
- }
- FOR_PROVIDES(p2, pp, s->name)
- {
- s2 = pool->solvables + p2;
- if (s2->name == s->name && (map[p2] & 1) != 0)
- {
- map[p] = 2;
- break;
- }
- }
- if (p2)
- continue;
- }
-#endif
- if (m != map[p])
- {
- map[p] = m;
- did = 0;
- }
- }
- queue_free(res);
- queue_init_clone(res, pkgs);
- for (i = 0; i < pkgs->count; i++)
- {
- m = map[pkgs->elements[i]];
- if ((m & 9) == 9)
- r = 1;
- else if (m & 1)
- r = -1;
- else
- r = 0;
- res->elements[i] = r;
- }
- free(map);
-}
-
-void
-pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res)
-{
- pool_trivial_installable_multiversionmap(pool, installedmap, pkgs, res, 0);
-}
-
const char *
pool_lookup_str(Pool *pool, Id entry, Id keyname)
{
diff --git a/src/pool.h b/src/pool.h
index 069594b..86d49aa 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -289,13 +289,6 @@ static inline const char *pool_solvid2str(Pool *pool, Id p)
void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
-int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap);
-int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *multiversionmap);
-int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap);
-int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap);
-
-void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
-
int pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, int evr);
int pool_match_dep(Pool *pool, Id d1, Id d2);
@@ -358,6 +351,16 @@ void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*c
void pool_clear_pos(Pool *pool);
+/* lookup functions */
+const char *pool_lookup_str(Pool *pool, Id entry, Id keyname);
+Id pool_lookup_id(Pool *pool, Id entry, Id keyname);
+unsigned long long pool_lookup_num(Pool *pool, Id entry, Id keyname, unsigned long long notfound);
+int pool_lookup_void(Pool *pool, Id entry, Id keyname);
+const unsigned char *pool_lookup_bin_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
+int pool_lookup_idarray(Pool *pool, Id entry, Id keyname, Queue *q);
+const char *pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
+const char *pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp);
+
#define DUCHANGES_ONLYADD 1
@@ -368,19 +371,10 @@ typedef struct _DUChanges {
int flags;
} DUChanges;
-void pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps);
-int pool_calc_installsizechange(Pool *pool, Map *installedmap);
-void pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res);
-void pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap);
-const char *pool_lookup_str(Pool *pool, Id entry, Id keyname);
-Id pool_lookup_id(Pool *pool, Id entry, Id keyname);
-unsigned long long pool_lookup_num(Pool *pool, Id entry, Id keyname, unsigned long long notfound);
-int pool_lookup_void(Pool *pool, Id entry, Id keyname);
-const unsigned char *pool_lookup_bin_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
-int pool_lookup_idarray(Pool *pool, Id entry, Id keyname, Queue *q);
-const char *pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
-const char *pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp);
+void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
+void pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps);
+int pool_calc_installsizechange(Pool *pool, Map *installedmap);
void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts);
@@ -411,6 +405,10 @@ void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts);
#define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
#define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)
+/* weird suse stuff */
+void pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap);
+void pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/repo.c b/src/repo.c
index 15e7e80..9e59fe2 100644
--- a/src/repo.c
+++ b/src/repo.c
@@ -666,230 +666,6 @@ repo_reserve_ids(Repo *repo, Offset olddeps, int num)
/***********************************************************************/
-/*
- * some SUSE specific fixups, should go into a separate file
- */
-
-Offset
-repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
-{
- Pool *pool = repo->pool;
- Id id, idp, idl;
- char buf[1024], *p, *dep;
- int i, l;
-
- if (provides)
- {
- for (i = provides; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
- {
- idp = 0;
- strcpy(buf + 2, dep);
- dep = buf + 2 + 7;
- if ((p = strchr(dep, ':')) != 0 && p != dep)
- {
- *p++ = 0;
- idp = pool_str2id(pool, dep, 1);
- dep = p;
- }
- id = 0;
- while ((p = strchr(dep, ';')) != 0)
- {
- if (p == dep)
- {
- dep = p + 1;
- continue;
- }
- *p++ = 0;
- idl = pool_str2id(pool, dep, 1);
- idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
- if (id)
- id = pool_rel2id(pool, id, idl, REL_OR, 1);
- else
- id = idl;
- dep = p;
- }
- if (dep[0] && dep[1])
- {
- for (p = dep; *p && *p != ')'; p++)
- ;
- *p = 0;
- idl = pool_str2id(pool, dep, 1);
- idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
- if (id)
- id = pool_rel2id(pool, id, idl, REL_OR, 1);
- else
- id = idl;
- }
- if (idp)
- id = pool_rel2id(pool, idp, id, REL_AND, 1);
- if (id)
- supplements = repo_addid_dep(repo, supplements, id, 0);
- }
- else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- p = buf + (p - dep);
- *p++ = 0;
- idp = pool_str2id(pool, buf, 1);
- /* strip trailing slashes */
- l = strlen(p);
- while (l > 1 && p[l - 1] == '/')
- p[--l] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, idp, id, REL_WITH, 1);
- id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
- supplements = repo_addid_dep(repo, supplements, id, 0);
- }
- }
- }
- if (supplements)
- {
- for (i = supplements; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "system:modalias(", 16))
- dep += 7;
- if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- p = strchr(buf + 9, ':');
- if (p && p != buf + 9 && strchr(p + 1, ':'))
- {
- *p++ = 0;
- idp = pool_str2id(pool, buf + 9, 1);
- p[strlen(p) - 1] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
- id = pool_rel2id(pool, idp, id, REL_AND, 1);
- }
- else
- {
- p = buf + 9;
- p[strlen(p) - 1] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
- }
- if (id)
- repo->idarraydata[i] = id;
- }
- else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- id = 0;
- dep = buf + 11;
- while ((p = strchr(dep, ':')) != 0)
- {
- if (p == dep)
- {
- dep = p + 1;
- continue;
- }
- /* argh, allow pattern: prefix. sigh */
- if (p - dep == 7 && !strncmp(dep, "pattern", 7))
- {
- p = strchr(p + 1, ':');
- if (!p)
- break;
- }
- *p++ = 0;
- idp = pool_str2id(pool, dep, 1);
- if (id)
- id = pool_rel2id(pool, id, idp, REL_AND, 1);
- else
- id = idp;
- dep = p;
- }
- if (dep[0] && dep[1])
- {
- dep[strlen(dep) - 1] = 0;
- idp = pool_str2id(pool, dep, 1);
- if (id)
- id = pool_rel2id(pool, id, idp, REL_AND, 1);
- else
- id = idp;
- }
- if (id)
- repo->idarraydata[i] = id;
- }
- else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep + 11);
- if ((p = strrchr(buf, ')')) != 0)
- *p = 0;
- id = pool_str2id(pool, buf, 1);
- id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
- repo->idarraydata[i] = id;
- }
- }
- }
- if (freshens && repo->idarraydata[freshens])
- {
- Id idsupp = 0, idfresh = 0;
- if (!supplements || !repo->idarraydata[supplements])
- return freshens;
- for (i = supplements; repo->idarraydata[i]; i++)
- {
- if (!idsupp)
- idsupp = repo->idarraydata[i];
- else
- idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
- }
- for (i = freshens; repo->idarraydata[i]; i++)
- {
- if (!idfresh)
- idfresh = repo->idarraydata[i];
- else
- idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
- }
- if (!idsupp)
- idsupp = idfresh;
- else
- idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
- supplements = repo_addid_dep(repo, 0, idsupp, 0);
- }
- return supplements;
-}
-
-Offset
-repo_fix_conflicts(Repo *repo, Offset conflicts)
-{
- char buf[1024], *p, *dep;
- Pool *pool = repo->pool;
- Id id;
- int i;
-
- if (!conflicts)
- return conflicts;
- for (i = conflicts; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
- {
- strcpy(buf, dep + 15);
- if ((p = strchr(buf, ')')) != 0)
- *p = 0;
- id = pool_str2id(pool, buf, 1);
- id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
- repo->idarraydata[i] = id;
- }
- }
- return conflicts;
-}
-
-/***********************************************************************/
-
struct matchdata
{
Pool *pool;
diff --git a/src/repo.h b/src/repo.h
index 952dbeb..a63999a 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -72,8 +72,6 @@ extern Id repo_add_solvable_block_before(Repo *repo, int count, Repo *beforerepo
extern Offset repo_addid(Repo *repo, Offset olddeps, Id id);
extern Offset repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker);
extern Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num);
-extern Offset repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens);
-extern Offset repo_fix_conflicts(Repo *repo, Offset conflicts);
static inline const char *repo_name(const Repo *repo)
{
@@ -181,6 +179,11 @@ void repo_disable_paging(Repo *repo);
for (rdid = 1; rdid < repo->nrepodata && (data = repo_id2repodata(repo, rdid)); rdid++)
#endif
+/* weird suse stuff, do not use */
+extern Offset repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens);
+extern Offset repo_fix_conflicts(Repo *repo, Offset conflicts);
+extern void repo_rewrite_suse_deps(Solvable *s, Offset freshens);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/rules.c b/src/rules.c
index 32855e4..aa90b5f 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -3869,9 +3869,8 @@ complex_cleandeps_addback(Pool *pool, Id ip, Id req, Map *im, Map *installedm, Q
{
if (!MAPTST(installedm, -p))
break;
- continue;
}
- if (MAPTST(im, p))
+ else if (p == ip)
break;
}
if (!p)
@@ -3880,6 +3879,8 @@ complex_cleandeps_addback(Pool *pool, Id ip, Id req, Map *im, Map *installedm, Q
{
if (p < 0)
continue;
+ if (MAPTST(im, p))
+ continue;
if (!MAPTST(installedm, p))
continue;
if (p == ip || MAPTST(userinstalled, p - pool->installed->start))
@@ -4387,6 +4388,36 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
#ifdef CLEANDEPSDEBUG
printf("adding back %s\n", pool_solvable2str(pool, s));
#endif
+ if (s->repo == installed && pool->implicitobsoleteusescolors)
+ {
+ Id a, bestarch = 0;
+ FOR_PROVIDES(p, pp, s->name)
+ {
+ Solvable *ps = pool->solvables + p;
+ if (ps->name != s->name || ps->repo == installed)
+ continue;
+ a = ps->arch;
+ a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
+ if (a && a != 1 && (!bestarch || a < bestarch))
+ bestarch = a;
+ }
+ if (bestarch && (s->arch > pool->lastarch || pool->id2arch[s->arch] != bestarch))
+ {
+ FOR_PROVIDES(p, pp, s->name)
+ {
+ Solvable *ps = pool->solvables + p;
+ if (ps->repo == installed && ps->name == s->name && ps->evr == s->evr && ps->arch != s->arch && ps->arch < pool->lastarch && pool->id2arch[ps->arch] == bestarch)
+ if (!MAPTST(&im, p))
+ {
+#ifdef CLEANDEPSDEBUG
+ printf("%s lockstep %s\n", pool_solvid2str(pool, ip), pool_solvid2str(pool, p));
+#endif
+ MAPSET(&im, p);
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
if (s->requires)
{
reqp = s->repo->idarraydata + s->requires;
@@ -4400,12 +4431,14 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
}
#endif
FOR_PROVIDES(p, pp, req)
- if (MAPTST(&im, p))
+ if (p == ip)
break;
if (p)
continue;
FOR_PROVIDES(p, pp, req)
{
+ if (MAPTST(&im, p))
+ continue;
if (MAPTST(&installedm, p))
{
if (p == ip)
@@ -4434,12 +4467,14 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
}
#endif
FOR_PROVIDES(p, pp, req)
- if (MAPTST(&im, p))
+ if (p == ip)
break;
if (p)
continue;
FOR_PROVIDES(p, pp, req)
{
+ if (MAPTST(&im, p))
+ continue;
if (MAPTST(&installedm, p))
{
if (p == ip)
diff --git a/src/solvable.c b/src/solvable.c
index cccc89d..2570e4f 100644
--- a/src/solvable.c
+++ b/src/solvable.c
@@ -409,305 +409,12 @@ solvable_lookup_sourcepkg(Solvable *s)
/*****************************************************************************/
-static inline Id dep2name(Pool *pool, Id dep)
-{
- while (ISRELDEP(dep))
- {
- Reldep *rd = GETRELDEP(pool, dep);
- dep = rd->name;
- }
- return dep;
-}
-
-static int providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con)
-{
- Id p, pp;
- Solvable *sn = pool->solvables + n;
-
- FOR_PROVIDES(p, pp, sn->name)
- {
- Solvable *s = pool->solvables + p;
- if (s->name != sn->name || s->arch != sn->arch)
- continue;
- if (!MAPTST(installed, p))
- continue;
- if (pool_match_nevr(pool, pool->solvables + p, con))
- continue;
- return 1; /* found installed package that doesn't conflict */
- }
- return 0;
-}
-
-static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *multiversionmap)
-{
- Id p, pp;
- FOR_PROVIDES(p, pp, dep)
- {
- if (p == SYSTEMSOLVABLE)
- return -1;
- if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
- continue;
- if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
- if (providedbyinstalled_multiversion(pool, installed, p, dep))
- continue;
- if (MAPTST(installed, p))
- return 1;
- }
- return 0;
-}
-
-/*
- * solvable_trivial_installable_map - anwers is a solvable is installable
- * without any other installs/deinstalls.
- * The packages considered to be installed are provided via the
- * installedmap bitmap. A additional "conflictsmap" bitmap providing
- * information about the conflicts of the installed packages can be
- * used for extra speed up. Provide a NULL pointer if you do not
- * have this information.
- * Both maps can be created with pool_create_state_maps() or
- * solver_create_state_maps().
- *
- * returns:
- * 1: solvable is installable without any other package changes
- * 0: solvable is not installable
- * -1: solvable is installable, but doesn't constrain any installed packages
- */
-int
-solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap)
-{
- Pool *pool = s->repo->pool;
- Solvable *s2;
- Id p, *dp;
- Id *reqp, req;
- Id *conp, con;
- int r, interesting = 0;
-
- if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
- return 0;
- if (s->requires)
- {
- reqp = s->repo->idarraydata + s->requires;
- while ((req = *reqp++) != 0)
- {
- if (req == SOLVABLE_PREREQMARKER)
- continue;
- r = providedbyinstalled(pool, installedmap, req, 0, 0);
- if (!r)
- return 0;
- if (r > 0)
- interesting = 1;
- }
- }
- if (s->conflicts)
- {
- int ispatch = 0;
-
- if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
- ispatch = 1;
- conp = s->repo->idarraydata + s->conflicts;
- while ((con = *conp++) != 0)
- {
- if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
- {
- if (ispatch && solvable_is_irrelevant_patch(s, installedmap))
- return -1;
- return 0;
- }
- if (!interesting && ISRELDEP(con))
- {
- con = dep2name(pool, con);
- if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
- interesting = 1;
- }
- }
- if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap))
- interesting = 0;
- }
-#if 0
- if (s->repo)
- {
- Id *obsp, obs;
- Repo *installed = 0;
- if (s->obsoletes && s->repo != installed)
- {
- obsp = s->repo->idarraydata + s->obsoletes;
- while ((obs = *obsp++) != 0)
- {
- if (providedbyinstalled(pool, installedmap, obs, 0, 0))
- return 0;
- }
- }
- if (s->repo != installed)
- {
- Id pp;
- FOR_PROVIDES(p, pp, s->name)
- {
- s2 = pool->solvables + p;
- if (s2->repo == installed && s2->name == s->name)
- return 0;
- }
- }
- }
-#endif
- if (!conflictsmap)
- {
- int i;
-
- p = s - pool->solvables;
- for (i = 1; i < pool->nsolvables; i++)
- {
- if (!MAPTST(installedmap, i))
- continue;
- s2 = pool->solvables + i;
- if (!s2->conflicts)
- continue;
- conp = s2->repo->idarraydata + s2->conflicts;
- while ((con = *conp++) != 0)
- {
- dp = pool_whatprovides_ptr(pool, con);
- for (; *dp; dp++)
- if (*dp == p)
- return 0;
- }
- }
- }
- return interesting ? 1 : -1;
-}
-
-/*
- * different interface for solvable_trivial_installable_map, where
- * the information about the installed packages is provided
- * by a queue.
- */
-int
-solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap)
-{
- Pool *pool = s->repo->pool;
- int i;
- Id p;
- Map installedmap;
- int r;
-
- map_init(&installedmap, pool->nsolvables);
- for (i = 0; i < installed->count; i++)
- {
- p = installed->elements[i];
- if (p > 0) /* makes it work with decisionq */
- MAPSET(&installedmap, p);
- }
- r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
- map_free(&installedmap);
- return r;
-}
-
-/*
- * different interface for solvable_trivial_installable_map, where
- * the information about the installed packages is provided
- * by a repo containing the installed solvables.
- */
-int
-solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *multiversionmap)
-{
- Pool *pool = s->repo->pool;
- Id p;
- Solvable *s2;
- Map installedmap;
- int r;
-
- map_init(&installedmap, pool->nsolvables);
- FOR_REPO_SOLVABLES(installed, p, s2)
- MAPSET(&installedmap, p);
- r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
- map_free(&installedmap);
- return r;
-}
-
-/* FIXME: this mirrors policy_illegal_vendorchange */
-static int
-pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2)
-{
- Id v1, v2;
- Id vendormask1, vendormask2;
-
- if (pool->custom_vendorcheck)
- return pool->custom_vendorcheck(pool, s1, s2);
- /* treat a missing vendor as empty string */
- v1 = s1->vendor ? s1->vendor : ID_EMPTY;
- v2 = s2->vendor ? s2->vendor : ID_EMPTY;
- if (v1 == v2)
- return 0;
- vendormask1 = pool_vendor2mask(pool, v1);
- if (!vendormask1)
- return 1; /* can't match */
- vendormask2 = pool_vendor2mask(pool, v2);
- if ((vendormask1 & vendormask2) != 0)
- return 0;
- return 1; /* no class matches */
-}
-
-/* check if this patch is relevant according to the vendor. To bad that patches
- * don't have a vendor, so we need to do some careful repo testing. */
-int
-solvable_is_irrelevant_patch(Solvable *s, Map *installedmap)
-{
- Pool *pool = s->repo->pool;
- Id con, *conp;
- int hadpatchpackage = 0;
-
- if (!s->conflicts)
- return 0;
- conp = s->repo->idarraydata + s->conflicts;
- while ((con = *conp++) != 0)
- {
- Reldep *rd;
- Id p, pp, p2, pp2;
- if (!ISRELDEP(con))
- continue;
- rd = GETRELDEP(pool, con);
- if (rd->flags != REL_LT)
- continue;
- FOR_PROVIDES(p, pp, con)
- {
- Solvable *si;
- if (!MAPTST(installedmap, p))
- continue;
- si = pool->solvables + p;
- if (!pool_match_nevr(pool, si, con))
- continue;
- FOR_PROVIDES(p2, pp2, rd->name)
- {
- Solvable *s2 = pool->solvables + p2;
- if (!pool_match_nevr(pool, s2, rd->name))
- continue;
- if (pool_match_nevr(pool, s2, con))
- continue; /* does not fulfill patch */
- if (s2->repo == s->repo)
- {
- hadpatchpackage = 1;
- /* ok, we have a package from the patch repo that solves the conflict. check vendor */
- if (si->vendor == s2->vendor)
- return 0;
- if (!pool_illegal_vendorchange(pool, si, s2))
- return 0;
- /* vendor change was illegal, ignore conflict */
- }
- }
- }
- }
- /* if we didn't find a patchpackage don't claim that the patch is irrelevant */
- if (!hadpatchpackage)
- return 0;
- return 1;
-}
-
-/*****************************************************************************/
-
/*
* Create maps containing the state of each solvable. Input is a "installed" queue,
* it contains all solvable ids that are considered to be installed.
*
- * The created maps can be used for solvable_trivial_installable_map(),
- * pool_calc_duchanges(), pool_calc_installsizechange().
+ * The created maps can be used for * pool_calc_duchanges() and
+ * pool_calc_installsizechange().
*
*/
void
diff --git a/src/solvable.h b/src/solvable.h
index 85d20c4..090b758 100644
--- a/src/solvable.h
+++ b/src/solvable.h
@@ -17,6 +17,7 @@
#include "pooltypes.h"
#include "queue.h"
+#include "bitmap.h"
#ifdef __cplusplus
extern "C" {
@@ -80,6 +81,12 @@ int solvable_identical(Solvable *s1, Solvable *s2);
Id solvable_selfprovidedep(Solvable *s);
int solvable_matchesdep(Solvable *s, Id keyname, Id dep, int marker);
+/* weird suse stuff */
+int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap);
+int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap);
+int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap);
+int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *multiversionmap);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/solver.c b/src/solver.c
index 4f849ec..5fca20d 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -2913,6 +2913,8 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
lastsi = -1;
break;
}
+ if (solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, p))
+ continue;
if (lastsi < 0 && (MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p)))
lastsi = i;
}
@@ -2925,6 +2927,9 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
p = -solv->branches.elements[i];
if (p <= 0 || solv->decisionmap[p] != l + 1)
continue;
+ if (solv->favormap.size && MAPTST(&solv->favormap, p))
+ if (!(solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, p)))
+ continue; /* current selection is favored */
if (!(MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p)))
{
lasti = lastsi;
@@ -4480,24 +4485,6 @@ solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap)
pool_create_state_maps(solv->pool, &solv->decisionq, installedmap, conflictsmap);
}
-void
-solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
-{
- Pool *pool = solv->pool;
- Map installedmap;
- int i;
- pool_create_state_maps(pool, &solv->decisionq, &installedmap, 0);
- pool_trivial_installable_multiversionmap(pool, &installedmap, pkgs, res, solv->multiversion.size ? &solv->multiversion : 0);
- for (i = 0; i < res->count; i++)
- if (res->elements[i] != -1)
- {
- Solvable *s = pool->solvables + pkgs->elements[i];
- if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap))
- res->elements[i] = -1;
- }
- map_free(&installedmap);
-}
-
/*-------------------------------------------------------------------
*
* decision introspection
diff --git a/src/solver.h b/src/solver.h
index 3495fd8..758f1eb 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -348,7 +348,6 @@ extern void solver_create_state_maps(Solver *solv, Map *installedmap, Map *confl
extern void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps);
extern int solver_calc_installsizechange(Solver *solv);
-extern void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res);
extern void pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what);
extern int pool_isemptyupdatejob(Pool *pool, Id how, Id what);
@@ -384,6 +383,9 @@ extern const char *solver_alternative2str(Solver *solv, int type, Id id, Id from
continue; \
else
+/* weird suse stuff */
+extern void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/solverdebug.c b/src/solverdebug.c
index 39f5d78..bb74ef6 100644
--- a/src/solverdebug.c
+++ b/src/solverdebug.c
@@ -568,36 +568,3 @@ solver_printallsolutions(Solver *solv)
}
}
-void
-solver_printtrivial(Solver *solv)
-{
- Pool *pool = solv->pool;
- Queue in, out;
- Id p;
- const char *n;
- Solvable *s;
- int i;
-
- queue_init(&in);
- for (p = 1, s = pool->solvables + p; p < solv->pool->nsolvables; p++, s++)
- {
- n = pool_id2str(pool, s->name);
- if (strncmp(n, "patch:", 6) != 0 && strncmp(n, "pattern:", 8) != 0)
- continue;
- queue_push(&in, p);
- }
- if (!in.count)
- {
- queue_free(&in);
- return;
- }
- queue_init(&out);
- solver_trivial_installable(solv, &in, &out);
- POOL_DEBUG(SOLV_DEBUG_RESULT, "trivial installable status:\n");
- for (i = 0; i < in.count; i++)
- POOL_DEBUG(SOLV_DEBUG_RESULT, " %s: %d\n", pool_solvid2str(pool, in.elements[i]), out.elements[i]);
- POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
- queue_free(&in);
- queue_free(&out);
-}
-
diff --git a/src/solverdebug.h b/src/solverdebug.h
index 32e427e..b6923b4 100644
--- a/src/solverdebug.h
+++ b/src/solverdebug.h
@@ -33,10 +33,12 @@ extern void solver_printprobleminfo(Solver *solv, Id problem);
extern void solver_printcompleteprobleminfo(Solver *solv, Id problem);
extern void solver_printsolution(Solver *solv, Id problem, Id solution);
extern void solver_printallsolutions(Solver *solv);
-extern void solver_printtrivial(Solver *solv);
extern void transaction_print(Transaction *trans);
+/* weird suse stuff */
+extern void solver_printtrivial(Solver *solv);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/solvversion.h.in b/src/solvversion.h.in
index 268219c..75dc63f 100644
--- a/src/solvversion.h.in
+++ b/src/solvversion.h.in
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Novell Inc.
+ * Copyright (c) 2016, SUSE LLC
*
* This program is licensed under the BSD license, read LICENSE.BSD
* for further information
@@ -24,4 +24,26 @@ extern int solv_version_major;
extern int solv_version_minor;
extern int solv_version_patch;
+#cmakedefine LIBSOLV_FEATURE_LINKED_PKGS
+#cmakedefine LIBSOLV_FEATURE_COMPLEX_DEPS
+#cmakedefine LIBSOLV_FEATURE_MULTI_SEMANTICS
+
+#cmakedefine LIBSOLVEXT_FEATURE_RPMDB
+#cmakedefine LIBSOLVEXT_FEATURE_RPMDB_BYRPMHEADER
+#cmakedefine LIBSOLVEXT_FEATURE_PUBKEY
+#cmakedefine LIBSOLVEXT_FEATURE_RPMMD
+#cmakedefine LIBSOLVEXT_FEATURE_SUSEREPO
+#cmakedefine LIBSOLVEXT_FEATURE_COMPS
+#cmakedefine LIBSOLVEXT_FEATURE_HELIXREPO
+#cmakedefine LIBSOLVEXT_FEATURE_DEBIAN
+#cmakedefine LIBSOLVEXT_FEATURE_ARCHREPO
+#cmakedefine LIBSOLVEXT_FEATURE_CUDFREPO
+#cmakedefine LIBSOLVEXT_FEATURE_HAIKU
+#cmakedefine LIBSOLVEXT_FEATURE_APPDATA
+#cmakedefine LIBSOLVEXT_FEATURE_LZMA_COMPRESSION
+#cmakedefine LIBSOLVEXT_FEATURE_BZIP2_COMPRESSION
+
+/* see tools/common_write.c for toolversion history */
+#define LIBSOLV_TOOLVERSION "1.1"
+
#endif
diff --git a/src/suse.c b/src/suse.c
new file mode 100644
index 0000000..6106f3f
--- /dev/null
+++ b/src/suse.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 2016, SUSE LLC.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/* weird SUSE stuff. better not use it for your projects. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "solver.h"
+#include "solver_private.h"
+#include "bitmap.h"
+#include "pool.h"
+#include "poolvendor.h"
+#include "util.h"
+
+Offset
+repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
+{
+ Pool *pool = repo->pool;
+ Id id, idp, idl;
+ char buf[1024], *p, *dep;
+ int i, l;
+
+ if (provides)
+ {
+ for (i = provides; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
+ {
+ idp = 0;
+ strcpy(buf + 2, dep);
+ dep = buf + 2 + 7;
+ if ((p = strchr(dep, ':')) != 0 && p != dep)
+ {
+ *p++ = 0;
+ idp = pool_str2id(pool, dep, 1);
+ dep = p;
+ }
+ id = 0;
+ while ((p = strchr(dep, ';')) != 0)
+ {
+ if (p == dep)
+ {
+ dep = p + 1;
+ continue;
+ }
+ *p++ = 0;
+ idl = pool_str2id(pool, dep, 1);
+ idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idl, REL_OR, 1);
+ else
+ id = idl;
+ dep = p;
+ }
+ if (dep[0] && dep[1])
+ {
+ for (p = dep; *p && *p != ')'; p++)
+ ;
+ *p = 0;
+ idl = pool_str2id(pool, dep, 1);
+ idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idl, REL_OR, 1);
+ else
+ id = idl;
+ }
+ if (idp)
+ id = pool_rel2id(pool, idp, id, REL_AND, 1);
+ if (id)
+ supplements = repo_addid_dep(repo, supplements, id, 0);
+ }
+ else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ p = buf + (p - dep);
+ *p++ = 0;
+ idp = pool_str2id(pool, buf, 1);
+ /* strip trailing slashes */
+ l = strlen(p);
+ while (l > 1 && p[l - 1] == '/')
+ p[--l] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, idp, id, REL_WITH, 1);
+ id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
+ supplements = repo_addid_dep(repo, supplements, id, 0);
+ }
+ }
+ }
+ if (supplements)
+ {
+ for (i = supplements; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "system:modalias(", 16))
+ dep += 7;
+ if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ p = strchr(buf + 9, ':');
+ if (p && p != buf + 9 && strchr(p + 1, ':'))
+ {
+ *p++ = 0;
+ idp = pool_str2id(pool, buf + 9, 1);
+ p[strlen(p) - 1] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
+ id = pool_rel2id(pool, idp, id, REL_AND, 1);
+ }
+ else
+ {
+ p = buf + 9;
+ p[strlen(p) - 1] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
+ }
+ if (id)
+ repo->idarraydata[i] = id;
+ }
+ else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ id = 0;
+ dep = buf + 11;
+ while ((p = strchr(dep, ':')) != 0)
+ {
+ if (p == dep)
+ {
+ dep = p + 1;
+ continue;
+ }
+ /* argh, allow pattern: prefix. sigh */
+ if (p - dep == 7 && !strncmp(dep, "pattern", 7))
+ {
+ p = strchr(p + 1, ':');
+ if (!p)
+ break;
+ }
+ *p++ = 0;
+ idp = pool_str2id(pool, dep, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idp, REL_AND, 1);
+ else
+ id = idp;
+ dep = p;
+ }
+ if (dep[0] && dep[1])
+ {
+ dep[strlen(dep) - 1] = 0;
+ idp = pool_str2id(pool, dep, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idp, REL_AND, 1);
+ else
+ id = idp;
+ }
+ if (id)
+ repo->idarraydata[i] = id;
+ }
+ else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep + 11);
+ if ((p = strrchr(buf, ')')) != 0)
+ *p = 0;
+ id = pool_str2id(pool, buf, 1);
+ id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
+ repo->idarraydata[i] = id;
+ }
+ }
+ }
+ if (freshens && repo->idarraydata[freshens])
+ {
+ Id idsupp = 0, idfresh = 0;
+ if (!supplements || !repo->idarraydata[supplements])
+ return freshens;
+ for (i = supplements; repo->idarraydata[i]; i++)
+ {
+ if (!idsupp)
+ idsupp = repo->idarraydata[i];
+ else
+ idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
+ }
+ for (i = freshens; repo->idarraydata[i]; i++)
+ {
+ if (!idfresh)
+ idfresh = repo->idarraydata[i];
+ else
+ idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
+ }
+ if (!idsupp)
+ idsupp = idfresh;
+ else
+ idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
+ supplements = repo_addid_dep(repo, 0, idsupp, 0);
+ }
+ return supplements;
+}
+
+Offset
+repo_fix_conflicts(Repo *repo, Offset conflicts)
+{
+ char buf[1024], *p, *dep;
+ Pool *pool = repo->pool;
+ Id id;
+ int i;
+
+ if (!conflicts)
+ return conflicts;
+ for (i = conflicts; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
+ {
+ strcpy(buf, dep + 15);
+ if ((p = strchr(buf, ')')) != 0)
+ *p = 0;
+ id = pool_str2id(pool, buf, 1);
+ id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
+ repo->idarraydata[i] = id;
+ }
+ }
+ return conflicts;
+}
+
+void
+repo_rewrite_suse_deps(Solvable *s, Offset freshens)
+{
+ s->supplements = repo_fix_supplements(s->repo, s->provides, s->supplements, freshens);
+ if (s->conflicts)
+ s->conflicts = repo_fix_conflicts(s->repo, s->conflicts);
+}
+
+/**********************************************************************************/
+
+static inline Id
+dep2name(Pool *pool, Id dep)
+{
+ while (ISRELDEP(dep))
+ {
+ Reldep *rd = GETRELDEP(pool, dep);
+ dep = rd->name;
+ }
+ return dep;
+}
+
+static int
+providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con)
+{
+ Id p, pp;
+ Solvable *sn = pool->solvables + n;
+
+ FOR_PROVIDES(p, pp, sn->name)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != sn->name || s->arch != sn->arch)
+ continue;
+ if (!MAPTST(installed, p))
+ continue;
+ if (pool_match_nevr(pool, pool->solvables + p, con))
+ continue;
+ return 1; /* found installed package that doesn't conflict */
+ }
+ return 0;
+}
+
+static inline int
+providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *multiversionmap)
+{
+ Id p, pp;
+ FOR_PROVIDES(p, pp, dep)
+ {
+ if (p == SYSTEMSOLVABLE)
+ return -1;
+ if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+ continue;
+ if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
+ if (providedbyinstalled_multiversion(pool, installed, p, dep))
+ continue;
+ if (MAPTST(installed, p))
+ return 1;
+ }
+ return 0;
+}
+
+/* xmap:
+ * 1: installed
+ * 2: conflicts with installed
+ * 8: interesting (only true if installed)
+ * 16: undecided
+ */
+
+static int
+providedbyinstalled_multiversion_xmap(Pool *pool, unsigned char *map, Id n, Id con)
+{
+ Id p, pp;
+ Solvable *sn = pool->solvables + n;
+
+ FOR_PROVIDES(p, pp, sn->name)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != sn->name || s->arch != sn->arch)
+ continue;
+ if ((map[p] & 9) != 9)
+ continue;
+ if (pool_match_nevr(pool, pool->solvables + p, con))
+ continue;
+ return 1; /* found installed package that doesn't conflict */
+ }
+ return 0;
+}
+
+
+static inline int
+providedbyinstalled_xmap(Pool *pool, unsigned char *map, Id dep, int ispatch, Map *multiversionmap)
+{
+ Id p, pp;
+ int r = 0;
+ FOR_PROVIDES(p, pp, dep)
+ {
+ if (p == SYSTEMSOLVABLE)
+ return 1; /* always boring, as never constraining */
+ if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+ continue;
+ if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
+ if (providedbyinstalled_multiversion_xmap(pool, map, p, dep))
+ continue;
+ if ((map[p] & 9) == 9)
+ return 9;
+ r |= map[p] & 17;
+ }
+ return r;
+}
+
+/* FIXME: this mirrors policy_illegal_vendorchange */
+static int
+pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2)
+{
+ Id v1, v2;
+ Id vendormask1, vendormask2;
+
+ if (pool->custom_vendorcheck)
+ return pool->custom_vendorcheck(pool, s1, s2);
+ /* treat a missing vendor as empty string */
+ v1 = s1->vendor ? s1->vendor : ID_EMPTY;
+ v2 = s2->vendor ? s2->vendor : ID_EMPTY;
+ if (v1 == v2)
+ return 0;
+ vendormask1 = pool_vendor2mask(pool, v1);
+ if (!vendormask1)
+ return 1; /* can't match */
+ vendormask2 = pool_vendor2mask(pool, v2);
+ if ((vendormask1 & vendormask2) != 0)
+ return 0;
+ return 1; /* no class matches */
+}
+
+/* check if this patch is relevant according to the vendor. To bad that patches
+ * don't have a vendor, so we need to do some careful repo testing. */
+int
+solvable_is_irrelevant_patch(Solvable *s, Map *installedmap)
+{
+ Pool *pool = s->repo->pool;
+ Id con, *conp;
+ int hadpatchpackage = 0;
+
+ if (!s->conflicts)
+ return 0;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ Reldep *rd;
+ Id p, pp, p2, pp2;
+ if (!ISRELDEP(con))
+ continue;
+ rd = GETRELDEP(pool, con);
+ if (rd->flags != REL_LT)
+ continue;
+ FOR_PROVIDES(p, pp, con)
+ {
+ Solvable *si;
+ if (!MAPTST(installedmap, p))
+ continue;
+ si = pool->solvables + p;
+ if (!pool_match_nevr(pool, si, con))
+ continue;
+ FOR_PROVIDES(p2, pp2, rd->name)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (!pool_match_nevr(pool, s2, rd->name))
+ continue;
+ if (pool_match_nevr(pool, s2, con))
+ continue; /* does not fulfill patch */
+ if (s2->repo == s->repo)
+ {
+ hadpatchpackage = 1;
+ /* ok, we have a package from the patch repo that solves the conflict. check vendor */
+ if (si->vendor == s2->vendor)
+ return 0;
+ if (!pool_illegal_vendorchange(pool, si, s2))
+ return 0;
+ /* vendor change was illegal, ignore conflict */
+ }
+ }
+ }
+ }
+ /* if we didn't find a patchpackage don't claim that the patch is irrelevant */
+ if (!hadpatchpackage)
+ return 0;
+ return 1;
+}
+
+/*
+ * solvable_trivial_installable_map - answers if a solvable is installable
+ * without any other installs/deinstalls.
+ * The packages considered to be installed are provided via the
+ * installedmap bitmap. A additional "conflictsmap" bitmap providing
+ * information about the conflicts of the installed packages can be
+ * used for extra speed up. Provide a NULL pointer if you do not
+ * have this information.
+ * Both maps can be created with pool_create_state_maps() or
+ * solver_create_state_maps().
+ *
+ * returns:
+ * 1: solvable is installable without any other package changes
+ * 0: solvable is not installable
+ * -1: solvable is installable, but doesn't constrain any installed packages
+ */
+int
+solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ Solvable *s2;
+ Id p, *dp;
+ Id *reqp, req;
+ Id *conp, con;
+ int r, interesting = 0;
+
+ if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
+ return 0;
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ r = providedbyinstalled(pool, installedmap, req, 0, 0);
+ if (!r)
+ return 0;
+ if (r > 0)
+ interesting = 1;
+ }
+ }
+ if (s->conflicts)
+ {
+ int ispatch = 0;
+
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+ ispatch = 1;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
+ {
+ if (ispatch && solvable_is_irrelevant_patch(s, installedmap))
+ return -1;
+ return 0;
+ }
+ if (!interesting && ISRELDEP(con))
+ {
+ con = dep2name(pool, con);
+ if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
+ interesting = 1;
+ }
+ }
+ if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap))
+ interesting = 0;
+ }
+ if (!conflictsmap)
+ {
+ int i;
+
+ p = s - pool->solvables;
+ for (i = 1; i < pool->nsolvables; i++)
+ {
+ if (!MAPTST(installedmap, i))
+ continue;
+ s2 = pool->solvables + i;
+ if (!s2->conflicts)
+ continue;
+ conp = s2->repo->idarraydata + s2->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ dp = pool_whatprovides_ptr(pool, con);
+ for (; *dp; dp++)
+ if (*dp == p)
+ return 0;
+ }
+ }
+ }
+ return interesting ? 1 : -1;
+}
+
+/*
+ * different interface for solvable_trivial_installable_map, where
+ * the information about the installed packages is provided
+ * by a queue.
+ */
+int
+solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ int i;
+ Id p;
+ Map installedmap;
+ int r;
+
+ map_init(&installedmap, pool->nsolvables);
+ for (i = 0; i < installed->count; i++)
+ {
+ p = installed->elements[i];
+ if (p > 0) /* makes it work with decisionq */
+ MAPSET(&installedmap, p);
+ }
+ r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
+ map_free(&installedmap);
+ return r;
+}
+
+/*
+ * different interface for solvable_trivial_installable_map, where
+ * the information about the installed packages is provided
+ * by a repo containing the installed solvables.
+ */
+int
+solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ Id p;
+ Solvable *s2;
+ Map installedmap;
+ int r;
+
+ map_init(&installedmap, pool->nsolvables);
+ FOR_REPO_SOLVABLES(installed, p, s2)
+ MAPSET(&installedmap, p);
+ r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
+ map_free(&installedmap);
+ return r;
+}
+
+/*
+ * pool_trivial_installable - calculate if a set of solvables is
+ * trivial installable without any other installs/deinstalls of
+ * packages not belonging to the set.
+ *
+ * the state is returned in the result queue:
+ * 1: solvable is installable without any other package changes
+ * 0: solvable is not installable
+ * -1: solvable is installable, but doesn't constrain any installed packages
+ */
+
+void
+pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap)
+{
+ int i, r, m, did;
+ Id p, *dp, con, *conp, req, *reqp;
+ unsigned char *map;
+ Solvable *s;
+
+ map = solv_calloc(pool->nsolvables, 1);
+ for (p = 1; p < pool->nsolvables; p++)
+ {
+ if (!MAPTST(installedmap, p))
+ continue;
+ map[p] |= 9;
+ s = pool->solvables + p;
+ if (!s->conflicts)
+ continue;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ dp = pool_whatprovides_ptr(pool, con);
+ for (; *dp; dp++)
+ map[p] |= 2; /* XXX: self conflict ? */
+ }
+ }
+ for (i = 0; i < pkgs->count; i++)
+ map[pkgs->elements[i]] = 16;
+
+ for (i = 0, did = 0; did < pkgs->count; i++, did++)
+ {
+ if (i == pkgs->count)
+ i = 0;
+ p = pkgs->elements[i];
+ if ((map[p] & 16) == 0)
+ continue;
+ if ((map[p] & 2) != 0)
+ {
+ map[p] = 2;
+ continue;
+ }
+ s = pool->solvables + p;
+ m = 1;
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ r = providedbyinstalled_xmap(pool, map, req, 0, 0);
+ if (!r)
+ {
+ /* decided and miss */
+ map[p] = 2;
+ did = 0;
+ break;
+ }
+ if (r == 16)
+ break; /* undecided */
+ m |= r; /* 1 | 9 | 17 */
+ }
+ if (req)
+ continue;
+ if ((m & 9) == 9)
+ m = 9;
+ }
+ if (s->conflicts)
+ {
+ int ispatch = 0; /* see solver.c patch handling */
+
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+ ispatch = 1;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
+ {
+ map[p] = 2;
+ did = 0;
+ break;
+ }
+ if ((m == 1 || m == 17) && ISRELDEP(con))
+ {
+ con = dep2name(pool, con);
+ if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
+ m = 9;
+ }
+ }
+ if (con)
+ continue; /* found a conflict */
+ }
+ if (m != map[p])
+ {
+ map[p] = m;
+ did = 0;
+ }
+ }
+ queue_free(res);
+ queue_init_clone(res, pkgs);
+ for (i = 0; i < pkgs->count; i++)
+ {
+ m = map[pkgs->elements[i]];
+ if ((m & 9) == 9)
+ r = 1;
+ else if (m & 1)
+ r = -1;
+ else
+ r = 0;
+ res->elements[i] = r;
+ }
+ free(map);
+}
+
+void
+pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res)
+{
+ pool_trivial_installable_multiversionmap(pool, installedmap, pkgs, res, 0);
+}
+
+void
+solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
+{
+ Pool *pool = solv->pool;
+ Map installedmap;
+ int i;
+ pool_create_state_maps(pool, &solv->decisionq, &installedmap, 0);
+ pool_trivial_installable_multiversionmap(pool, &installedmap, pkgs, res, solv->multiversion.size ? &solv->multiversion : 0);
+ for (i = 0; i < res->count; i++)
+ if (res->elements[i] != -1)
+ {
+ Solvable *s = pool->solvables + pkgs->elements[i];
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap))
+ res->elements[i] = -1;
+ }
+ map_free(&installedmap);
+}
+
+void
+solver_printtrivial(Solver *solv)
+{
+ Pool *pool = solv->pool;
+ Queue in, out;
+ Id p;
+ const char *n;
+ Solvable *s;
+ int i;
+
+ queue_init(&in);
+ for (p = 1, s = pool->solvables + p; p < solv->pool->nsolvables; p++, s++)
+ {
+ n = pool_id2str(pool, s->name);
+ if (strncmp(n, "patch:", 6) != 0 && strncmp(n, "pattern:", 8) != 0)
+ continue;
+ queue_push(&in, p);
+ }
+ if (!in.count)
+ {
+ queue_free(&in);
+ return;
+ }
+ queue_init(&out);
+ solver_trivial_installable(solv, &in, &out);
+ POOL_DEBUG(SOLV_DEBUG_RESULT, "trivial installable status:\n");
+ for (i = 0; i < in.count; i++)
+ POOL_DEBUG(SOLV_DEBUG_RESULT, " %s: %d\n", pool_solvid2str(pool, in.elements[i]), out.elements[i]);
+ POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
+ queue_free(&in);
+ queue_free(&out);
+}
+
+
diff --git a/src/transaction.c b/src/transaction.c
index ffe1ec2..9a32966 100644
--- a/src/transaction.c
+++ b/src/transaction.c
@@ -56,6 +56,14 @@ obsq_sortcmp(const void *ap, const void *bp, void *dp)
r = pool_evrcmp(pool, oas->evr, obs->evr, EVRCMP_COMPARE);
if (r)
return -r; /* highest version first */
+ if (oas->arch != obs->arch)
+ {
+ /* bring same arch to front */
+ if (oas->arch == s->arch)
+ return -1;
+ if (obs->arch == s->arch)
+ return 1;
+ }
return oa - ob;
}