about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDuncaen <mail@duncano.de>2019-01-28 15:30:19 +0100
committerLeah Neukirchen <chneukirchen@gmail.com>2020-05-15 18:41:13 +0200
commit4baa330b631136e981e9232a6adb7196cc6aa8da (patch)
tree58210d53fe9913bd422170edbef350d2a997ff30
parentd235a3e64ca740e4cee57fc85c5270494b9b81fd (diff)
downloadmblaze-4baa330b631136e981e9232a6adb7196cc6aa8da.tar.gz
mblaze-4baa330b631136e981e9232a6adb7196cc6aa8da.tar.xz
mblaze-4baa330b631136e981e9232a6adb7196cc6aa8da.zip
mpick: allow reading expressions from files i.e. using #!/bin/mpick
-rw-r--r--mpick.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/mpick.c b/mpick.c
index 16028a7..1a6c810 100644
--- a/mpick.c
+++ b/mpick.c
@@ -23,6 +23,7 @@
 #endif
 
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -858,8 +859,18 @@ parse_cond()
 static struct expr *
 parse_expr()
 {
-	pos = s;
-	struct expr *e = parse_cond();
+	ws();
+	return parse_cond();
+}
+
+static struct expr *
+parse_buf(const char *f, char *s)
+{
+	struct expr *e;
+	fname = f;
+	line = pos = s;
+	linenr = 1;
+	e = parse_expr();
 	if (*pos)
 		parse_error_at(NULL, "trailing garbage");
 	return e;
@@ -1377,16 +1388,40 @@ main(int argc, char *argv[])
 	while ((c = getopt(argc, argv, "Tt:v")) != -1)
 		switch (c) {
 		case 'T': Tflag = need_thr = 1; break;
-		case 't': expr = chain(expr, EXPR_AND, parse_expr(optarg)); break;
+		case 't': expr = chain(expr, EXPR_AND, parse_buf("argv", optarg)); break;
 		case 'v': vflag = 1; break;
 		default:
 			fprintf(stderr, "Usage: %s [-Tv] [-t test] [msglist ...]\n", argv0);
 			exit(1);
 		}
 
-	if (optind != argc)
-		for (c = optind; c < argc; c++)
+	if (optind != argc) {
+		for (c = optind; c < argc; c++) {
+			if (strchr(argv[c], '/') && access(argv[c], R_OK) == 0)
+				break;
 			expr = chain(expr, EXPR_AND, parse_msglist(argv[c]));
+		}
+
+		struct stat st;
+		int fd;
+		size_t len;
+		for (; c < argc; c++) {
+			if ((fd = open(argv[c], O_RDONLY)) == -1)
+				exit(1);
+			if (fstat(fd, &st) == -1)
+				exit(1);
+			len = st.st_size;
+			char *s = mmap(0, len+1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+			if (s == MAP_FAILED) {
+				perror("mmap");
+				exit(1);
+			}
+			s[len+1] = '\0';
+			close(fd);
+			expr = chain(expr, EXPR_AND, parse_buf(argv[c], s));
+			munmap(s, len+1);
+		}
+	}
 
 	if (isatty(0))
 		i = blaze822_loop1(":", need_thr ? collect : oneline);