source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mandoc: Major cleanup; may imply minor changes in edge cases of error
@ 2018-12-14  1:18 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2018-12-14  1:18 UTC (permalink / raw)
  To: source

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 <sys/types.h>
+
+#include <stdio.h>
 #include <string.h>
 
 #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 <assert.h>
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
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 <ctype.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
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, "<stdin>");
+		thisarg = "<stdin>";
+		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 ? "<stdin>" : 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 <assert.h>
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
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 <sys/types.h>
 
+#include <stdio.h>
 #include <string.h>
 
 #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 <sys/types.h>
 
 #include <assert.h>
-#include <stddef.h>
+#include <stdio.h>
 
 #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 <sys/types.h>
 
 #include <assert.h>
-#include <stddef.h>
+#include <stdio.h>
 #include <string.h>
 
 #include "mandoc.h"
--- /dev/null
+++ mandoc_msg.c
@@ -0,0 +1,335 @@
+/*	$OpenBSD$ */
+/*
+ * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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 <ctype.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
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 <sys/types.h>
 
 #include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
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 <errno.h>
 #include <limits.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
--
 To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-12-14  1:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-14  1:18 mandoc: Major cleanup; may imply minor changes in edge cases of error schwarze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).