source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Enable the unified error/warning enumeration in mandoc.h that's
@ 2010-05-17 22:11 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-05-17 22:11 UTC (permalink / raw)
  To: source

Log Message:
-----------
Enable the unified error/warning enumeration in mandoc.h that's
stringified in main.c.

Allow `An' to handle an argument and child (with a warning).

Allow `Rv' and `Ex' to work without a prior `Nm' as groff does (with a
warning).

Allow inconsistent column syntax to only raise a warning.

Modified Files:
--------------
    mdocml:
        arch.c
        att.c
        lib.c
        libman.h
        libmdoc.h
        main.c
        man.c
        man.h
        man_action.c
        man_argv.c
        man_hash.c
        man_html.c
        man_macro.c
        man_term.c
        man_validate.c
        mandoc.h
        mdoc.c
        mdoc.h
        mdoc_action.c
        mdoc_argv.c
        mdoc_hash.c
        mdoc_html.c
        mdoc_macro.c
        mdoc_strings.c
        mdoc_term.c
        mdoc_validate.c
        msec.c
        st.c
        term.c
        tree.c
        vol.c

Revision Data
-------------
Index: mdoc_hash.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_hash.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -Lmdoc_hash.c -Lmdoc_hash.c -u -p -r1.14 -r1.15
--- mdoc_hash.c
+++ mdoc_hash.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 static	u_char		 table[27 * 12];
Index: arch.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/arch.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Larch.c -Larch.c -u -p -r1.6 -r1.7
--- arch.c
+++ arch.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: mdoc_action.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_action.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -Lmdoc_action.c -Lmdoc_action.c -u -p -r1.58 -r1.59
--- mdoc_action.c
+++ mdoc_action.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
@@ -269,12 +270,21 @@ concat(struct mdoc *m, char *p, const st
 	p[0] = '\0';
 	for ( ; n; n = n->next) {
 		assert(MDOC_TEXT == n->type);
-		if (strlcat(p, n->string, sz) >= sz)
-			return(mdoc_nerr(m, n, ETOOLONG));
+		/*
+		 * XXX: yes, these can technically be resized, but it's
+		 * highly unlikely that we're going to get here, so let
+		 * it slip for now.
+		 */
+		if (strlcat(p, n->string, sz) >= sz) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
 		if (NULL == n->next)
 			continue;
-		if (strlcat(p, " ", sz) >= sz)
-			return(mdoc_nerr(m, n, ETOOLONG));
+		if (strlcat(p, " ", sz) >= sz) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
 	}
 
 	return(1);
@@ -288,14 +298,16 @@ concat(struct mdoc *m, char *p, const st
 static int
 post_std(POST_ARGS)
 {
-	struct mdoc_node	*nn;
+	struct mdoc_node *nn;
 
 	if (n->child)
 		return(1);
+	if (NULL == m->meta.name)
+		return(1);
 	
 	nn = n;
 	m->next = MDOC_NEXT_CHILD;
-	assert(m->meta.name);
+
 	if ( ! mdoc_word_alloc(m, n->line, n->pos, m->meta.name))
 		return(0);
 	m->last = nn;
@@ -453,7 +465,7 @@ post_sh(POST_ARGS)
 			break;
 		if (*m->meta.msec == '9')
 			break;
-		return(mdoc_nwarn(m, n, EWRONGMSEC));
+		return(mdoc_nmsg(m, n, MANDOCERR_SECMSEC));
 	default:
 		break;
 	}
@@ -517,7 +529,7 @@ post_dt(POST_ARGS)
 	if (cp) {
 		m->meta.vol = mandoc_strdup(cp);
 		m->meta.msec = mandoc_strdup(nn->string);
-	} else if (mdoc_nwarn(m, n, EBADMSEC)) {
+	} else if (mdoc_nmsg(m, n, MANDOCERR_BADMSEC)) {
 		m->meta.vol = mandoc_strdup(nn->string);
 		m->meta.msec = mandoc_strdup(nn->string);
 	} else
@@ -574,19 +586,32 @@ post_os(POST_ARGS)
 	if ( ! concat(m, buf, n->child, BUFSIZ))
 		return(0);
 
+	/* XXX: yes, these can all be dynamically-adjusted buffers, but
+	 * it's really not worth the extra hackery.
+	 */
+
 	if ('\0' == buf[0]) {
 #ifdef OSNAME
-		if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ)
-			return(mdoc_nerr(m, n, EUTSNAME));
+		if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
 #else /*!OSNAME */
 		if (-1 == uname(&utsname))
-			return(mdoc_nerr(m, n, EUTSNAME));
-		if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ)
-			return(mdoc_nerr(m, n, ETOOLONG));
-		if (strlcat(buf, " ", 64) >= BUFSIZ)
-			return(mdoc_nerr(m, n, ETOOLONG));
-		if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ)
-			return(mdoc_nerr(m, n, ETOOLONG));
+			return(mdoc_nmsg(m, n, MANDOCERR_UTSNAME));
+
+		if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
+		if (strlcat(buf, " ", 64) >= BUFSIZ) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
+		if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) {
+			mdoc_nmsg(m, n, MANDOCERR_MEM);
+			return(0);
+		}
 #endif /*!OSNAME*/
 	}
 
@@ -621,7 +646,7 @@ post_bl_tagwidth(POST_ARGS)
 		if (MDOC_TEXT != nn->type) {
 			sz = mdoc_macro2len(nn->tok);
 			if (sz == 0) {
-				if ( ! mdoc_nwarn(m, n, ENOWIDTH))
+				if ( ! mdoc_nmsg(m, n, MANDOCERR_NOWIDTHARG))
 					return(0);
 				sz = 10;
 			}
@@ -684,12 +709,11 @@ post_bl_width(POST_ARGS)
 	 */
 
 	if (0 == strcmp(p, "Ds"))
-		/* XXX: make into a macro. */
 		width = 6;
 	else if (MDOC_MAX == (tok = mdoc_hash_find(p)))
 		return(1);
 	else if (0 == (width = mdoc_macro2len(tok))) 
-		return(mdoc_nwarn(m, n, ENOWIDTH));
+		return(mdoc_nmsg(m, n, MANDOCERR_BADWIDTH));
 
 	/* The value already exists: free and reallocate it. */
 
@@ -848,7 +872,7 @@ post_dd(POST_ARGS)
 		(MTIME_MDOCDATE | MTIME_CANONICAL, buf);
 
 	if (0 == m->meta.date) {
-		if ( ! mdoc_nwarn(m, n, EBADDATE))
+		if ( ! mdoc_nmsg(m, n, MANDOCERR_BADDATE))
 			return(0);
 		m->meta.date = time(NULL);
 	}
Index: mandoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -Lmandoc.h -Lmandoc.h -u -p -r1.4 -r1.5
--- mandoc.h
+++ mandoc.h
@@ -21,14 +21,76 @@ __BEGIN_DECLS
 
 enum	mandocerr {
 	MANDOCERR_OK,
+	MANDOCERR_UPPERCASE, /* text should be uppercase */
+	MANDOCERR_SECOOO, /* sections out of conentional order */
+	MANDOCERR_SECREP, /* section name repeats */
+	MANDOCERR_PROLOGOOO, /* out of order prologue */
+	MANDOCERR_PROLOGREP, /* repeated prologue entry */
+	MANDOCERR_LISTFIRST, /* list type must come first */
+	MANDOCERR_COLUMNS, /* column syntax is inconsistent */
+	MANDOCERR_BADSTANDARD, /* bad standard */
+	MANDOCERR_BADLIB, /* bad library */
+	MANDOCERR_BADESCAPE, /* bad escape sequence */
+	MANDOCERR_BADQUOTE, /* unterminated quoted string */
+	MANDOCERR_NOWIDTHARG, /* argument requires the width argument */
+	MANDOCERR_WIDTHARG, /* superfluous width argument */
+	MANDOCERR_BADDATE, /* bad date argument */
+	MANDOCERR_BADWIDTH, /* bad width argument */
+	MANDOCERR_BADMSEC, /* unknown manual sction */
+	MANDOCERR_SECMSEC, /* section not in conventional manual section */
+	MANDOCERR_EOLNSPACE, /* end of line whitespace */
 	MANDOCERR_SCOPEEXIT, /* scope open on exit */
 #define	MANDOCERR_WARNING	MANDOCERR_SCOPEEXIT
 
+	MANDOCERR_NAMESECFIRST, /* NAME section must come first */
+	MANDOCERR_BADBOOL, /* bad Boolean value */
+	MANDOCERR_CHILD, /* child violates parent syntax */
+	MANDOCERR_BADATT, /* bad AT&T symbol */
+	MANDOCERR_LISTREP, /* list type repeated */
+	MANDOCERR_DISPREP, /* display type repeated */
+	MANDOCERR_ARGVREP, /* argument repeated */
+	MANDOCERR_NONAME, /* manual name not yet set */
+	MANDOCERR_MACROOBS, /* obsolete macro ignored */
+	MANDOCERR_MACROEMPTY, /* empty macro ignored */
+	MANDOCERR_BADBODY, /* macro not allowed in body */
+	MANDOCERR_BADPROLOG, /* macro not allowed in prologue */
+	MANDOCERR_BADCHAR, /* bad character */
+	MANDOCERR_BADNAMESEC, /* bad NAME section contents */
+	MANDOCERR_NOBLANKLN, /* no blank lines */
+	MANDOCERR_NOTEXT, /* no text in this context */
+	MANDOCERR_BADCOMMENT, /* bad comment style */
+	MANDOCERR_MACRO, /* unknown macro will be lost */
+	MANDOCERR_LINESCOPE, /* line scope broken */
+	MANDOCERR_SCOPE, /* scope broken */
+	MANDOCERR_ARGCOUNT, /* argument count wrong */
 	MANDOCERR_NOSCOPE, /* request scope close w/none open */
-	MANDOCERR_NOARGS, /* macro requires argument(s) */
-	MANDOCERR_ARGSLOST, /* line arguments will be lost */
+	MANDOCERR_SCOPEREP, /* scope already open */
+	/* FIXME: merge following with MANDOCERR_ARGCOUNT */
+	MANDOCERR_NOARGS, /* macro requires line argument(s) */
+	MANDOCERR_NOBODY, /* macro requires body argument(s) */
+	MANDOCERR_NOARGV, /* macro requires argument(s) */
+	MANDOCERR_NOTITLE, /* no title in document */
+	MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
+	MANDOCERR_BODYLOST, /* body argument(s) will be lost */
 #define	MANDOCERR_ERROR		MANDOCERR_ARGSLOST
 
+	/* FIXME: this should be a MANDOCERR_ERROR */
+	MANDOCERR_FONTTYPE, /* missing font type */
+	/* FIXME: this should be a MANDOCERR_ERROR */
+	MANDOCERR_DISPTYPE, /* missing display type */
+	/* FIXME: this should be a MANDOCERR_ERROR */
+	MANDOCERR_LISTTYPE, /* missing list type */
+	/* FIXME: this should be a MANDOCERR_ERROR */
+	MANDOCERR_NESTEDDISP, /* displays may not be nested */
+	MANDOCERR_SYNTNOSCOPE, /* request scope close w/none open */
+	MANDOCERR_SYNTSCOPE, /* scope broken, syntax violated */
+	MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */
+	MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */
+	MANDOCERR_SYNTCHILD, /* child violates parent syntax */
+	MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */
+	MANDOCERR_NODOCBODY, /* no document body */
+	MANDOCERR_NODOCPROLOG, /* no document prologue */
+	MANDOCERR_UTSNAME, /* utsname() system call failed */
 	MANDOCERR_MEM, /* memory exhausted */
 #define	MANDOCERR_FATAL		MANDOCERR_MEM
 
Index: libman.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libman.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -Llibman.h -Llibman.h -u -p -r1.33 -r1.34
--- libman.h
+++ libman.h
@@ -26,7 +26,7 @@ enum	man_next {
 
 struct	man {
 	void		*data;
-	struct man_cb	 cb;
+	mandocmsg	 msg;
 	int		 pflags; /* parse flags (see man.h) */
 	int		 flags; /* parse flags */
 #define	MAN_HALT	(1 << 0) /* badness happened: die */
@@ -41,30 +41,6 @@ struct	man {
 	struct man_meta	 meta;
 };
 
-enum	merr {
-	WNPRINT = 0,
-	WDATE,
-	WLNSCOPE,
-	WLNSCOPE2,
-	WTSPACE,
-	WTQUOTE,
-	WNODATA,
-	WNOTITLE,
-	WESCAPE,
-	WNUMFMT,
-	WHEADARGS,
-	WBODYARGS,
-	WNHEADARGS,
-	WMACROFORM,
-	WEXITSCOPE,
-	WNOSCOPE,
-	WOLITERAL,
-	WNLITERAL,
-	WTITLECASE,
-	WBADCOMMENT,
-	WERRMAX
-};
-
 #define	MACRO_PROT_ARGS	  struct man *m, enum mant tok, int line, \
 			  int ppos, int *pos, char *buf
 
@@ -82,15 +58,10 @@ extern	const struct man_macro *const man
 
 __BEGIN_DECLS
 
-#define		  man_perr(m, l, p, t) \
-		  man_err((m), (l), (p), 1, (t))
-#define		  man_pwarn(m, l, p, t) \
-		  man_err((m), (l), (p), 0, (t))
-#define		  man_nerr(m, n, t) \
-		  man_err((m), (n)->line, (n)->pos, 1, (t))
-#define		  man_nwarn(m, n, t) \
-		  man_err((m), (n)->line, (n)->pos, 0, (t))
-
+#define		  man_pmsg(m, l, p, t) \
+		  (*(m)->msg)((t), (m)->data, (l), (p), NULL)
+#define		  man_nmsg(m, n, t) \
+		  (*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
 int		  man_word_alloc(struct man *, int, int, const char *);
 int		  man_block_alloc(struct man *, int, int, enum mant);
 int		  man_head_alloc(struct man *, int, int, enum mant);
@@ -105,15 +76,14 @@ int		  man_args(struct man *, int, int *
 #define	ARGS_EOLN	(0)
 #define	ARGS_WORD	(1)
 #define	ARGS_QWORD	(1)
-int		  man_err(struct man *, int, int, int, enum merr);
-int		  man_vwarn(struct man *, int, int, const char *, ...);
-int		  man_verr(struct man *, int, int, const char *, ...);
+int		  man_vmsg(struct man *, enum mandocerr,
+			int, int, const char *, ...);
 int		  man_valid_post(struct man *);
 int		  man_valid_pre(struct man *, const struct man_node *);
 int		  man_action_post(struct man *);
 int		  man_action_pre(struct man *, struct man_node *);
 int		  man_unscope(struct man *, 
-			const struct man_node *, enum merr);
+			const struct man_node *, enum mandocerr);
 
 __END_DECLS
 
Index: main.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -Lmain.c -Lmain.c -u -p -r1.78 -r1.79
--- main.c
+++ main.c
@@ -81,17 +81,83 @@ struct	curparse {
 #define	FL_NIGN_MACRO	 (1 << 2) 	/* Don't ignore bad macros. */
 #define	FL_IGN_ERRORS	 (1 << 4)	/* Ignore failed parse. */
 #define	FL_STRICT	  FL_NIGN_ESCAPE | \
-			  FL_NIGN_MACRO
-	enum intt	  inttype;	/* Input parsers... */
-	struct man	 *man;
-	struct mdoc	 *mdoc;
-	struct roff	 *roff;
-	enum outt	  outtype;	/* Output devices... */
-	out_mdoc	  outmdoc;
-	out_man	  	  outman;
-	out_free	  outfree;
-	void		 *outdata;
-	char		  outopts[BUFSIZ];
+			  FL_NIGN_MACRO /* ignore nothing */
+	enum intt	  inttype;	/* which parser to use */
+	struct man	 *man;		/* man parser */
+	struct mdoc	 *mdoc;		/* mdoc parser */
+	struct roff	 *roff;		/* roff parser (!NULL) */
+	enum outt	  outtype; 	/* which output to use */
+	out_mdoc	  outmdoc;	/* mdoc output ptr */
+	out_man	  	  outman;	/* man output ptr */
+	out_free	  outfree;	/* free output ptr */
+	void		 *outdata;	/* data for output */
+	char		  outopts[BUFSIZ]; /* buf of output opts */
+};
+
+static	const char * const	mandocerrs[MANDOCERR_MAX] = {
+	"ok",
+	"text should be uppercase",
+	"sections out of conentional order",
+	"section name repeats",
+	"out of order prologue",
+	"repeated prologue entry",
+	"list type must come first",
+	"column syntax is inconsistent",
+	"bad standard",
+	"bad library",
+	"bad escape sequence",
+	"unterminated quoted string",
+	"argument requires the width argument",
+	"superfluous width argument",
+	"bad date argument",
+	"bad width argument",
+	"unknown manual sction",
+	"section not in conventional manual section",
+	"end of line whitespace",
+	"scope open on exit",
+	"NAME section must come first",
+	"bad Boolean value",
+	"child violates parent syntax",
+	"bad AT&T symbol",
+	"list type repeated",
+	"display type repeated",
+	"argument repeated",
+	"manual name not yet set",
+	"obsolete macro ignored",
+	"empty macro ignored",
+	"macro not allowed in body",
+	"macro not allowed in prologue",
+	"bad character",
+	"bad NAME section contents",
+	"no blank lines",
+	"no text in this context",
+	"bad comment style",
+	"unknown macro will be lost",
+	"line scope broken",
+	"scope broken",
+	"argument count wrong",
+	"request scope close w/none open",
+	"scope already open",
+	"macro requires line argument(s)",
+	"macro requires body argument(s)",
+	"macro requires argument(s)",
+	"no title in document",
+	"line argument(s) will be lost",
+	"body argument(s) will be lost",
+	"missing font type",
+	"missing display type",
+	"missing list type",
+	"displays may not be nested",
+	"no scope to rewind: syntax violated",
+	"scope broken, syntax violated",
+	"line scope broken, syntax violated",
+	"argument count wrong, violates syntax",
+	"child violates parent syntax",
+	"argument count wrong, violates syntax",
+	"no document body",
+	"no document prologue",
+	"utsname system call failed",
+	"memory exhausted",
 };
 
 static	void		  fdesc(struct curparse *);
@@ -100,9 +166,7 @@ static	int		  foptions(int *, char *);
 static	struct man	 *man_init(struct curparse *);
 static	struct mdoc	 *mdoc_init(struct curparse *);
 static	struct roff	 *roff_init(struct curparse *);
-static	int		  merr(void *, int, int, const char *); /* DEPRECATED */
 static	int		  moptions(enum intt *, char *);
-static	int		  mwarn(void *, int, int, const char *); /* DEPRECATED */
 static	int		  mmsg(enum mandocerr, void *, 
 				int, int, const char *);
 static	int		  pset(const char *, int, struct curparse *,
@@ -220,10 +284,6 @@ static struct man *
 man_init(struct curparse *curp)
 {
 	int		 pflags;
-	struct man_cb	 mancb;
-
-	mancb.man_err = merr;
-	mancb.man_warn = mwarn;
 
 	/* Defaults from mandoc.1. */
 
@@ -234,7 +294,7 @@ man_init(struct curparse *curp)
 	if (curp->fflags & FL_NIGN_ESCAPE)
 		pflags &= ~MAN_IGN_ESCAPE;
 
-	return(man_alloc(curp, pflags, &mancb));
+	return(man_alloc(curp, pflags, mmsg));
 }
 
 
@@ -250,10 +310,6 @@ static struct mdoc *
 mdoc_init(struct curparse *curp)
 {
 	int		 pflags;
-	struct mdoc_cb	 mdoccb;
-
-	mdoccb.mdoc_err = merr;
-	mdoccb.mdoc_warn = mwarn;
 
 	/* Defaults from mandoc.1. */
 
@@ -266,7 +322,7 @@ mdoc_init(struct curparse *curp)
 	if (curp->fflags & FL_NIGN_MACRO)
 		pflags &= ~MDOC_IGN_MACRO;
 
-	return(mdoc_alloc(curp, pflags, &mdoccb));
+	return(mdoc_alloc(curp, pflags, mmsg));
 }
 
 
@@ -756,67 +812,20 @@ woptions(int *wflags, char *arg)
 }
 
 
-/* ARGSUSED */
-static int
-merr(void *arg, int line, int col, const char *msg)
-{
-	struct curparse *curp;
-
-	curp = (struct curparse *)arg;
-
-	(void)fprintf(stderr, "%s:%d:%d: error: %s\n", 
-			curp->file, line, col + 1, msg);
-
-	with_error = 1;
-
-	return(0);
-}
-
-
-static int
-mwarn(void *arg, int line, int col, const char *msg)
-{
-	struct curparse *curp;
-
-	curp = (struct curparse *)arg;
-
-	if ( ! (curp->wflags & WARN_WALL))
-		return(1);
-
-	(void)fprintf(stderr, "%s:%d:%d: warning: %s\n", 
-			curp->file, line, col + 1, msg);
-
-	with_warning = 1;
-	if (curp->wflags & WARN_WERR) {
-		with_error = 1;
-		return(0);
-	}
-
-	return(1);
-}
-
-static	const char * const	mandocerrs[MANDOCERR_MAX] = {
-	"ok",
-	"multi-line scope open on exit",
-	"request for scope closure when no matching scope is open: ignored",
-	"macro requires line argument(s): ignored",
-	"line arguments will be lost",
-	"memory exhausted"
-};
-
-/*
- * XXX: this is experimental code that will eventually become the
- * generic means of covering all warnings and errors!
- */
-/* ARGSUSED */
 static int
 mmsg(enum mandocerr t, void *arg, int ln, int col, const char *msg)
 {
-#if 0
 	struct curparse *cp;
 
 	cp = (struct curparse *)arg;
 
+	if (t <= MANDOCERR_ERROR) {
+		if ( ! (cp->wflags & WARN_WALL))
+			return(1);
+		with_warning = 1;
+	} else
+		with_error = 1;
+
 	fprintf(stderr, "%s:%d:%d: %s", cp->file, 
 			ln, col + 1, mandocerrs[t]);
 
@@ -824,6 +833,13 @@ mmsg(enum mandocerr t, void *arg, int ln
 		fprintf(stderr, ": %s", msg);
 
 	fputc('\n', stderr);
-#endif
+
+	/* This is superfluous, but whatever. */
+	if (t > MANDOCERR_ERROR)
+		return(0);
+	if (cp->wflags & WARN_WERR) {
+		with_error = 1;
+		return(0);
+	}
 	return(1);
 }
Index: vol.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/vol.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lvol.c -Lvol.c -u -p -r1.6 -r1.7
--- vol.c
+++ vol.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: mdoc_validate.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_validate.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.78 -r1.79
--- mdoc_validate.c
+++ mdoc_validate.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
@@ -321,8 +322,9 @@ warn_count(struct mdoc *m, const char *k
 		int want, const char *v, int has)
 {
 
-	return(mdoc_vwarn(m, m->last->line, m->last->pos, 
-		"suggests %s %s %d (has %d)", v, k, want, has));
+	return(mdoc_vmsg(m, MANDOCERR_ARGCOUNT, 
+				m->last->line, m->last->pos, 
+				"%s %s %d (have %d)", v, k, want, has));
 }
 
 
@@ -331,8 +333,11 @@ err_count(struct mdoc *m, const char *k,
 		int want, const char *v, int has)
 {
 
-	return(mdoc_verr(m, m->last->line, m->last->pos,
-		"requires %s %s %d (has %d)", v, k, want, has));
+	mdoc_vmsg(m, MANDOCERR_SYNTARGCOUNT, 
+			m->last->line, m->last->pos, 
+			"%s %s %d (have %d)", 
+			v, k, want, has);
+	return(0);
 }
 
 
@@ -405,7 +410,7 @@ check_stdarg(PRE_ARGS)
 	if (n->args && 1 == n->args->argc)
 		if (MDOC_Std == n->args->argv[0].arg)
 			return(1);
-	return(mdoc_nwarn(mdoc, n, EARGVAL));
+	return(mdoc_nmsg(mdoc, n, MANDOCERR_NOARGV));
 }
 
 
@@ -437,10 +442,10 @@ check_argv(struct mdoc *m, const struct 
 			return(0);
 
 	if (MDOC_Std == v->arg) {
-		/* `Nm' name must be set. */
 		if (v->sz || m->meta.name)
 			return(1);
