version 1.6, 2000/06/30 16:00:23 |
version 1.7, 2001/02/04 21:27:00 |
|
|
|
|
#include <string.h> |
#include <string.h> |
|
|
|
static int seq __P((FILE *, DBT *, DBT *)); |
|
|
/* |
/* |
* this is the subroutine for file management for fsort(). |
* this is the subroutine for file management for fsort(). |
* It keeps the buffers for all temporary files. |
* It keeps the buffers for all temporary files. |
|
|
int binno; |
int binno; |
union f_handle infl0; |
union f_handle infl0; |
int nfiles; |
int nfiles; |
register RECHEADER *pos; |
RECHEADER *pos; |
register u_char *end; |
u_char *end; |
struct field *dummy; |
struct field *dummy; |
{ |
{ |
register int i; |
int i; |
register u_char *hp; |
u_char *hp; |
static int nleft = 0; |
static size_t nleft = 0; |
static int cnt = 0, flag = -1; |
static int cnt = 0, flag = -1; |
static u_char maxb = 0; |
static u_char maxb = 0; |
static FILE *fp; |
static FILE *fp; |
|
|
return (EOF); |
return (EOF); |
} |
} |
fp = fstack[infl0.top + cnt].fp; |
fp = fstack[infl0.top + cnt].fp; |
hp = (u_char *) &nleft; |
fread(&nleft, sizeof(nleft), 1, fp); |
for (i = sizeof(TRECHEADER); i; --i) |
|
*hp++ = getc(fp); |
|
if (binno < maxb) |
if (binno < maxb) |
fstack[infl0.top+cnt].max_o |
fstack[infl0.top+cnt].max_o |
+= sizeof(nleft) + nleft; |
+= sizeof(nleft) + nleft; |
|
|
} |
} |
if ((u_char *) pos > end - sizeof(TRECHEADER)) |
if ((u_char *) pos > end - sizeof(TRECHEADER)) |
return (BUFFEND); |
return (BUFFEND); |
hp = (u_char *) pos; |
fread(pos, sizeof(TRECHEADER), 1, fp); |
for (i = sizeof(TRECHEADER); i ; --i) |
|
*hp++ = (u_char) getc(fp); |
|
if (end - pos->data < pos->length) { |
if (end - pos->data < pos->length) { |
|
hp = ((u_char *)pos) + sizeof(TRECHEADER); |
for (i = sizeof(TRECHEADER); i ; i--) |
for (i = sizeof(TRECHEADER); i ; i--) |
ungetc(*--hp, fp); |
ungetc(*--hp, fp); |
return (BUFFEND); |
return (BUFFEND); |
|
|
u_char *bufend; |
u_char *bufend; |
struct field *dummy2; |
struct field *dummy2; |
{ |
{ |
static char *opos; |
static u_char *obufend; |
register char *end, *pos; |
static size_t osz; |
|
char *pos; |
static int fileno = 0, overflow = 0; |
static int fileno = 0, overflow = 0; |
static FILE *fp = 0; |
static FILE *fp = 0; |
register int c; |
int c; |
|
|
pos = (char *) buffer->data; |
pos = (char *) buffer->data; |
end = min((char *) bufend, pos + MAXLLEN); |
|
if (overflow) { |
if (overflow) { |
memmove(pos, opos, bufend - (u_char *) opos); |
/* |
pos += ((char *) bufend - opos); |
* Buffer shortage is solved by either of two ways: |
|
* * Flush previous buffered data and start using the |
|
* buffer from start (see fsort()) |
|
* * realloc buffer and bump bufend |
|
* |
|
* The former is perferred, realloc is only done when |
|
* there is exactly one item in buffer which does not fit. |
|
*/ |
|
if (bufend == obufend) |
|
memmove(pos, bufend - osz, osz); |
|
pos+=osz; |
overflow = 0; |
overflow = 0; |
} |
} |
for (;;) { |
for (;;) { |
|
|
err(2, "%s", filelist.names[fileno]); |
err(2, "%s", filelist.names[fileno]); |
fileno++; |
fileno++; |
} |
} |
while ((pos < end) && ((c = getc(fp)) != EOF)) { |
while ((pos < (char *)bufend) && ((c = getc(fp)) != EOF)) { |
if ((*pos++ = c) == REC_D) { |
if ((*pos++ = c) == REC_D) { |
buffer->offset = 0; |
buffer->offset = 0; |
buffer->length = pos - (char *) buffer->data; |
buffer->length = pos - (char *) buffer->data; |
return (0); |
return (0); |
} |
} |
} |
} |
if (pos >= end && end == (char *) bufend) { |
if (pos >= (char *)bufend) { |
if ((char *) buffer->data < end) { |
if (buffer->data < bufend) { |
overflow = 1; |
overflow = 1; |
opos = (char *) buffer->data; |
obufend = bufend; |
|
osz = (pos - (char *)buffer->data); |
} |
} |
return (BUFFEND); |
return (BUFFEND); |
} else if (c == EOF) { |
} else if (c == EOF) { |
if (buffer->data != (u_char *) pos) { |
if (buffer->data != (u_char *) pos) { |
warnx("last character not record delimiter"); |
|
*pos++ = REC_D; |
*pos++ = REC_D; |
buffer->offset = 0; |
buffer->offset = 0; |
buffer->length = pos - (char *) buffer->data; |
buffer->length = pos - (char *) buffer->data; |
|
|
if (flno >= 0) |
if (flno >= 0) |
fstack[flno].fp = 0; |
fstack[flno].fp = 0; |
} else { |
} else { |
buffer->data[100] = '\000'; |
warnx("line too long: ignoring %100s...", buffer->data); |
warnx("line too long: ignoring %s...", buffer->data); |
|
|
/* Consume the rest of the line from input */ |
|
while((c = getc(fp)) != REC_D && c != EOF) |
|
; |
|
|
|
buffer->offset = 0; |
|
buffer->length = 0; |
|
|
|
return (BUFFEND); |
} |
} |
} |
} |
} |
} |
|
|
u_char *bufend; |
u_char *bufend; |
struct field *ftbl; |
struct field *ftbl; |
{ |
{ |
static int (*get)(); |
|
static int fileno = 0; |
static int fileno = 0; |
static FILE *dbdesc = 0; |
static FILE *dbdesc = 0; |
static DBT dbkey[1], line[1]; |
static DBT dbkey[1], line[1]; |
static int overflow = 0; |
static int overflow = 0; |
int c; |
static int c; |
|
|
if (overflow) { |
if (overflow) { |
overflow = 0; |
overflow = enterkey(buffer, line, bufend - (u_char *)buffer, |
enterkey(buffer, line, bufend - (u_char *) buffer, ftbl); |
ftbl); |
return (0); |
if (overflow) |
|
return (BUFFEND); |
|
else |
|
return (0); |
} |
} |
|
|
for (;;) { |
for (;;) { |
if (flno >= 0) { |
if (flno >= 0) { |
get = seq; |
|
if (!(dbdesc = fstack[flno].fp)) |
if (!(dbdesc = fstack[flno].fp)) |
return (EOF); |
return (EOF); |
} else if (!dbdesc) { |
} else if (!dbdesc) { |
|
|
if (!dbdesc) |
if (!dbdesc) |
err(2, "%s", filelist.names[fileno]); |
err(2, "%s", filelist.names[fileno]); |
fileno++; |
fileno++; |
get = seq; |
|
} |
} |
if (!(c = get(dbdesc, line, dbkey))) { |
if (!(c = seq(dbdesc, line, dbkey))) { |
if ((signed)line->size > bufend - buffer->data) |
if ((signed)line->size > bufend - buffer->data) { |
overflow = 1; |
overflow = 1; |
else |
} else { |
overflow = enterkey(buffer, line, |
overflow = enterkey(buffer, line, |
bufend - (u_char *) buffer, ftbl); |
bufend - (u_char *) buffer, ftbl); |
|
} |
if (overflow) |
if (overflow) |
return (BUFFEND); |
return (BUFFEND); |
else |
else |
|
|
/* |
/* |
* get a key/line pair from fp |
* get a key/line pair from fp |
*/ |
*/ |
int |
static int |
seq(fp, line, key) |
seq(fp, line, key) |
FILE *fp; |
FILE *fp; |
DBT *line; |
DBT *line; |
DBT *key; |
DBT *key; |
{ |
{ |
static char *buf, flag = 1; |
static char *buf, flag = 1; |
register char *end, *pos; |
char *end, *pos; |
register int c; |
int c; |
|
|
if (flag) { |
if (flag) { |
flag = 0; |
flag = 0; |
buf = (char *) linebuf; |
buf = (char *) linebuf; |
end = buf + MAXLLEN; |
end = buf + linebuf_size; |
line->data = buf; |
line->data = buf; |
} |
} |
pos = buf; |
pos = buf; |
|
|
return (0); |
return (0); |
} |
} |
if (pos == end) { |
if (pos == end) { |
line->size = MAXLLEN; |
linebuf_size *= 2; |
*--pos = REC_D; |
linebuf = realloc(linebuf, linebuf_size); |
while ((c = getc(fp)) != EOF) { |
if (!linebuf) |
if (c == REC_D) |
err(2, "realloc of linebuf to %lu bytes failed", |
return (BUFFEND); |
(unsigned long)linebuf_size); |
} |
end = linebuf + linebuf_size; |
|
pos = linebuf + (pos - buf); |
|
line->data = buf = (char *)linebuf; |
|
continue; |
} |
} |
} |
} |
if (pos != buf) { |
if (pos != buf) { |
warnx("last character not record delimiter"); |
|
*pos++ = REC_D; |
*pos++ = REC_D; |
line->size = pos - buf; |
line->size = pos - buf; |
return (0); |
return (0); |
|
|
*/ |
*/ |
void |
void |
putrec(rec, fp) |
putrec(rec, fp) |
register RECHEADER *rec; |
RECHEADER *rec; |
register FILE *fp; |
FILE *fp; |
{ |
{ |
EWRITE(rec, 1, rec->length + sizeof(TRECHEADER), fp); |
EWRITE(rec, 1, rec->length + sizeof(TRECHEADER), fp); |
} |
} |
|
|
*/ |
*/ |
void |
void |
putline(rec, fp) |
putline(rec, fp) |
register RECHEADER *rec; |
RECHEADER *rec; |
register FILE *fp; |
FILE *fp; |
{ |
{ |
EWRITE(rec->data+rec->offset, 1, rec->length - rec->offset, fp); |
EWRITE(rec->data+rec->offset, 1, rec->length - rec->offset, fp); |
} |
} |
|
|
geteasy(flno, filelist, nfiles, rec, end, dummy2) |
geteasy(flno, filelist, nfiles, rec, end, dummy2) |
int flno, nfiles; |
int flno, nfiles; |
union f_handle filelist; |
union f_handle filelist; |
register RECHEADER *rec; |
RECHEADER *rec; |
register u_char *end; |
u_char *end; |
struct field *dummy2; |
struct field *dummy2; |
{ |
{ |
int i; |
int i; |