From 824aca06ffbde70f86a72e474c051e0bf4474906 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 27 Apr 2022 20:06:25 -0700 Subject: Regex matching for trigger mode. --- pw.1 | 35 +++++++++++++++++++++-------------- pw.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/pw.1 b/pw.1 index 5fe9000..6effc43 100644 --- a/pw.1 +++ b/pw.1 @@ -177,33 +177,40 @@ and also terminate colon mode without executing a command. Colon commands are documented in the COLON COMMANDS section below. -.IP \fB/\fP\fIpattern\fP -Activate head trigger mode if a non-empty +.IP "\fB/\fP\fIpattern\fP, \fB?\fP\fIpattern\fP" +Activate trigger mode if a non-empty .I pattern is specified, or else cancel trigger mode if an empty pattern is -specified. Under head trigger mode, -the display refreshes only when the most recent line in the FIFO -matches the specified +specified. The +.B / +command specifies +.I "head trigger" +mode, whereas +.B ? +specifies +.I "tail trigger" +mode. +Under head trigger mode, +the display refreshes only when the most recent line ("head line") +in the FIFO matches the specified .IR pattern . -That line at the head of the FIFO is the one which will appear at +The head line is the one which will appear at the bottom of the display, since newer lines appear at the bottom and scroll out toward the top. In head trigger mode, the status string .BI "TRIG (/" pattern ")" appears, showing the pattern preceded by a slash. - -.IP \fB?\fP\fIpattern\fP -Activate tail trigger mode if a non-empty -.I pattern -is specified, or else cancel trigger mode if an empty pattern is -specified. Under tail trigger mode, -the display refreshes only when the least recent line in the FIFO +Under tail trigger mode, +the display refreshes only when the least recent line ("tail line") in the FIFO matches the specified .IR pattern . -That line at the tail of the FIFO is the one which will appear at +That line is the one which will appear at the top of the display. In tail trigger mode, the status string .BI "TRIG (?" pattern ")" appears, showing the pattern preceded by a question mark. +The +.I pattern +is an extended regular expression (ERE). .SH COLON COMMANDS diff --git a/pw.c b/pw.c index 9e2a64a..60c94b0 100644 --- a/pw.c +++ b/pw.c @@ -11,6 +11,7 @@ #include #include #include +#include enum status_flags { stat_dirty = 1, // display needs refresh @@ -32,6 +33,7 @@ typedef struct dstr { char **snapshot; int snaplines; char *trigpat; +regex_t trigex; static void panic(const char *fmt, ...) { @@ -429,7 +431,7 @@ int main(int argc, char **argv) if ((stat & stat_eof) == 0 && pe[1].revents) { if ((line = getln(stdin))) { if ((stat & stat_htmode)) - if (strstr(line, trigpat)) + if (regexec(&trigex, line, 0, NULL, 0) == 0) stat |= stat_trgrd; if (nlines == maxlines) { dsdrop(circbuf[0]); @@ -437,7 +439,7 @@ int main(int argc, char **argv) circbuf[nlines - 1] = line; stat |= stat_dirty; if ((stat & stat_ttmode)) - if (strstr(circbuf[0], trigpat)) + if (regexec(&trigex, circbuf[0], 0, NULL, 0) == 0) stat |= stat_trgrd; } else { circbuf[nlines++] = line; @@ -542,12 +544,18 @@ int main(int argc, char **argv) goto fakecmd; } break; - case kbd_colon: case kbd_htrig: case kbd_ttrig: + if (trigpat) { + regfree(&trigex); + dsdrop(trigpat); + trigpat = 0; + } + stat &= ~(stat_htmode | stat_ttmode); + // fallthrough + case kbd_colon: switch (ch) { case 27: case 13: case 3: - kbd_state = kbd_cmd; stat |= stat_dirty; if (ch == 13) { if (kbd_state == kbd_colon && cmdbuf[1]) { @@ -556,14 +564,23 @@ int main(int argc, char **argv) kbd_state = kbd_result; break; } else if (cmdbuf[1]) { - dsdrop(trigpat); + int err; trigpat = dsdup(cmdbuf + 1); - stat &= ~(stat_htmode | stat_ttmode); - stat |= (kbd_state == kbd_htrig) ? stat_htmode : stat_ttmode; - } else { - stat &= ~(stat_htmode | stat_ttmode); + if ((err = regcomp(&trigex, trigpat, + REG_EXTENDED | REG_NOSUB))) + { + regerror(err, &trigex, cmdbuf, sizeof cmdbuf); + if (columns < (int) sizeof cmdbuf - 1) + cmdbuf[columns] = 0; + kbd_state = kbd_result; + dsdrop(trigpat); + trigpat = 0; + break; + } + stat |= (kbd_state == kbd_htrig ? stat_htmode : stat_ttmode); } } + kbd_state = kbd_cmd; curcmd = 0; break; case 8: case 127: -- cgit v1.2.3