=================================================================== RCS file: /cvs/mandoc/read.c,v retrieving revision 1.46 retrieving revision 1.68 diff -u -p -r1.46 -r1.68 --- mandoc/read.c 2014/03/23 11:25:26 1.46 +++ mandoc/read.c 2014/07/07 21:36:20 1.68 @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.46 2014/03/23 11:25:26 schwarze Exp $ */ +/* $Id: read.c,v 1.68 2014/07/07 21:36:20 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -46,7 +46,7 @@ #define REPARSE_LIMIT 1000 struct buf { - char *buf; /* binary input buffer */ + char *buf; /* binary input buffer */ size_t sz; /* size of binary buffer */ }; @@ -63,7 +63,7 @@ struct mparse { char *sodest; /* filename pointed to by .so */ int reparse_count; /* finite interp. stack */ mandocmsg mmsg; /* warning/error message handler */ - const char *file; + const char *file; struct buf *secondary; char *defos; /* default operating system */ }; @@ -93,67 +93,74 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "generic warning", /* related to the prologue */ - "no title in document", - "document title should be all caps", + "missing .TH macro, using \"unknown 1\"", + "lower case character in document title", "unknown manual section", "unknown manual volume or arch", - "date missing, using today's date", + "missing date, using today's date", "cannot parse date, using it verbatim", "prologue macros out of order", "duplicate prologue macro", - "macro not allowed in prologue", - "macro not allowed in body", + "incomplete prologue, terminated by", + "skipping prologue macro in body", /* related to document structure */ ".so is fragile, better use ln(1)", - "NAME section must come first", + "no document body", + "content before first section header", + "first section is not \"NAME\"", "bad NAME section contents", "sections out of conventional order", - "duplicate section name", - "section header suited to sections 2, 3, and 9 only", + "duplicate section title", + "unexpected section", /* related to macros and nesting */ - "skipping obsolete macro", + "obsolete macro", "skipping paragraph macro", "moving paragraph macro out of list", "skipping no-space macro", "blocks badly nested", - "child violates parent syntax", "nested displays are not portable", - "already in literal mode", + "moving content out of list", + ".Vt block has child macro", + "fill mode already enabled, skipping .fi", + "fill mode already disabled, skipping .nf", "line scope broken", /* related to missing macro arguments */ + "skipping empty request", + "conditional request controls empty scope", "skipping empty macro", + "empty argument, using 0n", "argument count wrong", - "missing display type", - "list type must come first", - "tag lists require a width argument", - "missing font type", - "skipping end of block that is not open", + "missing display type, using -ragged", + "list type is not the first argument", + "missing -width in -tag list, using 8n", + "empty head in list item", + "empty list item", + "missing font type, using \\fR", + "unknown font type, using \\fR", + "missing -std argument, adding it", /* related to bad macro arguments */ "skipping argument", + "unterminated quoted argument", "duplicate argument", - "duplicate display type", - "duplicate list type", + "skipping duplicate display type", + "skipping duplicate list type", "unknown AT&T UNIX version", - "bad Boolean value", - "unknown font", - "unknown standard specifier", - "bad width argument", + "invalid content in Rs block", + "invalid Boolean argument", + "unknown font, skipping request", /* related to plain text */ - "blank line in non-literal context", - "tab in non-literal context", - "end of line whitespace", + "blank line in fill mode, using .sp", + "tab in filled text", + "whitespace at end of input line", "bad comment style", - "bad escape sequence", - "unterminated quoted string", + "invalid escape sequence", + "undefined string, using \"\"", - /* related to equations */ - "unexpected literal in equation", - "generic error", /* related to equations */ @@ -173,26 +180,25 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "data block still open", "ignoring extra data cells", + /* related to document structure and macros */ "input stack limit exceeded, infinite loop?", "skipping bad character", - "escaped character not allowed in a name", - "manual name not yet set", - "skipping text before the first section header", "skipping unknown macro", - "NOT IMPLEMENTED, please use groff: skipping request", - "argument count wrong", "skipping column outside column list", "skipping end of block that is not open", - "missing end of block", - "scope open on exit", + "inserting missing end of block", + "appending missing end of block", + + /* related to request and macro arguments */ + "escaped character not allowed in a name", + "manual name not yet set", + "argument count wrong", + "unknown standard specifier", "uname(3) system call failed", - "macro requires line argument(s)", - "macro requires body argument(s)", - "macro requires argument(s)", "request requires a numeric argument", - "missing list type", - "line argument(s) will be lost", - "body argument(s) will be lost", + "missing list type, using -item", + "skipping all arguments", + "skipping excess arguments", "generic fatal error", @@ -200,16 +206,15 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "not a manual", "column syntax is inconsistent", "NOT IMPLEMENTED: .Bd -file", - "argument count wrong, violates syntax", "child violates parent syntax", "argument count wrong, violates syntax", "NOT IMPLEMENTED: .so with absolute path or \"..\"", - "no document body", + ".so request failed", "no document prologue", "static buffer exhausted", /* system errors */ - "cannot open file", + NULL, "cannot stat file", "cannot read file", }; @@ -224,6 +229,7 @@ static const char * const mandoclevels[MANDOCLEVEL_MAX "SYSERR" }; + static void resize_buf(struct buf *buf, size_t initial) { @@ -257,7 +263,7 @@ pset(const char *buf, int pos, struct mparse *curp) } if (MPARSE_MDOC & curp->options) { - if (NULL == curp->pmdoc) + if (NULL == curp->pmdoc) curp->pmdoc = mdoc_alloc( curp->roff, curp, curp->defos, MPARSE_QUICK & curp->options ? 1 : 0); @@ -265,7 +271,7 @@ pset(const char *buf, int pos, struct mparse *curp) curp->mdoc = curp->pmdoc; return; } else if (MPARSE_MAN & curp->options) { - if (NULL == curp->pman) + if (NULL == curp->pman) curp->pman = man_alloc(curp->roff, curp, MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pman); @@ -274,16 +280,16 @@ pset(const char *buf, int pos, struct mparse *curp) } if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) { - if (NULL == curp->pmdoc) + if (NULL == curp->pmdoc) curp->pmdoc = mdoc_alloc( curp->roff, curp, curp->defos, MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pmdoc); curp->mdoc = curp->pmdoc; return; - } + } - if (NULL == curp->pman) + if (NULL == curp->pman) curp->pman = man_alloc(curp->roff, curp, MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pman); @@ -308,8 +314,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int memset(&ln, 0, sizeof(struct buf)); - lnn = curp->line; - pos = 0; + lnn = curp->line; + pos = 0; for (i = 0; i < (int)blk.sz; ) { if (0 == pos && '\0' == blk.buf[i]) @@ -346,7 +352,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int if (pos + 2 >= (int)ln.sz) resize_buf(&ln, 256); - /* + /* * Warn about bogus characters. If you're using * non-ASCII encoding, you're screwing your * readers. Since I'd rather this not happen, @@ -357,10 +363,10 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int c = (unsigned char) blk.buf[i]; - if ( ! (isascii(c) && - (isgraph(c) || isblank(c)))) { + if ( ! (isascii(c) && + (isgraph(c) || isblank(c)))) { mandoc_msg(MANDOCERR_BADCHAR, curp, - curp->line, pos, NULL); + curp->line, pos, NULL); i++; ln.buf[pos++] = '?'; continue; @@ -414,10 +420,10 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int c = (unsigned char) blk.buf[i+1]; - if ( ! (isascii(c) && - (isgraph(c) || isblank(c)))) { + if ( ! (isascii(c) && + (isgraph(c) || isblank(c)))) { mandoc_msg(MANDOCERR_BADCHAR, curp, - curp->line, pos, NULL); + curp->line, pos, NULL); i += 2; ln.buf[pos++] = '?'; continue; @@ -429,7 +435,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int ln.buf[pos++] = blk.buf[i++]; } - if (pos >= (int)ln.sz) + if (pos >= (int)ln.sz) resize_buf(&ln, 256); ln.buf[pos] = '\0'; @@ -452,13 +458,12 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int */ if (curp->secondary) { - curp->secondary->buf = - mandoc_realloc - (curp->secondary->buf, - curp->secondary->sz + pos + 2); - memcpy(curp->secondary->buf + - curp->secondary->sz, - ln.buf, pos); + curp->secondary->buf = mandoc_realloc( + curp->secondary->buf, + curp->secondary->sz + pos + 2); + memcpy(curp->secondary->buf + + curp->secondary->sz, + ln.buf, pos); curp->secondary->sz += pos; curp->secondary->buf [curp->secondary->sz] = '\n'; @@ -467,31 +472,30 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int [curp->secondary->sz] = '\0'; } rerun: - rr = roff_parseln - (curp->roff, curp->line, - &ln.buf, &ln.sz, of, &of); + rr = roff_parseln(curp->roff, curp->line, + &ln.buf, &ln.sz, of, &of); switch (rr) { - case (ROFF_REPARSE): + case ROFF_REPARSE: if (REPARSE_LIMIT >= ++curp->reparse_count) mparse_buf_r(curp, ln, 0); else mandoc_msg(MANDOCERR_ROFFLOOP, curp, - curp->line, pos, NULL); + curp->line, pos, NULL); pos = 0; continue; - case (ROFF_APPEND): + case ROFF_APPEND: pos = (int)strlen(ln.buf); continue; - case (ROFF_RERUN): + case ROFF_RERUN: goto rerun; - case (ROFF_IGN): + case ROFF_IGN: pos = 0; continue; - case (ROFF_ERR): + case ROFF_ERR: assert(MANDOCLEVEL_FATAL <= curp->file_status); break; - case (ROFF_SO): + case ROFF_SO: if (0 == (MPARSE_SO & curp->options) && (i >= (int)blk.sz || '\0' == blk.buf[i])) { curp->sodest = mandoc_strdup(ln.buf + of); @@ -503,11 +507,15 @@ rerun: * buffer because we're going to descend into * the file recursively. */ - if (curp->secondary) + if (curp->secondary) curp->secondary->sz -= pos + 1; mparse_readfd(curp, -1, ln.buf + of); - if (MANDOCLEVEL_FATAL <= curp->file_status) + if (MANDOCLEVEL_FATAL <= curp->file_status) { + mandoc_vmsg(MANDOCERR_SO_FAIL, + curp, curp->line, pos, + ".so %s", ln.buf + of); break; + } pos = 0; continue; default: @@ -532,7 +540,7 @@ rerun: if ( ! (curp->man || curp->mdoc)) pset(ln.buf + of, pos - of, curp); - /* + /* * Lastly, push down into the parsers themselves. One * of these will have already been set in the pset() * routine. @@ -548,23 +556,23 @@ rerun: if (ROFF_TBL == rr) while (NULL != (span = roff_span(curp->roff))) { rc = curp->man ? - man_addspan(curp->man, span) : - mdoc_addspan(curp->mdoc, span); + man_addspan(curp->man, span) : + mdoc_addspan(curp->mdoc, span); if (0 == rc) break; } else if (ROFF_EQN == rr) - rc = curp->mdoc ? - mdoc_addeqn(curp->mdoc, - roff_eqn(curp->roff)) : - man_addeqn(curp->man, - roff_eqn(curp->roff)); + rc = curp->mdoc ? + mdoc_addeqn(curp->mdoc, + roff_eqn(curp->roff)) : + man_addeqn(curp->man, + roff_eqn(curp->roff)); else if (curp->man || curp->mdoc) rc = curp->man ? - man_parseln(curp->man, - curp->line, ln.buf, of) : - mdoc_parseln(curp->mdoc, - curp->line, ln.buf, of); + man_parseln(curp->man, + curp->line, ln.buf, of) : + mdoc_parseln(curp->mdoc, + curp->line, ln.buf, of); if (0 == rc) { assert(MANDOCLEVEL_FATAL <= curp->file_status); @@ -685,7 +693,7 @@ mparse_end(struct mparse *curp) } if ( ! (curp->mdoc || curp->man || curp->sodest)) { - mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL); + mandoc_msg(MANDOCERR_NOTMANUAL, curp, 0, 0, NULL); curp->file_status = MANDOCLEVEL_FATAL; return; } @@ -853,14 +861,14 @@ mandoc_vmsg(enum mandocerr t, struct mparse *m, va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf) - 1, fmt, ap); + (void)vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); mandoc_msg(t, m, ln, pos, buf); } void -mandoc_msg(enum mandocerr er, struct mparse *m, +mandoc_msg(enum mandocerr er, struct mparse *m, int ln, int col, const char *msg) { enum mandoclevel level;