aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2019-06-12 11:11:44 +0200
committerFabian Groffen <grobian@gentoo.org>2019-06-12 11:11:44 +0200
commit753605792fab143ded32ebabbf85cc840151f0d2 (patch)
tree890815c9fbf0c4b9b2b7b079dbc9d706400505e4
parentman/mkman: skip generation for applets that aren't enabled (diff)
downloadportage-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.yaml4
-rw-r--r--man/quse.17
-rw-r--r--quse.c81
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).
diff --git a/man/quse.1 b/man/quse.1
index 7f559fd..0a031ba 100644
--- a/man/quse.1
+++ b/man/quse.1
@@ -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
diff --git a/quse.c b/quse.c
index c7fbe81..751f767 100644
--- a/quse.c
+++ b/quse.c
@@ -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);