Let's do something.. hum. :/ mkay, trying to show the different patches with color
diff -Narup portage-utils-20070504/applet-list portage-utils-20070504.new/applet-list --- portage-utils-20070504/applet-list 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/applet-list 2007-05-04 09:05:54.469792120 +0200 @@ -1,13 +1,10 @@ qatom -qcache qcheck qdepends qfile -qglsa qgrep qlist qlop -qmerge qpkg qsearch qsize diff -Narup portage-utils-20070504/applets.h portage-utils-20070504.new/applets.h --- portage-utils-20070504/applets.h 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/applets.h 2007-05-04 09:05:54.480790442 +0200 @@ -29,8 +29,8 @@ DECLARE_APPLET(qxpak) DECLARE_APPLET(qpkg) DECLARE_APPLET(qgrep) DECLARE_APPLET(qatom) -DECLARE_APPLET(qmerge) -DECLARE_APPLET(qcache) +DECLARE_APPLET(qmerge) /* disable */ +DECLARE_APPLET(qcache) /* disable */ DECLARE_APPLET(qglsa) /* disable */ #undef DECLARE_APPLET @@ -48,21 +48,21 @@ struct applet_t { /* q must always be the first applet */ {"q", q_main, "<applet> <args>", "virtual applet"}, {"qatom", qatom_main, "<pkg>", "split atom strings"}, - {"qcache", qcache_main, "<action> <args>", "search the metadata cache"}, {"qcheck", qcheck_main, "<pkgname>", "verify integrity of installed packages"}, {"qdepends", qdepends_main, "<pkgname>", "show dependency info"}, {"qfile", qfile_main, "<filename>", "list all pkgs owning files"}, - {"qglsa", qglsa_main, "<action> <list>", "check GLSAs against system"}, {"qgrep", qgrep_main, "<misc args>", "grep in ebuilds"}, {"qlist", qlist_main, "<pkgname>", "list files owned by pkgname"}, {"qlop", qlop_main, "<pkgname>", "emerge log analyzer"}, - {"qmerge", qmerge_main, "<pkgnames>", "fetch and merge binary package"}, {"qpkg", qpkg_main, "<misc args>", "manipulate Gentoo binpkgs"}, {"qsearch", qsearch_main, "<regex>", "search pkgname/desc"}, {"qsize", qsize_main, "<pkgname>", "calculate size usage"}, {"qtbz2", qtbz2_main, "<misc args>", "manipulate tbz2 packages"}, {"quse", quse_main, "<useflag>", "find pkgs using useflags"}, {"qxpak", qxpak_main, "<misc args>", "manipulate xpak archives"}, + {"qcache", qcache_main, "<action> <args>", NULL}, /* "search the metadata cache" */ + {"qglsa", qglsa_main, "<action> <list>", NULL}, /* "check GLSAs against system" */ + {"qmerge", qmerge_main, "<pkgnames>", NULL}, /* "fetch and merge binary package" */ /* aliases for equery capatability */ diff -Narup portage-utils-20070504/libq/atom_compare.c portage-utils-20070504.new/libq/atom_compare.c --- portage-utils-20070504/libq/atom_compare.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/libq/atom_compare.c 2007-05-04 09:05:54.487789374 +0200 @@ -43,11 +43,27 @@ int atom_compare(const depend_atom * con /* check version */ if (a1->PV && a2->PV) { + int i; char *s1, *s2; unsigned int n1, n2; /* first we compare the version [1.0]z_alpha1 */ s1 = a1->PV; s2 = a2->PV; + /* treat the case of svn/live/scm/cvs.. version */ + n1=n2=0; + for (i=0; i<ARR_SIZE(atom_version_str); ++i) { + if (!strcmp(s1,&atom_version_str[i].version[1])) + n1=1; + if (!strcmp(s2,&atom_version_str[i].version[1])) + n2=1; + } + if (n1+n2) { + if (n1==n2) + goto same_version; + else + return (n1<n2 ? OLDER : NEWER); + } + while (s1 || s2) { if (s1 && s2) { /* deal with leading zeros */ @@ -101,7 +117,7 @@ int atom_compare(const depend_atom * con /* fall through to -r# check below */ } else if (a1->PV || a2->PV) return NOT_EQUAL; - +same_version: if (a1->PR_int == a2->PR_int) return EQUAL; else if (a1->PR_int < a2->PR_int) diff -Narup portage-utils-20070504/libq/atom_explode.c portage-utils-20070504.new/libq/atom_explode.c --- portage-utils-20070504/libq/atom_explode.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/libq/atom_explode.c 2007-05-04 09:05:54.495788154 +0200 @@ -13,8 +13,21 @@ typedef enum { VER_ALPHA=0, VER_BETA, VER_PRE, VER_RC, VER_NORM, VER_P } atom_suffixes; const char * const atom_suffixes_str[] = { "_alpha", "_beta", "_pre", "_rc", "_/*bogus*/", "_p", NULL }; +const struct { + const char *version; + const size_t version_len; +} atom_version_str[] = { + {"-scm", 4}, + {"-cvs", 4}, + {"-svn", 4}, + {"-live", 5}, + {"-9999", 5} +}; + + typedef struct { + char *OVERLAY; char *CATEGORY; char *PN; int PR_int; @@ -61,6 +74,16 @@ depend_atom *atom_explode(const char *at ret->suffix = VER_NORM; memcpy(ret->CATEGORY, atom, slen); + /* find the OVERLAY, if present */ + if ((ptr_tmp=strstr(ret->CATEGORY, "::"))) { + if (*(ptr_tmp+2)) + ret->OVERLAY = ptr_tmp + 2; + else + ret->OVERLAY = NULL; + *ptr_tmp = 0; + ptr_tmp = NULL; + } + /* break up the CATEOGRY and PVR */ if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL) { ret->PN = ptr+1; @@ -144,6 +167,16 @@ eat_version: ret->PV = ptr_tmp+1; ret->PV[-1] = '\0'; goto found_pv; + } + + for (i=0; i<ARR_SIZE(atom_version_str); ++i) + if ((ptr_tmp = strstr(ret->PN, atom_version_str[i].version)) && ptr_tmp == ret->PN+strlen(ret->PN)-atom_version_str[i].version_len) + break; + + if (ptr_tmp && *ptr_tmp) { + ret->PV = ptr_tmp+1; + ret->PV[-1] = '\0'; + goto found_pv; } else { /* atom has no version */ ret->PV = ret->PVR = NULL; diff -Narup portage-utils-20070504/main.c portage-utils-20070504.new/main.c --- portage-utils-20070504/main.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/main.c 2007-05-04 09:15:46.696444231 +0200 @@ -70,9 +70,22 @@ static char eat_file(const char *file, c int rematch(const char *, const char *, int); static char *rmspace(char *); +typedef struct overlay_t overlay_t; +struct overlay_t { + char name[64]; + char path[_Q_PATH_MAX]; + char cache[_Q_PATH_MAX]; + /* if overlay/profiles/categories exist, this will contain the categories listing */ + char **categories; + struct overlay_t *next; +}; + +static overlay_t *first_overlay = NULL; + void initialize_portage_env(void); -void initialize_ebuild_flat(void); -void reinitialize_ebuild_flat(void); +void initialize_overlays (char portdir_overlay[]); +void initialize_ebuild_flat(short force); +void reinitialize_ebuild_flat(short force); void reinitialize_as_needed(void); void cleanup(void); int lookup_applet_idx(const char *); @@ -82,16 +95,19 @@ static char exact = 0; static int found = 0; static int verbose = 0; static int quiet = 0; +static int max_categories = 200; static char pretend = 0; static char reinitialize = 0; static char reinitialize_metacache = 0; -static char portdir[_Q_PATH_MAX] = "/usr/portage"; static char portarch[20] = ""; -static char portvdb[] = "var/db/pkg"; +static char portvdb[_Q_PATH_MAX] = "var/db/pkg"; static char portcachedir[] = "metadata/cache"; static char portroot[_Q_PATH_MAX] = "/"; static char config_protect[_Q_PATH_MAX] = "/etc/"; +/* temporary workaround ? */ +static overlay_t *overlay_gentoo = NULL; + char pkgdir[512] = "/usr/portage/packages/"; char port_tmpdir[512] = "/var/tmp/portage/"; @@ -201,10 +217,10 @@ static void usage(int status, const char for (i = 0; opts[i].name; ++i) { assert(help[i] != NULL); /* this assert is a life saver when adding new applets. */ if (opts[i].has_arg == no_argument) - printf(" -%c, --%-15s%s*%s %s\n", opts[i].val, + printf(" -%c, --%-16s%s*%s %s\n", opts[i].val, opts[i].name, RED, NORM, _(help[i])); else - printf(" -%c, --%-8s %s<arg>%s %s*%s %s\n", opts[i].val, + printf(" -%c, --%-9s %s<arg>%s %s*%s %s\n", opts[i].val, opts[i].name, DKBLUE, NORM, RED, NORM, _(help[i])); } exit(status); @@ -469,17 +485,107 @@ char *strincr_var(const char *name, char return (char *) value; } +void initialize_overlays (char portdir_overlay[]) +{ + short merror = 0; + int i; + char buf[BUFSIZE], file[_Q_PATH_MAX], category[32], *s, *p, *t; + overlay_t *cur_overlay; + FILE *fp; + s = portdir_overlay; + + first_overlay = xmalloc(sizeof(*first_overlay)); + cur_overlay = first_overlay; + + while (*s) { + /* except on the first loop */ + if (s!=portdir_overlay) { + cur_overlay->next = xmalloc (sizeof (*cur_overlay->next)); + cur_overlay = cur_overlay->next; + } + cur_overlay->next = NULL; + + if ((p=strchr(s,' '))) + *p = 0; + + snprintf(cur_overlay->path, sizeof(cur_overlay->path), "%s%s", (strcmp(portroot, "/") ? portroot : ""), s); + + /* find the name for the overlay */ + snprintf(file, sizeof(file), "%s/profiles/repo_name", cur_overlay->path); + if ((fp = fopen(file, "r"))) { + if (!(fgets(buf, sizeof(buf),fp))) + merror++; + rmspace(buf); + if ((t = strchr(buf,'\n'))) + *t = 0; + strncpy(cur_overlay->name, buf, sizeof(cur_overlay->name)); + + fclose(fp); + } else + merror++; + + if (merror) { + /* delete trailing '/' */ + t = cur_overlay->path + strlen(cur_overlay->path) - 1; + if (*t == '/') + *t = 0; + strncpy(file, cur_overlay->path, sizeof(file)); + strncpy(cur_overlay->name, basename(file), sizeof(cur_overlay->name)); + merror=0; + } + + /* now we test if overlay/profiles/categories exist, and if it does we fill cur_overlay->categories */ + snprintf(file, sizeof(file), "%s/profiles/categories", cur_overlay->path); + if ((fp = fopen(file, "r"))) { + cur_overlay->categories = xmalloc(max_categories*sizeof(char *)); + i = 0; + while (i < max_categories && (fgets(category, sizeof(category), fp))) { + if ((t = strchr(category, '\n'))) + *t = 0; + if (t==category) + continue; + cur_overlay->categories[i] = xstrdup(category); + i++; + } + if (i == max_categories) + warn("It might be time to increase max_categories"); + else + cur_overlay->categories[i] = NULL; + fclose(fp); + } else + cur_overlay->categories = NULL; + + /* if the gentoo overlay is found, then we make a pointer to it */ + if (!strncmp(cur_overlay->name, "gentoo", sizeof(cur_overlay->name))) { + snprintf(cur_overlay->cache, sizeof(cur_overlay->cache), "%s/%s", cur_overlay->path, portcachedir); + overlay_gentoo = cur_overlay; + } else + strcpy(cur_overlay->cache, "/var/empty"); + + if (p) + s = p+1; /* because portdir_overlay has no trailing space */ + else + break; + } + +} + + void initialize_portage_env(void) { char nocolor = 0; int i, f; struct stat st; FILE *fp; + char tmp_portdir[_Q_PATH_MAX]; char buf[BUFSIZE], *s, *p; char profile[_Q_PATH_MAX], portage_file[_Q_PATH_MAX]; + char portdir_overlay[BUFSIZE] = ""; + const char *files[] = {portage_file, "/etc/make.globals", "/etc/make.conf"}; typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types; + struct { const char *name; const size_t name_len; @@ -493,7 +599,8 @@ void initialize_portage_env(void) {"CONFIG_PROTECT", 14, _Q_STR, config_protect, sizeof(config_protect)}, {"NOCOLOR", 7, _Q_BOOL, &nocolor, 1}, {"FEATURES", 8, _Q_ISTR, features, sizeof(features)}, - {"PORTDIR", 7, _Q_STR, portdir, sizeof(portdir)}, + {"PORTDIR", 7, _Q_STR, tmp_portdir, sizeof(tmp_portdir)}, + {"PORTDIR_OVERLAY", 15, _Q_ISTR, portdir_overlay,sizeof(portdir_overlay)}, {"PORTAGE_BINHOST", 15, _Q_STR, binhost, sizeof(binhost)}, {"PORTAGE_TMPDIR", 14, _Q_STR, port_tmpdir, sizeof(port_tmpdir)}, {"PKGDIR", 6, _Q_STR, pkgdir, sizeof(pkgdir)}, @@ -595,6 +702,15 @@ void initialize_portage_env(void) no_colors(); else color_remap(); + + /* we add the gentoo repository in the overlay list */ + strincr_var("PORTDIR_OVERLAY", tmp_portdir, portdir_overlay, sizeof(portdir_overlay)); + snprintf(tmp_portdir, sizeof(tmp_portdir), "%s/%s", (strcmp(portroot, "/") ? portroot : ""), portvdb); + strncpy(portvdb, tmp_portdir, sizeof(portvdb)); + + /* now we initialiase the overlay chained list */ + initialize_overlays(portdir_overlay); + } enum { @@ -611,113 +727,153 @@ int filter_hidden(const struct dirent *d } #define CACHE_EBUILD_FILE (getenv("CACHE_EBUILD_FILE") ? getenv("CACHE_EBUILD_FILE") : ".ebuild.x") -#define CACHE_METADATA_FILE ".metadata.x" -const char *initialize_flat(int cache_type); -const char *initialize_flat(int cache_type) +#define CACHE_METADATA_FILE (getenv("CACHE_METADATA_FILE") ? getenv("CACHE_METADATA_FILE") : ".metadata.x") +const char *initialize_flat(int cache_type, short force); +const char *initialize_flat(int cache_type, short force) { struct dirent **category, **pn, **eb; struct stat st; struct timeval start, finish; static const char *cache_file; char *p; - int a, b, c, d, e, i; + int a, b, c, d, e, i, k; int frac, secs, count; FILE *fp; + overlay_t *cur_overlay; a = b = c = d = e = i = 0; count = frac = secs = 0; + cur_overlay = first_overlay; cache_file = (cache_type == CACHE_EBUILD ? CACHE_EBUILD_FILE : CACHE_METADATA_FILE); - if (chdir(portdir) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); - goto ret; - } - - if (cache_type == CACHE_METADATA && chdir(portcachedir) != 0) { - warnp("chdir to portage cache '%s/%s' failed", portdir, portcachedir); - goto ret; + if (cache_type == CACHE_METADATA) { + /* if it's full path no need to chdir */ + if (CACHE_METADATA_FILE[0] != '/' ) { + if (chdir(overlay_gentoo->cache) != 0) { + warnp("chdir to portage cache '%s' failed", overlay_gentoo->cache); + goto ret; + } + } + } else { + /* if it's full path no need to chdir */ + if (CACHE_EBUILD_FILE[0] != '/' ) { + if (chdir(overlay_gentoo->path) != 0) { + warnp("chdir to PORTDIR '%s' failed", overlay_gentoo->path); + goto ret; + } + } } - if ((stat(cache_file, &st)) != (-1)) - if (st.st_size == 0) + if ((stat(cache_file, &st)) != (-1)) { + if (force || st.st_size == 0) unlink(cache_file); + else + goto ret; + } - /* assuming --sync is used with --delete this will get recreated after every merge */ - if (access(cache_file, R_OK) == 0) - goto ret; if (!quiet) warn("Updating ebuild %scache ... ", cache_type == CACHE_EBUILD ? "" : "meta"); unlink(cache_file); if (errno != ENOENT) { - warnfp("unlinking '%s/%s' failed", portdir, cache_file); + warnfp("unlinking '%s/%s' failed", (cache_type == CACHE_EBUILD ? overlay_gentoo->path : overlay_gentoo->cache), cache_file); + warn("define CACHE_METADATA_FILE and/or CACHE_EBUILD_FILE to use different cache file"); goto ret; } if ((fp = fopen(cache_file, "w")) == NULL) { - if (cache_type == CACHE_EBUILD) - warnfp("opening '%s/%s' failed", portdir, cache_file); - else - warnfp("opening '%s/%s/%s' failed", portdir, portcachedir, cache_file); - if (errno == EACCES) - warnf("You should run this command as root: q -%c", - cache_type == CACHE_EBUILD ? 'r' : 'm'); + warnfp("opening '%s/%s' failed", (cache_type == CACHE_EBUILD ? overlay_gentoo->path : overlay_gentoo->cache), cache_file); goto ret; } gettimeofday(&start, NULL); - if ((a = scandir(".", &category, filter_hidden, alphasort)) < 0) - goto ret; - - for (i = 0; i < a; i++) { - stat(category[i]->d_name, &st); - if (!S_ISDIR(st.st_mode)) - continue; - if (strchr(category[i]->d_name, '-') == NULL) - if ((strncmp(category[i]->d_name, "virtual", 7)) != 0) + do { + switch (cache_type) { + case CACHE_EBUILD: + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository", cur_overlay->path, cur_overlay->name); continue; - - if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) + } + break; + case CACHE_METADATA: + if (!strcmp(cur_overlay->cache, "/var/empty")) { + if (verbose) + warnp("No cache defined for the %s repository", cur_overlay->name); + continue; + } else if (chdir(cur_overlay->cache) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository",cur_overlay->cache, cur_overlay->name); + continue; + } + break; + } + if ((a = scandir(".", &category, filter_hidden, alphasort)) < 0) continue; - for (c = 0; c < b; c++) { - char de[_Q_PATH_MAX]; - snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->d_name); + for (i = 0; i < a; i++) { + /* if overlay/profiles/categories exist, then just consider those categories */ + /* instead of the whole listing */ + if (cur_overlay->categories) { + k = 0; + while (k<max_categories && cur_overlay->categories[k]) { + if (!strncmp(cur_overlay->categories[k], category[i]->d_name, strlen(cur_overlay->categories[k]))) + break; + k++; + } + if (k<max_categories && !cur_overlay->categories[k]) + continue; + } - if (stat(de, &st) < 0) + stat(category[i]->d_name, &st); + if (!S_ISDIR(st.st_mode)) continue; - - switch (cache_type) { - case CACHE_EBUILD: - if (!S_ISDIR(st.st_mode)) + if (strchr(category[i]->d_name, '-') == NULL) + if ((strncmp(category[i]->d_name, "virtual", 7)) != 0) continue; - break; - case CACHE_METADATA: - if (S_ISREG(st.st_mode)) - fprintf(fp, "%s\n", de); - continue; - break; - } - if ((e = scandir(de, &eb, filter_hidden, alphasort)) < 0) + + if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) continue; - for (d = 0; d < e; d++) { - if ((p = strrchr(eb[d]->d_name, '.')) != NULL) - if (strcmp(p, ".ebuild") == 0) { + for (c = 0; c < b; c++) { + char de[_Q_PATH_MAX]; + + snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->d_name); + + if (stat(de, &st) < 0) + continue; + + switch (cache_type) { + case CACHE_EBUILD: + if (!S_ISDIR(st.st_mode)) + continue; + break; + case CACHE_METADATA: + if (S_ISREG(st.st_mode)) count++; - fprintf(fp, "%s/%s/%s\n", category[i]->d_name, pn[c]->d_name, eb[d]->d_name); - } + fprintf(fp, "%s::%s\n", de, cur_overlay->name); + continue; + break; + } + if ((e = scandir(de, &eb, filter_hidden, alphasort)) < 0) + continue; + for (d = 0; d < e; d++) { + if ((p = strrchr(eb[d]->d_name, '.')) != NULL) + if (strcmp(p, ".ebuild") == 0) { + count++; + fprintf(fp, "%s/%s/%s::%s\n", category[i]->d_name, pn[c]->d_name, eb[d]->d_name, cur_overlay->name); + } + } + while (d--) free(eb[d]); + free(eb); } - while (d--) free(eb[d]); - free(eb); + while (b--) free(pn[b]); + free(pn); } - while (b--) free(pn[b]); - free(pn); - } + while (a--) free(category[a]); + free(category); + } while ((cur_overlay = cur_overlay->next)); + fclose(fp); - while (a--) free(category[a]); - free(category); if (quiet) goto ret; @@ -734,32 +890,32 @@ const char *initialize_flat(int cache_ty warn("Finished %u entries in %d.%06d seconds", count, secs, frac); if (secs > 100) #ifdef __linux__ - warn("You should consider a faster file system such as reiserfs for PORTDIR='%s'", portdir); + warn("You should consider a faster file system such as reiserfs for repositories"); #else - warn("You should consider using the noatime mount option for PORTDIR='%s' if it's not already enabled", portdir); + warn("You should consider using the noatime mount option for repositories if it's not already enabled"); #endif ret: return cache_file; } -#define initialize_ebuild_flat() initialize_flat(CACHE_EBUILD) -#define initialize_metadata_flat() initialize_flat(CACHE_METADATA) +#define initialize_ebuild_flat(force) initialize_flat(CACHE_EBUILD, force) +#define initialize_metadata_flat(force) initialize_flat(CACHE_METADATA, force) -void reinitialize_ebuild_flat(void) +void reinitialize_ebuild_flat(short force) { - if ((chdir(portdir)) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); + if ((chdir(first_overlay->path)) != 0) { + warnp("chdir to PORTDIR '%s' failed", first_overlay->path); return; } unlink(CACHE_EBUILD_FILE); - initialize_ebuild_flat(); + initialize_ebuild_flat(force); } void reinitialize_as_needed(void) { if (reinitialize) - reinitialize_ebuild_flat(); + reinitialize_ebuild_flat(1); if (reinitialize_metacache) - initialize_metadata_flat(); + initialize_metadata_flat(1); } typedef struct { @@ -783,8 +939,8 @@ typedef struct { } portage_cache; void cache_free(portage_cache *cache); -portage_cache *cache_read_file(const char *file); -portage_cache *cache_read_file(const char *file) +portage_cache *cache_read_file(char *file); +portage_cache *cache_read_file(char *file) { struct stat s; char *ptr; @@ -792,8 +948,12 @@ portage_cache *cache_read_file(const cha portage_cache *ret = NULL; size_t len; + if ((ptr = strstr(file, "::"))) + *ptr = 0; if ((f = fopen(file, "r")) == NULL) goto err; + if (ptr) + *ptr = ':'; if (fstat(fileno(f), &s) != 0) goto err; @@ -1022,10 +1182,30 @@ fuckit: return cpf; } +/* free overlays */ +void free_overlays(overlay_t *overlay); +void free_overlays(overlay_t *overlay) +{ + int i; + if (overlay->next) + free_overlays(overlay->next); + if (overlay->categories) { + for (i=0; i<max_categories; i++) { + if (overlay->categories[i]) + free(overlay->categories[i]); + else + break; + } + free(overlay->categories); + } + free(overlay); +} + void cleanup() { reinitialize_as_needed(); free_sets(virtuals); + free_overlays(first_overlay); fclose(stderr); } @@ -1054,3 +1234,5 @@ int main(int argc, char **argv) } #include "include_applets.h" +/* vim: set noet sts=8 sw=8 : */ + diff -Narup portage-utils-20070504/man/q.1 portage-utils-20070504.new/man/q.1 --- portage-utils-20070504/man/q.1 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/man/q.1 2007-05-04 09:05:54.521784188 +0200 @@ -61,11 +61,14 @@ quse <useflag> qxpak <misc args> : manipulate xpak archives .PP -Options: \fB\-[irmvqChV]\fR +Options: \fB\-[ilrmvqChV]\fR .TP \fB\-i\fR, \fB\-\-install\fR * Install symlinks for applets .TP +\fB\-l\fR, \fB\-\-ls\-overlays\fR +* List configured overlays +.TP \fB\-r\fR, \fB\-\-reinitialize\fR * Reinitialize ebuild cache .TP diff -Narup portage-utils-20070504/man/qgrep.1 portage-utils-20070504.new/man/qgrep.1 --- portage-utils-20070504/man/qgrep.1 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/man/qgrep.1 2007-05-04 09:05:54.529782968 +0200 @@ -19,6 +19,11 @@ Options: \fB\-[IiHNclLexJEsS:B:A:vqChV]\ \fB\-N\fR, \fB\-\-with\-name\fR * Print the package or eclass name for each match .TP +\fB\-o\fR, \fB\-\-overlay\fR +<arg> +.BR + * Only consider the <arg> overlay +.TP \fB\-c\fR, \fB\-\-count\fR * Only print a count of matching lines per FILE .TP diff -Narup portage-utils-20070504/man/qgrep.1.orig portage-utils-20070504.new/man/qgrep.1.orig --- portage-utils-20070504/man/qgrep.1.orig 1970-01-01 01:00:00.000000000 +0100 +++ portage-utils-20070504.new/man/qgrep.1.orig 2007-05-04 09:05:54.530782815 +0200 @@ -0,0 +1,73 @@ +.TH qgrep "1" "April 2007" "Gentoo Foundation" "qgrep" +.SH NAME +qgrep \- grep in ebuilds +.SH SYNOPSIS +.B qgrep +\fI<misc args>\fR +.SH DESCRIPTION +Options: \fB\-[IiHNclLexJEsS:B:A:vqChV]\fR +.TP +\fB\-I\fR, \fB\-\-invert\-match\fR +* Select non\-matching lines +.TP +\fB\-i\fR, \fB\-\-ignore\-case\fR +* Ignore case distinctions +.TP +\fB\-H\fR, \fB\-\-with\-filename\fR +* Print the filename for each match +.TP +\fB\-N\fR, \fB\-\-with\-name\fR +* Print the package or eclass name for each match +.TP +\fB\-c\fR, \fB\-\-count\fR +* Only print a count of matching lines per FILE +.TP +\fB\-l\fR, \fB\-\-list\fR +* Only print FILE names containing matches +.TP +\fB\-L\fR, \fB\-\-invert\-list\fR +* Only print FILE names containing no match +.TP +\fB\-e\fR, \fB\-\-regexp\fR +* Use PATTERN as a regular expression +.TP +\fB\-x\fR, \fB\-\-extended\fR +* Use PATTERN as an extended regular expression +.TP +\fB\-J\fR, \fB\-\-installed\fR +* Search in installed ebuilds instead of the tree +.TP +\fB\-E\fR, \fB\-\-eclass\fR +* Search in eclasses instead of ebuilds +.TP +\fB\-s\fR, \fB\-\-skip\-comments\fR +* Skip comments lines +.TP +\fB\-S\fR, \fB\-\-skip\fR <arg> +.BR + * Skip lines matching <arg> +.TP +\fB\-B\fR, \fB\-\-before\fR <arg> +.BR + * Print <arg> lines of leading context +.TP +\fB\-A\fR, \fB\-\-after\fR <arg> +.BR + * Print <arg> lines of trailing context +.TP +\fB\-v\fR, \fB\-\-verbose\fR +* Make a lot of noise +.TP +\fB\-q\fR, \fB\-\-quiet\fR +* Tighter output; suppress warnings +.TP +\fB\-C\fR, \fB\-\-nocolor\fR +* Don't output color +.TP +\fB\-h\fR, \fB\-\-help\fR +* Print this help and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +* Print version and exit +.PP +$Id: qgrep.1,v 1.17 2007/04/05 18:25:27 solar Exp $ diff -Narup portage-utils-20070504/man/qsearch.1 portage-utils-20070504.new/man/qsearch.1 --- portage-utils-20070504/man/qsearch.1 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/man/qsearch.1 2007-05-04 09:05:54.538781595 +0200 @@ -5,7 +5,7 @@ qsearch \- search pkgname/desc .B qsearch \fI<regex>\fR .SH DESCRIPTION -Options: \fB\-[acsSNHvqChV]\fR +Options: \fB\-[aco\fR:psSNHvqChV] .TP \fB\-a\fR, \fB\-\-all\fR * List the descriptions of every package in the cache @@ -13,6 +13,14 @@ Options: \fB\-[acsSNHvqChV]\fR \fB\-c\fR, \fB\-\-cache\fR * Use the portage cache .TP +\fB\-o\fR, \fB\-\-overlay\fR +<arg> +.BR + * Search only in the <arg> overlay +.TP +\fB\-p\fR, \fB\-\-show\-path\fR +* Show the path to the ebuild +.TP \fB\-s\fR, \fB\-\-search\fR * Regex search package basenames .TP diff -Narup portage-utils-20070504/man/quse.1 portage-utils-20070504.new/man/quse.1 --- portage-utils-20070504/man/quse.1 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/man/quse.1 2007-05-04 09:05:54.546780375 +0200 @@ -5,7 +5,7 @@ quse \- find pkgs using useflags .B quse \fI<useflag>\fR .SH DESCRIPTION -Options: \fB\-[eavKLDF:NvqChV]\fR +Options: \fB\-[eao\fR:vKLDF:NvqChV] .TP \fB\-e\fR, \fB\-\-exact\fR * Show exact non regexp matching using strcmp @@ -13,6 +13,11 @@ Options: \fB\-[eavKLDF:NvqChV]\fR \fB\-a\fR, \fB\-\-all\fR * Show annoying things in IUSE .TP +\fB\-o\fR, \fB\-\-overlay\fR +<arg> +.BR + * Only consider the <arg> overlay +.TP \fB\-K\fR, \fB\-\-keywords\fR * Use the KEYWORDS vs IUSE .TP diff -Narup portage-utils-20070504/qatom.c portage-utils-20070504.new/qatom.c --- portage-utils-20070504/qatom.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qatom.c 2007-05-04 09:05:54.555779002 +0200 @@ -60,6 +60,7 @@ int qatom_main(int argc, char **argv) printf(" r%i", atom->PR_int); if (verbose > 1) printf(" %c", (atom->letter ? : '-')); + printf(" %s", atom->OVERLAY); putchar('\n'); atom_implode(atom); } diff -Narup portage-utils-20070504/q.c portage-utils-20070504.new/q.c --- portage-utils-20070504/q.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/q.c 2007-05-04 09:05:54.563777781 +0200 @@ -7,15 +7,17 @@ * Copyright 2005-2006 Mike Frysinger - <vapier@gentoo.org> */ -#define Q_FLAGS "irm" COMMON_FLAGS +#define Q_FLAGS "ilrm" COMMON_FLAGS static struct option const q_long_opts[] = { {"install", no_argument, NULL, 'i'}, + {"ls-overlays", no_argument, NULL, 'l'}, {"reinitialize", no_argument, NULL, 'r'}, {"metacache", no_argument, NULL, 'm'}, COMMON_LONG_OPTS }; static const char *q_opts_help[] = { "Install symlinks for applets", + "List configured overlays", "Reinitialize ebuild cache", "Reinitialize metadata cache", COMMON_OPTS_HELP @@ -70,6 +72,7 @@ int q_main(int argc, char **argv) int i; char *p; APPLET func; + overlay_t * cur_overlay; if (argc == 0) return 1; @@ -89,6 +92,17 @@ int q_main(int argc, char **argv) COMMON_GETOPTS_CASES(q) case 'm': reinitialize_metacache = 1; break; case 'r': reinitialize = 1; break; + case 'l': { + printf("\n%sOverlay(s) :%s\n\n", GREEN, NORM); + cur_overlay=first_overlay; + do { + printf(" Name : %s%-20.20s%s \tlocation : %s%-60.60s%s \tmetadata : %s%-60.60s%s\n", + CYAN, cur_overlay->name, NORM, CYAN, cur_overlay->path, NORM, + CYAN, cur_overlay->cache, NORM); + } while ((cur_overlay=cur_overlay->next)); + fputc('\n', stdout); + return 0; + } case 'i': { char buf[_Q_PATH_MAX]; /* always bzero a buffer before using readlink() */ @@ -131,3 +145,5 @@ int q_main(int argc, char **argv) return (func)(argc - 1, ++argv); } +/* vim: set noet sts=8 sw=8 : */ + diff -Narup portage-utils-20070504/qcheck.c portage-utils-20070504.new/qcheck.c --- portage-utils-20070504/qcheck.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qcheck.c 2007-05-04 09:05:54.572776409 +0200 @@ -64,10 +64,10 @@ int qcheck_main(int argc, char **argv) if ((argc == optind) && !search_all) qcheck_usage(EXIT_FAILURE); - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -114,7 +114,7 @@ int qcheck_main(int argc, char **argv) } - snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, dentry->d_name, de->d_name); + snprintf(buf, sizeof(buf), "%s/%s/%s/CONTENTS", portvdb, dentry->d_name, de->d_name); if ((fp = fopen(buf, "r")) == NULL) continue; strncat(buf, "~", sizeof(buf)); @@ -259,7 +259,7 @@ int qcheck_main(int argc, char **argv) fclose(fp); if (qc_update) { fclose(fpx); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/CONTENTS", portvdb, dentry->d_name, de->d_name); strcpy(buffer, buf); strncat(buffer, "~", sizeof(buffer)); diff -Narup portage-utils-20070504/qdepends.c portage-utils-20070504.new/qdepends.c --- portage-utils-20070504/qdepends.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qdepends.c 2007-05-04 09:05:54.580775189 +0200 @@ -360,10 +360,10 @@ int qdepends_main_vdb(const char *depend dep_node *dep_tree; struct stat st; - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -391,7 +391,7 @@ int qdepends_main_vdb(const char *depend continue; IF_DEBUG(warn("matched %s/%s", dentry->d_name, de->d_name)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/%s", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/%s", portvdb, dentry->d_name, de->d_name, depend_file); /* >=portage-2.1_pre3 wont ensure these files always exist. @@ -425,7 +425,7 @@ int qdepends_main_vdb(const char *depend printf("%s%s/%s%s%s: ", BOLD, dentry->d_name, BLUE, de->d_name, NORM); } - snprintf(buf, sizeof(buf), "%s%s/%s/%s/USE", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/USE", portvdb, dentry->d_name, de->d_name); if (access(buf, R_OK) != 0) { @@ -472,10 +472,10 @@ int qdepends_vdb_deep(const char *depend char depend[16384], use[8192]; dep_node *dep_tree; - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -491,7 +491,7 @@ int qdepends_vdb_deep(const char *depend continue; IF_DEBUG(warn("matched %s/%s", dentry->d_name, de->d_name)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/%s", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/%s", portvdb, dentry->d_name, de->d_name, depend_file); if (access(buf, R_OK) != 0) @@ -508,7 +508,7 @@ int qdepends_vdb_deep(const char *depend IF_DEBUG(puts(depend)); IF_DEBUG(dep_dump_tree(dep_tree)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/USE", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/USE", portvdb, dentry->d_name, de->d_name); assert(eat_file(buf, use, sizeof(use)) == 1); for (ptr = use; *ptr; ++ptr) diff -Narup portage-utils-20070504/qfile.c portage-utils-20070504.new/qfile.c --- portage-utils-20070504/qfile.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qfile.c 2007-05-04 09:05:54.589773816 +0200 @@ -598,16 +598,14 @@ int qfile_main(int argc, char **argv) if (nb_of_queries < 0) goto exit; - if (chdir(portroot) - || chdir(portvdb) != 0 - || (dir = opendir(".")) == NULL) { - warnp("could not chdir(ROOT/%s) for installed packages database", portvdb); + if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) { + warnp("could not chdir(%s) for installed packages database", portvdb); goto exit; } /* Iteration over VDB categories */ while (nb_of_queries && (dentry = q_vdb_get_next_dir(dir))) { - snprintf(path, _Q_PATH_MAX, "%s/%s/%s", qfile_args->real_root, portvdb, dentry->d_name); + snprintf(path, _Q_PATH_MAX, "%s/%s", portvdb, dentry->d_name); qfile(path, (assume_root_prefix ? root_prefix : NULL), qfile_args); } diff -Narup portage-utils-20070504/qgrep.c portage-utils-20070504.new/qgrep.c --- portage-utils-20070504/qgrep.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qgrep.c 2007-05-04 09:05:54.597772596 +0200 @@ -10,12 +10,13 @@ #ifdef APPLET_qgrep -#define QGREP_FLAGS "IiHNclLexJEsS:B:A:" COMMON_FLAGS +#define QGREP_FLAGS "IiHNo:clLexJEsS:B:A:" COMMON_FLAGS static struct option const qgrep_long_opts[] = { {"invert-match", no_argument, NULL, 'I'}, {"ignore-case", no_argument, NULL, 'i'}, {"with-filename", no_argument, NULL, 'H'}, {"with-name", no_argument, NULL, 'N'}, + {"overlay", a_argument, NULL, 'o'}, {"count", no_argument, NULL, 'c'}, {"list", no_argument, NULL, 'l'}, {"invert-list", no_argument, NULL, 'L'}, @@ -34,6 +35,7 @@ static const char *qgrep_opts_help[] = { "Ignore case distinctions", "Print the filename for each match", "Print the package or eclass name for each match", + "Only consider the <arg> overlay", "Only print a count of matching lines per FILE", "Only print FILE names containing matches", "Only print FILE names containing no match", @@ -62,8 +64,11 @@ char qgrep_name_match(const char* name, for (i = 0; i < argc; i++) { if (argv[i] == NULL) continue; + if (atom->OVERLAY && argv[i]->OVERLAY && *(argv[i]->OVERLAY) + && !strstr(atom->OVERLAY, argv[i]->OVERLAY)) + continue; if (atom->CATEGORY && argv[i]->CATEGORY && *(argv[i]->CATEGORY) - && strcmp(atom->CATEGORY, argv[i]->CATEGORY)) + && !strstr(atom->CATEGORY, argv[i]->CATEGORY)) continue; if (atom->PN && argv[i]->PN && *(argv[i]->PN) && strcmp(atom->PN, argv[i]->PN)) @@ -134,16 +139,16 @@ void qgrep_buf_list_invalidate(qgrep_buf typedef char *(*QGREP_STR_FUNC) (const char *, const char *); /* Display a buffer, with an optionnal prefix. */ -void qgrep_print_line(qgrep_buf_t *, const char *, const int, const char, +void qgrep_print_line(qgrep_buf_t *, const char *, const char *, const int, const char, const regex_t*, const QGREP_STR_FUNC, const char*); -void qgrep_print_line(qgrep_buf_t *current, const char *label, +void qgrep_print_line(qgrep_buf_t *current, const char *overlay_name, const char *label, const int line_number, const char zig, const regex_t* preg, const QGREP_STR_FUNC searchfunc, const char* searchstr) { char *p = current->buf; /* Print line prefix, when in verbose mode */ if (label != NULL) { - printf("%s", label); + printf("%s::%s", overlay_name, label); if (line_number > 0) printf(":%d", line_number); putchar(zig); @@ -183,26 +188,26 @@ void qgrep_print_line(qgrep_buf_t *curre /* Once a line has been displayed, it is not valid anymore */ current->valid = 0; } -#define qgrep_print_context_line(buf, label, lineno) \ - qgrep_print_line(buf, label, lineno, '-', NULL, NULL, NULL) -#define qgrep_print_matching_line_nocolor(buf, label, lineno) \ - qgrep_print_line(buf, label, lineno, ':', NULL, NULL, NULL) -#define qgrep_print_matching_line_regcolor(buf, label, lineno, preg) \ - qgrep_print_line(buf, label, lineno, ':', preg, NULL, NULL) -#define qgrep_print_matching_line_strcolor(buf, label, lineno, searchfunc, searchstr) \ - qgrep_print_line(buf, label, lineno, ':', NULL, searchfunc, searchstr) +#define qgrep_print_context_line(buf, overlay_name, label, lineno) \ + qgrep_print_line(buf, overlay_name, label, lineno, '-', NULL, NULL, NULL) +#define qgrep_print_matching_line_nocolor(buf, overlay_name, label, lineno) \ + qgrep_print_line(buf, overlay_name, label, lineno, ':', NULL, NULL, NULL) +#define qgrep_print_matching_line_regcolor(buf, overlay_name, label, lineno, preg) \ + qgrep_print_line(buf, overlay_name, label, lineno, ':', preg, NULL, NULL) +#define qgrep_print_matching_line_strcolor(buf, overlay_name, label, lineno, searchfunc, searchstr) \ + qgrep_print_line(buf, overlay_name, label, lineno, ':', NULL, searchfunc, searchstr) /* Display a leading context (valid lines of the buffers list, but the matching one). */ -void qgrep_print_before_context(qgrep_buf_t *, const char, const char *, const int); +void qgrep_print_before_context(qgrep_buf_t *, const char, const char *, const char *, const int); void qgrep_print_before_context(qgrep_buf_t *current, const char num_lines_before, - const char *label, const int match_line_number) + const char *overlay_name, const char *label, const int match_line_number) { int line_number; line_number = match_line_number - num_lines_before; while ((current = current->next) && (line_number < match_line_number)) { if (current->valid) - qgrep_print_context_line(current, label, line_number); + qgrep_print_context_line(current, overlay_name, label, line_number); line_number++; } } @@ -233,15 +238,16 @@ get_next_category: goto get_next_ebuild_from_category; } - int qgrep_main(int argc, char **argv) { int i; int count = 0; + short myerror = 0, repo = 0, bad_overlay=0; + char overlay_name[64], repo_search[64]; char *p; char do_count, do_regex, do_eclass, do_installed, do_list; char show_filename, skip_comments, invert_list, show_name; - char per_file_output; + char per_file_output; FILE *fp = NULL; DIR *eclass_dir = NULL; DIR *vdb_dir = NULL; @@ -261,9 +267,14 @@ int qgrep_main(int argc, char **argv) qgrep_buf_t *buf_list; int need_separator = 0; char status = 1; + overlay_t *cur_overlay, *overlay_tmp; QGREP_STR_FUNC strfunc = (QGREP_STR_FUNC) strstr; + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; + DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -277,6 +288,12 @@ int qgrep_main(int argc, char **argv) strfunc = (QGREP_STR_FUNC) strcasestr; reflags |= REG_ICASE; break; + case 'H': show_filename = 1; break; + case 'N': show_name = 1; break; + case 'o': + repo = 1; + strncpy(repo_search, optarg, sizeof(repo_search)); + break; case 'c': do_count = 1; break; case 'l': do_list = 1; break; case 'L': do_list = invert_list = 1; break; @@ -287,8 +304,6 @@ int qgrep_main(int argc, char **argv) break; case 'J': do_installed = 1; break; case 'E': do_eclass = 1; break; - case 'H': show_filename = 1; break; - case 'N': show_name = 1; break; case 's': skip_comments = 1; break; case 'S': skip_pattern = optarg; break; case 'B': @@ -306,9 +321,19 @@ int qgrep_main(int argc, char **argv) else num_lines_after = context_optarg; break; - COMMON_GETOPTS_CASES(qgrep) + COMMON_GETOPTS_CASES(qgrep) } } + + if (repo) { + do { + if (!strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + } + if (argc == optind) qgrep_usage(EXIT_FAILURE); @@ -385,71 +410,145 @@ int qgrep_main(int argc, char **argv) /* go look either in ebuilds or eclasses or VDB */ if (!do_eclass && !do_installed) { - initialize_ebuild_flat(); /* sets our pwd to $PORTDIR */ + initialize_ebuild_flat(0); if ((fp = fopen(CACHE_EBUILD_FILE, "r")) == NULL) return 1; } else if (do_eclass) { - if ((chdir(portdir)) != 0) - errp("chdir to PORTDIR '%s' failed", portdir); - if ((eclass_dir = opendir("eclass")) == NULL) - errp("opendir(\"%s/eclass\") failed", portdir); + cur_overlay = first_overlay; + do { + if (repo && strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + continue; + if ((chdir(cur_overlay->path)) != 0) { + if (verbose) + warn("chdir to '%s' failed", cur_overlay->path); + continue; + } + if ((eclass_dir = opendir("eclass")) != NULL) + break; + else if (verbose) + warn(" opendir(\"%s/eclass\") failed", cur_overlay->path); + } while ((cur_overlay=cur_overlay->next)); + if (cur_overlay == NULL) + err("No eclass found"); } else { /* if (do_install) */ - if (chdir(portroot) != 0) - errp("could not chdir(%s) for ROOT", portroot); if (chdir(portvdb) != 0) - errp("could not chdir(%s/%s) for ROOT/VDB", portroot, portvdb); + errp("could not chdir(%s) for ROOT/VDB", portvdb); if ((vdb_dir = opendir(".")) == NULL) - errp("could not opendir(%s/%s) for ROOT/VDB", portroot, portvdb); - } + errp("could not opendir(%s) for ROOT/VDB", portvdb); + } /* allocate a circular buffers list for --before */ buf_list = qgrep_buf_list_alloc(num_lines_before + 1); /* iteration is either over ebuilds or eclasses */ - while (do_eclass - ? ((dentry = readdir(eclass_dir)) - && snprintf(ebuild, sizeof(ebuild), "eclass/%s", dentry->d_name)) - : (do_installed - ? (get_next_installed_ebuild(ebuild, vdb_dir, &dentry, &cat_dir) != NULL) - : ((fgets(ebuild, sizeof(ebuild), fp)) != NULL))) { + while (do_eclass || do_installed || ((fgets(ebuild, sizeof(ebuild), fp)) != NULL)) { FILE *newfp; - - /* filter badly named files, prepare eclass or package name, etc. */ if (do_eclass) { + if ((dentry = readdir(eclass_dir))) + snprintf(ebuild, sizeof(ebuild), "eclass/%s", dentry->d_name); + else { + closedir(eclass_dir); + if (repo) + break; + while ((cur_overlay=cur_overlay->next)) { + if ((chdir(cur_overlay->path)) != 0) { + if (verbose) + warn("chdir to '%s' failed", cur_overlay->path); + continue; + } + if ((eclass_dir = opendir("eclass")) != NULL) + break; + else if (verbose) + warn(" opendir(\"%s/eclass\") failed", cur_overlay->path); + } + if (cur_overlay && eclass_dir && (dentry = readdir(eclass_dir))) + snprintf(ebuild, sizeof(ebuild), "eclass/%s", dentry->d_name); + else + break; + } + if ((p = strrchr(ebuild, '.')) == NULL) continue; if (strcmp(p, ".eclass")) continue; - if (show_name || (include_atoms != NULL)) { + if (include_atoms != NULL) { /* cut ".eclass" */ *p = '\0'; /* and skip "eclass/" */ - snprintf(name, sizeof(name), "%s", ebuild + 7); + snprintf(name, sizeof(name), "%s::%s", ebuild + 7, cur_overlay->name); /* restore the filepath */ *p = '.'; } - } else { - if ((p = strchr(ebuild, '\n')) != NULL) - *p = '\0'; - if (show_name || (include_atoms != NULL)) { - /* cut ".ebuild" */ - if (p == NULL) - p = ebuild + strlen(ebuild); - *(p-7) = '\0'; - /* cut "/foo/" from "cat/foo/foo-x.y" */ - if ((p = strchr(ebuild, '/')) == NULL) - continue; - *(p++) = '\0'; - /* find head of the ebuild basename */ - if ((p = strchr(p, '/')) == NULL) - continue; - /* find start of the pkg name */ - snprintf(name, sizeof(name), "%s/%s", ebuild, (p+1)); - /* restore the filepath */ - *p = '/'; - *(p + strlen(p)) = '.'; - ebuild[strlen(ebuild)] = '/'; + } else if (do_installed && (get_next_installed_ebuild(ebuild, vdb_dir, &dentry, &cat_dir) == NULL)) + break; + else if ((p = strchr(ebuild, '\n')) != NULL) + *p = 0; + + /* find the overlay, we're working on, and change to the + * corresponding (location|cache) directory */ + if ((p = strchr(ebuild, ':'))) { + /* delete the ::overlay */ + *p = 0; + + /* restrict the search to one overlay if the users wants it */ + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + else { + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + + if (overlay_tmp) { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror = 1; + } else + bad_overlay = 0; + } else + myerror = 1; + + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } } + } else + myerror=1; + + /* no ':' in ebuild when searching eclasses nor when do_installed=1 */ + if (do_eclass || do_installed) + myerror=0; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + + if (!do_eclass && (include_atoms != NULL)) { + /* cut ".ebuild" */ + p = ebuild + strlen(ebuild); + *(p-7) = '\0'; + /* cut "/foo/" from "cat/foo/foo-x.y" */ + if ((p = strchr(ebuild, '/')) == NULL) + continue; + *(p++) = '\0'; + /* find head of the ebuild basename */ + if ((p = strchr(p, '/')) == NULL) + continue; + /* find start of the pkg name, and add to overlay at the end for atom_explode */ + snprintf(name, sizeof(name), "%s/%s::%s", ebuild, (p+1), cur_overlay->name); + /* restore the filepath */ + *p = '/'; + *(p + strlen(p)) = '.'; + ebuild[strlen(ebuild)] = '/'; } /* filter the files we grep when there are extra args */ @@ -466,10 +565,33 @@ int qgrep_main(int argc, char **argv) /* whatever is in the circular buffers list is no more a valid context */ qgrep_buf_list_invalidate(buf_list); + if (show_name) { + p = ebuild + strlen(ebuild); + if (do_eclass) { + /* cut ".eclass" */ + *(p-7) = '\0'; + /* and skip "eclass/" */ + snprintf(name, sizeof(name), "%s", ebuild + 7); + } + else { + /* cut ".ebuild" */ + *(p-7) = '\0'; + /* cut "/foo/" from "cat/foo/foo-x.y" */ + if ((p = strchr(ebuild, '/')) == NULL) + continue; + *(p++) = '\0'; + /* find head of the ebuild basename */ + if ((p = strchr(p, '/')) == NULL) + continue; + /* find start of the pkg name */ + snprintf(name, sizeof(name), "%s/%s", ebuild, ++p); + } + } + /* reading a new line always happen in the next buffer of the list */ while ((buf_list = buf_list->next) && (fgets(buf_list->buf, sizeof(buf_list->buf), newfp)) != NULL) { - lineno++; + lineno++; buf_list->valid = 1; /* cleanup EOL */ @@ -529,21 +651,22 @@ int qgrep_main(int argc, char **argv) need_separator = 0 - num_lines_before; if (!do_list) { /* print the leading context */ - qgrep_print_before_context(buf_list, num_lines_before, label, + qgrep_print_before_context(buf_list, num_lines_before, (do_installed ? "installed" : cur_overlay->name), label, ((verbose > 1) ? lineno : -1)); /* print matching line */ if (invert_match || *RED == '\0') - qgrep_print_matching_line_nocolor(buf_list, label, + qgrep_print_matching_line_nocolor(buf_list, (do_installed ? "installed" : cur_overlay->name), label, ((verbose > 1) ? lineno : -1)); else if (do_regex) - qgrep_print_matching_line_regcolor(buf_list, label, + qgrep_print_matching_line_regcolor(buf_list, (do_installed ? "installed" : cur_overlay->name), label, ((verbose > 1) ? lineno : -1), &preg); else - qgrep_print_matching_line_strcolor(buf_list, label, + qgrep_print_matching_line_strcolor(buf_list, (do_installed ? "installed" : cur_overlay->name), label, ((verbose > 1) ? lineno : -1), strfunc, argv[optind]); + } else { /* in verbose do_list mode, list the file once per match */ - printf("%s", label); + printf("%s::%s", (do_installed ? "installed" : cur_overlay->name), label); if (verbose > 1) printf(":%d", lineno); putchar('\n'); @@ -552,7 +675,7 @@ int qgrep_main(int argc, char **argv) remaining_after_context = num_lines_after; continue; -print_after_context: + print_after_context: /* print some trailing context lines when needed */ if (!remaining_after_context) { if (!status) @@ -560,10 +683,11 @@ print_after_context: * current match block and the next one */ ++need_separator; } else { - qgrep_print_context_line(buf_list, label, + qgrep_print_context_line(buf_list, overlay_name, label, ((verbose > 1) ? lineno : -1)); --remaining_after_context; - } + } + } fclose(newfp); if (!per_file_output) @@ -572,15 +696,14 @@ print_after_context: if (label != NULL) /* -c without -v/-N/-H only outputs * the matches count of the file */ - printf("%s:", label); + printf("%s::%s:", (do_installed ? "installed" : cur_overlay->name), label); printf("%d\n", count); } else if ((count && !invert_list) || (!count && invert_list)) - printf("%s\n", label); /* do_list == 1, or we wouldn't be here */ + printf("%s::%s\n", (do_installed ? "installed" : cur_overlay->name), label); /* do_list == 1, or we wouldn't be here */ + } } - if (do_eclass) - closedir(eclass_dir); - else if (!do_installed) + if (!do_eclass && !do_installed) fclose(fp); if (do_regex) regfree(&preg); diff -Narup portage-utils-20070504/qsearch.c portage-utils-20070504.new/qsearch.c --- portage-utils-20070504/qsearch.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/qsearch.c 2007-05-04 09:05:54.606771223 +0200 @@ -9,10 +9,12 @@ #ifdef APPLET_qsearch -#define QSEARCH_FLAGS "acsSNH" COMMON_FLAGS +#define QSEARCH_FLAGS "aco:psSNH" COMMON_FLAGS static struct option const qsearch_long_opts[] = { {"all", no_argument, NULL, 'a'}, {"cache", no_argument, NULL, 'c'}, + {"overlay", a_argument, NULL, 'o'}, + {"show-path", no_argument, NULL, 'p'}, {"search", no_argument, NULL, 's'}, {"desc", a_argument, NULL, 'S'}, {"name-only", no_argument, NULL, 'N'}, @@ -22,6 +24,8 @@ static struct option const qsearch_long_ static const char *qsearch_opts_help[] = { "List the descriptions of every package in the cache", "Use the portage cache", + "Search only in the <arg> overlay", + "Show the path to the ebuild", "Regex search package basenames", "Regex search package descriptions", "Only show package name", @@ -40,13 +44,28 @@ int qsearch_main(int argc, char **argv) char last[126] = ""; char dp[126] = ""; char bp[126] = ""; - char *p, *q, *str; + char debuild[126] = ""; + short repo = 0; + char repo_search[64]; + char *p, *q, *str, *t, *pn, overlay_name[64]; char *search_me = NULL; - char show_homepage = 0, show_name_only = 0; + char show_homepage = 0, show_name_only = 0, show_path_to_ebuild = 0; char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD; const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" }; + int reflags= (REG_NOSUB | REG_EXTENDED); + regex_t preg_overlay, preg_category, preg_pname, preg_desc; size_t search_len; - int i, idx=0; + depend_atom *search_me_atom; + overlay_t *cur_overlay, *overlay_tmp; + int ret; + char err[256]; + int i, idx=0, myerror=0, bad_overlay=0; + + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; + str = NULL; + search_me_atom = NULL; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -56,6 +75,8 @@ int qsearch_main(int argc, char **argv) COMMON_GETOPTS_CASES(qsearch) case 'a': search_all = 1; break; case 'c': search_cache = CACHE_METADATA; break; + case 'o': repo = 1; strncpy(repo_search, optarg, sizeof(repo_search)); break; + case 'p': show_path_to_ebuild = 1; 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; @@ -63,6 +84,18 @@ int qsearch_main(int argc, char **argv) } } + if (repo) { + do { + if (! strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + if (search_cache == CACHE_METADATA && !strncmp(cur_overlay->cache,"/var/empty",sizeof(cur_overlay->cache))) + err("No cache defined for the '%s' overlay", cur_overlay->name); + } + + if (search_all) { search_desc = 1; search_name = 0; @@ -71,9 +104,38 @@ int qsearch_main(int argc, char **argv) qsearch_usage(EXIT_FAILURE); search_me = argv[optind]; } + if (search_name) { + if ((search_me_atom=atom_explode(search_me)) == NULL) + err("Error: atom_explode(%s)", search_me); + if (search_me_atom->OVERLAY && (ret = regcomp(&preg_overlay, search_me_atom->OVERLAY, reflags))) { + if (regerror(ret, &preg_overlay, err, sizeof(err))) + err("regcomp failed: %s", err); + else + err("regcomp failed"); + } + if (search_me_atom->CATEGORY && (ret = regcomp(&preg_category, search_me_atom->CATEGORY, reflags))) { + if (regerror(ret, &preg_category, err, sizeof(err))) + err("regcomp failed: %s", err); + else + err("regcomp failed"); + } + if (search_me_atom->PN && (ret = regcomp(&preg_pname, search_me_atom->PN, reflags))) { + if (regerror(ret, &preg_pname, err, sizeof(err))) + err("regcomp failed: %s", err); + else + err("regcomp failed"); + } + } else if (search_desc && !search_all) { + if ((ret = regcomp(&preg_desc, search_me, REG_EXTENDED | REG_ICASE))) { + if (regerror(ret, &preg_desc, err, sizeof(err))) + err("regcomp failed: %s", err); + else + err("regcomp failed"); + } + } last[0] = 0; - fp = fopen(initialize_flat(search_cache), "r"); + fp = fopen(initialize_flat(search_cache, 0), "r"); if (!fp) return 1; @@ -86,6 +148,58 @@ int qsearch_main(int argc, char **argv) if (!ebuild[0]) continue; + /* find the overlay, we're working on, and change to the + * corresponding (location|cache) directory */ + if ((p = strchr(ebuild, ':'))) { + /* separator is '::' */ + /* restrict the search to one overlay if the users wants it */ + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + last[0] = 0; + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + + if (overlay_tmp) { + cur_overlay=overlay_tmp; + switch (search_cache) { + case CACHE_EBUILD: + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror = 1; + } else + bad_overlay = 0; + break; + case CACHE_METADATA: + if (chdir(cur_overlay->cache) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository", cur_overlay->cache, cur_overlay->name); + myerror = 1; + } else + bad_overlay = 0; + break; + } + } else + myerror = 1; + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } + } else + myerror++; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + + switch (search_cache) { case CACHE_METADATA: { @@ -93,11 +207,45 @@ int qsearch_main(int argc, char **argv) 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) - 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))); + if (!search_all) { + if (search_desc && regexec(&preg_desc, pcache->DESCRIPTION, 0, NULL, 0) != 0) { + cache_free(pcache); + continue; + } else { + if (search_name) { + if (search_me_atom->CATEGORY && regexec(&preg_category, pcache->atom->CATEGORY, 0, NULL, 0) != 0) { + cache_free(pcache); + continue; + } + if (search_me_atom->PN && regexec(&preg_pname, pcache->atom->PN, 0, NULL, 0) != 0) { + cache_free(pcache); + continue; + } + if (search_me_atom->OVERLAY && regexec(&preg_overlay, pcache->atom->OVERLAY, 0, NULL, 0) != 0) { + cache_free(pcache); + continue; + } + } + } + } + + if (show_path_to_ebuild) { + /* delete the ::overlay */ + *p = 0; + strncpy(debuild, ebuild, sizeof(debuild)); + printf("%s%s/%s%s%s::%s\t %s%s/%s/\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW, pcache->atom->OVERLAY, NORM, + cur_overlay->path, dirname(debuild)); + } else { + printf("%s%s/%s%s%s::%s %s%s\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW, pcache->atom->OVERLAY, NORM, + (show_name_only ? "" : + (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); + } } cache_free(pcache); } else { @@ -110,14 +258,32 @@ int qsearch_main(int argc, char **argv) case CACHE_EBUILD: { FILE *ebuildfp; + /* delete the ::overlay and makes q points to 'overlay' */ + *p = 0; + q = p+2; + str = xstrdup(ebuild); p = (char *) dirname(str); if ((strcmp(p, last)) != 0) { strncpy(last, p, sizeof(last)); - if (search_name) - if ((rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE)) != 0) + if (search_name) { + if ((t=strrchr(ebuild, '/')) == NULL) goto no_cache_ebuild_match; + *t = 0; + if ((pn=strrchr(ebuild, '/')) == NULL) + goto no_cache_ebuild_match; + *pn = 0; + if (search_me_atom->CATEGORY && regexec(&preg_category, ebuild, 0, NULL, 0) != 0) + goto no_cache_ebuild_match; + if (search_me_atom->PN && regexec(&preg_pname, pn+1, 0, NULL, 0) != 0) + goto no_cache_ebuild_match; + if (search_me_atom->OVERLAY && regexec(&preg_overlay, q, 0, NULL, 0) != 0) + goto no_cache_ebuild_match; + /* put the slaches back */ + *t = '/'; + *pn = '/'; + } if ((ebuildfp = fopen(ebuild, "r")) != NULL) { while ((fgets(buf, sizeof(buf), ebuildfp)) != NULL) { if (strlen(buf) <= search_len) @@ -128,15 +294,24 @@ int qsearch_main(int argc, char **argv) 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) + if (!search_all && !search_name && regexec(&preg_desc, q, 0, NULL, 0) != 0) break; /* hppa/arm dirname(),basename() eats the ptr so we need to copy the variables before */ /* doing operations with them. */ strncpy(dp, p, sizeof(dp)); strncpy(bp, p, sizeof(bp)); - printf("%s%s/%s%s%s %s\n", - BOLD, dirname(dp), BLUE, basename(bp), NORM, + strncpy(debuild, ebuild, sizeof(debuild)); + if (show_path_to_ebuild) { + printf("%s%s/%s%s%s::%s\t %s%s/%s/\n", + BOLD, dirname(dp), BLUE, basename(bp), + YELLOW, cur_overlay->name, NORM, + cur_overlay->path, dirname(debuild)); + } else { + printf("%s%s/%s%s%s::%s %s%s\n", + BOLD, dirname(dp), BLUE, basename(bp), + YELLOW, cur_overlay->name, NORM, (show_name_only ? "" : q)); + } break; } } @@ -155,9 +330,17 @@ no_cache_ebuild_match: } /* switch (search_cache) */ } fclose(fp); + if (search_name) { + if (search_me_atom->OVERLAY) regfree(&preg_overlay); + if (search_me_atom->CATEGORY) regfree(&preg_category); + if (search_me_atom->PN) regfree(&preg_pname); + atom_implode(search_me_atom); + } return EXIT_SUCCESS; } #else DEFINE_APPLET_STUB(qsearch) #endif +/* vim: set noet sts=8 sw=8 : */ + diff -Narup portage-utils-20070504/quse.c portage-utils-20070504.new/quse.c --- portage-utils-20070504/quse.c 2007-05-04 09:05:02.000000000 +0200 +++ portage-utils-20070504.new/quse.c 2007-05-04 09:17:01.518029728 +0200 @@ -14,10 +14,11 @@ quse -Ke -- nls */ -#define QUSE_FLAGS "eavKLDF:N" COMMON_FLAGS +#define QUSE_FLAGS "eao:vKLDF:N" COMMON_FLAGS static struct option const quse_long_opts[] = { {"exact", no_argument, NULL, 'e'}, {"all", no_argument, NULL, 'a'}, + {"overlay", a_argument, NULL, 'o'}, {"keywords", no_argument, NULL, 'K'}, {"license", no_argument, NULL, 'L'}, {"describe", no_argument, NULL, 'D'}, @@ -28,6 +29,7 @@ static struct option const quse_long_opt static const char *quse_opts_help[] = { "Show exact non regexp matching using strcmp", "Show annoying things in IUSE", + "Only consider the <arg> overlay", "Use the KEYWORDS vs IUSE", "Use the LICENSE vs IUSE", "Describe the USE flag", @@ -38,7 +40,7 @@ static const char *quse_opts_help[] = { static const char quse_rcsid[] = "$Id: quse.c,v 1.57 2007/04/18 18:20:47 vapier Exp $"; #define quse_usage(ret) usage(ret, QUSE_FLAGS, quse_long_opts, quse_opts_help, lookup_applet_idx("quse")) -int quse_describe_flag(int ind, int argc, char **argv); +int quse_describe_flag(int ind, short repo, char repo_search[], int argc, char **argv); char quse_name_only = 0; @@ -81,7 +83,7 @@ static void print_highlighted_use_flags( } } -int quse_describe_flag(int ind, int argc, char **argv) +int quse_describe_flag(int ind, short repo, char repo_search[], int argc, char **argv) { #define NUM_SEARCH_FILES ARR_SIZE(search_files) char buf[BUFSIZE], *p; @@ -91,116 +93,136 @@ int quse_describe_flag(int ind, int argc FILE *fp[NUM_SEARCH_FILES]; DIR *d; struct dirent *de; + overlay_t *cur_overlay; - for (i = 0; i < NUM_SEARCH_FILES; ++i) { - snprintf(buf, sizeof(buf), "%s/profiles/%s", portdir, search_files[i]); - if ((fp[i] = fopen(buf, "r")) == NULL) - if ((strcmp(search_files[i], "lang.desc")) != 0) - warnp("skipping %s", search_files[i]); - } + cur_overlay=first_overlay; - for (i = ind; i < argc; i++) { - s = strlen(argv[i]); + do { + if (repo && strncmp(repo_search, cur_overlay->name, sizeof(repo_search))) + continue; + for (i = 0; i < NUM_SEARCH_FILES; ++i) { + snprintf(buf, sizeof(buf), "%s/profiles/%s", cur_overlay->path, search_files[i]); + if ((fp[i] = fopen(buf, "r")) == NULL) + if (verbose>2) + warnp("skipping %s for the %s overlay", search_files[i], cur_overlay->name); + } - for (f = 0; f < NUM_SEARCH_FILES; ++f) { - if (fp[f] == NULL) - continue; + for (i = ind; i < argc; i++) { + s = strlen(argv[i]); - while (fgets(buf, sizeof(buf), fp[f]) != NULL) { - if (buf[0] == '#' || buf[0] == '\n') + for (f = 0; f < NUM_SEARCH_FILES; ++f) { + if (fp[f] == NULL) continue; - if ((p = strrchr(buf, '\n')) != NULL) - *p = '\0'; + while (fgets(buf, sizeof(buf), fp[f]) != NULL) { + if (buf[0] == '#' || buf[0] == '\n') + continue; - switch (f) { - case 0: /* Global use.desc */ - if (!strncmp(buf, argv[i], s)) - if (buf[s] == ' ' && buf[s+1] == '-') { - printf(" %sglobal%s:%s%s%s: %s\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); - goto skip_file; - } - break; + if ((p = strrchr(buf, '\n')) != NULL) + *p = '\0'; - case 1: /* Local use.local.desc */ - if ((p = strchr(buf, ':')) == NULL) + switch (f) { + case 0: /* Global use.desc */ + if (!strncmp(buf, argv[i], s)) + if (buf[s] == ' ' && buf[s+1] == '-') { + printf(" (%s) %sglobal%s:%s%s%s: %s\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + goto skip_file; + } break; - ++p; - if (!strncmp(p, argv[i], s)) { - if (p[s] == ' ' && p[s+1] == '-') { - *p = '\0'; - printf(" %slocal%s:%s%s%s:%s%s%s %s\n", BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3); - } - } - break; - case 2: /* Architectures arch.list */ - if (!strcmp(buf, argv[i])) { - printf(" %sarch%s:%s%s%s: %s architecture\n", BOLD, NORM, BLUE, argv[i], NORM, argv[i]); - goto skip_file; - } - break; + case 1: /* Local use.local.desc */ + if ((p = strchr(buf, ':')) == NULL) + break; + ++p; + if (!strncmp(p, argv[i], s)) { + if (p[s] == ' ' && p[s+1] == '-') { + *p = '\0'; + printf(" (%s) %slocal%s:%s%s%s:%s%s%s %s\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3); + } + } + break; - case 3: /* Languages lang.desc */ - if (!strncmp(buf, argv[i], s)) - if (buf[s] == ' ' && buf[s+1] == '-') { - printf(" %slang%s:%s%s%s: %s lingua\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + case 2: /* Architectures arch.list */ + if (!strcmp(buf, argv[i])) { + printf(" (%s) %sarch%s:%s%s%s: %s architecture\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, argv[i]); goto skip_file; } - break; + break; + + case 3: /* Languages lang.desc */ + if (!strncmp(buf, argv[i], s)) + if (buf[s] == ' ' && buf[s+1] == '-') { + printf(" (%s) %slang%s:%s%s%s: %s lingua\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + goto skip_file; + } + break; + } } - } skip_file: - rewind(fp[f]); + rewind(fp[f]); + } + + if (i == (argc - 1)) + for (f=0; f<NUM_SEARCH_FILES; ++f) + if (fp[f]) { + fclose(fp[f]); + fp[f] = NULL; + } } - } - for (f=0; f<NUM_SEARCH_FILES; ++f) - if (fp[f] != NULL) - fclose(fp[f]); + } while ((cur_overlay=cur_overlay->next)); /* now scan the desc dir */ - snprintf(buf, sizeof(buf), "%s/profiles/desc/", portdir); - d = opendir(buf); - while ((de = readdir(d)) != NULL) { - if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc")) + cur_overlay=first_overlay; + do { + if (repo && strncmp(repo_search, cur_overlay->name, sizeof(repo_search))) continue; - - snprintf(buf, sizeof(buf), "%s/profiles/desc/%s", portdir, de->d_name); - if ((fp[0]=fopen(buf, "r")) == NULL) { - warn("Could not open '%s' for reading; skipping", de->d_name); + snprintf(buf, sizeof(buf), "%s/profiles/desc/", cur_overlay->path); + if (!(d = opendir(buf))) { + if (verbose>2) + warn("Could not open %s -> skipping", buf); continue; } + while ((de = readdir(d)) != NULL) { + if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc")) + continue; - while (fgets(buf, sizeof(buf), fp[0]) != NULL) { - if (buf[0] == '#' || buf[0] == '\n') + snprintf(buf, sizeof(buf), "%s/profiles/desc/%s", cur_overlay->path, de->d_name); + if ((fp[0]=fopen(buf, "r")) == NULL) { + warn("Could not open '%s' for reading; skipping", de->d_name); continue; + } - if ((p = strrchr(buf, '\n')) != NULL) - *p = '\0'; + while (fgets(buf, sizeof(buf), fp[0]) != NULL) { + if (buf[0] == '#' || buf[0] == '\n') + continue; - if ((p = strchr(buf, '-')) == NULL) { + if ((p = strrchr(buf, '\n')) != NULL) + *p = '\0'; + + if ((p = strchr(buf, '-')) == NULL) { invalid_line: - warn("Invalid line in '%s': %s", de->d_name, buf); - continue; - } - while (p[-1] != ' ' && p[1] != ' ') { - /* maybe the flag has a '-' in it ... */ - if ((p = strchr(p+1, '-')) == NULL) - goto invalid_line; - } - p[-1] = '\0'; - p += 2; + warn("Invalid line in '%s': %s", de->d_name, buf); + continue; + } + while (p[-1] != ' ' && p[1] != ' ') { + /* maybe the flag has a '-' in it ... */ + if ((p = strchr(p+1, '-')) == NULL) + goto invalid_line; + } + p[-1] = '\0'; + p += 2; - for (i = ind; i < argc; i++) - if (!strcmp(argv[i], buf)) - printf(" %s%s%s:%s%s%s: %s\n", BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p); - } - close(f); - } - closedir(d); + for (i = ind; i < argc; i++) + if (!strcmp(argv[i], buf)) + printf(" (%s) %s%s%s:%s%s%s: %s\n", cur_overlay->name, BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p); + } + fclose(fp[0]); + } + closedir(d); + } while ((cur_overlay=cur_overlay->next)); return 0; } @@ -208,6 +230,9 @@ int quse_main(int argc, char **argv) { FILE *fp; char *p; + short myerror = 0, repo = 0; + char repo_search[64]; + char overlay_name[64]; char buf0[_Q_PATH_MAX]; char buf1[_Q_PATH_MAX]; @@ -218,8 +243,13 @@ int quse_main(int argc, char **argv) const char *search_var = NULL; const char *search_vars[] = { "IUSE=", "KEYWORDS=", "LICENSE=", search_var }; short quse_all = 0; - int regexp_matching = 1, i, idx = 0; + int regexp_matching = 1, i, idx = 0, bad_overlay = 0; size_t search_len; + overlay_t *cur_overlay, *overlay_tmp; + + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -228,6 +258,10 @@ int quse_main(int argc, char **argv) switch (i) { case 'e': regexp_matching = 0; break; case 'a': quse_all = 1; break; + case 'o': + repo = 1; + strncpy(repo_search, optarg, sizeof(repo_search)); + break; case 'K': idx = 1; break; case 'L': idx = 2; break; case 'D': idx = -1; break; @@ -236,14 +270,26 @@ int quse_main(int argc, char **argv) COMMON_GETOPTS_CASES(quse) } } - if (argc == optind && !quse_all && idx >= 0) + + if (repo) { + do { + if (!strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + } + + if (argc == optind && !quse_all && idx >= 0) { + if (idx == 3) + free((char *)search_vars[idx]); quse_usage(EXIT_FAILURE); + } if (idx == -1) - return quse_describe_flag(optind, argc, argv); + return quse_describe_flag(optind, repo, repo_search, argc, argv); - if (quse_all) optind = argc; - initialize_ebuild_flat(); /* sets our pwd to $PORTDIR */ + initialize_ebuild_flat(0); /* cd into the right directory */ search_len = strlen(search_vars[idx]); assert(search_len < sizeof(buf0)); @@ -254,6 +300,54 @@ int quse_main(int argc, char **argv) FILE *newfp; if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; + if ((p = strchr(ebuild, ':'))) + { + /* delete the ::overlay */ + *p = 0; + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + else { + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if (overlay_tmp) + { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror=1; + } else + bad_overlay = 0; + } else + myerror=1; + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } + } + } else + myerror=1; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + + if ((quse_all) && optind!=argc) { + for (i=optind;i<argc;i++) + if ((strstr(ebuild,argv[i]))) + break; + if (i==argc) + continue; + } + if ((newfp = fopen(ebuild, "r")) != NULL) { unsigned int lineno = 0; char revision[sizeof(buf0)]; @@ -377,15 +471,18 @@ int quse_main(int argc, char **argv) if (verbose > 3) printf("%s %s %s ", *user ? user : "MISSING", *revision ? revision : "MISSING", *date ? date : "MISSING"); - printf("%s%s%s ", CYAN, ebuild, NORM); - print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv); + printf("%s%s::%s%s ", CYAN, cur_overlay->name, ebuild, NORM); + if (quse_all) + print_highlighted_use_flags(&buf0[search_len+1], argc, argc, argv); + else + print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv); puts(NORM); if (verbose > 1) { char **ARGV = NULL; int ARGC = 0; makeargv(&buf0[search_len+1], &ARGC, &ARGV); if (ARGC > 0) { - quse_describe_flag(1, ARGC, ARGV); + quse_describe_flag(1, 0, repo_search, ARGC, ARGV); for (i = 0; i < ARGC; i++) free(ARGV[i]); free(ARGV); @@ -402,9 +499,13 @@ int quse_main(int argc, char **argv) } } fclose(fp); + if (idx == 3) + free((char *) search_vars[idx]); return EXIT_SUCCESS; } #else DEFINE_APPLET_STUB(quse) #endif +/* vim: set noet sts=8 sw=8 : */ +