- add SOLVER_NOAUTOSET to disable automatic SET deduction
[platform/upstream/libsolv.git] / src / pool.c
index 48bb5f2..cd649d2 100644 (file)
@@ -61,6 +61,9 @@ pool_create(void)
   queue_init(&pool->vendormap);
 
   pool->debugmask = SAT_DEBUG_RESULT;  /* FIXME */
+#ifdef FEDORA
+  pool->obsoleteusescolors = 1;
+#endif
   return pool;
 }
 
@@ -88,6 +91,14 @@ pool_free(Pool *pool)
   sat_free(pool);
 }
 
+#ifdef MULTI_SEMANTICS
+void
+pool_setdisttype(Pool *pool, int disttype)
+{
+  pool->disttype = disttype;
+}
+#endif
+
 Id
 pool_add_solvable(Pool *pool)
 {
@@ -271,7 +282,7 @@ pool_createwhatprovides(Pool *pool)
   pool->whatprovides_rel = sat_calloc_block(pool->nrels, sizeof(Offset), WHATPROVIDES_BLOCK);
 
   /* count providers for each name */
-  for (i = 1; i < pool->nsolvables; i++)
+  for (i = pool->nsolvables - 1; i > 0; i--)
     {
       Id *pp;
       s = pool->solvables + i;
@@ -282,7 +293,7 @@ pool_createwhatprovides(Pool *pool)
       if (s->repo != installed && !pool_installable(pool, s))
        continue;
       pp = s->repo->idarraydata + s->provides;
-      while ((id = *pp++) != ID_NULL)
+      while ((id = *pp++) != 0)
        {
          while (ISRELDEP(id))
            {
@@ -294,16 +305,15 @@ pool_createwhatprovides(Pool *pool)
     }
 
   off = 2;     /* first entry is undef, second is empty list */
-  idp = whatprovides;
   np = 0;                             /* number of names provided */
-  for (i = 0; i < num; i++, idp++)
+  for (i = 0, idp = whatprovides; i < num; i++, idp++)
     {
       n = *idp;
       if (!n)                         /* no providers */
        continue;
-      *idp = off;                     /* move from counts to offsets into whatprovidesdata */
-      off += n + 1;                   /* make space for all providers + terminating ID_NULL */
-      np++;                           /* inc # of provider 'slots' */
+      off += n;                               /* make space for all providers */
+      *idp = off++;                   /* now idp points to terminating zero */
+      np++;                           /* inc # of provider 'slots' for stats */
     }
 
   POOL_DEBUG(SAT_DEBUG_STATS, "provide ids: %d\n", np);
@@ -319,7 +329,7 @@ pool_createwhatprovides(Pool *pool)
   whatprovidesdata = sat_calloc(off + extra, sizeof(Id));
 
   /* now fill data for all provides */
-  for (i = 1; i < pool->nsolvables; i++)
+  for (i = pool->nsolvables - 1; i > 0; i--)
     {
       Id *pp;
       s = pool->solvables + i;
@@ -338,15 +348,11 @@ pool_createwhatprovides(Pool *pool)
              id = rd->name;
            }
          d = whatprovidesdata + whatprovides[id];   /* offset into whatprovidesdata */
-         if (*d)
+         if (*d != i)          /* don't add same solvable twice */
            {
-             d++;
-             while (*d)               /* find free slot */
-               d++;
-             if (d[-1] == i)          /* solvable already tacked at end ? */
-               continue;              /* Y: skip, on to next provides */
+             d[-1] = i;
+             whatprovides[id]--;
            }
-         *d = i;                      /* put solvable Id into data */
        }
     }
   pool->whatprovidesdata = whatprovidesdata;
@@ -416,6 +422,14 @@ pool_queuetowhatprovides(Pool *pool, Queue *q)
 
 /*************************************************************************/
 
+#if defined(MULTI_SEMANTICS)
+# define EVRCMP_DEPCMP (pool->disttype == DISTTYPE_DEB ? EVRCMP_COMPARE : EVRCMP_MATCH_RELEASE)
+#elif defined(DEBIAN_SEMANTICS)
+# define EVRCMP_DEPCMP EVRCMP_COMPARE
+#else
+# define EVRCMP_DEPCMP EVRCMP_MATCH_RELEASE
+#endif
+
 /* check if a package's nevr matches a dependency */
 
 int
@@ -457,23 +471,41 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d)
     return 1;
   if (flags != 2 && flags != 5)
     flags ^= 5;
-#ifdef DEBIAN_SEMANTICS
-  if ((flags & (1 << (1 + evrcmp(pool, s->evr, evr, EVRCMP_COMPARE)))) != 0)
+  if ((flags & (1 << (1 + evrcmp(pool, s->evr, evr, EVRCMP_DEPCMP)))) != 0)
     return 1;
-#else
-  if ((flags & (1 << (1 + evrcmp(pool, s->evr, evr, EVRCMP_MATCH_RELEASE)))) != 0)
-    return 1;
-#endif
   return 0;
 }
 
-/* match two dependencies */
+/* match (flags, evr) against provider (pflags, pevr) */
+static inline int
+pool_match_flags_evr(Pool *pool, int pflags, Id pevr, int flags, int evr)
+{
+  if (!pflags || !flags || pflags >= 8 || flags >= 8)
+    return 0;
+  if (flags == 7 || pflags == 7)
+    return 1;          /* rel provides every version */
+  if ((pflags & flags & 5) != 0)
+    return 1;          /* both rels show in the same direction */
+  if (pevr == evr)
+    {
+      if ((pflags & flags & 2) != 0)
+       return 1;       /* both have '=', match */
+    }
+  else
+    {
+      int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5);
+      if ((f & (1 << (1 + evrcmp(pool, pevr, evr, EVRCMP_DEPCMP)))) != 0)
+       return 1;
+    }
+  return 0;
+}
+
+/* match two dependencies (d1 = provider) */
 
 int
 pool_match_dep(Pool *pool, Id d1, Id d2)
 {
   Reldep *rd1, *rd2;
-  int pflags, flags;
 
   if (d1 == d2)
     return 1;
@@ -490,33 +522,11 @@ pool_match_dep(Pool *pool, Id d1, Id d2)
       return pool_match_dep(pool, rd1->name, d2);
     }
   rd2 = GETRELDEP(pool, d2);
