about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--blaze822.c24
-rw-r--r--blaze822.h19
-rw-r--r--mseq.c130
-rw-r--r--seq.c198
5 files changed, 226 insertions, 155 deletions
diff --git a/Makefile b/Makefile
index c23e443..b7f8221 100644
--- a/Makefile
+++ b/Makefile
@@ -4,12 +4,12 @@ ALL = scan thread hdr show list unmime mseq
 
 all: $(ALL)
 
-scan: blaze822.o scan.o seq.o rfc2047.o
-thread: blaze822.o thread.o
-hdr: blaze822.o hdr.o rfc2047.o
-show: blaze822.o show.o rfc2045.o rfc2047.c
+scan: scan.o blaze822.o seq.o rfc2047.o
+thread: thread.o blaze822.o seq.o
+hdr: hdr.o blaze822.o seq.o rfc2047.o
+show: show.o blaze822.o seq.o rfc2045.o rfc2047.c
 list: list.o
-unmime: blaze822.o unmime.o rfc2045.o rfc2047.o
+unmime: unmime.o blaze822.o seq.o rfc2045.o rfc2047.o
 mseq: mseq.o seq.o
 
 clean: FRC
diff --git a/blaze822.c b/blaze822.c
index 4170ed5..dad52f3 100644
--- a/blaze822.c
+++ b/blaze822.c
@@ -450,30 +450,6 @@ blaze822_chdr(struct message *mesg, const char *chdr)
 	return blaze822_hdr_(mesg, hdr, l);
 }
 
-int
-blaze822_loop(int argc, char *argv[], void (*cb)(char *))
-{
-	char *line = 0;
-	size_t linelen = 0;
-	ssize_t rd;
-	int i = 0;
-
-	if (argc == 0 || (argc == 1 && strcmp(argv[0], "-") == 0)) {
-		while ((rd = getdelim(&line, &linelen, '\n', stdin)) != -1) {
-			if (line[rd-1] == '\n')
-				line[rd-1] = 0;
-			cb(line);
-			i++;
-		}
-		free(line);
-	} else {
-		for (i = 0; i < argc; i++)
-			cb(argv[i]);
-	}
-
-	return i;
-}
-
 struct message *
 blaze822_file(char *file)
 {
diff --git a/blaze822.h b/blaze822.h
index 96588a7..06687eb 100644
--- a/blaze822.h
+++ b/blaze822.h
@@ -24,8 +24,6 @@ char *blaze822_body(struct message *mesg);
 size_t blaze822_bodylen(struct message *mesg);
 size_t blaze822_headerlen(struct message *mesg);
 
-int blaze822_loop(int, char **, void (*)(char *));
-
 // rfc2047.c
 
 int blaze822_decode_rfc2047(char *, char *, size_t, char *);
@@ -44,3 +42,20 @@ int blaze822_mime_parameter(char *s, char *name, char **starto, char **stopo);
 char *blaze822_seq_open(char *file);
 int blaze822_seq_load(char *map);
 long blaze822_seq_find(char *ref);
+
+
+char *blaze822_seq_cur();
+int blaze822_seq_setcur(char *s);
+
+struct blaze822_seq_iter {
+	long lines;
+	long cur;
+	long start;
+	long stop;
+
+	long line;
+	char *s;
+};
+
+char *blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter);
+int blaze822_loop(int, char **, void (*)(char *));
diff --git a/mseq.c b/mseq.c
index 776966d..a700b72 100644
--- a/mseq.c
+++ b/mseq.c
@@ -12,54 +12,6 @@
 
 #include "blaze822.h"
 
