Imported Upstream version 0.6.5 04/94104/1 upstream/0.6.5
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 27 Oct 2016 05:52:55 +0000 (14:52 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 27 Oct 2016 05:53:17 +0000 (14:53 +0900)
Change-Id: If69a2170a61800e3f778ec1f78364531c9642950
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
29 files changed:
VERSION.cmake
bindings/solv.i
examples/solv.c
ext/repo_arch.c
ext/testcase.c
package/libsolv.changes
src/policy.c
src/policy.h
src/pool.c
src/pool.h
src/poolid.c
src/poolvendor.c
src/problems.c
src/qsort_r.c
src/repo.c
src/repo.h
src/repo_solv.c
src/repo_write.c
src/repodata.c
src/rules.c
src/rules.h
src/selection.c
src/solver.c
src/solver.h
src/solverdebug.c
src/strpool.c
src/transaction.c
test/testcases/yumobs/split.t [new file with mode: 0644]
tools/testsolv.c

index ac9ef35..324dfa7 100644 (file)
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "0")
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "4")
+SET(LIBSOLV_PATCH "5")
 
index 2d8f775..e8acd35 100644 (file)
@@ -1397,6 +1397,15 @@ typedef struct {
     return pool_queuetowhatprovides($self, &q);
   }
 
+  %typemap(out) Queue whatmatchesdep Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
+  %newobject whatmatchesdep;
+  Queue whatmatchesdep(Id keyname, DepId dep, Id marker = -1) {
+    Queue q;
+    queue_init(&q);
+    pool_whatmatchesdep($self, keyname, dep, &q, marker);
+    return q;
+  }
+
 #ifdef SWIGRUBY
   %rename("isknownarch?") isknownarch;
 #endif
@@ -2769,6 +2778,7 @@ rb_eval_string(
   static const int SOLVER_FLAG_KEEP_ORPHANS = SOLVER_FLAG_KEEP_ORPHANS;
   static const int SOLVER_FLAG_BREAK_ORPHANS = SOLVER_FLAG_BREAK_ORPHANS;
   static const int SOLVER_FLAG_FOCUS_INSTALLED = SOLVER_FLAG_FOCUS_INSTALLED;
+  static const int SOLVER_FLAG_YUM_OBSOLETES = SOLVER_FLAG_YUM_OBSOLETES;
 
   static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED;
   static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE;
index d9b03a1..7ae67e3 100644 (file)
@@ -2464,6 +2464,7 @@ showdiskusagechanges(Transaction *trans)
   int i;
 
   /* XXX: use mountpoints here */
+  memset(duc, 0, sizeof(duc));
   duc[0].path = "/";
   duc[1].path = "/usr/share/man";
   duc[2].path = "/sbin";
index 394e8b5..a0c45ce 100644 (file)
@@ -294,13 +294,13 @@ adddep(Repo *repo, Offset olddeps, char *line)
   char *p;
   Id id;
 
-  while (*line == ' ' && *line == '\t')
+  while (*line == ' ' || *line == '\t')
     line++;
   p = line;
   while (*p && *p != ' ' && *p != '\t' && *p != '<' && *p != '=' && *p != '>')
     p++;
   id = pool_strn2id(pool, line, p - line, 1);
-  while (*p == ' ' && *p == '\t')
+  while (*p == ' ' || *p == '\t')
     p++;
   if (*p == '<' || *p == '=' || *p == '>')
     {
@@ -316,7 +316,7 @@ adddep(Repo *repo, Offset olddeps, char *line)
          else
            break;
        }
-      while (*p == ' ' && *p == '\t')
+      while (*p == ' ' || *p == '\t')
         p++;
       line = p;
       while (*p && *p != ' ' && *p != '\t')
index 3da7aff..fa9c807 100644 (file)
@@ -105,6 +105,7 @@ static struct solverflags2str {
   { SOLVER_FLAG_KEEP_ORPHANS,               "keeporphans", 0 },
   { SOLVER_FLAG_BREAK_ORPHANS,              "breakorphans", 0 },
   { SOLVER_FLAG_FOCUS_INSTALLED,            "focusinstalled", 0 },
+  { SOLVER_FLAG_YUM_OBSOLETES,              "yumobsoletes", 0 },
   { 0, 0, 0 }
 };
 
@@ -1728,6 +1729,18 @@ testcase_write(Solver *solv, char *dir, int resultflags, const char *testcasenam
        }
     }
 
