Implemented support for virtual packages.
The patch adds 150 lines approximately. It is implemented by modifying xbps_find_pkg_in_dict_by_name() and xbps_find_pkg_in_dict_by_pattern(). When no dictionary is returned if tries to find a virtual package by looking at the "provides" array object, if found.
This commit is contained in:
parent
bc259ae720
commit
f06a605854
21
NEWS
21
NEWS
@ -1,5 +1,12 @@
|
|||||||
xbps-0.8.0 (???):
|
xbps-0.8.0 (???):
|
||||||
|
|
||||||
|
* Added support for virtual packages. A virtual package is one that doesn't
|
||||||
|
exist in the repository, but other packages can provide it. A new array
|
||||||
|
in the package properties dictionary has been added to specify which
|
||||||
|
virtual packages the package supports. As an example, the `rsyslog'
|
||||||
|
package provides the virtual package `syslog-daemon-0'. Other packages
|
||||||
|
can depend in `syslog-daemon>=0' and `rsyslog' will satisfy the dependency.
|
||||||
|
|
||||||
* Merged the `progress_callback' branch that makes possible to specify a
|
* Merged the `progress_callback' branch that makes possible to specify a
|
||||||
function callback to update progress while unpacking binary packages
|
function callback to update progress while unpacking binary packages
|
||||||
and while fetching files. xbps-bin(8) now reports a percentage while
|
and while fetching files. xbps-bin(8) now reports a percentage while
|
||||||
@ -11,13 +18,15 @@ xbps-0.8.0 (???):
|
|||||||
found in the first repository registered in the pool. It can also be used
|
found in the first repository registered in the pool. It can also be used
|
||||||
to find the newest version found in all registered repositories.
|
to find the newest version found in all registered repositories.
|
||||||
|
|
||||||
* Improved package dependency sorting algorithm that uses less memory
|
* Improved package dependency sorting algorithm that uses less memory,
|
||||||
and as bonus sorts all packages in the way they should be (previously
|
it is 15% faster approximately and as bonus sorts all packages in the way
|
||||||
the sorting was a bit different for packages with no run-time dependencies).
|
they should be (previously the sorting was a bit different for packages
|
||||||
|
with no run-time dependencies).
|
||||||
|
|
||||||
* Hide implementation details in the API, so the ABI is not compatible
|
* Many structural changes in the API. Made some stuff private and changed
|
||||||
anymore with previous versions. ABI will be respected once the API
|
some function arguments in the API, the ABI is not compatible anymore with
|
||||||
has been stabilized, but not for now.
|
previous versions... anyway you shouldn't be using libxbps just yet.
|
||||||
|
The API documentation has been modified to stay in sync with reality.
|
||||||
|
|
||||||
xbps-0.7.3 (2011-01-16):
|
xbps-0.7.3 (2011-01-16):
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
* @def XBPS_RELVER
|
* @def XBPS_RELVER
|
||||||
* Current library release date.
|
* Current library release date.
|
||||||
*/
|
*/
|
||||||
#define XBPS_RELVER "20110125"
|
#define XBPS_RELVER "20110126"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def XBPS_META_PATH
|
* @def XBPS_META_PATH
|
||||||
@ -460,6 +460,26 @@ prop_dictionary_t xbps_find_pkg_from_plist(const char *plist,
|
|||||||
prop_dictionary_t xbps_find_pkg_dict_installed(const char *str,
|
prop_dictionary_t xbps_find_pkg_dict_installed(const char *str,
|
||||||
bool bypattern);
|
bool bypattern);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a package name matching an string object in a proplib array.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a package pattern matching an string object in a proplib array.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a string matching an object in a proplib array.
|
* Finds a string matching an object in a proplib array.
|
||||||
*
|
*
|
||||||
|
119
lib/plist.c
119
lib/plist.c
@ -233,6 +233,37 @@ out:
|
|||||||
return rpkgd;
|
return rpkgd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static prop_dictionary_t
|
||||||
|
find_virtual_pkg(prop_dictionary_t d,
|
||||||
|
const char *key,
|
||||||
|
const char *str,
|
||||||
|
bool bypattern)
|
||||||
|
{
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
prop_object_t obj;
|
||||||
|
prop_array_t provides;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if ((iter = xbps_get_array_iter_from_dict(d, key)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter))) {
|
||||||
|
if ((provides = prop_dictionary_get(obj, "provides")) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bypattern)
|
||||||
|
found = xbps_find_pkgpattern_in_array(provides, str);
|
||||||
|
else
|
||||||
|
found = xbps_find_pkgname_in_array(provides, str);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
|
xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
|
||||||
const char *key,
|
const char *key,
|
||||||
@ -255,10 +286,17 @@ xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prop_object_iterator_release(iter);
|
prop_object_iterator_release(iter);
|
||||||
|
if (obj == NULL) {
|
||||||
|
/*
|
||||||
|
* If a package couldn't be found by its name, try looking
|
||||||
|
* for a package providing a virtual package, i.e "provides".
|
||||||
|
*/
|
||||||
|
obj = find_virtual_pkg(dict, key, pkgname, false);
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -285,19 +323,90 @@ xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prop_object_iterator_release(iter);
|
prop_object_iterator_release(iter);
|
||||||
|
if (obj == NULL) {
|
||||||
|
/*
|
||||||
|
* If a package couldn't be found by a pattern, try looking
|
||||||
|
* for a package providing a virtual package pattern via
|
||||||
|
* "provides".
|
||||||
|
*/
|
||||||
|
obj = find_virtual_pkg(dict, key, pattern, true);
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
xbps_find_pkgname_in_array(prop_array_t array, const char *pkgname)
|
||||||
|
{
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
prop_object_t obj;
|
||||||
|
const char *pkgdep;
|
||||||
|
char *curpkgname;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
assert(array != NULL);
|
||||||
|
assert(pkgname != NULL);
|
||||||
|
|
||||||
|
iter = prop_array_iterator(array);
|
||||||
|
if (iter == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter))) {
|
||||||
|
assert(prop_object_type(obj) == PROP_TYPE_STRING);
|
||||||
|
pkgdep = prop_string_cstring_nocopy(obj);
|
||||||
|
curpkgname = xbps_get_pkg_name(pkgdep);
|
||||||
|
if (curpkgname == NULL)
|
||||||
|
break;
|
||||||
|
if (strcmp(curpkgname, pkgname) == 0) {
|
||||||
|
free(curpkgname);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(curpkgname);
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
xbps_find_pkgpattern_in_array(prop_array_t array, const char *pattern)
|
||||||
|
{
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
prop_object_t obj;
|
||||||
|
const char *curpkgdep;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
assert(array != NULL);
|
||||||
|
assert(pattern != NULL);
|
||||||
|
|
||||||
|
iter = prop_array_iterator(array);
|
||||||
|
if (iter == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter))) {
|
||||||
|
assert(prop_object_type(obj) == PROP_TYPE_STRING);
|
||||||
|
curpkgdep = prop_string_cstring_nocopy(obj);
|
||||||
|
if (xbps_pkgpattern_match(curpkgdep, __UNCONST(pattern))) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_find_string_in_array(prop_array_t array, const char *val)
|
xbps_find_string_in_array(prop_array_t array, const char *val)
|
||||||
{
|
{
|
||||||
prop_object_iterator_t iter;
|
prop_object_iterator_t iter;
|
||||||
prop_object_t obj;
|
prop_object_t obj;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
assert(array != NULL);
|
assert(array != NULL);
|
||||||
assert(val != NULL);
|
assert(val != NULL);
|
||||||
@ -307,17 +416,15 @@ xbps_find_string_in_array(prop_array_t array, const char *val)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
if (prop_object_type(obj) != PROP_TYPE_STRING)
|
assert(prop_object_type(obj) == PROP_TYPE_STRING);
|
||||||
continue;
|
|
||||||
if (prop_string_equals_cstring(obj, val)) {
|
if (prop_string_equals_cstring(obj, val)) {
|
||||||
prop_object_iterator_release(iter);
|
found = true;
|
||||||
return true;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_object_iterator_release(iter);
|
prop_object_iterator_release(iter);
|
||||||
|
|
||||||
return false;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_object_iterator_t
|
prop_object_iterator_t
|
||||||
|
@ -262,9 +262,6 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xbps_dbg_printf("Didn't find '%s' (%s)\n",
|
|
||||||
rpf->pattern, rpi->rpi_uri);
|
|
||||||
/* Not found */
|
/* Not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user