aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pw.152
-rw-r--r--pw.c122
2 files changed, 133 insertions, 41 deletions
diff --git a/pw.1 b/pw.1
index 0738873..f4f05fc 100644
--- a/pw.1
+++ b/pw.1
@@ -156,8 +156,12 @@ Scroll the display to the right.
Reset scroll to first column.
.IP \fISpace\fP
-Suspend the refresh of the display. In suspended mode, input continues to pass
-through the FIFO, but all display refresh is stopped. The status indicator
+Suspend the acquisition of new snapshots. In suspended mode,
+input continues to pass through the FIFO, but new snapshots of data aren't
+taken. The display updates only due to horizontal scrolling, history
+browsing, resize, or
+.B Ctrl-Z
+suspend and resume. The status indicator
.B SUSPENDED
is displayed below the data. If the the status is already
.B EOF
@@ -299,6 +303,50 @@ less recently received items, closer to the tail of the FIFO.
The advance/delay commands will not move any trigger to a position which
corresponds to a line that is not displayed.
+.IP "\fBk\fP, \fIUp Arrow\fP"
+Switch the display to earlier snapshot. Each time
+.I pw
+updates the display with a snapshot of data, the existing snapshot
+is entered into a history window, where it becomes snapshot 1.
+The previous snapshot 1 becomes 2, and so on. 19 snapshots are retained.
+The
+.B k
+command switches to an older snapshot: from current to 1, or from
+1 to 2, and so on. When snapshot 1 to 19 is being displayed,
+the status line shows
+.BI HIST num
+where
+.I num
+is the snapshot number.
+
+Tip: the snapshot history is particularly useful when it is gathered by
+triggering. See the
+.B /
+and
+.B ?
+commands above. Triggered snapshots can reveal recurring patterns in the input.
+The history can be used to identify differences among triggered snapshots which
+appear and disappear too rapidly to be read in real time. One of the possible
+uses of that information is to refine the trigger patterns in order to capture
+snapshots that are more similar to each other. In the absence of triggering,
+historic snapshots may be completely unrelated.
+
+Tip: it is usually useful to pause the acquisition of snapshots when browsing
+the history: see the
+.B Space
+command above. Snapshot acquisition is be observed while browsing the history,
+since every historic snapshot moves to a higher number when a snapshot is
+taken, while the displayed number stays the same, and the display updates
+accordingly.
+
+.IP "\fBl\fP, \fIDown Arrow\fP"
+Go back to earlier snapshot in history. If snapshot 1 is
+currently being displayed, then
+.I pw
+switches to the current snapshot and the
+.B HIST
+indicator in the status line disappears.
+
.IP "[\fIcount\fP]\fB+\fP"
Increases the display size by
.I count
diff --git a/pw.c b/pw.c
index baa62c5..2f19e25 100644
--- a/pw.c
+++ b/pw.c
@@ -52,6 +52,7 @@ typedef struct grep {
#define cmdsize 256
#define maxgrep 64
#define maxtrig 100
+#define snhistsize 20
typedef struct dstr {
int refs;
@@ -65,8 +66,8 @@ static int poll_interval = 1000;
static int long_interval = 10000;
static int regex_flags = 0;
-static char **snapshot;
-static int snaplines;
+static char **snapshot[snhistsize];
+static int snaplines[snhistsize];
static grep grepstack[maxgrep];
static int ngrep;
@@ -246,7 +247,7 @@ static void clreol(int nl)
putchar('\n');
}
-static void drawline(const char *line, int hpos, int columns)
+static void drawline(const char *line, unsigned hpos, int columns)
{
size_t len = dslen(line);
@@ -271,7 +272,7 @@ static void drawline(const char *line, int hpos, int columns)
}
}
-static void drawstatus(int columns, unsigned stat, char *cmd)
+static void drawstatus(unsigned hist, int columns, unsigned stat, char *cmd)
{
char status[cmdsize] = "", *ptr = status;
size_t lim = sizeof status;
@@ -283,9 +284,13 @@ static void drawstatus(int columns, unsigned stat, char *cmd)
if (cmd) {
snprintf(status, lim, "%s", cmd);
- } else if ((stat & (stat_eof | stat_susp | stat_htmode | stat_ttmode |
+ } else if (hist > 0 ||
+ (stat & (stat_eof | stat_susp | stat_htmode | stat_ttmode |
stat_grep)))
{
+ if (hist > 0)
+ ptr += snprintf(ptr, end - ptr, "HIST%u ", hist);
+
if ((stat & stat_eof))
ptr += snprintf(ptr, end - ptr, "EOF ");
@@ -325,33 +330,42 @@ static void drawstatus(int columns, unsigned stat, char *cmd)
fflush(stdout);
}
-static unsigned redraw(char **circbuf, int nlines, int hpos,
+static void freebuf(char **buf, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ dsdrop(buf[i]);
+}
+
+static unsigned redraw(char **circbuf, int nlines, unsigned hpos, unsigned hist,
int columns, unsigned stat, char *cmd)
{
if ((stat & (stat_dirty | stat_susp)) == stat_dirty &&
(stat & (stat_htmode | stat_trgrd)) != stat_htmode &&
(stat & (stat_ttmode | stat_trgrd)) != stat_ttmode)
{
- if (snapshot) {
- for (int i = 0; i < snaplines; i++)
- dsdrop(snapshot[i]);
+ if (snapshot[snhistsize - 1]) {
+ freebuf(snapshot[snhistsize - 1], snaplines[snhistsize - 1]);
+ free(snapshot[snhistsize - 1]);
}
- snaplines = nlines;
+ memmove(snapshot + 1, snapshot, sizeof *snapshot * (snhistsize - 1));
+ memmove(snaplines + 1, snaplines, sizeof *snaplines * (snhistsize - 1));
+ snapshot[0] = calloc(sizeof *snapshot[0], nlines);
+ snaplines[0] = nlines;
printf("\r\033[%dA", nlines);
for (int i = 0; i < nlines; i++) {
- drawline(circbuf[i], hpos, columns);
- snapshot[i] = dsref(circbuf[i]);
+ snapshot[0][i] = dsref(circbuf[i]);
+ drawline(snapshot[hist][i], hpos, columns);
}
stat &= ~(stat_dirty | stat_trgrd);
} else if ((stat & stat_force)) {
- printf("\r\033[%dA", snaplines);
- for (int i = 0; i < snaplines; i++)
- drawline(snapshot[i], hpos, columns);
+ printf("\r\033[%dA", snaplines[hist]);
+ for (int i = 0; i < snaplines[hist]; i++)
+ drawline(snapshot[hist][i], hpos, columns);
stat &= ~stat_force;
} else {
clrline();
}
- drawstatus(columns, stat, cmd);
+ drawstatus(hist, columns, stat, cmd);
return stat;
}
@@ -409,7 +423,7 @@ static int getms(const char *str, char **err)
return msec;
}
-static void execute(char *cmd, unsigned *pstat)
+static void execute(char *cmd, unsigned *pstat, unsigned hist)
{
char *arg = cmd + 2 + strspn(cmd + 2, " \t");
@@ -430,8 +444,8 @@ static void execute(char *cmd, unsigned *pstat)
break;
}
- for (int i = 0; ok && i < snaplines; i++)
- if (fprintf(f, "%s\n", snapshot[i]) < 0) {
+ for (int i = 0; ok && i < snaplines[hist]; i++)
+ if (fprintf(f, "%s\n", snapshot[hist][i]) < 0) {
sprintf(cmd, "write error!");
ok = 0;
break;
@@ -456,8 +470,8 @@ static void execute(char *cmd, unsigned *pstat)
break;
}
- for (int i = 0; i < snaplines && ok; i++)
- if (fprintf(p, "%s\n", snapshot[i]) < 0) {
+ for (int i = 0; i < snaplines[hist] && ok; i++)
+ if (fprintf(p, "%s\n", snapshot[hist][i]) < 0) {
sprintf(cmd, "write error!");
ok = 0;
break;
@@ -645,7 +659,7 @@ int main(int argc, char **argv)
if ((circbuf = calloc(sizeof *circbuf, maxlines)) == 0)
panic("out of memory");
- if ((snapshot = calloc(sizeof *snapshot, maxlines)) == 0)
+ if ((snapshot[0] = calloc(sizeof *snapshot[0], maxlines)) == 0)
panic("out of memory");
if (isatty(fd)) {
@@ -688,7 +702,7 @@ int main(int argc, char **argv)
sigaction(SIGWINCH, &sa, NULL);
#endif
- for (unsigned stat = stat_dirty, hpos = 0,
+ for (unsigned stat = stat_dirty, hpos = 0, hist = 0,
kbd_state = kbd_cmd, kbd_prev = kbd_cmd, lasttime = ~0U,
workbout = 1024, work = workbout, histpos = 0,
cmdcount = UINT_MAX;
@@ -708,7 +722,7 @@ int main(int argc, char **argv)
if (feof(stdin) || (errno != EAGAIN && errno != EWOULDBLOCK)) {
nfds = 1;
stat |= stat_eof;
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (!ferror(stdin))
exit_status = 0;
if (auto_quit) {
@@ -766,10 +780,11 @@ int main(int argc, char **argv)
} else {
circbuf[nlines++] = line;
if ((stat & stat_susp) == 0) {
- snapshot[snaplines++] = dsref(line);
+ snapshot[0] = resizebuf(snapshot[0], snaplines[0], snaplines[0] + 1);
+ snapshot[0][snaplines[0]++] = dsref(line);
clrline();
drawline(line, hpos, columns);
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
}
line = 0;
@@ -783,9 +798,14 @@ int main(int argc, char **argv)
winch = 0;
if (ioctl(ttyfd, TIOCGWINSZ, &ws) == 0) {
if (maxed) {
+ hist = 0;
circbuf = resizebuf(circbuf, maxlines, ws.ws_row - 1);
- snapshot = resizebuf(snapshot, maxlines, ws.ws_row - 1);
- maxlines = ws.ws_row - 1;
+ snapshot[0] = resizebuf(snapshot[0], maxlines, ws.ws_row - 1);
+ for (int i = 1; i < snhistsize; i++) {
+ freebuf(snapshot[i], snaplines[i]);
+ free(snapshot[i]);
+ snapshot[i] = 0;
+ }
} else {
if (maxlines >= ws.ws_row) {
maxlines = ws.ws_row - 1;
@@ -795,8 +815,8 @@ int main(int argc, char **argv)
if (nlines > maxlines)
nlines = maxlines;
- if (snaplines > maxlines)
- snaplines = maxlines;
+ if (snaplines[0] > maxlines)
+ snaplines[0] = maxlines;
columns = ws.ws_col;
}
@@ -832,17 +852,17 @@ int main(int argc, char **argv)
}
if (force)
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (poll(pe, nfds, pollms) <= 0) {
if (pollms) {
if ((stat & stat_dirty) && nlines == maxlines)
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (kbd_state == kbd_esc || kbd_state == kbd_result) {
kbd_state = kbd_cmd;
curcmd = 0;
clrline();
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
}
work = workbout += workbout / 4;
@@ -859,7 +879,8 @@ int main(int argc, char **argv)
ttyset(ttyfd, &tty_new);
for (int i = 0; i < nlines; i++)
puts("");
- stat = redraw(circbuf, nlines, hpos, columns, stat | stat_force, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns,
+ stat | stat_force, curcmd);
continue;
}
@@ -887,6 +908,18 @@ int main(int argc, char **argv)
stat |= stat_force;
}
break;
+ case 'j':
+ if (hist > 0) {
+ hist--;
+ stat |= stat_force;
+ }
+ break;
+ case 'k':
+ if (hist < snhistsize - 1 && snapshot[hist + 1]) {
+ hist++;
+ stat |= stat_force;
+ }
+ break;
case ' ':
if ((stat & stat_eof) == 0)
stat |= stat_susp;
@@ -941,7 +974,7 @@ int main(int argc, char **argv)
}
break;
case '+':
- if (ws.ws_row && maxlines >= ws.ws_row - 1) {
+ if (hist > 0 || (ws.ws_row && maxlines >= ws.ws_row - 1)) {
break;
} else {
unsigned count = (cmdcount == UINT_MAX) ? 1 : cmdcount;
@@ -954,7 +987,12 @@ int main(int argc, char **argv)
}
circbuf = resizebuf(circbuf, maxlines, maxlines + 1);
- snapshot = resizebuf(snapshot, maxlines, maxlines + 1);
+ snapshot[0] = resizebuf(snapshot[0], maxlines, maxlines + 1);
+ for (int i = 1; i < snhistsize; i++) {
+ freebuf(snapshot[i], snaplines[i]);
+ free(snapshot[i]);
+ snapshot[i] = 0;
+ }
}
break;
case '0':
@@ -994,6 +1032,12 @@ int main(int argc, char **argv)
case 'H':
ch = '0';
goto fakecmd;
+ case 'A':
+ ch = 'k';
+ goto fakecmd;
+ case 'B':
+ ch = 'j';
+ goto fakecmd;
}
switch (ch) {
case 'A':
@@ -1032,7 +1076,7 @@ int main(int argc, char **argv)
}
if (kbd_state == kbd_colon && cmdbuf[1]) {
- execute(cmdbuf, &stat);
+ execute(cmdbuf, &stat, hist);
if (cmdbuf[0] != 0) {
kbd_state = kbd_result;
break;
@@ -1176,11 +1220,11 @@ int main(int argc, char **argv)
}
if ((stat & (stat_dirty | stat_force))) {
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
} else switch (kbd_state) {
case kbd_colon: case kbd_trig: case kbd_result: case kbd_cmd:
clrline();
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
} else {
work = workbout += workbout / 4;