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;

Reply via email to