Imported Upstream version 0.7.18
[platform/upstream/libsolv.git] / src / pool.c
index 60cc0f4..0b4b9dd 100644 (file)
@@ -27,6 +27,9 @@
 #include "util.h"
 #include "bitmap.h"
 #include "evr.h"
+#ifdef ENABLE_CONDA
+#include "conda.h"
+#endif
 
 #define SOLVABLE_BLOCK 255
 
@@ -158,6 +161,9 @@ pool_setdisttype(Pool *pool, int disttype)
     case DISTTYPE_HAIKU:
       pool->noarchid = ARCH_ANY;
       break;
+    case DISTTYPE_CONDA:
+      pool->noarchid = ARCH_ANY;
+      break;
     default:
       return -1;
     }
@@ -196,6 +202,8 @@ pool_get_flag(Pool *pool, int flag)
       return pool->addfileprovidesfiltered;
     case POOL_FLAG_NOWHATPROVIDESAUX:
       return pool->nowhatprovidesaux;
+    case POOL_FLAG_WHATPROVIDESWITHDISABLED:
+      return pool->whatprovideswithdisabled;
     default:
       break;
     }
@@ -241,6 +249,9 @@ pool_set_flag(Pool *pool, int flag, int value)
     case POOL_FLAG_NOWHATPROVIDESAUX:
       pool->nowhatprovidesaux = value;
       break;
+    case POOL_FLAG_WHATPROVIDESWITHDISABLED:
+      pool->whatprovideswithdisabled = value;
+      break;
     default:
       break;
     }
@@ -444,7 +455,6 @@ pool_createwhatprovides(Pool *pool)
   Offset *whatprovides;
   Id *whatprovidesdata, *dp, *whatprovidesauxdata;
   Offset *whatprovidesaux;
-  Repo *installed = pool->installed;
   unsigned int now;
 
   now = solv_timems(0);
@@ -467,9 +477,7 @@ pool_createwhatprovides(Pool *pool)
       s = pool->solvables + i;
       if (!s->provides || !s->repo || s->repo->disabled)
        continue;
-      /* we always need the installed solvable in the whatprovides data,
-         otherwise obsoletes/conflicts on them won't work */
-      if (s->repo != installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
        continue;
       pp = s->repo->idarraydata + s->provides;
       while ((id = *pp++) != 0)
@@ -528,9 +536,8 @@ pool_createwhatprovides(Pool *pool)
       s = pool->solvables + i;
       if (!s->provides || !s->repo || s->repo->disabled)
        continue;
-      if (s->repo != installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
        continue;
-
       /* for all provides of this solvable */
       pp = s->repo->idarraydata + s->provides;
       while ((id = *pp++) != 0)
@@ -808,6 +815,23 @@ pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr)
   return pool_match_flags_evr(pool, pflags, pevr, flags, evr);
 }
 
+
+static int
+is_interval_dep(Pool *pool, Id d1, Id d2)
+{
+  Reldep *rd1, *rd2;
+  if (!ISRELDEP(d1) || !ISRELDEP(d2))
+    return 0;
+  rd1 = GETRELDEP(pool, d1);
+  rd2 = GETRELDEP(pool, d2);
+  if (rd1->name != rd2->name || rd1->flags >= 8 || rd2->flags >= 8)
+    return 0;
+  if (((rd1->flags ^ rd2->flags) & (REL_LT|REL_GT)) != (REL_LT|REL_GT))
+    return 0;
+  return 1;
+}
+
+
 /* match two dependencies (d1 = provider) */
 
 int
@@ -824,6 +848,8 @@ pool_match_dep(Pool *pool, Id d1, Id d2)
       rd1 = GETRELDEP(pool, d1);
       if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_WITHOUT || rd1->flags == REL_COND || rd1->flags == REL_UNLESS)
        {
+         if (rd1->flags == REL_WITH && is_interval_dep(pool, rd1->name, rd1->evr))
+           return pool_match_dep(pool, rd1->name, d2) && pool_match_dep(pool, rd1->evr, d2);
          if (pool_match_dep(pool, rd1->name, d2))
            return 1;
          if ((rd1->flags == REL_COND || rd1->flags == REL_UNLESS) && ISRELDEP(rd1->evr))
@@ -843,6 +869,8 @@ pool_match_dep(Pool *pool, Id d1, Id d2)
       rd2 = GETRELDEP(pool, d2);
       if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_WITHOUT || rd2->flags == REL_COND || rd2->flags == REL_UNLESS)
        {
+         if (rd2->flags == REL_WITH && is_interval_dep(pool, rd2->name, rd2->evr))
+           return pool_match_dep(pool, d1, rd2->name) && pool_match_dep(pool, d1, rd2->evr);
          if (pool_match_dep(pool, d1, rd2->name))
            return 1;
          if ((rd2->flags == REL_COND || rd2->flags == REL_UNLESS) && ISRELDEP(rd2->evr))
@@ -927,7 +955,7 @@ pool_addstdproviders(Pool *pool, Id d)
       return 1;
     }
   queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