-static const char *
-readlin(const char *p)
-{
-        static char b[PATH_MAX];
-        int r = readlink(p, b, sizeof b - 1);
-        if (r < 0)
-		r = 0;
-        b[r] = 0;
-        return b;
-}
-
-char *
-parse_relnum(char *a, long cur, long last, long *out)
-{
-	long base;
-	char *b;
-
-	if (strcmp(a, "+") == 0)
-		a = ".+1";
-	else if (strcmp(a, "-") == 0)
-		a = ".-1";
-	else if (strcmp(a, "$") == 0)
-		a = "-1";
-	
-	if (*a == '.') {
-		a++;
-		base = cur;
-	} else if (*a == '-') {
-		base = last + 1;
-	} else {
-		base = 0;
-	}
-	errno = 0;
-	long d = strtol(a, &b, 10);
-	if (errno != 0) {
-		perror("strtol");
-		exit(1);
-	}
-
-	*out = base + d;
-	if (*out <= 0)
-		*out = 1;
-	if (*out > last)
-		*out = last;
-	
-	return b;
-}
-
 int
 main(int argc, char *argv[])
 {
@@ -67,85 +19,15 @@ main(int argc, char *argv[])
 	if (!map)
 		return 1;
 
-	long lines;
-	long cur = 0;
-
-	const char *curfile = readlin("map.cur");
-	char *curpath;
-
-	char *s, *t;
-	for (s = map, lines = 0; s; s = t) {
-		t = strchr(s+1, '\n');
-		if (!t)
-			break;
-		s++;
-//		printf("{%.*s}\n", t-s, s);
-		lines++;
-		// XXX compare modulo whitespace
-		if (!cur &&
-		    strncmp(s, curfile, strlen(curfile)) == 0 &&
-		    s[strlen(curfile)] == '\n')
-			cur = lines;
-	}
-	lines--;
-
-	long i, start, stop;
+	int i;
+	char *f;
+	struct blaze822_seq_iter iter = { 0 };
 	for (i = 1; i < argc; i++) {
-		char *a = argv[i];
-		start = stop = 0;
-
-		while (*a && *a != ':') {
-			char *b = parse_relnum(a, cur, lines, &start);
-			if (a == b) {
-				printf("huh\n");
-				exit(1);
-			}
-			a = b;
-		}
-		if (*a == ':') {
-			a++;
-			if (!*a) {
-				stop = lines;
-			} else {
-				char *b = parse_relnum(a, cur, lines, &stop);
-				if (a == b) {
-					printf("huh\n");
-					exit(1);
-				}
-				a = b;
-			}
-		} else if (!*a) {
-			stop = start;
-		} else {
-			printf("huh\n");
-			exit(1);
-		}
-
-		long line;
-		for (s = map, line = 0; s; s = t) {
-			t = strchr(s+1, '\n');
-			if (!t)
-				break;
-			s++;
-			line++;
-
-			if (line >= start && line <= stop) {
-				fwrite(s, 1, t-s, stdout);
-				putchar('\n');
-				cur = line;
-				curpath = s;
-				while (*curpath == ' ')
-					curpath++;
-			}
+		while ((f = blaze822_seq_next(map, argv[i], &iter))) {
+			printf("%s\n", f);
+			free(f);
 		}
 	}
 
-/*
-	char *e = strchr(curpath, '\n');
-	unlink("map.cur-");
-	symlink(strndup(curpath, e-curpath), "map.cur-");
-	rename("map.cur-", "map.cur");
-*/
-
 	return 0;
 }
diff --git a/seq.c b/seq.c
index 26b0328..ab74023 100644
--- a/seq.c
+++ b/seq.c
@@ -99,3 +99,201 @@ blaze822_seq_load(char *map)
 
 	return 0;
 }
