summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:49:16 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:49:16 +0900
commit6a68988035ea989055076d81b7ab53c7015c8c32 (patch)
tree882953ab11585f025ce133c8ad5a281eb4857a80
parentcbc3c6a32d29006dda50336e30b42c25f5ca7454 (diff)
downloadlibsolv-6a68988035ea989055076d81b7ab53c7015c8c32.tar.gz
libsolv-6a68988035ea989055076d81b7ab53c7015c8c32.tar.bz2
libsolv-6a68988035ea989055076d81b7ab53c7015c8c32.zip
Imported Upstream version 0.7.12upstream/0.7.12
-rw-r--r--CMakeLists.txt7
-rw-r--r--NEWS7
-rw-r--r--VERSION.cmake2
-rw-r--r--ext/repo_conda.c117
-rw-r--r--ext/repo_updateinfoxml.c4
-rw-r--r--ext/solv_xfopen.c10
-rw-r--r--package/libsolv.changes6
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/knownid.h1
-rw-r--r--src/policy.c10
-rw-r--r--src/repo.c138
-rw-r--r--src/repo.h1
-rw-r--r--src/repodata.c51
-rw-r--r--src/repodata.h1
-rw-r--r--src/rules.c17
-rw-r--r--src/solvable.c6
-rw-r--r--src/solvable.h1
-rw-r--r--win32/config.h13
-rw-r--r--win32/getopt.c6
-rw-r--r--win32/getopt.h7
20 files changed, 334 insertions, 83 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1ada00..347bb0d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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
--- 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:
diff --git a/VERSION.cmake b/VERSION.cmake
index 180eda5..ffa76f3 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1")
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "11")
+SET(LIBSOLV_PATCH "12")
diff --git a/ext/repo_conda.c b/ext/repo_conda.c
index 9352b71..f58da0f 100644
--- a/ext/repo_conda.c
+++ b/ext/repo_conda.c
@@ -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);
diff --git a/ext/repo_updateinfoxml.c b/ext/repo_updateinfoxml.c
index 5b980a1..36d76b5 100644
--- a/ext/repo_updateinfoxml.c
+++ b/ext/repo_updateinfoxml.c
@@ -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);
diff --git a/ext/solv_xfopen.c b/ext/solv_xfopen.c
index 9aab68b..4bb4628 100644
--- a/ext/solv_xfopen.c
+++ b/ext/solv_xfopen.c
@@ -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)
diff --git a/package/libsolv.changes b/package/libsolv.changes
index 253784b..caccbeb 100644
--- a/package/libsolv.changes
+++ b/package/libsolv.changes
@@ -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
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6abb3ad..bbf30ba 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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})
diff --git a/src/knownid.h b/src/knownid.h
index 96c9adf..4c1730b 100644
--- a/src/knownid.h
+++ b/src/knownid.h
@@ -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)
diff --git a/src/policy.c b/src/policy.c
index 10a2c4d..fe8d55e 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -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);
diff --git a/src/repo.c b/src/repo.c
index da40219..45e8681 100644
--- a/src/repo.c
+++ b/src/repo.c
@@ -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;
}
}
diff --git a/src/repo.h b/src/repo.h
index 9a5e981..b503431 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -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);
diff --git a/src/repodata.c b/src/repodata.c
index 3cae0fe..0580cff 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -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
diff --git a/src/repodata.h b/src/repodata.h
index f204e34..7dd5259 100644
--- a/src/repodata.h
+++ b/src/repodata.h
@@ -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);
diff --git a/src/rules.c b/src/rules.c
index f735e5d..6b1432f 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -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
diff --git a/src/solvable.c b/src/solvable.c
index 474e6f5..181d9bc 100644
--- a/src/solvable.c
+++ b/src/solvable.c
@@ -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)
{
diff --git a/src/solvable.h b/src/solvable.h
index 7788e7c..0298db4 100644
--- a/src/solvable.h
+++ b/src/solvable.h
@@ -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
index 0000000..68eca63
--- /dev/null
+++ b/win32/config.h
@@ -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
diff --git a/win32/getopt.c b/win32/getopt.c
index 1e7e451..c4fc964 100644
--- a/win32/getopt.c
+++ b/win32/getopt.c
@@ -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
diff --git a/win32/getopt.h b/win32/getopt.h
index 35cbd35..861ff0b 100644
--- a/win32/getopt.h
+++ b/win32/getopt.h
@@ -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;