-		return(mdoc_nerr(m, n, ENAME));
+		if ( ! mdoc_nmsg(m, n, MANDOCERR_NONAME))
+			return(0);
 	}
 
 	return(1);
@@ -455,10 +460,10 @@ check_text(struct mdoc *mdoc, int line, 
 	for ( ; *p; p++, pos++) {
 		if ('\t' == *p) {
 			if ( ! (MDOC_LITERAL & mdoc->flags))
-				if ( ! mdoc_pwarn(mdoc, line, pos, EPRINT))
+				if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR))
 					return(0);
 		} else if ( ! isprint((u_char)*p))
-			if ( ! mdoc_pwarn(mdoc, line, pos, EPRINT))
+			if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR))
 				return(0);
 
 		if ('\\' != *p)
@@ -470,10 +475,10 @@ check_text(struct mdoc *mdoc, int line, 
 			pos += c - 1;
 			continue;
 		}
-		if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags))
-			return(mdoc_perr(mdoc, line, pos, EESCAPE));
-		if ( ! mdoc_pwarn(mdoc, line, pos, EESCAPE))
-			return(0);
+
+		c = mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADESCAPE);
+		if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags) && ! c)
+			return(c);
 	}
 
 	return(1);
@@ -491,8 +496,11 @@ check_parent(PRE_ARGS, enum mdoct tok, e
 			(t == n->parent->type))
 		return(1);
 
