diff options
author | Fabian Groffen <grobian@gentoo.org> | 2019-06-12 11:11:44 +0200 |
---|---|---|
committer | Fabian Groffen <grobian@gentoo.org> | 2019-06-12 11:11:44 +0200 |
commit | 753605792fab143ded32ebabbf85cc840151f0d2 (patch) | |
tree | 890815c9fbf0c4b9b2b7b079dbc9d706400505e4 | |
parent | man/mkman: skip generation for applets that aren't enabled (diff) | |
download | portage-utils-75360579.tar.gz portage-utils-75360579.tar.bz2 portage-utils-75360579.zip |
quse: add mode for querying installed packages (only)
Instead of traversing the tree(s), look in the VDB (= installed
packages). While doing this, when using -v, we can print the enabled
flags next to the flag and its description, as with `equery uses'.
Bug: https://bugs.gentoo.org/656550
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
-rw-r--r-- | man/include/quse.optdesc.yaml | 4 | ||||
-rw-r--r-- | man/quse.1 | 7 | ||||
-rw-r--r-- | quse.c | 81 |
3 files changed, 76 insertions, 16 deletions
diff --git a/man/include/quse.optdesc.yaml b/man/include/quse.optdesc.yaml index 79a98fa..693aade 100644 --- a/man/include/quse.optdesc.yaml +++ b/man/include/quse.optdesc.yaml @@ -4,3 +4,7 @@ verbose: | Also shows problems encountered during parsing. These are mostly diagnostic and indicate possible incorrectness in the results. quiet: Ignored for compatibility with other qapplets. +installed: | + Only search installed packages. Together with \fB-v\fR this shows + USE-flags and their descriptions, and currently enabled flags + prefixed with an asterisk (\fI*\fR). @@ -1,5 +1,5 @@ .\" generated by mkman.py, please do NOT edit! -.TH quse "1" "May 2019" "Gentoo Foundation" "quse" +.TH quse "1" "Jun 2019" "Gentoo Foundation" "quse" .SH NAME quse \- find pkgs using useflags .SH SYNOPSIS @@ -22,6 +22,11 @@ Use the LICENSE vs IUSE. \fB\-D\fR, \fB\-\-describe\fR Describe the USE flag. .TP +\fB\-I\fR, \fB\-\-installed\fR +Only search installed packages. Together with \fB-v\fR this shows +USE-flags and their descriptions, and currently enabled flags +prefixed with an asterisk (\fI*\fR). +.TP \fB\-p\fR \fI<arg>\fR, \fB\-\-package\fR \fI<arg>\fR Restrict matching to package or category. .TP @@ -21,17 +21,19 @@ #include <ctype.h> #include <assert.h> +#include "set.h" #include "rmspace.h" #include "tree.h" #include "xarray.h" #include "xregex.h" -#define QUSE_FLAGS "eaLDp:R" COMMON_FLAGS +#define QUSE_FLAGS "eaLDIp:R" COMMON_FLAGS static struct option const quse_long_opts[] = { {"exact", no_argument, NULL, 'e'}, {"all", no_argument, NULL, 'a'}, {"license", no_argument, NULL, 'L'}, {"describe", no_argument, NULL, 'D'}, + {"installed", no_argument, NULL, 'I'}, {"package", a_argument, NULL, 'p'}, {"repo", no_argument, NULL, 'R'}, COMMON_LONG_OPTS @@ -41,6 +43,7 @@ static const char * const quse_opts_help[] = { "List all ebuilds, don't match anything", "Use the LICENSE vs IUSE", "Describe the USE flag", + "Only search installed packages", "Restrict matching to package or category", "Show repository the ebuild originates from", COMMON_OPTS_HELP @@ -56,6 +59,7 @@ struct quse_state { bool do_regex:1; bool do_describe:1; bool do_licence:1; + bool do_installed:1; bool do_list:1; bool do_repo:1; depend_atom *match; @@ -407,6 +411,7 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) depend_atom *atom = NULL; /* pacify compiler */ char buf[8192]; tree_pkg_meta *meta; + set *use = NULL; bool match; char *p; char *q; @@ -432,16 +437,44 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) } } - meta = tree_pkg_read(pkg_ctx); - if (meta == NULL) - return 0; + if (state->overlay != NULL) { + meta = tree_pkg_read(pkg_ctx); + if (meta == NULL) + return 0; + if (meta->IUSE == NULL) + return 0; + } else { + size_t dummy; - if (meta->IUSE == NULL) - return 0; + meta = xzalloc(sizeof(*meta)); + + dummy = 0; + if (!tree_pkg_vdb_eat(pkg_ctx, "IUSE", &meta->IUSE, &dummy)) { + free(meta); + return 0; + } + + dummy = 0; + tree_pkg_vdb_eat(pkg_ctx, "LICENSE", &meta->LICENSE, &dummy); + + s = NULL; + dummy = 0; + tree_pkg_vdb_eat(pkg_ctx, "USE", &s, &dummy); + p = s; + while ((q = strchr(p, (int)' ')) != NULL) { + *q++ = '\0'; + use = add_set(p, use); + p = q; + } + if (*p != '\0') + use = add_set(p, use); + free(s); + } if (verbose) { portdirfd = openat(pkg_ctx->cat_ctx->ctx->portroot_fd, - state->overlay, O_RDONLY | O_CLOEXEC | O_PATH); + state->overlay == NULL ? main_overlay : state->overlay, + O_RDONLY | O_CLOEXEC | O_PATH); if (portdirfd == -1) return 0; } @@ -566,7 +599,9 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) quse_search_profiles_desc(portdirfd, &us); for (i = 0; i < cnt; i++) { - printf(" %c%s%s%s%*s %s\n", + match = use != NULL && contains_set(us.argv[i], use); + printf("%s%c%s%s%s%*s %s\n", + match ? "*" : " ", us.argv[i][-1], /* selected ? RED : NORM */ MAGENTA, us.argv[i], @@ -585,7 +620,16 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) } } - tree_close_meta(meta); + if (state->overlay != NULL) { + tree_close_meta(meta); + } else { + free(meta->IUSE); + if (meta->LICENSE != NULL) + free(meta->LICENSE); + free(meta); + if (use != NULL) + free_set(use); + } if (verbose) close(portdirfd); @@ -603,6 +647,7 @@ int quse_main(int argc, char **argv) .do_regex = true, .do_describe = false, .do_licence = false, + .do_installed = false, .do_repo = false, .match = NULL, .overlay = NULL, @@ -610,12 +655,13 @@ int quse_main(int argc, char **argv) while ((i = GETOPT_LONG(QUSE, quse, "")) != -1) { switch (i) { - case 'e': state.do_regex = false; break; - case 'a': state.do_all = true; break; - case 'L': state.do_licence = true; break; - case 'D': state.do_describe = true; break; - case 'R': state.do_repo = true; break; - case 'p': match = optarg; break; + case 'e': state.do_regex = false; break; + case 'a': state.do_all = true; break; + case 'L': state.do_licence = true; break; + case 'D': state.do_describe = true; break; + case 'I': state.do_installed = true; break; + case 'R': state.do_repo = true; break; + case 'p': match = optarg; break; COMMON_GETOPTS_CASES(quse) } } @@ -646,6 +692,11 @@ int quse_main(int argc, char **argv) if (state.do_describe) { array_for_each(overlays, n, overlay) quse_describe_flag(portroot, overlay, &state); + } else if (state.do_installed) { + tree_ctx *t = tree_open_vdb(portroot, portvdb); + state.overlay = NULL; + tree_foreach_pkg_sorted(t, quse_results_cb, &state); + tree_close(t); } else { array_for_each(overlays, n, overlay) { tree_ctx *t = tree_open(portroot, overlay); |