Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm/deps.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/deps.c')
-rw-r--r--lib/libalpm/deps.c176
1 files changed, 91 insertions, 85 deletions
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 7bb15d08..ee95c897 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -43,7 +43,7 @@ void _alpm_dep_free(pmdepend_t *dep)
FREE(dep);
}
-pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep,
+static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep,
const char *causingpkg)
{
pmdepmissing_t *miss;
@@ -67,6 +67,18 @@ void _alpm_depmiss_free(pmdepmissing_t *miss)
FREE(miss);
}
+/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */
+static int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2)
+{
+ alpm_list_t *i;
+ for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) {
+ if(_alpm_depcmp(pkg2, i->data)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* Convert a list of pmpkg_t * to a graph structure,
* with a edge for each dependency.
* Returns a list of vertices (one vertex = one package)
@@ -192,13 +204,37 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
return newtargs;
}
-pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
+static int no_dep_version(void)
+{
+ int flags = alpm_trans_get_flags();
+ return flags != -1 && (flags & PM_TRANS_FLAG_NODEPVERSION);
+}
+
+static pmdepend_t *filtered_depend(pmdepend_t *dep, int nodepversion)
+{
+ if(nodepversion) {
+ pmdepend_t *newdep = _alpm_dep_dup(dep);
+ ASSERT(newdep, return dep);
+ newdep->mod = PM_DEP_MOD_ANY;
+ dep = newdep;
+ }
+ return dep;
+}
+
+static void release_filtered_depend(pmdepend_t *dep, int nodepversion)
+{
+ if(nodepversion) {
+ free(dep);
+ }
+}
+
+static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
{
alpm_list_t *i;
for(i = pkgs; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = i->data;
- if(_alpm_depcmp_tolerant(pkg, dep)) {
+ if(_alpm_depcmp(pkg, dep)) {
return pkg;
}
}
@@ -214,7 +250,7 @@ pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
{
pmdepend_t *dep = _alpm_splitdep(depstring);
- pmpkg_t *pkg = _alpm_find_dep_satisfier(pkgs, dep);
+ pmpkg_t *pkg = find_dep_satisfier(pkgs, dep);
_alpm_dep_free(dep);
return pkg;
}
@@ -233,6 +269,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
alpm_list_t *i, *j;
alpm_list_t *targets, *dblist = NULL, *modified = NULL;
alpm_list_t *baddeps = NULL;
+ int nodepversion;
ALPM_LOG_FUNC;
@@ -247,6 +284,8 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
}
alpm_list_free(targets);
+ nodepversion = no_dep_version();
+
/* look for unsatisfied dependencies of the upgrade list */
for(i = upgrade; i; i = i->next) {
pmpkg_t *tp = i->data;
@@ -255,19 +294,21 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
pmdepend_t *depend = j->data;
+ depend = filtered_depend(depend, nodepversion);
/* 1. we check the upgrade list */
/* 2. we check database for untouched satisfying packages */
- if(!_alpm_find_dep_satisfier(upgrade, depend) &&
- !_alpm_find_dep_satisfier(dblist, depend)) {
+ if(!find_dep_satisfier(upgrade, depend) &&
+ !find_dep_satisfier(dblist, depend)) {
/* Unsatisfied dependency in the upgrade list */
pmdepmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
missdepstring, alpm_pkg_get_name(tp));
free(missdepstring);
- miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend, NULL);
+ miss = depmiss_new(alpm_pkg_get_name(tp), depend, NULL);
baddeps = alpm_list_add(baddeps, miss);
}
+ release_filtered_depend(depend, nodepversion);
}
}
@@ -278,21 +319,23 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
pmpkg_t *lp = i->data;
for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
pmdepend_t *depend = j->data;
- pmpkg_t *causingpkg = _alpm_find_dep_satisfier(modified, depend);
+ depend = filtered_depend(depend, nodepversion);
+ pmpkg_t *causingpkg = find_dep_satisfier(modified, depend);
/* we won't break this depend, if it is already broken, we ignore it */
/* 1. check upgrade list for satisfiers */
/* 2. check dblist for satisfiers */
if(causingpkg &&
- !_alpm_find_dep_satisfier(upgrade, depend) &&
- !_alpm_find_dep_satisfier(dblist, depend)) {
+ !find_dep_satisfier(upgrade, depend) &&
+ !find_dep_satisfier(dblist, depend)) {
pmdepmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
missdepstring, alpm_pkg_get_name(lp));
free(missdepstring);
- miss = _alpm_depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg));
+ miss = depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg));
baddeps = alpm_list_add(baddeps, miss);
}
+ release_filtered_depend(depend, nodepversion);
}
}
}
@@ -324,18 +367,10 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod,
return equal;
}
-/* nodepversion: skip version checking */
-static int _depcmp(pmpkg_t *pkg, pmdepend_t *dep, int nodepversion)
+int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
{
alpm_list_t *i;
int satisfy = 0;
- int depmod;
-
- if(nodepversion) {
- depmod = PM_DEP_MOD_ANY;
- } else {
- depmod = dep->mod;
- }
/* check (pkg->name, pkg->version) */
if(pkg->name_hash && dep->name_hash
@@ -343,7 +378,7 @@ static int _depcmp(pmpkg_t *pkg, pmdepend_t *dep, int nodepversion)
/* skip more expensive checks */
} else {
satisfy = (strcmp(pkg->name, dep->name) == 0
- && dep_vercmp(pkg->version, depmod, dep->version));
+ && dep_vercmp(pkg->version, dep->mod, dep->version));
if(satisfy) {
return satisfy;
}
@@ -355,7 +390,7 @@ static int _depcmp(pmpkg_t *pkg, pmdepend_t *dep, int nodepversion)
const char *provver = strchr(provision, '=');
if(provver == NULL) { /* no provision version */
- satisfy = (depmod == PM_DEP_MOD_ANY
+ satisfy = (dep->mod == PM_DEP_MOD_ANY
&& strcmp(provision, dep->name) == 0);
} else {
/* This is a bit tricker than the old code for performance reasons. To
@@ -367,32 +402,13 @@ static int _depcmp(pmpkg_t *pkg, pmdepend_t *dep, int nodepversion)
provver += 1;
satisfy = (strlen(dep->name) == namelen
&& strncmp(provision, dep->name, namelen) == 0
- && dep_vercmp(provver, depmod, dep->version));
+ && dep_vercmp(provver, dep->mod, dep->version));
}
}
return satisfy;
}
-/* tolerant : respects NODEPVERSION flag */
-int _alpm_depcmp_tolerant(pmpkg_t *pkg, pmdepend_t *dep)
-{
- int nodepversion = 0;
- int flags = alpm_trans_get_flags();
-
- if (flags != -1) {
- nodepversion = flags & PM_TRANS_FLAG_NODEPVERSION;
- }
-
- return _depcmp(pkg, dep, nodepversion);
-}
-
-/* strict : ignores NODEPVERSION flag */
-int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
-{
- return _depcmp(pkg, dep, 0);
-}
-
pmdepend_t *_alpm_splitdep(const char *depstring)
{
pmdepend_t *depend;
@@ -526,28 +542,6 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)
}
}
-/** Find a package satisfying a specified dependency.
- * First look for a literal, going through each db one by one. Then look for
- * providers. The first satisfier found is returned.
- * The dependency can include versions with depmod operators.
- * @param dbs an alpm_list_t* of pmdb_t where the satisfier will be searched
- * @param depstring package or provision name, versioned or not
- * @return a pmpkg_t* satisfying depstring
- */
-pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstring)
-{
- pmdepend_t *dep;
- pmpkg_t *pkg;
-
- ASSERT(dbs, return NULL);
-
- dep = _alpm_splitdep(depstring);
- ASSERT(dep, return NULL);
- pkg = _alpm_resolvedep(dep, dbs, NULL, 1);
- _alpm_dep_free(dep);
- return pkg;
-}
-
/**
* helper function for resolvedeps: search for dep satisfier in dbs
*
@@ -560,7 +554,7 @@ pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstri
* an error code without prompting
* @return the resolved package
**/
-pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
+static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
alpm_list_t *excluding, int prompt)
{
alpm_list_t *i, *j;
@@ -572,7 +566,7 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
/* 1. literals */
for(i = dbs; i; i = i->next) {
pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
- if(pkg && _alpm_depcmp_tolerant(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
+ if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
int install = 0;
if (prompt) {
@@ -593,7 +587,7 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
for(i = dbs; i; i = i->next) {
for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) {
pmpkg_t *pkg = j->data;
- if(_alpm_depcmp_tolerant(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&
+ if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&
!_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
int install = 0;
@@ -650,7 +644,30 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
return NULL;
}
-/* Computes resolvable dependencies for a given package and adds that package
+/** Find a package satisfying a specified dependency.
+ * First look for a literal, going through each db one by one. Then look for
+ * providers. The first satisfier found is returned.
+ * The dependency can include versions with depmod operators.
+ * @param dbs an alpm_list_t* of pmdb_t where the satisfier will be searched
+ * @param depstring package or provision name, versioned or not
+ * @return a pmpkg_t* satisfying depstring
+ */
+pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstring)
+{
+ pmdepend_t *dep;
+ pmpkg_t *pkg;
+
+ ASSERT(dbs, return NULL);
+
+ dep = _alpm_splitdep(depstring);
+ ASSERT(dep, return NULL);
+ pkg = resolvedep(dep, dbs, NULL, 1);
+ _alpm_dep_free(dep);
+ return pkg;
+}
+
+/**
+ * Computes resolvable dependencies for a given package and adds that package
* and those resolvable dependencies to a list.
*
* @param localpkgs is the list of local packages
@@ -704,16 +721,16 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
pmdepend_t *missdep = alpm_miss_get_dep(miss);
/* check if one of the packages in the [*packages] list already satisfies
* this dependency */
- if(_alpm_find_dep_satisfier(*packages, missdep)) {
+ if(find_dep_satisfier(*packages, missdep)) {
_alpm_depmiss_free(miss);
continue;
}
/* check if one of the packages in the [preferred] list already satisfies
* this dependency */
- pmpkg_t *spkg = _alpm_find_dep_satisfier(preferred, missdep);
+ pmpkg_t *spkg = find_dep_satisfier(preferred, missdep);
if(!spkg) {
/* find a satisfier package in the given repositories */
- spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, 0);
+ spkg = resolvedep(missdep, dbs_sync, *packages, 0);
}
if(!spkg) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
@@ -746,18 +763,6 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
return ret;
}
-/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */
-int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2)
-{
- alpm_list_t *i;
- for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) {
- if(_alpm_depcmp_tolerant(pkg2, i->data)) {
- return 1;
- }
- }
- return 0;
-}
-
const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss)
{
ALPM_LOG_FUNC;
@@ -825,7 +830,8 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
*/
char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
{
- char *name, *opr, *ver, *str = NULL;
+ const char *name, *opr, *ver;
+ char *str;
size_t len;
ALPM_LOG_FUNC;
@@ -863,7 +869,7 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
break;
}
- if(dep->version) {
+ if(dep->mod != PM_DEP_MOD_ANY && dep->version) {
ver = dep->version;
} else {
ver = "";