diff options
-rw-r--r-- | CMakeLists.txt | 25 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | VERSION.cmake | 2 | ||||
-rw-r--r-- | examples/solv/repoinfo_system_rpm.c | 9 | ||||
-rw-r--r-- | ext/repo_appdata.c | 19 | ||||
-rw-r--r-- | ext/repo_autopattern.c | 7 | ||||
-rw-r--r-- | ext/repo_content.c | 4 | ||||
-rw-r--r-- | ext/repo_helix.c | 3 | ||||
-rw-r--r-- | ext/repo_products.c | 8 | ||||
-rw-r--r-- | ext/repo_rpmdb.c | 3 | ||||
-rw-r--r-- | ext/repo_rpmmd.c | 3 | ||||
-rw-r--r-- | ext/repo_susetags.c | 8 | ||||
-rw-r--r-- | ext/testcase.c | 123 | ||||
-rw-r--r-- | package/libsolv.changes | 17 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/libsolv.ver | 1 | ||||
-rw-r--r-- | src/pool.c | 218 | ||||
-rw-r--r-- | src/pool.h | 36 | ||||
-rw-r--r-- | src/repo.c | 224 | ||||
-rw-r--r-- | src/repo.h | 7 | ||||
-rw-r--r-- | src/rules.c | 43 | ||||
-rw-r--r-- | src/solvable.c | 297 | ||||
-rw-r--r-- | src/solvable.h | 7 | ||||
-rw-r--r-- | src/solver.c | 23 | ||||
-rw-r--r-- | src/solver.h | 4 | ||||
-rw-r--r-- | src/solverdebug.c | 33 | ||||
-rw-r--r-- | src/solverdebug.h | 4 | ||||
-rw-r--r-- | src/solvversion.h.in | 24 | ||||
-rw-r--r-- | src/suse.c | 748 | ||||
-rw-r--r-- | src/transaction.c | 8 | ||||
-rw-r--r-- | tools/common_write.c | 6 | ||||
-rw-r--r-- | tools/rpmdb2solv.c | 5 |
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) @@ -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; @@ -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) { @@ -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 @@ -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; @@ -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); |