X-Git-Url: https://git.cameronkatri.com/mandoc.git/blobdiff_plain/2a37145b398147deef315887314495f6a9b9637e..3d673e1a84f7b7f238eeab1d52469fc06197bce1:/mdoc_validate.c?ds=sidebyside

diff --git a/mdoc_validate.c b/mdoc_validate.c
index a566ad00..0f5cf5c5 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,4 +1,4 @@
-/*	$Id: mdoc_validate.c,v 1.249 2014/09/12 00:54:10 schwarze Exp $ */
+/*	$Id: mdoc_validate.c,v 1.265 2014/12/18 20:15:56 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -53,15 +53,15 @@ enum	check_lvl {
 	CHECK_ERROR,
 };
 
-typedef	int	(*v_pre)(PRE_ARGS);
-typedef	int	(*v_post)(POST_ARGS);
+typedef	void	(*v_pre)(PRE_ARGS);
+typedef	void	(*v_post)(POST_ARGS);
 
 struct	valids {
 	v_pre	 pre;
 	v_post	 post;
 };
 
-static	int	 check_count(struct mdoc *, enum mdoc_type,
+static	void	 check_count(struct mdoc *, enum mdoc_type,
 			enum check_lvl, enum check_ineq, int);
 static	void	 check_text(struct mdoc *, int, int, char *);
 static	void	 check_argv(struct mdoc *,
@@ -70,69 +70,67 @@ static	void	 check_args(struct mdoc *, struct mdoc_node *);
 static	int	 child_an(const struct mdoc_node *);
 static	enum mdoc_sec	a2sec(const char *);
 static	size_t		macro2len(enum mdoct);
-
-static	int	 ebool(POST_ARGS);
-static	int	 berr_ge1(POST_ARGS);
-static	int	 bwarn_ge1(POST_ARGS);
-static	int	 ewarn_eq0(POST_ARGS);
-static	int	 ewarn_eq1(POST_ARGS);
-static	int	 ewarn_ge1(POST_ARGS);
-static	int	 ewarn_le1(POST_ARGS);
-static	int	 hwarn_eq0(POST_ARGS);
-static	int	 hwarn_eq1(POST_ARGS);
-static	int	 hwarn_ge1(POST_ARGS);
-
-static	int	 post_an(POST_ARGS);
-static	int	 post_at(POST_ARGS);
-static	int	 post_bf(POST_ARGS);
-static	int	 post_bk(POST_ARGS);
-static	int	 post_bl(POST_ARGS);
-static	int	 post_bl_block(POST_ARGS);
-static	int	 post_bl_block_width(POST_ARGS);
-static	int	 post_bl_block_tag(POST_ARGS);
-static	int	 post_bl_head(POST_ARGS);
-static	int	 post_bx(POST_ARGS);
-static	int	 post_d1(POST_ARGS);
-static	int	 post_defaults(POST_ARGS);
-static	int	 post_dd(POST_ARGS);
-static	int	 post_dt(POST_ARGS);
-static	int	 post_en(POST_ARGS);
-static	int	 post_es(POST_ARGS);
-static	int	 post_eoln(POST_ARGS);
-static	int	 post_ex(POST_ARGS);
-static	int	 post_fa(POST_ARGS);
-static	int	 post_fo(POST_ARGS);
-static	int	 post_hyph(POST_ARGS);
-static	int	 post_hyphtext(POST_ARGS);
-static	int	 post_ignpar(POST_ARGS);
-static	int	 post_it(POST_ARGS);
-static	int	 post_lb(POST_ARGS);
-static	int	 post_literal(POST_ARGS);
-static	int	 post_nd(POST_ARGS);
-static	int	 post_nm(POST_ARGS);
-static	int	 post_ns(POST_ARGS);
-static	int	 post_os(POST_ARGS);
-static	int	 post_par(POST_ARGS);
-static	int	 post_root(POST_ARGS);
-static	int	 post_rs(POST_ARGS);
-static	int	 post_sh(POST_ARGS);
-static	int	 post_sh_head(POST_ARGS);
-static	int	 post_sh_name(POST_ARGS);
-static	int	 post_sh_see_also(POST_ARGS);
-static	int	 post_sh_authors(POST_ARGS);
-static	int	 post_st(POST_ARGS);
-static	int	 post_vt(POST_ARGS);
-static	int	 pre_an(PRE_ARGS);
-static	int	 pre_bd(PRE_ARGS);
-static	int	 pre_bl(PRE_ARGS);
-static	int	 pre_dd(PRE_ARGS);
-static	int	 pre_display(PRE_ARGS);
-static	int	 pre_dt(PRE_ARGS);
-static	int	 pre_literal(PRE_ARGS);
-static	int	 pre_obsolete(PRE_ARGS);
-static	int	 pre_os(PRE_ARGS);
-static	int	 pre_par(PRE_ARGS);
-static	int	 pre_std(PRE_ARGS);
+static	void	 rewrite_macro2len(char **);
+
+static	void	 bwarn_ge1(POST_ARGS);
+static	void	 ewarn_eq1(POST_ARGS);
+static	void	 ewarn_ge1(POST_ARGS);
+static	void	 hwarn_eq0(POST_ARGS);
+
+static	void	 post_an(POST_ARGS);
+static	void	 post_at(POST_ARGS);
+static	void	 post_bf(POST_ARGS);
+static	void	 post_bk(POST_ARGS);
+static	void	 post_bl(POST_ARGS);
+static	void	 post_bl_block(POST_ARGS);
+static	void	 post_bl_block_tag(POST_ARGS);
+static	void	 post_bl_head(POST_ARGS);
+static	void	 post_bx(POST_ARGS);
+static	void	 post_d1(POST_ARGS);
+static	void	 post_defaults(POST_ARGS);
+static	void	 post_dd(POST_ARGS);
+static	void	 post_dt(POST_ARGS);
+static	void	 post_en(POST_ARGS);
+static	void	 post_es(POST_ARGS);
+static	void	 post_eoln(POST_ARGS);
+static	void	 post_ex(POST_ARGS);
+static	void	 post_fa(POST_ARGS);
+static	void	 post_fn(POST_ARGS);
+static	void	 post_fname(POST_ARGS);
+static	void	 post_fo(POST_ARGS);
+static	void	 post_hyph(POST_ARGS);
+static	void	 post_hyphtext(POST_ARGS);
+static	void	 post_ignpar(POST_ARGS);
+static	void	 post_it(POST_ARGS);
+static	void	 post_lb(POST_ARGS);
+static	void	 post_literal(POST_ARGS);
+static	void	 post_nd(POST_ARGS);
+static	void	 post_nm(POST_ARGS);
+static	void	 post_ns(POST_ARGS);
+static	void	 post_os(POST_ARGS);
+static	void	 post_par(POST_ARGS);
+static	void	 post_root(POST_ARGS);
+static	void	 post_rs(POST_ARGS);
+static	void	 post_sh(POST_ARGS);
+static	void	 post_sh_head(POST_ARGS);
+static	void	 post_sh_name(POST_ARGS);
+static	void	 post_sh_see_also(POST_ARGS);
+static	void	 post_sh_authors(POST_ARGS);
+static	void	 post_sm(POST_ARGS);
+static	void	 post_st(POST_ARGS);
+static	void	 post_vt(POST_ARGS);
+
+static	void	 pre_an(PRE_ARGS);
+static	void	 pre_bd(PRE_ARGS);
+static	void	 pre_bl(PRE_ARGS);
+static	void	 pre_dd(PRE_ARGS);
+static	void	 pre_display(PRE_ARGS);
+static	void	 pre_dt(PRE_ARGS);
+static	void	 pre_literal(PRE_ARGS);
+static	void	 pre_obsolete(PRE_ARGS);
+static	void	 pre_os(PRE_ARGS);
+static	void	 pre_par(PRE_ARGS);
+static	void	 pre_std(PRE_ARGS);
 
 static	const struct valids mdoc_valids[MDOC_MAX] = {
 	{ NULL, NULL },				/* Ap */
