From 33d6d2e166e90c10a41575725b4b4492d5c92763 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Fri, 15 Jul 2011 18:22:58 +0200 Subject: [PATCH] libxbps: API/ABI break changes to fix issues with virtual packages. Please see the NEWS file for info about this commit. --- NEWS | 13 ++- bin/xbps-repo/index.c | 9 -- include/xbps_api.h | 48 +++++++--- include/xbps_api_impl.h | 21 +++-- lib/package_orphans.c | 2 +- lib/package_requiredby.c | 4 +- lib/plist_find.c | 187 ++++++++++++++++++++++--------------- lib/repository_finddeps.c | 3 +- lib/repository_pool.c | 53 +++-------- lib/transaction_sortdeps.c | 8 +- lib/util.c | 3 +- 11 files changed, 198 insertions(+), 153 deletions(-) diff --git a/NEWS b/NEWS index 45c5e845..b75f73f7 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,15 @@ -xbps-0.9.1 (???): +xbps-0.10.0 (???): + + * libxbps: revamped virtual package handling. The public API find + functions (xbps_find_pkg_*) don't know anything about virtual packages. + To find virtual packages the xbps_find_virtualpkg_* functions must be + used instead of the "classic" ones. + + * libxbps: the xbps_find_foo_in_array functions have been renamed + to xbps_match_foo_in_array because its task is only matching against + the provided package name, package pattern or string. + +xbps-0.9.1 (2011-07-15): * libxbps: xbps_repository_pool no longer loops forever if a package index plist file cannot be fetched due to network problems, or diff --git a/bin/xbps-repo/index.c b/bin/xbps-repo/index.c index f50eb203..0379a7ad 100644 --- a/bin/xbps-repo/index.c +++ b/bin/xbps-repo/index.c @@ -203,15 +203,6 @@ add_binpkg_to_index(prop_dictionary_t idxdict, goto out; } } else if (curpkgd) { - /* - * Ignore packages providing virtual packages greater than or - * equal than current package. - */ - if (xbps_find_virtual_pkg_in_dict(curpkgd, pkgname, false)) { - prop_object_release(newpkgd); - rv = EEXIST; - goto out; - } prop_dictionary_get_cstring_nocopy(curpkgd, "version", ®ver); if (xbps_cmpver(version, regver) <= 0) { xbps_warn_printf("skipping %s. %s-%s already " diff --git a/include/xbps_api.h b/include/xbps_api.h index 664bc8de..1927a0ce 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -55,11 +55,16 @@ */ #define XBPS_PKGINDEX_VERSION "1.2" +#define XBPS_API_VERSION "20110715" +#define XBPS_VERSION "0.10.0" + /** * @def XBPS_RELVER * Current library release date. */ -#define XBPS_RELVER "API: 20110714 INDEX: " XBPS_PKGINDEX_VERSION +#define XBPS_RELVER "XBPS: " XBPS_VERSION \ + " API: " XBPS_API_VERSION \ + " INDEX: " XBPS_PKGINDEX_VERSION /** * @def XBPS_META_PATH @@ -607,19 +612,36 @@ prop_dictionary_t xbps_find_pkg_dict_from_plist_by_pattern(const char *plist, prop_dictionary_t xbps_find_pkg_dict_installed(const char *str, bool bypattern); + /** - * Finds a virtual package by looking at package's dictionary by - * using a package name or a package pattern. + * Finds a virtual package's dictionary searching in the registered packages + * database by using a package name or a package pattern. + * + * @param[in] str Virtual package name or package pattern to match. + * @param[in] bypattern Set it to true to find the package dictionary + * by using a package pattern. If false, \a str is assumed to be a package name. + * + * @return The virtual package's dictionary on success, NULL otherwise and + * errno is set appropiately. Returned dictionary is copied via + * prop_dictionary_copy(), which means that caller is responsible to + * release the object with prop_object_release() when done. + */ +prop_dictionary_t xbps_find_virtualpkg_dict_installed(const char *str, + bool bypattern); + +/** + * Match a virtual package name or pattern by looking at package's + * dictionary "provides" array object. * * @param[in] pkgd Package dictionary. - * @param[in] str Virtual package name or package pattern. + * @param[in] str Virtual package name or package pattern to match. * @param[in] bypattern If true, \a str should be a package name, * otherwise it should be a package pattern. * - * @return True if package dictionary matches the virtual package - * name or pattern, false otherwise. + * @return True if \a str matches a virtual package in \a pkgd, false + * otherwise. */ -bool xbps_find_virtual_pkg_in_dict(prop_dictionary_t pkgd, +bool xbps_match_virtual_pkg_in_dict(prop_dictionary_t pkgd, const char *str, bool bypattern); @@ -646,34 +668,34 @@ prop_dictionary_t xbps_find_pkg_in_array_by_pattern(prop_array_t array, const char *pattern); /** - * Finds a package name matching an string object in a proplib array. + * Match a package name in the specified array of strings. * * @param[in] array The proplib array where to look for. * @param[in] pkgname The package name to match. * * @return true on success, false otherwise and errno is set appropiately. */ -bool xbps_find_pkgname_in_array(prop_array_t array, const char *pkgname); +bool xbps_match_pkgname_in_array(prop_array_t array, const char *pkgname); /** - * Finds a package pattern matching an string object in a proplib array. + * Match a package pattern in the specified array of strings. * * @param[in] array The proplib array where to look for. * @param[in] pattern The package pattern to match. * * @return true on success, false otherwise and errno is set appropiately. */ -bool xbps_find_pkgpattern_in_array(prop_array_t array, const char *pattern); +bool xbps_match_pkgpattern_in_array(prop_array_t array, const char *pattern); /** - * Finds a string matching an object in a proplib array. + * Match a string (exact match) in the specified array of strings. * * @param[in] array The proplib array where to look for. * @param[in] val The value of string to match. * * @return true on success, false otherwise and errno is set appropiately. */ -bool xbps_find_string_in_array(prop_array_t array, const char *val); +bool xbps_match_string_in_array(prop_array_t array, const char *val); /** * Gets a proplib object iterator associated with an array, contained diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index 6a7afc04..8b95f124 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -181,13 +181,22 @@ int HIDDEN xbps_repository_pkg_replaces(prop_dictionary_t, * From lib/plist_find.c */ prop_dictionary_t HIDDEN - xbps_find_virtualpkg_user_in_dict_by_name(prop_dictionary_t, - const char *, - const char *); + xbps_find_virtualpkg_in_dict_by_name(prop_dictionary_t, + const char *, + const char *); prop_dictionary_t HIDDEN - xbps_find_virtualpkg_user_in_dict_by_pattern(prop_dictionary_t, - const char *, - const char *); + xbps_find_virtualpkg_in_dict_by_pattern(prop_dictionary_t, + const char *, + const char *); + +prop_dictionary_t HIDDEN + xbps_find_virtualpkg_conf_in_dict_by_name(prop_dictionary_t, + const char *, + const char *); +prop_dictionary_t HIDDEN + xbps_find_virtualpkg_conf_in_dict_by_pattern(prop_dictionary_t, + const char *, + const char *); __END_DECLS diff --git a/lib/package_orphans.c b/lib/package_orphans.c index 7526e27b..6d9f7480 100644 --- a/lib/package_orphans.c +++ b/lib/package_orphans.c @@ -111,7 +111,7 @@ find_orphan_pkg(prop_object_t obj, void *arg, bool *loop_done) for (i = 0; i < prop_array_count(od->orphans_user); i++) { prop_array_get_cstring_nocopy(od->orphans_user, i, &curpkgname); - if (xbps_find_pkgname_in_array(reqby, curpkgname)) { + if (xbps_match_pkgname_in_array(reqby, curpkgname)) { prop_array_add(od->array, obj); return 0; } diff --git a/lib/package_requiredby.c b/lib/package_requiredby.c index a2dccd54..cd51999a 100644 --- a/lib/package_requiredby.c +++ b/lib/package_requiredby.c @@ -44,7 +44,7 @@ add_pkg_into_reqby(prop_dictionary_t pkgd, const char *pkgver) return ENOMEM; } - if (xbps_find_string_in_array(reqby, pkgver)) { + if (xbps_match_string_in_array(reqby, pkgver)) { if (alloc) prop_object_release(reqby); @@ -92,7 +92,7 @@ remove_pkg_from_reqby(prop_object_t obj, void *arg, bool *loop_done) if (reqby == NULL || prop_array_count(reqby) == 0) return 0; - if (xbps_find_pkgname_in_array(reqby, pkgname)) + if (xbps_match_pkgname_in_array(reqby, pkgname)) if (!xbps_remove_pkgname_from_array(reqby, pkgname)) return EINVAL; diff --git a/lib/plist_find.c b/lib/plist_find.c index 595bb80e..64910948 100644 --- a/lib/plist_find.c +++ b/lib/plist_find.c @@ -39,73 +39,28 @@ * These functions manipulate plist files and objects shared by almost * all library functions. */ -static prop_dictionary_t -find_pkg_dict_from_plist(const char *plist, - const char *key, - const char *str, - bool bypattern) -{ - prop_dictionary_t dict, obj, res; - - assert(plist != NULL); - assert(str != NULL); - - dict = prop_dictionary_internalize_from_zfile(plist); - if (dict == NULL) { - xbps_dbg_printf("cannot internalize %s for pkg %s: %s", - plist, str, strerror(errno)); - return NULL; - } - if (bypattern) - obj = xbps_find_pkg_in_dict_by_pattern(dict, key, str); - else - obj = xbps_find_pkg_in_dict_by_name(dict, key, str); - - if (obj == NULL) { - prop_object_release(dict); - return NULL; - } - res = prop_dictionary_copy(obj); - prop_object_release(dict); - - return res; -} - -prop_dictionary_t -xbps_find_pkg_dict_from_plist_by_name(const char *plist, - const char *key, - const char *pkgname) -{ - return find_pkg_dict_from_plist(plist, key, pkgname, false); -} - -prop_dictionary_t -xbps_find_pkg_dict_from_plist_by_pattern(const char *plist, - const char *key, - const char *pattern) -{ - return find_pkg_dict_from_plist(plist, key, pattern, true); -} - bool -xbps_find_virtual_pkg_in_dict(prop_dictionary_t d, - const char *str, - bool bypattern) +xbps_match_virtual_pkg_in_dict(prop_dictionary_t d, + const char *str, + bool bypattern) { prop_array_t provides; bool found = false; if ((provides = prop_dictionary_get(d, "provides"))) { if (bypattern) - found = xbps_find_pkgpattern_in_array(provides, str); + found = xbps_match_pkgpattern_in_array(provides, str); else - found = xbps_find_pkgname_in_array(provides, str); + found = xbps_match_pkgname_in_array(provides, str); } return found; } static prop_dictionary_t -find_pkg_in_array(prop_array_t array, const char *str, bool bypattern) +find_pkg_in_array(prop_array_t array, + const char *str, + bool bypattern, + bool virtual) { prop_object_iterator_t iter; prop_object_t obj = NULL; @@ -136,11 +91,13 @@ find_pkg_in_array(prop_array_t array, const char *str, bool bypattern) if (strcmp(dpkgn, str) == 0) break; } + if (!virtual) + continue; /* * Finally check if package pattern matches * any virtual package version in dictionary. */ - if (xbps_find_virtual_pkg_in_dict(obj, str, bypattern)) + if (xbps_match_virtual_pkg_in_dict(obj, str, bypattern)) break; } prop_object_iterator_release(iter); @@ -148,19 +105,20 @@ find_pkg_in_array(prop_array_t array, const char *str, bool bypattern) errno = ENOENT; return NULL; } + return obj; } prop_dictionary_t xbps_find_pkg_in_array_by_name(prop_array_t array, const char *name) { - return find_pkg_in_array(array, name, false); + return find_pkg_in_array(array, name, false, false); } prop_dictionary_t xbps_find_pkg_in_array_by_pattern(prop_array_t array, const char *pattern) { - return find_pkg_in_array(array, pattern, true); + return find_pkg_in_array(array, pattern, true, false); } static const char * @@ -250,9 +208,11 @@ find_pkg_in_dict(prop_dictionary_t d, const char *key, const char *str, bool bypattern, - bool virtual) + bool virtual, + bool virtual_in_conf) { prop_array_t array; + prop_dictionary_t vpkgd; assert(d != NULL); assert(str != NULL); @@ -262,10 +222,13 @@ find_pkg_in_dict(prop_dictionary_t d, if (prop_object_type(array) != PROP_TYPE_ARRAY) return NULL; - if (virtual) - return find_virtualpkg_user_in_array(array, str, bypattern); + if (virtual_in_conf) { + vpkgd = find_virtualpkg_user_in_array(array, str, bypattern); + if (vpkgd != NULL) + return vpkgd; + } - return find_pkg_in_array(array, str, bypattern); + return find_pkg_in_array(array, str, bypattern, virtual); } prop_dictionary_t @@ -273,7 +236,7 @@ xbps_find_pkg_in_dict_by_name(prop_dictionary_t d, const char *key, const char *pkgname) { - return find_pkg_in_dict(d, key, pkgname, false, false); + return find_pkg_in_dict(d, key, pkgname, false, false, false); } prop_dictionary_t @@ -281,27 +244,87 @@ xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t d, const char *key, const char *pattern) { - return find_pkg_in_dict(d, key, pattern, true, false); + return find_pkg_in_dict(d, key, pattern, true, false, false); } prop_dictionary_t HIDDEN -xbps_find_virtualpkg_user_in_dict_by_name(prop_dictionary_t d, +xbps_find_virtualpkg_in_dict_by_name(prop_dictionary_t d, const char *key, const char *name) { - return find_pkg_in_dict(d, key, name, false, true); + return find_pkg_in_dict(d, key, name, false, true, false); } prop_dictionary_t HIDDEN -xbps_find_virtualpkg_user_in_dict_by_pattern(prop_dictionary_t d, +xbps_find_virtualpkg_in_dict_by_pattern(prop_dictionary_t d, const char *key, const char *pattern) { - return find_pkg_in_dict(d, key, pattern, true, true); + return find_pkg_in_dict(d, key, pattern, true, true, false); +} + +prop_dictionary_t HIDDEN +xbps_find_virtualpkg_conf_in_dict_by_name(prop_dictionary_t d, + const char *key, + const char *name) +{ + return find_pkg_in_dict(d, key, name, false, false, true); +} + +prop_dictionary_t HIDDEN +xbps_find_virtualpkg_conf_in_dict_by_pattern(prop_dictionary_t d, + const char *key, + const char *pattern) +{ + return find_pkg_in_dict(d, key, pattern, true, false, true); +} + +static prop_dictionary_t +find_pkg_dict_from_plist(const char *plist, + const char *key, + const char *str, + bool bypattern) +{ + prop_dictionary_t dict, obj, res; + + assert(plist != NULL); + assert(str != NULL); + + dict = prop_dictionary_internalize_from_zfile(plist); + if (dict == NULL) { + xbps_dbg_printf("cannot internalize %s for pkg %s: %s", + plist, str, strerror(errno)); + return NULL; + } + obj = find_pkg_in_dict(dict, key, str, bypattern, true, true); + if (obj == NULL) { + prop_object_release(dict); + return NULL; + } + res = prop_dictionary_copy(obj); + prop_object_release(dict); + + return res; } prop_dictionary_t -xbps_find_pkg_dict_installed(const char *str, bool bypattern) +xbps_find_pkg_dict_from_plist_by_name(const char *plist, + const char *key, + const char *pkgname) +{ + return find_pkg_dict_from_plist(plist, key, pkgname, false); +} + +prop_dictionary_t +xbps_find_pkg_dict_from_plist_by_pattern(const char *plist, + const char *key, + const char *pattern) +{ + return find_pkg_dict_from_plist(plist, key, pattern, true); +} + +static prop_dictionary_t +find_pkgd_installed(const char *str, bool bypattern, bool virtual) { const struct xbps_handle *xhp; prop_dictionary_t pkgd, rpkgd = NULL; @@ -314,7 +337,7 @@ xbps_find_pkg_dict_installed(const char *str, bool bypattern) return NULL; pkgd = find_pkg_in_dict(xhp->regpkgdb_dictionary, - "packages", str, bypattern, false); + "packages", str, bypattern, virtual, true); if (pkgd == NULL) return rpkgd; @@ -338,8 +361,20 @@ xbps_find_pkg_dict_installed(const char *str, bool bypattern) return rpkgd; } +prop_dictionary_t +xbps_find_pkg_dict_installed(const char *str, bool bypattern) +{ + return find_pkgd_installed(str, bypattern, false); +} + +prop_dictionary_t +xbps_find_virtualpkg_dict_installed(const char *str, bool bypattern) +{ + return find_pkgd_installed(str, bypattern, true); +} + static bool -find_string_in_array(prop_array_t array, const char *str, int mode) +match_string_in_array(prop_array_t array, const char *str, int mode) { prop_object_iterator_t iter; prop_object_t obj; @@ -389,19 +424,19 @@ find_string_in_array(prop_array_t array, const char *str, int mode) } bool -xbps_find_string_in_array(prop_array_t array, const char *str) +xbps_match_string_in_array(prop_array_t array, const char *str) { - return find_string_in_array(array, str, 0); + return match_string_in_array(array, str, 0); } bool -xbps_find_pkgname_in_array(prop_array_t array, const char *pkgname) +xbps_match_pkgname_in_array(prop_array_t array, const char *pkgname) { - return find_string_in_array(array, pkgname, 1); + return match_string_in_array(array, pkgname, 1); } bool -xbps_find_pkgpattern_in_array(prop_array_t array, const char *pattern) +xbps_match_pkgpattern_in_array(prop_array_t array, const char *pattern) { - return find_string_in_array(array, pattern, 2); + return match_string_in_array(array, pattern, 2); } diff --git a/lib/repository_finddeps.c b/lib/repository_finddeps.c index 19096271..8f665b82 100644 --- a/lib/repository_finddeps.c +++ b/lib/repository_finddeps.c @@ -326,8 +326,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ break; } free(pkgname); - if (xbps_find_virtual_pkg_in_dict(tmpd, - reqpkg, true)) { + if (xbps_match_virtual_pkg_in_dict(tmpd,reqpkg,true)) { /* * Check if required dependency is a virtual * package and is satisfied by an diff --git a/lib/repository_pool.c b/lib/repository_pool.c index cf14855c..e4683ca3 100644 --- a/lib/repository_pool.c +++ b/lib/repository_pool.c @@ -285,11 +285,11 @@ repo_find_virtualpkg_cb(struct repository_pool_index *rpi, void *arg, bool *done if (rpf->bypattern) { rpf->pkgd = - xbps_find_virtualpkg_user_in_dict_by_pattern(rpi->rpi_repod, + xbps_find_virtualpkg_conf_in_dict_by_pattern(rpi->rpi_repod, "packages", rpf->pattern); } else { rpf->pkgd = - xbps_find_virtualpkg_user_in_dict_by_name(rpi->rpi_repod, + xbps_find_virtualpkg_conf_in_dict_by_name(rpi->rpi_repod, "packages", rpf->pattern); } if (rpf->pkgd) { @@ -311,9 +311,19 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done) if (rpf->bypattern) { rpf->pkgd = xbps_find_pkg_in_dict_by_pattern(rpi->rpi_repod, "packages", rpf->pattern); + /* If no pkg exists matching pattern, look for virtual packages */ + if (rpf->pkgd == NULL) { + rpf->pkgd = xbps_find_virtualpkg_in_dict_by_pattern( + rpi->rpi_repod, "packages", rpf->pattern); + } } else { rpf->pkgd = xbps_find_pkg_in_dict_by_name(rpi->rpi_repod, "packages", rpf->pattern); + /* If no pkg exists matching pattern, look for virtual packages */ + if (rpf->pkgd == NULL) { + rpf->pkgd = xbps_find_virtualpkg_in_dict_by_name( + rpi->rpi_repod, "packages", rpf->pattern); + } } if (rpf->pkgd) { /* @@ -336,9 +346,8 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi, bool *done) { struct repo_pool_fpkg *rpf = arg; - prop_dictionary_t instpkgd, vpkgd; + prop_dictionary_t instpkgd; const char *instver, *repover; - char *vpattern = NULL; rpf->pkgd = xbps_find_pkg_in_dict_by_name(rpi->rpi_repod, "packages", rpf->pattern); @@ -369,42 +378,6 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi, errno = EEXIST; return 0; } - /* - * New package version is greater than current installed, but first - * check if this is a virtual package and it's set specifically - * in the configuration file. - */ - vpattern = xbps_xasprintf("%s>=0", rpf->pattern); - if (vpattern == NULL) - return EINVAL; - - vpkgd = xbps_find_virtualpkg_user_in_dict_by_pattern( - rpi->rpi_repod, "packages", vpattern); - if (vpkgd) { - /* - * Virtual package enabled in conf file and new - * version found. - */ - free(vpattern); - prop_dictionary_set_cstring(vpkgd, "repository", - rpi->rpi_uri); - *done = true; - errno = 0; - rpf->pkgfound = true; - return 0; - } else { - /* - * Virtual package not enabled in conf file but it's - * currently proviving the same virtual package that - * we are updating... ignore it. - */ - if (xbps_find_virtual_pkg_in_dict(rpf->pkgd, - vpattern, true)) { - free(vpattern); - return 0; - } - free(vpattern); - } /* * New package version found, exit from the loop. */ diff --git a/lib/transaction_sortdeps.c b/lib/transaction_sortdeps.c index 1c8f1435..0a0a3f1f 100644 --- a/lib/transaction_sortdeps.c +++ b/lib/transaction_sortdeps.c @@ -70,7 +70,7 @@ pkgdep_find(const char *name, const char *trans) } if (pd->d == NULL) continue; - if (xbps_find_virtual_pkg_in_dict(pd->d, name, false)) + if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) return pd; } @@ -93,7 +93,7 @@ pkgdep_find_idx(const char *name, const char *trans) } if (pd->d == NULL) continue; - if (xbps_find_virtual_pkg_in_dict(pd->d, name, false)) + if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) return idx; idx++; @@ -231,6 +231,10 @@ again: } curpkgd = xbps_find_pkg_in_dict_by_name(transd, "unsorted_deps", pkgnamedep); + if (curpkgd == NULL) { + curpkgd = xbps_find_virtualpkg_in_dict_by_name(transd, + "unsorted_deps", pkgnamedep); + } if (curpkgd == NULL) { free(pkgnamedep); rv = EINVAL; diff --git a/lib/util.c b/lib/util.c index 8e71a927..e7393c79 100644 --- a/lib/util.c +++ b/lib/util.c @@ -199,7 +199,8 @@ xbps_check_is_installed_pkg_by_pattern(const char *pattern) assert(pattern != NULL); - dict = xbps_find_pkg_dict_installed(pattern, true); + if ((dict = xbps_find_pkg_dict_installed(pattern, true)) == NULL) + dict = xbps_find_virtualpkg_dict_installed(pattern, true); if (dict == NULL) { if (errno == ENOENT) { errno = 0;