From: "Mike Frysinger" <vapier@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage-utils:master commit in: /, man/, tests/qlop/
Date: Mon, 28 Mar 2016 04:53:50 +0000 (UTC) [thread overview]
Message-ID: <1459137122.79ae531435cf37e50676c25e794f335a6587c7d3.vapier@gentoo> (raw)
commit: 79ae531435cf37e50676c25e794f335a6587c7d3
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 28 03:52:02 2016 +0000
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Mon Mar 28 03:52:02 2016 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=79ae5314
qlop: add --date option to filter output
Allow people to filter results by start & end dates.
URL: https://bugs.gentoo.org/192918
Reported-by: Laurento Frittella <laurento.frittella <AT> gmail.com>
man/qlop.1 | 5 +-
qlop.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++---
tests/qlop/dotest | 5 ++
tests/qlop/list06.good | 2 +
tests/qlop/list07.good | 2 +
tests/qlop/list08.good | 2 +
6 files changed, 139 insertions(+), 8 deletions(-)
diff --git a/man/qlop.1 b/man/qlop.1
index 6e645a8..77cf5ef 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -1,4 +1,4 @@
-.TH qlop "1" "Feb 2016" "Gentoo Foundation" "qlop"
+.TH qlop "1" "Mar 2016" "Gentoo Foundation" "qlop"
.SH NAME
qlop \- emerge log analyzer
.SH SYNOPSIS
@@ -29,6 +29,9 @@ Show sync history
\fB\-c\fR, \fB\-\-current\fR
Show current emerging packages
.TP
+\fB\-d\fR \fI<arg>\fR, \fB\-\-date\fR \fI<arg>\fR
+Limit selection to this time (1st -d is start, 2nd -d is end)
+.TP
\fB\-f\fR \fI<arg>\fR, \fB\-\-logfile\fR \fI<arg>\fR
Read emerge logfile instead of $EMERGE_LOG_DIR/emerge.log
.TP
diff --git a/qlop.c b/qlop.c
index 319d767..0da636a 100644
--- a/qlop.c
+++ b/qlop.c
@@ -10,7 +10,7 @@
#define QLOP_DEFAULT_LOGFILE "emerge.log"
-#define QLOP_FLAGS "gtHluscf:" COMMON_FLAGS
+#define QLOP_FLAGS "gtHluscd:f:" COMMON_FLAGS
static struct option const qlop_long_opts[] = {
{"gauge", no_argument, NULL, 'g'},
{"time", no_argument, NULL, 't'},
@@ -19,6 +19,7 @@ static struct option const qlop_long_opts[] = {
{"unlist", no_argument, NULL, 'u'},
{"sync", no_argument, NULL, 's'},
{"current", no_argument, NULL, 'c'},
+ {"date", a_argument, NULL, 'd'},
{"logfile", a_argument, NULL, 'f'},
COMMON_LONG_OPTS
};
@@ -30,6 +31,7 @@ static const char * const qlop_opts_help[] = {
"Show unmerge history",
"Show sync history",
"Show current emerging packages",
+ "Limit selection to this time (1st -d is start, 2nd -d is end)",
"Read emerge logfile instead of $EMERGE_LOG_DIR/" QLOP_DEFAULT_LOGFILE,
COMMON_OPTS_HELP
};
@@ -64,7 +66,8 @@ chop_ctime(time_t t)
}
_q_static unsigned long
-show_merge_times(char *package, const char *logfile, int average, char human_readable)
+show_merge_times(char *package, const char *logfile, int average, char human_readable,
+ time_t start_time, time_t end_time)
{
FILE *fp;
char cat[126], buf[2][BUFSIZ];
@@ -103,6 +106,8 @@ show_merge_times(char *package, const char *logfile, int average, char human_rea
continue;
*p = 0;
t[0] = atol(buf[0]);
+ if (t[0] < start_time || t[0] > end_time)
+ continue;
strcpy(buf[1], p + 1);
rmspace(buf[1]);
if (strncmp(buf[1], ">>> emerge (", 12) == 0) {
@@ -216,7 +221,8 @@ show_merge_times(char *package, const char *logfile, int average, char human_rea
}
_q_static void
-show_emerge_history(int listflag, array_t *atoms, const char *logfile)
+show_emerge_history(int listflag, array_t *atoms, const char *logfile,
+ time_t start_time, time_t end_time)
{
FILE *fp;
size_t buflen, linelen;
@@ -247,6 +253,8 @@ show_emerge_history(int listflag, array_t *atoms, const char *logfile)
continue;
t = (time_t) atol(buf);
+ if (t < start_time || t > end_time)
+ continue;
if ((listflag & QLOP_LIST) && !strncmp(q, "::: completed emerge (", 22)) {
merged = 1;
@@ -313,7 +321,7 @@ New format:
1431764493: *** terminating.
*/
_q_static void
-show_sync_history(const char *logfile)
+show_sync_history(const char *logfile, time_t start_time, time_t end_time)
{
FILE *fp;
size_t buflen, linelen;
@@ -344,6 +352,8 @@ show_sync_history(const char *logfile)
rmspace_len(buf, linelen);
t = (time_t)atol(buf);
+ if (t < start_time || t > end_time)
+ continue;
if (!strncmp(p, "with ", 5))
p += 5;
@@ -635,16 +645,112 @@ void show_current_emerge(void)
}
#endif
+_q_static
+bool parse_date(const char *sdate, time_t *t)
+{
+ struct tm tm;
+ const char *s;
+
+ memset(&tm, 0, sizeof(tm));
+
+ s = strchr(sdate, '|');
+ if (s) {
+ /* Handle custom format like "%Y|2012". */
+ size_t fmtlen = s - sdate;
+ char fmt[fmtlen + 1];
+ memcpy(fmt, sdate, fmtlen);
+ fmt[fmtlen] = '\0';
+ sdate = s + 1;
+ s = strptime(sdate, fmt, &tm);
+ if (s == NULL || s[0] != '\0')
+ return false;
+ } else {
+ /* Handle automatic formats:
+ * - "12315128" -> %s
+ * - "2015-12-24" -> %F (same as %Y-%m-%d
+ * - human readable format (see below)
+ */
+ size_t len = strspn(sdate, "0123456789-");
+ if (sdate[len] == '\0') {
+ const char *fmt;
+ if (strchr(sdate, '-') == NULL)
+ fmt = "%s";
+ else
+ fmt = "%F";
+
+ s = strptime(sdate, fmt, &tm);
+ if (s == NULL || s[0] != '\0')
+ return false;
+ } else {
+ /* Handle the formats:
+ * <#> <day|week|month|year>[s] [ago]
+ */
+ len = strlen(sdate);
+
+ unsigned long num;
+ char dur[len];
+ char ago[len];
+ int ret = sscanf(sdate, "%lu %s %s", &num, dur, ago);
+
+ if (ret < 2)
+ return false;
+ if (ret == 3 && strcmp(ago, "ago") != 0)
+ return false;
+
+ if (time(t) == -1)
+ return false;
+ if (localtime_r(t, &tm) == NULL)
+ return false;
+
+ /* Chop and trailing "s" sizes. */
+ len = strlen(dur);
+ if (dur[len - 1] == 's')
+ dur[len - 1] = '\0';
+
+ /* Step down the current time. */
+ if (!strcmp(dur, "year")) {
+ tm.tm_year -= num;
+ } else if (!strcmp(dur, "month")) {
+ if (num >= 12) {
+ tm.tm_year -= (num / 12);
+ num %= 12;
+ }
+ tm.tm_mon -= num;
+ if (tm.tm_mon < 0) {
+ tm.tm_mon += 12;
+ tm.tm_year -= 1;
+ }
+ } else if (!strcmp(dur, "week")) {
+ num *= 7;
+ goto days;
+ } else if (!strcmp(dur, "day")) {
+ days:
+ /* This is in seconds, so scale w/that. */
+ *t -= (num * 24 * 60 * 60);
+ if (localtime_r(t, &tm) == NULL)
+ return false;
+ } else
+ return false;
+ }
+ }
+
+ *t = mktime(&tm);
+ return (*t == -1) ? false : true;
+}
+
int qlop_main(int argc, char **argv)
{
size_t i;
int average = 1;
+ time_t start_time, end_time;
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);
+ start_time = 0;
+ end_time = LONG_MAX;
do_time = do_list = do_unlist = do_sync = do_current = 0;
while ((i = GETOPT_LONG(QLOP, qlop, "")) != -1) {
@@ -658,6 +764,16 @@ int qlop_main(int argc, char **argv)
case 'c': do_current = 1; break;
case 'g': do_time = 1; average = 0; break;
case 'H': do_human_readable = 1; break;
+ case 'd':
+ if (start_time == 0) {
+ if (!parse_date(optarg, &start_time))
+ err("invalid date: %s", optarg);
+ } else if (end_time == LONG_MAX) {
+ if (!parse_date(optarg, &end_time))
+ err("invalid date: %s", optarg);
+ } else
+ err("too many -d options");
+ break;
case 'f':
if (logfile) err("Only use -f once");
logfile = xstrdup(optarg);
@@ -685,16 +801,17 @@ int qlop_main(int argc, char **argv)
if (do_unlist)
flags |= QLOP_UNLIST;
if (flags)
- show_emerge_history(flags, atoms, logfile);
+ show_emerge_history(flags, atoms, logfile, start_time, end_time);
if (do_current)
show_current_emerge();
if (do_sync)
- show_sync_history(logfile);
+ show_sync_history(logfile, start_time, end_time);
if (do_time) {
for (i = 0; i < argc; ++i)
- show_merge_times(argv[i], logfile, average, do_human_readable);
+ show_merge_times(argv[i], logfile, average, do_human_readable,
+ start_time, end_time);
}
array_for_each(atoms, i, atom)
diff --git a/tests/qlop/dotest b/tests/qlop/dotest
index fad6011..0275d45 100755
--- a/tests/qlop/dotest
+++ b/tests/qlop/dotest
@@ -37,6 +37,11 @@ test 04 0 "qlop -l gcc -f ${as}/sync.log"
# verify atom version parsing works
test 05 0 "qlop -l '<gcc-5' -f ${as}/sync.log"
+# check date time parser
+test 06 0 "qlop -l -f ${as}/sync.log -d 2005-01-01"
+test 07 0 "qlop -l -f ${as}/sync.log -d '%d%Y%m|01200501'"
+test 08 0 "qlop -l -f ${as}/sync.log -d 1104898893"
+
cleantmpdir
end
diff --git a/tests/qlop/list06.good b/tests/qlop/list06.good
new file mode 100644
index 0000000..e9fccc3
--- /dev/null
+++ b/tests/qlop/list06.good
@@ -0,0 +1,2 @@
+Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
+Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1
diff --git a/tests/qlop/list07.good b/tests/qlop/list07.good
new file mode 100644
index 0000000..e9fccc3
--- /dev/null
+++ b/tests/qlop/list07.good
@@ -0,0 +1,2 @@
+Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
+Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1
diff --git a/tests/qlop/list08.good b/tests/qlop/list08.good
new file mode 100644
index 0000000..e9fccc3
--- /dev/null
+++ b/tests/qlop/list08.good
@@ -0,0 +1,2 @@
+Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
+Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1
reply other threads:[~2016-03-28 4:53 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1459137122.79ae531435cf37e50676c25e794f335a6587c7d3.vapier@gentoo \
--to=vapier@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox