Imported Upstream version 0.7.12 upstream/0.7.12
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 27 Nov 2020 05:49:16 +0000 (14:49 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 27 Nov 2020 05:49:16 +0000 (14:49 +0900)
20 files changed:
CMakeLists.txt
NEWS
VERSION.cmake
ext/repo_conda.c
ext/repo_updateinfoxml.c
ext/solv_xfopen.c
package/libsolv.changes
src/CMakeLists.txt
src/knownid.h
src/policy.c
src/repo.c
src/repo.h
src/repodata.c
src/repodata.h
src/rules.c
src/solvable.c
src/solvable.h
win32/config.h [new file with mode: 0644]
win32/getopt.c
win32/getopt.h

index c1ada00..347bb0d 100644 (file)
@@ -58,6 +58,9 @@ ENDIF (NOT PKGCONFIG_INSTALL_DIR)
 SET (CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
 INSTALL( FILES ${CMAKE_MODULE_PATH}/FindLibSolv.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share/cmake/Modules )
 
+# for shared libraries on windows (DLLs), we just export all symbols for now
+SET(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+
 INCLUDE (${CMAKE_SOURCE_DIR}/VERSION.cmake)
 
 SET (have_system x)
@@ -431,9 +434,9 @@ ENDIF (HAVE_LINKER_AS_NEEDED)
 ADD_SUBDIRECTORY (src)
 ADD_SUBDIRECTORY (ext)
 ADD_SUBDIRECTORY (tools)
-IF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_RUBY OR ENABLE_TCL)
+IF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_PYTHON3 OR ENABLE_RUBY OR ENABLE_TCL)
     ADD_SUBDIRECTORY (bindings)
-ENDIF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_RUBY OR ENABLE_TCL)
+ENDIF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_PYTHON3 OR ENABLE_RUBY OR ENABLE_TCL)
 ADD_SUBDIRECTORY (examples)
 ADD_SUBDIRECTORY (doc)
 
diff --git a/NEWS b/NEWS
index 9d2d833..9bdc2d8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@
 This file contains the major changes between
 libsolv versions:
 
+Version 0.7.12
+- conda: support packages.conda repositories
+- conda: de-priorize track features
+- allow win32 to build shared lib
+- selected bug fixes:
+  * fix ruleinfo of complex dependencies returning the wrong origin
+
 Version 0.7.11
 - ENABLE_RPMDB_LIBRPM is now the default
 - selected bug fixes:
index 180eda5..ffa76f3 100644 (file)
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1")
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "11")
+SET(LIBSOLV_PATCH "12")
 
index 9352b71..f58da0f 100644 (file)
@@ -22,6 +22,9 @@ struct parsedata {
   Pool *pool;
   Repo *repo;
   Repodata *data;
+
+  Stringpool fnpool;
+  Queue fndata;
 };
 
 static int
@@ -61,17 +64,76 @@ parse_otherdeps(struct parsedata *pd, struct solv_jsonparser *jp, Id handle, Id
 }
 
 static int
