version 1.41, 2014/11/25 10:22:08 |
version 1.42, 2014/12/09 20:28:43 |
|
|
static int tifd = -1; /* plan b virtual string array */ |
static int tifd = -1; /* plan b virtual string array */ |
static char *tibuf[2]; /* plan b buffers */ |
static char *tibuf[2]; /* plan b buffers */ |
static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */ |
static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */ |
static LINENUM lines_per_buf; /* how many lines per buffer */ |
static size_t lines_per_buf; /* how many lines per buffer */ |
static int tireclen; /* length of records in tmp file */ |
static size_t tibuflen; /* plan b buffer length */ |
|
static size_t tireclen; /* length of records in tmp file */ |
|
|
static bool rev_in_string(const char *); |
static bool rev_in_string(const char *); |
static bool reallocate_lines(size_t *); |
static bool reallocate_lines(size_t *); |
|
|
plan_b(const char *filename) |
plan_b(const char *filename) |
{ |
{ |
FILE *ifp; |
FILE *ifp; |
size_t i = 0, j, maxlen = 1; |
size_t i = 0, j, len, maxlen = 1; |
char *p; |
char *lbuf = NULL, *p; |
bool found_revision = (revision == NULL); |
bool found_revision = (revision == NULL); |
|
|
using_plan_a = false; |
using_plan_a = false; |
|
|
(void) unlink(TMPINNAME); |
(void) unlink(TMPINNAME); |
if ((tifd = open(TMPINNAME, O_EXCL | O_CREAT | O_WRONLY, 0666)) < 0) |
if ((tifd = open(TMPINNAME, O_EXCL | O_CREAT | O_WRONLY, 0666)) < 0) |
pfatal("can't open file %s", TMPINNAME); |
pfatal("can't open file %s", TMPINNAME); |
while (fgets(buf, sizeof buf, ifp) != NULL) { |
while ((p = fgetln(ifp, &len)) != NULL) { |
if (revision != NULL && !found_revision && rev_in_string(buf)) |
if (p[len - 1] == '\n') |
|
p[len - 1] = '\0'; |
|
else { |
|
/* EOF without EOL, copy and add the NUL */ |
|
if ((lbuf = malloc(len + 1)) == NULL) |
|
fatal("out of memory\n"); |
|
memcpy(lbuf, p, len); |
|
lbuf[len] = '\0'; |
|
p = lbuf; |
|
|
|
last_line_missing_eol = true; |
|
len++; |
|
} |
|
if (revision != NULL && !found_revision && rev_in_string(p)) |
found_revision = true; |
found_revision = true; |
if ((i = strlen(buf)) > maxlen) |
if (len > maxlen) |
maxlen = i; /* find longest line */ |
maxlen = len; /* find longest line */ |
} |
} |
last_line_missing_eol = i > 0 && buf[i - 1] != '\n'; |
free(lbuf); |
if (last_line_missing_eol && maxlen == i) |
if (ferror(ifp)) |
maxlen++; |
pfatal("can't read file %s", filename); |
|
|
if (revision != NULL) { |
if (revision != NULL) { |
if (!found_revision) { |
if (!found_revision) { |
|
|
revision); |
revision); |
} |
} |
fseek(ifp, 0L, SEEK_SET); /* rewind file */ |
fseek(ifp, 0L, SEEK_SET); /* rewind file */ |
lines_per_buf = BUFFERSIZE / maxlen; |
|
tireclen = maxlen; |
tireclen = maxlen; |
tibuf[0] = malloc(BUFFERSIZE + 1); |
tibuflen = maxlen > BUFFERSIZE ? maxlen : BUFFERSIZE; |
|
lines_per_buf = tibuflen / maxlen; |
|
tibuf[0] = malloc(tibuflen + 1); |
if (tibuf[0] == NULL) |
if (tibuf[0] == NULL) |
fatal("out of memory\n"); |
fatal("out of memory\n"); |
tibuf[1] = malloc(BUFFERSIZE + 1); |
tibuf[1] = malloc(tibuflen + 1); |
if (tibuf[1] == NULL) |
if (tibuf[1] == NULL) |
fatal("out of memory\n"); |
fatal("out of memory\n"); |
for (i = 1;; i++) { |
for (i = 1;; i++) { |
p = tibuf[0] + maxlen * (i % lines_per_buf); |
p = tibuf[0] + maxlen * (i % lines_per_buf); |
if (i % lines_per_buf == 0) /* new block */ |
if (i % lines_per_buf == 0) /* new block */ |
if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) |
if (write(tifd, tibuf[0], tibuflen) != |
|
(ssize_t) tibuflen) |
pfatal("can't write temp file"); |
pfatal("can't write temp file"); |
if (fgets(p, maxlen + 1, ifp) == NULL) { |
if (fgets(p, maxlen + 1, ifp) == NULL) { |
input_lines = i - 1; |
input_lines = i - 1; |
if (i % lines_per_buf != 0) |
if (i % lines_per_buf != 0) |
if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) |
if (write(tifd, tibuf[0], tibuflen) != |
|
(ssize_t) tibuflen) |
pfatal("can't write temp file"); |
pfatal("can't write temp file"); |
break; |
break; |
} |
} |
|
|
tiline[whichbuf] = baseline; |
tiline[whichbuf] = baseline; |
|
|
if (lseek(tifd, (off_t) (baseline / lines_per_buf * |
if (lseek(tifd, (off_t) (baseline / lines_per_buf * |
BUFFERSIZE), SEEK_SET) < 0) |
tibuflen), SEEK_SET) < 0) |
pfatal("cannot seek in the temporary input file"); |
pfatal("cannot seek in the temporary input file"); |
|
|
if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0) |
if (read(tifd, tibuf[whichbuf], tibuflen) |
|
!= (ssize_t) tibuflen) |
pfatal("error reading tmp file %s", TMPINNAME); |
pfatal("error reading tmp file %s", TMPINNAME); |
} |
} |
return tibuf[whichbuf] + (tireclen * offline); |
return tibuf[whichbuf] + (tireclen * offline); |