diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libalpm/deps.c | 104 | ||||
| -rw-r--r-- | lib/libalpm/deps.h | 2 | ||||
| -rw-r--r-- | lib/libalpm/remove.c | 10 | 
3 files changed, 56 insertions, 60 deletions
| diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index ddbd99a2..a2d60dd1 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -520,10 +520,12 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)  	return(depend);  } -/* 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) +/* 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, or if 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; @@ -531,13 +533,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 here, 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); @@ -550,69 +560,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. +/** + * @brief Adds unneeded dependencies to an existing list of packages. + * By unneeded, we mean dependencies that are only required by packages in the + * target list, so they can be safely removed. + * + * @param db package database to do dependency tracing in + * @param *targs pointer to a list of packages + * @param include_explicit if 0, explicitly installed packages are not included   */ -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); - +				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(pkg)); +								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 diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 2edbb503..f11a19a0 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 5315d96c..2a080f85 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -135,11 +135,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); @@ -147,6 +142,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);  	return(0); | 
