=================================================================== RCS file: /cvs/mandoc/read.c,v retrieving revision 1.149 retrieving revision 1.169 diff -u -p -r1.149 -r1.169 --- mandoc/read.c 2016/07/10 13:34:30 1.149 +++ mandoc/read.c 2017/06/03 15:55:24 1.169 @@ -1,7 +1,7 @@ -/* $Id: read.c,v 1.149 2016/07/10 13:34:30 schwarze Exp $ */ +/* $Id: read.c,v 1.169 2017/06/03 15:55:24 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010-2016 Ingo Schwarze + * Copyright (c) 2010-2017 Ingo Schwarze * Copyright (c) 2010, 2012 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -19,10 +19,8 @@ #include "config.h" #include -#if HAVE_MMAP #include #include -#endif #include #include @@ -32,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -50,8 +47,8 @@ #define REPARSE_LIMIT 1000 struct mparse { - struct roff_man *man; /* man parser */ struct roff *roff; /* roff parser (!NULL) */ + struct roff_man *man; /* man parser */ char *sodest; /* filename pointed to by .so */ const char *file; /* filename of current input file */ struct buf *primary; /* buffer currently being parsed */ @@ -69,7 +66,7 @@ struct mparse { static void choose_parser(struct mparse *); static void resize_buf(struct buf *, size_t); -static void mparse_buf_r(struct mparse *, struct buf, size_t, int); +static int mparse_buf_r(struct mparse *, struct buf, size_t, int); static int read_whole_file(struct mparse *, const char *, int, struct buf *, int *); static void mparse_end(struct mparse *); @@ -78,8 +75,8 @@ static void mparse_parse_buffer(struct mparse *, str static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = { MANDOCERR_OK, + MANDOCERR_STYLE, MANDOCERR_WARNING, - MANDOCERR_WARNING, MANDOCERR_ERROR, MANDOCERR_UNSUPP, MANDOCERR_MAX, @@ -89,6 +86,12 @@ static const enum mandocerr mandoclimits[MANDOCLEVEL_M static const char * const mandocerrs[MANDOCERR_MAX] = { "ok", + "generic style suggestion", + + "useless macro", + "consider using OS macro", + "description line ends with a full stop", + "generic warning", /* related to the prologue */ @@ -110,11 +113,13 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "no document body", "content before first section header", "first section is not \"NAME\"", - "NAME section without name", + "NAME section without Nm before Nd", "NAME section without description", "description not at the end of NAME", "bad NAME section content", + "missing comma before name", "missing description line, using \"\"", + "description line outside NAME section", "sections out of conventional order", "duplicate section title", "unexpected section", @@ -134,6 +139,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "fill mode already enabled, skipping", "fill mode already disabled, skipping", "line scope broken", + "skipping blank line in line scope", /* related to missing macro arguments */ "skipping empty request", @@ -143,7 +149,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "empty argument, using 0n", "missing display type, using -ragged", "list type is not the first argument", - "missing -width in -tag list, using 8n", + "missing -width in -tag list, using 6n", "missing utility name, using \"\"", "missing function name, using \"\"", "empty head in list item", @@ -152,6 +158,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "unknown font type, using \\fR", "nothing follows prefix", "empty reference block", + "missing section argument", "missing -std argument, adding it", "missing option string, using \"\"", "missing resource identifier, using \"\"", @@ -177,6 +184,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "blank line in fill mode, using .sp", "tab in filled text", "whitespace at end of input line", + "new sentence, new line", "bad comment style", "invalid escape sequence", "undefined string, using \"\"", @@ -240,7 +248,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = static const char * const mandoclevels[MANDOCLEVEL_MAX] = { "SUCCESS", - "RESERVED", + "STYLE", "WARNING", "ERROR", "UNSUPP", @@ -291,22 +299,16 @@ choose_parser(struct mparse *curp) } } - if (curp->man == NULL) { - curp->man = roff_man_alloc(curp->roff, curp, curp->defos, - curp->options & MPARSE_QUICK ? 1 : 0); - curp->man->macroset = MACROSET_MAN; - curp->man->first->tok = TOKEN_NONE; - } - if (format == MPARSE_MDOC) { - mdoc_hash_init(); curp->man->macroset = MACROSET_MDOC; - curp->man->first->tok = TOKEN_NONE; + if (curp->man->mdocmac == NULL) + curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX); } else { - man_hash_init(); curp->man->macroset = MACROSET_MAN; - curp->man->first->tok = TOKEN_NONE; + if (curp->man->manmac == NULL) + curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX); } + curp->man->first->tok = TOKEN_NONE; } /* @@ -316,7 +318,7 @@ choose_parser(struct mparse *curp) * macros, inline equations, and input line traps) * and indirectly (for .so file inclusion). */ -static void +static int mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start) { const struct tbl_span *span; @@ -324,6 +326,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size const char *save_file; char *cp; size_t pos; /* byte number in the ln buffer */ + size_t j; /* auxiliary byte number in the blk buffer */ enum rofferr rr; int of; int lnn; /* line number in the real file */ @@ -429,14 +432,21 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size } if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { + j = i; i += 2; /* Comment, skip to end of line */ for (; i < blk.sz; ++i) { - if ('\n' == blk.buf[i]) { - ++i; - ++lnn; - break; - } + if (blk.buf[i] != '\n') + continue; + if (blk.buf[i - 1] == ' ' || + blk.buf[i - 1] == '\t') + mandoc_msg( + MANDOCERR_SPACE_EOL, + curp, curp->line, + pos + i-1 - j, NULL); + ++i; + ++lnn; + break; } /* Backout trailing whitespaces */ @@ -509,13 +519,16 @@ rerun: switch (rr) { case ROFF_REPARSE: - if (REPARSE_LIMIT >= ++curp->reparse_count) - mparse_buf_r(curp, ln, of, 0); - else + if (++curp->reparse_count > REPARSE_LIMIT) mandoc_msg(MANDOCERR_ROFFLOOP, curp, curp->line, pos, NULL); - pos = 0; - continue; + else if (mparse_buf_r(curp, ln, of, 0) == 1 || + start == 1) { + pos = 0; + continue; + } + free(ln.buf); + return 0; case ROFF_APPEND: pos = strlen(ln.buf); continue; @@ -529,7 +542,7 @@ rerun: (i >= blk.sz || blk.buf[i] == '\0')) { curp->sodest = mandoc_strdup(ln.buf + of); free(ln.buf); - return; + return 1; } /* * We remove `so' clauses from our lookaside @@ -562,15 +575,7 @@ rerun: break; } - /* - * If input parsers have not been allocated, do so now. - * We keep these instanced between parsers, but set them - * locally per parse routine since we can use different - * parsers with each one. - */ - - if (curp->man == NULL || - curp->man->macroset == MACROSET_NONE) + if (curp->man->macroset == MACROSET_NONE) choose_parser(curp); /* @@ -603,19 +608,18 @@ rerun: } free(ln.buf); + return 1; } static int read_whole_file(struct mparse *curp, const char *file, int fd, struct buf *fb, int *with_mmap) { + struct stat st; gzFile gz; size_t off; ssize_t ssz; -#if HAVE_MMAP - struct stat st; - if (fstat(fd, &st) == -1) err((int)MANDOCLEVEL_SYSERR, "%s", file); @@ -637,7 +641,6 @@ read_whole_file(struct mparse *curp, const char *file, if (fb->buf != MAP_FAILED) return 1; } -#endif if (curp->gzip) { if ((gz = gzdopen(fd, "rb")) == NULL) @@ -683,10 +686,6 @@ read_whole_file(struct mparse *curp, const char *file, static void mparse_end(struct mparse *curp) { - - if (curp->man == NULL && curp->sodest == NULL) - curp->man = roff_man_alloc(curp->roff, curp, curp->defos, - curp->options & MPARSE_QUICK ? 1 : 0); if (curp->man->macroset == MACROSET_NONE) curp->man->macroset = MACROSET_MAN; if (curp->man->macroset == MACROSET_MDOC) @@ -766,11 +765,9 @@ mparse_readfd(struct mparse *curp, int fd, const char (MPARSE_UTF8 | MPARSE_LATIN1); mparse_parse_buffer(curp, blk, file); curp->filenc = save_filenc; -#if HAVE_MMAP if (with_mmap) munmap(blk.buf, blk.sz); else -#endif free(blk.buf); } return curp->file_status; @@ -829,11 +826,13 @@ mparse_alloc(int options, enum mandoclevel wlevel, man curp->man = roff_man_alloc( curp->roff, curp, curp->defos, curp->options & MPARSE_QUICK ? 1 : 0); if (curp->options & MPARSE_MDOC) { - mdoc_hash_init(); curp->man->macroset = MACROSET_MDOC; + if (curp->man->mdocmac == NULL) + curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX); } else if (curp->options & MPARSE_MAN) { - man_hash_init(); curp->man->macroset = MACROSET_MAN; + if (curp->man->manmac == NULL) + curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX); } curp->man->first->tok = TOKEN_NONE; return curp; @@ -842,27 +841,27 @@ mparse_alloc(int options, enum mandoclevel wlevel, man void mparse_reset(struct mparse *curp) { - roff_reset(curp->roff); + roff_man_reset(curp->man); - if (curp->man != NULL) - roff_man_reset(curp->man); + free(curp->sodest); + curp->sodest = NULL; + if (curp->secondary) curp->secondary->sz = 0; curp->file_status = MANDOCLEVEL_OK; - - free(curp->sodest); - curp->sodest = NULL; + curp->gzip = 0; } void mparse_free(struct mparse *curp) { + roffhash_free(curp->man->mdocmac); + roffhash_free(curp->man->manmac); roff_man_free(curp->man); - if (curp->roff) - roff_free(curp->roff); + roff_free(curp->roff); if (curp->secondary) free(curp->secondary->buf); @@ -882,6 +881,13 @@ mparse_result(struct mparse *curp, struct roff_man **m } if (man) *man = curp->man; +} + +void +mparse_updaterc(struct mparse *curp, enum mandoclevel *rc) +{ + if (curp->file_status > *rc) + *rc = curp->file_status; } void