Signed-off-by: Benedikt Morbach <[email protected]>
---
 doc/pacman.8.txt      |    6 ++++++
 lib/libalpm/alpm.h    |    2 +-
 lib/libalpm/package.c |   33 +++++++++++++++++++++++----------
 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, 49 insertions(+), 16 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 5985381..45386c7 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -280,6 +280,12 @@ Query Options[[QO]]
        database(s).  Typically these are packages that were downloaded manually
        and installed with '\--upgrade'.
 
+*-n, \--optdeps*::
+       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 4587148..f1e7fd6 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -700,7 +700,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 c1fbcca..8c0a678 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -389,7 +389,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;
@@ -397,11 +398,23 @@ 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) {
+                               alpm_optdepend_t *optdep = j->data;
+                               if(_alpm_depcmp(pkg, optdep->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));
+                                       }
                                }
                        }
                }
@@ -409,7 +422,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;
@@ -420,17 +433,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->status & DB_STATUS_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 396cde5..552afad 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_optdeps;
        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 7e17f0c..b8b34c3 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -108,7 +108,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, 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 d285a05..3a19619 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -148,6 +148,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, --optdeps        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"));
@@ -461,6 +462,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_optdeps = 1; break;
                case 'g': (config->group)++; break;
                case 'i': (config->op_q_info)++; break;
                case 'k': config->op_q_check = 1; break;
@@ -604,6 +606,7 @@ static int parseargs(int argc, char *argv[])
                {"list",       no_argument,       0, 'l'},
                {"foreign",    no_argument,       0, 'm'},
                {"nosave",     no_argument,       0, 'n'},
+               {"optdeps",    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 1098b85..8523e23 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -363,9 +363,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;
        }
@@ -390,7 +396,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_optdeps && 
!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 b883291..2dd543b 100644
--- a/src/util/pactree.c
+++ b/src/util/pactree.c
@@ -347,7 +347,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.1


Reply via email to