@@ -161,7 +159,7 @@ static	const struct valids mdoc_valids[MDOC_MAX] = {
 	{ NULL, post_fa },			/* Fa */
 	{ NULL, ewarn_ge1 },			/* Fd */
 	{ NULL, NULL },				/* Fl */
-	{ NULL, post_fa },			/* Fn */
+	{ NULL, post_fn },			/* Fn */
 	{ NULL, NULL },				/* Ft */
 	{ NULL, NULL },				/* Ic */
 	{ NULL, ewarn_eq1 },			/* In */
@@ -197,7 +195,7 @@ static	const struct valids mdoc_valids[MDOC_MAX] = {
 	{ NULL, NULL },				/* Bq */
 	{ NULL, NULL },				/* Bsx */
 	{ NULL, post_bx },			/* Bx */
-	{ NULL, ebool },			/* Db */
+	{ pre_obsolete, NULL },			/* Db */
 	{ NULL, NULL },				/* Dc */
 	{ NULL, NULL },				/* Do */
 	{ NULL, NULL },				/* Dq */
@@ -207,12 +205,12 @@ static	const struct valids mdoc_valids[MDOC_MAX] = {
 	{ NULL, NULL },				/* Eo */
 	{ NULL, NULL },				/* Fx */
 	{ NULL, NULL },				/* Ms */
-	{ NULL, ewarn_eq0 },			/* No */
+	{ NULL, NULL },				/* No */
 	{ NULL, post_ns },			/* Ns */
 	{ NULL, NULL },				/* Nx */
 	{ NULL, NULL },				/* Ox */
 	{ NULL, NULL },				/* Pc */
-	{ NULL, ewarn_eq1 },			/* Pf */
+	{ NULL, NULL },				/* Pf */
 	{ NULL, NULL },				/* Po */
 	{ NULL, NULL },				/* Pq */
 	{ NULL, NULL },				/* Qc */
@@ -224,7 +222,7 @@ static	const struct valids mdoc_valids[MDOC_MAX] = {
 	{ NULL, NULL },				/* Sc */
 	{ NULL, NULL },				/* So */
 	{ NULL, NULL },				/* Sq */
-	{ NULL, ebool },			/* Sm */
+	{ NULL, post_sm },			/* Sm */
 	{ NULL, post_hyph },			/* Sx */
 	{ NULL, NULL },				/* Sy */
 	{ NULL, NULL },				/* Tn */
@@ -306,7 +304,7 @@ static	const char * const secnames[SEC__MAX] = {
 };
 
 
-int
+void
 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
 {
 	v_pre	 p;
@@ -320,17 +318,18 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
 	case MDOC_EQN:
 		/* FALLTHROUGH */
 	case MDOC_ROOT:
-		return(1);
+		return;
 	default:
 		break;
 	}
 
 	check_args(mdoc, n);
 	p = mdoc_valids[n->tok].pre;
-	return(*p ? (*p)(mdoc, n) : 1);
+	if (*p)
+		(*p)(mdoc, n);
 }
 
-int
+void
 mdoc_valid_post(struct mdoc *mdoc)
 {
 	struct mdoc_node *n;
@@ -338,7 +337,7 @@ mdoc_valid_post(struct mdoc *mdoc)
 
 	n = mdoc->last;
 	if (n->flags & MDOC_VALID)
-		return(1);
+		return;
 	n->flags |= MDOC_VALID;
 
 	switch (n->type) {
@@ -347,16 +346,33 @@ mdoc_valid_post(struct mdoc *mdoc)
 	case MDOC_EQN:
 		/* FALLTHROUGH */
 	case MDOC_TBL:
-		return(1);
+		break;
 	case MDOC_ROOT:
-		return(post_root(mdoc));
+		post_root(mdoc);
+		break;
 	default:
+
+		/*
+		 * Closing delimiters are not special at the
+		 * beginning of a block, opening delimiters
+		 * are not special at the end.
+		 */
+
+		if (n->child != NULL)
+			n->child->flags &= ~MDOC_DELIMC;
+		if (n->last != NULL)
+			n->last->flags &= ~MDOC_DELIMO;
+
+		/* Call the macro's postprocessor. */
+
 		p = mdoc_valids[n->tok].post;
-		return(*p ? (*p)(mdoc) : 1);
+		if (*p)
+			(*p)(mdoc);
+		break;
 	}
 }
 
-static int
+static void
 check_count(struct mdoc *mdoc, enum mdoc_type type,
 		enum check_lvl lvl, enum check_ineq ineq, int val)
 {
@@ -364,23 +380,23 @@ check_count(struct mdoc *mdoc, enum mdoc_type type,
 	enum mandocerr	 t;
 
 	if (mdoc->last->type != type)
-		return(1);
+		return;
 
 	switch (ineq) {
 	case CHECK_LT:
 		p = "less than ";
 		if (mdoc->last->nchild < val)
-			return(1);
+			return;
 		break;
 	case CHECK_GT:
 		p = "more than ";
 		if (mdoc->last->nchild > val)
-			return(1);
+			return;
 		break;
 	case CHECK_EQ:
 		p = "";
 		if (val == mdoc->last->nchild)
-			return(1);
+			return;
 		break;
 	default:
 		abort();
@@ -391,62 +407,30 @@ check_count(struct mdoc *mdoc, enum mdoc_type type,
 	mandoc_vmsg(t, mdoc->parse, mdoc->last->line,
 	    mdoc->last->pos, "want %s%d children (have %d)",
 	    p, val, mdoc->last->nchild);
-	return(1);
 }
 
-static int
-berr_ge1(POST_ARGS)
-{
-
-	return(check_count(mdoc, MDOC_BODY, CHECK_ERROR, CHECK_GT, 0));
-}
-
-static int
+static void
 bwarn_ge1(POST_ARGS)
 {
-	return(check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0));
-}
-
-static int
-ewarn_eq0(POST_ARGS)
-{
-	return(check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0));
+	check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0);
 }
 
-static int
+static void
 ewarn_eq1(POST_ARGS)
 {
-	return(check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1));
+	check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1);
 }
 
-static int
+static void
 ewarn_ge1(POST_ARGS)
 {
-	return(check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0));
+	check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0);
 }
 