+
+char *
+blaze822_seq_cur()
+{
+        static char b[PATH_MAX];
+	// XXX env
+        int r = readlink("map.cur", b, sizeof b - 1);
+        if (r < 0)
+		return 0;
+        b[r] = 0;
+        return b;
+}
+
+int
+blaze822_seq_setcur(char *s)
+{
+	// XXX env
+	if (unlink("map.cur-") < 0 && errno != ENOENT)
+		return -1;
+	if (symlink(s, "map.cur-") < 0)
+		return -1;
+	if (rename("map.cur-", "map.cur") < 0)
+		return -1;
+	return 0;
+}
+
+static char *
+parse_relnum(char *a, long cur, long last, long *out)
+{
+	long base;
+	char *b;
+
+	if (strcmp(a, "+") == 0)
+		a = ".+1";
+	else if (strcmp(a, "-") == 0)
+		a = ".-1";
+	else if (strcmp(a, "$") == 0)
+		a = "-1";
+
+	if (*a == '.') {
+		a++;
+		base = cur;
+	} else if (*a == '-') {
+		base = last + 1;
+	} else {
+		base = 0;
+	}
+	errno = 0;
+	long d = strtol(a, &b, 10);
+	if (errno != 0) {
+		perror("strtol");
+		exit(1);
+	}
+
+	*out = base + d;
+	if (*out <= 0)
+		*out = 1;
+	if (*out > last)
+		*out = last;
+
+	return b;
+}
+
+static int
+parse_range(char *a, long *start, long *stop, long cur, long lines)
+{
+	*start = *stop = 1;
+
+	while (*a && *a != ':') {
+		char *b = parse_relnum(a, cur, lines, start);
+		if (a == b)
+			return 0;
+		a = b;
+	}
+	if (*a == ':') {
+		a++;
+		if (!*a) {
+			*stop = lines;
+		} else {
+			char *b = parse_relnum(a, cur, lines, stop);
+			if (a == b)
+				return 0;
+			a = b;
+		}
+	} else if (!*a) {
+		*stop = *start;
+	} else {
+		return 0;
+	}
+
+	return 1;
+}
+
+void
+find_cur(char *map, struct blaze822_seq_iter *iter)
+{
+	char *s, *t;
+	long cur = 0;
+	const char *curfile = blaze822_seq_cur();
+
+	iter->lines = 0;
+	for (s = map; s; s = t+1) {
+		t = strchr(s, '\n');
+		if (!t)
+			break;
+		while (*s == ' ' || *s == '\t')
+			s++;
+
+//		printf("{%.*s}\n", t-s, s);
+		iter->lines++;
+		if (!cur && curfile &&
+		    strncmp(s, curfile, strlen(curfile)) == 0 &&
+		    (s[strlen(curfile)] == '\n' ||
+		    s[strlen(curfile)] == ' ' ||
+		    s[strlen(curfile)] == '\t'))
+			iter->cur = iter->lines;
+	}
+}
+
+char *
+blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter)
+{
+	if (!map)
+		return 0;
+
+	if (!iter->lines)  // count total lines
+		find_cur(map, iter);
+
+	if (!iter->start) {
+		if (!parse_range(range, &iter->start, &iter->stop,
+				 iter->cur, iter->lines)) {
+			fprintf(stderr, "can't parse range: %s\n", range);
+			return 0;
+		}
+
+		iter->s = map;
+		iter->line = 1;
+	}
+
+	while (iter->line < iter->start) {
+		char *t = strchr(iter->s, '\n');
+		if (!t)
+			return 0;
+		iter->line++;
+		iter->s = t + 1;
+	}
+
+	if (iter->line > iter->stop) {
+		iter->start = iter->stop = 0;  // reset iteration
+		return 0;
+	}
+
+	char *t = strchr(iter->s, '\n');
+	if (!t)
+		return 0;
+	iter->cur = iter->line;
+	iter->line++;
+	char *r = strndup(iter->s, t-iter->s);
+	iter->s = t + 1;
+	return r;
+}
+
+
+int
+blaze822_loop(int argc, char *argv[], void (*cb)(char *))
+{
+	char *line = 0;
+	size_t linelen = 0;
+	ssize_t rd;
+	int i = 0;
+
+	if (argc == 0 || (argc == 1 && strcmp(argv[0], "-") == 0)) {
+		while ((rd = getdelim(&line, &linelen, '\n', stdin)) != -1) {
+			if (line[rd-1] == '\n')
+				line[rd-1] = 0;
+			cb(line);
+			i++;
+		}
+		free(line);
+		return i;
+	}
+
+	char *map = blaze822_seq_open(0);
+	struct blaze822_seq_iter iter = { 0 };
+	int j = 0;
+	for (i = 0; i < argc; i++) {
+		if (strchr(argv[i], '/')) {  // a file name
+			cb(argv[i]);
+		} else {
+			while ((line = blaze822_seq_next(map, argv[i], &iter))) {
+				cb(line);
+				free(line);
+				j++;
+			}
+		}
+	}
+	return j;
+}