From aa62c737002cbc7079709df4acbcfc75ed55eeba Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Sat, 16 Jul 2016 18:45:39 +0200 Subject: add mseq (replaces next) --- Makefile | 4 +- mseq.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ next.c | 81 ------------------------------ 3 files changed, 174 insertions(+), 83 deletions(-) create mode 100644 mseq.c delete mode 100644 next.c diff --git a/Makefile b/Makefile index cfed8a3..9a37fce 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CFLAGS=-g -O1 -Wall -Wno-switch -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2 -ALL = scan thread hdr show list next unmime +ALL = scan thread hdr show list unmime mseq all: $(ALL) @@ -9,8 +9,8 @@ thread: blaze822.o thread.o hdr: blaze822.o hdr.o rfc2047.o show: blaze822.o show.o list: list.o -next: next.o unmime: blaze822.o unmime.o rfc2045.o rfc2047.o +mseq: mseq.o clean: FRC -rm -f $(ALL) *.o diff --git a/mseq.c b/mseq.c new file mode 100644 index 0000000..7c65c8e --- /dev/null +++ b/mseq.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char * +seq_open(char *file) +{ + int fd; + struct stat st; + + // env $SEQ or something + if (!file) + file = "map"; + fd = open(file, O_RDONLY); + if (!fd) + return 0; + + fstat(fd, &st); + char *map = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + + if (map == MAP_FAILED) + return 0; + + return map; +} + +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[]) +{ + char *map = seq_open(0); + 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; + 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++; + } + } + } + +/* + 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/next.c b/next.c deleted file mode 100644 index b121c74..0000000 --- a/next.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int -main(int argc, char *argv[]) -{ - int fd; - struct stat st; - - fd = open("map", O_RDONLY); - if (!fd) - exit(101); - - fstat(fd, &st); - char *map = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) - exit(102); - - char *s; - char *arg; - if (argc > 2) - arg = argv[2]; - else - arg = "+1"; - - if (argc <= 1 || !argv[1][0]) { - // default to first line - arg = "1"; - } - - if (*arg == '+' || *arg == '-') { - s = strstr(map, argv[1]); - int a = atoi(arg); - if (!s) { - s = map; - a = 0; - } - if (a > 0) { - while (a-- > 0) { - while (*s && *s != '\n') - s++; - s++; - } - } else { - while (a++ <= 0 && map < s) { - s--; - while (map < s && *s != '\n') - s--; - } - if (map < s && *s == '\n') - s++; - } - } else { - int a = atoi(arg); - s = map; - while (--a > 0) { - char *n = strchr(s+1, '\n'); - if (!n) - break; - s = n; - } - if (s && *s) - s++; - } - char *t = s; - while (*t && *t != '\n') - t++; - if (!*t) - return 1; - t++; - if (write(1, s, t-s) <= 0) - return 2; - return 0; -} -- cgit 1.4.1