+parse_trackfeatures(struct parsedata *pd, struct solv_jsonparser *jp, Id handle)
+{
+  int type = JP_ARRAY;
+  while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_ARRAY_END)
+    {
+      if (type == JP_STRING)
+       {
+         char *p = jp->value, *pe;
+         while (*p == ' ' || *p == '\t')
+           p++;
+         if (!*p)
+           continue;
+         for (pe = p + strlen(p) - 1; pe > p; pe--)
+           if (*pe != ' ' && *pe != '\t')
+             break;
+         repodata_add_idarray(pd->data, handle, SOLVABLE_TRACK_FEATURES, pool_strn2id(pd->pool, p, pe - p + 1, 1));
+       }
+      else
+       type = jsonparser_skip(jp, type);
+    }
+  return type;
+}
+
+static void 
+swap_solvables(Repo *repo, Repodata *data, Id pa, Id pb)
+{
+  Pool *pool = repo->pool;
+  Solvable tmp; 
+
+  tmp = pool->solvables[pa];
+  pool->solvables[pa] = pool->solvables[pb];
+  pool->solvables[pb] = tmp; 
+  repodata_swap_attrs(data, pa, pb); 
+}
+
+static Id *
+fn2data(struct parsedata *pd, const char *fn, Id *fntypep, int create)
+{
+  size_t l = strlen(fn), extl = 0;
+  Id fnid;
+  if (l > 6 && !strcmp(fn + l - 6, ".conda"))
+    extl = 6;
+  else if (l > 8 && !strcmp(fn + l - 8, ".tar.bz2"))
+    extl = 8;
+  else
+    return 0;
+  fnid = stringpool_strn2id(&pd->fnpool, fn, l - extl, create);
+  if (!fnid)
+    return 0;
+  if (fnid * 2 + 2 > pd->fndata.count)
+    queue_insertn(&pd->fndata, pd->fndata.count, fnid * 2 + 2 - pd->fndata.count, 0);
+  if (fntypep)
+    *fntypep = extl == 8 ? 1 : 2;      /* 1: legacy .tar.bz2  2: .conda */
+  return pd->fndata.elements + 2 * fnid;
+}
+
+static int
 parse_package(struct parsedata *pd, struct solv_jsonparser *jp, char *kfn)
 {
   int type = JP_OBJECT;
   Pool *pool= pd->pool;
   Repodata *data = pd->data;
   Solvable *s;
-  Id handle = repo_add_solvable(pd->repo);
-  s = pool_id2solvable(pool, handle);
+  Id handle;
   char *fn = 0;
   char *subdir = 0;
+  Id *fndata = 0, fntype = 0;
 
+  handle = repo_add_solvable(pd->repo);
+  s = pool_id2solvable(pool, handle);
   while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_OBJECT_END)
     {
       if (type == JP_STRING && !strcmp(jp->key, "build"))
@@ -107,17 +169,56 @@ parse_package(struct parsedata *pd, struct solv_jsonparser *jp, char *kfn)
            ts /= 1000;
          repodata_set_num(data, handle, SOLVABLE_BUILDTIME, ts);
        }
+      else if (type == JP_STRING && !strcmp(jp->key, "track_features"))
+       {
+         char *p = jp->value, *pe;
+         for (; *p; p++)
+           {
+             if (*p == ' ' || *p == '\t' || *p == ',')
+               continue;
+             pe = p + 1;
+             while (*pe && *pe != ' ' && *pe != '\t' && *pe != ',')
+               pe++;
+             repodata_add_idarray(data, handle, SOLVABLE_TRACK_FEATURES, pool_strn2id(pool, p, pe - p, 1));
+             p = pe - 1;
+           }
+       }
+      else if (type == JP_ARRAY && !strcmp(jp->key, "track_features"))
+       type = parse_trackfeatures(pd, jp, handle);
       else
        type = jsonparser_skip(jp, type);
     }
   if (fn || kfn)
-    repodata_set_location(data, handle, 0, subdir, fn ? fn : kfn);
+    {
+      repodata_set_location(data, handle, 0, subdir, fn ? fn : kfn);
+      fndata = fn2data(pd, fn ? fn : kfn, &fntype, 1);
+    }
   solv_free(fn);
   solv_free(subdir);
   if (!s->evr)
     s->evr = 1;
   if (s->name)
     s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+
+  if (fndata)
+    {
+      /* deal with legacy package entries */
+      if (fndata[0] && fndata[0] > fntype)
+       {
+         /* ignore this package */
+         repo_free_solvable(pd->repo, handle, 1);
+         return type;
+       }
+      if (fndata[0] && fndata[0] < fntype)
+       {
+         /* replace old package */
+         swap_solvables(pd->repo, data, handle, fndata[1]);
+         repo_free_solvable(pd->repo, handle, 1);
+         handle = fndata[1];
+       }
+      fndata[0] = fntype;
+      fndata[1] = handle;
+    }
   return type;
 }
 