+  /* dump disabled packages (must come before the namespace/job lines) */
+  if (pool->considered)
+    {
+      Id p;
+      FOR_POOL_SOLVABLES(p)
+       if (!MAPTST(pool->considered, p))
+         {
+           cmd = pool_tmpjoin(pool, "disable pkg ", testcase_solvid2str(pool, p), 0);
+           strqueue_push(&sq, cmd);
+         }
+    }
+
   s = testcase_getsolverflags(solv);
   if (*s)
     {
@@ -2116,7 +2129,7 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp,
        {
          char *sp;
          Id how, what;
-         if (!prepared)
+         if (prepared <= 0)
            {
              pool_addfileprovides(pool);
              pool_createwhatprovides(pool);
@@ -2162,7 +2175,7 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp,
              for (i = 2; i < npieces; i++)
                queue_push(&q, testcase_str2solvid(pool, pieces[i]));
              /* now do the callback */
-             if (!prepared)
+             if (prepared <= 0)
                {
                  pool_addfileprovides(pool);
                  pool_createwhatprovides(pool);
@@ -2227,6 +2240,29 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp,
        {
          break;
        }
+      else if (!strcmp(pieces[0], "disable") && npieces == 3)
+       {
+         Id p;
+         if (strcmp(pieces[1], "pkg"))
+           {
+             pool_debug(pool, SOLV_ERROR, "testcase_read: bad disable type '%s'\n", pieces[1]);
+             continue;
+           }
+         if (!prepared)
+           pool_createwhatprovides(pool);
+         prepared = -1;
+         if (!pool->considered)
+           {
+             pool->considered = solv_calloc(1, sizeof(Map));
+             map_init(pool->considered, pool->nsolvables);
+             map_setall(pool->considered);
+           }
+         p = testcase_str2solvid(pool, pieces[2]);
+         if (p)
+           MAPCLR(pool->considered, p);
+         else
+           pool_debug(pool, SOLV_ERROR, "disable: unknown package '%s'\n", pieces[2]);
+       }
       else
        {
          pool_debug(pool, SOLV_ERROR, "testcase_read: cannot parse command '%s'\n", pieces[0]);
index 7368f38..28bd976 100644 (file)
@@ -1,4 +1,15 @@
 -------------------------------------------------------------------
+Thu Sep 11 17:33:04 CEST 2014 - mls@suse.de
+
+- support DUCHANGES_ONLYADD flag in diskusage calculation
+  [bnc#783100]
+- add whatmatchesdep to bindings
+- support pool->considered in testcases
+- always call selection_filelist if SELECTION_FILELIST is set
+- support yum style obsolete handling for package splits
+- bump version to 0.6.5
+
+-------------------------------------------------------------------
 Tue Jul  8 14:13:40 CEST 2014 - mls@suse.de
 
 - expand solver_identical fix to applications [bnc#885830]
index 5b72517..9e5a934 100644 (file)
@@ -776,7 +776,7 @@ move_installed_to_front(Pool *pool, Queue *plist)
  * sort list of packages (given through plist) by name and evr
  * return result through plist
  */
-static void
+void
 prune_to_best_version(Pool *pool, Queue *plist)
 {
   int i, j;
index d034f0d..a4dd4c4 100644 (file)
@@ -36,6 +36,9 @@ extern void policy_update_recommendsmap(Solver *solv);
 
 extern void policy_create_obsolete_index(Solver *solv);
 
+/* internal, do not use */
+extern void prune_to_best_version(Pool *pool, Queue *plist);
+
 
 #ifdef __cplusplus
 }
index 946f6da..8dff38a 100644 (file)
@@ -118,7 +118,7 @@ pool_free(Pool *pool)
     solv_free(pool->tmpspace.buf[i]);
   for (i = 0; i < pool->nlanguages; i++)
     free((char *)pool->languages[i]);
-  solv_free(pool->languages);
+  solv_free((void *)pool->languages);
   solv_free(pool->languagecache);
   solv_free(pool->errstr);
   solv_free(pool->rootdir);
@@ -1674,7 +1674,7 @@ pool_set_languages(Pool *pool, const char **languages, int nlanguages)
   pool->languagecacheother = 0;
   for (i = 0; i < pool->nlanguages; i++)
     free((char *)pool->languages[i]);
-  pool->languages = solv_free(pool->languages);
+  pool->languages = solv_free((void *)pool->languages);
   pool->nlanguages = nlanguages;
   if (!nlanguages)
     return;
@@ -1922,7 +1922,7 @@ solver_fill_DU_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyVa
       cbd->mps[mp].kbytes += value->num;
       cbd->mps[mp].files += value->num2;
     }
-  else
+  else if (!(cbd->mps[mp].flags & DUCHANGES_ONLYADD))
     {
       cbd->mps[mp].kbytes -= value->num;
       cbd->mps[mp].files -= value->num2;
@@ -2030,13 +2030,17 @@ pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
   struct mptree *mptree;
   struct ducbdata cbd;
   Solvable *s;
-  int sp;
+  int i, sp;
   Map ignoredu;
   Repo *oldinstalled = pool->installed;
+  int haveonlyadd = 0;
 
   map_init(&ignoredu, 0);
   mptree = create_mptree(mps, nmps);
 
+  for (i = 0; i < nmps; i++)
+    if ((mps[i].flags & DUCHANGES_ONLYADD) != 0)
+      haveonlyadd = 1;
   cbd.mps = mps;
   cbd.dirmap = 0;
   cbd.nmap = 0;
@@ -2054,21 +2058,55 @@ pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
       if (!cbd.hasdu && oldinstalled)
        {
          Id op, opp;
+         int didonlyadd = 0;
          /* no du data available, ignore data of all installed solvables we obsolete */
          if (!ignoredu.size)
            map_grow(&ignoredu, oldinstalled->end - oldinstalled->start);
+         FOR_PROVIDES(op, opp, s->name)
+           {
+             Solvable *s2 = pool->solvables + op;
+             if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
+               continue;
+             if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
+               continue;
+             if (op >= oldinstalled->start && op < oldinstalled->end)
+               {
+                 MAPSET(&ignoredu, op - oldinstalled->start);
+                 if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
+                   {
+                     repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+                     cbd.addsub = -1;
+                     repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+                     cbd.addsub = 1;
+                     didonlyadd = 1;
+                   }
+               }
+           }
          if (s->obsoletes)
            {
              Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
              while ((obs = *obsp++) != 0)
                FOR_PROVIDES(op, opp, obs)
-                 if (op >= oldinstalled->start && op < oldinstalled->end)
-                   MAPSET(&ignoredu, op - oldinstalled->start);
+                 {
+                   Solvable *s2 = pool->solvables + op;
+                   if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs))
+                     continue;
+                   if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+                     continue;
+                   if (op >= oldinstalled->start && op < oldinstalled->end)
+                     {
+                       MAPSET(&ignoredu, op - oldinstalled->start);
+                       if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
+                         {
+                           repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+                           cbd.addsub = -1;
+                           repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+                           cbd.addsub = 1;
+                           didonlyadd = 1;
+                         }
+                     }
+                 }
            }
-         FOR_PROVIDES(op, opp, s->name)
-           if (pool->solvables[op].name == s->name)
-             if (op >= oldinstalled->start && op < oldinstalled->end)
-               MAPSET(&ignoredu, op - oldinstalled->start);
        }
     }
   cbd.addsub = -1;
index d29f615..9761ce1 100644 (file)
@@ -346,10 +346,13 @@ void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*c
 void pool_clear_pos(Pool *pool);
 
 
+#define DUCHANGES_ONLYADD      1
+
 typedef struct _DUChanges {
   const char *path;
   int kbytes;
   int files;
+  int flags;
 } DUChanges;
 
 void pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps);
index 5fe502b..7bcc1f6 100644 (file)
@@ -65,7 +65,7 @@ pool_rel2id(Pool *pool, Id name, Id evr, int flags, int create)
   ran = pool->rels;
 
   /* extend hashtable if needed */
-  if (pool->nrels * 2 > hashmask)
+  if ((Hashval)pool->nrels * 2 > hashmask)
     {
       solv_free(pool->relhashtbl);
       pool->relhashmask = hashmask = mkmask(pool->nrels + REL_BLOCK);
index a52a94b..ec25f9d 100644 (file)
@@ -89,7 +89,7 @@ pool_setvendorclasses(Pool *pool, const char **vendorclasses)
     {
       for (v = pool->vendorclasses; v[0] || v[1]; v++)
        solv_free((void *)*v);
-      pool->vendorclasses = solv_free(pool->vendorclasses);
+      pool->vendorclasses = solv_free((void *)pool->vendorclasses);
     }
   if (!vendorclasses || !vendorclasses[0])
     return;
@@ -120,7 +120,7 @@ pool_addvendorclass(Pool *pool, const char **vendorclass)
       if (i)
         i++;
     }
-  pool->vendorclasses = solv_realloc2(pool->vendorclasses, i + j + 2, sizeof(const char *));
+  pool->vendorclasses = solv_realloc2((void *)pool->vendorclasses, i + j + 2, sizeof(const char *));
   for (j = 0; vendorclass[j]; j++)
     pool->vendorclasses[i++] = solv_strdup(vendorclass[j]);
   pool->vendorclasses[i++] = 0;
index bb00aa6..b2063a5 100644 (file)
@@ -918,7 +918,7 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,
          MAPSET(rseen, rid - solv->learntrules);
          findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, rseen);
        }
-      else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end) || (rid >= solv->bestrules && rid < solv->bestrules_end))
+      else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end) || (rid >= solv->bestrules && rid < solv->bestrules_end) || (rid >= solv->yumobsrules && rid <= solv->yumobsrules_end))
        {
          if (!*jobrp)
            *jobrp = rid;
@@ -1105,6 +1105,10 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ
       return pool_tmpjoin(pool, pool_dep2str(pool, dep), " is provided by the system", 0);
     case SOLVER_RULE_RPM:
       return "some dependency problem";
+    case SOLVER_RULE_BEST:
+      if (source > 0)
+        return pool_tmpjoin(pool, "cannot install the best update candidate for package ", pool_solvid2str(pool, source), 0);
+     return "cannot install the best candidate for the job";
     case SOLVER_RULE_RPM_NOT_INSTALLABLE:
       return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is not installable");
     case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
@@ -1135,6 +1139,10 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ
     case SOLVER_RULE_RPM_SELF_CONFLICT:
       s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " conflicts with ");
       return pool_tmpappend(pool, s, pool_dep2str(pool, dep), " provided by itself");