-static int
-ewarn_le1(POST_ARGS)
-{
-	return(check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2));
-}
-
-static int
+static void
 hwarn_eq0(POST_ARGS)
 {
-	return(check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0));
-}
-
-static int
-hwarn_eq1(POST_ARGS)
-{
-	return(check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 1));
-}
-
-static int
-hwarn_ge1(POST_ARGS)
-{
-	return(check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_GT, 0));
+	check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0);
 }
 
 static void
@@ -484,13 +468,13 @@ check_text(struct mdoc *mdoc, int ln, int pos, char *p)
 		    ln, pos + (int)(p - cp), NULL);
 }
 
-static int
+static void
 pre_display(PRE_ARGS)
 {
 	struct mdoc_node *node;
 
 	if (MDOC_BLOCK != n->type)
-		return(1);
+		return;
 
 	for (node = mdoc->last->parent; node; node = node->parent)
 		if (MDOC_BLOCK == node->type)
@@ -501,11 +485,9 @@ pre_display(PRE_ARGS)
 		mandoc_vmsg(MANDOCERR_BD_NEST,
 		    mdoc->parse, n->line, n->pos,
 		    "%s in Bd", mdoc_macronames[n->tok]);
-
-	return(1);
 }
 
-static int
+static void
 pre_bl(PRE_ARGS)
 {
 	struct mdoc_node *np;
@@ -524,7 +506,7 @@ pre_bl(PRE_ARGS)
 		assert(np);
 		assert(MDOC_BLOCK == np->type);
 		assert(MDOC_Bl == np->tok);
-		return(1);
+		return;
 	}
 
 	/*
@@ -595,6 +577,7 @@ pre_bl(PRE_ARGS)
 				    mdoc->parse, argv->line,
 				    argv->pos, "Bl -width %s",
 				    argv->value[0]);
+			rewrite_macro2len(argv->value);
 			n->norm->Bl.width = argv->value[0];
 			break;
 		case MDOC_Offset:
@@ -609,6 +592,7 @@ pre_bl(PRE_ARGS)
 				    mdoc->parse, argv->line,
 				    argv->pos, "Bl -offset %s",
 				    argv->value[0]);
+			rewrite_macro2len(argv->value);
 			n->norm->Bl.offs = argv->value[0];
 			break;
 		default:
@@ -693,11 +677,10 @@ pre_bl(PRE_ARGS)
 	default:
 		break;
 	}
-
-	return(pre_par(mdoc, n));
+	pre_par(mdoc, n);
 }
 
-static int
+static void
 pre_bd(PRE_ARGS)
 {
 	struct mdoc_node *np;
@@ -717,7 +700,7 @@ pre_bd(PRE_ARGS)
 		assert(np);
 		assert(MDOC_BLOCK == np->type);
 		assert(MDOC_Bd == np->tok);
-		return(1);
+		return;
 	}
 
 	for (i = 0; n->args && i < (int)n->args->argc; i++) {
@@ -743,7 +726,7 @@ pre_bd(PRE_ARGS)
 		case MDOC_File:
 			mandoc_msg(MANDOCERR_BD_FILE, mdoc->parse,
 			    n->line, n->pos, NULL);
-			return(0);
+			break;
 		case MDOC_Offset:
 			if (0 == argv->sz) {
 				mandoc_msg(MANDOCERR_ARG_EMPTY,
@@ -756,6 +739,7 @@ pre_bd(PRE_ARGS)
 				    mdoc->parse, argv->line,
 				    argv->pos, "Bd -offset %s",
 				    argv->value[0]);
+			rewrite_macro2len(argv->value);
 			n->norm->Bd.offs = argv->value[0];
 			break;
 		case MDOC_Compact:
@@ -785,18 +769,17 @@ pre_bd(PRE_ARGS)
 		    n->line, n->pos, "Bd");
 		n->norm->Bd.type = DISP_ragged;
 	}
-
-	return(pre_par(mdoc, n));
+	pre_par(mdoc, n);
 }
 
-static int
+static void
 pre_an(PRE_ARGS)
 {
 	struct mdoc_argv *argv;
 	size_t	 i;
 
 	if (n->args == NULL)
-		return(1);
+		return;
 
 	for (i = 1; i < n->args->argc; i++) {
 		argv = n->args->argv + i;
@@ -812,34 +795,30 @@ pre_an(PRE_ARGS)
 		n->norm->An.auth = AUTH_nosplit;
 	else
 		abort();
-
-	return(1);
 }
 
-static int
+static void
 pre_std(PRE_ARGS)
 {
 
 	if (n->args && 1 == n->args->argc)
 		if (MDOC_Std == n->args->argv[0].arg)
-			return(1);
+			return;
 
 	mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse,
 	    n->line, n->pos, mdoc_macronames[n->tok]);
-	return(1);
 }
 
-static int
+static void
 pre_obsolete(PRE_ARGS)
 {
 
 	if (MDOC_ELEM == n->type || MDOC_BLOCK == n->type)
 		mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse,
 		    n->line, n->pos, mdoc_macronames[n->tok]);
-	return(1);
 }
 
-static int
+static void
 pre_dt(PRE_ARGS)
 {
 
@@ -849,10 +828,9 @@ pre_dt(PRE_ARGS)
 	else if (mdoc->meta.os != NULL)
 		mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
 		    n->line, n->pos, "Dt after Os");
-	return(1);
 }
 
-static int
+static void
 pre_os(PRE_ARGS)
 {
 
@@ -862,10 +840,9 @@ pre_os(PRE_ARGS)
 	else if (mdoc->flags & MDOC_PBODY)
 		mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
 		    n->line, n->pos, "Os");
-	return(1);
 }
 
-static int
+static void
 pre_dd(PRE_ARGS)
 {
 
@@ -881,10 +858,9 @@ pre_dd(PRE_ARGS)
 	else if (mdoc->meta.os != NULL)
 		mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
 		    n->line, n->pos, "Dd after Os");
-	return(1);
 }
 
-static int
+static void
 post_bf(POST_ARGS)
 {
 	struct mdoc_node *np, *nch;
@@ -907,7 +883,7 @@ post_bf(POST_ARGS)
 		assert(np);
 		assert(MDOC_HEAD == np->type);
 		assert(MDOC_Bf == np->tok);
-		return(1);
+		return;
 	}
 
 	np = mdoc->last;
@@ -921,7 +897,7 @@ post_bf(POST_ARGS)
 		if (NULL == nch) {
 			mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse,
 			    np->line, np->pos, "Bf");
-			return(1);
+			return;
 		}
 		nch = nch->next;
 	}
@@ -941,7 +917,7 @@ post_bf(POST_ARGS)
 			np->norm->Bf.font = FONT_Sy;
 		else
 			abort();
-		return(1);
+		return;
 	}
 
 	/* Extract parameter into data. */