@@ -161,7 +262,11 @@ parse_main(struct parsedata *pd, struct solv_jsonparser *jp)
     {
       if (type == JP_OBJECT && !strcmp("packages", jp->key))
        type = parse_packages(pd, jp);
-      if (type == JP_ARRAY && !strcmp("packages", jp->key))
+      else if (type == JP_ARRAY && !strcmp("packages", jp->key))
+       type = parse_packages2(pd, jp);
+      else if (type == JP_OBJECT && !strcmp("packages.conda", jp->key))
+       type = parse_packages(pd, jp);
+      else if (type == JP_ARRAY && !strcmp("packages.conda", jp->key))
        type = parse_packages2(pd, jp);
       else
        type = jsonparser_skip(jp, type);
@@ -184,6 +289,8 @@ repo_add_conda(Repo *repo, FILE *fp, int flags)
   pd.pool = pool;
   pd.repo = repo;
   pd.data = data;
+  stringpool_init_empty(&pd.fnpool);
+  queue_init(&pd.fndata);
 
   jsonparser_init(&jp, fp);
   if ((type = jsonparser_parse(&jp)) != JP_OBJECT)
@@ -192,6 +299,8 @@ repo_add_conda(Repo *repo, FILE *fp, int flags)
     ret = pool_error(pool, -1, "parse error line %d", jp.line);
   jsonparser_free(&jp);
 
+  queue_free(&pd.fndata);
+  stringpool_free(&pd.fnpool);
   if (!(flags & REPO_NO_INTERNALIZE))
     repodata_internalize(data);
 
index 5b980a1..36d76b5 100644 (file)
@@ -524,7 +524,7 @@ repo_mark_retracted_packages(Repo *repo, Id retractedmarker)
 
   Queue q;
   queue_init(&q);
-  for (p = 1; p < pool->nsolvables; p++)
+  FOR_REPO_SOLVABLES(repo, p, s)
     {
       const char *status;
       s = pool->solvables + p;
@@ -578,7 +578,7 @@ repo_mark_retracted_packages(Repo *repo, Id retractedmarker)
       else if (q.elements[i + 1] == retractedname && q.elements[i + 2] == retractedevr)
        {
          s = pool->solvables + q.elements[i];
-         s->provides = repo_addid_dep(repo, s->provides, retractedmarker, 0);
+         s->provides = repo_addid_dep(s->repo, s->provides, retractedmarker, 0);
        }
     }
   queue_free(&q);
index 9aab68b..4bb4628 100644 (file)
@@ -61,7 +61,15 @@ static FILE *cookieopen(void *cookie, const char *mode,
 
 static ssize_t cookie_gzread(void *cookie, char *buf, size_t nbytes)
 {
-  return gzread((gzFile)cookie, buf, nbytes);
+  ssize_t r = gzread((gzFile)cookie, buf, nbytes);
+  if (r == 0)
+    {
+      int err = 0;
+      gzerror((gzFile)cookie, &err);
+      if (err == Z_BUF_ERROR)
+       r = -1;
+    }
+  return r;
 }
 
 static ssize_t cookie_gzwrite(void *cookie, const char *buf, size_t nbytes)
index 253784b..caccbeb 100644 (file)
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Mon Apr 20 17:24:21 CEST 2020 - mls@suse.de
+
+- fix ruleinfo of complex dependencies returning the wrong origin
+- bump version to 0.7.12
+
+-------------------------------------------------------------------
 Wed Jan 22 13:52:48 CET 2020 - mls@suse.de
 
 - fixed solv_zchunk decoding error if large chunks are used
index 6abb3ad..bbf30ba 100644 (file)
@@ -48,11 +48,19 @@ SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINK_FLAGS} -Wl,-
 ENDIF (HAVE_LINKER_VERSION_SCRIPT)
 
 IF (DISABLE_SHARED)
-ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS})
+    ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS})
 ELSE (DISABLE_SHARED)
-ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS})
+    ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS})
 ENDIF (DISABLE_SHARED)
 
+IF (WIN32)
+    IF (DISABLE_SHARED)
+        TARGET_COMPILE_DEFINITIONS(libsolv PUBLIC SOLV_STATIC_LIB)
+    ELSE (DISABLE_SHARED)
+        TARGET_COMPILE_DEFINITIONS(libsolv PRIVATE SOLV_EXPORTS)
+    ENDIF (DISABLE_SHARED)
+ENDIF (WIN32)
+
 SET_TARGET_PROPERTIES(libsolv PROPERTIES OUTPUT_NAME "solv")
 SET_TARGET_PROPERTIES(libsolv PROPERTIES SOVERSION ${LIBSOLV_SOVERSION})
 