+    case SOLVER_RULE_YUMOBS:
+      s = pool_tmpjoin(pool, "both package ", pool_solvid2str(pool, source), " and ");
+      s = pool_tmpjoin(pool, s, pool_solvid2str(pool, target), " obsolete ");
+      return pool_tmpappend(pool, s, pool_dep2str(pool, dep), 0);
     default:
       return "bad problem rule type";
     }
index f264ed0..d49049a 100644 (file)
@@ -47,7 +47,9 @@ typedef int            cmp_t(const void *, const void *, void *);
 static inline char     *med3(char *, char *, char *, cmp_t *, void *);
 static inline void      swapfunc(char *, char *, int, int);
 
+#ifndef min
 #define min(a, b)      (a) < (b) ? a : b
+#endif
 
 /*
  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
index 511fd92..15e7e80 100644 (file)
@@ -388,10 +388,10 @@ repo_addid_dep_hash(Repo *repo, Offset olddeps, Id id, Id marker, int size)
     }
 
   /* maintain hash and lastmarkerpos */
-  if (repo->lastidhash_idarraysize != repo->idarraysize || size * 2 > repo->lastidhash_mask || repo->lastmarker != marker)
+  if (repo->lastidhash_idarraysize != repo->idarraysize || (Hashval)size * 2 > repo->lastidhash_mask || repo->lastmarker != marker)
     {
       repo->lastmarkerpos = 0;
-      if (size * 2 > repo->lastidhash_mask)
+      if (size * 2 > (Hashval)repo->lastidhash_mask)
        {
          repo->lastidhash_mask = mkmask(size < REPO_ADDID_DEP_HASHMIN ? REPO_ADDID_DEP_HASHMIN : size);
          repo->lastidhash = solv_realloc2(repo->lastidhash, repo->lastidhash_mask + 1, sizeof(Id));
index 106f2a5..952dbeb 100644 (file)
@@ -41,7 +41,7 @@ typedef struct _Repo {
   Id *idarraydata;             /* array of metadata Ids, solvable dependencies are offsets into this array */
   int idarraysize;
 
-  unsigned nrepodata;          /* number of our stores..  */
+  int nrepodata;               /* number of our stores..  */
 
   Id *rpmdbid;                 /* solvable side data: rpm database id */
 
index 0e8b854..86c851c 100644 (file)
@@ -113,7 +113,7 @@ read_id(Repodata *data, Id max)
       if (!(c & 128))
        {
          x = (x << 7) | c;
-         if (max && x >= max)
+         if (max && x >= (unsigned int)max)
            {
              data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_id: id too large (%u/%u)", x, max);
              return 0;
@@ -149,7 +149,7 @@ read_idarray(Repodata *data, Id max, Id *map, Id *store, Id *end)
          continue;
        }
       x = (x << 6) | (c & 63);
-      if (max && x >= max)
+      if (max && x >= (unsigned int)max)
        {
          data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_idarray: id too large (%u/%u)", x, max);
          return 0;
@@ -217,7 +217,7 @@ data_read_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata *da
          continue;
        }
       x = (x << 6) | (c & 63);
-      if (max && x >= max)
+      if (max && x >= (unsigned int)max)
        {
          data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "data_read_idarray: id too large (%u/%u)", x, max);
          data->error = SOLV_ERROR_ID_RANGE;
@@ -261,7 +261,7 @@ data_read_rel_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata
        }
       x = old + (x - 1);
       old = x;
-      if (max && x >= max)
+      if (max && x >= (unsigned int)max)
        {
          data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "data_read_rel_idarray: id too large (%u/%u)", x, max);
          break;
@@ -360,7 +360,7 @@ incore_add_ideof(Repodata *data, Id sx, int eof)
 static void
 incore_add_blob(Repodata *data, unsigned char *buf, int len)
 {
-  if (data->incoredatafree < len)
+  if (data->incoredatafree < (unsigned int)len)
     {
       data->incoredata = solv_realloc(data->incoredata, data->incoredatalen + INCORE_ADD_CHUNK + len);
       data->incoredatafree = INCORE_ADD_CHUNK + len;
@@ -444,8 +444,8 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
 {
   Pool *pool = repo->pool;
   int i, l;
-  unsigned int numid, numrel, numdir, numsolv;
-  unsigned int numkeys, numschemata;
+  int numid, numrel, numdir, numsolv;
+  int numkeys, numschemata;
 
   Offset sizeid;
   Offset *str;                        /* map Id -> Offset into string space */
@@ -519,16 +519,26 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
         return pool_error(pool, SOLV_ERROR_UNSUPPORTED, "unsupported SOLV version");
     }
 
-  numid = read_u32(&data);
-  numrel = read_u32(&data);
-  numdir = read_u32(&data);
-  numsolv = read_u32(&data);
-  numkeys = read_u32(&data);
-  numschemata = read_u32(&data);
+  numid = (int)read_u32(&data);
+  numrel = (int)read_u32(&data);
+  numdir = (int)read_u32(&data);
+  numsolv = (int)read_u32(&data);
+  numkeys = (int)read_u32(&data);
+  numschemata = (int)read_u32(&data);
   solvflags = read_u32(&data);
 
-  if (numdir && numdir < 2)
+  if (numid < 0 || numid >= 0x20000000)
+    return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of ids");
+  if (numrel < 0 || numrel >= 0x20000000)
+    return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of rels");
+  if (numdir && (numdir < 2 || numdir >= 0x20000000))
     return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of dirs");
+  if (numsolv < 0 || numsolv >= 0x20000000)
+    return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of solvables");
+  if (numkeys < 0 || numkeys >= 0x20000000)
+    return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of keys");
+  if (numschemata < 0 || numschemata >= 0x20000000)
+    return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of schematas");
 
   if (numrel && (flags & REPO_LOCALPOOL) != 0)
     return pool_error(pool, SOLV_ERROR_CORRUPT, "relations are forbidden in a local pool");
index 11002b4..210636c 100644 (file)
@@ -1568,7 +1568,7 @@ for (i = 1; i < target.nkeys; i++)
 
   /* remove unused keys */
   keyused = solv_calloc(target.nkeys, sizeof(Id));
-  for (i = 1; i < target.schemadatalen; i++)
+  for (i = 1; i < (int)target.schemadatalen; i++)
     keyused[target.schemadata[i]] = 1;
   keyused[0] = 0;
   for (n = i = 1; i < target.nkeys; i++)
@@ -1592,7 +1592,7 @@ for (i = 1; i < target.nkeys; i++)
     queue_truncate(keyq, 2 * n - 2);
 
   /* update schema data to the new key ids */
-  for (i = 1; i < target.schemadatalen; i++)
+  for (i = 1; i < (int)target.schemadatalen; i++)
     target.schemadata[i] = keyused[target.schemadata[i]];
   /* update keymap to the new key ids */
   for (i = 0; i < cbdata.nkeymap; i++)
index d527a42..4d57790 100644 (file)
@@ -479,11 +479,11 @@ get_vertical_data(Repodata *data, Repokey *key, Id off, Id len)
   if (off >= data->lastverticaloffset)
     {
       off -= data->lastverticaloffset;
-      if (off + len > data->vincorelen)
+      if ((unsigned int)off + len > data->vincorelen)
        return 0;
       return data->vincore + off;
     }
-  if (off + len > key->size)
+  if ((unsigned int)off + len > key->size)
     return 0;
   /* we now have the offset, go into vertical */
   off += data->verticaloffset[key - data->keys];
@@ -2928,7 +2928,7 @@ compact_attrdata(Repodata *data, int entry, int nentry)
            case REPOKEY_TYPE_STR:
            case REPOKEY_TYPE_BINARY:
            case_CHKSUM_TYPES:
-             if (attrs[1] < attrdatastart)
+             if ((unsigned int)attrs[1] < attrdatastart)
                 attrdatastart = attrs[1];
              break;
            case REPOKEY_TYPE_DIRSTRARRAY:
@@ -2938,7 +2938,7 @@ compact_attrdata(Repodata *data, int entry, int nentry)
              /* FALLTHROUGH */
            case REPOKEY_TYPE_IDARRAY:
            case REPOKEY_TYPE_DIRNUMNUMARRAY:
-             if (attrs[1] < attriddatastart)
+             if ((unsigned int)attrs[1] < attriddatastart)
                attriddatastart = attrs[1];
              break;
            case REPOKEY_TYPE_FIXARRAY:
index 6b561cc..922b9d0 100644 (file)
@@ -434,8 +434,11 @@ makemultiversionconflict(Solver *solv, Id n, Id con)
       queue_push(&q, p);
     }
   if (q.count == 1)
-    return -n; /* no other package found, generate normal conflict */
-  return pool_queuetowhatprovides(pool, &q);
+    n = -n;    /* no other package found, generate normal conflict */
+  else
+    n = pool_queuetowhatprovides(pool, &q);
+  queue_free(&q);
+  return n;
 }
 
 static inline void
@@ -2649,8 +2652,26 @@ solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp)
     }
   if (rid >= solv->bestrules && rid < solv->bestrules_end)
     {
+      if (fromp && solv->bestrules_pkg[rid - solv->bestrules] > 0)
+       *fromp = solv->bestrules_pkg[rid - solv->bestrules];
       return SOLVER_RULE_BEST;
     }
+  if (rid >= solv->yumobsrules && rid < solv->yumobsrules_end)
+    {
+      if (fromp)
+       *fromp = -r->p;
+      if (top)
+       {
+         /* first solvable is enough, we just need it for the name */
+         if (!r->d || r->d == -1)
+           *top = r->w2;
+         else
+           *top = pool->whatprovidesdata[r->d < 0 ? -r->d : r->d];
+       }
+      if (depp)
+       *depp = solv->yumobsrules_info[rid - solv->yumobsrules];
+      return SOLVER_RULE_YUMOBS;
+    }
   if (rid >= solv->choicerules && rid < solv->choicerules_end)
     {
       return SOLVER_RULE_CHOICE;
@@ -2681,6 +2702,8 @@ solver_ruleclass(Solver *solv, Id rid)
     return SOLVER_RULE_INFARCH;
   if (rid >= solv->bestrules && rid < solv->bestrules_end)
     return SOLVER_RULE_BEST;
+  if (rid >= solv->yumobsrules && rid < solv->yumobsrules_end)
+    return SOLVER_RULE_YUMOBS;
   if (rid >= solv->choicerules && rid < solv->choicerules_end)
     return SOLVER_RULE_CHOICE;
   if (rid >= solv->learntrules)
@@ -3248,6 +3271,229 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
   queue_free(&r2pkg);
 }
 
+
+
+
+/* yumobs rule handling */
+
+static void
+find_obsolete_group(Solver *solv, Id obs, Queue *q)
+{
+  Pool *pool = solv->pool;
+  Queue qn;
+  Id p2, pp2, op, *opp, opp2;
+  int i, j, qnc, ncnt;
+
+  queue_empty(q);
+  FOR_PROVIDES(p2, pp2, obs)
+    {
+      Solvable *s2 = pool->solvables + p2;
+      if (s2->repo != pool->installed)
+       continue;
+      if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
+       continue;
+      /* we obsolete installed package s2 with obs. now find all other packages that have the same dep  */
+      for (opp = solv->obsoletes_data + solv->obsoletes[p2 - solv->installed->start]; (op = *opp++) != 0;)
+       {
+         Solvable *os = pool->solvables + op;
+         Id obs2, *obsp2;
+         if (!os->obsoletes)
+           continue;
+         if (pool->obsoleteusescolors && !pool_colormatch(pool, s2, os))
+           continue;
+         obsp2 = os->repo->idarraydata + os->obsoletes; 
+         while ((obs2 = *obsp2++) != 0)
+           if (obs2 == obs)
+             break;
+         if (obs2)
+           queue_pushunique(q, op);
+       }
+      /* also search packages with the same name */
+      FOR_PROVIDES(op, opp2, s2->name)
+       {
+         Solvable *os = pool->solvables + op;
+         Id obs2, *obsp2;
+         if (os->name != s2->name)
+           continue;
+         if (!os->obsoletes)
+           continue;
+         if (pool->obsoleteusescolors && !pool_colormatch(pool, s2, os))
+           continue;
+         obsp2 = os->repo->idarraydata + os->obsoletes; 
+         while ((obs2 = *obsp2++) != 0)
+           if (obs2 == obs)
+             break;
+         if (obs2)
+           queue_pushunique(q, op);
+       }
+    }
+  /* find names so that we can build groups */
+  queue_init_clone(&qn, q);
+  prune_to_best_version(solv->pool, &qn);
+#if 0
+{
+  for (i = 0; i < qn.count; i++)
+    printf(" + %s\n", pool_solvid2str(pool, qn.elements[i]));
+}
+#endif
+  /* filter into name groups */
+  qnc = qn.count;
+  if (qnc == 1)
+    {
+      queue_free(&qn);
+      queue_empty(q);
+      return;
+    }
+  ncnt = 0;
+  for (i = 0; i < qnc; i++)
+    {
+      Id n = pool->solvables[qn.elements[i]].name;
+      int got = 0;
+      for (j = 0; j < q->count; j++)
+       {
+         Id p = q->elements[j];
+         if (pool->solvables[p].name == n)
+           {
+             queue_push(&qn, p);
+             got = 1;
+           }
+       }
+      if (got)
+       {
+         queue_push(&qn, 0);
+         ncnt++;
+       }
+    }
+  if (ncnt <= 1)
+    {
+      queue_empty(q);
+    }
+  else
+    {
+      queue_empty(q);
+      queue_insertn(q, 0, qn.count - qnc, qn.elements + qnc);
+    }
+  queue_free(&qn);
+}
+
+void
+solver_addyumobsrules(Solver *solv)
+{
+  Pool *pool = solv->pool;
+  Repo *installed = solv->installed;
+  Id p, op, *opp;
+  Solvable *s;
+  Queue qo, qq, yumobsinfoq;
+  int i, j, k;
+  unsigned int now;
+
+  solv->yumobsrules = solv->nrules;
+  if (!installed || !solv->obsoletes)
+    {
+      solv->yumobsrules_end = solv->nrules;
+      return;
+    }
+  now = solv_timems(0);
+  queue_init(&qo);
+  FOR_REPO_SOLVABLES(installed, p, s)
+    {
+      if (!solv->obsoletes[p - installed->start])
+       continue;
+#if 0
+printf("checking yumobs for %s\n", pool_solvable2str(pool, s));
+#endif
+      queue_empty(&qo);
+      for (opp = solv->obsoletes_data + solv->obsoletes[p - installed->start]; (op = *opp++) != 0;)
+       {
+         Solvable *os = pool->solvables + op;
+          Id obs, *obsp = os->repo->idarraydata + os->obsoletes;
+         Id p2, pp2;
+         while ((obs = *obsp++) != 0)
+           {
+             FOR_PROVIDES(p2, pp2, obs)
+               {
+                 Solvable *s2 = pool->solvables + p2;
+                 if (s2->repo != installed)
+                   continue;
+                 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
+                   continue;
+                 if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+                   continue;
+                 queue_pushunique(&qo, obs);
+                 break;
+               }
+           }
+       }
+    }
+  if (!qo.count)
+    {
+      queue_free(&qo);
+      return;
+    }
+  queue_init(&yumobsinfoq);
+  queue_init(&qq);
+  for (i = 0; i < qo.count; i++)
+    {
+      int group, groupk, groupstart;
+      queue_empty(&qq);
+#if 0
+printf("investigating %s\n", pool_dep2str(pool, qo.elements[i]));
+#endif
+      find_obsolete_group(solv, qo.elements[i], &qq);
+#if 0
+printf("result:\n");
+for (j = 0; j < qq.count; j++)
+  if (qq.elements[j] == 0)
+    printf("---\n");
+  else
+    printf("%s\n", pool_solvid2str(pool, qq.elements[j]));
+#endif
+  
+      if (!qq.count)
+       continue;
+      /* at least two goups, build rules */
+      group = 0;
+      for (j = 0; j < qq.count; j++)
+       {
+         p = qq.elements[j];
+         if (!p)
+           {
+             group++;
+             continue;
+           }
+         if (pool->solvables[p].repo == installed)
+           continue;
+         groupk = 0;
+         groupstart = 0;
+         for (k = 0; k < qq.count; k++)
+           {
+             Id pk = qq.elements[k];
+             if (pk)
+               continue;
+             if (group != groupk && k > groupstart)
+               {
+                 /* add the rule */
+                 Queue qhelper;
+                 memset(&qhelper, 0, sizeof(qhelper));
+                 qhelper.count = k - groupstart;
+                 qhelper.elements = qq.elements + groupstart;
+                 solver_addrule(solv, -p, pool_queuetowhatprovides(pool, &qhelper));
+                 queue_push(&yumobsinfoq, qo.elements[i]);
+               }
+             groupstart = k + 1;
+             groupk++;
+           }
+       }
+    }
+  if (yumobsinfoq.count)
+    solv->yumobsrules_info = solv_memdup2(yumobsinfoq.elements, yumobsinfoq.count, sizeof(Id));
+  queue_free(&yumobsinfoq);
+  queue_free(&qq);
+  queue_free(&qo);
+  solv->yumobsrules_end = solv->nrules;
+  POOL_DEBUG(SOLV_DEBUG_STATS, "yumobs rule creation took %d ms\n", solv_timems(now));
+}
+
 #undef CLEANDEPSDEBUG
 
 /*
index 06048e4..3be3ea1 100644 (file)
@@ -69,7 +69,8 @@ typedef enum {
   SOLVER_RULE_INFARCH = 0x600,
   SOLVER_RULE_CHOICE = 0x700,
   SOLVER_RULE_LEARNT = 0x800,
-  SOLVER_RULE_BEST = 0x900
+  SOLVER_RULE_BEST = 0x900,
+  SOLVER_RULE_YUMOBS = 0xa00
 } SolverRuleinfo;
 
 #define SOLVER_RULE_TYPEMASK    0xff00
@@ -127,6 +128,9 @@ extern void solver_disablechoicerules(struct _Solver *solv, Rule *r);
 /* best rules */
 extern void solver_addbestrules(struct _Solver *solv, int havebestinstalljobs);
 
+/* yumobs rules */
+extern void solver_addyumobsrules(struct _Solver *solv);
+
 /* policy rule disabling/reenabling */
 extern void solver_disablepolicyrules(struct _Solver *solv);
 extern void solver_reenablepolicyrules(struct _Solver *solv, int jobidx);
index f0e61ea..8856436 100644 (file)
@@ -551,6 +551,14 @@ selection_filelist(Pool *pool, Queue *selection, const char *name, int flags)
   Queue q;
   int type;
 
+  /* all files in the file list start with a '/' */
+  if (*name != '/')
+    {
+      if (!(flags & SELECTION_GLOB))
+       return 0;
+      if (*name != '*' && *name != '[' && *name != '?')
+       return 0;
+    }
   type = !(flags & SELECTION_GLOB) || strpbrk(name, "[*?") == 0 ? SEARCH_STRING : SEARCH_GLOB;
   if ((flags & SELECTION_NOCASE) != 0)
     type |= SEARCH_NOCASE;
@@ -842,7 +850,7 @@ selection_make(Pool *pool, Queue *selection, const char *name, int flags)
   int ret = 0;
 
   queue_empty(selection);
-  if (*name == '/' && (flags & SELECTION_FILELIST))
+  if ((flags & SELECTION_FILELIST) != 0)
     ret = selection_filelist(pool, selection, name, flags);
   if (!ret && (flags & SELECTION_REL) != 0 && strpbrk(name, "<=>") != 0)
     ret = selection_rel(pool, selection, name, flags);
index b0f1bce..48b3aaa 100644 (file)
@@ -1681,6 +1681,7 @@ solver_free(Solver *solv)
   solv_free(solv->specialupdaters);
   solv_free(solv->choicerules_ref);
   solv_free(solv->bestrules_pkg);
+  solv_free(solv->yumobsrules_info);
   solv_free(solv->instbuddy);
   solv_free(solv);
 }
