version 1.93, 2014/10/25 01:03:52 |
version 1.95, 2014/11/01 04:08:43 |
|
|
struct man *man; /* man parser */ |
struct man *man; /* man parser */ |
struct mdoc *mdoc; /* mdoc parser */ |
struct mdoc *mdoc; /* mdoc parser */ |
struct roff *roff; /* roff parser (!NULL) */ |
struct roff *roff; /* roff parser (!NULL) */ |
|
const struct mchars *mchars; /* character table */ |
char *sodest; /* filename pointed to by .so */ |
char *sodest; /* filename pointed to by .so */ |
const char *file; /* filename of current input file */ |
const char *file; /* filename of current input file */ |
struct buf *primary; /* buffer currently being parsed */ |
struct buf *primary; /* buffer currently being parsed */ |
|
|
|
|
static void choose_parser(struct mparse *); |
static void choose_parser(struct mparse *); |
static void resize_buf(struct buf *, size_t); |
static void resize_buf(struct buf *, size_t); |
static void mparse_buf_r(struct mparse *, struct buf, int); |
static void mparse_buf_r(struct mparse *, struct buf, size_t, int); |
static int read_whole_file(struct mparse *, const char *, int, |
static int read_whole_file(struct mparse *, const char *, int, |
struct buf *, int *); |
struct buf *, int *); |
static void mparse_end(struct mparse *); |
static void mparse_end(struct mparse *); |
Line 302 choose_parser(struct mparse *curp) |
|
Line 303 choose_parser(struct mparse *curp) |
|
} |
} |
|
|
/* |
/* |
* Main parse routine for an opened file. This is called for each |
* Main parse routine for a buffer. |
* opened file and simply loops around the full input file, possibly |
* It assumes encoding and line numbering are already set up. |
* nesting (i.e., with `so'). |
* It can recurse directly (for invocations of user-defined |
|
* macros, inline equations, and input line traps) |
|
* and indirectly (for .so file inclusion). |
*/ |
*/ |
static void |
static void |
mparse_buf_r(struct mparse *curp, struct buf blk, int start) |
mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start) |
{ |
{ |
const struct tbl_span *span; |
const struct tbl_span *span; |
struct buf ln; |
struct buf ln; |
|
size_t pos; /* byte number in the ln buffer */ |
enum rofferr rr; |
enum rofferr rr; |
int i, of, rc; |
int of, rc; |
int pos; /* byte number in the ln buffer */ |
|
int lnn; /* line number in the real file */ |
int lnn; /* line number in the real file */ |
unsigned char c; |
unsigned char c; |
|
|
memset(&ln, 0, sizeof(struct buf)); |
memset(&ln, 0, sizeof(ln)); |
|
|
lnn = curp->line; |
lnn = curp->line; |
pos = 0; |
pos = 0; |
|
|
for (i = blk.offs; i < (int)blk.sz; ) { |
while (i < blk.sz) { |
if (0 == pos && '\0' == blk.buf[i]) |
if (0 == pos && '\0' == blk.buf[i]) |
break; |
break; |
|
|
Line 332 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 335 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
|
|
if (lnn < 3 && |
if (lnn < 3 && |
curp->filenc & MPARSE_UTF8 && |
curp->filenc & MPARSE_UTF8 && |
curp->filenc & MPARSE_LATIN1) { |
curp->filenc & MPARSE_LATIN1) |
blk.offs = i; |
curp->filenc = preconv_cue(&blk, i); |
curp->filenc = preconv_cue(&blk); |
|
} |
|
} |
} |
|
|
while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) { |
while (i < blk.sz && (start || blk.buf[i] != '\0')) { |
|
|
/* |
/* |
* When finding an unescaped newline character, |
* When finding an unescaped newline character, |
Line 346 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 347 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
* Skip a preceding carriage return, if any. |
* Skip a preceding carriage return, if any. |
*/ |
*/ |
|
|
if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz && |
if ('\r' == blk.buf[i] && i + 1 < blk.sz && |
'\n' == blk.buf[i + 1]) |
'\n' == blk.buf[i + 1]) |
++i; |
++i; |
if ('\n' == blk.buf[i]) { |
if ('\n' == blk.buf[i]) { |
Line 360 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 361 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
* case of 11 bytes: "\\[u10ffff]\0" |
* case of 11 bytes: "\\[u10ffff]\0" |
*/ |
*/ |
|
|
if (pos + 11 > (int)ln.sz) |
if (pos + 11 > ln.sz) |
resize_buf(&ln, 256); |
resize_buf(&ln, 256); |
|
|
/* |
/* |
Line 369 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 370 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
|
|
c = blk.buf[i]; |
c = blk.buf[i]; |
if (c & 0x80) { |
if (c & 0x80) { |
blk.offs = i; |
if ( ! (curp->filenc && preconv_encode( |
ln.offs = pos; |
&blk, &i, &ln, &pos, &curp->filenc))) { |
if (curp->filenc && preconv_encode( |
|
&blk, &ln, &curp->filenc)) { |
|
pos = ln.offs; |
|
i = blk.offs; |
|
} else { |
|
mandoc_vmsg(MANDOCERR_BADCHAR, |
mandoc_vmsg(MANDOCERR_BADCHAR, |
curp, curp->line, pos, |
curp, curp->line, pos, |
"0x%x", c); |
"0x%x", c); |
Line 399 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 395 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
|
|
/* Trailing backslash = a plain char. */ |
/* Trailing backslash = a plain char. */ |
|
|
if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) { |
if (blk.buf[i] != '\\' || i + 1 == blk.sz) { |
ln.buf[pos++] = blk.buf[i++]; |
ln.buf[pos++] = blk.buf[i++]; |
continue; |
continue; |
} |
} |
Line 411 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 407 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
* skip that one as well. |
* skip that one as well. |
*/ |
*/ |
|
|
if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz && |
if ('\r' == blk.buf[i + 1] && i + 2 < blk.sz && |
'\n' == blk.buf[i + 2]) |
'\n' == blk.buf[i + 2]) |
++i; |
++i; |
if ('\n' == blk.buf[i + 1]) { |
if ('\n' == blk.buf[i + 1]) { |
Line 423 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 419 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { |
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { |
i += 2; |
i += 2; |
/* Comment, skip to end of line */ |
/* Comment, skip to end of line */ |
for (; i < (int)blk.sz; ++i) { |
for (; i < blk.sz; ++i) { |
if ('\n' == blk.buf[i]) { |
if ('\n' == blk.buf[i]) { |
++i; |
++i; |
++lnn; |
++lnn; |
Line 460 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
Line 456 mparse_buf_r(struct mparse *curp, struct buf blk, int |
|
ln.buf[pos++] = blk.buf[i++]; |
ln.buf[pos++] = blk.buf[i++]; |
} |
} |
|
|
if (pos >= (int)ln.sz) |
if (pos >= ln.sz) |
resize_buf(&ln, 256); |
resize_buf(&ln, 256); |
|
|
ln.buf[pos] = '\0'; |
ln.buf[pos] = '\0'; |
|
|
switch (rr) { |
switch (rr) { |
case ROFF_REPARSE: |
case ROFF_REPARSE: |
if (REPARSE_LIMIT >= ++curp->reparse_count) |
if (REPARSE_LIMIT >= ++curp->reparse_count) |
mparse_buf_r(curp, ln, 0); |
mparse_buf_r(curp, ln, of, 0); |
else |
else |
mandoc_msg(MANDOCERR_ROFFLOOP, curp, |
mandoc_msg(MANDOCERR_ROFFLOOP, curp, |
curp->line, pos, NULL); |
curp->line, pos, NULL); |
pos = 0; |
pos = 0; |
continue; |
continue; |
case ROFF_APPEND: |
case ROFF_APPEND: |
pos = (int)strlen(ln.buf); |
pos = strlen(ln.buf); |
continue; |
continue; |
case ROFF_RERUN: |
case ROFF_RERUN: |
goto rerun; |
goto rerun; |
|
|
assert(MANDOCLEVEL_FATAL <= curp->file_status); |
assert(MANDOCLEVEL_FATAL <= curp->file_status); |
break; |
break; |
case ROFF_SO: |
case ROFF_SO: |
if (0 == (MPARSE_SO & curp->options) && |
if ( ! (curp->options & MPARSE_SO) && |
(i >= (int)blk.sz || '\0' == blk.buf[i])) { |
(i >= blk.sz || blk.buf[i] == '\0')) { |
curp->sodest = mandoc_strdup(ln.buf + of); |
curp->sodest = mandoc_strdup(ln.buf + of); |
free(ln.buf); |
free(ln.buf); |
return; |
return; |
Line 649 read_whole_file(struct mparse *curp, const char *file, |
|
Line 645 read_whole_file(struct mparse *curp, const char *file, |
|
return(0); |
return(0); |
} |
} |
*with_mmap = 1; |
*with_mmap = 1; |
fb->offs = 0; |
|
fb->sz = (size_t)st.st_size; |
fb->sz = (size_t)st.st_size; |
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); |
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); |
if (fb->buf != MAP_FAILED) |
if (fb->buf != MAP_FAILED) |
Line 681 read_whole_file(struct mparse *curp, const char *file, |
|
Line 676 read_whole_file(struct mparse *curp, const char *file, |
|
ssz = read(fd, fb->buf + (int)off, fb->sz - off); |
ssz = read(fd, fb->buf + (int)off, fb->sz - off); |
if (ssz == 0) { |
if (ssz == 0) { |
fb->sz = off; |
fb->sz = off; |
fb->offs = 0; |
|
return(1); |
return(1); |
} |
} |
if (ssz == -1) { |
if (ssz == -1) { |
Line 738 mparse_parse_buffer(struct mparse *curp, struct buf bl |
|
Line 732 mparse_parse_buffer(struct mparse *curp, struct buf bl |
|
{ |
{ |
struct buf *svprimary; |
struct buf *svprimary; |
const char *svfile; |
const char *svfile; |
|
size_t offset; |
static int recursion_depth; |
static int recursion_depth; |
|
|
if (64 < recursion_depth) { |
if (64 < recursion_depth) { |
Line 758 mparse_parse_buffer(struct mparse *curp, struct buf bl |
|
Line 753 mparse_parse_buffer(struct mparse *curp, struct buf bl |
|
(unsigned char)blk.buf[0] == 0xef && |
(unsigned char)blk.buf[0] == 0xef && |
(unsigned char)blk.buf[1] == 0xbb && |
(unsigned char)blk.buf[1] == 0xbb && |
(unsigned char)blk.buf[2] == 0xbf) { |
(unsigned char)blk.buf[2] == 0xbf) { |
blk.offs = 3; |
offset = 3; |
curp->filenc &= ~MPARSE_LATIN1; |
curp->filenc &= ~MPARSE_LATIN1; |
} |
} else |
|
offset = 0; |
|
|
mparse_buf_r(curp, blk, 1); |
mparse_buf_r(curp, blk, offset, 1); |
|
|
if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status) |
if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status) |
mparse_end(curp); |
mparse_end(curp); |
Line 779 mparse_readmem(struct mparse *curp, const void *buf, s |
|
Line 775 mparse_readmem(struct mparse *curp, const void *buf, s |
|
|
|
blk.buf = UNCONST(buf); |
blk.buf = UNCONST(buf); |
blk.sz = len; |
blk.sz = len; |
blk.offs = 0; |
|
|
|
mparse_parse_buffer(curp, blk, file); |
mparse_parse_buffer(curp, blk, file); |
return(curp->file_status); |
return(curp->file_status); |
Line 914 mparse_wait(struct mparse *curp, pid_t child_pid) |
|
Line 909 mparse_wait(struct mparse *curp, pid_t child_pid) |
|
} |
} |
|
|
struct mparse * |
struct mparse * |
mparse_alloc(int options, enum mandoclevel wlevel, |
mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg, |
mandocmsg mmsg, const char *defos) |
const struct mchars *mchars, const char *defos) |
{ |
{ |
struct mparse *curp; |
struct mparse *curp; |
|
|
Line 928 mparse_alloc(int options, enum mandoclevel wlevel, |
|
Line 923 mparse_alloc(int options, enum mandoclevel wlevel, |
|
curp->mmsg = mmsg; |
curp->mmsg = mmsg; |
curp->defos = defos; |
curp->defos = defos; |
|
|
curp->roff = roff_alloc(curp, options); |
curp->mchars = mchars; |
|
curp->roff = roff_alloc(curp, curp->mchars, options); |
if (curp->options & MPARSE_MDOC) |
if (curp->options & MPARSE_MDOC) |
curp->pmdoc = mdoc_alloc( |
curp->pmdoc = mdoc_alloc( |
curp->roff, curp, curp->defos, |
curp->roff, curp, curp->defos, |