-	return(mdoc_verr(mdoc, n->line, n->pos, "require parent %s",
-		MDOC_ROOT == t ? "<root>" : mdoc_macronames[tok]));
+	mdoc_vmsg(mdoc, MANDOCERR_SYNTCHILD,
+				n->line, n->pos, "want parent %s",
+				MDOC_ROOT == t ? "<root>" : 
+					mdoc_macronames[tok]);
+	return(0);
 }
 
 
@@ -515,7 +523,8 @@ pre_display(PRE_ARGS)
 	if (NULL == node)
 		return(1);
 
-	return(mdoc_nerr(mdoc, n, ENESTDISP));
+	mdoc_nmsg(mdoc, n, MANDOCERR_NESTEDDISP);
+	return(0);
 }
 
 
@@ -526,8 +535,10 @@ pre_bl(PRE_ARGS)
 
 	if (MDOC_BLOCK != n->type)
 		return(1);
-	if (NULL == n->args)
-		return(mdoc_nerr(mdoc, n, ELISTTYPE));
+	if (NULL == n->args) {
+		mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
+		return(0);
+	}
 
 	/* Make sure that only one type of list is specified.  */
 
@@ -567,7 +578,7 @@ pre_bl(PRE_ARGS)
 			 * FIXME: this should occur in mdoc_action.c.
 			 */
 			if (type >= 0) {
-				if ( ! mdoc_nwarn(mdoc, n, EMULTILIST))
+				if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
 					return(0);
 				mdoc_argn_free(n->args, pos);
 				break;
@@ -575,20 +586,22 @@ pre_bl(PRE_ARGS)
 			type = n->args->argv[pos].arg;
 			break;
 		case (MDOC_Compact):
-			if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE))
+			if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
 				return(0);
 			break;
 		case (MDOC_Width):
 			if (width >= 0)
-				return(mdoc_nerr(mdoc, n, EARGREP));
-			if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE))
+				if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+					return(0);
+			if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
 				return(0);
 			width = n->args->argv[pos].arg;
 			break;
 		case (MDOC_Offset):
 			if (offset >= 0)
-				return(mdoc_nerr(mdoc, n, EARGREP));
-			if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE))
+				if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+					return(0);
+			if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
 				return(0);
 			offset = n->args->argv[pos].arg;
 			break;
@@ -596,8 +609,10 @@ pre_bl(PRE_ARGS)
 			break;
 		}
 
-	if (type < 0)
-		return(mdoc_nerr(mdoc, n, ELISTTYPE));
+	if (type < 0) {
+		mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
+		return(0);
+	}
 
 	/* 
 	 * Validate the width field.  Some list types don't need width
@@ -607,7 +622,7 @@ pre_bl(PRE_ARGS)
 
 	switch (type) {
 	case (MDOC_Tag):
-		if (width < 0 && ! mdoc_nwarn(mdoc, n, EMISSWIDTH))
+		if (width < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
 			return(0);
 		break;
 	case (MDOC_Column):
@@ -619,7 +634,7 @@ pre_bl(PRE_ARGS)
 	case (MDOC_Inset):
 		/* FALLTHROUGH */
 	case (MDOC_Item):
-		if (width >= 0 && ! mdoc_nwarn(mdoc, n, ENOWIDTH))
+		if (width >= 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
 			return(0);
 		break;
 	default:
@@ -637,8 +652,10 @@ pre_bd(PRE_ARGS)
 
 	if (MDOC_BLOCK != n->type)
 		return(1);
-	if (NULL == n->args) 
-		return(mdoc_nerr(mdoc, n, EDISPTYPE));
+	if (NULL == n->args) {
+		mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE);
+		return(0);
+	}
 
 	/* Make sure that only one type of display is specified.  */
 
@@ -657,14 +674,17 @@ pre_bd(PRE_ARGS)
 		case (MDOC_Literal):
 			if (0 == type++) 
 				break;
-			return(mdoc_nerr(mdoc, n, EMULTIDISP));
+			if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP))
+				return(0);
+			break;
 		default:
 			break;
 		}
 
 	if (type)
 		return(1);
-	return(mdoc_nerr(mdoc, n, EDISPTYPE));
+	mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE);
+	return(0);
 }
 
 
@@ -694,6 +714,10 @@ pre_it(PRE_ARGS)
 
 	if (MDOC_BLOCK != n->type)
 		return(1);
+	/* 
+	 * FIXME: this can probably be lifted if we make the It into
+	 * something else on-the-fly?
+	 */
 	return(check_parent(mdoc, n, MDOC_Bl, MDOC_BODY));
 }
 
@@ -704,8 +728,11 @@ pre_an(PRE_ARGS)
 
 	if (NULL == n->args || 1 == n->args->argc)
 		return(1);
-	return(mdoc_verr(mdoc, n->line, n->pos, 
-				"only one argument allowed"));
+	mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT, 
+				n->line, n->pos,
+				"line arguments == 1 (have %d)",
+				n->args->argc);
+	return(0);
 }
 
 
@@ -724,10 +751,10 @@ pre_dt(PRE_ARGS)
 	/* FIXME: make sure is capitalised. */
 
 	if (0 == mdoc->meta.date || mdoc->meta.os)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLOOO))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO))
 			return(0);
 	if (mdoc->meta.title)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLREP))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP))
 			return(0);
 	return(1);
 }
@@ -738,10 +765,10 @@ pre_os(PRE_ARGS)
 {
 
 	if (NULL == mdoc->meta.title || 0 == mdoc->meta.date)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLOOO))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO))
 			return(0);
 	if (mdoc->meta.os)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLREP))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP))
 			return(0);
 	return(1);
 }
@@ -752,10 +779,10 @@ pre_dd(PRE_ARGS)
 {
 
 	if (mdoc->meta.title || mdoc->meta.os)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLOOO))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO))
 			return(0);
 	if (mdoc->meta.date)
-		if ( ! mdoc_nwarn(mdoc, n, EPROLREP))
+		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP))
 			return(0);
 	return(1);
 }
@@ -772,13 +799,18 @@ post_bf(POST_ARGS)
 
 	head = mdoc->last->head;
 
-	if (mdoc->last->args && head->child)
-		return(mdoc_nerr(mdoc, mdoc->last, ELINE));
-	else if (mdoc->last->args)
+	if (mdoc->last->args && head->child) {
+		/* FIXME: this should provide a default. */
+		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT);
+		return(0);
+	} else if (mdoc->last->args)
 		return(1);
 
