Gentoo Archives: gentoo-commits

From: Mike Frysinger <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: /
Date: Sat, 28 Nov 2015 02:44:41
Message-Id: 1448651050.f162c6a9219deacfe23c8e21b732f8594a938130.vapier@gentoo
1 commit: f162c6a9219deacfe23c8e21b732f8594a938130
2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
3 AuthorDate: Fri Nov 27 19:04:10 2015 +0000
4 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
5 CommitDate: Fri Nov 27 19:04:10 2015 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f162c6a9
7
8 qsearch: add multiple overlay support
9
10 We ractor some of the main code into helper funcs to make iterating
11 over the overlays easier to manage.
12
13 URL: https://bugs.gentoo.org/553260
14
15 qsearch.c | 268 +++++++++++++++++++++++++++++++++++---------------------------
16 1 file changed, 152 insertions(+), 116 deletions(-)
17
18 diff --git a/qsearch.c b/qsearch.c
19 index 02d43ca..b7c992e 100644
20 --- a/qsearch.c
21 +++ b/qsearch.c
22 @@ -31,18 +31,114 @@ static const char * const qsearch_opts_help[] = {
23 };
24 #define qsearch_usage(ret) usage(ret, QSEARCH_FLAGS, qsearch_long_opts, qsearch_opts_help, lookup_applet_idx("qsearch"))
25
26 -int qsearch_main(int argc, char **argv)
27 +#define LAST_BUF_SIZE 256
28 +
29 +/* Search an ebuild's details via the metadata cache. */
30 +static void
31 +qsearch_ebuild_metadata(_q_unused_ int overlay_fd, const char *ebuild, const char *search_me, char *last,
32 + bool search_desc, bool search_all, _q_unused_ bool search_name, bool show_name_only, bool show_homepage)
33 +{
34 + portage_cache *pcache = cache_read_file(ebuild);
35 +
36 + if (pcache == NULL) {
37 + if (!reinitialize)
38 + warnf("(cache update pending) %s", ebuild);
39 + reinitialize = 1;
40 + return;
41 + }
42 +
43 + if (strcmp(pcache->atom->PN, last) != 0) {
44 + strncpy(last, pcache->atom->PN, LAST_BUF_SIZE);
45 + if (search_all || rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0)
46 + printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE,
47 + pcache->atom->PN, NORM,
48 + (show_name_only ? "" :
49 + (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION)));
50 + }
51 + cache_free(pcache);
52 +}
53 +
54 +/* Search an ebuild's details via the ebuild cache. */
55 +static void
56 +qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me, char *last,
57 + _q_unused_ bool search_desc, bool search_all, bool search_name, bool show_name_only, _q_unused_ bool show_homepage)
58 {
59 - FILE *fp;
60 - char *ebuild = NULL;
61 - char last[126] = "";
62 + const char * const search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" };
63 + const char *search_var = search_vars[show_homepage ? 1 : 0];
64 + size_t search_len = strlen(search_var);
65 char *p, *q, *str;
66 +
67 + FILE *ebuildfp;
68 + str = xstrdup(ebuild);
69 + p = dirname(str);
70 +
71 + if (strcmp(p, last) == 0)
72 + goto no_cache_ebuild_match;
73 +
74 + bool show_it = false;
75 + strncpy(last, p, LAST_BUF_SIZE);
76 + if (search_name) {
77 + if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) {
78 + goto no_cache_ebuild_match;
79 + } else {
80 + q = NULL;
81 + show_it = true;
82 + }
83 + }
84 +
85 + int fd = openat(overlay_fd, ebuild, O_RDONLY|O_CLOEXEC);
86 + if (fd != -1) {
87 + ebuildfp = fdopen(fd, "r");
88 + if (ebuildfp == NULL) {
89 + close(fd);
90 + goto no_cache_ebuild_match;
91 + }
92 + } else {
93 + if (!reinitialize)
94 + warnfp("(cache update pending) %s", ebuild);
95 + reinitialize = 1;
96 + goto no_cache_ebuild_match;
97 + }
98 +
99 + char *buf = NULL;
100 + size_t buflen, linelen;
101 + while ((linelen = getline(&buf, &buflen, ebuildfp)) != -1) {
102 + if (linelen <= search_len)
103 + continue;
104 + if (strncmp(buf, search_var, search_len) != 0)
105 + continue;
106 + if ((q = strrchr(buf, '"')) != NULL)
107 + *q = 0;
108 + if (strlen(buf) <= search_len)
109 + break;
110 + q = buf + search_len + 1;
111 + if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
112 + break;
113 + show_it = true;
114 + break;
115 + }
116 +
117 + if (show_it) {
118 + printf("%s%s/%s%s%s %s\n",
119 + BOLD, dirname(p), BLUE, basename(p), NORM,
120 + (show_name_only ? "" : q ? : "<no DESCRIPTION found>"));
121 + }
122 +
123 + free(buf);
124 + fclose(ebuildfp);
125 + no_cache_ebuild_match:
126 + free(str);
127 +}
128 +
129 +int qsearch_main(int argc, char **argv)
130 +{
131 + char last[LAST_BUF_SIZE];
132 char *search_me = NULL;
133 - char show_homepage = 0, show_name_only = 0;
134 - char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD;
135 - const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" };
136 - size_t search_len, ebuild_len, linelen;
137 - int i, idx=0;
138 + bool show_homepage = false, show_name_only = false;
139 + bool search_desc = false, search_all = false, search_name = true;
140 + int search_cache = CACHE_EBUILD;
141 + int i;
142 + void (*search_func)(int, const char *, const char *, char *last, bool, bool, bool, bool, bool);
143
144 DBG("argc=%d argv[0]=%s argv[1]=%s",
145 argc, argv[0], argc > 1 ? argv[1] : "NULL?");
146 @@ -50,132 +146,72 @@ int qsearch_main(int argc, char **argv)
147 while ((i = GETOPT_LONG(QSEARCH, qsearch, "")) != -1) {
148 switch (i) {
149 COMMON_GETOPTS_CASES(qsearch)
150 - case 'a': search_all = 1; break;
151 + case 'a': search_all = true; break;
152 case 'c': search_cache = CACHE_METADATA; break;
153 case 'e': search_cache = CACHE_EBUILD; break;
154 - case 's': search_desc = 0; search_name = 1; break;
155 - case 'S': search_desc = 1; search_name = 0; break;
156 - case 'N': show_name_only = 1; break;
157 - case 'H': show_homepage = 1, idx = 1; break;
158 + case 's': search_desc = false; search_name = true; break;
159 + case 'S': search_desc = true; search_name = false; break;
160 + case 'N': show_name_only = true; break;
161 + case 'H': show_homepage = true; break;
162 }
163 }
164
165 + switch (search_cache) {
166 + case CACHE_METADATA:
167 + search_func = qsearch_ebuild_metadata;
168 + break;
169 + case CACHE_EBUILD:
170 + search_func = qsearch_ebuild_ebuild;
171 + break;
172 + default:
173 + err("unknown cache %i", search_cache);
174 + }
175 +
176 if (search_all) {
177 - search_desc = 1;
178 - search_name = 0;
179 + search_desc = true;
180 + search_name = false;
181 } else {
182 if (argc == optind)
183 qsearch_usage(EXIT_FAILURE);
184 search_me = argv[optind];
185 }
186 last[0] = 0;
187 - fp = fopen(initialize_flat(portdir, search_cache, false), "r");
188 - if (!fp)
189 - return 1;
190 -
191 - int portdir_fd = open(portdir, O_RDONLY|O_CLOEXEC|O_PATH);
192 - if (portdir_fd < 0)
193 - errp("open(%s) failed", portdir);
194 -
195 - q = NULL; /* Silence a gcc warning. */
196 - search_len = strlen(search_vars[idx]);
197
198 - while ((linelen = getline(&ebuild, &ebuild_len, fp)) != -1) {
199 - rmspace_len(ebuild, linelen);
200 - if (!ebuild[0])
201 + int ret = 0;
202 + size_t n;
203 + const char *overlay;
204 + array_for_each(overlays, n, overlay) {
205 + FILE *fp = fopen(initialize_flat(overlay, search_cache, false), "r");
206 + if (!fp) {
207 + warnp("opening cache for %s failed", overlay);
208 + ret = 1;
209 continue;
210 + }
211
212 - switch (search_cache) {
213 -
214 - case CACHE_METADATA: {
215 - portage_cache *pcache;
216 - if ((pcache = cache_read_file(ebuild)) != NULL) {
217 - if (strcmp(pcache->atom->PN, last) != 0) {
218 - strncpy(last, pcache->atom->PN, sizeof(last));
219 - if ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0) || search_all)
220 - printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE,
221 - pcache->atom->PN, NORM,
222 - (show_name_only ? "" :
223 - (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION)));
224 - }
225 - cache_free(pcache);
226 - } else {
227 - if (!reinitialize)
228 - warnf("(cache update pending) %s", ebuild);
229 - reinitialize = 1;
230 - }
231 - break;
232 + int overlay_fd = open(overlay, O_RDONLY|O_CLOEXEC|O_PATH);
233 + if (overlay_fd < 0) {
234 + fclose(fp);
235 + warnp("open failed: %s", overlay);
236 + ret = 1;
237 + continue;
238 }
239
240 - case CACHE_EBUILD: {
241 - FILE *ebuildfp;
242 - str = xstrdup(ebuild);
243 - p = dirname(str);
244 -
245 - if (strcmp(p, last) != 0) {
246 - bool show_it = false;
247 - strncpy(last, p, sizeof(last));
248 - if (search_name) {
249 - if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) {
250 - goto no_cache_ebuild_match;
251 - } else {
252 - q = NULL;
253 - show_it = true;
254 - }
255 - }
256 -
257 - int fd = openat(portdir_fd, ebuild, O_RDONLY|O_CLOEXEC);
258 - if (fd != -1) {
259 - ebuildfp = fdopen(fd, "r");
260 - if (ebuildfp == NULL) {
261 - close(fd);
262 - continue;
263 - }
264 - } else {
265 - if (!reinitialize)
266 - warnfp("(cache update pending) %s", ebuild);
267 - reinitialize = 1;
268 - goto no_cache_ebuild_match;
269 - }
270 -
271 - char *buf = NULL;
272 - size_t buflen;
273 - while ((linelen = getline(&buf, &buflen, ebuildfp)) != -1) {
274 - if (linelen <= search_len)
275 - continue;
276 - if (strncmp(buf, search_vars[idx], search_len) != 0)
277 - continue;
278 - if ((q = strrchr(buf, '"')) != NULL)
279 - *q = 0;
280 - if (strlen(buf) <= search_len)
281 - break;
282 - q = buf + search_len + 1;
283 - if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
284 - break;
285 - show_it = true;
286 - break;
287 - }
288 -
289 - if (show_it) {
290 - printf("%s%s/%s%s%s %s\n",
291 - BOLD, dirname(p), BLUE, basename(p), NORM,
292 - (show_name_only ? "" : q ? : "<no DESCRIPTION found>"));
293 - }
294 -
295 - free(buf);
296 - fclose(ebuildfp);
297 - }
298 -no_cache_ebuild_match:
299 - free(str);
300 + size_t buflen, linelen;
301 + char *buf = NULL;
302 + while ((linelen = getline(&buf, &buflen, fp)) != -1) {
303 + rmspace_len(buf, linelen);
304 + if (!buf[0])
305 + continue;
306
307 - break;
308 - } /* case CACHE_EBUILD */
309 - } /* switch (search_cache) */
310 + search_func(overlay_fd, buf, search_me, last, search_desc,
311 + search_all, search_name, show_name_only, show_homepage);
312 + }
313 + free(buf);
314 + close(overlay_fd);
315 + fclose(fp);
316 }
317 - free(ebuild);
318 - close(portdir_fd);
319 - fclose(fp);
320 - return EXIT_SUCCESS;
321 +
322 + return ret;
323 }
324
325 #else