--- 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