-	if (NULL == head->child || MDOC_TEXT != head->child->type)
-		return(mdoc_nerr(mdoc, mdoc->last, ELINE));
+	if (NULL == head->child || MDOC_TEXT != head->child->type) {
+		/* FIXME: this should provide a default. */
+		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT);
+		return(0);
+	}
 
 	p = head->child->string;
 
@@ -789,7 +821,8 @@ post_bf(POST_ARGS)
 	else if (0 == strcmp(p, "Sy"))
 		return(1);
 
-	return(mdoc_nerr(mdoc, head, EFONT));
+	mdoc_nmsg(mdoc, head, MANDOCERR_FONTTYPE);
+	return(0);
 }
 
 
@@ -799,7 +832,7 @@ post_lb(POST_ARGS)
 
 	if (mdoc_a2lib(mdoc->last->child->string))
 		return(1);
-	return(mdoc_nwarn(mdoc, mdoc->last, ELIB));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADLIB));
 }
 
 
@@ -822,7 +855,7 @@ post_vt(POST_ARGS)
 	
 	for (n = mdoc->last->child; n; n = n->next)
 		if (MDOC_TEXT != n->type) 
-			if ( ! mdoc_nwarn(mdoc, n, EBADCHILD))
+			if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_CHILD))
 				return(0);
 
 	return(1);
@@ -837,7 +870,7 @@ post_nm(POST_ARGS)
 		return(1);
 	if (mdoc->meta.name)
 		return(1);
-	return(mdoc_nerr(mdoc, mdoc->last, ENAME));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME));
 }
 
 
@@ -847,11 +880,10 @@ post_at(POST_ARGS)
 
 	if (NULL == mdoc->last->child)
 		return(1);
-	if (MDOC_TEXT != mdoc->last->child->type)
-		return(mdoc_nerr(mdoc, mdoc->last, EATT));
+	assert(MDOC_TEXT == mdoc->last->child->type);
 	if (mdoc_a2att(mdoc->last->child->string))
 		return(1);
-	return(mdoc_nwarn(mdoc, mdoc->last, EATT));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADATT));
 }
 
 
@@ -862,12 +894,12 @@ post_an(POST_ARGS)
 	if (mdoc->last->args) {
 		if (NULL == mdoc->last->child)
 			return(1);
-		return(mdoc_nerr(mdoc, mdoc->last, ENOLINE));
+		return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGCOUNT));
 	}
 
 	if (mdoc->last->child)
 		return(1);
-	return(mdoc_nerr(mdoc, mdoc->last, ELINE));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS));
 }
 
 
@@ -881,8 +913,10 @@ post_it(POST_ARGS)
 		return(1);
 
 	n = mdoc->last->parent->parent;
-	if (NULL == n->args)
-		return(mdoc_nerr(mdoc, mdoc->last, ELISTTYPE));
+	if (NULL == n->args) {
+		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE);
+		return(0);
+	}
 
 	/* Some types require block-head, some not. */
 
@@ -919,13 +953,15 @@ post_it(POST_ARGS)
 			break;
 		}
 
-	if (-1 == type)
-		return(mdoc_nerr(mdoc, mdoc->last, ELISTTYPE));
+	if (-1 == type) {
+		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE);
+		return(0);
+	}
 
 	switch (type) {
 	case (MDOC_Tag):
 		if (NULL == mdoc->last->head->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS))
 				return(0);
 		break;
 	case (MDOC_Hang):
@@ -936,10 +972,10 @@ post_it(POST_ARGS)
 		/* FALLTHROUGH */
 	case (MDOC_Diag):
 		if (NULL == mdoc->last->head->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS))
 				return(0);
 		if (NULL == mdoc->last->body->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, EMULTILINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY))
 				return(0);
 		break;
 	case (MDOC_Bullet):
@@ -952,36 +988,38 @@ post_it(POST_ARGS)
 		/* FALLTHROUGH */
 	case (MDOC_Item):
 		if (mdoc->last->head->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, ENOLINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGSLOST))
 				return(0);
 		if (NULL == mdoc->last->body->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, EMULTILINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY))
 				return(0);
 		break;
 	case (MDOC_Column):
 		if (NULL == mdoc->last->head->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS))
 				return(0);
 		if (mdoc->last->body->child)
-			if ( ! mdoc_nwarn(mdoc, mdoc->last, ENOMULTILINE))
+			if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BODYLOST))
 				return(0);
 		c = mdoc->last->child;
 		for (i = 0; c && MDOC_HEAD == c->type; c = c->next)
 			i++;
 
 		if (i < cols) {
-			if ( ! mdoc_vwarn(mdoc, mdoc->last->line, 
-					mdoc->last->pos, "column "
-					"mismatch: have %d, want %d", 
-					i, cols))
+			if ( ! mdoc_vmsg(mdoc, MANDOCERR_ARGCOUNT,
+					mdoc->last->line, 
+					mdoc->last->pos, 
+					"columns == %d (have %d)",
+					cols, i))
 				return(0);
 			break;
 		} else if (i == cols || i == cols + 1)
 			break;
 
-		return(mdoc_verr(mdoc, mdoc->last->line, 
-				mdoc->last->pos, "column mismatch: "
-				"have %d, want %d", i, cols));
+		mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT,
+				mdoc->last->line, mdoc->last->pos, 
+				"columns == %d (have %d)", cols, i);
+		return(0);
 	default:
 		break;
 	}
@@ -1004,7 +1042,7 @@ post_bl_head(POST_ARGS) 
 		a = &n->args->argv[i];
 		if (a->arg == MDOC_Column) {
 			if (a->sz && mdoc->last->nchild)
-				return(mdoc_nerr(mdoc, n, ECOLMIS));
+				return(mdoc_nmsg(mdoc, n, MANDOCERR_COLUMNS));
 			return(1);
 		}
 	}
@@ -1039,7 +1077,8 @@ post_bl(POST_ARGS)
 			continue;
 		if (MDOC_Sm == n->tok)
 			continue;
-		return(mdoc_nerr(mdoc, n, EBADCHILD));
+		mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD);
+		return(0);
 	}
 
 	return(1);
@@ -1064,7 +1103,7 @@ ebool(struct mdoc *mdoc)
 
 	if (NULL == n)
 		return(1);
-	return(mdoc_nerr(mdoc, n, EBOOL));
+	return(mdoc_nmsg(mdoc, n, MANDOCERR_BADBOOL));
 }
 
 
@@ -1073,16 +1112,17 @@ post_root(POST_ARGS)
 {
 
 	if (NULL == mdoc->first->child)
-		return(mdoc_nerr(mdoc, mdoc->first, ENODAT));
-	if ( ! (MDOC_PBODY & mdoc->flags))
-		return(mdoc_nerr(mdoc, mdoc->first, ENOPROLOGUE));
-
-	if (MDOC_BLOCK != mdoc->first->child->type)
-		return(mdoc_nerr(mdoc, mdoc->first, ENODAT));
-	if (MDOC_Sh != mdoc->first->child->tok)
-		return(mdoc_nerr(mdoc, mdoc->first, ENODAT));
+		mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY);
+	else if ( ! (MDOC_PBODY & mdoc->flags))
+		mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCPROLOG);
+	else if (MDOC_BLOCK != mdoc->first->child->type)
+		mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY);
+	else if (MDOC_Sh != mdoc->first->child->tok)
+		mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY);
+	else
+		return(1);
 
-	return(1);
+	return(0);
 }
 
 
@@ -1092,7 +1132,7 @@ post_st(POST_ARGS)
 
 	if (mdoc_a2st(mdoc->last->child->string))
 		return(1);
-	return(mdoc_nwarn(mdoc, mdoc->last, EBADSTAND));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADSTANDARD));
 }
 
 
@@ -1135,7 +1175,8 @@ post_rs(POST_ARGS)
 		case(MDOC__V):
 			break;
 		default:
-			return(mdoc_nerr(mdoc, nn, EBADCHILD));
+			mdoc_nmsg(mdoc, nn, MANDOCERR_SYNTCHILD);
+			return(0);
 		}
 
 	return(1);
@@ -1170,21 +1211,21 @@ post_sh_body(POST_ARGS)
 	 */
 
 	if (NULL == (n = mdoc->last->child))
-		return(mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC));
+		return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC));
 
 	for ( ; n && n->next; n = n->next) {
 		if (MDOC_ELEM == n->type && MDOC_Nm == n->tok)
 			continue;
 		if (MDOC_TEXT == n->type)
 			continue;
-		if ( ! mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC))
+		if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC))
 			return(0);
 	}
 
 	assert(n);
 	if (MDOC_BLOCK == n->type && MDOC_Nd == n->tok)
 		return(1);
-	return(mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC));
+	return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC));
 }
 
 
@@ -1202,18 +1243,27 @@ post_sh_head(POST_ARGS)
 	 * certain manual sections.
 	 */
 
-	buf[0] = 0;
+	buf[0] = '\0';
+
+	/*
+	 * FIXME: yes, these can use a dynamic buffer, but I don't do so
+	 * in the interests of simplicity.
+	 */
 
 	for (n = mdoc->last->child; n; n = n->next) {
 		/* XXX - copied from compact(). */
 		assert(MDOC_TEXT == n->type);
 
-		if (strlcat(buf, n->string, 64) >= 64)
-			return(mdoc_nerr(mdoc, n, ETOOLONG));
+		if (strlcat(buf, n->string, 64) >= 64) {
+			mdoc_nmsg(mdoc, n, MANDOCERR_MEM);
+			return(0);
+		}
 		if (NULL == n->next)
 			continue;
-		if (strlcat(buf, " ", 64) >= 64)
-			return(mdoc_nerr(mdoc, n, ETOOLONG));
+		if (strlcat(buf, " ", 64) >= 64) {
+			mdoc_nmsg(mdoc, n, MANDOCERR_MEM);
+			return(0);
+		}
 	}
 
 	sec = mdoc_str2sec(buf);
@@ -1224,18 +1274,18 @@ post_sh_head(POST_ARGS)
 	 */
 
 	if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
-		if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECNAME))
+		if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NAMESECFIRST))
 			return(0);
 
 	if (SEC_CUSTOM == sec)
 		return(1);
 
 	if (sec == mdoc->lastnamed)
-		if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECREP))
+		if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECREP))
 			return(0);
 
 	if (sec < mdoc->lastnamed)
