From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]) by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id 342a6272 for ; Thu, 13 Dec 2018 20:18:56 -0500 (EST) Date: Thu, 13 Dec 2018 20:18:56 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: Major cleanup; may imply minor changes in edge cases of error X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <05f5dec3a9d9e59e@fantadrom.bsd.lv> Log Message: ----------- Major cleanup; may imply minor changes in edge cases of error reporting. Finally, drop support for the run-time configurable mandocmsg() callback. It was over-engineered from the start, never used for anything in a decade, and repeatedly caused maintenance headaches. Consolidate reporting infrastructure into two files, mandoc.h and mandoc_msg.c, mopping up the bits and pieces that were scattered around main.c, read.c, mandoc_parse.h, libmandoc.h, the prototypes of four parsing-related functions, and both parser structs. Modified Files: -------------- mandoc: Makefile Makefile.depend cgi.c chars.c demandoc.c libmandoc.h main.c man_macro.c man_validate.c mandoc.3 mandoc.h mandoc_headers.3 mandoc_parse.h mandocd.c mandocdb.c mdoc_state.c msec.c read.c roff_term.c roff_validate.c st.c tbl_data.c tbl_layout.c Added Files: ----------- mandoc: mandoc_msg.c Revision Data ------------- Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/Makefile,v retrieving revision 1.526 retrieving revision 1.527 diff -LMakefile -LMakefile -u -p -r1.526 -r1.527 --- Makefile +++ Makefile @@ -96,6 +96,7 @@ SRCS = att.c \ man_validate.c \ mandoc.c \ mandoc_aux.c \ + mandoc_msg.c \ mandoc_ohash.c \ mandoc_xr.c \ mandocd.c \ @@ -237,6 +238,7 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ chars.o \ mandoc.o \ mandoc_aux.o \ + mandoc_msg.o \ mandoc_ohash.o \ mandoc_xr.o \ msec.o \ Index: st.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/st.c,v retrieving revision 1.15 retrieving revision 1.16 diff -Lst.c -Lst.c -u -p -r1.15 -r1.16 --- st.c +++ st.c @@ -17,6 +17,8 @@ #include "config.h" #include + +#include #include #include "mandoc.h" Index: mandocd.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandocd.c,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmandocd.c -Lmandocd.c -u -p -r1.7 -r1.8 --- mandocd.c +++ mandocd.c @@ -172,7 +172,7 @@ main(int argc, char *argv[]) mchars_alloc(); parser = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1, - MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, defos); + MANDOC_OS_OTHER, defos); memset(&options, 0, sizeof(options)); switch (outtype) { Index: tbl_data.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/tbl_data.c,v retrieving revision 1.49 retrieving revision 1.50 diff -Ltbl_data.c -Ltbl_data.c -u -p -r1.49 -r1.50 --- tbl_data.c +++ tbl_data.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include Index: tbl_layout.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/tbl_layout.c,v retrieving revision 1.46 retrieving revision 1.47 diff -Ltbl_layout.c -Ltbl_layout.c -u -p -r1.46 -r1.47 --- tbl_layout.c +++ tbl_layout.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include Index: read.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/read.c,v retrieving revision 1.202 retrieving revision 1.203 diff -Lread.c -Lread.c -u -p -r1.202 -r1.203 --- read.c +++ read.c @@ -48,14 +48,10 @@ struct mparse { 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 */ struct buf *secondary; /* copy of top level input */ struct buf *loop; /* open .while request line */ const char *os_s; /* default operating system */ - mandocmsg mmsg; /* warning/error message handler */ - enum mandoclevel file_status; /* status of current parse */ - enum mandocerr mmin; /* ignore messages below this */ int options; /* parser options */ int gzip; /* current input file is gzipped */ int filenc; /* encoding of the current file */ @@ -67,229 +63,11 @@ static void choose_parser(struct mpars static void free_buf_list(struct buf *); static void resize_buf(struct buf *, size_t); 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 int read_whole_file(struct mparse *, int, struct buf *, int *); static void mparse_end(struct mparse *); static void mparse_parse_buffer(struct mparse *, struct buf, const char *); -static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = { - MANDOCERR_OK, - MANDOCERR_OK, - MANDOCERR_WARNING, - MANDOCERR_ERROR, - MANDOCERR_UNSUPP, - MANDOCERR_MAX, - MANDOCERR_MAX -}; - -static const char * const mandocerrs[MANDOCERR_MAX] = { - "ok", - - "base system convention", - - "Mdocdate found", - "Mdocdate missing", - "unknown architecture", - "operating system explicitly specified", - "RCS id missing", - "referenced manual not found", - - "generic style suggestion", - - "legacy man(7) date format", - "normalizing date format to", - "lower case character in document title", - "duplicate RCS id", - "possible typo in section name", - "unterminated quoted argument", - "useless macro", - "consider using OS macro", - "errnos out of order", - "duplicate errno", - "trailing delimiter", - "no blank before trailing delimiter", - "fill mode already enabled, skipping", - "fill mode already disabled, skipping", - "verbatim \"--\", maybe consider using \\(em", - "function name without markup", - "whitespace at end of input line", - "bad comment style", - - "generic warning", - - /* related to the prologue */ - "missing manual title, using UNTITLED", - "missing manual title, using \"\"", - "missing manual section, using \"\"", - "unknown manual section", - "missing date, using today's date", - "cannot parse date, using it verbatim", - "date in the future, using it anyway", - "missing Os macro, using \"\"", - "late prologue macro", - "prologue macros out of order", - - /* related to document structure */ - ".so is fragile, better use ln(1)", - "no document body", - "content before first section header", - "first section is not \"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", - "cross reference to self", - "unusual Xr order", - "unusual Xr punctuation", - "AUTHORS section without An macro", - - /* related to macros and nesting */ - "obsolete macro", - "macro neither callable nor escaped", - "skipping paragraph macro", - "moving paragraph macro out of list", - "skipping no-space macro", - "blocks badly nested", - "nested displays are not portable", - "moving content out of list", - "first macro on line", - "line scope broken", - "skipping blank line in line scope", - - /* related to missing macro arguments */ - "skipping empty request", - "conditional request controls empty scope", - "skipping empty macro", - "empty block", - "empty argument, using 0n", - "missing display type, using -ragged", - "list type is not the first argument", - "missing -width in -tag list, using 6n", - "missing utility name, using \"\"", - "missing function name, using \"\"", - "empty head in list item", - "empty list item", - "missing argument, using next line", - "missing font type, using \\fR", - "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 \"\"", - "missing eqn box, using \"\"", - - /* related to bad macro arguments */ - "duplicate argument", - "skipping duplicate argument", - "skipping duplicate display type", - "skipping duplicate list type", - "skipping -width argument", - "wrong number of cells", - "unknown AT&T UNIX version", - "comma in function argument", - "parenthesis in function name", - "unknown library name", - "invalid content in Rs block", - "invalid Boolean argument", - "argument contains two font escapes", - "unknown font, skipping request", - "odd number of characters in request", - - /* related to plain text */ - "blank line in fill mode, using .sp", - "tab in filled text", - "new sentence, new line", - "invalid escape sequence", - "undefined string, using \"\"", - - /* related to tables */ - "tbl line starts with span", - "tbl column starts with span", - "skipping vertical bar in tbl layout", - - "generic error", - - /* related to tables */ - "non-alphabetic character in tbl options", - "skipping unknown tbl option", - "missing tbl option argument", - "wrong tbl option argument size", - "empty tbl layout", - "invalid character in tbl layout", - "unmatched parenthesis in tbl layout", - "tbl without any data cells", - "ignoring data in spanned tbl cell", - "ignoring extra tbl data cells", - "data block open at end of tbl", - - /* related to document structure and macros */ - NULL, - "duplicate prologue macro", - "skipping late title macro", - "input stack limit exceeded, infinite loop?", - "skipping bad character", - "skipping unknown macro", - "ignoring request outside macro", - "skipping insecure request", - "skipping item outside list", - "skipping column outside column list", - "skipping end of block that is not open", - "fewer RS blocks open, skipping", - "inserting missing end of block", - "appending missing end of block", - - /* related to request and macro arguments */ - "escaped character not allowed in a name", - "using macro argument outside macro", - "argument number is not numeric", - "NOT IMPLEMENTED: Bd -file", - "skipping display without arguments", - "missing list type, using -item", - "argument is not numeric, using 1", - "argument is not a character", - "missing manual name, using \"\"", - "uname(3) system call failed, using UNKNOWN", - "unknown standard specifier", - "skipping request without numeric argument", - "excessive shift", - "NOT IMPLEMENTED: .so with absolute path or \"..\"", - ".so request failed", - "skipping all arguments", - "skipping excess arguments", - "divide by zero", - - "unsupported feature", - "input too large", - "unsupported control character", - "unsupported roff request", - "nested .while loops", - "end of scope with open .while loop", - "end of .while loop in inner scope", - "cannot continue this .while loop", - "eqn delim option in tbl", - "unsupported tbl layout modifier", - "ignoring macro in table", -}; - -static const char * const mandoclevels[MANDOCLEVEL_MAX] = { - "SUCCESS", - "STYLE", - "WARNING", - "ERROR", - "UNSUPP", - "BADARG", - "SYSERR" -}; - static void resize_buf(struct buf *buf, size_t initial) @@ -370,7 +148,6 @@ mparse_buf_r(struct mparse *curp, struct { struct buf ln; struct buf *firstln, *lastln, *thisln, *loop; - const char *save_file; char *cp; size_t pos; /* byte number in the ln buffer */ int line_result, result; @@ -593,13 +370,10 @@ rerun: curp->sodest = mandoc_strdup(ln.buf + of); goto out; } - save_file = curp->file; if ((fd = mparse_open(curp, ln.buf + of)) != -1) { mparse_readfd(curp, fd, ln.buf + of); close(fd); - curp->file = save_file; } else { - curp->file = save_file; mandoc_vmsg(MANDOCERR_SO_FAIL, curp, curp->line, pos, ".so %s", ln.buf + of); @@ -648,8 +422,7 @@ out: } static int -read_whole_file(struct mparse *curp, const char *file, int fd, - struct buf *fb, int *with_mmap) +read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap) { struct stat st; gzFile gz; @@ -779,8 +552,8 @@ mparse_parse_buffer(struct mparse *curp, } /* Line number is per-file. */ - svfile = curp->file; - curp->file = file; + svfile = mandoc_msg_getinfilename(); + mandoc_msg_setinfilename(file); svprimary = curp->primary; curp->primary = &blk; curp->line = 1; @@ -802,7 +575,8 @@ mparse_parse_buffer(struct mparse *curp, mparse_end(curp); curp->primary = svprimary; - curp->file = svfile; + if (svfile != NULL) + mandoc_msg_setinfilename(svfile); } enum mandoclevel @@ -815,21 +589,21 @@ mparse_readmem(struct mparse *curp, void blk.sz = len; mparse_parse_buffer(curp, blk, file); - return curp->file_status; + return mandoc_msg_getrc(); } /* * Read the whole file into memory and call the parsers. * Called recursively when an .so request is encountered. */ -enum mandoclevel +void mparse_readfd(struct mparse *curp, int fd, const char *file) { struct buf blk; int with_mmap; int save_filenc; - if (read_whole_file(curp, file, fd, &blk, &with_mmap)) { + if (read_whole_file(curp, fd, &blk, &with_mmap)) { save_filenc = curp->filenc; curp->filenc = curp->options & (MPARSE_UTF8 | MPARSE_LATIN1); @@ -840,7 +614,6 @@ mparse_readfd(struct mparse *curp, int f else free(blk.buf); } - return curp->file_status; } int @@ -849,7 +622,6 @@ mparse_open(struct mparse *curp, const c char *cp; int fd; - curp->file = file; cp = strrchr(file, '.'); curp->gzip = (cp != NULL && ! strcmp(cp + 1, "gz")); @@ -880,16 +652,13 @@ mparse_open(struct mparse *curp, const c } struct mparse * -mparse_alloc(int options, enum mandocerr mmin, mandocmsg mmsg, - enum mandoc_os os_e, const char *os_s) +mparse_alloc(int options, enum mandoc_os os_e, const char *os_s) { struct mparse *curp; curp = mandoc_calloc(1, sizeof(struct mparse)); curp->options = options; - curp->mmin = mmin; - curp->mmsg = mmsg; curp->os_s = os_s; curp->roff = roff_alloc(curp, options); @@ -916,11 +685,8 @@ mparse_reset(struct mparse *curp) roff_man_reset(curp->man); free_buf_list(curp->secondary); curp->secondary = NULL; - free(curp->sodest); curp->sodest = NULL; - - curp->file_status = MANDOCLEVEL_OK; curp->gzip = 0; } @@ -947,60 +713,6 @@ mparse_result(struct mparse *curp, struc } if (man) *man = curp->man; -} - -void -mparse_updaterc(struct mparse *curp, enum mandoclevel *rc) -{ - if (curp->file_status > *rc) - *rc = curp->file_status; -} - -void -mandoc_vmsg(enum mandocerr t, struct mparse *m, - int ln, int pos, const char *fmt, ...) -{ - char buf[256]; - va_list ap; - - va_start(ap, fmt); - (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, - int ln, int col, const char *msg) -{ - enum mandoclevel level; - - if (er < m->mmin && er != MANDOCERR_FILE) - return; - - level = MANDOCLEVEL_UNSUPP; - while (er < mandoclimits[level]) - level--; - - if (m->mmsg) - (*m->mmsg)(er, level, m->file, ln, col, msg); - - if (m->file_status < level) - m->file_status = level; -} - -const char * -mparse_strerror(enum mandocerr er) -{ - - return mandocerrs[er]; -} - -const char * -mparse_strlevel(enum mandoclevel lvl) -{ - return mandoclevels[lvl]; } void Index: main.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/main.c,v retrieving revision 1.311 retrieving revision 1.312 diff -Lmain.c -Lmain.c -u -p -r1.311 -r1.312 --- main.c +++ main.c @@ -82,7 +82,6 @@ struct curparse { void *outdata; /* data for output */ char *os_s; /* operating system for display */ int wstop; /* stop after a file with a warning */ - enum mandocerr mmin; /* ignore messages below this */ enum mandoc_os os_e; /* check base system conventions */ enum outt outtype; /* which output to use */ }; @@ -90,7 +89,7 @@ struct curparse { int mandocdb(int, char *[]); -static void check_xr(const char *); +static void check_xr(void); static int fs_lookup(const struct manpaths *, size_t ipath, const char *, const char *, const char *, @@ -100,8 +99,6 @@ static int fs_search(const struct man struct manpage **, size_t *); static int koptions(int *, char *); static void moptions(int *, char *); -static void mmsg(enum mandocerr, enum mandoclevel, - const char *, int, int, const char *); static void outdata_alloc(struct curparse *); static void parse(struct curparse *, int, const char *); static void passthrough(const char *, int, int); @@ -113,8 +110,6 @@ static int woptions(struct curparse * static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; static char help_arg[] = "help"; static char *help_argv[] = {help_arg, NULL}; -static enum mandoclevel rc; -static FILE *mmsg_stream; int @@ -192,10 +187,8 @@ main(int argc, char *argv[]) memset(&curp, 0, sizeof(struct curparse)); curp.outtype = OUTT_LOCALE; - curp.mmin = MANDOCERR_MAX; curp.outopts = &conf.output; options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; - mmsg_stream = stderr; use_pager = 1; tag_files = NULL; @@ -372,8 +365,6 @@ main(int argc, char *argv[]) #endif } - rc = MANDOCLEVEL_OK; - /* man(1), whatis(1), apropos(1) */ if (search.argmode != ARG_FILE) { @@ -415,7 +406,7 @@ main(int argc, char *argv[]) if (sz == 0) { if (search.argmode != ARG_NAME) warnx("nothing appropriate"); - rc = MANDOCLEVEL_BADARG; + mandoc_msg_setrc(MANDOCLEVEL_BADARG); goto out; } @@ -483,13 +474,15 @@ main(int argc, char *argv[]) moptions(&options, auxpaths); mchars_alloc(); - curp.mp = mparse_alloc(options, curp.mmin, mmsg, - curp.os_e, curp.os_s); + curp.mp = mparse_alloc(options, curp.os_e, curp.os_s); if (argc < 1) { if (use_pager) tag_files = tag_init(); - parse(&curp, STDIN_FILENO, ""); + thisarg = ""; + mandoc_msg_setinfilename(thisarg); + parse(&curp, STDIN_FILENO, thisarg); + mandoc_msg_setinfilename(NULL); } /* @@ -513,9 +506,12 @@ main(int argc, char *argv[]) (void)chdir(conf.manpath.paths[resp->ipath]); else if (startdir != -1) (void)fchdir(startdir); - } + thisarg = resp->file; + } else + thisarg = *argv; - fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); + mandoc_msg_setinfilename(thisarg); + fd = mparse_open(curp.mp, thisarg); if (fd != -1) { if (use_pager) { use_pager = 0; @@ -527,10 +523,8 @@ main(int argc, char *argv[]) conf.output.tag : *argv; } - if (resp == NULL) - parse(&curp, fd, *argv); - else if (resp->form == FORM_SRC) - parse(&curp, fd, resp->file); + if (resp == NULL || resp->form == FORM_SRC) + parse(&curp, fd, thisarg); else passthrough(resp->file, fd, conf.output.synopsisonly); @@ -542,7 +536,7 @@ main(int argc, char *argv[]) tag_files = NULL; } else warn("stdout"); - rc = MANDOCLEVEL_SYSERR; + mandoc_msg_setrc(MANDOCLEVEL_SYSERR); break; } @@ -551,10 +545,10 @@ main(int argc, char *argv[]) outdata_alloc(&curp); terminal_sepline(curp.outdata); } - } else if (rc < MANDOCLEVEL_ERROR) - rc = MANDOCLEVEL_ERROR; + } + mandoc_msg_setinfilename(NULL); - if (MANDOCLEVEL_OK != rc && curp.wstop) + if (curp.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK) break; if (resp != NULL) @@ -645,7 +639,7 @@ out: if (pid == -1) { warn("wait"); - rc = MANDOCLEVEL_SYSERR; + mandoc_msg_setrc(MANDOCLEVEL_SYSERR); break; } if (!WIFSTOPPED(status)) @@ -655,8 +649,7 @@ out: } tag_unlink(); } - - return (int)rc; + return (int)mandoc_msg_getrc(); } static void @@ -806,7 +799,6 @@ fs_search(const struct mansearch *cfg, c static void parse(struct curparse *curp, int fd, const char *file) { - enum mandoclevel rctmp; struct roff_man *man; /* Begin by parsing the file itself. */ @@ -814,18 +806,16 @@ parse(struct curparse *curp, int fd, con assert(file); assert(fd >= 0); - rctmp = mparse_readfd(curp->mp, fd, file); + mparse_readfd(curp->mp, fd, file); if (fd != STDIN_FILENO) close(fd); - if (rc < rctmp) - rc = rctmp; /* * With -Wstop and warnings or errors of at least the requested * level, do not produce output. */ - if (rctmp != MANDOCLEVEL_OK && curp->wstop) + if (curp->wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK) return; if (curp->outdata == NULL) @@ -889,13 +879,12 @@ parse(struct curparse *curp, int fd, con break; } } - if (curp->mmin < MANDOCERR_STYLE) - check_xr(file); - mparse_updaterc(curp->mp, &rc); + if (mandoc_msg_getmin() < MANDOCERR_STYLE) + check_xr(); } static void -check_xr(const char *file) +check_xr(void) { static struct manpaths paths; struct mansearch search; @@ -923,8 +912,7 @@ check_xr(const char *file) else mandoc_asprintf(&cp, "Xr %s %s (%d times)", xr->name, xr->sec, xr->count); - mmsg(MANDOCERR_XR_BAD, MANDOCLEVEL_STYLE, - file, xr->line, xr->pos + 1, cp); + mandoc_msg(MANDOCERR_XR_BAD, NULL, xr->line, xr->pos + 1, cp); free(cp); } } @@ -1024,8 +1012,7 @@ done: fail: free(line); warn("%s: SYSERR: %s", file, syscall); - if (rc < MANDOCLEVEL_SYSERR) - rc = MANDOCLEVEL_SYSERR; + mandoc_msg_setrc(MANDOCLEVEL_SYSERR); } static int @@ -1067,8 +1054,8 @@ toptions(struct curparse *curp, char *ar curp->outtype = OUTT_ASCII; else if (0 == strcmp(arg, "lint")) { curp->outtype = OUTT_LINT; - curp->mmin = MANDOCERR_BASE; - mmsg_stream = stdout; + mandoc_msg_setoutfile(stdout); + mandoc_msg_setmin(MANDOCERR_BASE); } else if (0 == strcmp(arg, "tree")) curp->outtype = OUTT_TREE; else if (0 == strcmp(arg, "man")) @@ -1119,29 +1106,29 @@ woptions(struct curparse *curp, char *ar break; case 1: case 2: - curp->mmin = MANDOCERR_BASE; + mandoc_msg_setmin(MANDOCERR_BASE); break; case 3: - curp->mmin = MANDOCERR_STYLE; + mandoc_msg_setmin(MANDOCERR_STYLE); break; case 4: - curp->mmin = MANDOCERR_WARNING; + mandoc_msg_setmin(MANDOCERR_WARNING); break; case 5: - curp->mmin = MANDOCERR_ERROR; + mandoc_msg_setmin(MANDOCERR_ERROR); break; case 6: - curp->mmin = MANDOCERR_UNSUPP; + mandoc_msg_setmin(MANDOCERR_UNSUPP); break; case 7: - curp->mmin = MANDOCERR_MAX; + mandoc_msg_setmin(MANDOCERR_MAX); break; case 8: - curp->mmin = MANDOCERR_BASE; + mandoc_msg_setmin(MANDOCERR_BASE); curp->os_e = MANDOC_OS_OPENBSD; break; case 9: - curp->mmin = MANDOCERR_BASE; + mandoc_msg_setmin(MANDOCERR_BASE); curp->os_e = MANDOC_OS_NETBSD; break; default: @@ -1150,29 +1137,6 @@ woptions(struct curparse *curp, char *ar } } return 1; -} - -static void -mmsg(enum mandocerr t, enum mandoclevel lvl, - const char *file, int line, int col, const char *msg) -{ - const char *mparse_msg; - - fprintf(mmsg_stream, "%s: %s:", getprogname(), - file == NULL ? "" : file); - - if (line) - fprintf(mmsg_stream, "%d:%d:", line, col + 1); - - fprintf(mmsg_stream, " %s", mparse_strlevel(lvl)); - - if ((mparse_msg = mparse_strerror(t)) != NULL) - fprintf(mmsg_stream, ": %s", mparse_msg); - - if (msg) - fprintf(mmsg_stream, ": %s", msg); - - fputc('\n', mmsg_stream); } static pid_t Index: man_macro.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_macro.c,v retrieving revision 1.133 retrieving revision 1.134 diff -Lman_macro.c -Lman_macro.c -u -p -r1.133 -r1.134 --- man_macro.c +++ man_macro.c @@ -22,6 +22,7 @@ #include #include +#include #include #include Index: mandocdb.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandocdb.c,v retrieving revision 1.260 retrieving revision 1.261 diff -Lmandocdb.c -Lmandocdb.c -u -p -r1.260 -r1.261 --- mandocdb.c +++ mandocdb.c @@ -422,8 +422,7 @@ mandocdb(int argc, char *argv[]) exitcode = (int)MANDOCLEVEL_OK; mchars_alloc(); - mp = mparse_alloc(mparse_options, MANDOCERR_MAX, NULL, - MANDOC_OS_OTHER, NULL); + mp = mparse_alloc(mparse_options, MANDOC_OS_OTHER, NULL); mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev)); mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file)); Index: msec.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/msec.c,v retrieving revision 1.15 retrieving revision 1.16 diff -Lmsec.c -Lmsec.c -u -p -r1.15 -r1.16 --- msec.c +++ msec.c @@ -18,6 +18,7 @@ #include +#include #include #include "mandoc.h" Index: mandoc.3 =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc.3,v retrieving revision 1.42 retrieving revision 1.43 diff -Lmandoc.3 -Lmandoc.3 -u -p -r1.42 -r1.43 --- mandoc.3 +++ mandoc.3 @@ -21,7 +21,6 @@ .Sh NAME .Nm mandoc , .Nm deroff , -.Nm mandocmsg , .Nm man_validate , .Nm mdoc_validate , .Nm mparse_alloc , @@ -30,13 +29,11 @@ .Nm mparse_open , .Nm mparse_readfd , .Nm mparse_reset , -.Nm mparse_result , -.Nm mparse_strerror , -.Nm mparse_strlevel , -.Nm mparse_updaterc +.Nm mparse_result .Nd mandoc macro compiler library .Sh SYNOPSIS .In sys/types.h +.In stdio.h .In mandoc.h .Pp .Fd "#define ASCII_NBRSP" @@ -45,21 +42,10 @@ .Ft struct mparse * .Fo mparse_alloc .Fa "int options" -.Fa "enum mandocerr mmin" -.Fa "mandocmsg mmsg" .Fa "enum mandoc_os oe_e" .Fa "char *os_s" .Fc .Ft void -.Fo (*mandocmsg) -.Fa "enum mandocerr errtype" -.Fa "enum mandoclevel level" -.Fa "const char *file" -.Fa "int line" -.Fa "int col" -.Fa "const char *msg" -.Fc -.Ft void .Fo mparse_free .Fa "struct mparse *parse" .Fc @@ -72,7 +58,7 @@ .Fa "struct mparse *parse" .Fa "const char *fname" .Fc -.Ft "enum mandoclevel" +.Ft void .Fo mparse_readfd .Fa "struct mparse *parse" .Fa "int fd" @@ -88,19 +74,6 @@ .Fa "struct roff_man **man" .Fa "char **sodest" .Fc -.Ft "const char *" -.Fo mparse_strerror -.Fa "enum mandocerr" -.Fc -.Ft "const char *" -.Fo mparse_strlevel -.Fa "enum mandoclevel" -.Fc -.Ft void -.Fo mparse_updaterc -.Fa "struct mparse *parse" -.Fa "enum mandoclevel *rc" -.Fc .In roff.h .Ft void .Fo deroff @@ -222,9 +195,6 @@ and freed with This may be used across parsed input if .Fn mparse_reset is called between parses. -.It Vt "mandocmsg" -A prototype for a function to handle error and warning -messages emitted by the parser. .El .Ss Functions .Bl -ohang @@ -289,24 +259,6 @@ This is for example useful in .Xr makewhatis 8 .Fl Q to quickly build minimal databases. -.It Ar mmin -Can be set to -.Dv MANDOCERR_BASE , -.Dv MANDOCERR_STYLE , -.Dv MANDOCERR_WARNING , -.Dv MANDOCERR_ERROR , -.Dv MANDOCERR_UNSUPP , -or -.Dv MANDOCERR_MAX . -Messages below the selected level will be suppressed. -.It Ar mmsg -A callback function to handle errors and warnings. -See -.Pa main.c -for an example. -If printing of error messages is not desired, -.Dv NULL -may be passed. .It Ar os_e Operating system to check base system conventions for. If @@ -396,34 +348,6 @@ implemented in .It Fn mparse_result Obtain the result of a parse. One of the two pointers will be filled in. -Declared in -.In mandoc.h , -implemented in -.Pa read.c . -.It Fn mparse_strerror -Return a statically-allocated string representation of an error code. -Declared in -.In mandoc.h , -implemented in -.Pa read.c . -.It Fn mparse_strlevel -Return a statically-allocated string representation of a level code. -Declared in -.In mandoc.h , -implemented in -.Pa read.c . -.It Fn mparse_updaterc -If the highest warning or error level that occurred during the current -.Fa parse -is higher than -.Pf * Fa rc , -update -.Pf * Fa rc -accordingly. -This is useful after calling -.Fn mdoc_validate -or -.Fn man_validate . Declared in .In mandoc.h , implemented in Index: demandoc.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/demandoc.c,v retrieving revision 1.30 retrieving revision 1.31 diff -Ldemandoc.c -Ldemandoc.c -u -p -r1.30 -r1.31 --- demandoc.c +++ demandoc.c @@ -79,8 +79,7 @@ main(int argc, char *argv[]) argv += optind; mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCERR_MAX, NULL, - MANDOC_OS_OTHER, NULL); + mp = mparse_alloc(MPARSE_SO, MANDOC_OS_OTHER, NULL); assert(mp); if (argc < 1) Index: roff_term.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff_term.c,v retrieving revision 1.15 retrieving revision 1.16 diff -Lroff_term.c -Lroff_term.c -u -p -r1.15 -r1.16 --- roff_term.c +++ roff_term.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include "mandoc.h" #include "roff.h" Index: Makefile.depend =================================================================== RCS file: /home/cvs/mandoc/mandoc/Makefile.depend,v retrieving revision 1.38 retrieving revision 1.39 diff -LMakefile.depend -LMakefile.depend -u -p -r1.38 -r1.39 --- Makefile.depend +++ Makefile.depend @@ -40,6 +40,7 @@ man_term.o: man_term.c config.h mandoc_a man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h +mandoc_msg.o: mandoc_msg.c mandoc.h mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h main.h manconf.h Index: mandoc_headers.3 =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc_headers.3,v retrieving revision 1.26 retrieving revision 1.27 diff -Lmandoc_headers.3 -Lmandoc_headers.3 -u -p -r1.26 -r1.27 --- mandoc_headers.3 +++ mandoc_headers.3 @@ -90,18 +90,23 @@ can be used everywhere. Requires .In sys/types.h for -.Vt size_t . +.Vt size_t +and +.In stdio.h +for +.Vt FILE . .Pp Provides .Vt enum mandoc_esc , .Vt enum mandocerr , .Vt enum mandoclevel , -the function prototype typedef -.Fn mandocmsg , the function .Xr mandoc_escape 3 , -and the functions described in -.Xr mchars_alloc 3 . +the functions described in +.Xr mchars_alloc 3 , +and the +.Fn mandoc_msg* +functions. .It Qq Pa roff.h Common data types for all syntax trees and related functions; can be used everywhere. Index: cgi.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/cgi.c,v retrieving revision 1.162 retrieving revision 1.163 diff -Lcgi.c -Lcgi.c -u -p -r1.162 -r1.163 --- cgi.c +++ cgi.c @@ -861,7 +861,7 @@ resp_format(const struct req *req, const mchars_alloc(); mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1, - MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, req->q.manpath); + MANDOC_OS_OTHER, req->q.manpath); mparse_readfd(mp, fd, file); close(fd); Index: roff_validate.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff_validate.c,v retrieving revision 1.12 retrieving revision 1.13 diff -Lroff_validate.c -Lroff_validate.c -u -p -r1.12 -r1.13 --- roff_validate.c +++ roff_validate.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include "mandoc.h" --- /dev/null +++ mandoc_msg.c @@ -0,0 +1,335 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include + +#include "mandoc.h" + +static const enum mandocerr lowest_type[MANDOCLEVEL_MAX] = { + MANDOCERR_OK, + MANDOCERR_OK, + MANDOCERR_WARNING, + MANDOCERR_ERROR, + MANDOCERR_UNSUPP, + MANDOCERR_MAX, + MANDOCERR_MAX +}; + +static const char *const level_name[MANDOCLEVEL_MAX] = { + "SUCCESS", + "STYLE", + "WARNING", + "ERROR", + "UNSUPP", + "BADARG", + "SYSERR" +}; + +static const char *const type_message[MANDOCERR_MAX] = { + "ok", + + "base system convention", + + "Mdocdate found", + "Mdocdate missing", + "unknown architecture", + "operating system explicitly specified", + "RCS id missing", + "referenced manual not found", + + "generic style suggestion", + + "legacy man(7) date format", + "normalizing date format to", + "lower case character in document title", + "duplicate RCS id", + "possible typo in section name", + "unterminated quoted argument", + "useless macro", + "consider using OS macro", + "errnos out of order", + "duplicate errno", + "trailing delimiter", + "no blank before trailing delimiter", + "fill mode already enabled, skipping", + "fill mode already disabled, skipping", + "verbatim \"--\", maybe consider using \\(em", + "function name without markup", + "whitespace at end of input line", + "bad comment style", + + "generic warning", + + /* related to the prologue */ + "missing manual title, using UNTITLED", + "missing manual title, using \"\"", + "missing manual section, using \"\"", + "unknown manual section", + "missing date, using today's date", + "cannot parse date, using it verbatim", + "date in the future, using it anyway", + "missing Os macro, using \"\"", + "late prologue macro", + "prologue macros out of order", + + /* related to document structure */ + ".so is fragile, better use ln(1)", + "no document body", + "content before first section header", + "first section is not \"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", + "cross reference to self", + "unusual Xr order", + "unusual Xr punctuation", + "AUTHORS section without An macro", + + /* related to macros and nesting */ + "obsolete macro", + "macro neither callable nor escaped", + "skipping paragraph macro", + "moving paragraph macro out of list", + "skipping no-space macro", + "blocks badly nested", + "nested displays are not portable", + "moving content out of list", + "first macro on line", + "line scope broken", + "skipping blank line in line scope", + + /* related to missing macro arguments */ + "skipping empty request", + "conditional request controls empty scope", + "skipping empty macro", + "empty block", + "empty argument, using 0n", + "missing display type, using -ragged", + "list type is not the first argument", + "missing -width in -tag list, using 6n", + "missing utility name, using \"\"", + "missing function name, using \"\"", + "empty head in list item", + "empty list item", + "missing argument, using next line", + "missing font type, using \\fR", + "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 \"\"", + "missing eqn box, using \"\"", + + /* related to bad macro arguments */ + "duplicate argument", + "skipping duplicate argument", + "skipping duplicate display type", + "skipping duplicate list type", + "skipping -width argument", + "wrong number of cells", + "unknown AT&T UNIX version", + "comma in function argument", + "parenthesis in function name", + "unknown library name", + "invalid content in Rs block", + "invalid Boolean argument", + "argument contains two font escapes", + "unknown font, skipping request", + "odd number of characters in request", + + /* related to plain text */ + "blank line in fill mode, using .sp", + "tab in filled text", + "new sentence, new line", + "invalid escape sequence", + "undefined string, using \"\"", + + /* related to tables */ + "tbl line starts with span", + "tbl column starts with span", + "skipping vertical bar in tbl layout", + + "generic error", + + /* related to tables */ + "non-alphabetic character in tbl options", + "skipping unknown tbl option", + "missing tbl option argument", + "wrong tbl option argument size", + "empty tbl layout", + "invalid character in tbl layout", + "unmatched parenthesis in tbl layout", + "tbl without any data cells", + "ignoring data in spanned tbl cell", + "ignoring extra tbl data cells", + "data block open at end of tbl", + + /* related to document structure and macros */ + NULL, + "duplicate prologue macro", + "skipping late title macro", + "input stack limit exceeded, infinite loop?", + "skipping bad character", + "skipping unknown macro", + "ignoring request outside macro", + "skipping insecure request", + "skipping item outside list", + "skipping column outside column list", + "skipping end of block that is not open", + "fewer RS blocks open, skipping", + "inserting missing end of block", + "appending missing end of block", + + /* related to request and macro arguments */ + "escaped character not allowed in a name", + "using macro argument outside macro", + "argument number is not numeric", + "NOT IMPLEMENTED: Bd -file", + "skipping display without arguments", + "missing list type, using -item", + "argument is not numeric, using 1", + "argument is not a character", + "missing manual name, using \"\"", + "uname(3) system call failed, using UNKNOWN", + "unknown standard specifier", + "skipping request without numeric argument", + "excessive shift", + "NOT IMPLEMENTED: .so with absolute path or \"..\"", + ".so request failed", + "skipping all arguments", + "skipping excess arguments", + "divide by zero", + + "unsupported feature", + "input too large", + "unsupported control character", + "unsupported roff request", + "nested .while loops", + "end of scope with open .while loop", + "end of .while loop in inner scope", + "cannot continue this .while loop", + "eqn delim option in tbl", + "unsupported tbl layout modifier", + "ignoring macro in table", +}; + +static FILE *fileptr = stderr; +static const char *filename = NULL; +static enum mandocerr min_type = MANDOCERR_MAX; +static enum mandoclevel rc = MANDOCLEVEL_OK; + + +void +mandoc_msg_setoutfile(FILE *fp) +{ + fileptr = fp; +} + +const char * +mandoc_msg_getinfilename(void) +{ + return filename; +} + +void +mandoc_msg_setinfilename(const char *fn) +{ + filename = fn; +} + +enum mandocerr +mandoc_msg_getmin(void) +{ + return min_type; +} + +void +mandoc_msg_setmin(enum mandocerr t) +{ + min_type = t; +} + +enum mandoclevel +mandoc_msg_getrc(void) +{ + return rc; +} + +void +mandoc_msg_setrc(enum mandoclevel level) +{ + if (rc < level) + rc = level; +} + +void +mandoc_vmsg(enum mandocerr t, void *dummy, int line, int col, + const char *fmt, ...) +{ + va_list ap; + enum mandoclevel level; + + if (t < min_type && t != MANDOCERR_FILE) + return; + + level = MANDOCLEVEL_UNSUPP; + while (t < lowest_type[level]) + level--; + mandoc_msg_setrc(level); + + if (fileptr == NULL) + return; + + fprintf(fileptr, "%s:", getprogname()); + if (filename != NULL) + fprintf(fileptr, " %s:", filename); + + if (line > 0) + fprintf(fileptr, "%d:%d:", line, col + 1); + + fprintf(fileptr, " %s", level_name[level]); + if (type_message[t] != NULL) + fprintf(fileptr, ": %s", type_message[t]); + + if (fmt != NULL) { + fprintf(fileptr, ": "); + va_start(ap, fmt); + vfprintf(fileptr, fmt, ap); + va_end(ap); + } + fputc('\n', fileptr); +} + +void +mandoc_msg(enum mandocerr t, void *dummy, int line, int col, const char *msg) +{ + if (msg == NULL) + mandoc_vmsg(t, dummy, line, col, NULL); + else + mandoc_vmsg(t, dummy, line, col, "%s", msg); +} Index: mandoc.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc.h,v retrieving revision 1.258 retrieving revision 1.259 diff -Lmandoc.h -Lmandoc.h -u -p -r1.258 -r1.259 --- mandoc.h +++ mandoc.h @@ -265,11 +265,19 @@ enum mandoc_esc { ESCAPE_OVERSTRIKE /* overstrike all chars in the argument */ }; -typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel, - const char *, int, int, const char *); - enum mandoc_esc mandoc_escape(const char **, const char **, int *); +void mandoc_msg_setoutfile(FILE *); +const char *mandoc_msg_getinfilename(void); +void mandoc_msg_setinfilename(const char *); +enum mandocerr mandoc_msg_getmin(void); +void mandoc_msg_setmin(enum mandocerr); +enum mandoclevel mandoc_msg_getrc(void); +void mandoc_msg_setrc(enum mandoclevel); +void mandoc_msg(enum mandocerr, void *, int, int, const char *); +void mandoc_vmsg(enum mandocerr, void *, int, int, + const char *, ...) + __attribute__((__format__ (__printf__, 5, 6))); void mchars_alloc(void); void mchars_free(void); int mchars_num2char(const char *, size_t); Index: chars.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/chars.c,v retrieving revision 1.76 retrieving revision 1.77 diff -Lchars.c -Lchars.c -u -p -r1.76 -r1.77 --- chars.c +++ chars.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include Index: mandoc_parse.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc_parse.h,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmandoc_parse.h -Lmandoc_parse.h -u -p -r1.1 -r1.2 --- mandoc_parse.h +++ mandoc_parse.h @@ -33,17 +33,13 @@ struct mparse; struct roff_man; -struct mparse *mparse_alloc(int, enum mandocerr, mandocmsg, - enum mandoc_os, const char *); +struct mparse *mparse_alloc(int, enum mandoc_os, const char *); void mparse_copy(const struct mparse *); void mparse_free(struct mparse *); int mparse_open(struct mparse *, const char *); -enum mandoclevel mparse_readfd(struct mparse *, int, const char *); +void mparse_readfd(struct mparse *, int, const char *); enum mandoclevel mparse_readmem(struct mparse *, void *, size_t, const char *); void mparse_reset(struct mparse *); void mparse_result(struct mparse *, struct roff_man **, char **); -const char *mparse_strerror(enum mandocerr); -const char *mparse_strlevel(enum mandoclevel); -void mparse_updaterc(struct mparse *, enum mandoclevel *); Index: libmandoc.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/libmandoc.h,v retrieving revision 1.74 retrieving revision 1.75 diff -Llibmandoc.h -Llibmandoc.h -u -p -r1.74 -r1.75 --- libmandoc.h +++ libmandoc.h @@ -49,11 +49,6 @@ struct mparse; struct roff; struct roff_man; -void mandoc_msg(enum mandocerr, struct mparse *, - int, int, const char *); -void mandoc_vmsg(enum mandocerr, struct mparse *, - int, int, const char *, ...) - __attribute__((__format__ (__printf__, 5, 6))); char *mandoc_getarg(struct mparse *, char **, int, int *); char *mandoc_normdate(struct roff_man *, char *, int, int); int mandoc_eos(const char *, size_t); Index: mdoc_state.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mdoc_state.c,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmdoc_state.c -Lmdoc_state.c -u -p -r1.10 -r1.11 --- mdoc_state.c +++ mdoc_state.c @@ -17,6 +17,7 @@ #include #include +#include #include #include Index: man_validate.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_validate.c,v retrieving revision 1.139 retrieving revision 1.140 diff -Lman_validate.c -Lman_validate.c -u -p -r1.139 -r1.140 --- man_validate.c +++ man_validate.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv