version 1.66, 2010/05/15 05:11:50 |
version 1.70, 2010/05/15 16:20:12 |
Line 268 ffile(const char *file, struct curparse *curp) |
|
Line 268 ffile(const char *file, struct curparse *curp) |
|
|
|
|
|
static int |
static int |
|
resize_buf(struct buf *buf, size_t initial) |
|
{ |
|
void *tmp; |
|
size_t sz; |
|
|
|
if (buf->sz == 0) |
|
sz = initial; |
|
else |
|
sz = 2 * buf->sz; |
|
tmp = realloc(buf->buf, sz); |
|
if (NULL == tmp) { |
|
perror(NULL); |
|
return(0); |
|
} |
|
buf->buf = tmp; |
|
buf->sz = sz; |
|
return(1); |
|
} |
|
|
|
|
|
static int |
read_whole_file(struct curparse *curp, struct buf *fb, int *with_mmap) |
read_whole_file(struct curparse *curp, struct buf *fb, int *with_mmap) |
{ |
{ |
struct stat st; |
struct stat st; |
char *buf; |
size_t off; |
size_t sz, off; |
|
ssize_t ssz; |
ssize_t ssz; |
|
|
if (-1 == fstat(curp->fd, &st)) { |
if (-1 == fstat(curp->fd, &st)) { |
Line 319 read_whole_file(struct curparse *curp, struct buf *fb, |
|
Line 339 read_whole_file(struct curparse *curp, struct buf *fb, |
|
curp->file); |
curp->file); |
break; |
break; |
} |
} |
if (fb->sz == 0) |
if (! resize_buf(fb, 65536)) |
sz = 65536; |
|
else |
|
sz = 2 * fb->sz; |
|
buf = realloc(fb->buf, sz); |
|
if (NULL == buf) { |
|
perror(NULL); |
|
break; |
break; |
} |
|
fb->buf = buf; |
|
fb->sz = sz; |
|
} |
} |
ssz = read(curp->fd, fb->buf + off, fb->sz - off); |
ssz = read(curp->fd, fb->buf + off, fb->sz - off); |
if (ssz == 0) { |
if (ssz == 0) { |
Line 353 read_whole_file(struct curparse *curp, struct buf *fb, |
|
Line 364 read_whole_file(struct curparse *curp, struct buf *fb, |
|
static void |
static void |
fdesc(struct curparse *curp) |
fdesc(struct curparse *curp) |
{ |
{ |
size_t sz; |
|
struct buf ln, blk; |
struct buf ln, blk; |
int j, i, pos, lnn, comment, with_mmap; |
int i, pos, lnn, lnn_start, with_mmap; |
struct man *man; |
struct man *man; |
struct mdoc *mdoc; |
struct mdoc *mdoc; |
|
|
sz = BUFSIZ; |
|
man = NULL; |
man = NULL; |
mdoc = NULL; |
mdoc = NULL; |
memset(&ln, 0, sizeof(struct buf)); |
memset(&ln, 0, sizeof(struct buf)); |
|
|
/* |
/* |
* Two buffers: ln and buf. buf is the input buffer optimised |
* Two buffers: ln and buf. buf is the input file and may be |
* here for each file's block size. ln is a line buffer. Both |
* memory mapped. ln is a line buffer and grows on-demand. |
* growable, hence passed in by ptr-ptr. |
|
*/ |
*/ |
|
|
if (!read_whole_file(curp, &blk, &with_mmap)) |
if (!read_whole_file(curp, &blk, &with_mmap)) |
return; |
return; |
|
|
/* Fill buf with file blocksize. */ |
for (i = 0, lnn = 1; i < (int)blk.sz;) { |
|
pos = 0; |
for (i = lnn = pos = comment = 0; i < (int)blk.sz; ++i) { |
lnn_start = lnn; |
if (pos >= (int)ln.sz) { |
while (i < (int)blk.sz) { |
ln.sz += 256; /* Step-size. */ |
if ('\n' == blk.buf[i]) { |
ln.buf = realloc(ln.buf, ln.sz); |
++i; |
if (NULL == ln.buf) { |
++lnn; |
perror(NULL); |
break; |
goto bailout; |
|
} |
|
} |
} |
|
/* Trailing backslash is like a plain character. */ |
if ('\n' != blk.buf[i]) { |
if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) { |
if (comment) |
if (pos >= (int)ln.sz) |
continue; |
if (! resize_buf(&ln, 256)) |
ln.buf[pos++] = blk.buf[i]; |
goto bailout; |
|
ln.buf[pos++] = blk.buf[i++]; |
/* Handle in-line `\"' comments. */ |
continue; |
|
} |
if (1 == pos || '\"' != ln.buf[pos - 1]) |
/* Found an escape and at least one other character. */ |
continue; |
if ('\n' == blk.buf[i + 1]) { |
|
/* Escaped newlines are skipped over */ |
for (j = pos - 2; j >= 0; j--) |
i += 2; |
if ('\\' != ln.buf[j]) |
++lnn; |
|
continue; |
|
} |
|
if ('"' == blk.buf[i + 1]) { |
|
i += 2; |
|
/* Comment, skip to end of line */ |
|
for (; i < (int)blk.sz; ++i) { |
|
if ('\n' == blk.buf[i]) { |
|
++i; |
|
++lnn; |
break; |
break; |
|
} |
if ( ! ((pos - 2 - j) % 2)) |
} |
continue; |
/* Backout trailing whitespaces */ |
|
|
comment = 1; |
|
pos -= 2; |
|
for (; pos > 0; --pos) { |
for (; pos > 0; --pos) { |
if (ln.buf[pos - 1] != ' ') |
if (ln.buf[pos - 1] != ' ') |
break; |
break; |
if (pos > 2 && ln.buf[pos - 2] == '\\') |
if (pos > 2 && ln.buf[pos - 2] == '\\') |
break; |
break; |
} |
} |
continue; |
break; |
} |
|
|
|
/* Handle escaped `\\n' newlines. */ |
|
|
|
if (pos > 0 && 0 == comment && |
|
'\\' == ln.buf[pos - 1]) { |
|
for (j = pos - 1; j >= 0; j--) |
|
if ('\\' != ln.buf[j]) |
|
break; |
|
if ( ! ((pos - j) % 2)) { |
|
pos--; |
|
lnn++; |
|
continue; |
|
} |
|
} |
} |
|
/* Some other escape sequence, copy and continue. */ |
|
if (pos + 1 >= (int)ln.sz) |
|
if (! resize_buf(&ln, 256)) |
|
goto bailout; |
|
|
ln.buf[pos] = 0; |
ln.buf[pos++] = blk.buf[i++]; |
lnn++; |
ln.buf[pos++] = blk.buf[i++]; |
|
} |
|
|
/* If unset, assign parser in pset(). */ |
if (pos >= (int)ln.sz) |
|
if (! resize_buf(&ln, 256)) |
if ( ! (man || mdoc) && ! pset(ln.buf, |
|
pos, curp, &man, &mdoc)) |
|
goto bailout; |
goto bailout; |
|
ln.buf[pos] = 0; |
|
|
pos = comment = 0; |
/* If unset, assign parser in pset(). */ |
|
|
/* Pass down into parsers. */ |
if ( ! (man || mdoc) && ! pset(ln.buf, pos, curp, &man, &mdoc)) |
|
goto bailout; |
|
|
if (man && ! man_parseln(man, lnn, ln.buf)) |
/* Pass down into parsers. */ |
goto bailout; |
|
if (mdoc && ! mdoc_parseln(mdoc, lnn, ln.buf)) |
if (man && ! man_parseln(man, lnn, ln.buf)) |
goto bailout; |
goto bailout; |
|
if (mdoc && ! mdoc_parseln(mdoc, lnn, ln.buf)) |
|
goto bailout; |
} |
} |
|
|
/* NOTE a parser may not have been assigned, yet. */ |
/* NOTE a parser may not have been assigned, yet. */ |
Line 481 fdesc(struct curparse *curp) |
|
Line 486 fdesc(struct curparse *curp) |
|
case (OUTT_LINT): |
case (OUTT_LINT): |
break; |
break; |
default: |
default: |
curp->outdata = ascii_alloc(); |
curp->outdata = ascii_alloc(80); |
curp->outman = terminal_man; |
curp->outman = terminal_man; |
curp->outmdoc = terminal_mdoc; |
curp->outmdoc = terminal_mdoc; |
curp->outfree = terminal_free; |
curp->outfree = terminal_free; |