Gentoo Archives: gentoo-commits

From: Fabian Groffen <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: man/, /
Date: Fri, 03 May 2019 08:50:48
Message-Id: 1556873246.47c13a275a7b76d77e5ac3e3ada5024bfc5372bd.grobian@gentoo
1 commit: 47c13a275a7b76d77e5ac3e3ada5024bfc5372bd
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Fri May 3 08:47:26 2019 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Fri May 3 08:47:26 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=47c13a27
7
8 quse: make -v output faster, format and introduce --repo
9
10 - improve performance for -v output (listing all use-flags with
11 descriptions per package match)
12 - add -R/--repo flag to print repository next to atom
13 - align USE-flags in -v mode per package
14
15 Bug: https://bugs.gentoo.org/656550
16 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
17
18 TODO.md | 1 -
19 man/quse.1 | 3 ++
20 quse.c | 171 +++++++++++++++++++++++++++++++++++++++++++++----------------
21 3 files changed, 131 insertions(+), 44 deletions(-)
22
23 diff --git a/TODO.md b/TODO.md
24 index 349170f..b70dffc 100644
25 --- a/TODO.md
26 +++ b/TODO.md
27 @@ -88,5 +88,4 @@
28 package X
29
30 # quse
31 -- make -v faster by calling searcg funcs once per package match
32 - make -v only print requested USE-flag when flags given
33
34 diff --git a/man/quse.1 b/man/quse.1
35 index 6f0d8d3..ef17c10 100644
36 --- a/man/quse.1
37 +++ b/man/quse.1
38 @@ -25,6 +25,9 @@ Describe the USE flag.
39 \fB\-p\fR \fI<arg>\fR, \fB\-\-package\fR \fI<arg>\fR
40 Restrict matching to package or category.
41 .TP
42 +\fB\-R\fR, \fB\-\-repo\fR
43 +Show repository the ebuild originates from.
44 +.TP
45 \fB\-\-root\fR \fI<arg>\fR
46 Set the ROOT env var.
47 .TP
48
49 diff --git a/quse.c b/quse.c
50 index fbf61cf..604efdf 100644
51 --- a/quse.c
52 +++ b/quse.c
53 @@ -26,13 +26,14 @@
54 #include "xarray.h"
55 #include "xregex.h"
56
57 -#define QUSE_FLAGS "eaLDp:" COMMON_FLAGS
58 +#define QUSE_FLAGS "eaLDp:R" COMMON_FLAGS
59 static struct option const quse_long_opts[] = {
60 {"exact", no_argument, NULL, 'e'},
61 {"all", no_argument, NULL, 'a'},
62 {"license", no_argument, NULL, 'L'},
63 {"describe", no_argument, NULL, 'D'},
64 {"package", a_argument, NULL, 'p'},
65 + {"repo", no_argument, NULL, 'R'},
66 COMMON_LONG_OPTS
67 };
68 static const char * const quse_opts_help[] = {
69 @@ -41,6 +42,7 @@ static const char * const quse_opts_help[] = {
70 "Use the LICENSE vs IUSE",
71 "Describe the USE flag",
72 "Restrict matching to package or category",
73 + "Show repository the ebuild originates from",
74 COMMON_OPTS_HELP
75 };
76 #define quse_usage(ret) usage(ret, QUSE_FLAGS, quse_long_opts, quse_opts_help, NULL, lookup_applet_idx("quse"))
77 @@ -48,12 +50,14 @@ static const char * const quse_opts_help[] = {
78 struct quse_state {
79 int argc;
80 char **argv;
81 + char **retv;
82 const char *overlay;
83 bool do_all:1;
84 bool do_regex:1;
85 bool do_describe:1;
86 bool do_licence:1;
87 bool do_list:1;
88 + bool do_repo:1;
89 depend_atom *match;
90 regex_t *pregv;
91 };
92 @@ -110,6 +114,9 @@ quse_search_use_local_desc(int portdirfd, struct quse_state *state)
93
94 match = false;
95 for (i = 0; i < state->argc; i++) {
96 + if (state->do_list && state->retv[i] != NULL)
97 + continue;
98 +
99 if (state->do_regex) {
100 if (regexec(&state->pregv[i], p, 0, NULL, 0) != 0)
101 continue;
102 @@ -128,13 +135,14 @@ quse_search_use_local_desc(int portdirfd, struct quse_state *state)
103 if (state->match == NULL ||
104 atom_compare(atom, state->match) == EQUAL)
105 {
106 - if (state->do_list)
107 - printf(" %s%s%s %s\n", MAGENTA, p, NORM, q);
108 - else
109 + if (state->do_list) {
110 + state->retv[i] = xstrdup(q);
111 + } else {
112 printf("%s%s/%s%s%s[%s%s%s] %s\n",
113 BOLD, atom->CATEGORY,
114 BLUE, atom->PN, NORM,
115 MAGENTA, p, NORM, q);
116 + }
117 }
118
119 atom_implode(atom);
120 @@ -142,6 +150,16 @@ quse_search_use_local_desc(int portdirfd, struct quse_state *state)
121 }
122 } while (1);
123
124 + if (state->do_list && ret) {
125 + /* check if all requested flags are retrieved */
126 + ret = true;
127 + for (i = 0; i < state->argc; i++)
128 + if (state->retv[i] == NULL)
129 + break;
130 + if (i < state->argc)
131 + ret = false;
132 + }
133 +
134 fclose(f);
135 return ret;
136 }
137 @@ -186,6 +204,9 @@ quse_search_use_desc(int portdirfd, struct quse_state *state)
138
139 match = false;
140 for (i = 0; i < state->argc; i++) {
141 + if (state->do_list && state->retv[i] != NULL)
142 + continue;
143 +
144 if (state->do_regex) {
145 if (regexec(&state->pregv[i], buf, 0, NULL, 0) != 0)
146 continue;
147 @@ -198,16 +219,27 @@ quse_search_use_desc(int portdirfd, struct quse_state *state)
148 }
149
150 if (match) {
151 - if (state->do_list)
152 - printf(" %s%s%s %s\n", MAGENTA, buf, NORM, p);
153 - else
154 + if (state->do_list) {
155 + state->retv[i] = xstrdup(p);
156 + } else {
157 printf("%sglobal%s[%s%s%s] %s\n",
158 BOLD, NORM, MAGENTA, buf, NORM, p);
159 + }
160
161 ret = true;
162 }
163 } while (1);
164
165 + if (state->do_list && ret) {
166 + /* check if all requested flags are retrieved */
167 + ret = true;
168 + for (i = 0; i < state->argc; i++)
169 + if (state->retv[i] == NULL)
170 + break;
171 + if (i < state->argc)
172 + ret = false;
173 + }
174 +
175 fclose(f);
176 return ret;
177 }
178 @@ -287,6 +319,9 @@ quse_search_profiles_desc(
179
180 match = false;
181 for (i = 0; i < state->argc; i++) {
182 + if (state->do_list && state->retv[i] != NULL)
183 + continue;
184 +
185 arglen = strlen(state->argv[i]);
186 if (arglen > namelen) {
187 /* nginx_modules_http_lua = NGINX_MODULES_HTTP[lua] */
188 @@ -312,17 +347,18 @@ quse_search_profiles_desc(
189 }
190
191 if (match) {
192 - const char *r = de->d_name;
193 - char *s = ubuf;
194 - do {
195 - *s++ = (char)toupper((int)*r);
196 - } while (++r < (de->d_name + namelen));
197 - *s = '\0';
198 - if (state->do_list)
199 - printf(" %s=%s%s%s %s\n", ubuf, MAGENTA, buf, NORM, p);
200 - else
201 + if (state->do_list) {
202 + state->retv[i] = xstrdup(p);
203 + } else {
204 + const char *r = de->d_name;
205 + char *s = ubuf;
206 + do {
207 + *s++ = (char)toupper((int)*r);
208 + } while (++r < (de->d_name + namelen));
209 + *s = '\0';
210 printf("%s%s%s[%s%s%s] %s\n",
211 BOLD, ubuf, NORM, MAGENTA, buf, NORM, p);
212 + }
213
214 ret = true;
215 }
216 @@ -332,6 +368,16 @@ quse_search_profiles_desc(
217 }
218 closedir(d);
219
220 + if (state->do_list && ret) {
221 + /* check if all requested flags are retrieved */
222 + ret = true;
223 + for (i = 0; i < state->argc; i++)
224 + if (state->retv[i] == NULL)
225 + break;
226 + if (i < state->argc)
227 + ret = false;
228 + }
229 +
230 return ret;
231 }
232
233 @@ -369,6 +415,8 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
234 char *w;
235 int i;
236 int len;
237 + int maxlen;
238 + int cnt;
239 int portdirfd = -1; /* pacify compiler */
240
241 if (state->match || verbose) {
242 @@ -402,13 +450,15 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
243 return 0;
244 }
245
246 + maxlen = 0;
247 + cnt = 0;
248 match = false;
249 q = p = state->do_licence ? meta->LICENSE : meta->IUSE;
250 buf[0] = '\0';
251 v = buf;
252 w = buf + sizeof(buf);
253
254 - if (state->do_all) {
255 + if (state->do_all && !verbose) {
256 match = true;
257 v = q;
258 } else {
259 @@ -423,7 +473,10 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
260 s = q;
261 if (*q == '-' || *q == '+' || *q == '@')
262 q++;
263 - if (state->do_regex) {
264 + if (state->do_all) {
265 + i = 0;
266 + match = true;
267 + } else if (state->do_regex) {
268 char r;
269 for (i = 0; i < state->argc; i++) {
270 r = *p;
271 @@ -452,6 +505,11 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
272 }
273 if (i == state->argc)
274 v += snprintf(v, w - v, "%.*s%c", (int)(p - s), s, *p);
275 +
276 + if (maxlen < p - q)
277 + maxlen = p - q;
278 + cnt++;
279 +
280 q = p + 1;
281 }
282 } while (*p++ != '\0' && v < w);
283 @@ -459,57 +517,82 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
284 }
285
286 if (match) {
287 + char *repo = state->do_repo ? pkg_ctx->repo : NULL;
288 +
289 if (quiet) {
290 - printf("%s%s/%s%s%s\n", BOLD, pkg_ctx->cat_ctx->name,
291 - BLUE, pkg_ctx->name, NORM);
292 - } else if (verbose) {
293 + printf("%s%s/%s%s%s%s%s%s\n", BOLD, pkg_ctx->cat_ctx->name,
294 + BLUE, pkg_ctx->name,
295 + repo ? RED : "", repo ? "::" : "", repo ? repo : "",
296 + NORM);
297 + } else if (verbose && !state->do_licence) {
298 /* multi-line result, printing USE-flags with their descs */
299 struct quse_state us = {
300 .do_regex = false,
301 .do_describe = false,
302 .do_list = true,
303 .match = atom,
304 - .argc = 1,
305 - .argv = NULL,
306 + .argc = cnt,
307 + .argv = xmalloc(sizeof(char *) * cnt),
308 + .retv = xzalloc(sizeof(char *) * cnt),
309 .overlay = NULL,
310 };
311
312 - printf("%s%s/%s%s%s:\n", BOLD, pkg_ctx->cat_ctx->name,
313 - BLUE, pkg_ctx->name, NORM);
314 + printf("%s%s/%s%s%s%s%s%s\n", BOLD, pkg_ctx->cat_ctx->name,
315 + BLUE, pkg_ctx->name,
316 + repo ? RED : "", repo ? "::" : "", repo ? repo : "",
317 + NORM);
318
319 - q = p = state->do_licence ? meta->LICENSE : meta->IUSE;
320 + q = p = meta->IUSE;
321 buf[0] = '\0';
322 + v = buf;
323 + w = buf + sizeof(buf);
324 + i = 0;
325 do {
326 if (*p == ' ' || *p == '\0') {
327 s = q;
328 if (*q == '-' || *q == '+' || *q == '@')
329 q++;
330
331 - snprintf(buf, sizeof(buf), "%.*s", (int)(p - q), q);
332 - v = buf;
333 - us.argv = &v;
334 -
335 - /* print at most one match for each flag, this is
336 - * why we can't setup all flags in argc/argv,
337 - * because then we either print way to few, or way
338 - * too many, possible opt: when argv would be
339 - * modified by search funcs so they remove what they
340 - * matched */
341 - if (!quse_search_use_local_desc(portdirfd, &us))
342 - if (!quse_search_use_desc(portdirfd, &us))
343 - quse_search_profiles_desc(portdirfd, &us);
344 + /* pre-padd everything such that we always refer to
345 + * the char before the USE-flag */
346 + us.argv[i++] = v + 1;
347 + v += snprintf(v, w - v, "%c%.*s",
348 + s == q ? ' ' : *s, (int)(p - q), q) + 1;
349
350 q = p + 1;
351 }
352 - } while (*p++ != '\0');
353 + } while (*p++ != '\0' && i < cnt && v < w);
354 +
355 + /* harvest descriptions for USE-flags */
356 + if (!quse_search_use_local_desc(portdirfd, &us))
357 + if (!quse_search_use_desc(portdirfd, &us))
358 + quse_search_profiles_desc(portdirfd, &us);
359 +
360 + for (i = 0; i < cnt; i++) {
361 + printf(" %c%s%s%s%*s %s\n",
362 + us.argv[i][-1],
363 + /* selected ? RED : NORM */ MAGENTA,
364 + us.argv[i],
365 + NORM,
366 + (int)(maxlen - strlen(us.argv[i])), "",
367 + us.retv[i] == NULL ? "<no description found>" :
368 + us.retv[i]);
369 + if (us.retv[i] != NULL)
370 + free(us.retv[i]);
371 + }
372 +
373 + free(us.retv);
374 + free(us.argv);
375 } else {
376 - printf("%s%s/%s%s%s: %s\n", BOLD, pkg_ctx->cat_ctx->name,
377 - BLUE, pkg_ctx->name, NORM, v);
378 + printf("%s%s/%s%s%s%s%s%s: %s\n", BOLD, pkg_ctx->cat_ctx->name,
379 + BLUE, pkg_ctx->name,
380 + repo ? RED : "", repo ? "::" : "", repo ? repo : "",
381 + NORM, v);
382 }
383 }
384
385 cache_close_meta(meta);
386 - if (state->match || verbose)
387 + if (state->match && verbose)
388 atom_implode(atom);
389 if (verbose)
390 close(portdirfd);
391 @@ -528,6 +611,7 @@ int quse_main(int argc, char **argv)
392 .do_regex = true,
393 .do_describe = false,
394 .do_licence = false,
395 + .do_repo = false,
396 .match = NULL,
397 .overlay = NULL,
398 };
399 @@ -538,6 +622,7 @@ int quse_main(int argc, char **argv)
400 case 'a': state.do_all = true; break;
401 case 'L': state.do_licence = true; break;
402 case 'D': state.do_describe = true; break;
403 + case 'R': state.do_repo = true; break;
404 case 'p': match = optarg; break;
405 COMMON_GETOPTS_CASES(quse)
406 }