From 6a68988035ea989055076d81b7ab53c7015c8c32 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Fri, 27 Nov 2020 14:49:16 +0900 Subject: [PATCH 1/1] Imported Upstream version 0.7.12 --- CMakeLists.txt | 7 ++- NEWS | 7 +++ VERSION.cmake | 2 +- ext/repo_conda.c | 117 ++++++++++++++++++++++++++++++++++++++-- ext/repo_updateinfoxml.c | 4 +- ext/solv_xfopen.c | 10 +++- package/libsolv.changes | 6 +++ src/CMakeLists.txt | 12 ++++- src/knownid.h | 1 + src/policy.c | 10 +++- src/repo.c | 138 ++++++++++++++++++++++++++--------------------- src/repo.h | 1 + src/repodata.c | 51 ++++++++++++++++++ src/repodata.h | 1 + src/rules.c | 17 ++++-- src/solvable.c | 6 +++ src/solvable.h | 1 + win32/config.h | 13 +++++ win32/getopt.c | 6 ++- win32/getopt.h | 7 ++- 20 files changed, 334 insertions(+), 83 deletions(-) create mode 100644 win32/config.h 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 #include -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; -- 2.7.4