commit: a713624891de6d3e7b2c9d61f7ff47bd65db89ee Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> AuthorDate: Sat Feb 13 23:30:47 2016 +0000 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> CommitDate: Sat Feb 13 23:30:47 2016 +0000 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=a7136248
qlop: parse args as atoms instead of substrings Update the arg parsing logic to treat them as atoms rather than as ad-hoc substring parsing. This makes the listing logic much more natural and brings it inline with other applets. URL: https://bugs.gentoo.org/112818 Reported-by: Jeroen Roovers <jer <AT> gentoo.org> libq/xarray.c | 31 +++++++++++++++++++-------- qlop.c | 68 ++++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/libq/xarray.c b/libq/xarray.c index 339d759..36a5df5 100644 --- a/libq/xarray.c +++ b/libq/xarray.c @@ -24,24 +24,37 @@ typedef struct { #define array_cnt(arr) (arr)->num #define DECLARE_ARRAY(arr) array_t _##arr = array_init_decl, *arr = &_##arr -static void *xarraypush(array_t *arr, const void *ele, size_t ele_len) +/* Push a pointer to memory we already hold and don't want to release. Do not + * mix xarraypush_ptr usage with the other push funcs which duplicate memory. + * The free stage won't know which pointers to release directly. + */ +static void *xarraypush_ptr(array_t *arr, void *ele) { - void *nele; size_t n = arr->num++; arr->eles = xrealloc_array(arr->eles, arr->num, sizeof(ele)); - arr->eles[n] = nele = xmemdup(ele, ele_len); - return nele; + arr->eles[n] = ele; + return ele; +} +static void *xarraypush(array_t *arr, const void *ele, size_t ele_len) +{ + return xarraypush_ptr(arr, xmemdup(ele, ele_len)); } #define xarraypush_str(arr, ele) xarraypush(arr, ele, strlen(ele) + 1 /*NUL*/) +#define xarraypush_struct(arr, ele) xarraypush(arr, ele, sizeof(*(ele))) -static void xarrayfree(array_t *arr) +/* Useful for people who call xarraypush_ptr as it does not free any of the + * pointers in the eles list. + */ +static void xarrayfree_int(array_t *arr) { array_t blank = array_init_decl; + free(arr->eles); + *arr = blank; +} +static void xarrayfree(array_t *arr) +{ size_t n; - for (n = 0; n < arr->num; ++n) free(arr->eles[n]); - free(arr->eles); - - *arr = blank; + xarrayfree_int(arr); } diff --git a/qlop.c b/qlop.c index bb32474..8a89fba 100644 --- a/qlop.c +++ b/qlop.c @@ -235,14 +235,15 @@ show_merge_times(char *package, const char *logfile, int average, char human_rea } _q_static void -show_emerge_history(char listflag, int argc, char **argv, const char *logfile) +show_emerge_history(int listflag, array_t *atoms, const char *logfile) { FILE *fp; size_t buflen, linelen; char *buf, merged; char *p, *q; - int i; + size_t i; time_t t; + depend_atom *atom, *logatom; if ((fp = fopen(logfile, "r")) == NULL) { warnp("Could not open logfile '%s'", logfile); @@ -254,12 +255,6 @@ show_emerge_history(char listflag, int argc, char **argv, const char *logfile) if (linelen < 30) continue; - for (i = 0; i < argc; ++i) - if (strstr(buf, argv[i]) != NULL) - break; - if (argc && i == argc) - continue; - rmspace_len(buf, linelen); if ((p = strchr(buf, ':')) == NULL) continue; @@ -286,18 +281,23 @@ show_emerge_history(char listflag, int argc, char **argv, const char *logfile) q = p + 2; } else continue; - if (!quiet) - printf("%s %s %s%s%s\n", chop_ctime(t), (merged ? ">>>" : "<<<"), (merged ? GREEN : RED), q, NORM); - else { - depend_atom *atom; - atom = atom_explode(q); - if (quiet == 1) - printf("%s ", chop_ctime(t)); - if (quiet <= 2) - printf("%s ", (merged ? ">>>" : "<<<")); - printf("%s%s/%s%s\n", (merged ? GREEN : RED), atom->CATEGORY, atom->PN, NORM); - atom_implode(atom); + + logatom = atom_explode(q); + array_for_each(atoms, i, atom) { + if (atom_compare(atom, logatom) != EQUAL) + continue; + + if (!quiet) + printf("%s %s %s%s%s\n", chop_ctime(t), (merged ? ">>>" : "<<<"), (merged ? GREEN : RED), q, NORM); + else { + if (quiet == 1) + printf("%s ", chop_ctime(t)); + if (quiet <= 2) + printf("%s ", (merged ? ">>>" : "<<<")); + printf("%s%s/%s%s\n", (merged ? GREEN : RED), logatom->CATEGORY, logatom->PN, NORM); + } } + atom_implode(logatom); } free(buf); @@ -642,9 +642,13 @@ void show_current_emerge(void) int qlop_main(int argc, char **argv) { - int i, average = 1; + size_t i; + int average = 1; char do_time, do_list, do_unlist, do_sync, do_current, do_human_readable = 0; char *logfile = NULL; + int flags; + depend_atom *atom; + DECLARE_ARRAY(atoms); do_time = do_list = do_unlist = do_sync = do_current = 0; @@ -672,13 +676,22 @@ int qlop_main(int argc, char **argv) argc -= optind; argv += optind; + for (i = 0; i < argc; ++i) { + atom = atom_explode(argv[i]); + if (!atom) + warn("invalid atom: %s", argv[i]); + else + xarraypush_ptr(atoms, atom); + } + + flags = 0; + if (do_list) + flags |= QLOP_LIST; + if (do_unlist) + flags |= QLOP_UNLIST; + if (flags) + show_emerge_history(flags, atoms, logfile); - if (do_list && do_unlist) - show_emerge_history(QLOP_LIST | QLOP_UNLIST, argc, argv, logfile); - else if (do_list) - show_emerge_history(QLOP_LIST, argc, argv, logfile); - else if (do_unlist) - show_emerge_history(QLOP_UNLIST, argc, argv, logfile); if (do_current) show_current_emerge(); if (do_sync) @@ -689,6 +702,9 @@ int qlop_main(int argc, char **argv) show_merge_times(argv[i], logfile, average, do_human_readable); } + array_for_each(atoms, i, atom) + atom_implode(atom); + xarrayfree_int(atoms); free(logfile); return EXIT_SUCCESS;