summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt25
-rw-r--r--NEWS3
-rw-r--r--VERSION.cmake2
-rw-r--r--examples/solv/repoinfo_system_rpm.c9
-rw-r--r--ext/repo_appdata.c19
-rw-r--r--ext/repo_autopattern.c7
-rw-r--r--ext/repo_content.c4
-rw-r--r--ext/repo_helix.c3
-rw-r--r--ext/repo_products.c8
-rw-r--r--ext/repo_rpmdb.c3
-rw-r--r--ext/repo_rpmmd.c3
-rw-r--r--ext/repo_susetags.c8
-rw-r--r--ext/testcase.c123
-rw-r--r--package/libsolv.changes17
-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
-rw-r--r--tools/common_write.c6
-rw-r--r--tools/rpmdb2solv.c5
32 files changed, 1029 insertions, 895 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f2a6e16..0153a70 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -172,7 +172,6 @@ ENDIF (RPM5)
IF (MULTI_SEMANTICS)
MESSAGE (STATUS "Enabling multi dist support")
-ADD_DEFINITIONS (-DMULTI_SEMANTICS)
ENDIF (MULTI_SEMANTICS)
INCLUDE (CheckIncludeFile)
@@ -237,14 +236,32 @@ ENDIF (${CMAKE_MAJOR_VERSION} GREATER 2)
# should create config.h with #cmakedefine instead...
FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
- HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS
+ HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS)
+ IF(${VAR})
+ ADD_DEFINITIONS (-D${VAR}=1)
+ SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
+ ENDIF (${VAR})
+ENDFOREACH (VAR)
+
+FOREACH (VAR
+ ENABLE_LINKED_PKGS ENABLE_COMPLEX_DEPS MULTI_SEMANTICS)
+ IF(${VAR})
+ ADD_DEFINITIONS (-D${VAR}=1)
+ SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
+ STRING(REPLACE ENABLE_ "" VARX ${VAR})
+ SET (LIBSOLV_FEATURE_${VARX} 1)
+ ENDIF (${VAR})
+ENDFOREACH (VAR)
+
+FOREACH (VAR
ENABLE_RPMDB ENABLE_PUBKEY ENABLE_RPMMD ENABLE_RPMDB_BYRPMHEADER ENABLE_SUSEREPO ENABLE_COMPS
ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_ARCHREPO ENABLE_DEBIAN ENABLE_HAIKU
- ENABLE_LZMA_COMPRESSION ENABLE_BZIP2_COMPRESSION ENABLE_PGPVRFY ENABLE_APPDATA
- ENABLE_LINKED_PKGS ENABLE_COMPLEX_DEPS)
+ ENABLE_LZMA_COMPRESSION ENABLE_BZIP2_COMPRESSION ENABLE_PGPVRFY ENABLE_APPDATA)
IF(${VAR})
ADD_DEFINITIONS (-D${VAR}=1)
SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
+ STRING(REPLACE ENABLE_ "" VARX ${VAR})
+ SET (LIBSOLVEXT_FEATURE_${VARX} 1)
ENDIF (${VAR})
ENDFOREACH (VAR)
diff --git a/NEWS b/NEWS
index a5403ed..1745af8 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@
This file contains the major changes between
libsolv versions:
+Version 0.6.22, 0.6.23
+- bug fix releases, no new features
+
Version 0.6.21
- new features:
* SOLVER_FAVOR and SOLVER_DISFAVOR job types
diff --git a/VERSION.cmake b/VERSION.cmake
index 2da1637..10ade66 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "0")
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "22")
+SET(LIBSOLV_PATCH "23")
diff --git a/examples/solv/repoinfo_system_rpm.c b/examples/solv/repoinfo_system_rpm.c
index b385d72..4926ecd 100644
--- a/examples/solv/repoinfo_system_rpm.c
+++ b/examples/solv/repoinfo_system_rpm.c
@@ -27,7 +27,8 @@
# define PRODUCTS_PATH "/etc/products.d"
#endif
#ifdef ENABLE_APPDATA
-# define APPDATA_PATH "/usr/share/appdata"
+# define APPDATA_PATH "/usr/share/metainfo"
+# define APPDATA_LEGACY_PATH "/usr/share/appdata"
#endif
static void
@@ -101,6 +102,12 @@ read_installed_rpm(struct repoinfo *cinfo)
fprintf(stderr, "appdata reading failed: %s\n", pool_errstr(pool));
return 0;
}
+#elif defined(ENABLE_APPDATA) && defined(APPDATA_LEGACY_PATH)
+ if (repo_add_appdata_dir(repo, APPDATA_LEGACY_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
+ {
+ fprintf(stderr, "appdata reading from legacy dir failed: %s\n", pool_errstr(pool));
+ return 0;
+ }
#endif
ofp = fopen(calc_cachepath(repo, 0, 0), "r");
if (repo_add_rpmdb_reffp(repo, ofp, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
diff --git a/ext/repo_appdata.c b/ext/repo_appdata.c
index cbc42e4..2b9844e 100644
--- a/ext/repo_appdata.c
+++ b/ext/repo_appdata.c
@@ -178,12 +178,18 @@ startElement(void *userData, const char *name, const char **atts)
switch(pd->state)
{
case STATE_APPLICATION:
- s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
- pd->handle = s - pool->solvables;
- pd->havesummary = 0;
type = find_attr("type", atts);
if (!type || !*type)
type = "desktop";
+ if (strcmp(type, "desktop") != 0)
+ {
+ /* ignore for now */
+ pd->solvable = 0;
+ break;
+ }
+ s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
+ pd->handle = s - pool->solvables;
+ pd->havesummary = 0;
repodata_set_poolstr(pd->data, pd->handle, SOLVABLE_CATEGORY, type);
break;
case STATE_DESCRIPTION:
@@ -373,6 +379,13 @@ endElement(void *userData, const char *name)
}
pd->skip_depth = 0;
+ if (!s)
+ {
+ pd->state = pd->sbtab[pd->state];
+ pd->docontent = 0;
+ return;
+ }
+
switch (pd->state)
{
case STATE_APPLICATION:
diff --git a/ext/repo_autopattern.c b/ext/repo_autopattern.c
index 4c767e1..f6e1004 100644
--- a/ext/repo_autopattern.c
+++ b/ext/repo_autopattern.c
@@ -396,11 +396,10 @@ repo_add_autopattern(Repo *repo, int flags)
repodata_set_str(data, h, PRODUCT_UPDATES_REPOID, newname);
repodata_add_flexarray(data, s2 - pool->solvables, PRODUCT_UPDATES, h);
}
- else if (!strcmp(pn, "product-endoflife()") && evr)
+ else if (!strcmp(pn, "product-endoflife()"))
{
- time_t t = datestr2timestamp(newname);
- if (t)
- repodata_set_num(data, s2 - pool->solvables, PRODUCT_ENDOFLIFE, t);
+ /* FATE#320699: Support tri-state product-endoflife (tag absent, present but nodate(0), present + date) */
+ repodata_set_num(data, s2 - pool->solvables, PRODUCT_ENDOFLIFE,(evr ? datestr2timestamp(newname) : 0) );
}
else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32)
{
diff --git a/ext/repo_content.c b/ext/repo_content.c
index 0cd1293..b12c4cd 100644
--- a/ext/repo_content.c
+++ b/ext/repo_content.c
@@ -404,7 +404,7 @@ repo_add_content(Repo *repo, FILE *fp, int flags)
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
if (code10)
- s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
+ repo_rewrite_suse_deps(s, 0);
}
/* create new solvable */
s = pool_id2solvable(pool, repo_add_solvable(repo));
@@ -538,7 +538,7 @@ repo_add_content(Repo *repo, FILE *fp, int flags)
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
if (code10)
- s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
+ repo_rewrite_suse_deps(s, 0);
/* now for every other arch, clone the product except the architecture */
for (i = 0; i < numotherarchs; ++i)
diff --git a/ext/repo_helix.c b/ext/repo_helix.c
index f495be7..6358f72 100644
--- a/ext/repo_helix.c
+++ b/ext/repo_helix.c
@@ -636,8 +636,7 @@ endElement(void *userData, const char *name)
/* ensure self-provides */
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, pd->freshens);
- s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts);
+ repo_rewrite_suse_deps(s, pd->freshens);
pd->freshens = 0;
/* see bugzilla bnc#190163 */
diff --git a/ext/repo_products.c b/ext/repo_products.c
index cb69c49..326f8fd 100644
--- a/ext/repo_products.c
+++ b/ext/repo_products.c
@@ -376,12 +376,8 @@ endElement(void *userData, const char *name)
repodata_set_str(pd->data, pd->handle, SOLVABLE_CPEID, pd->content);
break;
case STATE_ENDOFLIFE:
- if (*pd->content)
- {
- time_t t = datestr2timestamp(pd->content);
- if (t)
- repodata_set_num(pd->data, pd->handle, PRODUCT_ENDOFLIFE, (unsigned long long)t);
- }
+ /* FATE#320699: Support tri-state product-endoflife (tag absent, present but nodate(0), present + date) */
+ repodata_set_num(pd->data, pd->handle, PRODUCT_ENDOFLIFE, (*pd->content ? datestr2timestamp(pd->content) : 0));
break;
default:
break;
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index 9445023..95756c0 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -990,8 +990,7 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead,
s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0, 0);
s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0, 0);
- s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
- s->conflicts = repo_fix_conflicts(repo, s->conflicts);
+ repo_rewrite_suse_deps(s, 0);
if (data && ignq.count)
repodata_set_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, &ignq);
diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c
index 729f4f7..8854bca 100644
--- a/ext/repo_rpmmd.c
+++ b/ext/repo_rpmmd.c
@@ -1119,8 +1119,7 @@ endElement(void *userData, const char *name)
s->evr = ID_EMPTY; /* some patterns have this */
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens);
- s->conflicts = repo_fix_conflicts(repo, s->conflicts);
+ repo_rewrite_suse_deps(s, pd->freshens);
pd->freshens = 0;
pd->kind = 0;
pd->solvable = 0;
diff --git a/ext/repo_susetags.c b/ext/repo_susetags.c
index a96ba97..be73a7f 100644
--- a/ext/repo_susetags.c
+++ b/ext/repo_susetags.c
@@ -388,12 +388,8 @@ finish_solvable(struct parsedata *pd, Solvable *s, Offset freshens)
/* A self provide, except for source packages. This is harmless
to do twice (in case we see the same package twice). */
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
- s->provides = repo_addid_dep(pd->repo, s->provides,
- pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- /* XXX This uses repo_addid_dep internally, so should also be
- harmless to do twice. */
- s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, freshens);
- s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts);
+ s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+ repo_rewrite_suse_deps(s, freshens);
if (pd->ndirs)
commit_diskusage(pd, handle);
}
diff --git a/ext/testcase.c b/ext/testcase.c
index 6e2b574..52c139f 100644
--- a/ext/testcase.c
+++ b/ext/testcase.c
@@ -1264,8 +1264,7 @@ finish_v2_solvable(Pool *pool, Repodata *data, Solvable *s, char *filelist, int
repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, did, p);
}
}
- s->supplements = repo_fix_supplements(s->repo, s->provides, s->supplements, 0);
- s->conflicts = repo_fix_conflicts(s->repo, s->conflicts);
+ repo_rewrite_suse_deps(s, 0);
}
/* stripped down version of susetags parser used for testcases */
@@ -1737,6 +1736,33 @@ testcase_reason2str(Id reason)
return "?";
}
+static struct rclass2str {
+ Id rclass;
+ const char *str;
+} rclass2str[] = {
+ { SOLVER_RULE_PKG, "pkg" },
+ { SOLVER_RULE_UPDATE, "update" },
+ { SOLVER_RULE_FEATURE, "feature" },
+ { SOLVER_RULE_JOB, "job" },
+ { SOLVER_RULE_DISTUPGRADE, "distupgrade" },
+ { SOLVER_RULE_INFARCH, "infarch" },
+ { SOLVER_RULE_CHOICE, "choice" },
+ { SOLVER_RULE_LEARNT, "learnt" },
+ { SOLVER_RULE_BEST, "best" },
+ { SOLVER_RULE_YUMOBS, "yumobs" },
+ { 0, 0 }
+};
+
+static const char *
+testcase_rclass2str(Id rclass)
+{
+ int i;
+ for (i = 0; rclass2str[i].str; i++)
+ if (rclass == rclass2str[i].rclass)
+ return rclass2str[i].str;
+ return "unknown";
+}
+
static int
dump_genid(Pool *pool, Strqueue *sq, Id id, int cnt)
{
@@ -1981,44 +2007,8 @@ testcase_solverresult(Solver *solv, int resultflags)
queue_init(&q);
for (rid = 1; (rclass = solver_ruleclass(solv, rid)) != SOLVER_RULE_UNKNOWN; rid++)
{
- char *prefix;
- switch (rclass)
- {
- case SOLVER_RULE_PKG:
- prefix = "pkg ";
- break;
- case SOLVER_RULE_UPDATE:
- prefix = "update ";
- break;
- case SOLVER_RULE_FEATURE:
- prefix = "feature ";
- break;
- case SOLVER_RULE_JOB:
- prefix = "job ";
- break;
- case SOLVER_RULE_DISTUPGRADE:
- prefix = "distupgrade ";
- break;
- case SOLVER_RULE_INFARCH:
- prefix = "infarch ";
- break;
- case SOLVER_RULE_CHOICE:
- prefix = "choice ";
- break;
- case SOLVER_RULE_LEARNT:
- prefix = "learnt ";
- break;
- case SOLVER_RULE_BEST:
- prefix = "best ";
- break;
- case SOLVER_RULE_YUMOBS:
- prefix = "yumobs ";
- break;
- default:
- prefix = "unknown ";
- break;
- }
- prefix = solv_dupjoin("rule ", prefix, testcase_ruleid(solv, rid));
+ char *prefix = solv_dupjoin("rule ", testcase_rclass2str(rclass), " ");
+ prefix = solv_dupappend(prefix, testcase_ruleid(solv, rid), 0);
solver_ruleliterals(solv, rid, &q);
if (rclass == SOLVER_RULE_FEATURE && q.count == 1 && q.elements[0] == -SYSTEMSOLVABLE)
continue;
@@ -2099,8 +2089,8 @@ testcase_solverresult(Solver *solv, int resultflags)
}
-int
-testcase_write(Solver *solv, const char *dir, int resultflags, const char *testcasename, const char *resultname)
+static int
+testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const char *testcasename, const char *resultname)
{
Pool *pool = solv->pool;
Repo *repo;
@@ -2132,6 +2122,9 @@ testcase_write(Solver *solv, const char *dir, int resultflags, const char *testc
else
sprintf(priobuf, "%d", repo->priority);
out = pool_tmpjoin(pool, name, ".repo", ".gz");
+ for (i = 0; out[i]; i++)
+ if (out[i] == '/')
+ out[i] = '_';
cmd = pool_tmpjoin(pool, "repo ", name, " ");
cmd = pool_tmpappend(pool, cmd, priobuf, " ");
cmd = pool_tmpappend(pool, cmd, "testtags ", out);
@@ -2320,6 +2313,52 @@ testcase_write(Solver *solv, const char *dir, int resultflags, const char *testc
return 1;
}
+int
+testcase_write(Solver *solv, const char *dir, int resultflags, const char *testcasename, const char *resultname)
+{
+ Pool *pool = solv->pool;
+ int i, r, repoid;
+ int mangle = 1;
+ const char **orignames;
+
+ /* mangle repo names so that there are no conflicts */
+ orignames = solv_calloc(pool->nrepos, sizeof(char *));
+ for (repoid = 1; repoid < pool->nrepos; repoid++)
+ {
+ Repo *repo = pool_id2repo(pool, repoid);
+ char *buf = solv_malloc((repo->name ? strlen(repo->name) : 0) + 40);
+ char *mp;
+ orignames[i] = repo->name;
+ if (!repo->name || !repo->name[0])
+ sprintf(buf, "#%d", repoid);
+ else
+ strcpy(buf, repo->name);
+ for (i = 0; buf[i]; i++)
+ if (buf[i] == ' ' || buf[i] == '\t' || buf[i] == '/')
+ buf[i] = '_';
+ mp = buf + strlen(buf);
+ for (;;)
+ {
+ for (i = 1; i < repoid; i++)
+ if (!strcmp(buf, pool_id2repo(pool, i)->name))
+ break;
+ if (i == repoid)
+ break;
+ sprintf(mp, "_%d", mangle++);
+ }
+ repo->name = buf;
+ }
+ r = testcase_write_mangled(solv, dir, resultflags, testcasename, resultname);
+ for (repoid = 1; repoid < pool->nrepos; repoid++)
+ {
+ Repo *repo = pool_id2repo(pool, repoid);
+ solv_free((void *)repo->name);
+ repo->name = orignames[i];
+ }
+ solv_free(orignames);
+ return r;
+}
+
static char *
read_inline_file(FILE *fp, char **bufp, char **bufpp, int *buflp)
{
diff --git a/package/libsolv.changes b/package/libsolv.changes
index 02d4b31..7d12812 100644
--- a/package/libsolv.changes
+++ b/package/libsolv.changes
@@ -1,7 +1,22 @@
-------------------------------------------------------------------
+Fri Jul 22 11:37:23 CEST 2016 - mls@suse.de
+
+- also scan /usr/share/metainfo for appdata files [bnc#989830]
+- support tri-state product-endoflife [fate#320699]
+- take lockstep into account when calculating unneeded packages
+- ignore appplication extensions for now in appdata parser
+ [bnc#984332]
+- add enabled features to solvversion.h
+- take disfavors into account when auto-minimizing for recommended
+ packages
+- change cleandeps code so that it keeps all providers
+- make sure that all repos have different names in a testcase
+- bump version to 0.6.23
+
+-------------------------------------------------------------------
Tue Jun 7 11:24:47 CEST 2016 - mls@suse.de
-- fix bug in bug in ignoreinst logic [bnc#983141]
+- fix bug in ignoreinst logic [bnc#983141]
-------------------------------------------------------------------
Wed May 18 15:09:56 CEST 2016 - mls@suse.de
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;
}
diff --git a/tools/common_write.c b/tools/common_write.c
index 6de8a69..1336b3f 100644
--- a/tools/common_write.c
+++ b/tools/common_write.c
@@ -16,8 +16,12 @@
#include "repo.h"
#include "repo_write.h"
#include "common_write.h"
+#include "solvversion.h"
-#define LIBSOLV_TOOLVERSION "1.0"
+/* toolversion history
+ * 1.0: initial tool version
+ * 1.1: changed PRODUCT_ENDOFLIFE parsing
+*/
static Id verticals[] = {
SOLVABLE_AUTHORS,
diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c
index 3b1d41b..99c4880 100644
--- a/tools/rpmdb2solv.c
+++ b/tools/rpmdb2solv.c
@@ -207,7 +207,10 @@ main(int argc, char **argv)
#ifdef ENABLE_APPDATA
if (add_appdata)
- repo_add_appdata_dir(repo, "/usr/share/appdata", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST);
+ {
+ repo_add_appdata_dir(repo, "/usr/share/metainfo", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST);
+ repo_add_appdata_dir(repo, "/usr/share/appdata", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST);
+ }
#endif
repodata_internalize(data);