index 96c9adf..4c1730b 100644 (file)
@@ -266,6 +266,7 @@ KNOWNID(UPDATE_STATUS,                      "update:status"),               /* "stable", "testing", ...*/
 KNOWNID(LIBSOLV_SELF_DESTRUCT_PKG,      "libsolv-self-destruct-pkg()"),        /* this package will self-destruct on installation */
 
 KNOWNID(SOLVABLE_CONSTRAINS,           "solvable:constrains"),         /* conda */
+KNOWNID(SOLVABLE_TRACK_FEATURES,       "solvable:track_features"),     /* conda */
 
 KNOWNID(ID_NUM_INTERNAL,               0)
 
index 10a2c4d..fe8d55e 100644 (file)
@@ -836,8 +836,14 @@ move_installed_to_front(Pool *pool, Queue *plist)
 static int
 pool_buildversioncmp(Pool *pool, Solvable *s1, Solvable *s2)
 {
-  const char *bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION);
-  const char *bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION);
+  const char *bv1, *bv2;
+  unsigned int cnt1, cnt2;
+  cnt1 = solvable_lookup_count(s1, SOLVABLE_TRACK_FEATURES);
+  cnt2 = solvable_lookup_count(s2, SOLVABLE_TRACK_FEATURES);
+  if (cnt1 != cnt2)
+    return cnt1 > cnt2 ? -1 : 1;
+  bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION);
+  bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION);
   if (!bv1 && !bv2)
     return 0;
   return pool_evrcmp_str(pool, bv1 ? bv1 : "" , bv2 ? bv2 : "", EVRCMP_COMPARE);
index da40219..45e8681 100644 (file)
@@ -737,6 +737,32 @@ domatch_idarray(Solvable *s, Id keyname, struct matchdata *md, Id *ida)
     }
 }
 
+static Offset *
+solvable_offsetptr(Solvable *s, Id keyname)
+{
+  switch(keyname)
+  {
+  case SOLVABLE_PROVIDES:
+    return &s->provides;
+  case SOLVABLE_OBSOLETES:
+    return &s->obsoletes;
+  case SOLVABLE_CONFLICTS:
+    return &s->conflicts;
+  case SOLVABLE_REQUIRES:
+    return &s->requires;
+  case SOLVABLE_RECOMMENDS:
+    return &s->recommends;
+  case SOLVABLE_SUGGESTS:
+    return &s->suggests;
+  case SOLVABLE_SUPPLEMENTS:
+    return &s->supplements;
+  case SOLVABLE_ENHANCES:
+    return &s->enhances;
+  default:
+    return 0;
+  }
+}
+
 static void
 repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
 {
@@ -1131,18 +1157,6 @@ repo_lookup_id(Repo *repo, Id entry, Id keyname)
   return 0;
 }
 
-static int
-lookup_idarray_solvable(Repo *repo, Offset off, Queue *q)
-{
-  Id *p;
-
-  queue_empty(q);
-  if (off)
-    for (p = repo->idarraydata + off; *p; p++)
-      queue_push(q, *p);
-  return 1;
-}
-
 int
 repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
 {
@@ -1150,24 +1164,25 @@ repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
   int i;
   if (entry >= 0)
     {
+      Offset *offp;
       switch (keyname)
         {
        case SOLVABLE_PROVIDES:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].provides, q);
        case SOLVABLE_OBSOLETES:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].obsoletes, q);
        case SOLVABLE_CONFLICTS:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].conflicts, q);
        case SOLVABLE_REQUIRES:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].requires, q);
        case SOLVABLE_RECOMMENDS:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].recommends, q);
        case SOLVABLE_SUGGESTS:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].suggests, q);
        case SOLVABLE_SUPPLEMENTS:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].supplements, q);
        case SOLVABLE_ENHANCES:
-         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q);
+         offp = solvable_offsetptr(repo->pool->solvables + entry, keyname);
+         if (*offp)
+           {
+             Id *p;
+             for (p = repo->idarraydata + *offp; *p; p++)
+               queue_push(q, *p);
+           }
+         return 1;
         }
     }
   data = repo_lookup_repodata_opt(repo, entry, keyname);
@@ -1270,6 +1285,37 @@ repo_lookup_binary(Repo *repo, Id entry, Id keyname, int *lenp)
   return 0;
 }
 
+unsigned int
+repo_lookup_count(Repo *repo, Id entry, Id keyname)
+{
+  Repodata *data;
+  if (keyname >= SOLVABLE_NAME && keyname <= RPM_RPMDBID)
+  if (entry >= 0 && keyname >= SOLVABLE_NAME && keyname <= RPM_RPMDBID)
+    {
+      Id *p;
+      Offset *offp;
+      unsigned int cnt;
+      switch (keyname)
+        {
+       case SOLVABLE_PROVIDES:
+       case SOLVABLE_OBSOLETES:
+       case SOLVABLE_CONFLICTS:
+       case SOLVABLE_REQUIRES:
+       case SOLVABLE_RECOMMENDS:
+       case SOLVABLE_SUGGESTS:
+       case SOLVABLE_SUPPLEMENTS:
+       case SOLVABLE_ENHANCES:
+         offp = solvable_offsetptr(repo->pool->solvables + entry, keyname);
+         for (cnt = 0, p = repo->idarraydata + *offp; *p; p++)
+           cnt++;
+         return cnt;
+        }
+      return 1;
+    }
+  data = repo_lookup_repodata_opt(repo, entry, keyname);
+  return data ? repodata_lookup_count(data, entry, keyname) : 0;
+}
+
 /***********************************************************************/
 
 Repodata *
@@ -1429,32 +1475,19 @@ repo_add_deparray(Repo *repo, Id p, Id keyname, Id dep, Id marker)
     marker = solv_depmarker(keyname, marker);
   if (p >= 0)
     {
-      Solvable *s = repo->pool->solvables + p;
+      Offset *offp;
       switch (keyname)
        {
        case SOLVABLE_PROVIDES:
-         s->provides = repo_addid_dep(repo, s->provides, dep, marker);
-         return;
        case SOLVABLE_OBSOLETES:
-         s->obsoletes = repo_addid_dep(repo, s->obsoletes, dep, marker);
-         return;
        case SOLVABLE_CONFLICTS:
-         s->conflicts = repo_addid_dep(repo, s->conflicts, dep, marker);
-         return;
        case SOLVABLE_REQUIRES:
-         s->requires = repo_addid_dep(repo, s->requires, dep, marker);
-         return;
        case SOLVABLE_RECOMMENDS:
-         s->recommends = repo_addid_dep(repo, s->recommends, dep, marker);
-         return;
        case SOLVABLE_SUGGESTS:
-         s->suggests = repo_addid_dep(repo, s->suggests, dep, marker);
-         return;
        case SOLVABLE_SUPPLEMENTS:
-         s->supplements = repo_addid_dep(repo, s->supplements, dep, marker);
-         return;
        case SOLVABLE_ENHANCES:
-         s->enhances = repo_addid_dep(repo, s->enhances, dep, marker);
+         offp = solvable_offsetptr(repo->pool->solvables + p, keyname);
+         *offp = repo_addid_dep(repo, *offp, dep, marker);
          return;
        }
     }
@@ -1468,16 +1501,6 @@ repo_add_idarray(Repo *repo, Id p, Id keyname, Id id)
   repo_add_deparray(repo, p, keyname, id, 0);
 }
 