+  /* first match name */
   if (!pool_match_dep(pool, rd1->name, rd2->name))
     return 0;
-  pflags = rd1->flags;
-  flags = rd2->flags;
-  if (!pflags || !flags || pflags >= 8 || flags >= 8)
-    return 0;
-  if (flags == 7 || pflags == 7)
-    return 1;
-  if ((pflags & flags & 5) != 0)
-    return 1;
-  if (rd1->evr == rd2->evr)
-    {
-      if ((pflags & flags & 2) != 0)
-       return 1;
-    }
-  else
-    {
-      int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5);
-#ifdef DEBIAN_SEMANTICS
-      if ((f & (1 << (1 + evrcmp(pool, rd1->evr, rd2->evr, EVRCMP_COMPARE)))) != 0)
-       return 1;
-#else
-      if ((f & (1 << (1 + evrcmp(pool, rd1->evr, rd2->evr, EVRCMP_MATCH_RELEASE)))) != 0)
-       return 1;
-#endif
-    }
-  return 0;
+  /* name matches, check flags and evr */
+  return pool_match_flags_evr(pool, rd1->flags, rd1->evr, rd2->flags, rd2->evr);
 }
 
 /*
@@ -674,12 +684,14 @@ pool_addrelproviders(Pool *pool, Id d)
          pidp = s->repo->idarraydata + s->provides;
          while ((pid = *pidp++) != 0)
            {
-             int pflags;
-             Id pevr;
-
              if (pid == name)
                {
-#ifdef DEBIAN_SEMANTICS
+#if defined(MULTI_SEMANTICS)
+                 if (pool->disttype == DISTTYPE_DEB)
+                   continue;
+                 else
+                   break;
+#elif defined(DEBIAN_SEMANTICS)
                  continue;             /* unversioned provides can
                                         * never match versioned deps */
 #else
@@ -691,34 +703,12 @@ pool_addrelproviders(Pool *pool, Id d)
              prd = GETRELDEP(pool, pid);
              if (prd->name != name)
                continue;               /* wrong provides name */
-             /* right package, both deps are rels */
-             pflags = prd->flags;
-             if (!pflags)
-               continue;
-             if (flags == 7 || pflags == 7)
-               break; /* included */
-             if ((pflags & flags & 5) != 0)
-               break; /* same direction, match */
-             pevr = prd->evr;
-             if (pevr == evr)
-               {
-                 if ((pflags & flags & 2) != 0)
-                   break; /* both have =, match */
-               }
-             else
-               {
-                 int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5);
-#ifdef DEBIAN_SEMANTICS
-                 if ((f & (1 << (1 + evrcmp(pool, pevr, evr, EVRCMP_COMPARE)))) != 0)
-                   break;
-#else
-                 if ((f & (1 << (1 + evrcmp(pool, pevr, evr, EVRCMP_MATCH_RELEASE)))) != 0)
-                   break;
-#endif
-               }
+             /* right package, both deps are rels. check flags/evr */
+             if (pool_match_flags_evr(pool, prd->flags, prd->evr, flags, evr))
+               break;  /* matches */
            }
          if (!pid)
-           continue;   /* no rel match */
+           continue;   /* none of the providers matched */
          queue_push(&plist, p);
        }
       /* make our system solvable provide all unknown rpmlib() stuff */
@@ -900,7 +890,7 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
            MAPSET(&cbd->useddirs, did);
        }
     }
-  if (!MAPTST(&cbd->useddirs, value->id))
+  if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id))
     return 0;
   for (i = 0; i < cbd->nfiles; i++)
     {
@@ -956,13 +946,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
        {
          if (ndone >= repo->nsolvables)
            break;
-         if (!repodata_precheck_keyname(data, SOLVABLE_FILELIST))
-           continue;
-         for (j = 1; j < data->nkeys; j++)
-           if (data->keys[j].name == SOLVABLE_FILELIST)
-             break;
-         if (j == data->nkeys)
-           continue;
+
          if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
            {
              map_empty(&cbd->providedids);
@@ -987,13 +971,14 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
                  continue;
                }
            }
-          else
+
+         if (!repodata_has_keyname(data, SOLVABLE_FILELIST))
+           continue;
+
+         if (data->start < provstart || data->end > provend)
            {
-             if (data->start < provstart || data->end > provend)
-               {
-                 map_empty(&cbd->providedids);
-                 provstart = provend = 0;
-               }
+             map_empty(&cbd->providedids);
+             provstart = provend = 0;
            }
 
          /* check if the data is incomplete */
@@ -1544,7 +1529,7 @@ static inline Id dep2name(Pool *pool, Id dep)
   return dep;
 }
 
-static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id dep
+static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id con
 {
   Id p, pp;
   Solvable *sn = pool->solvables + n; 
@@ -1554,9 +1539,12 @@ static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n
       Solvable *s = pool->solvables + p; 
       if (s->name != sn->name || s->arch != sn->arch)
         continue;
-      if ((map[p] & 9) == 9)
-        return 1;
-    }    
+      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;
 }