-  dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, str, SEARCH_STRING|SEARCH_FILES|SEARCH_COMPLETE_FILELIST);
+  dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, str, SEARCH_STRING|SEARCH_FILES);
   for (; dataiterator_step(&di); dataiterator_skip_solvable(&di))
     {
       Solvable *s = pool->solvables + di.solvid;
@@ -936,7 +964,7 @@ pool_addstdproviders(Pool *pool, Id d)
        * and those should not use filelist entries */
       if (s->repo->disabled)
        continue;
-      if (s->repo != pool->installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
        continue;
       queue_push(&q, di.solvid);
     }
@@ -1216,7 +1244,7 @@ pool_addrelproviders(Pool *pool, Id d)
              FOR_POOL_SOLVABLES(p)
                {
                  Solvable *s = pool->solvables + p;
-                 if (s->repo != pool->installed && !pool_installable(pool, s))
+                 if (!pool_installable_whatprovides(pool, s))
                    continue;
                  if (s->arch == evr)
                    queue_push(&plist, p);
@@ -1281,6 +1309,11 @@ pool_addrelproviders(Pool *pool, Id d)
                queue_push(&plist, p);
            }
          break;
+#ifdef ENABLE_CONDA
+       case REL_CONDA:
+          wp = pool_addrelproviders_conda(pool, name, evr, &plist);
+         break;
+#endif
        default:
          break;
        }
@@ -1301,7 +1334,7 @@ pool_addrelproviders(Pool *pool, Id d)
       POOL_DEBUG(SOLV_DEBUG_STATS, "addrelproviders: what provides %s?\n", pool_dep2str(pool, name));
 #endif
       pp = pool_whatprovides_ptr(pool, name);
-      if (!ISRELDEP(name) && name < pool->whatprovidesauxoff)
+      if (!ISRELDEP(name) && (Offset)name < pool->whatprovidesauxoff)
        ppaux = pool->whatprovidesaux[name] ? pool->whatprovidesauxdata + pool->whatprovidesaux[name] : 0;
       while (ISRELDEP(name))
        {
@@ -1344,9 +1377,9 @@ pool_addrelproviders(Pool *pool, Id d)
                  continue;
                }
            }
-         if (!s->provides)
+         if (!s->provides || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
            {
-             /* no provides - check nevr */
+             /* no provides or src rpm - check nevr */
              if (pool_match_nevr_rel(pool, s, MAKERELDEP(d)))
                queue_push(&plist, p);
              continue;
@@ -1485,6 +1518,37 @@ pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker)
   queue_free(&qq);
 }
 
+/* intersect dependencies in keyname with all provides of solvable solvid,
+ * return list of matching packages */
+/* this currently only works for installable packages */
+void
+pool_whatmatchessolvable(Pool *pool, Id keyname, Id solvid, Queue *q, int marker)
+{
+  Id p;
+  Queue qq;
+  Map missc;           /* cache for misses */
+  int reloff;
+
+  queue_empty(q);
+  queue_init(&qq);
+  reloff = pool->ss.nstrings;
+  map_init(&missc, reloff + pool->nrels);
+  FOR_POOL_SOLVABLES(p)
+    {
+      Solvable *s = pool->solvables + p;
+      if (p == solvid)
+       continue;       /* filter out self-matches */
+      if (s->repo->disabled)
+       continue;
+      if (s->repo != pool->installed && !pool_installable(pool, s))
+       continue;
+      if (solvable_matchessolvable_int(s, keyname, marker, solvid, 0, &qq, &missc, reloff, 0))
+        queue_push(q, p);
+    }
+  map_free(&missc);
+  queue_free(&qq);
+}
+
 /*************************************************************************/
 
 void
@@ -1505,6 +1569,7 @@ pool_debug(Pool *pool, int type, const char *format, ...)
         vprintf(format, args);
       else
         vfprintf(stderr, format, args);
+      va_end(args);
       return;
     }
   vsnprintf(buf, sizeof(buf), format, args);
@@ -1566,12 +1631,12 @@ pool_setdebuglevel(Pool *pool, int level)
   if (level > 2)
     mask |= SOLV_DEBUG_PROPAGATE;
   if (level > 3)
-    mask |= SOLV_DEBUG_RULE_CREATION;
+    mask |= SOLV_DEBUG_RULE_CREATION | SOLV_DEBUG_WATCHES;
   mask |= pool->debugmask & SOLV_DEBUG_TO_STDERR;      /* keep bit */
   pool->debugmask = mask;
 }
 
-void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct _Pool *, void *data, int type, const char *str), void *debugcallbackdata)
+void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct s_Pool *, void *data, int type, const char *str), void *debugcallbackdata)
 {
   pool->debugcallback = debugcallback;
   pool->debugcallbackdata = debugcallbackdata;
@@ -1582,20 +1647,20 @@ void pool_setdebugmask(Pool *pool, int mask)
   pool->debugmask = mask;
 }
 
-void pool_setloadcallback(Pool *pool, int (*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata)
+void pool_setloadcallback(Pool *pool, int (*cb)(struct s_Pool *, struct s_Repodata *, void *), void *loadcbdata)
 {
   pool->loadcallback = cb;
   pool->loadcallbackdata = loadcbdata;
 }
 
-void pool_setnamespacecallback(Pool *pool, Id (*cb)(struct _Pool *, void *, Id, Id), void *nscbdata)
+void pool_setnamespacecallback(Pool *pool, Id (*cb)(struct s_Pool *, void *, Id, Id), void *nscbdata)
 {
   pool->nscallback = cb;
   pool->nscallbackdata = nscbdata;
 }
 
 void
-pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata)
+pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct s_Repodata *data, struct s_Repokey *key, struct s_KeyValue *kv), void *cbdata)
 {
   if (p)
     {
@@ -1883,7 +1948,7 @@ pool_set_whatprovides(Pool *pool, Id id, Id providers)
   else
     {
       pool->whatprovides[id] = providers;
-      if (id < pool->whatprovidesauxoff)
+      if ((Offset)id < pool->whatprovidesauxoff)
        pool->whatprovidesaux[id] = 0;  /* sorry */
       d = 1;
     }