@@ -956,11 +932,9 @@ post_bf(POST_ARGS)
 		mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse,
 		    np->child->line, np->child->pos,
 		    "Bf %s", np->child->string);
-
-	return(1);
 }
 
-static int
+static void
 post_lb(POST_ARGS)
 {
 	struct mdoc_node	*n;
@@ -968,10 +942,7 @@ post_lb(POST_ARGS)
 	char			*libname;
 
 	check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1);
-
 	n = mdoc->last->child;
-
-	assert(n);
 	assert(MDOC_TEXT == n->type);
 
 	if (NULL == (stdlibname = mdoc_a2lib(n->string)))
@@ -982,10 +953,9 @@ post_lb(POST_ARGS)
 
 	free(n->string);
 	n->string = libname;
-	return(1);
 }
 
-static int
+static void
 post_eoln(POST_ARGS)
 {
 	const struct mdoc_node *n;
@@ -996,19 +966,42 @@ post_eoln(POST_ARGS)
 		    mdoc->parse, n->line, n->pos,
 		    "%s %s", mdoc_macronames[n->tok],
 		    n->child->string);
-	return(1);
 }
 
-static int
+static void
+post_fname(POST_ARGS)
+{
+	const struct mdoc_node	*n;
+	const char		*cp;
+	size_t			 pos;
+
+	n = mdoc->last->child;
+	pos = strcspn(n->string, "()");
+	cp = n->string + pos;
+	if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*')))
+		mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse,
+		    n->line, n->pos + pos, n->string);
+}
+
+static void
+post_fn(POST_ARGS)
+{
+
+	post_fname(mdoc);
+	post_fa(mdoc);
+}
+
+static void
 post_fo(POST_ARGS)
 {
 
-	hwarn_eq1(mdoc);
+	check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 1);
 	bwarn_ge1(mdoc);
-	return(1);
+	if (mdoc->last->type == MDOC_HEAD && mdoc->last->nchild)
+		post_fname(mdoc);
 }
 
-static int
+static void
 post_fa(POST_ARGS)
 {
 	const struct mdoc_node *n;
@@ -1027,10 +1020,9 @@ post_fa(POST_ARGS)
 			break;
 		}
 	}
-	return(1);
 }
 
-static int
+static void
 post_vt(POST_ARGS)
 {
 	const struct mdoc_node *n;
@@ -1044,48 +1036,45 @@ post_vt(POST_ARGS)
 	 */
 
 	if (MDOC_BODY != mdoc->last->type)
-		return(1);
+		return;
 
 	for (n = mdoc->last->child; n; n = n->next)
 		if (MDOC_TEXT != n->type)
 			mandoc_msg(MANDOCERR_VT_CHILD, mdoc->parse,
 			    n->line, n->pos, mdoc_macronames[n->tok]);
-
-	return(1);
 }
 
-static int
+static void
 post_nm(POST_ARGS)
 {
 
 	if (NULL != mdoc->meta.name)
-		return(1);
+		return;
 
 	mdoc_deroff(&mdoc->meta.name, mdoc->last);
 
 	if (NULL == mdoc->meta.name)
 		mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
 		    mdoc->last->line, mdoc->last->pos, "Nm");
-	return(1);
 }
 
-static int
+static void
 post_nd(POST_ARGS)
 {
 
-	berr_ge1(mdoc);
-	return(post_hyph(mdoc));
+	check_count(mdoc, MDOC_BODY, CHECK_ERROR, CHECK_GT, 0);
+	post_hyph(mdoc);
 }
 
-static int
+static void
 post_d1(POST_ARGS)
 {
 
 	bwarn_ge1(mdoc);
-	return(post_hyph(mdoc));
+	post_hyph(mdoc);
 }
 
-static int
+static void
 post_literal(POST_ARGS)
 {
 
@@ -1102,11 +1091,9 @@ post_literal(POST_ARGS)
 
 	if (MDOC_BODY == mdoc->last->type)
 		mdoc->flags &= ~MDOC_LITERAL;
-
-	return(1);
 }
 
-static int
+static void
 post_defaults(POST_ARGS)
 {
 	struct mdoc_node *nn;
@@ -1118,38 +1105,29 @@ post_defaults(POST_ARGS)
 	 */
 
 	if (mdoc->last->child)
-		return(1);
+		return;
 
 	nn = mdoc->last;
 	mdoc->next = MDOC_NEXT_CHILD;
 
 	switch (nn->tok) {
 	case MDOC_Ar:
-		if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "file"))
-			return(0);
-		if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "..."))
-			return(0);
-		break;
-	case MDOC_Li:
-		if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, ""))
-			return(0);
+		mdoc_word_alloc(mdoc, nn->line, nn->pos, "file");
+		mdoc_word_alloc(mdoc, nn->line, nn->pos, "...");
 		break;
 	case MDOC_Pa:
 		/* FALLTHROUGH */
 	case MDOC_Mt:
-		if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "~"))
-			return(0);
+		mdoc_word_alloc(mdoc, nn->line, nn->pos, "~");
 		break;
 	default:
 		abort();
 		/* NOTREACHED */
 	}
-
 	mdoc->last = nn;
-	return(1);
 }
 
