[pacman-dev] [patch] removedeps

Xavier shiningxc at gmail.com
Fri Jul 13 09:38:31 EDT 2007


On Thu, Jul 12, 2007 at 09:09:41PM +0200, ngaba at petra.hos.u-szeged.hu wrote:
> > Wouldn't it be better to use **list instead then ?
> AFAIK, if we'd use **list, that assumption could be dropped.
> Bye, ngaba
> 

I see, that's also the problem you had with your previous patch for
removedeps.
I took it back, and made a few changes, including usage of **targs instead of
targs. I also renamed removedeps to recursedeps, added an include_explicit
argument, and added some comments.
Does this look ok to you ?


>From e9ec64516957efb3eba4a9226ac52131636fa013 Mon Sep 17 00:00:00 2001
From: Chantry Xavier <shiningxc at gmail.com>
Date: Fri, 13 Jul 2007 15:30:37 +0200
Subject: [PATCH] libalpm/deps.c : fix for remove044 pactest.

Patch from Nagy that makes removedeps use alpm_depcmp.

I also renamed removedeps to recursedeps, as it can have
a more general usage, and added an include_explicit argument,
so we can control if packages explictly installed are added or not.

Signed-off-by: Chantry Xavier <shiningxc at gmail.com>
---
 lib/libalpm/deps.c   |  100 +++++++++++++++++++++++--------------------------
 lib/libalpm/deps.h   |    2 +-
 lib/libalpm/remove.c |   10 ++--
 3 files changed, 53 insertions(+), 59 deletions(-)

diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 591e5a8..fa99630 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -484,8 +484,10 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
 
 /* These parameters are messy.  We check if this package, given a list of
  * targets (and a db), is safe to remove.  We do NOT remove it if it is in the
- * target list */
-static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
+ * target list. We do not remove it either if the package was
+ * explictly installed, and include_explicit == 0 */
+static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,
+		int include_explicit)
 {
 	alpm_list_t *i;
 
@@ -493,13 +495,21 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
 		return(0);
 	}
 
-	/* see if it was explicitly installed */
-	if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
-		_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed",
-				alpm_pkg_get_name(pkg));
-		return(0);
+	if(!include_explicit) {
+		/* see if it was explicitly installed */
+		if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
+			_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed",
+					alpm_pkg_get_name(pkg));
+			return(0);
+		}
 	}
 
+	/* TODO: checkdeps could be used there, it handles multiple providers
+	 * better, but that also makes it slower.
+	 * Also this would require to first add the package to the targets list,
+	 * then call checkdeps with it, then remove the package from the targets list
+	 * if checkdeps detected it would break something */
+
 	/* see if other packages need it */
 	for(i = alpm_pkg_get_requiredby(pkg); i; i = i->next) {
 		pmpkg_t *reqpkg = _alpm_db_get_pkgfromcache(db, i->data);
@@ -512,71 +522,55 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
 	return(1);
 }
 
-/* return a new alpm_list_t target list containing all packages in the original
- * target list, as well as all their un-needed dependencies.  By un-needed,
- * I mean dependencies that are *only* required for packages in the target
- * list, so they can be safely removed.  This function is recursive.
+/* Adds un-needed dependencies in a list of packages
+ * By un-needed, I mean dependencies that are *only* required for packages in the target
+ * list, so they can be safely removed.
+ * @param targs pointer to a list of packages
+ * @param include_explicit if set to 0, then explictly installed packages are not added
  */
