aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-08 08:19:56 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-08 08:19:56 -0700
commit4e3ef6118691fce8dcdcd8214c5866a7e5a8c8f3 (patch)
treee18d0a7f7ef46dfd1435363a13ad9388d9a34c18
parent7ff253cfee19cb798096dd0193a67e9663573f92 (diff)
downloadpw-4e3ef6118691fce8dcdcd8214c5866a7e5a8c8f3.tar.gz
pw-4e3ef6118691fce8dcdcd8214c5866a7e5a8c8f3.tar.bz2
pw-4e3ef6118691fce8dcdcd8214c5866a7e5a8c8f3.zip
Implement -f option: commands from file.
-rw-r--r--pw.123
-rw-r--r--pw.c41
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"
"<command> 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;