From 417366afdbaac255275db19f41df3e2ad3389ced Mon Sep 17 00:00:00 2001
From: Nagy Gabor <ngaba@bibl.u-szeged.hu>
Date: Thu, 29 Nov 2007 13:54:44 +0100
Subject: [PATCH] alpm_checkdeps clean-up

No bugfixes, just makes the code human-readable

Signed-off-by: Nagy Gabor <ngaba@bibl.u-szeged.hu>
---
 lib/libalpm/deps.c |  151 ++++++++++++----------------------------------------
 1 files changed, 34 insertions(+), 117 deletions(-)

diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 4a4f654..ff4b9c5 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -229,6 +229,12 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
 	return(newtargs);
 }
 
+/* Little helper function for alpm_list_find */
+static int satisfycmp(const void *pkg, const void *depend)
+{
+	return(!alpm_depcmp((pmpkg_t*) pkg, (pmdepend_t*) depend));
+}
+
 /** Checks dependencies and returns missing ones in a list.
  * Dependencies can include versions with depmod operators.
  * @param db pointer to the local package database
@@ -240,8 +246,8 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
 alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
 		alpm_list_t *remove, alpm_list_t *upgrade)
 {
-	alpm_list_t *i, *j, *k, *l;
-	int found = 0;
+	alpm_list_t *i, *j;
+	alpm_list_t *joined, *dblist;
 	alpm_list_t *baddeps = NULL;
 	pmdepmissing_t *miss = NULL;
 
@@ -251,6 +257,10 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
 		return(NULL);
 	}
 
+	joined = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));
+	dblist = alpm_list_diff(_alpm_db_get_pkgcache(db), joined, _alpm_pkg_cmp);
+	alpm_list_free(joined);
+
 	/* look for unsatisfied dependencies of the upgrade list */
 	for(i = upgrade; i; i = i->next) {
 		pmpkg_t *tp = i->data;
@@ -262,34 +272,19 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
 				alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));
 
 		for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
-			/* split into name/version pairs */
 			pmdepend_t *depend = j->data;
-			found = 0;
 			/* 1. we check the upgrade list */
-			for(k = upgrade; k && !found; k = k->next) {
-				pmpkg_t *p = k->data;
-				found = p && alpm_depcmp(p, depend);
-			}
 			/* 2. we check database for untouched satisfying packages */
-			for(k = _alpm_db_get_pkgcache(db); k && !found; k = k->next) {
-				pmpkg_t *p = k->data;
-				found = p && alpm_depcmp(p, depend)
-					&& !_alpm_pkg_find(alpm_pkg_get_name(p), upgrade)
-					&& !_alpm_pkg_find(alpm_pkg_get_name(p), remove);
-			}
-			/* else if still not found... */
-			if(!found) {
+			if(!alpm_list_find(upgrade, depend, satisfycmp) &&
+			   !alpm_list_find(dblist, depend, satisfycmp)) {
+				/* Unsatisfied dependency in the upgrade list */
 				char *missdepstring = alpm_dep_get_string(depend);
 				_alpm_log(PM_LOG_DEBUG, "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->mod,
 						depend->name, depend->version);
-				if(!_alpm_depmiss_isin(miss, baddeps)) {
-					baddeps = alpm_list_add(baddeps, miss);
-				} else {
-					FREE(miss);
-				}
+				baddeps = alpm_list_add(baddeps, miss);
 			}
 		}
 	}
@@ -298,113 +293,35 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
 		/* reversedeps handles the backwards dependencies, ie,
 		 * the packages listed in the requiredby field. */
 
