Imported Upstream version 0.6.23
[platform/upstream/libsolv.git] / src / repo.c
index abb2b3b..9e59fe2 100644 (file)
@@ -92,11 +92,13 @@ repo_empty(Repo *repo, int reuseids)
        if (s->repo != repo)
          break;
       pool_free_solvable_block(pool, i + 1, repo->end - (i + 1), reuseids);
+      repo->end = i + 1;
     }
   /* zero out (i.e. free) solvables belonging to this repo */
   for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++)
     if (s->repo == repo)
       memset(s, 0, sizeof(*s));
+  repo->end = repo->start;
   repo->nsolvables = 0;
 
   /* free all data belonging to this repo */
@@ -146,7 +148,7 @@ repo_add_solvable(Repo *repo)
     repo->start = repo->end = p;
   /* warning: sidedata must be extended before adapting start/end */
   if (repo->rpmdbid)
-    repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, 1); 
+    repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, 1);
   if (p < repo->start)
     repo->start = p;
   if (p + 1 > repo->end)
@@ -160,7 +162,7 @@ Id
 repo_add_solvable_block(Repo *repo, int count)
 {
   Id p;
-  Solvable *s; 
+  Solvable *s;
   if (!count)
     return 0;
   p = pool_add_solvable_block(repo->pool, count);
@@ -360,7 +362,7 @@ repo_addid(Repo *repo, Offset olddeps, Id id)
 #define REPO_ADDID_DEP_HASHTHRES       64
 #define REPO_ADDID_DEP_HASHMIN         128
 
-/* 
+/*
  * Optimization for packages with an excessive amount of provides/requires:
  * if the number of deps exceed a threshold, we build a hash of the already
  * seen ids.
@@ -386,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));
@@ -590,6 +592,20 @@ repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker)
   return repo_addid(repo, olddeps, id);
 }
 
+/* return standard marker for the keyname dependency.
+ * 1: return positive marker, -1: return negative marker
+ */
+Id
+solv_depmarker(Id keyname, Id marker)
+{
+  if (marker != 1 && marker != -1)
+    return marker;
+  if (keyname == SOLVABLE_PROVIDES)
+    return marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
+  if (keyname == SOLVABLE_REQUIRES)
+    return marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
+  return 0;
+}
 
 /*
  * reserve Ids
@@ -598,7 +614,6 @@ repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker)
  *
  * reserved ids will always begin at offset idarraysize
  */
-
 Offset
 repo_reserve_ids(Repo *repo, Offset olddeps, int num)
 {
@@ -651,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;
@@ -892,12 +683,13 @@ repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValu
 
   if (md->matcher.match)
     {
+      const char *str;
       if (key->name == SOLVABLE_FILELIST && key->type == REPOKEY_TYPE_DIRSTRARRAY && (md->matcher.flags & SEARCH_FILES) != 0)
        if (!datamatcher_checkbasename(&md->matcher, kv->str))
          return 0;
-      if (!repodata_stringify(md->pool, data, key, kv, md->flags))
+      if (!(str = repodata_stringify(md->pool, data, key, kv, md->flags)))
        return 0;
-      if (!datamatcher_match(&md->matcher, kv->str))
+      if (!datamatcher_match(&md->matcher, str))
        return 0;
     }
   md->stop = md->callback(md->callback_data, s, data, key, kv);
@@ -1249,6 +1041,7 @@ lookup_idarray_solvable(Repo *repo, Offset off, Queue *q)
 int
 repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
 {
+  Pool *pool = repo->pool;
   Repodata *data;
   int i;
   if (entry >= 0)
@@ -1273,6 +1066,19 @@ repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
          return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q);
         }
     }
+  else if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+    {
+      Repodata *data = pool->pos.repo->repodata + pool->pos.repodataid;
+      if (repodata_lookup_idarray(data, entry, keyname, q))
+       {
+         if (data->localpool)
+           {
+             for (i = 0; i < q->count; i++)
+               q->elements[i] = repodata_globalize_id(data, q->elements[i], 1);
+           }
+         return 1;
+       }
+    }
   FOR_REPODATAS(repo, i, data)
     {
       if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
@@ -1299,7 +1105,11 @@ int
 repo_lookup_deparray(Repo *repo, Id entry, Id keyname, Queue *q, Id marker)
 {
   int r = repo_lookup_idarray(repo, entry, keyname, q);
-  if (r && marker && q->count)
+  if (!r)
+    return 0;
+  if (marker == -1 || marker == 1)
+    marker = solv_depmarker(keyname, marker);
+  if (marker && q->count)
     {
       int i;
       if (marker < 0)
@@ -1405,6 +1215,30 @@ repo_lookup_type(Repo *repo, Id entry, Id keyname)
   return 0;
 }
 
+const void *
+repo_lookup_binary(Repo *repo, Id entry, Id keyname, int *lenp)
+{
+  Pool *pool = repo->pool;
+  Repodata *data;
+  int i;
+  const void *bin;
+
+  if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+    return repodata_lookup_binary(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname, lenp);
+  FOR_REPODATAS(repo, i, data)
+    {
+      if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
+       continue;
+      if (!repodata_precheck_keyname(data, keyname))
+       continue;
+      bin = repodata_lookup_binary(data, entry, keyname, lenp);
+      if (bin)
+       return bin;
+    }
+  *lenp = 0;
+  return 0;
+}
+
 /***********************************************************************/
 
 Repodata *
@@ -1433,16 +1267,16 @@ repo_add_repodata(Repo *repo, int flags)
          return repo->repodata + i;
     }
   if (!repo->nrepodata)
-    {    
+    {
       repo->nrepodata = 2;      /* start with id 1 */
       repo->repodata = solv_calloc(repo->nrepodata, sizeof(*data));
-    }    
-  else 
-    {    
+    }
+  else
+    {
       repo->nrepodata++;
       repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
-    }    
-  data = repo->repodata + repo->nrepodata - 1; 
+    }
+  data = repo->repodata + repo->nrepodata - 1;
   repodata_initdata(data, repo, (flags & REPO_LOCALPOOL) ? 1 : 0);
   return data;
 }
@@ -1560,6 +1394,8 @@ void
 repo_add_deparray(Repo *repo, Id p, Id keyname, Id dep, Id marker)
 {
   Repodata *data;
+  if (marker == -1 || marker == 1)
+    marker = solv_depmarker(keyname, marker);
   if (p >= 0)
     {
       Solvable *s = repo->pool->solvables + p;
@@ -1615,6 +1451,8 @@ void
 repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
 {
   Repodata *data;
+  if (marker == -1 || marker == 1)
+    marker = solv_depmarker(keyname, marker);
   if (marker)
     {
       /* complex case, splice old and new arrays */
@@ -1759,6 +1597,3 @@ repo_disable_paging(Repo *repo)
     repodata_disable_paging(data);
 }
 
-/*
-vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
-*/