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; +}