-static int
+static void
 post_at(POST_ARGS)
 {
 	struct mdoc_node	*n;
@@ -1159,10 +1137,9 @@ post_at(POST_ARGS)
 	n = mdoc->last;
 	if (n->child == NULL) {
 		mdoc->next = MDOC_NEXT_CHILD;
-		if ( ! mdoc_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"))
-			return(0);
+		mdoc_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX");
 		mdoc->last = n;
-		return(1);
+		return;
 	}
 
 	/*
@@ -1182,10 +1159,9 @@ post_at(POST_ARGS)
 
 	free(n->string);
 	n->string = att;
-	return(1);
 }
 
-static int
+static void
 post_an(POST_ARGS)
 {
 	struct mdoc_node *np;
@@ -1196,28 +1172,24 @@ post_an(POST_ARGS)
 			check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0);
 	} else if (np->child)
 		check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0);
-
-	return(1);
 }
 
-static int
+static void
 post_en(POST_ARGS)
 {
 
 	if (MDOC_BLOCK == mdoc->last->type)
 		mdoc->last->norm->Es = mdoc->last_es;
-	return(1);
 }
 
-static int
+static void
 post_es(POST_ARGS)
 {
 
 	mdoc->last_es = mdoc->last;
-	return(1);
 }
 
-static int
+static void
 post_it(POST_ARGS)
 {
 	int		  i, cols;
@@ -1225,8 +1197,8 @@ post_it(POST_ARGS)
 	struct mdoc_node *nbl, *nit, *nch;
 
 	nit = mdoc->last;
-	if (MDOC_BLOCK != nit->type)
-		return(1);
+	if (nit->type != MDOC_BLOCK)
+		return;
 
 	nbl = nit->parent->parent;
 	lt = nbl->norm->Bl.type;
@@ -1241,7 +1213,7 @@ post_it(POST_ARGS)
 	case LIST_inset:
 		/* FALLTHROUGH */
 	case LIST_diag:
-		if (NULL == nit->head->child)
+		if (nit->head->child == NULL)
 			mandoc_vmsg(MANDOCERR_IT_NOHEAD,
 			    mdoc->parse, nit->line, nit->pos,
 			    "Bl -%s It",
@@ -1254,14 +1226,14 @@ post_it(POST_ARGS)
 	case LIST_enum:
 		/* FALLTHROUGH */
 	case LIST_hyphen:
-		if (NULL == nit->body->child)
+		if (nit->body == NULL || nit->body->child == NULL)
 			mandoc_vmsg(MANDOCERR_IT_NOBODY,
 			    mdoc->parse, nit->line, nit->pos,
 			    "Bl -%s It",
 			    mdoc_argnames[nbl->args->argv[0].arg]);
 		/* FALLTHROUGH */
 	case LIST_item:
-		if (NULL != nit->head->child)
+		if (nit->head->child != NULL)
 			mandoc_vmsg(MANDOCERR_ARG_SKIP,
 			    mdoc->parse, nit->line, nit->pos,
 			    "It %s", nit->head->child->string);
@@ -1269,10 +1241,10 @@ post_it(POST_ARGS)
 	case LIST_column:
 		cols = (int)nbl->norm->Bl.ncols;
 
-		assert(NULL == nit->head->child);
+		assert(nit->head->child == NULL);
 
 		for (i = 0, nch = nit->child; nch; nch = nch->next)
-			if (MDOC_BODY == nch->type)
+			if (nch->type == MDOC_BODY)
 				i++;
 
 		if (i < cols || i > cols + 1)
@@ -1283,11 +1255,9 @@ post_it(POST_ARGS)
 	default:
 		abort();
 	}
-
-	return(1);
 }
 
-static int
+static void
 post_bl_block(POST_ARGS)
 {
 	struct mdoc_node *n, *ni, *nc;
@@ -1304,12 +1274,7 @@ post_bl_block(POST_ARGS)
 
 	if (LIST_tag == n->norm->Bl.type &&
 	    NULL == n->norm->Bl.width) {
-		if ( ! post_bl_block_tag(mdoc))
-			return(0);
-		assert(n->norm->Bl.width);
-	} else if (NULL != n->norm->Bl.width) {
-		if ( ! post_bl_block_width(mdoc))
-			return(0);
+		post_bl_block_tag(mdoc);
 		assert(n->norm->Bl.width);
 	}
 
@@ -1333,8 +1298,7 @@ post_bl_block(POST_ARGS)
 				mandoc_msg(MANDOCERR_PAR_MOVE,
 				    mdoc->parse, nc->line, nc->pos,
 				    mdoc_macronames[nc->tok]);
-				if ( ! mdoc_node_relink(mdoc, nc))
-					return(0);
+				mdoc_node_relink(mdoc, nc);
 			} else if (0 == n->norm->Bl.comp &&
 			    LIST_column != n->norm->Bl.type) {
 				mandoc_vmsg(MANDOCERR_PAR_SKIP,
@@ -1347,56 +1311,32 @@ post_bl_block(POST_ARGS)
 			nc = ni->body->last;
 		}
 	}
-	return(1);
 }
 
-static int
-post_bl_block_width(POST_ARGS)
+/*
+ * If the argument of -offset or -width is a macro,
+ * replace it with the associated default width.
+ */
+void
+rewrite_macro2len(char **arg)
 {
 	size_t		  width;
-	int		  i;
 	enum mdoct	  tok;
-	struct mdoc_node *n;
-	char		  buf[24];
-
-	n = mdoc->last;
 
-	/*
-	 * Calculate the real width of a list from the -width string,
-	 * which may contain a macro (with a known default width), a
-	 * literal string, or a scaling width.
-	 *
-	 * If the value to -width is a macro, then we re-write it to be
-	 * the macro's width as set in share/tmac/mdoc/doc-common.
-	 */
-
-	if (0 == strcmp(n->norm->Bl.width, "Ds"))
+	if (*arg == NULL)
+		return;
+	else if ( ! strcmp(*arg, "Ds"))
 		width = 6;
-	else if (MDOC_MAX == (tok = mdoc_hash_find(n->norm->Bl.width)))
-		return(1);
+	else if ((tok = mdoc_hash_find(*arg)) == MDOC_MAX)
+		return;
 	else
 		width = macro2len(tok);
 
-	/* The value already exists: free and reallocate it. */
-
-	assert(n->args);
-
-	for (i = 0; i < (int)n->args->argc; i++)
-		if (MDOC_Width == n->args->argv[i].arg)
-			break;
-
-	assert(i < (int)n->args->argc);
-
-	(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)width);
-	free(n->args->argv[i].value[0]);
-	n->args->argv[i].value[0] = mandoc_strdup(buf);
-
-	/* Set our width! */
-	n->norm->Bl.width = n->args->argv[i].value[0];
-	return(1);
+	free(*arg);
+	mandoc_asprintf(arg, "%zun", width);
 }
 