-		if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECOOO))
+		if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECOOO))
 			return(0);
 
 	/* 
@@ -1252,7 +1302,7 @@ post_sh_head(POST_ARGS)
 			break;
 		if (*mdoc->meta.msec == '9')
 			break;
-		return(mdoc_nwarn(mdoc, mdoc->last, EWRONGMSEC));
+		return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECMSEC));
 	default:
 		break;
 	}
Index: man.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -Lman.h -Lman.h -u -p -r1.34 -r1.35
--- man.h
+++ man.h
@@ -100,17 +100,12 @@ struct	man_node {
 
 extern	const char *const *man_macronames;
 
-struct	man_cb {
-	int	(*man_warn)(void *, int, int, const char *);
-	int	(*man_err)(void *, int, int, const char *);
-};
-
 __BEGIN_DECLS
 
 struct	man;
 
 void	 	  man_free(struct man *);
-struct	man	 *man_alloc(void *, int, const struct man_cb *);
+struct	man	 *man_alloc(void *, int, mandocmsg);
 void		  man_reset(struct man *);
 int	 	  man_parseln(struct man *, int, char *, int);
 int		  man_endparse(struct man *);
Index: lib.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/lib.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Llib.c -Llib.c -u -p -r1.6 -r1.7
--- lib.c
+++ lib.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: mdoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.h,v
retrieving revision 1.80
retrieving revision 1.81
diff -Lmdoc.h -Lmdoc.h -u -p -r1.80 -r1.81
--- mdoc.h
+++ mdoc.h
@@ -278,13 +278,6 @@ struct	mdoc_node {
 #define	MDOC_IGN_ESCAPE	 (1 << 1) /* Ignore bad escape sequences. */
 #define	MDOC_IGN_MACRO	 (1 << 2) /* Ignore unknown macros. */
 
-/* Call-backs for parse messages. */
-
-struct	mdoc_cb {
-	int	(*mdoc_err)(void *, int, int, const char *);
-	int	(*mdoc_warn)(void *, int, int, const char *);
-};
-
 /* See mdoc.3 for documentation. */
 
 extern	const char *const *mdoc_macronames;
@@ -297,7 +290,7 @@ struct	mdoc;
 /* See mdoc.3 for documentation. */
 
 void	 	  mdoc_free(struct mdoc *);
-struct	mdoc	 *mdoc_alloc(void *, int, const struct mdoc_cb *);
+struct	mdoc	 *mdoc_alloc(void *, int, mandocmsg);
 void		  mdoc_reset(struct mdoc *);
 int	 	  mdoc_parseln(struct mdoc *, int, char *, int);
 const struct mdoc_node *mdoc_node(const struct mdoc *);
