Imported Upstream version 0.6.23 22/94122/1 upstream/0.6.23
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 27 Oct 2016 05:58:05 +0000 (14:58 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 27 Oct 2016 05:58:05 +0000 (14:58 +0900)
Change-Id: Idc1e282dc113b7350d8e123283f1a36097b76857
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
32 files changed:
CMakeLists.txt
NEWS
VERSION.cmake
examples/solv/repoinfo_system_rpm.c
ext/repo_appdata.c
ext/repo_autopattern.c
ext/repo_content.c
ext/repo_helix.c
ext/repo_products.c
ext/repo_rpmdb.c
ext/repo_rpmmd.c
ext/repo_susetags.c
ext/testcase.c
package/libsolv.changes
src/CMakeLists.txt
src/libsolv.ver
src/pool.c
src/pool.h
src/repo.c
src/repo.h
src/rules.c
src/solvable.c
src/solvable.h
src/solver.c
src/solver.h
src/solverdebug.c
src/solverdebug.h
src/solvversion.h.in
src/suse.c [new file with mode: 0644]
src/transaction.c
tools/common_write.c
tools/rpmdb2solv.c

index f2a6e16..0153a70 100644 (file)
@@ -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 (file)
--- 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
index 2da1637..10ade66 100644 (file)
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "0")
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "22")
+SET(LIBSOLV_PATCH "23")
 
index b385d72..4926ecd 100644 (file)
@@ -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))
index cbc42e4..2b9844e 100644 (file)
@@ -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:
index 4c767e1..f6e1004 100644 (file)
@@ -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)
            {
index 0cd1293..b12c4cd 100644 (file)
@@ -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)
index f495be7..6358f72 100644 (file)
@@ -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 */
index cb69c49..326f8fd 100644 (file)
@@ -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;
index 9445023..95756c0 100644 (file)
@@ -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);
index 729f4f7..8854bca 100644 (file)
@@ -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;
index a96ba97..be73a7f 100644 (file)
@@ -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);
 }
index 6e2b574..52c139f 100644 (file)
@@ -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)
 {
index 02d4b31..7d12812 100644 (file)
@@ -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
index 241890d..0109755 100644 (file)
@@ -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
index a5efd6a..dd1596e 100644 (file)
@@ -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;
index c51c62e..72e22f8 100644 (file)
@@ -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)
 {
index 069594b..86d49aa 100644 (file)
@@ -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
index 15e7e80..9e59fe2 100644 (file)
@@ -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;
index 952dbeb..a63999a 100644 (file)
@@ -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
index 32855e4..aa90b5f 100644 (file)
@@ -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)
index cccc89d..2570e4f 100644 (file)
@@ -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
index 85d20c4..090b758 100644 (file)
@@ -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
index 4f849ec..5fca20d 100644 (file)
@@ -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
index 3495fd8..758f1eb 100644 (file)
@@ -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
index 39f5d78..bb74ef6 100644 (file)
@@ -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);
-}
-
index 32e427e..b6923b4 100644 (file)
@@ -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
index 268219c..75dc63f 100644 (file)
@@ -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 (file)
index 0000000..6106f3f
--- /dev/null
@@ -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);
+}
+
+
index ffe1ec2..9a32966 100644 (file)
@@ -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;
 }
 
index 6de8a69..1336b3f 100644 (file)
 #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,
index 3b1d41b..99c4880 100644 (file)
@@ -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);