-static Offset
-repo_set_idarray_solvable(Repo *repo, Queue *q)
-{
-  Offset o = 0;
-  int i;
-  for (i = 0; i < q->count; i++)
-    repo_addid_dep(repo, o, q->elements[i], 0);
-  return o;
-}
-
 void
 repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
 {
@@ -1512,32 +1535,23 @@ repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
     }
   if (p >= 0)
     {
-      Solvable *s = repo->pool->solvables + p;
+      Offset off, *offp;
+      int i;
       switch (keyname)
        {
        case SOLVABLE_PROVIDES:
-         s->provides = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_OBSOLETES:
-         s->obsoletes = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_CONFLICTS:
-         s->conflicts = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_REQUIRES:
-         s->requires = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_RECOMMENDS:
-         s->recommends = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_SUGGESTS:
-         s->suggests = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_SUPPLEMENTS:
-         s->supplements = repo_set_idarray_solvable(repo, q);
-         return;
        case SOLVABLE_ENHANCES:
-         s->enhances = repo_set_idarray_solvable(repo, q);
+         off = 0;
+         for (i = 0; i < q->count; i++)
+           off = repo_addid_dep(repo, off, q->elements[i], 0);
+         offp = solvable_offsetptr(repo->pool->solvables + p, keyname);
+         *offp = off;
          return;
        }
     }
index 9a5e981..b503431 100644 (file)
@@ -189,6 +189,7 @@ int repo_lookup_void(Repo *repo, Id entry, Id keyname);
 const char *repo_lookup_checksum(Repo *repo, Id entry, Id keyname, Id *typep);
 const unsigned char *repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep);
 const void *repo_lookup_binary(Repo *repo, Id entry, Id keyname, int *lenp);
+unsigned int repo_lookup_count(Repo *repo, Id entry, Id keyname);      /* internal */
 Id solv_depmarker(Id keyname, Id marker);
 
 void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
index 3cae0fe..0580cff 100644 (file)
@@ -841,6 +841,57 @@ repodata_lookup_binary(Repodata *data, Id solvid, Id keyname, int *lenp)
   return dp;
 }
 
+unsigned int
+repodata_lookup_count(Repodata *data, Id solvid, Id keyname)
+{
+  unsigned char *dp;
+  Repokey *key;
+  unsigned int cnt = 0;
+
+  dp = find_key_data(data, solvid, keyname, &key);
+  if (!dp)
+    return 0;
+  switch (key->type)
+    {
+    case REPOKEY_TYPE_IDARRAY:
+    case REPOKEY_TYPE_REL_IDARRAY:
+      for (cnt = 1; (*dp & 0xc0) != 0; dp++)
+       if ((*dp & 0xc0) == 0x40)
+         cnt++;
+      return cnt;
+    case REPOKEY_TYPE_FIXARRAY:
+    case REPOKEY_TYPE_FLEXARRAY:
+      data_read_id(dp, (int *)&cnt);
+      return cnt;
+    case REPOKEY_TYPE_DIRSTRARRAY:
+      for (;;)
+       {
+         cnt++;
+         while (*dp & 0x80)
+           dp++;
+         if (!(*dp++ & 0x40))
+           return cnt;
+         dp += strlen((const char *)dp) + 1;
+       }
+    case REPOKEY_TYPE_DIRNUMNUMARRAY:
+      for (;;)
+       {
+         cnt++;
+         while (*dp++ & 0x80)
+           ;
+         while (*dp++ & 0x80)
+           ;
+         while (*dp & 0x80)
+           dp++;
+         if (!(*dp++ & 0x40))
+           return cnt;
+       }
+      default:
+       break;
+    }
+  return 1;
+}
+
 /* highly specialized function to speed up fileprovides adding.
  * - repodata must be available
  * - solvid must be >= data->start and < data->end
index f204e34..7dd5259 100644 (file)
@@ -229,6 +229,7 @@ int repodata_lookup_void(Repodata *data, Id solvid, Id keyname);
 const unsigned char *repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep);
 int repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q);
 const void *repodata_lookup_binary(Repodata *data, Id solvid, Id keyname, int *lenp);
+unsigned int repodata_lookup_count(Repodata *data, Id solvid, Id keyname);     /* internal */
 
 /* internal, used in fileprovides code */
 const unsigned char *repodata_lookup_packed_dirstrarray(Repodata *data, Id solvid, Id keyname);
