From 4e3ef6118691fce8dcdcd8214c5866a7e5a8c8f3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 8 May 2022 08:19:56 -0700 Subject: Implement -f option: commands from file. --- pw.1 | 23 +++++++++++++++++++++++ pw.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/pw.1 b/pw.1 index fcb4709..6785564 100644 --- a/pw.1 +++ b/pw.1 @@ -856,6 +856,29 @@ sets a head-referenced trigger for the pattern .B ^Failed matching against line 3 of the FIFO. +.IP "\fB-f\fP \fIfile\fP" +Read colon and trigger commands from +.I file +and execute them. + +Each line of +.I file +must contain either a command in the same form as the argument of the +.B -e +option, or else a comment indicated by the first character being +.B # +(hash). + +If any line is diagnosed as erroneous, a diagnostic is issued +and execution continues. In this case, +.I pw +will terminate unsuccessfully after +.I file +is read. + +Command lines with leading whitespace are invalid, and trailing whitespace +counts as a command character (for example, as a constituent of a pattern), + .SH ENVIRONMENT .I pw diff --git a/pw.c b/pw.c index e878823..cfc4d71 100644 --- a/pw.c +++ b/pw.c @@ -269,6 +269,18 @@ static char *addchesc(char *line, int ch) return line; } +static char *getln(FILE *stream) +{ + for (char *line = 0;;) { + int ch = getc(stream); + if (ch == EOF) + return line; + if (ch == '\n') + return dsensure(line); + line = addchesc(line, ch); + } +} + static void usage(void) { fprintf(stderr, @@ -283,7 +295,8 @@ static void usage(void) "-g [!]pattern add pattern to grep stack; ! inverts\n" "-m integer specify maixmum line length\n" "-p values set display parameters\n" - "-e command execute :, / or ? command\n\n" + "-e command execute : / ? command\n" + "-f file execute : / ? commands from file\n\n" " represents an arbitrary command that generates the\n" "output to be monitored by %s.\n\n" "Standard input must be redirected; it cannot be the same device\n" @@ -994,7 +1007,7 @@ int main(int argc, char **argv) } } - while ((opt = getopt(argc, argv, "n:i:l:dEBg:q:m:p:e:")) != -1) { + while ((opt = getopt(argc, argv, "n:i:l:dEBg:q:m:p:e:f:")) != -1) { switch (opt) { case 'n': { @@ -1121,7 +1134,31 @@ int main(int argc, char **argv) error("-%c option: %s: %s\n", opt, optarg, pw.cmdbuf); return EXIT_FAILURE; } + } + break; + case 'f': + { + FILE *f = fopen(optarg, "r"); + long lino = 1; + int errors = 0; + char *line; + if (f == 0) { + error("-%c option: unable to open %s\n", opt, optarg); + return EXIT_FAILURE; + } + for (; (line = getln(f)) != 0; lino++) { + if (line[0] == '#') + continue; + if (batchexe(&pw, line, pw.cmdbuf, cmdsize) == exec_failed) { + error("%s:%ld: %s\n", optarg, lino, pw.cmdbuf); + errors = 1; + } + dsdrop(line); + } + fclose(f); + if (errors) { return EXIT_FAILURE; + dsdrop(line); } } break; -- cgit v1.2.3