-static int
+static void
 post_bl_block_tag(POST_ARGS)
 {
 	struct mdoc_node *n, *nn;
@@ -1408,7 +1348,7 @@ post_bl_block_tag(POST_ARGS)
 	 * Calculate the -width for a `Bl -tag' list if it hasn't been
 	 * provided.  Uses the first head macro.  NOTE AGAIN: this is
 	 * ONLY if the -width argument has NOT been provided.  See
-	 * post_bl_block_width() for converting the -width string.
+	 * rewrite_macro2len() for converting the -width string.
 	 */
 
 	sz = 10;
@@ -1459,19 +1399,20 @@ post_bl_block_tag(POST_ARGS)
 
 	/* Set our width! */
 	n->norm->Bl.width = n->args->argv[i].value[0];
-	return(1);
 }
 
-static int
+static void
 post_bl_head(POST_ARGS)
 {
 	struct mdoc_node *np, *nn, *nnp;
 	struct mdoc_argv *argv;
 	int		  i, j;
 
-	if (LIST_column != mdoc->last->norm->Bl.type)
+	if (LIST_column != mdoc->last->norm->Bl.type) {
 		/* FIXME: this should be ERROR class... */
-		return(hwarn_eq0(mdoc));
+		hwarn_eq0(mdoc);
+		return;
+	}
 
 	/*
 	 * Append old-style lists, where the column width specifiers
@@ -1480,7 +1421,7 @@ post_bl_head(POST_ARGS)
 	 */
 
 	if (mdoc->last->child == NULL)
-		return(1);
+		return;
 
 	np = mdoc->last->parent;
 	assert(np->args);
@@ -1516,11 +1457,9 @@ post_bl_head(POST_ARGS)
 
 	mdoc->last->nchild = 0;
 	mdoc->last->child = NULL;
-
-	return(1);
 }
 
-static int
+static void
 post_bl(POST_ARGS)
 {
 	struct mdoc_node	*nparent, *nprev; /* of the Bl block */
@@ -1530,20 +1469,25 @@ post_bl(POST_ARGS)
 	nbody = mdoc->last;
 	switch (nbody->type) {
 	case MDOC_BLOCK:
-		return(post_bl_block(mdoc));
+		post_bl_block(mdoc);
+		return;
 	case MDOC_HEAD:
-		return(post_bl_head(mdoc));
+		post_bl_head(mdoc);
+		return;
 	case MDOC_BODY:
 		break;
 	default:
-		return(1);
+		return;
 	}
 
 	bwarn_ge1(mdoc);
 
 	nchild = nbody->child;
 	while (NULL != nchild) {
-		if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) {
+		if (nchild->tok == MDOC_It ||
+		    (nchild->tok == MDOC_Sm &&
+		     nchild->next != NULL &&
+		     nchild->next->tok == MDOC_It)) {
 			nchild = nchild->next;
 			continue;
 		}
@@ -1593,56 +1537,47 @@ post_bl(POST_ARGS)
 
 		nchild = nnext;
 	}
-
-	return(1);
 }
 
-static int
+static void
 post_bk(POST_ARGS)
 {
 
 	hwarn_eq0(mdoc);
 	bwarn_ge1(mdoc);
-	return(1);
 }
 
-static int
-ebool(struct mdoc *mdoc)
+static void
+post_sm(struct mdoc *mdoc)
 {
 	struct mdoc_node	*nch;
-	enum mdoct		 tok;
 
-	tok = mdoc->last->tok;
 	nch = mdoc->last->child;
 
-	if (NULL == nch) {
-		if (MDOC_Sm == tok)
-			mdoc->flags ^= MDOC_SMOFF;
-		return(1);
+	if (nch == NULL) {
+		mdoc->flags ^= MDOC_SMOFF;
+		return;
 	}
 
-	check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2);
+	assert(nch->type == MDOC_TEXT);
 
-	assert(MDOC_TEXT == nch->type);
-
-	if (0 == strcmp(nch->string, "on")) {
-		if (MDOC_Sm == tok)
-			mdoc->flags &= ~MDOC_SMOFF;
-		return(1);
+	if ( ! strcmp(nch->string, "on")) {
+		mdoc->flags &= ~MDOC_SMOFF;
+		return;
 	}
-	if (0 == strcmp(nch->string, "off")) {
-		if (MDOC_Sm == tok)
-			mdoc->flags |= MDOC_SMOFF;
-		return(1);
+	if ( ! strcmp(nch->string, "off")) {
+		mdoc->flags |= MDOC_SMOFF;
+		return;
 	}
 
 	mandoc_vmsg(MANDOCERR_SM_BAD,
 	    mdoc->parse, nch->line, nch->pos,
-	    "%s %s", mdoc_macronames[tok], nch->string);
-	return(mdoc_node_relink(mdoc, nch));
+	    "%s %s", mdoc_macronames[mdoc->last->tok], nch->string);
+	mdoc_node_relink(mdoc, nch);
+	return;
 }
 
-static int
+static void
 post_root(POST_ARGS)
 {
 	struct mdoc_node *n;
@@ -1680,11 +1615,9 @@ post_root(POST_ARGS)
 	else if (n->tok != MDOC_Sh)
 		mandoc_msg(MANDOCERR_SEC_BEFORE, mdoc->parse,
 		    n->line, n->pos, mdoc_macronames[n->tok]);
-
-	return(1);
 }
 
-static int
+static void
 post_st(POST_ARGS)
 {
 	struct mdoc_node	 *n, *nch;
@@ -1697,7 +1630,7 @@ post_st(POST_ARGS)
 		mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
 		    n->line, n->pos, mdoc_macronames[n->tok]);
 		mdoc_node_delete(mdoc, n);
-		return(1);
+		return;
 	}
 
 	assert(MDOC_TEXT == nch->type);
@@ -1710,11 +1643,9 @@ post_st(POST_ARGS)
 		free(nch->string);
 		nch->string = mandoc_strdup(p);
 	}
-
-	return(1);
 }
 
-static int
+static void
 post_rs(POST_ARGS)
 {
 	struct mdoc_node *nn, *next, *prev;
@@ -1723,14 +1654,14 @@ post_rs(POST_ARGS)
 	switch (mdoc->last->type) {
 	case MDOC_HEAD:
 		check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0);
-		return(1);
+		return;
 	case MDOC_BODY:
 		if (mdoc->last->child)
 			break;
 		check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0);
-		return(1);
+		return;
 	default:
-		return(1);
+		return;
 	}
 
 	/*
@@ -1804,15 +1735,13 @@ post_rs(POST_ARGS)
 			mdoc->last->child = nn;
 		}
 	}
-
-	return(1);
 }
 
 /*
  * For some arguments of some macros,
  * convert all breakable hyphens into ASCII_HYPH.
  */
-static int
+static void
 post_hyph(POST_ARGS)
 {
 	struct mdoc_node	*n, *nch;
@@ -1823,15 +1752,15 @@ post_hyph(POST_ARGS)
 	case MDOC_HEAD:
 		if (MDOC_Sh == n->tok || MDOC_Ss == n->tok)
 			break;
-		return(1);
+		return;
 	case MDOC_BODY:
 		if (MDOC_D1 == n->tok || MDOC_Nd == n->tok)
 			break;
-		return(1);
+		return;
 	case MDOC_ELEM:
 		break;
 	default:
-		return(1);
+		return;
 	}
 
 	for (nch = n->child; nch; nch = nch->next) {
@@ -1846,28 +1775,26 @@ post_hyph(POST_ARGS)
 			    isalpha((unsigned char)cp[1]))
 				*cp = ASCII_HYPH;
 	}
-	return(1);
 }
 
-static int
+static void
 post_hyphtext(POST_ARGS)
 {
 
 	ewarn_ge1(mdoc);
-	return(post_hyph(mdoc));
+	post_hyph(mdoc);
 }
 
-static int
+static void
 post_ns(POST_ARGS)
 {
 
 	if (MDOC_LINE & mdoc->last->flags)
 		mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse,
 		    mdoc->last->line, mdoc->last->pos, NULL);
-	return(1);
 }
 
-static int
+static void
 post_sh(POST_ARGS)
 {
 
@@ -1875,15 +1802,19 @@ post_sh(POST_ARGS)
 
 	switch (mdoc->last->type) {
 	case MDOC_HEAD:
-		return(post_sh_head(mdoc));
+		post_sh_head(mdoc);
+		break;
 	case MDOC_BODY:
 		switch (mdoc->lastsec)  {
 		case SEC_NAME:
-			return(post_sh_name(mdoc));
+			post_sh_name(mdoc);
+			break;
 		case SEC_SEE_ALSO:
-			return(post_sh_see_also(mdoc));
+			post_sh_see_also(mdoc);
+			break;
 		case SEC_AUTHORS:
-			return(post_sh_authors(mdoc));
+			post_sh_authors(mdoc);
+			break;
 		default:
 			break;
 		}
@@ -1891,11 +1822,9 @@ post_sh(POST_ARGS)
 	default:
 		break;
 	}
-
-	return(1);
 }
 
-static int
+static void
 post_sh_name(POST_ARGS)
 {
 	struct mdoc_node *n;
@@ -1909,7 +1838,7 @@ post_sh_name(POST_ARGS)
 	if (NULL == (n = mdoc->last->child)) {
 		mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
 		    mdoc->last->line, mdoc->last->pos, "empty");
-		return(1);
+		return;
 	}
 
 	for ( ; n && n->next; n = n->next) {
@@ -1923,14 +1852,13 @@ post_sh_name(POST_ARGS)
 
 	assert(n);
 	if (MDOC_BLOCK == n->type && MDOC_Nd == n->tok)
-		return(1);
+		return;
 
 	mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
 	    n->line, n->pos, mdoc_macronames[n->tok]);
-	return(1);
 }
 
-static int
+static void
 post_sh_see_also(POST_ARGS)
 {
 	const struct mdoc_node	*n;
@@ -1960,7 +1888,8 @@ post_sh_see_also(POST_ARGS)
 				    mdoc->parse, n->line, n->pos,
 				    "%s(%s) after %s(%s)", name,
 				    sec, lastname, lastsec);
-			else if (cmp == 0 && strcmp(lastname, name) > 0)
+			else if (cmp == 0 &&
+			    strcasecmp(lastname, name) > 0)
 				mandoc_vmsg(MANDOCERR_XR_ORDER,
 				    mdoc->parse, n->line, n->pos,
 				    "%s after %s", name, lastname);
@@ -1981,7 +1910,7 @@ post_sh_see_also(POST_ARGS)
 			break;
 		for (name = n->string; *name != '\0'; name++)
 			if (isalpha((const unsigned char)*name))
-				return(1);
+				return;
 		lastpunct = n->string;
 		if (n->next == NULL)
 			mandoc_vmsg(MANDOCERR_XR_PUNCT, mdoc->parse,
@@ -1989,7 +1918,6 @@ post_sh_see_also(POST_ARGS)
 			    lastpunct, lastname, lastsec);
 		n = n->next;
 	}
-	return(1);
 }
 
 static int
@@ -2002,17 +1930,16 @@ child_an(const struct mdoc_node *n)
 	return(0);
 }
 
-static int
+static void
 post_sh_authors(POST_ARGS)
 {
 
 	if ( ! child_an(mdoc->last))
 		mandoc_msg(MANDOCERR_AN_MISSING, mdoc->parse,
 		    mdoc->last->line, mdoc->last->pos, NULL);
-	return(1);
 }
 
-static int
+static void
 post_sh_head(POST_ARGS)
 {
 	struct mdoc_node *n;
@@ -2071,7 +1998,7 @@ post_sh_head(POST_ARGS)
 
 	if (SEC_CUSTOM == sec) {
 		free(secname);
-		return(1);
+		return;
 	}
 
 	/*
@@ -2097,7 +2024,7 @@ post_sh_head(POST_ARGS)
 
 	if (mdoc->meta.msec == NULL) {
 		free(secname);
-		return(1);
+		return;
 	}
 
 	goodsec = NULL;
@@ -2129,21 +2056,19 @@ post_sh_head(POST_ARGS)
 	default:
 		break;
 	}
-
 	free(secname);
-	return(1);
 }
 
-static int
+static void
 post_ignpar(POST_ARGS)
 {
 	struct mdoc_node *np;
 
-	hwarn_ge1(mdoc);
+	check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_GT, 0);
 	post_hyph(mdoc);
 
 	if (MDOC_BODY != mdoc->last->type)
-		return(1);
+		return;
 
 	if (NULL != (np = mdoc->last->child))
 		if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) {
@@ -2162,18 +2087,16 @@ post_ignpar(POST_ARGS)
 			    mdoc_macronames[mdoc->last->tok]);
 			mdoc_node_delete(mdoc, np);
 		}
-
-	return(1);
 }
 
-static int
+static void
 pre_par(PRE_ARGS)
 {
 
 	if (NULL == mdoc->last)
-		return(1);
+		return;
 	if (MDOC_ELEM != n->type && MDOC_BLOCK != n->type)
-		return(1);
+		return;
 
 	/*
 	 * Don't allow prior `Lp' or `Pp' prior to a paragraph-type
@@ -2183,63 +2106,59 @@ pre_par(PRE_ARGS)
 	if (MDOC_Pp != mdoc->last->tok &&
 	    MDOC_Lp != mdoc->last->tok &&
 	    MDOC_br != mdoc->last->tok)
-		return(1);
+		return;
 	if (MDOC_Bl == n->tok && n->norm->Bl.comp)
-		return(1);
+		return;
 	if (MDOC_Bd == n->tok && n->norm->Bd.comp)
-		return(1);
+		return;
 	if (MDOC_It == n->tok && n->parent->norm->Bl.comp)
-		return(1);
+		return;
 
 	mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
 	    mdoc->last->line, mdoc->last->pos,
 	    "%s before %s", mdoc_macronames[mdoc->last->tok],
 	    mdoc_macronames[n->tok]);
 	mdoc_node_delete(mdoc, mdoc->last);