@@ -1730,6 +1731,8 @@ solver_get_flag(Solver *solv, int flag)
     return solv->break_orphans;
   case SOLVER_FLAG_FOCUS_INSTALLED:
     return solv->focus_installed;
+  case SOLVER_FLAG_YUM_OBSOLETES:
+    return solv->do_yum_obsoletes;
   default:
     break;
   }
@@ -1802,6 +1805,9 @@ solver_set_flag(Solver *solv, int flag, int value)
   case SOLVER_FLAG_FOCUS_INSTALLED:
     solv->focus_installed = value;
     break;
+  case SOLVER_FLAG_YUM_OBSOLETES:
+    solv->do_yum_obsoletes = value;
+    break;
   default:
     break;
   }
@@ -3401,6 +3407,7 @@ solver_solve(Solver *solv, Queue *job)
   queuep_free(&solv->cleandeps_updatepkgs);
   queue_empty(&solv->ruleassertions);
   solv->bestrules_pkg = solv_free(solv->bestrules_pkg);
+  solv->yumobsrules_info = solv_free(solv->yumobsrules_info);
   solv->choicerules_ref = solv_free(solv->choicerules_ref);
   if (solv->noupdate.size)
     map_empty(&solv->noupdate);
@@ -3963,6 +3970,11 @@ solver_solve(Solver *solv, Queue *job)
   if (hasdupjob)
     solver_freedupmaps(solv);  /* no longer needed */
 
