diff options
author | Mike Frysinger <vapier@gentoo.org> | 2015-11-27 14:04:10 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2015-11-27 14:04:10 -0500 |
commit | f162c6a9219deacfe23c8e21b732f8594a938130 (patch) | |
tree | 92ab6a1122480152afc6e87ed891591671c24a31 | |
parent | use the return value of getline (diff) | |
download | portage-utils-f162c6a9219deacfe23c8e21b732f8594a938130.tar.gz portage-utils-f162c6a9219deacfe23c8e21b732f8594a938130.tar.bz2 portage-utils-f162c6a9219deacfe23c8e21b732f8594a938130.zip |
qsearch: add multiple overlay support
We ractor some of the main code into helper funcs to make iterating
over the overlays easier to manage.
URL: https://bugs.gentoo.org/553260
-rw-r--r-- | qsearch.c | 268 |
1 files changed, 152 insertions, 116 deletions
@@ -31,18 +31,114 @@ static const char * const qsearch_opts_help[] = { }; #define qsearch_usage(ret) usage(ret, QSEARCH_FLAGS, qsearch_long_opts, qsearch_opts_help, lookup_applet_idx("qsearch")) -int qsearch_main(int argc, char **argv) +#define LAST_BUF_SIZE 256 + +/* Search an ebuild's details via the metadata cache. */ +static void +qsearch_ebuild_metadata(_q_unused_ int overlay_fd, const char *ebuild, const char *search_me, char *last, + bool search_desc, bool search_all, _q_unused_ bool search_name, bool show_name_only, bool show_homepage) +{ + portage_cache *pcache = cache_read_file(ebuild); + + if (pcache == NULL) { + if (!reinitialize) + warnf("(cache update pending) %s", ebuild); + reinitialize = 1; + return; + } + + if (strcmp(pcache->atom->PN, last) != 0) { + strncpy(last, pcache->atom->PN, LAST_BUF_SIZE); + if (search_all || rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0) + printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE, + pcache->atom->PN, NORM, + (show_name_only ? "" : + (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); + } + cache_free(pcache); +} + +/* Search an ebuild's details via the ebuild cache. */ +static void +qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me, char *last, + _q_unused_ bool search_desc, bool search_all, bool search_name, bool show_name_only, _q_unused_ bool show_homepage) { - FILE *fp; - char *ebuild = NULL; - char last[126] = ""; + const char * const search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" }; + const char *search_var = search_vars[show_homepage ? 1 : 0]; + size_t search_len = strlen(search_var); char *p, *q, *str; + + FILE *ebuildfp; + str = xstrdup(ebuild); + p = dirname(str); + + if (strcmp(p, last) == 0) + goto no_cache_ebuild_match; + + bool show_it = false; + strncpy(last, p, LAST_BUF_SIZE); + if (search_name) { + if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) { + goto no_cache_ebuild_match; + } else { + q = NULL; + show_it = true; + } + } + + int fd = openat(overlay_fd, ebuild, O_RDONLY|O_CLOEXEC); + if (fd != -1) { + ebuildfp = fdopen(fd, "r"); + if (ebuildfp == NULL) { + close(fd); + goto no_cache_ebuild_match; + } + } else { + if (!reinitialize) + warnfp("(cache update pending) %s", ebuild); + reinitialize = 1; + goto no_cache_ebuild_match; + } + + char *buf = NULL; + size_t buflen, linelen; + while ((linelen = getline(&buf, &buflen, ebuildfp)) != -1) { + if (linelen <= search_len) + continue; + if (strncmp(buf, search_var, search_len) != 0) + continue; + if ((q = strrchr(buf, '"')) != NULL) + *q = 0; + if (strlen(buf) <= search_len) + break; + q = buf + search_len + 1; + if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0) + break; + show_it = true; + break; + } + + if (show_it) { + printf("%s%s/%s%s%s %s\n", + BOLD, dirname(p), BLUE, basename(p), NORM, + (show_name_only ? "" : q ? : "<no DESCRIPTION found>")); + } + + free(buf); + fclose(ebuildfp); + no_cache_ebuild_match: + free(str); +} + +int qsearch_main(int argc, char **argv) +{ + char last[LAST_BUF_SIZE]; char *search_me = NULL; - char show_homepage = 0, show_name_only = 0; - char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD; - const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" }; - size_t search_len, ebuild_len, linelen; - int i, idx=0; + bool show_homepage = false, show_name_only = false; + bool search_desc = false, search_all = false, search_name = true; + int search_cache = CACHE_EBUILD; + int i; + void (*search_func)(int, const char *, const char *, char *last, bool, bool, bool, bool, bool); DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -50,132 +146,72 @@ int qsearch_main(int argc, char **argv) while ((i = GETOPT_LONG(QSEARCH, qsearch, "")) != -1) { switch (i) { COMMON_GETOPTS_CASES(qsearch) - case 'a': search_all = 1; break; + case 'a': search_all = true; break; case 'c': search_cache = CACHE_METADATA; break; case 'e': search_cache = CACHE_EBUILD; break; - case 's': search_desc = 0; search_name = 1; break; - case 'S': search_desc = 1; search_name = 0; break; - case 'N': show_name_only = 1; break; - case 'H': show_homepage = 1, idx = 1; break; + case 's': search_desc = false; search_name = true; break; + case 'S': search_desc = true; search_name = false; break; + case 'N': show_name_only = true; break; + case 'H': show_homepage = true; break; } } + switch (search_cache) { + case CACHE_METADATA: + search_func = qsearch_ebuild_metadata; + break; + case CACHE_EBUILD: + search_func = qsearch_ebuild_ebuild; + break; + default: + err("unknown cache %i", search_cache); + } + if (search_all) { - search_desc = 1; - search_name = 0; + search_desc = true; + search_name = false; } else { if (argc == optind) qsearch_usage(EXIT_FAILURE); search_me = argv[optind]; } last[0] = 0; - fp = fopen(initialize_flat(portdir, search_cache, false), "r"); - if (!fp) - return 1; - - int portdir_fd = open(portdir, O_RDONLY|O_CLOEXEC|O_PATH); - if (portdir_fd < 0) - errp("open(%s) failed", portdir); - - q = NULL; /* Silence a gcc warning. */ - search_len = strlen(search_vars[idx]); - while ((linelen = getline(&ebuild, &ebuild_len, fp)) != -1) { - rmspace_len(ebuild, linelen); - if (!ebuild[0]) + int ret = 0; + size_t n; + const char *overlay; + array_for_each(overlays, n, overlay) { + FILE *fp = fopen(initialize_flat(overlay, search_cache, false), "r"); + if (!fp) { + warnp("opening cache for %s failed", overlay); + ret = 1; continue; + } - switch (search_cache) { - - case CACHE_METADATA: { - portage_cache *pcache; - if ((pcache = cache_read_file(ebuild)) != NULL) { - if (strcmp(pcache->atom->PN, last) != 0) { - strncpy(last, pcache->atom->PN, sizeof(last)); - if ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0) || search_all) - printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE, - pcache->atom->PN, NORM, - (show_name_only ? "" : - (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); - } - cache_free(pcache); - } else { - if (!reinitialize) - warnf("(cache update pending) %s", ebuild); - reinitialize = 1; - } - break; + int overlay_fd = open(overlay, O_RDONLY|O_CLOEXEC|O_PATH); + if (overlay_fd < 0) { + fclose(fp); + warnp("open failed: %s", overlay); + ret = 1; + continue; } - case CACHE_EBUILD: { - FILE *ebuildfp; - str = xstrdup(ebuild); - p = dirname(str); - - if (strcmp(p, last) != 0) { - bool show_it = false; - strncpy(last, p, sizeof(last)); - if (search_name) { - if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) { - goto no_cache_ebuild_match; - } else { - q = NULL; - show_it = true; - } - } - - int fd = openat(portdir_fd, ebuild, O_RDONLY|O_CLOEXEC); - if (fd != -1) { - ebuildfp = fdopen(fd, "r"); - if (ebuildfp == NULL) { - close(fd); - continue; - } - } else { - if (!reinitialize) - warnfp("(cache update pending) %s", ebuild); - reinitialize = 1; - goto no_cache_ebuild_match; - } - - char *buf = NULL; - size_t buflen; - while ((linelen = getline(&buf, &buflen, ebuildfp)) != -1) { - if (linelen <= search_len) - continue; - if (strncmp(buf, search_vars[idx], search_len) != 0) - continue; - if ((q = strrchr(buf, '"')) != NULL) - *q = 0; - if (strlen(buf) <= search_len) - break; - q = buf + search_len + 1; - if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0) - break; - show_it = true; - break; - } - - if (show_it) { - printf("%s%s/%s%s%s %s\n", - BOLD, dirname(p), BLUE, basename(p), NORM, - (show_name_only ? "" : q ? : "<no DESCRIPTION found>")); - } - - free(buf); - fclose(ebuildfp); - } -no_cache_ebuild_match: - free(str); + size_t buflen, linelen; + char *buf = NULL; + while ((linelen = getline(&buf, &buflen, fp)) != -1) { + rmspace_len(buf, linelen); + if (!buf[0]) + continue; - break; - } /* case CACHE_EBUILD */ - } /* switch (search_cache) */ + search_func(overlay_fd, buf, search_me, last, search_desc, + search_all, search_name, show_name_only, show_homepage); + } + free(buf); + close(overlay_fd); + fclose(fp); } - free(ebuild); - close(portdir_fd); - fclose(fp); - return EXIT_SUCCESS; + + return ret; } #else |