-	return(1);
 }
 
-static int
+static void
 post_par(POST_ARGS)
 {
 	struct mdoc_node *np;
 
 	if (mdoc->last->tok == MDOC_sp)
-		ewarn_le1(mdoc);
+		check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2);
 	else
-		ewarn_eq0(mdoc);
+		check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0);
 
 	if (MDOC_ELEM != mdoc->last->type &&
 	    MDOC_BLOCK != mdoc->last->type)
-		return(1);
+		return;
 
 	if (NULL == (np = mdoc->last->prev)) {
 		np = mdoc->last->parent;
 		if (MDOC_Sh != np->tok && MDOC_Ss != np->tok)
-			return(1);
-	} else {
-		if (MDOC_Pp != np->tok && MDOC_Lp != np->tok &&
-		    (MDOC_br != mdoc->last->tok ||
-		     (MDOC_sp != np->tok && MDOC_br != np->tok)))
-			return(1);
-	}
+			return;
+	} else if (MDOC_Pp != np->tok && MDOC_Lp != np->tok &&
+	    (MDOC_br != mdoc->last->tok ||
+	     (MDOC_sp != np->tok && MDOC_br != np->tok)))
+		return;
 
 	mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
 	    mdoc->last->line, mdoc->last->pos,
 	    "%s after %s", mdoc_macronames[mdoc->last->tok],
 	    mdoc_macronames[np->tok]);
 	mdoc_node_delete(mdoc, mdoc->last);