index f735e5d..6b1432f 100644 (file)
@@ -613,7 +613,7 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
        }
       else
        {
-         Id *qele;
+         Id *qele, d;
          int qcnt;
 
          qele = bq.elements + i;
@@ -653,7 +653,17 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
              break;
          if (j < qcnt)
            continue;
-         addpkgrule(solv, qele[0], 0, pool_ids2whatprovides(pool, qele + 1, qcnt - 1), type, dep);
+         d = pool_ids2whatprovides(pool, qele + 1, qcnt - 1);
+         if (solv->ruleinfoq && qele[0] != p)
+           {
+             int oldcount = solv->ruleinfoq->count;
+             addpkgrule(solv, qele[0], 0, d, type, dep);
+             /* fixup from element of ruleinfo */
+             if (solv->ruleinfoq->count > oldcount)
+               solv->ruleinfoq->elements[oldcount + 1] = p;
+           }
+         else
+           addpkgrule(solv, qele[0], 0, d, type, dep);
          if (m)
            for (j = 0; j < qcnt; j++)
              if (qele[j] > 0 && !MAPTST(m, qele[j]))
@@ -2729,7 +2739,8 @@ addpkgruleinfo(Solver *solv, Id p, Id p2, Id d, int type, Id dep)
          if (*odp)
            return;
        }
-      if (p < 0 && pool->whatprovidesdata[d] < 0 && type == SOLVER_RULE_PKG_CONFLICTS)
+      /* set p2 for multiversion conflicts */
+      if (p < 0 && pool->whatprovidesdata[d] < 0 && pool->whatprovidesdata[d + 1] >= 0 && type == SOLVER_RULE_PKG_CONFLICTS)
        p2 = pool->whatprovidesdata[d];
     }
   else
index 474e6f5..181d9bc 100644 (file)
@@ -323,6 +323,12 @@ solvable_lookup_checksum(Solvable *s, Id keyname, Id *typep)
   return chk ? pool_bin2hex(s->repo->pool, chk, solv_chksum_len(*typep)) : 0;
 }
 
+unsigned int
+solvable_lookup_count(Solvable *s, Id keyname)
+{
+  return s->repo ? repo_lookup_count(s->repo, s - s->repo->pool->solvables, keyname) : 0;
+}
+
 static inline const char *
 evrid2vrstr(Pool *pool, Id evrid)
 {
index 7788e7c..0298db4 100644 (file)
@@ -64,6 +64,7 @@ const unsigned char *solvable_lookup_bin_checksum(Solvable *s, Id keyname, Id *t
 const char *solvable_lookup_checksum(Solvable *s, Id keyname, Id *typep);
 int solvable_lookup_idarray(Solvable *s, Id keyname, Queue *q);
 int solvable_lookup_deparray(Solvable *s, Id keyname, Queue *q, Id marker);
+unsigned int solvable_lookup_count(Solvable *s, Id keyname);   /* internal */
 
 /* setter functions */
 void solvable_set_id(Solvable *s, Id keyname, Id id);
diff --git a/win32/config.h b/win32/config.h
new file mode 100644 (file)
index 0000000..68eca63
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef _WIN32
+    #ifdef SOLV_STATIC_LIB
+        #define SOLV_API
+    #else
+        #ifdef SOLV_EXPORTS
+            #define SOLV_API __declspec(dllexport)
+        #else
+            #define SOLV_API __declspec(dllimport)
+        #endif
+    #endif
+#else
+    #define SOLV_API
+#endif
\ No newline at end of file
index 1e7e451..c4fc964 100644 (file)
@@ -5,8 +5,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-char *optarg;
-int optind=1, opterr=1, optopt, __optpos, __optreset=0;
+#include "config.h"
+
+SOLV_API char *optarg;
+SOLV_API int optind=1, opterr=1, optopt, __optpos, __optreset=0;
 
 #define optpos __optpos
 
index 35cbd35..861ff0b 100644 (file)
@@ -5,9 +5,12 @@
 extern "C" {
 #endif
 
+#include "config.h"
+
 int getopt(int, char * const [], const char *);
-extern char *optarg;
-extern int optind, opterr, optopt, optreset;
+
+SOLV_API extern char *optarg;
+SOLV_API extern int optind, opterr, optopt, optreset;
 
 struct option {
        const char *name;