[pacman-dev] [PATCH 5/6] optdepends are not orphans unless --nooptdepends is specified

Benedikt Morbach benedikt.morbach at googlemail.com
Thu Jul 21 14:39:26 EDT 2011


---
 doc/pacman.8.txt      |    6 ++++++
 lib/libalpm/alpm.h    |    2 +-
 lib/libalpm/package.c |   32 ++++++++++++++++++++++----------
 src/pacman/conf.h     |    1 +
 src/pacman/package.c  |    2 +-
 src/pacman/pacman.c   |    3 +++
 src/pacman/query.c    |   16 +++++++++++++---
 src/util/pactree.c    |    2 +-
 8 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 64b1ff3..90fb040 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -269,6 +269,12 @@ Query Options[[QO]]
 	database(s).  Typically these are packages that were downloaded manually
 	and installed with '\--upgrade'.
 
+*-n, \--nooptdeps*::
+	When using the '-t' option with this flag, do not treat installed
+	optional dependencies as if they were normal dependencies. This option
+	can be used to list packages which were installed as dependencies but are
+	only optionally	used by other packages.
+
 *-o, \--owns* <file>::
 	Search for packages that own the specified file(s). The path can be
 	relative or absolute and one or more files can be specified.
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 21f65a1..adba014 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -535,7 +535,7 @@ int alpm_pkg_vercmp(const char *a, const char *b);
  * @param pkg a package
  * @return the list of packages requiring pkg
  */
-alpm_list_t *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg);
+alpm_list_t *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg, const int find_optdeps);
 
 /** @name Package Property Accessors
  * Any pointer returned by these functions points to internal structures
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index a64d613..d473973 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -376,7 +376,8 @@ int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg)
 	return pkg->ops->has_scriptlet(pkg);
 }
 
-static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
+static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db,
+                            alpm_list_t **reqs, const int find_optdeps)
 {
 	const alpm_list_t *i;
 	pkg->handle->pm_errno = 0;
@@ -384,11 +385,22 @@ static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
 	for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
 		alpm_pkg_t *cachepkg = i->data;
 		alpm_list_t *j;
-		for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
-			if(_alpm_depcmp(pkg, j->data)) {
-				const char *cachepkgname = cachepkg->name;
-				if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
-					*reqs = alpm_list_add(*reqs, strdup(cachepkgname));
+		if (find_optdeps) {
+			for(j = alpm_pkg_get_optdepends(cachepkg); j; j = j->next) {
+				if(_alpm_depcmp(pkg, ((alpm_optdepend_t *)j->data)->depend)) {
+					const char *cachepkgname = cachepkg->name;
+					if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
+						*reqs = alpm_list_add(*reqs, strdup(cachepkgname));
+					}
+				}
+			}
+		} else {
+			for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
+				if(_alpm_depcmp(pkg, j->data)) {
+					const char *cachepkgname = cachepkg->name;
+					if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
+						*reqs = alpm_list_add(*reqs, strdup(cachepkgname));
+					}
 				}
 			}
 		}
@@ -396,7 +408,7 @@ static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
 }
 
 /** Compute the packages requiring a given package. */
-alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
+alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg, const int find_optdeps)
 {
 	const alpm_list_t *i;
 	alpm_list_t *reqs = NULL;
@@ -407,17 +419,17 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
 
 	if(pkg->origin == PKG_FROM_FILE) {
 		/* The sane option; search locally for things that require this. */
-		find_requiredby(pkg, pkg->handle->db_local, &reqs);
+		find_requiredby(pkg, pkg->handle->db_local, &reqs, find_optdeps);
 	} else {
 		/* We have a DB package. if it is a local package, then we should
 		 * only search the local DB; else search all known sync databases. */
 		db = pkg->origin_data.db;
 		if(db->is_local) {
-			find_requiredby(pkg, db, &reqs);
+			find_requiredby(pkg, db, &reqs, find_optdeps);
 		} else {
 			for(i = pkg->handle->dbs_sync; i; i = i->next) {
 				db = i->data;
-				find_requiredby(pkg, db, &reqs);
+				find_requiredby(pkg, db, &reqs, find_optdeps);
 			}
 			reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);
 		}
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index bce42ab..2330e9a 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -54,6 +54,7 @@ typedef struct __config_t {
 	unsigned short op_q_unrequired;
 	unsigned short op_q_deps;
 	unsigned short op_q_explicit;
+	unsigned short op_q_nooptdeps;
 	unsigned short op_q_owns;
 	unsigned short op_q_search;
 	unsigned short op_q_changelog;
diff --git a/src/pacman/package.c b/src/pacman/package.c
index 3e882ef..250f701 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -92,7 +92,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
 
 	if(extra || from == PKG_FROM_LOCALDB) {
 		/* compute this here so we don't get a pause in the middle of output */
-		requiredby = alpm_pkg_compute_requiredby(pkg);
+		requiredby = alpm_pkg_compute_requiredby(pkg, 0);
 	}
 
 	/* actual output */
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index e855203..54ddbc0 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -146,6 +146,7 @@ static void usage(int op, const char * const myname)
 			addlist(_("  -k, --check          check that the files owned by the package(s) are present\n"));
 			addlist(_("  -l, --list           list the contents of the queried package\n"));
 			addlist(_("  -m, --foreign        list installed packages not found in sync db(s) [filter]\n"));
+			addlist(_("  -n, --nooptdeps      don't consider installed optdepends to be required\n"));
 			addlist(_("  -o, --owns <file>    query the package that owns <file>\n"));
 			addlist(_("  -p, --file <package> query a package file instead of the database\n"));
 			addlist(_("  -q, --quiet          show less information for query and search\n"));
@@ -458,6 +459,7 @@ static int parsearg_query(int opt)
 		case 'c': config->op_q_changelog = 1; break;
 		case 'd': config->op_q_deps = 1; break;
 		case 'e': config->op_q_explicit = 1; break;
+		case 'n': config->op_q_nooptdeps = 1; break;
 		case 'g': (config->group)++; break;
 		case 'i': (config->op_q_info)++; break;
 		case 'k': config->op_q_check = 1; break;
@@ -598,6 +600,7 @@ static int parseargs(int argc, char *argv[])
 		{"list",       no_argument,       0, 'l'},
 		{"foreign",    no_argument,       0, 'm'},
 		{"nosave",     no_argument,       0, 'n'},
+		{"nooptdeps",  no_argument,       0, 'n'},
 		{"owns",       no_argument,       0, 'o'},
 		{"file",       no_argument,       0, 'p'},
 		{"print",      no_argument,       0, 'p'},
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 251c4dd..6b6f521 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -360,9 +360,15 @@ static int is_foreign(alpm_pkg_t *pkg)
 	return 0;
 }
 
-static int is_unrequired(alpm_pkg_t *pkg)
+static int is_unrequired(alpm_pkg_t *pkg, const int find_optdeps)
 {
-	alpm_list_t *requiredby = alpm_pkg_compute_requiredby(pkg);
+	alpm_list_t *requiredby;
+	if (find_optdeps) {
+		requiredby = alpm_pkg_compute_requiredby(pkg, 1);
+	} else {
+		requiredby = alpm_pkg_compute_requiredby(pkg, 0);
+	}
+
 	if(requiredby == NULL) {
 		return 1;
 	}
@@ -387,7 +393,11 @@ static int filter(alpm_pkg_t *pkg)
 		return 0;
 	}
 	/* check if this pkg is unrequired */
-	if(config->op_q_unrequired && !is_unrequired(pkg)) {
+	if(config->op_q_unrequired && !is_unrequired(pkg, 0)) {
+		return 0;
+	}
+	/* check if this pkg is optionally required */
+	if(config->op_q_unrequired && !config->op_q_nooptdeps && !is_unrequired(pkg, 1)) {
 		return 0;
 	}
 	/* check if this pkg is outdated */
diff --git a/src/util/pactree.c b/src/util/pactree.c
index 9b67863..c7f2b20 100644
--- a/src/util/pactree.c
+++ b/src/util/pactree.c
@@ -342,7 +342,7 @@ static void walk_reverse_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
 	}
 
 	walked = alpm_list_add(walked, (void *)alpm_pkg_get_name(pkg));
-	required_by = alpm_pkg_compute_requiredby(pkg);
+	required_by = alpm_pkg_compute_requiredby(pkg, 0);
 
 	for(i = required_by; i; i = alpm_list_next(i)) {
 		const char *pkgname = alpm_list_getdata(i);
-- 
1.7.6



More information about the pacman-dev mailing list