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:
Juan RP 2011-01-26 18:05:43 +01:00
parent bc259ae720
commit f06a605854
4 changed files with 153 additions and 20 deletions

21
NEWS
View File

@ -1,5 +1,12 @@
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
function callback to update progress while unpacking binary packages
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
to find the newest version found in all registered repositories.
* Improved package dependency sorting algorithm that uses less memory
and as bonus sorts all packages in the way they should be (previously
the sorting was a bit different for packages with no run-time dependencies).
* Improved package dependency sorting algorithm that uses less memory,
it is 15% faster approximately and as bonus sorts all packages in the way
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
anymore with previous versions. ABI will be respected once the API
has been stabilized, but not for now.
* Many structural changes in the API. Made some stuff private and changed
some function arguments in the API, the ABI is not compatible anymore with
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):

View File

@ -53,7 +53,7 @@
* @def XBPS_RELVER
* Current library release date.
*/
#define XBPS_RELVER "20110125"
#define XBPS_RELVER "20110126"
/**
* @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,
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.
*

View File

@ -233,6 +233,37 @@ out:
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
xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
const char *key,
@ -255,10 +286,17 @@ xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
break;
}
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) {
errno = ENOENT;
return NULL;
}
}
return obj;
}
@ -285,19 +323,90 @@ xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
break;
}
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) {
errno = ENOENT;
return NULL;
}
}
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
xbps_find_string_in_array(prop_array_t array, const char *val)
{
prop_object_iterator_t iter;
prop_object_t obj;
bool found = false;
assert(array != NULL);
assert(val != NULL);
@ -307,17 +416,15 @@ xbps_find_string_in_array(prop_array_t array, const char *val)
return false;
while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (prop_object_type(obj) != PROP_TYPE_STRING)
continue;
assert(prop_object_type(obj) == PROP_TYPE_STRING);
if (prop_string_equals_cstring(obj, val)) {
prop_object_iterator_release(iter);
return true;
found = true;
break;
}
}
prop_object_iterator_release(iter);
return false;
return found;
}
prop_object_iterator_t

View File

@ -262,9 +262,6 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
errno = 0;
return 0;
}
xbps_dbg_printf("Didn't find '%s' (%s)\n",
rpf->pattern, rpi->rpi_uri);
/* Not found */
errno = ENOENT;
return 0;