-alpm_list_t *_alpm_removedeps(pmdb_t *db, alpm_list_t *targs)
+void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit)
 {
 	alpm_list_t *i, *j, *k;
-	alpm_list_t *newtargs = targs;
 
 	ALPM_LOG_FUNC;
 
-	if(db == NULL) {
-		return(newtargs);
+	if(db == NULL || targs == NULL) {
+		return;
 	}
 
-	for(i = targs; i; i = i->next) {
-		pmpkg_t *pkg = i->data;
-		for(j = alpm_pkg_get_depends(pkg); j; j = j->next) {
-			pmdepend_t *depend = alpm_splitdep(j->data);
-			pmpkg_t *deppkg;
-			if(depend == NULL) {
-				continue;
-			}
-
-			deppkg = _alpm_db_get_pkgfromcache(db, depend->name);
-			if(deppkg == NULL) {
-				/* package not found... look for a provision instead */
-				alpm_list_t *provides = _alpm_db_whatprovides(db, depend->name);
-				if(!provides) {
-					/* Not found, that's fine, carry on */
-					_alpm_log(PM_LOG_DEBUG, "cannot find package \"%s\" or anything that provides it!", depend->name);
+	/* TODO: the while loop should be removed if we can assume
+	 * that alpm_list_add (or another function) adds to the end of the list,
+	 * and that the target list is topo sorted (by _alpm_sortbydeps()).
+	 */
+	int ready = 0;
+	while(!ready) {
+		ready = 1;
+		for(i = *targs; i; i = i->next) {
+			pmpkg_t *pkg = i->data;
+			for(j = alpm_pkg_get_depends(pkg); j; j = j->next) {
+				pmdepend_t *depend = alpm_splitdep(j->data);
+				if(depend == NULL) {
 					continue;
 				}
-				for(k = provides; k; k = k->next) {
-					pmpkg_t *provpkg = k->data;
-					if(can_remove_package(db, provpkg, newtargs)) {
-						pmpkg_t *pkg = _alpm_pkg_dup(provpkg);
-
-						_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets",
-								alpm_pkg_get_name(pkg));
+				for(k = _alpm_db_get_pkgcache(db); k; k = k->next) {
+					pmpkg_t *deppkg = k->data;
+					if(alpm_depcmp(deppkg,depend) 
+							&& can_remove_package(db, deppkg, *targs, include_explicit)) {
+						_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets", 
+								alpm_pkg_get_name(deppkg));
 
 						/* add it to the target list */
-						newtargs = alpm_list_add(newtargs, pkg);
-						newtargs = _alpm_removedeps(db, newtargs);
+						*targs = alpm_list_add(*targs, _alpm_pkg_dup(deppkg));
+						ready = 0;
 					}
 				}
-				alpm_list_free(provides);
-			} else if(can_remove_package(db, deppkg, newtargs)) {
-				pmpkg_t *pkg = _alpm_pkg_dup(deppkg);
-
-				_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets",
-						alpm_pkg_get_name(pkg));
-
-				/* add it to the target list */
-				newtargs = alpm_list_add(newtargs, pkg);
-				newtargs = _alpm_removedeps(db, newtargs);
+				free(depend);
 			}
-			free(depend);
 		}
 	}
-
-	return(newtargs);
 }
 
+
 /* populates *list with packages that need to be installed to satisfy all
  * dependencies (recursive) for syncpkg
  *
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 2edbb50..f11a19a 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -58,7 +58,7 @@ int _alpm_depmiss_isin(pmdepmissing_t *needle, alpm_list_t *haystack);
 alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode);
 alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
                              alpm_list_t *packages);
-alpm_list_t *_alpm_removedeps(pmdb_t *db, alpm_list_t *targs);
+void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit);
 int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
                       alpm_list_t *list, alpm_list_t *trail, pmtrans_t *trans,
 											alpm_list_t **data);
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 57e452d..9876f41 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -131,11 +131,6 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
 			}
 		}
 
-		if(trans->flags & PM_TRANS_FLAG_RECURSE) {
-			_alpm_log(PM_LOG_DEBUG, "finding removable dependencies");
-			trans->packages = _alpm_removedeps(db, trans->packages);
-		}
-
 		/* re-order w.r.t. dependencies */ 
 		_alpm_log(PM_LOG_DEBUG, "sorting by dependencies");
 		lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_REMOVE);
@@ -143,6 +138,11 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
 		alpm_list_free(trans->packages);
 		trans->packages = lp;
 
+		if(trans->flags & PM_TRANS_FLAG_RECURSE) {
+			_alpm_log(PM_LOG_DEBUG, "finding removable dependencies");
+			_alpm_recursedeps(db, &trans->packages, 0);
+		}
+
 		EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
 	}
 
-- 
1.5.2.2





More information about the pacman-dev mailing list