+  if (solv->do_yum_obsoletes)
+    solver_addyumobsrules(solv);
+  else
+    solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
+
   if (1)
     solver_addchoicerules(solv);
   else
index 3d63b6f..49ccec8 100644 (file)
@@ -70,6 +70,10 @@ struct _Solver {
   Id bestrules_end;
   Id *bestrules_pkg;
 
+  Id yumobsrules;                      /* rules from yum obsoletes handling */
+  Id yumobsrules_end;
+  Id *yumobsrules_info;                        /* the dependency for each rule */
+
   Id choicerules;                      /* choice rules (always weak) */
   Id choicerules_end;
   Id *choicerules_ref;
@@ -161,6 +165,7 @@ struct _Solver {
   int bestobeypolicy;                  /* true: stay in policy with the best rules */
   int noautotarget;                    /* true: do not assume targeted for up/dup jobs that contain no installed solvable */
   int focus_installed;                 /* true: resolve update rules first */
+  int do_yum_obsoletes;                        /* true: add special yumobs rules */
 
   Map dupmap;                          /* dup these packages*/
   int dupmap_all;                      /* dup all packages */
@@ -289,6 +294,7 @@ typedef struct _Solver Solver;
 #define SOLVER_FLAG_KEEP_ORPHANS               18
 #define SOLVER_FLAG_BREAK_ORPHANS              19
 #define SOLVER_FLAG_FOCUS_INSTALLED            20
+#define SOLVER_FLAG_YUM_OBSOLETES              21
 
 #define GET_USERINSTALLED_NAMES                        (1 << 0)        /* package names instead if ids */
 #define GET_USERINSTALLED_INVERTED             (1 << 1)        /* autoinstalled */
index afec8c5..3e84046 100644 (file)
@@ -126,6 +126,8 @@ solver_printruleclass(Solver *solv, int type, Rule *r)
     POOL_DEBUG(type, "UPDATE ");
   else if (p >= solv->featurerules && p < solv->featurerules_end)
     POOL_DEBUG(type, "FEATURE ");
+  else if (p >= solv->yumobsrules && p < solv->yumobsrules_end)
+    POOL_DEBUG(type, "YUMOBS ");
   solver_printrule(solv, type, r);
 }
 
index 3ad0a80..af43e01 100644 (file)
@@ -93,7 +93,7 @@ stringpool_strn2id(Stringpool *ss, const char *str, unsigned int len, int create
   hashtbl = ss->stringhashtbl;
 
   /* expand hashtable if needed */
-  if (ss->nstrings * 2 > hashmask)
+  if ((Hashval)ss->nstrings * 2 > hashmask)
     {
       solv_free(hashtbl);
 
index 7dac0a8..49e58e8 100644 (file)
@@ -666,7 +666,7 @@ create_transaction_info(Transaction *trans, Queue *decisionq)
                  s2 = pool->solvables + p2;
                  if (s2->repo != installed)
                    continue;
-                 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
+                 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs))
                    continue;
                  if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
                    continue;
diff --git a/test/testcases/yumobs/split.t b/test/testcases/yumobs/split.t
new file mode 100644 (file)
index 0000000..a3921ed
--- /dev/null
@@ -0,0 +1,24 @@
+repo system 0 testtags <inline>
+#>=Ver: 2.0
+#>=Pkg: c 27 1 x86_64
+repo available 0 testtags <inline>
+#>=Ver: 2.0
+#>=Pkg: d 28 1 x86_64
+#>=Obs: c
+#>=Pkg: e 28 1 x86_64
+#>=Obs: c
+
+system x86_64 rpm system
+
+job update all packages
+result transaction,problems <inline>
+#>erase c-27-1.x86_64@system d-28-1.x86_64@available
+#>install d-28-1.x86_64@available
+
+nextjob
+solverflags yumobsoletes
+job update all packages
+result transaction,problems <inline>
+#>erase c-27-1.x86_64@system d-28-1.x86_64@available
+#>install d-28-1.x86_64@available
+#>install e-28-1.x86_64@available
index 34f393b..279b43b 100644 (file)
@@ -141,8 +141,11 @@ main(int argc, char **argv)
            printf("test %d:\n", multijob++);
          if (list)
            {
+             int selflags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT;
+             if (*list == '/')
+               selflags |= SELECTION_FILELIST;
              queue_empty(&job);
-             selection_make(pool, &job, list, SELECTION_NAME|SELECTION_PROVIDES|SELECTION_FILELIST|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT);
+             selection_make(pool, &job, list, selflags);
              if (!job.elements)
                printf("No match\n");
              else