Index: man_argv.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_argv.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lman_argv.c -Lman_argv.c -u -p -r1.2 -r1.3
--- man_argv.c
+++ man_argv.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libman.h"
 
 
@@ -57,7 +58,7 @@ man_args(struct man *m, int line, int *p
 		}
 
 		if (0 == buf[*pos]) {
-			if ( ! man_pwarn(m, line, *pos, WTQUOTE))
+			if ( ! man_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
 				return(ARGS_ERROR);
 			return(ARGS_QWORD);
 		}
@@ -71,7 +72,7 @@ man_args(struct man *m, int line, int *p
 			(*pos)++;
 
 		if (0 == buf[*pos])
-			if ( ! man_pwarn(m, line, *pos, WTSPACE))
+			if ( ! man_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 				return(ARGS_ERROR);
 
 		return(ARGS_QWORD);
@@ -95,7 +96,7 @@ man_args(struct man *m, int line, int *p
 		(*pos)++;
 
 	if (0 == buf[*pos])
-		if ( ! man_pwarn(m, line, *pos, WTSPACE))
+		if ( ! man_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 			return(ARGS_ERROR);
 
 	return(ARGS_WORD);
Index: man_action.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_action.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -Lman_action.c -Lman_action.c -u -p -r1.35 -r1.36
--- man_action.c
+++ man_action.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libman.h"
 #include "libmandoc.h"
 
@@ -103,7 +104,7 @@ post_fi(struct man *m)
 {
 
 	if ( ! (MAN_LITERAL & m->flags))
-		if ( ! man_nwarn(m, m->last, WNLITERAL))
+		if ( ! man_nmsg(m, m->last, MANDOCERR_NOSCOPE))
 			return(0);
 	m->flags &= ~MAN_LITERAL;
 	return(1);
@@ -115,7 +116,7 @@ post_nf(struct man *m)
 {
 
 	if (MAN_LITERAL & m->flags)
-		if ( ! man_nwarn(m, m->last, WOLITERAL))
+		if ( ! man_nmsg(m, m->last, MANDOCERR_SCOPEREP))
 			return(0);
 	m->flags |= MAN_LITERAL;
 	return(1);
@@ -159,7 +160,7 @@ post_TH(struct man *m)
 		m->meta.date = mandoc_a2time
 			(MTIME_ISO_8601, n->string);
 		if (0 == m->meta.date) {
-			if ( ! man_nwarn(m, n, WDATE))
+			if ( ! man_nmsg(m, n, MANDOCERR_BADDATE))
 				return(0);
 			m->meta.date = time(NULL);
 		}
Index: st.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/st.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lst.c -Lst.c -u -p -r1.6 -r1.7
--- st.c
+++ st.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: mdoc_argv.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_argv.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -Lmdoc_argv.c -Lmdoc_argv.c -u -p -r1.48 -r1.49
--- mdoc_argv.c
+++ mdoc_argv.c
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
@@ -407,7 +408,7 @@ args(struct mdoc *m, int line, int *pos,
 		 * is unterminated.
 		 */
 		if (MDOC_PHRASELIT & m->flags)
-			if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM))
+			if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
 				return(ARGS_ERROR);
 
 		m->flags &= ~MDOC_PHRASELIT;
@@ -440,7 +441,7 @@ args(struct mdoc *m, int line, int *pos,
 				return(ARGS_PUNCT);
 			if (ARGS_NOWARN & fl)
 				return(ARGS_PUNCT);
-			if ( ! mdoc_pwarn(m, line, *pos, ETAILWS))
+			if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 				return(ARGS_ERROR);
 			return(ARGS_PUNCT);
 		}
@@ -495,7 +496,7 @@ args(struct mdoc *m, int line, int *pos,
 
 		/* Whitespace check for eoln case... */
 		if (0 == *p && ' ' == *(p - 1) && ! (ARGS_NOWARN & fl))
-			if ( ! mdoc_pwarn(m, line, *pos, ETAILWS))
+			if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 				return(ARGS_ERROR);
 
 		*pos += (int)(p - *v);
@@ -540,7 +541,7 @@ args(struct mdoc *m, int line, int *pos,
 		if ('\0' == buf[*pos]) {
 			if (ARGS_NOWARN & fl || MDOC_PPHRASE & m->flags)
 				return(ARGS_QWORD);
-			if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM))
+			if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
 				return(ARGS_ERROR);
 			return(ARGS_QWORD);
 		}
@@ -555,7 +556,7 @@ args(struct mdoc *m, int line, int *pos,
 			(*pos)++;
 
 		if (0 == buf[*pos] && ! (ARGS_NOWARN & fl))
-			if ( ! mdoc_pwarn(m, line, *pos, ETAILWS))
+			if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 				return(ARGS_ERROR);
 
 		return(ARGS_QWORD);
@@ -579,7 +580,7 @@ args(struct mdoc *m, int line, int *pos,
 		(*pos)++;
 
 	if ('\0' == buf[*pos] && ! (ARGS_NOWARN & fl))
-		if ( ! mdoc_pwarn(m, line, *pos, ETAILWS))
+		if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
 			return(ARGS_ERROR);
 
 	return(ARGS_WORD);
@@ -751,10 +752,11 @@ argv_single(struct mdoc *m, int line, 
 	ppos = *pos;
 
 	ac = args(m, line, pos, buf, 0, &p);
-	if (ARGS_ERROR == ac)
+	if (ARGS_EOLN == ac) {
+		mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT);
+		return(0);
+	} else if (ARGS_ERROR == ac)
 		return(0);
-	if (ARGS_EOLN == ac)
-		return(mdoc_perr(m, line, ppos, EARGVAL));
 
 	v->sz = 1;
 	v->value = mandoc_malloc(sizeof(char *));
Index: man_validate.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_validate.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -Lman_validate.c -Lman_validate.c -u -p -r1.40 -r1.41
--- man_validate.c
+++ man_validate.c
@@ -27,6 +27,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#include "mandoc.h"
 #include "libman.h"
 #include "libmandoc.h"
 
@@ -151,17 +152,18 @@ check_root(CHKARGS) 
 {
 
 	if (MAN_BLINE & m->flags)
-		return(man_nwarn(m, n, WEXITSCOPE));
+		return(man_nmsg(m, n, MANDOCERR_SCOPEEXIT));
 	if (MAN_ELINE & m->flags)
-		return(man_nwarn(m, n, WEXITSCOPE));
+		return(man_nmsg(m, n, MANDOCERR_SCOPEEXIT));
 
 	m->flags &= ~MAN_BLINE;
 	m->flags &= ~MAN_ELINE;
 
-	if (NULL == m->first->child)
-		return(man_nerr(m, n, WNODATA));
-	if (NULL == m->meta.title) {
-		if ( ! man_nwarn(m, n, WNOTITLE))
+	if (NULL == m->first->child) {
+		man_nmsg(m, n, MANDOCERR_NODOCBODY);
+		return(0);
+	} else if (NULL == m->meta.title) {
+		if ( ! man_nmsg(m, n, MANDOCERR_NOTITLE))
 			return(0);
 		/*
 		 * If a title hasn't been set, do so now (by
@@ -184,12 +186,15 @@ check_title(CHKARGS) 
 	const char	*p;
 
 	assert(n->child);
-	if ('\0' == *n->child->string)
-		return(man_nerr(m, n, WNOTITLE));
+	/* FIXME: is this sufficient? */
+	if ('\0' == *n->child->string) {
+		man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
+		return(0);
+	}
 
 	for (p = n->child->string; '\0' != *p; p++)
 		if (isalpha((u_char)*p) && ! isupper((u_char)*p))
-			if ( ! man_nwarn(m, n, WTITLECASE))
+			if ( ! man_nmsg(m, n, MANDOCERR_UPPERCASE))
 				return(0);
 
 	return(1);
@@ -212,17 +217,16 @@ check_text(CHKARGS) 
 				pos += c - 1;
 				continue;
 			}
-			if ( ! (MAN_IGN_ESCAPE & m->pflags))
-				return(man_perr(m, n->line, pos, WESCAPE));
-			if ( ! man_pwarn(m, n->line, pos, WESCAPE))
-				return(0);
-			continue;
+
+			c = man_pmsg(m, n->line, pos, MANDOCERR_BADESCAPE);
+			if ( ! (MAN_IGN_ESCAPE & m->pflags) && ! c)
+				return(c);
 		}
 
 		if ('\t' == *p || isprint((u_char)*p)) 
 			continue;
-
-		return(man_pwarn(m, n->line, pos, WNPRINT));
+		if ( ! man_pmsg(m, n->line, pos, MANDOCERR_BADCHAR))
+			return(0);
 	}
 
 	return(1);
@@ -235,9 +239,10 @@ check_##name(CHKARGS) \
 { \
 	if (n->nchild ineq (x)) \
 		return(1); \
-	return(man_verr(m, n->line, n->pos, \
-			"expected line arguments %s %d, have %d", \
-			#ineq, (x), n->nchild)); \
+	man_vmsg(m, MANDOCERR_SYNTARGCOUNT, n->line, n->pos, \
+			"line arguments %s %d (have %d)", \
+			#ineq, (x), n->nchild); \
+	return(0); \
 }
 
 INEQ_DEFINE(0, ==, eq0)
@@ -250,10 +255,12 @@ static int
 check_sec(CHKARGS)
 {
 
-	if (MAN_BODY == n->type && 0 == n->nchild)
-		return(man_nwarn(m, n, WBODYARGS));
-	if (MAN_HEAD == n->type && 0 == n->nchild)
-		return(man_nerr(m, n, WHEADARGS));
+	if (MAN_HEAD == n->type && 0 == n->nchild) {
+		man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
+		return(0);
+	} else if (MAN_BODY == n->type && 0 == n->nchild)
+		return(man_nmsg(m, n, MANDOCERR_NOBODY));
+
 	return(1);
 }
 
@@ -263,7 +270,7 @@ check_part(CHKARGS)
 {
 
 	if (MAN_BODY == n->type && 0 == n->nchild)
-		return(man_nwarn(m, n, WBODYARGS));
+		return(man_nmsg(m, n, MANDOCERR_NOBODY));
 	return(1);
 }
 
@@ -284,7 +291,7 @@ check_par(CHKARGS)
 		default:
 			if (n->nchild)
 				break;
-			return(man_nwarn(m, n, WBODYARGS));
+			return(man_nmsg(m, n, MANDOCERR_NOBODY));
 		}
 	if (MAN_HEAD == n->type)
 		switch (n->tok) {
@@ -295,11 +302,11 @@ check_par(CHKARGS)
 		case (MAN_LP):
 			if (0 == n->nchild)
 				break;
-			return(man_nwarn(m, n, WNHEADARGS));
+			return(man_nmsg(m, n, MANDOCERR_ARGSLOST));
 		default:
 			if (n->nchild)
 				break;
-			return(man_nwarn(m, n, WHEADARGS));
+			return(man_nmsg(m, n, MANDOCERR_NOARGS));
 		}
 
 	return(1);
@@ -311,8 +318,10 @@ check_bline(CHKARGS)
 {
 
 	assert( ! (MAN_ELINE & m->flags));
-	if (MAN_BLINE & m->flags)
-		return(man_nerr(m, n, WLNSCOPE));
+	if (MAN_BLINE & m->flags) {
+		man_nmsg(m, n, MANDOCERR_SYNTLINESCOPE);
+		return(0);
+	}
 
 	return(1);
 }
Index: term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term.c,v
retrieving revision 1.136
retrieving revision 1.137
diff -Lterm.c -Lterm.c -u -p -r1.136 -r1.137
--- term.c
+++ term.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "chars.h"
 #include "out.h"
 #include "term.h"
Index: man_html.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_html.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -Lman_html.c -Lman_html.c -u -p -r1.34 -r1.35
--- man_html.c
+++ man_html.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "html.h"
 #include "man.h"
Index: mdoc_html.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_html.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -Lmdoc_html.c -Lmdoc_html.c -u -p -r1.64 -r1.65
--- mdoc_html.c
+++ mdoc_html.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "html.h"
 #include "mdoc.h"
@@ -729,6 +730,9 @@ mdoc_nm_pre(MDOC_ARGS)
 {
 	struct htmlpair	tag;
 
+	if (NULL == n->child && NULL == m->name)
+		return(1);
+
 	if (SEC_SYNOPSIS == n->sec && 
 			n->prev && MDOC_LINE & n->flags) {
 		bufcat_style(h, "clear", "both");
@@ -1181,7 +1185,7 @@ mdoc_ex_pre(MDOC_ARGS)
 			h->flags &= ~HTML_NOSPACE;
 	}
 
-	if (n->child->next)
+	if (n->child && n->child->next)
 		print_text(h, "utilities exit");
 	else
 		print_text(h, "utility exits");
@@ -1951,7 +1955,7 @@ mdoc_rv_pre(MDOC_ARGS)
 			print_text(h, "()");
 	}
 
-	if (n->child->next)
+	if (n->child && n->child->next)
 		print_text(h, "functions return");
 	else
 		print_text(h, "function returns");
Index: libmdoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libmdoc.h,v
retrieving revision 1.47
retrieving revision 1.48
diff -Llibmdoc.h -Llibmdoc.h -u -p -r1.47 -r1.48
--- libmdoc.h
+++ libmdoc.h
@@ -26,7 +26,7 @@ enum	mdoc_next {
 
 struct	mdoc {
 	void		 *data;
-	struct mdoc_cb	  cb;
+	mandocmsg	  msg;
 	int		  flags;
 #define	MDOC_HALT	 (1 << 0) /* error in parse: halt */
 #define	MDOC_LITERAL	 (1 << 1) /* in a literal scope */
@@ -142,19 +142,12 @@ extern	const struct mdoc_macro *const md
 
 __BEGIN_DECLS
 
-#define		  mdoc_perr(m, l, p, t) \
-		  mdoc_err((m), (l), (p), 1, (t))
-#define		  mdoc_pwarn(m, l, p, t) \
-		  mdoc_err((m), (l), (p), 0, (t))
-#define		  mdoc_nerr(m, n, t) \
-		  mdoc_err((m), (n)->line, (n)->pos, 1, (t))
-#define		  mdoc_nwarn(m, n, t) \
-		  mdoc_err((m), (n)->line, (n)->pos, 0, (t))
-
-int		  mdoc_err(struct mdoc *, int, int, int, enum merr);
-int		  mdoc_verr(struct mdoc *, int, int, const char *, ...);
-int		  mdoc_vwarn(struct mdoc *, int, int, const char *, ...);
-
+#define		  mdoc_pmsg(m, l, p, t) \
+		  (*(m)->msg)((t), (m)->data, (l), (p), NULL)
+#define		  mdoc_nmsg(m, n, t) \
+		  (*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
+int		  mdoc_vmsg(struct mdoc *, enum mandocerr, 
+			int, int, const char *, ...);
 int		  mdoc_macro(MACRO_PROT_ARGS);
 int		  mdoc_word_alloc(struct mdoc *, 
 			int, int, const char *);
Index: man.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -Lman.c -Lman.c -u -p -r1.73 -r1.74
--- man.c
+++ man.c
@@ -27,32 +27,10 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libman.h"
 #include "libmandoc.h"
 
-const	char *const __man_merrnames[WERRMAX] = {		 
-	"invalid character", /* WNPRINT */
-	"invalid date format", /* WDATE */
-	"scope of prior line violated", /* WLNSCOPE */
-	"over-zealous prior line scope violation", /* WLNSCOPE2 */
-	"trailing whitespace", /* WTSPACE */
-	"unterminated quoted parameter", /* WTQUOTE */
-	"document has no body", /* WNODATA */
-	"document has no title/section", /* WNOTITLE */
-	"invalid escape sequence", /* WESCAPE */
-	"invalid number format", /* WNUMFMT */
-	"expected block head arguments", /* WHEADARGS */
-	"expected block body arguments", /* WBODYARGS */
-	"expected empty block head", /* WNHEADARGS */
-	"ill-formed macro", /* WMACROFORM */
-	"scope open on exit", /* WEXITSCOPE */
-	"no scope context", /* WNOSCOPE */
-	"literal context already open", /* WOLITERAL */
-	"no literal context open", /* WNLITERAL */
-	"document title should be uppercase", /* WTITLECASE */
-	"deprecated comment style", /* WBADCOMMENT */
-};
-
 const	char *const __man_macronames[MAN_MAX] = {		 
 	"br",		"TH",		"SH",		"SS",
 	"TP", 		"LP",		"PP",		"P",
@@ -116,18 +94,16 @@ man_free(struct man *man)
 
 
 struct man *
-man_alloc(void *data, int pflags, const struct man_cb *cb)
+man_alloc(void *data, int pflags, mandocmsg msg)
 {
 	struct man	*p;
 
 	p = mandoc_calloc(1, sizeof(struct man));
 
-	if (cb)
-		memcpy(&p->cb, cb, sizeof(struct man_cb));
-
 	man_hash_init();
 	p->data = data;
 	p->pflags = pflags;
+	p->msg = msg;
 
 	man_alloc1(p);
 	return(p);
@@ -375,7 +351,7 @@ man_ptext(struct man *m, int line, char 
 	if ('\\' == buf[offs] && 
 			'.' == buf[offs + 1] && 
 			'"' == buf[offs + 2])
-		return(man_pwarn(m, line, offs, WBADCOMMENT));
+		return(man_pmsg(m, line, offs, MANDOCERR_BADCOMMENT));
 
 	/* Literal free-form text whitespace is preserved. */
 
@@ -407,7 +383,7 @@ man_ptext(struct man *m, int line, char 
 
 	if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
 		if (i > 1 && '\\' != buf[i - 2])
-			if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+			if ( ! man_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE))
 				return(0);
 
 		for (--i; i && ' ' == buf[i]; i--)
@@ -441,7 +417,7 @@ descope:
 
 	if (MAN_ELINE & m->flags) {
 		m->flags &= ~MAN_ELINE;
-		if ( ! man_unscope(m, m->last->parent, WERRMAX))
+		if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
 			return(0);
 	}
 
@@ -449,7 +425,7 @@ descope:
 		return(1);
 	m->flags &= ~MAN_BLINE;
 
-	if ( ! man_unscope(m, m->last->parent, WERRMAX))
+	if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
 		return(0);
 	return(man_body_alloc(m, line, offs, m->last->tok));
 }
@@ -458,11 +434,13 @@ descope:
 static int
 macrowarn(struct man *m, int ln, const char *buf, int offs)
 {
-	if ( ! (MAN_IGN_MACRO & m->pflags))
-		return(man_verr(m, ln, offs, "unknown macro: %s%s", 
-				buf, strlen(buf) > 3 ? "..." : ""));
-	return(man_vwarn(m, ln, offs, "unknown macro: %s%s",
-				buf, strlen(buf) > 3 ? "..." : ""));
+	int		 rc;
+
+	rc = man_vmsg(m, MANDOCERR_MACRO, ln, offs, 
+			"unknown macro: %s%s",
+			buf, strlen(buf) > 3 ? "..." : "");
+
+	return(MAN_IGN_MACRO & m->pflags ? rc : 0);
 }
 
 
@@ -510,17 +488,15 @@ man_pmacro(struct man *m, int ln, char *
 
 		if (isgraph((u_char)buf[i]))
 			continue;
-		return(man_perr(m, ln, i, WNPRINT));
+		if ( ! man_pmsg(m, ln, i, MANDOCERR_BADCHAR))
+			return(0);
+		i--;
 	}
 
 	mac[j] = '\0';
 
 	if (j == 4 || j < 1) {
-		if ( ! (MAN_IGN_MACRO & m->pflags)) {
-			(void)man_perr(m, ln, ppos, WMACROFORM);
-			goto err;
-		} 
-		if ( ! man_pwarn(m, ln, ppos, WMACROFORM))
+		if ( ! macrowarn(m, ln, mac, ppos))
 			goto err;
 		return(1);
 	}
@@ -542,7 +518,7 @@ man_pmacro(struct man *m, int ln, char *
 	 */
 
 	if ('\0' == buf[i] && ' ' == buf[i - 1])
-		if ( ! man_pwarn(m, ln, i - 1, WTSPACE))
+		if ( ! man_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE))
 			goto err;
 
 	/* 
@@ -564,8 +540,10 @@ man_pmacro(struct man *m, int ln, char *
 		 *   I hate man macros.
 		 * Flat-out disallow this madness.
 		 */
-		if (MAN_NSCOPED & man_macros[m->last->tok].flags)
-			return(man_perr(m, ln, ppos, WLNSCOPE));
+		if (MAN_NSCOPED & man_macros[m->last->tok].flags) {
+			man_pmsg(m, ln, ppos, MANDOCERR_SYNTLINESCOPE);
+			return(0);
+		}
 
 		n = m->last;
 
@@ -573,7 +551,7 @@ man_pmacro(struct man *m, int ln, char *
 		assert(NULL == n->child);
 		assert(0 == n->nchild);
 
-		if ( ! man_nwarn(m, n, WLNSCOPE))
+		if ( ! man_nmsg(m, n, MANDOCERR_LINESCOPE))
 			return(0);
 
 		man_node_delete(m, n);
@@ -630,7 +608,7 @@ out:
 	assert(MAN_BLINE & m->flags);
 	m->flags &= ~MAN_BLINE;
 
-	if ( ! man_unscope(m, m->last->parent, WERRMAX))
+	if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
 		return(0);
 	return(man_body_alloc(m, ln, offs, m->last->tok));
 
@@ -642,49 +620,16 @@ err:	/* Error out. */
 
 
 int
-man_verr(struct man *man, int ln, int pos, const char *fmt, ...)
-{
-	char		 buf[256];
-	va_list		 ap;
-
-	if (NULL == man->cb.man_err)
-		return(0);
-
-	va_start(ap, fmt);
-	(void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
-	va_end(ap);
-	return((*man->cb.man_err)(man->data, ln, pos, buf));
-}
-
-
-int
-man_vwarn(struct man *man, int ln, int pos, const char *fmt, ...)
+man_vmsg(struct man *man, enum mandocerr t, 
+		int ln, int pos, const char *fmt, ...)
 {
 	char		 buf[256];
 	va_list		 ap;
 
-	if (NULL == man->cb.man_warn)
-		return(0);
-
 	va_start(ap, fmt);
-	(void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+	vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
 	va_end(ap);
-	return((*man->cb.man_warn)(man->data, ln, pos, buf));
-}
-
-
-int
-man_err(struct man *m, int line, int pos, int iserr, enum merr type)
-{
-	const char	 *p;
-	
-	p = __man_merrnames[(int)type];
-	assert(p);
-
-	if (iserr)
-		return(man_verr(m, line, pos, p));
-
-	return(man_vwarn(m, line, pos, p));
+	return((*man->msg)(t, man->data, ln, pos, buf));
 }
 
 
Index: mdoc.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.c,v
retrieving revision 1.135
retrieving revision 1.136
diff -Lmdoc.c -Lmdoc.c -u -p -r1.135 -r1.136
--- mdoc.c
+++ mdoc.c
@@ -28,64 +28,10 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
-const	char *const __mdoc_merrnames[MERRMAX] = {		 
-	"trailing whitespace", /* ETAILWS */
-	"unexpected quoted parameter", /* EQUOTPARM */
-	"unterminated quoted parameter", /* EQUOTTERM */
-	"argument parameter suggested", /* EARGVAL */
-	"macro disallowed in prologue", /* EBODYPROL */
-	"macro disallowed in body", /* EPROLBODY */
-	"text disallowed in prologue", /* ETEXTPROL */
-	"blank line disallowed", /* ENOBLANK */
-	"text parameter too long", /* ETOOLONG */
-	"invalid escape sequence", /* EESCAPE */
-	"invalid character", /* EPRINT */
-	"document has no body", /* ENODAT */
-	"document has no prologue", /* ENOPROLOGUE */
-	"expected line arguments", /* ELINE */
-	"invalid AT&T argument", /* EATT */
-	"default name not yet set", /* ENAME */
-	"missing list type", /* ELISTTYPE */
-	"missing display type", /* EDISPTYPE */
-	"too many display types", /* EMULTIDISP */
-	"too many list types", /* EMULTILIST */
-	"NAME section must be first", /* ESECNAME */
-	"badly-formed NAME section", /* ENAMESECINC */
-	"argument repeated", /* EARGREP */
-	"expected boolean parameter", /* EBOOL */
-	"inconsistent column syntax", /* ECOLMIS */
-	"nested display invalid", /* ENESTDISP */
-	"width argument missing", /* EMISSWIDTH */
-	"invalid section for this manual section", /* EWRONGMSEC */
-	"section out of conventional order", /* ESECOOO */
-	"section repeated", /* ESECREP */
-	"invalid standard argument", /* EBADSTAND */
-	"multi-line arguments discouraged", /* ENOMULTILINE */
-	"multi-line arguments suggested", /* EMULTILINE */
-	"line arguments discouraged", /* ENOLINE */
-	"prologue macro out of conventional order", /* EPROLOOO */
-	"prologue macro repeated", /* EPROLREP */
-	"invalid manual section", /* EBADMSEC */
-	"invalid font mode", /* EFONT */
-	"invalid date syntax", /* EBADDATE */
-	"invalid number format", /* ENUMFMT */
-	"superfluous width argument", /* ENOWIDTH */
-	"system: utsname error", /* EUTSNAME */
-	"obsolete macro", /* EOBS */
-	"end-of-line scope violation", /* EIMPBRK */
-	"empty macro ignored", /* EIGNE */
-	"unclosed explicit scope", /* EOPEN */
-	"unterminated quoted phrase", /* EQUOTPHR */
-	"closure macro without prior context", /* ENOCTX */
-	"no description found for library", /* ELIB */
-	"bad child for parent context", /* EBADCHILD */
-	"list arguments preceding type", /* ENOTYPE */
-	"deprecated comment style", /* EBADCOMMENT */
-};
-
 const	char *const __mdoc_macronames[MDOC_MAX] = {		 
 	"Ap",		"Dd",		"Dt",		"Os",
 	"Sh",		"Ss",		"Pp",		"D1",
@@ -245,15 +191,13 @@ mdoc_free(struct mdoc *mdoc)
  * Allocate volatile and non-volatile parse resources.  
  */
 struct mdoc *
-mdoc_alloc(void *data, int pflags, const struct mdoc_cb *cb)
+mdoc_alloc(void *data, int pflags, mandocmsg msg)
 {
 	struct mdoc	*p;
 
 	p = mandoc_calloc(1, sizeof(struct mdoc));
 
-	if (cb)
-		memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
-
+	p->msg = msg;
 	p->data = data;
 	p->pflags = pflags;
 
@@ -299,52 +243,17 @@ mdoc_parseln(struct mdoc *m, int ln, cha
 
 
 int
-mdoc_verr(struct mdoc *mdoc, int ln, int pos, 
-		const char *fmt, ...)
-{
-	char		 buf[256];
-	va_list		 ap;
-
-	if (NULL == mdoc->cb.mdoc_err)
-		return(0);
-
-	va_start(ap, fmt);
-	(void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
-	va_end(ap);
-
-	return((*mdoc->cb.mdoc_err)(mdoc->data, ln, pos, buf));
-}
-
-
-int
-mdoc_vwarn(struct mdoc *mdoc, int ln, int pos, const char *fmt, ...)
+mdoc_vmsg(struct mdoc *mdoc, enum mandocerr t, 
+		int ln, int pos, const char *fmt, ...)
 {
 	char		 buf[256];
 	va_list		 ap;
 
-	if (NULL == mdoc->cb.mdoc_warn)
-		return(0);
-
 	va_start(ap, fmt);
-	(void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+	vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
 	va_end(ap);
 
-	return((*mdoc->cb.mdoc_warn)(mdoc->data, ln, pos, buf));
-}
-
-
-int
-mdoc_err(struct mdoc *m, int line, int pos, int iserr, enum merr type)
-{
-	const char	*p;
-
-	p = __mdoc_merrnames[(int)type];
-	assert(p);
-
-	if (iserr)
-		return(mdoc_verr(m, line, pos, p));
-
-	return(mdoc_vwarn(m, line, pos, p));
+	return((*mdoc->msg)(t, mdoc->data, ln, pos, buf));
 }
 
 
@@ -358,13 +267,13 @@ mdoc_macro(struct mdoc *m, enum mdoct to
 
 	if (MDOC_PROLOGUE & mdoc_macros[tok].flags && 
 			MDOC_PBODY & m->flags)
-		return(mdoc_perr(m, ln, pp, EPROLBODY));
+		return(mdoc_pmsg(m, ln, pp, MANDOCERR_BADBODY));
 
 	/* If we're in the prologue, deny "body" macros.  */
 
 	if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && 
 			! (MDOC_PBODY & m->flags)) {
-		if ( ! mdoc_pwarn(m, ln, pp, EBODYPROL))
+		if ( ! mdoc_pmsg(m, ln, pp, MANDOCERR_BADPROLOG))
 			return(0);
 		if (NULL == m->meta.title)
 			m->meta.title = mandoc_strdup("unknown");
@@ -640,12 +549,12 @@ mdoc_ptext(struct mdoc *m, int line, cha
 	if ('\\' == buf[offs] && 
 			'.' == buf[offs + 1] && 
 			'"' == buf[offs + 2])
-		return(mdoc_pwarn(m, line, offs, EBADCOMMENT));
+		return(mdoc_pmsg(m, line, offs, MANDOCERR_BADCOMMENT));
 
 	/* No text before an initial macro. */
 
 	if (SEC_NONE == m->lastnamed)
-		return(mdoc_perr(m, line, offs, ETEXTPROL));
+		return(mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT));
 
 	/* Literal just gets pulled in as-is. */
 	
@@ -658,7 +567,7 @@ mdoc_ptext(struct mdoc *m, int line, cha
 		/* Skip to first non-space. */ ;
 
 	if ('\0' == buf[i]) {
-		if ( ! mdoc_pwarn(m, line, offs, ENOBLANK))
+		if ( ! mdoc_pmsg(m, line, offs, MANDOCERR_NOBLANKLN))
 			return(0);
 
 		/*
@@ -683,7 +592,7 @@ mdoc_ptext(struct mdoc *m, int line, cha
 
 	if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
 		if (i > 1 && '\\' != buf[i - 2])
-			if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
+			if ( ! mdoc_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE))
 				return(0);
 
 		for (--i; i && ' ' == buf[i]; i--)
@@ -717,11 +626,14 @@ mdoc_ptext(struct mdoc *m, int line, cha
 static int
 macrowarn(struct mdoc *m, int ln, const char *buf, int offs)
 {
-	if ( ! (MDOC_IGN_MACRO & m->pflags))
-		return(mdoc_verr(m, ln, offs, "unknown macro: %s%s", 
-				buf, strlen(buf) > 3 ? "..." : ""));
-	return(mdoc_vwarn(m, ln, offs, "unknown macro: %s%s",
-				buf, strlen(buf) > 3 ? "..." : ""));
+	int		 rc;
+
+	rc = mdoc_vmsg(m, MANDOCERR_MACRO, ln, offs, 
+			"unknown macro: %s%s", 
+			buf, strlen(buf) > 3 ? "..." : "");
+
+	/* FIXME: logic should be in driver. */
+	return(MDOC_IGN_MACRO & m->pflags ? rc : 0);
 }
 
 
@@ -769,7 +681,9 @@ mdoc_pmacro(struct mdoc *m, int ln, char
 
 		if (isgraph((u_char)buf[i]))
 			continue;
-		return(mdoc_perr(m, ln, i, EPRINT));
+		if ( ! mdoc_pmsg(m, ln, i, MANDOCERR_BADCHAR))
+			return(0);
+		i--;
 	}
 
 	mac[j] = '\0';
@@ -797,7 +711,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char
 	 */
 
 	if ('\0' == buf[i] && ' ' == buf[i - 1])
-		if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS))
+		if ( ! mdoc_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE))
 			goto err;
 
 	/* 
Index: att.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/att.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Latt.c -Latt.c -u -p -r1.6 -r1.7
--- att.c
+++ att.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: man_term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_term.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -Lman_term.c -Lman_term.c -u -p -r1.70 -r1.71
--- man_term.c
+++ man_term.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "man.h"
 #include "term.h"
Index: mdoc_macro.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_macro.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -Lmdoc_macro.c -Lmdoc_macro.c -u -p -r1.67 -r1.68
--- mdoc_macro.c
+++ mdoc_macro.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
@@ -195,6 +196,7 @@ swarn(struct mdoc *mdoc, enum mdoc_type 
 		int line, int pos, const struct mdoc_node *p)
 {
 	const char	*n, *t, *tt;
+	int		 rc;
 
 	n = t = "<root>";
 	tt = "block";
@@ -227,13 +229,11 @@ swarn(struct mdoc *mdoc, enum mdoc_type 
 		break;
 	}
 
-	if ( ! (MDOC_IGN_SCOPE & mdoc->pflags))
-		return(mdoc_verr(mdoc, line, pos, 
-				"%s scope breaks %s scope of %s", 
-				tt, t, n));
-	return(mdoc_vwarn(mdoc, line, pos, 
-				"%s scope breaks %s scope of %s", 
-				tt, t, n));
+	rc = mdoc_vmsg(mdoc, MANDOCERR_SCOPE, line, pos,
+			"%s scope breaks %s of %s", tt, t, n);
+
+	/* FIXME: logic should be in driver. */
+	return(MDOC_IGN_SCOPE & mdoc->pflags ? rc : 0);
 }
 
 
@@ -256,7 +256,8 @@ mdoc_macroend(struct mdoc *m)
 			continue;
 		if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags))
 			continue;
-		return(mdoc_nerr(m, n, EOPEN));
+		mdoc_nmsg(m, n, MANDOCERR_SYNTSCOPE);
+		return(0);
 	}
 
 	/* Rewind to the first. */
@@ -588,7 +589,9 @@ rew_sub(enum mdoc_type t, struct mdoc *m
 				return(1);
 			if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
 				return(1);
-			return(mdoc_perr(m, line, ppos, ENOCTX));
+			/* FIXME: shouldn't raise an error */
+			mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTNOSCOPE);
+			return(0);
 		}
 		if (REWIND_REWIND == c)
 			break;
@@ -686,8 +689,9 @@ blk_exp_close(MACRO_PROT_ARGS)
 	}
 
 	if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
+		/* FIXME: do this in validate */
 		if (buf[*pos]) 
-			if ( ! mdoc_pwarn(m, line, ppos, ENOLINE))
+			if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST))
 				return(0);
 
 		if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
@@ -831,7 +835,7 @@ in_line(MACRO_PROT_ARGS)
 					return(0);
 			} else if ( ! nc && 0 == cnt) {
 				mdoc_argv_free(arg);
-				if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
+				if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY))
 					return(0);
 			}
 			if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
@@ -892,7 +896,7 @@ in_line(MACRO_PROT_ARGS)
 			return(0);
 	} else if ( ! nc && 0 == cnt) {
 		mdoc_argv_free(arg);
-		if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
+		if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY))
 			return(0);
 	}
 
@@ -1198,7 +1202,7 @@ blk_part_imp(MACRO_PROT_ARGS)
 		if (body == n)
 			break;
 
-	if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK))
+	if (NULL == n && ! mdoc_nmsg(m, body, MANDOCERR_SCOPE))
 		return(0);
 
 	if (n && ! rew_last(m, body))
@@ -1564,7 +1568,7 @@ static int
 obsolete(MACRO_PROT_ARGS)
 {
 
-	return(mdoc_pwarn(m, line, ppos, EOBS));
+	return(mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS));
 }
 
 
Index: mdoc_term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_term.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.124 -r1.125
--- mdoc_term.c
+++ mdoc_term.c
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "term.h"
 #include "mdoc.h"
@@ -1085,6 +1086,8 @@ static int
 termp_nm_pre(DECL_ARGS)
 {
 
+	if (NULL == n->child && NULL == m->name)
+
 	if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags)
 		term_newln(p);
 
@@ -1092,6 +1095,7 @@ termp_nm_pre(DECL_ARGS)
 
 	if (NULL == n->child)
 		term_word(p, m->name);
+
 	return(1);
 }
 
@@ -1216,7 +1220,7 @@ termp_rv_pre(DECL_ARGS)
 			term_word(p, "()");
 	}
 
-	if (n->child->next)
+	if (n->child && n->child->next)
 		term_word(p, "functions return");
 	else
 		term_word(p, "function returns");
@@ -1255,7 +1259,7 @@ termp_ex_pre(DECL_ARGS)
 			p->flags &= ~TERMP_NOSPACE;
 	}
 
-	if (n->child->next)
+	if (n->child && n->child->next)
 		term_word(p, "utilities exit");
 	else
 		term_word(p, "utility exits");
Index: msec.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/msec.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -Lmsec.c -Lmsec.c -u -p -r1.7 -r1.8
--- msec.c
+++ msec.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 #define LINE(x, y) \
Index: man_hash.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_hash.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -Lman_hash.c -Lman_hash.c -u -p -r1.20 -r1.21
--- man_hash.c
+++ man_hash.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libman.h"
 
 #define	HASH_DEPTH	 6
Index: tree.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/tree.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -Ltree.c -Ltree.c -u -p -r1.19 -r1.20
--- tree.c
+++ tree.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "mdoc.h"
 #include "man.h"
 #include "main.h"
Index: mdoc_strings.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_strings.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -Lmdoc_strings.c -Lmdoc_strings.c -u -p -r1.21 -r1.22
--- mdoc_strings.c
+++ mdoc_strings.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 
 static	const char * const secnames[SEC__MAX] = {
Index: man_macro.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man_macro.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -Lman_macro.c -Lman_macro.c -u -p -r1.45 -r1.46
--- man_macro.c
+++ man_macro.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "libman.h"
 
 enum	rew {
@@ -43,7 +44,7 @@ static	enum rew	 rew_dohalt(enum mant, e
 static	enum rew	 rew_block(enum mant, enum man_type, 
 				const struct man_node *);
 static	int		 rew_warn(struct man *, 
-				struct man_node *, enum merr);
+				struct man_node *, enum mandocerr);
 
 const	struct man_macro __man_macros[MAN_MAX] = {
 	{ in_line_eoln, MAN_NSCOPED }, /* br */
@@ -91,25 +92,26 @@ const	struct man_macro * const man_macro
  * Warn when "n" is an explicit non-roff macro.
  */
 static int
-rew_warn(struct man *m, struct man_node *n, enum merr er)
+rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
 {
 
-	if (er == WERRMAX || MAN_BLOCK != n->type)
+	if (er == MANDOCERR_MAX || MAN_BLOCK != n->type)
 		return(1);
 	if (MAN_VALID & n->flags)
 		return(1);
 	if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags))
 		return(1);
-	return(man_nwarn(m, n, er));
+	return(man_nmsg(m, n, er));
 }
 
 
 /*
- * Rewind scope.  If a code "er" != WERRMAX has been provided, it will
- * be used if an explicit block scope is being closed out.
+ * Rewind scope.  If a code "er" != MANDOCERR_MAX has been provided, it
+ * will be used if an explicit block scope is being closed out.
  */
 int
-man_unscope(struct man *m, const struct man_node *n, enum merr er)
+man_unscope(struct man *m, const struct man_node *n, 
+		enum mandocerr er)
 {
 
 	assert(n);
@@ -248,7 +250,7 @@ rew_scope(enum man_type type, struct man
 	 */
 	assert(n);
 
-	return(man_unscope(m, n, WERRMAX));
+	return(man_unscope(m, n, MANDOCERR_MAX));
 }
 
 
@@ -276,7 +278,7 @@ blk_close(MACRO_PROT_ARGS)
 			break;
 
 	if (NULL == nn)
-		if ( ! man_pwarn(m, line, ppos, WNOSCOPE))
+		if ( ! man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE))
 			return(0);
 
 	if ( ! rew_scope(MAN_BODY, m, ntok))
@@ -478,6 +480,6 @@ int
 man_macroend(struct man *m)
 {
 
-	return(man_unscope(m, m->first, WEXITSCOPE));
+	return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT));
 }
 
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

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

only message in thread, other threads:[~2010-05-17 22:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-17 22:11 mdocml: Enable the unified error/warning enumeration in mandoc.h that's kristaps

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).