-		/* we check the upgrade list then the remove list in one loop */
-		int upgr = 1; /* we are in the upgrade list */
-		i = upgrade;
-		while(upgr || i) {
-			if(!i) { /*this is the end of the upgrade list, jump to the remove list*/
-				i = remove;
-				upgr = 0;
-				continue;
-			}
-			pmpkg_t *newpkg = i->data;
-			pmpkg_t *oldpkg;
-			alpm_list_t *requiredby;
-			if(newpkg == NULL) {
-				_alpm_log(PM_LOG_DEBUG, "null package found in package list\n");
-				i = i->next;
-				continue;
-			}
-			_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
-					alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
+		alpm_list_t *modified = alpm_list_diff(_alpm_db_get_pkgcache(db), dblist, _alpm_pkg_cmp);
 
-			if((oldpkg = _alpm_db_get_pkgfromcache(db, alpm_pkg_get_name(newpkg))) == NULL) {
-				_alpm_log(PM_LOG_DEBUG, "cannot find package installed '%s'\n",
-						alpm_pkg_get_name(newpkg));
-				i = i->next;
+		for(i = dblist; i; i = i->next) {
+			pmpkg_t *lp = i->data;
+			if(lp == NULL) {
+				_alpm_log(PM_LOG_DEBUG, "null package found in localdb pkgcache\n");
 				continue;
 			}
-
-			requiredby = alpm_pkg_compute_requiredby(oldpkg);
-			for(j = requiredby; j; j = j->next) {
-				pmpkg_t *p;
-				found = 0;
-
-				if(_alpm_pkg_find(j->data, upgrade) || _alpm_pkg_find(j->data, remove)) {
-					continue;
-				}
-				if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
-					/* hmmm... package isn't installed.. */
-					continue;
-				}
-
-				for(k = alpm_pkg_get_depends(p); k; k = k->next) {
-					pmdepend_t *depend = k->data;
+			for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
+				pmdepend_t *depend = j->data;
+				/* 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(alpm_list_find(modified, depend, satisfycmp) &&
+				   !alpm_list_find(upgrade, depend, satisfycmp) &&
+				   !alpm_list_find(dblist, depend, satisfycmp)) {
 					char *missdepstring = alpm_dep_get_string(depend);
-
-					if(!alpm_depcmp(oldpkg, depend)) {
-						continue;
-					}
-					/* OK, we don't want to break this depend */
-
-					/* 1. for efficiency we check newpkg first if we are in the upgrade list */
-					if(upgr && alpm_depcmp(newpkg, depend)) {
-						_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' also satisfied by the upgraded version of '%s'\n",
-								missdepstring, alpm_pkg_get_name(newpkg));
-						free(missdepstring);
-						continue;
-					}
-					/* 2. we check the upgrade targets */
-					int satisfied = 0;
-					for(l = upgrade; l; l = l->next) {
-						pmpkg_t *pkg = l->data;
-						if(pkg && alpm_depcmp(pkg, depend)) {
-							_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by '%s' from the upgrade list\n",
-									missdepstring, alpm_pkg_get_name(pkg));
-							free(missdepstring);
-							satisfied = 1;
-							break;
-						}
-					}
-					if(satisfied) {
-						continue;
-					}
-					/* 3. we check untouched installed packages to see if anything else
-					 * satisfies this... */
-					for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
-						pmpkg_t *pkg = l->data;
-
-						if(pkg && alpm_depcmp(pkg, depend)
-								&& !_alpm_pkg_find(alpm_pkg_get_name(pkg), upgrade)
-								&& !_alpm_pkg_find(alpm_pkg_get_name(pkg), remove)) {
-							_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n",
-									missdepstring, alpm_pkg_get_name(pkg));
-							free(missdepstring);
-							satisfied = 1;
-							break;
-						}
-					}
-					if(satisfied) {
-						continue;
-					}
-
-					/* The transaction would break this depend, record it */
 					_alpm_log(PM_LOG_DEBUG, "checkdeps: the transaction would break '%s' dependency of '%s'\n",
-							missdepstring, alpm_pkg_get_name(p));
+							missdepstring, alpm_pkg_get_name(lp));
 					free(missdepstring);
-					miss = _alpm_depmiss_new(p->name, depend->mod,
+					miss = _alpm_depmiss_new(lp->name, depend->mod,
 							depend->name, depend->version);
-					if(!_alpm_depmiss_isin(miss, baddeps)) {
-						baddeps = alpm_list_add(baddeps, miss);
-					} else {
-						FREE(miss);
-					}
+					baddeps = alpm_list_add(baddeps, miss);
 				}
 			}
-			FREELIST(requiredby);
-			i = alpm_list_next(i);
 		}
+		alpm_list_free(modified);
 	}
+	alpm_list_free(dblist);
 
 	return(baddeps);
 }
-- 
1.5.2.5