-	return(1);
 }
 
-static int
+static void
 pre_literal(PRE_ARGS)
 {
 
 	pre_display(mdoc, n);
 
 	if (MDOC_BODY != n->type)
-		return(1);
+		return;
 
 	/*
 	 * The `Dl' (note "el" not "one") and `Bd -literal' and `Bd
@@ -2260,11 +2179,9 @@ pre_literal(PRE_ARGS)
 		abort();
 		/* NOTREACHED */
 	}
-
-	return(1);
 }
 
-static int
+static void
 post_dd(POST_ARGS)
 {
 	struct mdoc_node *n;
@@ -2291,10 +2208,9 @@ post_dd(POST_ARGS)
 	}
 out:
 	mdoc_node_delete(mdoc, n);
-	return(1);
 }
 
-static int
+static void
 post_dt(POST_ARGS)
 {
 	struct mdoc_node *nn, *n;
@@ -2367,39 +2283,21 @@ post_dt(POST_ARGS)
 		mdoc->meta.msec = mandoc_strdup(nn->string);
 	}
 
-	if (NULL == (nn = nn->next))
-		goto out;
+	/* Handle an optional architecture */
 
-	/* Handles: `.Dt TITLE SEC VOL'
-	 * title = TITLE,
-	 * volume = VOL is vol ? format(VOL) :
-	 *	    VOL is arch ? format(arch) :
-	 *	    VOL
-	 */
-
-	cp = mdoc_a2vol(nn->string);
-	if (cp) {
-		free(mdoc->meta.vol);
-		mdoc->meta.vol = mandoc_strdup(cp);
-	} else {
-		cp = mdoc_a2arch(nn->string);
-		if (NULL == cp) {
-			mandoc_vmsg(MANDOCERR_ARCH_BAD, mdoc->parse,
-			    nn->line, nn->pos, "Dt ... %s", nn->string);
-			free(mdoc->meta.vol);
-			mdoc->meta.vol = mandoc_strdup(nn->string);
-		} else
-			mdoc->meta.arch = mandoc_strdup(cp);
+	if ((nn = nn->next) != NULL) {
+		for (p = nn->string; *p; p++)
+			*p = tolower((unsigned char)*p);
+		mdoc->meta.arch = mandoc_strdup(nn->string);
 	}
 
 	/* Ignore any subsequent parameters... */
 	/* FIXME: warn about subsequent parameters. */
 out:
 	mdoc_node_delete(mdoc, n);
-	return(1);
 }
 
-static int
+static void
 post_bx(POST_ARGS)
 {
 	struct mdoc_node	*n;
@@ -2413,11 +2311,9 @@ post_bx(POST_ARGS)
 	n = mdoc->last->child;
 	if (n && NULL != (n = n->next))
 		*n->string = (char)toupper((unsigned char)*n->string);
-
-	return(1);
 }
 
-static int
+static void
 post_os(POST_ARGS)
 {
 #ifndef OSNAME
@@ -2465,14 +2361,13 @@ post_os(POST_ARGS)
 
 out:
 	mdoc_node_delete(mdoc, n);
-	return(1);
 }
 
 /*
  * If no argument is provided,
  * fill in the name of the current manual page.
  */
-static int
+static void
 post_ex(POST_ARGS)
 {
 	struct mdoc_node *n;
@@ -2480,21 +2375,17 @@ post_ex(POST_ARGS)
 	n = mdoc->last;
 
 	if (n->child)
-		return(1);
+		return;
 
 	if (mdoc->meta.name == NULL) {
 		mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
 		    n->line, n->pos, "Ex");
-		return(1);
+		return;
 	}
 
 	mdoc->next = MDOC_NEXT_CHILD;
-
-	if ( ! mdoc_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name))
-		return(0);
-
+	mdoc_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
 	mdoc->last = n;
-	return(1);
 }
 
 static enum mdoc_sec