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

Contents of /portage-utils/quse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.66 - (hide annotations) (download) (as text)
Sun Oct 28 04:16:19 2012 UTC (2 years, 1 month 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 solar 1.1 /*
2 solar 1.60 * Copyright 2005-2010 Gentoo Foundation
3 solar 1.1 * Distributed under the terms of the GNU General Public License v2
4 vapier 1.66 * $Header: /var/cvsroot/gentoo-projects/portage-utils/quse.c,v 1.65 2012/08/13 22:23:35 robbat2 Exp $
5 solar 1.1 *
6 solar 1.60 * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
7     * Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
8 solar 1.1 */
9    
10 vapier 1.47 #ifdef APPLET_quse
11 vapier 1.46
12 solar 1.23 /*
13     quse -CKe -- '-*' {'~',-,}{alpha,amd64,hppa,ia64,ppc,ppc64,sparc,x86}
14     quse -Ke -- nls
15     */
16    
17 solar 1.51 #define QUSE_FLAGS "eavKLDF:N" COMMON_FLAGS
18 vapier 1.2 static struct option const quse_long_opts[] = {
19 solar 1.20 {"exact", no_argument, NULL, 'e'},
20 solar 1.14 {"all", no_argument, NULL, 'a'},
21     {"keywords", no_argument, NULL, 'K'},
22 vapier 1.24 {"license", no_argument, NULL, 'L'},
23     {"describe", no_argument, NULL, 'D'},
24 solar 1.50 {"format", a_argument, NULL, 'F'},
25 solar 1.51 {"name-only", no_argument, NULL, 'N'},
26 vapier 1.2 COMMON_LONG_OPTS
27     };
28 vapier 1.63 static const char * const quse_opts_help[] = {
29 solar 1.20 "Show exact non regexp matching using strcmp",
30 solar 1.7 "Show annoying things in IUSE",
31 solar 1.14 "Use the KEYWORDS vs IUSE",
32     "Use the LICENSE vs IUSE",
33 vapier 1.24 "Describe the USE flag",
34 solar 1.50 "Use your own variable formats. -F NAME=",
35 solar 1.51 "Only show package name",
36 vapier 1.2 COMMON_OPTS_HELP
37     };
38 vapier 1.66 static const char quse_rcsid[] = "$Id: quse.c,v 1.65 2012/08/13 22:23:35 robbat2 Exp $";
39 solar 1.42 #define quse_usage(ret) usage(ret, QUSE_FLAGS, quse_long_opts, quse_opts_help, lookup_applet_idx("quse"))
40 vapier 1.2
41 robbat2 1.65 int quse_describe_flag(unsigned int ind, unsigned int argc, char **argv);
42 solar 1.34
43 solar 1.51 char quse_name_only = 0;
44    
45 vapier 1.53 static void print_highlighted_use_flags(char *string, int ind, int argc, char **argv)
46     {
47 solar 1.34 char *str, *p;
48     char buf[BUFSIZ];
49 solar 1.10 size_t pos, len;
50 solar 1.4 short highlight = 0;
51     int i;
52    
53 solar 1.51 if (quse_name_only)
54     return;
55    
56 solar 1.34 strncpy(buf, string, sizeof(buf));
57     str = buf;
58     remove_extra_space(str);
59     rmspace(str);
60    
61 solar 1.37 if (*WHITE != '\e') {
62 solar 1.4 printf("%s", str);
63     return;
64     }
65 solar 1.7
66 solar 1.10 len = strlen(str);
67     for (pos = 0; pos < len; pos++) {
68     highlight = 0;
69     if ((p = strchr(str, ' ')) != NULL)
70 solar 1.4 *p = 0;
71 solar 1.10 pos += strlen(str);
72 solar 1.11 for (i = ind; i < argc; ++i)
73 solar 1.10 if (strcmp(str, argv[i]) == 0)
74     highlight = 1;
75 solar 1.11 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 solar 1.4 }
82     }
83 solar 1.34
84 robbat2 1.65 int quse_describe_flag(unsigned int ind, unsigned int argc, char **argv)
85 vapier 1.24 {
86 vapier 1.64 #define NUM_SEARCH_FILES ARRAY_SIZE(search_files)
87     size_t buflen;
88     char *buf, *p;
89 robbat2 1.65 unsigned int i, f;
90 vapier 1.24 size_t s;
91 solar 1.33 const char *search_files[] = { "use.desc", "use.local.desc", "arch.list", "lang.desc" };
92 vapier 1.40 FILE *fp[NUM_SEARCH_FILES];
93 vapier 1.52 DIR *d;
94     struct dirent *de;
95 vapier 1.24
96 vapier 1.64 buflen = _Q_PATH_MAX;
97     buf = xmalloc(buflen);
98    
99 vapier 1.40 for (i = 0; i < NUM_SEARCH_FILES; ++i) {
100 vapier 1.64 snprintf(buf, buflen, "%s/profiles/%s", portdir, search_files[i]);
101 solar 1.33 if ((fp[i] = fopen(buf, "r")) == NULL)
102 vapier 1.66 if (strcmp(search_files[i], "lang.desc") != 0)
103 solar 1.56 warnp("skipping %s", search_files[i]);
104 solar 1.33 }
105 vapier 1.24
106 solar 1.34 for (i = ind; i < argc; i++) {
107 vapier 1.24 s = strlen(argv[i]);
108    
109 vapier 1.40 for (f = 0; f < NUM_SEARCH_FILES; ++f) {
110 vapier 1.24 if (fp[f] == NULL)
111     continue;
112    
113 vapier 1.64 while (getline(&buf, &buflen, fp[f]) != -1) {
114 vapier 1.24 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 solar 1.34 printf(" %sglobal%s:%s%s%s: %s\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3);
125 vapier 1.24 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 solar 1.34 printf(" %slocal%s:%s%s%s:%s%s%s %s\n", BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3);
137 vapier 1.24 }
138     }
139     break;
140    
141     case 2: /* Architectures arch.list */
142     if (!strcmp(buf, argv[i])) {
143 solar 1.34 printf(" %sarch%s:%s%s%s: %s architecture\n", BOLD, NORM, BLUE, argv[i], NORM, argv[i]);
144 vapier 1.24 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 solar 1.34 printf(" %slang%s:%s%s%s: %s lingua\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3);
152 vapier 1.24 goto skip_file;
153     }
154     break;
155     }
156     }
157    
158     skip_file:
159     rewind(fp[f]);
160     }
161     }
162    
163 solar 1.59 for (f=0; f < NUM_SEARCH_FILES; ++f)
164 vapier 1.55 if (fp[f] != NULL)
165     fclose(fp[f]);
166 vapier 1.24
167 vapier 1.52 /* now scan the desc dir */
168 vapier 1.64 snprintf(buf, buflen, "%s/profiles/desc/", portdir);
169 vapier 1.61 if ((d = opendir(buf)) == NULL) {
170     warnp("skipping profiles/desc/");
171 vapier 1.64 goto done;
172 vapier 1.61 }
173    
174 vapier 1.52 while ((de = readdir(d)) != NULL) {
175     if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc"))
176     continue;
177    
178 vapier 1.64 snprintf(buf, buflen, "%s/profiles/desc/%s", portdir, de->d_name);
179 vapier 1.66 if ((fp[0] = fopen(buf, "r")) == NULL) {
180 vapier 1.52 warn("Could not open '%s' for reading; skipping", de->d_name);
181     continue;
182     }
183    
184 vapier 1.64 while (getline(&buf, &buflen, fp[0]) != -1) {
185 vapier 1.52 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 vapier 1.64 done:
213     free(buf);
214 vapier 1.24 return 0;
215     }
216    
217 solar 1.1 int quse_main(int argc, char **argv)
218     {
219     FILE *fp;
220     char *p;
221 solar 1.20
222 vapier 1.43 char buf0[_Q_PATH_MAX];
223     char buf1[_Q_PATH_MAX];
224     char buf2[_Q_PATH_MAX];
225 solar 1.20
226 vapier 1.64 size_t ebuildlen;
227     char *ebuild;
228 solar 1.20
229 solar 1.14 const char *search_var = NULL;
230     const char *search_vars[] = { "IUSE=", "KEYWORDS=", "LICENSE=", search_var };
231 solar 1.49 short quse_all = 0;
232 vapier 1.24 int regexp_matching = 1, i, idx = 0;
233 solar 1.17 size_t search_len;
234 solar 1.1
235     DBG("argc=%d argv[0]=%s argv[1]=%s",
236     argc, argv[0], argc > 1 ? argv[1] : "NULL?");
237    
238 vapier 1.2 while ((i = GETOPT_LONG(QUSE, quse, "")) != -1) {
239     switch (i) {
240 solar 1.20 case 'e': regexp_matching = 0; break;
241 solar 1.49 case 'a': quse_all = 1; break;
242 vapier 1.24 case 'K': idx = 1; break;
243 solar 1.14 case 'L': idx = 2; break;
244 vapier 1.24 case 'D': idx = -1; break;
245 solar 1.50 case 'F': idx = 3, search_vars[idx] = xstrdup(optarg); break;
246 solar 1.51 case 'N': quse_name_only = 1; break;
247 vapier 1.2 COMMON_GETOPTS_CASES(quse)
248     }
249     }
250 solar 1.49 if (argc == optind && !quse_all && idx >= 0)
251 solar 1.20 quse_usage(EXIT_FAILURE);
252    
253 vapier 1.24 if (idx == -1)
254 solar 1.34 return quse_describe_flag(optind, argc, argv);
255 vapier 1.24
256 solar 1.49 if (quse_all) optind = argc;
257 solar 1.1 initialize_ebuild_flat(); /* sets our pwd to $PORTDIR */
258 solar 1.14
259     search_len = strlen(search_vars[idx]);
260 solar 1.21 assert(search_len < sizeof(buf0));
261 solar 1.14
262 solar 1.13 if ((fp = fopen(CACHE_EBUILD_FILE, "r")) == NULL)
263 solar 1.1 return 1;
264 vapier 1.64 ebuild = NULL;
265     while (getline(&ebuild, &ebuildlen, fp) != -1) {
266 solar 1.1 FILE *newfp;
267     if ((p = strchr(ebuild, '\n')) != NULL)
268     *p = 0;
269     if ((newfp = fopen(ebuild, "r")) != NULL) {
270 vapier 1.8 unsigned int lineno = 0;
271 solar 1.31 char revision[sizeof(buf0)];
272 solar 1.32 char date[sizeof(buf0)];
273 solar 1.31 char user[sizeof(buf0)];
274 solar 1.27
275     revision[0] = 0;
276     user[0] = 0;
277 solar 1.32 date[0] = 0;
278 vapier 1.66 while (fgets(buf0, sizeof(buf0), newfp) != NULL) {
279 solar 1.7 int ok = 0;
280 solar 1.26 char warned = 0;
281 solar 1.7 lineno++;
282 solar 1.14
283 solar 1.27 if (*buf0 == '#') {
284 vapier 1.66 if (strncmp(buf0, "# $Header: /", 12) == 0)
285 solar 1.32 sscanf(buf0, "%*s %*s %*s %s %s %*s %s %*s %*s", (char *) &revision, (char *) &date, (char *) &user);
286 solar 1.27 continue;
287     }
288 vapier 1.66 if (strncmp(buf0, search_vars[idx], search_len) != 0)
289 solar 1.7 continue;
290    
291 solar 1.20 if ((p = strchr(buf0, '\n')) != NULL)
292 solar 1.7 *p = 0;
293 vapier 1.29 if ((p = strchr(buf0, '#')) != NULL) {
294     if (buf0 != p && p[-1] == ' ')
295     p[-1] = 0;
296     else
297     *p = 0;
298     }
299 solar 1.26 if (verbose > 1) {
300 solar 1.20 if ((strchr(buf0, '\t') != NULL)
301 vapier 1.29 || (strchr(buf0, '$') != NULL)
302     || (strchr(buf0, '\\') != NULL)
303     || (strchr(buf0, '\'') != NULL)
304     || (strstr(buf0, " ") != NULL)) {
305 solar 1.26 warned = 1;
306     warn("# Line %d of %s has an annoying %s", lineno, ebuild, buf0);
307     }
308 solar 1.7 }
309 solar 1.19 #ifdef THIS_SUCKS
310 solar 1.20 if ((p = strrchr(&buf0[search_len+1], '\\')) != NULL) {
311 solar 1.7
312     multiline:
313     *p = ' ';
314    
315 vapier 1.66 if (fgets(buf1, sizeof(buf1), newfp) == NULL)
316 solar 1.17 continue;
317 solar 1.7 lineno++;
318    
319 solar 1.20 if ((p = strchr(buf1, '\n')) != NULL)
320 solar 1.4 *p = 0;
321 solar 1.20 snprintf(buf2, sizeof(buf2), "%s %s", buf0, buf1);
322     remove_extra_space(buf2);
323     strcpy(buf0, buf2);
324     if ((p = strrchr(buf1, '\\')) != NULL)
325 solar 1.7 goto multiline;
326     }
327 solar 1.19 #else
328 solar 1.20 remove_extra_space(buf0);
329 solar 1.27 #endif
330 solar 1.20 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 solar 1.14
334 solar 1.26 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 solar 1.20 if ((size_t)strlen(buf0) < (size_t)(search_len+1)) {
342 solar 1.54 /* warnf("err '%s'/%lu <= %lu; line %d\n", buf0, (unsigned long)strlen(buf0), (unsigned long)(search_len+1), lineno); */
343 solar 1.14 continue;
344     }
345 solar 1.11
346 solar 1.49 if ((argc == optind) || (quse_all)) {
347 solar 1.7 ok = 1;
348     } else {
349     ok = 0;
350 solar 1.20 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 solar 1.30 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 solar 1.20 *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 vapier 1.66 if (strchr(buf1, ' ') == NULL)
378 solar 1.23 for (i = (size_t) optind; i < argc && argv[i] != NULL; i++) {
379     if (strcmp(buf1, argv[i]) == 0) {
380     ok = 1;
381     }
382     }
383 solar 1.1 }
384 vapier 1.2 }
385 solar 1.1 }
386 solar 1.7 if (ok) {
387 solar 1.27 if (verbose > 3)
388 solar 1.32 printf("%s %s %s ", *user ? user : "MISSING", *revision ? revision : "MISSING", *date ? date : "MISSING");
389 solar 1.27
390 solar 1.7 printf("%s%s%s ", CYAN, ebuild, NORM);
391 solar 1.20 print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv);
392 solar 1.7 puts(NORM);
393 solar 1.34 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 solar 1.7 }
405     break;
406 solar 1.1 }
407     fclose(newfp);
408     } else {
409     if (!reinitialize)
410 vapier 1.57 warnfp("(cache update pending) %s", ebuild);
411 solar 1.1 reinitialize = 1;
412     }
413     }
414     fclose(fp);
415 vapier 1.12 return EXIT_SUCCESS;
416 solar 1.1 }
417 solar 1.45
418 vapier 1.48 #else
419     DEFINE_APPLET_STUB(quse)
420 vapier 1.46 #endif

  ViewVC Help
Powered by ViewVC 1.1.20