/[gentoo-projects]/portage-utils/quse.c
Gentoo

Contents of /portage-utils/quse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.66 - (show annotations) (download) (as text)
Sun Oct 28 04:16:19 2012 UTC (20 months, 3 weeks ago) by vapier
Branch: MAIN
Changes since 1.65: +9 -9 lines
File MIME type: text/x-csrc
kill off more spurious/useless parens

1 /*
2 * Copyright 2005-2010 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/portage-utils/quse.c,v 1.65 2012/08/13 22:23:35 robbat2 Exp $
5 *
6 * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 #ifdef APPLET_quse
11
12 /*
13 quse -CKe -- '-*' {'~',-,}{alpha,amd64,hppa,ia64,ppc,ppc64,sparc,x86}
14 quse -Ke -- nls
15 */
16
17 #define QUSE_FLAGS "eavKLDF:N" COMMON_FLAGS
18 static struct option const quse_long_opts[] = {
19 {"exact", no_argument, NULL, 'e'},
20 {"all", no_argument, NULL, 'a'},
21 {"keywords", no_argument, NULL, 'K'},
22 {"license", no_argument, NULL, 'L'},
23 {"describe", no_argument, NULL, 'D'},
24 {"format", a_argument, NULL, 'F'},
25 {"name-only", no_argument, NULL, 'N'},
26 COMMON_LONG_OPTS
27 };
28 static const char * const quse_opts_help[] = {
29 "Show exact non regexp matching using strcmp",
30 "Show annoying things in IUSE",
31 "Use the KEYWORDS vs IUSE",
32 "Use the LICENSE vs IUSE",
33 "Describe the USE flag",
34 "Use your own variable formats. -F NAME=",
35 "Only show package name",
36 COMMON_OPTS_HELP
37 };
38 static const char quse_rcsid[] = "$Id: quse.c,v 1.65 2012/08/13 22:23:35 robbat2 Exp $";
39 #define quse_usage(ret) usage(ret, QUSE_FLAGS, quse_long_opts, quse_opts_help, lookup_applet_idx("quse"))
40
41 int quse_describe_flag(unsigned int ind, unsigned int argc, char **argv);
42
43 char quse_name_only = 0;
44
45 static void print_highlighted_use_flags(char *string, int ind, int argc, char **argv)
46 {
47 char *str, *p;
48 char buf[BUFSIZ];
49 size_t pos, len;
50 short highlight = 0;
51 int i;
52
53 if (quse_name_only)
54 return;
55
56 strncpy(buf, string, sizeof(buf));
57 str = buf;
58 remove_extra_space(str);
59 rmspace(str);
60
61 if (*WHITE != '\e') {
62 printf("%s", str);
63 return;
64 }
65
66 len = strlen(str);
67 for (pos = 0; pos < len; pos++) {
68 highlight = 0;
69 if ((p = strchr(str, ' ')) != NULL)
70 *p = 0;
71 pos += strlen(str);
72 for (i = ind; i < argc; ++i)
73 if (strcmp(str, argv[i]) == 0)
74 highlight = 1;
75 if (highlight)
76 printf("%s%s%s ", BOLD, str, NORM);
77 else
78 printf("%s%s%s%s ", NORM, MAGENTA, str, NORM);
79 if (p != NULL)
80 str = p + 1;
81 }
82 }
83
84 int quse_describe_flag(unsigned int ind, unsigned int argc, char **argv)
85 {
86 #define NUM_SEARCH_FILES ARRAY_SIZE(search_files)
87 size_t buflen;
88 char *buf, *p;
89 unsigned int i, f;
90 size_t s;
91 const char *search_files[] = { "use.desc", "use.local.desc", "arch.list", "lang.desc" };
92 FILE *fp[NUM_SEARCH_FILES];
93 DIR *d;
94 struct dirent *de;
95
96 buflen = _Q_PATH_MAX;
97 buf = xmalloc(buflen);
98
99 for (i = 0; i < NUM_SEARCH_FILES; ++i) {
100 snprintf(buf, buflen, "%s/profiles/%s", portdir, search_files[i]);
101 if ((fp[i] = fopen(buf, "r")) == NULL)
102 if (strcmp(search_files[i], "lang.desc") != 0)
103 warnp("skipping %s", search_files[i]);
104 }
105
106 for (i = ind; i < argc; i++) {
107 s = strlen(argv[i]);
108
109 for (f = 0; f < NUM_SEARCH_FILES; ++f) {
110 if (fp[f] == NULL)
111 continue;
112
113 while (getline(&buf, &buflen, fp[f]) != -1) {
114 if (buf[0] == '#' || buf[0] == '\n')
115 continue;
116
117 if ((p = strrchr(buf, '\n')) != NULL)
118 *p = '\0';
119
120 switch (f) {
121 case 0: /* Global use.desc */
122 if (!strncmp(buf, argv[i], s))
123 if (buf[s] == ' ' && buf[s+1] == '-') {
124 printf(" %sglobal%s:%s%s%s: %s\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3);
125 goto skip_file;
126 }
127 break;
128
129 case 1: /* Local use.local.desc */
130 if ((p = strchr(buf, ':')) == NULL)
131 break;
132 ++p;
133 if (!strncmp(p, argv[i], s)) {
134 if (p[s] == ' ' && p[s+1] == '-') {
135 *p = '\0';
136 printf(" %slocal%s:%s%s%s:%s%s%s %s\n", BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3);
137 }
138 }
139 break;
140
141 case 2: /* Architectures arch.list */
142 if (!strcmp(buf, argv[i])) {
143 printf(" %sarch%s:%s%s%s: %s architecture\n", BOLD, NORM, BLUE, argv[i], NORM, argv[i]);
144 goto skip_file;
145 }
146 break;
147
148 case 3: /* Languages lang.desc */
149 if (!strncmp(buf, argv[i], s))
150 if (buf[s] == ' ' && buf[s+1] == '-') {
151 printf(" %slang%s:%s%s%s: %s lingua\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3);
152 goto skip_file;
153 }
154 break;
155 }
156 }
157
158 skip_file:
159 rewind(fp[f]);
160 }
161 }
162
163 for (f=0; f < NUM_SEARCH_FILES; ++f)
164 if (fp[f] != NULL)
165 fclose(fp[f]);
166
167 /* now scan the desc dir */
168 snprintf(buf, buflen, "%s/profiles/desc/", portdir);
169 if ((d = opendir(buf)) == NULL) {
170 warnp("skipping profiles/desc/");
171 goto done;
172 }
173
174 while ((de = readdir(d)) != NULL) {
175 if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc"))
176 continue;
177
178 snprintf(buf, buflen, "%s/profiles/desc/%s", portdir, de->d_name);
179 if ((fp[0] = fopen(buf, "r")) == NULL) {
180 warn("Could not open '%s' for reading; skipping", de->d_name);
181 continue;
182 }
183
184 while (getline(&buf, &buflen, fp[0]) != -1) {
185 if (buf[0] == '#' || buf[0] == '\n')
186 continue;
187
188 if ((p = strrchr(buf, '\n')) != NULL)
189 *p = '\0';
190
191 if ((p = strchr(buf, '-')) == NULL) {
192 invalid_line:
193 warn("Invalid line in '%s': %s", de->d_name, buf);
194 continue;
195 }
196 while (p[-1] != ' ' && p[1] != ' ') {
197 /* maybe the flag has a '-' in it ... */
198 if ((p = strchr(p+1, '-')) == NULL)
199 goto invalid_line;
200 }
201 p[-1] = '\0';
202 p += 2;
203
204 for (i = ind; i < argc; i++)
205 if (!strcmp(argv[i], buf))
206 printf(" %s%s%s:%s%s%s: %s\n", BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p);
207 }
208 close(f);
209 }
210 closedir(d);
211
212 done:
213 free(buf);
214 return 0;
215 }
216
217 int quse_main(int argc, char **argv)
218 {
219 FILE *fp;
220 char *p;
221
222 char buf0[_Q_PATH_MAX];
223 char buf1[_Q_PATH_MAX];
224 char buf2[_Q_PATH_MAX];
225
226 size_t ebuildlen;
227 char *ebuild;
228
229 const char *search_var = NULL;
230 const char *search_vars[] = { "IUSE=", "KEYWORDS=", "LICENSE=", search_var };
231 short quse_all = 0;
232 int regexp_matching = 1, i, idx = 0;
233 size_t search_len;
234
235 DBG("argc=%d argv[0]=%s argv[1]=%s",
236 argc, argv[0], argc > 1 ? argv[1] : "NULL?");
237
238 while ((i = GETOPT_LONG(QUSE, quse, "")) != -1) {
239 switch (i) {
240 case 'e': regexp_matching = 0; break;
241 case 'a': quse_all = 1; break;
242 case 'K': idx = 1; break;
243 case 'L': idx = 2; break;
244 case 'D': idx = -1; break;
245 case 'F': idx = 3, search_vars[idx] = xstrdup(optarg); break;
246 case 'N': quse_name_only = 1; break;
247 COMMON_GETOPTS_CASES(quse)
248 }
249 }
250 if (argc == optind && !quse_all && idx >= 0)
251 quse_usage(EXIT_FAILURE);
252
253 if (idx == -1)
254 return quse_describe_flag(optind, argc, argv);
255
256 if (quse_all) optind = argc;
257 initialize_ebuild_flat(); /* sets our pwd to $PORTDIR */
258
259 search_len = strlen(search_vars[idx]);
260 assert(search_len < sizeof(buf0));
261
262 if ((fp = fopen(CACHE_EBUILD_FILE, "r")) == NULL)
263 return 1;
264 ebuild = NULL;
265 while (getline(&ebuild, &ebuildlen, fp) != -1) {
266 FILE *newfp;
267 if ((p = strchr(ebuild, '\n')) != NULL)
268 *p = 0;
269 if ((newfp = fopen(ebuild, "r")) != NULL) {
270 unsigned int lineno = 0;
271 char revision[sizeof(buf0)];
272 char date[sizeof(buf0)];
273 char user[sizeof(buf0)];
274
275 revision[0] = 0;
276 user[0] = 0;
277 date[0] = 0;
278 while (fgets(buf0, sizeof(buf0), newfp) != NULL) {
279 int ok = 0;
280 char warned = 0;
281 lineno++;
282
283 if (*buf0 == '#') {
284 if (strncmp(buf0, "# $Header: /", 12) == 0)
285 sscanf(buf0, "%*s %*s %*s %s %s %*s %s %*s %*s", (char *) &revision, (char *) &date, (char *) &user);
286 continue;
287 }
288 if (strncmp(buf0, search_vars[idx], search_len) != 0)
289 continue;
290
291 if ((p = strchr(buf0, '\n')) != NULL)
292 *p = 0;
293 if ((p = strchr(buf0, '#')) != NULL) {
294 if (buf0 != p && p[-1] == ' ')
295 p[-1] = 0;
296 else
297 *p = 0;
298 }
299 if (verbose > 1) {
300 if ((strchr(buf0, '\t') != NULL)
301 || (strchr(buf0, '$') != NULL)
302 || (strchr(buf0, '\\') != NULL)
303 || (strchr(buf0, '\'') != NULL)
304 || (strstr(buf0, " ") != NULL)) {
305 warned = 1;
306 warn("# Line %d of %s has an annoying %s", lineno, ebuild, buf0);
307 }
308 }
309 #ifdef THIS_SUCKS
310 if ((p = strrchr(&buf0[search_len+1], '\\')) != NULL) {
311
312 multiline:
313 *p = ' ';
314
315 if (fgets(buf1, sizeof(buf1), newfp) == NULL)
316 continue;
317 lineno++;
318
319 if ((p = strchr(buf1, '\n')) != NULL)
320 *p = 0;
321 snprintf(buf2, sizeof(buf2), "%s %s", buf0, buf1);
322 remove_extra_space(buf2);
323 strcpy(buf0, buf2);
324 if ((p = strrchr(buf1, '\\')) != NULL)
325 goto multiline;
326 }
327 #else
328 remove_extra_space(buf0);
329 #endif
330 while ((p = strrchr(&buf0[search_len+1], '"')) != NULL) *p = 0;
331 while ((p = strrchr(&buf0[search_len+1], '\'')) != NULL) *p = 0;
332 while ((p = strrchr(&buf0[search_len+1], '\\')) != NULL) *p = ' ';
333
334 if (verbose && warned == 0) {
335 if ((strchr(buf0, '$') != NULL) || (strchr(buf0, '\\') != NULL)) {
336 warned=1;
337 warn("# Line %d of %s has an annoying %s", lineno, ebuild, buf0);
338 }
339 }
340
341 if ((size_t)strlen(buf0) < (size_t)(search_len+1)) {
342 /* warnf("err '%s'/%lu <= %lu; line %d\n", buf0, (unsigned long)strlen(buf0), (unsigned long)(search_len+1), lineno); */
343 continue;
344 }
345
346 if ((argc == optind) || (quse_all)) {
347 ok = 1;
348 } else {
349 ok = 0;
350 if (regexp_matching) {
351 for (i = optind; i < argc; ++i) {
352 if (rematch(argv[i], &buf0[search_len+1], REG_NOSUB) == 0) {
353 ok = 1;
354 break;
355 }
356 }
357 } else {
358 remove_extra_space(buf0);
359 strcpy(buf1, &buf0[search_len+1]);
360
361 for (i = (size_t) optind; i < argc && argv[i] != NULL; i++) {
362 if (strcmp(buf1, argv[i]) == 0) {
363 ok = 1;
364 break;
365 }
366 }
367 if (ok == 0) while ((p = strchr(buf1, ' ')) != NULL) {
368 *p = 0;
369 for (i = (size_t) optind; i < argc && argv[i] != NULL; i++) {
370 if (strcmp(buf1, argv[i]) == 0) {
371 ok = 1;
372 break;
373 }
374 }
375 strcpy(buf2, p + 1);
376 strcpy(buf1, buf2);
377 if (strchr(buf1, ' ') == NULL)
378 for (i = (size_t) optind; i < argc && argv[i] != NULL; i++) {
379 if (strcmp(buf1, argv[i]) == 0) {
380 ok = 1;
381 }
382 }
383 }
384 }
385 }
386 if (ok) {
387 if (verbose > 3)
388 printf("%s %s %s ", *user ? user : "MISSING", *revision ? revision : "MISSING", *date ? date : "MISSING");
389
390 printf("%s%s%s ", CYAN, ebuild, NORM);
391 print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv);
392 puts(NORM);
393 if (verbose > 1) {
394 char **ARGV = NULL;
395 int ARGC = 0;
396 makeargv(&buf0[search_len+1], &ARGC, &ARGV);
397 if (ARGC > 0) {
398 quse_describe_flag(1, ARGC, ARGV);
399 for (i = 0; i < ARGC; i++)
400 free(ARGV[i]);
401 free(ARGV);
402 }
403 }
404 }
405 break;
406 }
407 fclose(newfp);
408 } else {
409 if (!reinitialize)
410 warnfp("(cache update pending) %s", ebuild);
411 reinitialize = 1;
412 }
413 }
414 fclose(fp);
415 return EXIT_SUCCESS;
416 }
417
418 #else
419 DEFINE_APPLET_STUB(quse)
420 #endif

  ViewVC Help
Powered by ViewVC 1.1.20