seq: import most parts of mseq, make blaze822_loop resolve ranges

pull/1/merge
Christian Neukirchen 8 years ago
parent 7e17d9d631
commit 08032f89ba

@ -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

@ -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)
{

@ -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 *));

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

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

Loading…
Cancel
Save