summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2018-12-04 02:53:45 +0000
committerschwarze <schwarze@openbsd.org>2018-12-04 02:53:45 +0000
commit8251afdef70029d8fd8e4e7ccff5b8606a3e0521 (patch)
treeca22636a7a2a24db052cbce6ec116c4013da1cf3
parentPort p5-Crypt-Random has been removed, replace it with p5-BSD-arc4random. (diff)
downloadwireguard-openbsd-8251afdef70029d8fd8e4e7ccff5b8606a3e0521.tar.xz
wireguard-openbsd-8251afdef70029d8fd8e4e7ccff5b8606a3e0521.zip
Clean up the validation of .Pp, .PP, .sp, and .br. Make sure all
combinations are handled, and are handled in a systematic manner. This resolves some erratic duplicate handling, handles a number of missing cases, and improves diagnostics in various respects. Move validation of .br and .sp to the roff validation module rather than doing that twice in the mdoc and man validation modules. Move the node relinking function to the roff library where it belongs. In validation functions, only look at the node itself, at previous nodes, and at descendants, not at following nodes or ancestors, such that only nodes are inspected which are already validated.
-rw-r--r--regress/usr.bin/mandoc/man/PP/empty.out_lint1
-rw-r--r--regress/usr.bin/mandoc/man/blank/afterSH.out_lint2
-rw-r--r--regress/usr.bin/mandoc/man/blank/afterSS.out_lint2
-rw-r--r--regress/usr.bin/mandoc/man/blank/line.out_lint9
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/parborder.out_lint2
-rw-r--r--regress/usr.bin/mandoc/mdoc/blank/line.out_lint4
-rw-r--r--regress/usr.bin/mandoc/roff/args/roff.out_lint1
-rw-r--r--regress/usr.bin/mandoc/roff/cond/if.out_lint2
-rw-r--r--usr.bin/mandoc/libmdoc.h3
-rw-r--r--usr.bin/mandoc/man_validate.c89
-rw-r--r--usr.bin/mandoc/mdoc.c11
-rw-r--r--usr.bin/mandoc/mdoc_macro.c4
-rw-r--r--usr.bin/mandoc/mdoc_validate.c55
-rw-r--r--usr.bin/mandoc/roff.c10
-rw-r--r--usr.bin/mandoc/roff_int.h5
-rw-r--r--usr.bin/mandoc/roff_validate.c62
16 files changed, 157 insertions, 105 deletions
diff --git a/regress/usr.bin/mandoc/man/PP/empty.out_lint b/regress/usr.bin/mandoc/man/PP/empty.out_lint
index 4c62912fadd..2a8516ac5b3 100644
--- a/regress/usr.bin/mandoc/man/PP/empty.out_lint
+++ b/regress/usr.bin/mandoc/man/PP/empty.out_lint
@@ -1,3 +1,4 @@
mandoc: empty.in:8:2: WARNING: skipping paragraph macro: PP empty
mandoc: empty.in:11:2: WARNING: skipping paragraph macro: PP empty
mandoc: empty.in:14:2: WARNING: skipping paragraph macro: PP empty
+mandoc: empty.in:6:2: WARNING: skipping paragraph macro: PP after SH
diff --git a/regress/usr.bin/mandoc/man/blank/afterSH.out_lint b/regress/usr.bin/mandoc/man/blank/afterSH.out_lint
index 4f641b3c433..233661d6a30 100644
--- a/regress/usr.bin/mandoc/man/blank/afterSH.out_lint
+++ b/regress/usr.bin/mandoc/man/blank/afterSH.out_lint
@@ -1,4 +1,6 @@
+mandoc: afterSH.in:10:2: WARNING: skipping paragraph macro: PP after SH
mandoc: afterSH.in:32:2: WARNING: skipping paragraph macro: br after SH
mandoc: afterSH.in:36:2: WARNING: skipping paragraph macro: sp after SH
+mandoc: afterSH.in:45:2: WARNING: skipping paragraph macro: PP after SH
mandoc: afterSH.in:72:2: WARNING: skipping paragraph macro: br after SH
mandoc: afterSH.in:77:2: WARNING: skipping paragraph macro: sp after SH
diff --git a/regress/usr.bin/mandoc/man/blank/afterSS.out_lint b/regress/usr.bin/mandoc/man/blank/afterSS.out_lint
index e5f5bc47476..0204890c220 100644
--- a/regress/usr.bin/mandoc/man/blank/afterSS.out_lint
+++ b/regress/usr.bin/mandoc/man/blank/afterSS.out_lint
@@ -1,4 +1,6 @@
+mandoc: afterSS.in:11:2: WARNING: skipping paragraph macro: PP after SS
mandoc: afterSS.in:33:2: WARNING: skipping paragraph macro: br after SS
mandoc: afterSS.in:37:2: WARNING: skipping paragraph macro: sp after SS
+mandoc: afterSS.in:46:2: WARNING: skipping paragraph macro: PP after SS
mandoc: afterSS.in:73:2: WARNING: skipping paragraph macro: br after SS
mandoc: afterSS.in:78:2: WARNING: skipping paragraph macro: sp after SS
diff --git a/regress/usr.bin/mandoc/man/blank/line.out_lint b/regress/usr.bin/mandoc/man/blank/line.out_lint
index 30de6f49f9c..28a6898ab24 100644
--- a/regress/usr.bin/mandoc/man/blank/line.out_lint
+++ b/regress/usr.bin/mandoc/man/blank/line.out_lint
@@ -1,8 +1,13 @@
-mandoc: line.in:6:2: WARNING: skipping paragraph macro: sp after SH
+mandoc: line.in:18:2: WARNING: skipping paragraph macro: br after br
mandoc: line.in:24:2: WARNING: skipping paragraph macro: br after PP
mandoc: line.in:26:2: WARNING: skipping paragraph macro: PP empty
+mandoc: line.in:29:2: WARNING: skipping paragraph macro: br before sp
+mandoc: line.in:33:2: WARNING: skipping paragraph macro: br after sp
mandoc: line.in:36:2: WARNING: skipping paragraph macro: sp after PP
mandoc: line.in:39:2: WARNING: skipping paragraph macro: sp after PP
+mandoc: line.in:47:2: WARNING: skipping paragraph macro: br before sp
+mandoc: line.in:51:2: WARNING: skipping paragraph macro: br after sp
mandoc: line.in:54:1: WARNING: skipping paragraph macro: sp after PP
-mandoc: line.in:82:2: WARNING: skipping paragraph macro: sp after SH
+mandoc: line.in:6:2: WARNING: skipping paragraph macro: sp after SH
mandoc: line.in:85:2: WARNING: skipping paragraph macro: sp after SS
+mandoc: line.in:82:2: WARNING: skipping paragraph macro: sp after SH
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/parborder.out_lint b/regress/usr.bin/mandoc/mdoc/Sh/parborder.out_lint
index 0da9e5dfad2..03863fbabcb 100644
--- a/regress/usr.bin/mandoc/mdoc/Sh/parborder.out_lint
+++ b/regress/usr.bin/mandoc/mdoc/Sh/parborder.out_lint
@@ -1,7 +1,7 @@
mandoc: parborder.in:9:2: WARNING: skipping paragraph macro: Pp after Sh
mandoc: parborder.in:11:2: WARNING: skipping paragraph macro: Pp at the end of Sh
-mandoc: parborder.in:13:2: WARNING: skipping paragraph macro: Pp after Sh
mandoc: parborder.in:17:2: WARNING: skipping paragraph macro: Pp after Ss
mandoc: parborder.in:19:2: WARNING: skipping paragraph macro: Pp at the end of Ss
mandoc: parborder.in:15:2: WARNING: skipping paragraph macro: Pp before Ss
mandoc: parborder.in:22:2: WARNING: skipping paragraph macro: Pp at the end of Ss
+mandoc: parborder.in:13:2: WARNING: skipping paragraph macro: Pp after Sh
diff --git a/regress/usr.bin/mandoc/mdoc/blank/line.out_lint b/regress/usr.bin/mandoc/mdoc/blank/line.out_lint
index 990bb5bd3ad..e122298d739 100644
--- a/regress/usr.bin/mandoc/mdoc/blank/line.out_lint
+++ b/regress/usr.bin/mandoc/mdoc/blank/line.out_lint
@@ -11,13 +11,15 @@ mandoc: line.in:19:2: WARNING: skipping paragraph macro: br after br
mandoc: line.in:21:2: WARNING: skipping paragraph macro: br before Pp
mandoc: line.in:25:2: WARNING: skipping paragraph macro: br after Pp
mandoc: line.in:27:2: WARNING: skipping paragraph macro: Pp before Pp
+mandoc: line.in:30:2: WARNING: skipping paragraph macro: br before sp
mandoc: line.in:34:2: WARNING: skipping paragraph macro: br after sp
mandoc: line.in:37:2: WARNING: skipping paragraph macro: sp after Pp
mandoc: line.in:40:2: WARNING: skipping paragraph macro: sp after Pp
+mandoc: line.in:48:2: WARNING: skipping paragraph macro: br before sp
mandoc: line.in:52:2: WARNING: skipping paragraph macro: br after sp
mandoc: line.in:55:1: WARNING: skipping paragraph macro: sp after Pp
mandoc: line.in:82:2: WARNING: skipping paragraph macro: sp after Sh
mandoc: line.in:84:2: WARNING: skipping paragraph macro: Pp at the end of Sh
-mandoc: line.in:86:2: WARNING: skipping paragraph macro: Pp after Sh
mandoc: line.in:89:2: WARNING: skipping paragraph macro: Pp after Ss
mandoc: line.in:91:2: WARNING: skipping paragraph macro: Pp at the end of Ss
+mandoc: line.in:86:2: WARNING: skipping paragraph macro: Pp after Sh
diff --git a/regress/usr.bin/mandoc/roff/args/roff.out_lint b/regress/usr.bin/mandoc/roff/args/roff.out_lint
index 5ac03917282..c5f4b3d3284 100644
--- a/regress/usr.bin/mandoc/roff/args/roff.out_lint
+++ b/regress/usr.bin/mandoc/roff/args/roff.out_lint
@@ -14,3 +14,4 @@ mandoc: roff.in:69:7: STYLE: unterminated quoted argument
mandoc: roff.in:69:13: STYLE: whitespace at end of input line
mandoc: roff.in:70:11: STYLE: unterminated quoted argument
mandoc: roff.in:70:17: STYLE: whitespace at end of input line
+mandoc: roff.in:72:2: WARNING: skipping paragraph macro: br at the end of SH
diff --git a/regress/usr.bin/mandoc/roff/cond/if.out_lint b/regress/usr.bin/mandoc/roff/cond/if.out_lint
index 5fb37795c81..597140d86c5 100644
--- a/regress/usr.bin/mandoc/roff/cond/if.out_lint
+++ b/regress/usr.bin/mandoc/roff/cond/if.out_lint
@@ -1,2 +1,4 @@
mandoc: if.in:15:2: WARNING: conditional request controls empty scope: if
mandoc: if.in:17:2: WARNING: conditional request controls empty scope: if
+mandoc: if.in:42:2: WARNING: skipping paragraph macro: br before sp
+mandoc: if.in:71:2: WARNING: skipping paragraph macro: br after br
diff --git a/usr.bin/mandoc/libmdoc.h b/usr.bin/mandoc/libmdoc.h
index bc8bfed31e2..f9639a992fd 100644
--- a/usr.bin/mandoc/libmdoc.h
+++ b/usr.bin/mandoc/libmdoc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libmdoc.h,v 1.84 2018/08/17 20:31:52 schwarze Exp $ */
+/* $OpenBSD: libmdoc.h,v 1.85 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -69,7 +69,6 @@ void mdoc_tail_alloc(struct roff_man *, int, int,
enum roff_tok);
struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int,
enum roff_tok, struct roff_node *);
-void mdoc_node_relink(struct roff_man *, struct roff_node *);
void mdoc_node_validate(struct roff_man *);
void mdoc_state(struct roff_man *, struct roff_node *);
void mdoc_state_reset(struct roff_man *);
diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c
index 7fa99bcced2..e6d3775dd6e 100644
--- a/usr.bin/mandoc/man_validate.c
+++ b/usr.bin/mandoc/man_validate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: man_validate.c,v 1.109 2018/12/03 21:00:06 schwarze Exp $ */
+/* $OpenBSD: man_validate.c,v 1.110 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -47,16 +47,16 @@ static void check_text(CHKARGS);
static void post_AT(CHKARGS);
static void post_IP(CHKARGS);
static void post_OP(CHKARGS);
+static void post_SH(CHKARGS);
static void post_TH(CHKARGS);
static void post_UC(CHKARGS);
static void post_UR(CHKARGS);
static void post_in(CHKARGS);
-static void post_vs(CHKARGS);
static const v_check man_valids[MAN_MAX - MAN_TH] = {
post_TH, /* TH */
- NULL, /* SH */
- NULL, /* SS */
+ post_SH, /* SH */
+ post_SH, /* SS */
NULL, /* TP */
NULL, /* TQ */
check_abort,/* LP */
@@ -149,15 +149,7 @@ man_node_validate(struct roff_man *man)
break;
default:
if (n->tok < ROFF_MAX) {
- switch (n->tok) {
- case ROFF_br:
- case ROFF_sp:
- post_vs(man, n);
- break;
- default:
- roff_validate(man);
- break;
- }
+ roff_validate(man);
break;
}
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
@@ -238,6 +230,42 @@ post_OP(CHKARGS)
}
static void
+post_SH(CHKARGS)
+{
+ struct roff_node *nc;
+
+ if (n->type != ROFFT_BODY || (nc = n->child) == NULL)
+ return;
+
+ if (nc->tok == MAN_PP && nc->body->child != NULL) {
+ while (nc->body->last != NULL) {
+ man->next = ROFF_NEXT_CHILD;
+ roff_node_relink(man, nc->body->last);
+ man->last = n;
+ }
+ }
+
+ if (nc->tok == MAN_PP || nc->tok == ROFF_sp || nc->tok == ROFF_br) {
+ mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse,
+ nc->line, nc->pos, "%s after %s",
+ roff_name[nc->tok], roff_name[n->tok]);
+ roff_node_delete(man, nc);
+ }
+
+ /*
+ * Trailing PP is empty, so it is deleted by check_par().
+ * Trailing sp is significant.
+ */
+
+ if ((nc = n->last) != NULL && nc->tok == ROFF_br) {
+ mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse,
+ nc->line, nc->pos, "%s at the end of %s",
+ roff_name[nc->tok], roff_name[n->tok]);
+ roff_node_delete(man, nc);
+ }
+}
+
+static void
post_UR(CHKARGS)
{
if (n->type == ROFFT_HEAD && n->child == NULL)
@@ -265,6 +293,14 @@ check_par(CHKARGS)
roff_node_delete(man, n);
break;
case ROFFT_BODY:
+ if (n->child != NULL &&
+ (n->child->tok == ROFF_sp || n->child->tok == ROFF_br)) {
+ mandoc_vmsg(MANDOCERR_PAR_SKIP,
+ man->parse, n->child->line, n->child->pos,
+ "%s after %s", roff_name[n->child->tok],
+ roff_name[n->tok]);
+ roff_node_delete(man, n->child);
+ }
if (n->child == NULL)
mandoc_vmsg(MANDOCERR_PAR_SKIP,
man->parse, n->line, n->pos,
@@ -492,30 +528,3 @@ post_in(CHKARGS)
free(n->child->string);
n->child->string = s;
}
-
-static void
-post_vs(CHKARGS)
-{
-
- if (NULL != n->prev)
- return;
-
- switch (n->parent->tok) {
- case MAN_SH:
- case MAN_SS:
- case MAN_PP:
- mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos,
- "%s after %s", roff_name[n->tok],
- roff_name[n->parent->tok]);
- /* FALLTHROUGH */
- case TOKEN_NONE:
- /*
- * Don't warn about this because it occurs in pod2man
- * and would cause considerable (unfixable) warnage.
- */
- roff_node_delete(man, n);
- break;
- default:
- break;
- }
-}
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index a5fdc03cc93..87891670af6 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc.c,v 1.158 2018/08/17 20:31:52 schwarze Exp $ */
+/* $OpenBSD: mdoc.c,v 1.159 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -153,15 +153,6 @@ mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos,
mdoc->next = ROFF_NEXT_CHILD;
}
-void
-mdoc_node_relink(struct roff_man *mdoc, struct roff_node *p)
-{
-
- roff_node_unlink(mdoc, p);
- p->prev = p->next = NULL;
- roff_node_append(mdoc, p);
-}
-
/*
* Parse free-form text, that is, a line that does not begin with the
* control character.
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index 250b04e2ad7..d1a0000fad4 100644
--- a/usr.bin/mandoc/mdoc_macro.c
+++ b/usr.bin/mandoc/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc_macro.c,v 1.182 2018/08/17 20:31:52 schwarze Exp $ */
+/* $OpenBSD: mdoc_macro.c,v 1.183 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -1241,7 +1241,7 @@ blk_part_imp(MACRO_PROT_ARGS)
for (n = body->child; n && n->next; n = n->next)
/* Do nothing. */ ;
if (n && n->tok == MDOC_Ns)
- mdoc_node_relink(mdoc, n);
+ roff_node_relink(mdoc, n);
}
static void
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index 1c80db2b30d..61cdc5b96e6 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc_validate.c,v 1.278 2018/12/03 21:00:06 schwarze Exp $ */
+/* $OpenBSD: mdoc_validate.c,v 1.279 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -368,15 +368,7 @@ mdoc_node_validate(struct roff_man *mdoc)
/* Call the macro's postprocessor. */
if (n->tok < ROFF_MAX) {
- switch(n->tok) {
- case ROFF_br:
- case ROFF_sp:
- post_par(mdoc);
- break;
- default:
- roff_validate(mdoc);
- break;
- }
+ roff_validate(mdoc);
break;
}
@@ -954,7 +946,7 @@ build_list(struct roff_man *mdoc, int tok)
for (ic = 1;; ic++) {
roff_elem_alloc(mdoc, n->line, n->pos, tok);
mdoc->last->flags |= NODE_NOSRC;
- mdoc_node_relink(mdoc, n);
+ roff_node_relink(mdoc, n);
n = mdoc->last = mdoc->last->parent;
mdoc->next = ROFF_NEXT_SIBLING;
if (n->next == NULL)
@@ -1282,7 +1274,7 @@ post_nm(POST_ARGS)
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1);
if (n->last != NULL && n->last->tok == MDOC_Pp)
- mdoc_node_relink(mdoc, n->last);
+ roff_node_relink(mdoc, n->last);
if (mdoc->meta.name == NULL)
deroff(&mdoc->meta.name, n);
@@ -1361,7 +1353,7 @@ post_display(POST_ARGS)
mdoc->parse, n->line, n->pos, "Bd");
mdoc->next = ROFF_NEXT_SIBLING;
while (n->body->child != NULL)
- mdoc_node_relink(mdoc,
+ roff_node_relink(mdoc,
n->body->child);
roff_node_delete(mdoc, n);
break;
@@ -1644,7 +1636,7 @@ post_bl_block(POST_ARGS)
mandoc_msg(MANDOCERR_PAR_MOVE,
mdoc->parse, nc->line, nc->pos,
roff_name[nc->tok]);
- mdoc_node_relink(mdoc, nc);
+ roff_node_relink(mdoc, nc);
} else if (n->norm->Bl.comp == 0 &&
n->norm->Bl.type != LIST_column) {
mandoc_vmsg(MANDOCERR_PAR_SKIP,
@@ -1804,7 +1796,7 @@ post_bl(POST_ARGS)
roff_body_alloc(mdoc, nchild->line,
nchild->pos, MDOC_It);
while (nchild->tok != MDOC_It) {
- mdoc_node_relink(mdoc, nchild);
+ roff_node_relink(mdoc, nchild);
if ((nchild = nnext) == NULL)
break;
nnext = nchild->next;
@@ -1923,7 +1915,7 @@ post_sm(POST_ARGS)
mandoc_vmsg(MANDOCERR_SM_BAD,
mdoc->parse, nch->line, nch->pos,
"%s %s", roff_name[mdoc->last->tok], nch->string);
- mdoc_node_relink(mdoc, nch);
+ roff_node_relink(mdoc, nch);
return;
}
@@ -2507,7 +2499,8 @@ post_ignpar(POST_ARGS)
}
if ((np = mdoc->last->child) != NULL)
- if (np->tok == MDOC_Pp) {
+ if (np->tok == MDOC_Pp ||
+ np->tok == ROFF_br || np->tok == ROFF_sp) {
mandoc_vmsg(MANDOCERR_PAR_SKIP,
mdoc->parse, np->line, np->pos,
"%s after %s", roff_name[np->tok],
@@ -2516,7 +2509,7 @@ post_ignpar(POST_ARGS)
}
if ((np = mdoc->last->last) != NULL)
- if (np->tok == MDOC_Pp) {
+ if (np->tok == MDOC_Pp || np->tok == ROFF_br) {
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
np->line, np->pos, "%s at the end of %s",
roff_name[np->tok],
@@ -2561,33 +2554,13 @@ post_par(POST_ARGS)
{
struct roff_node *np;
- np = mdoc->last;
- if (np->tok != ROFF_br && np->tok != ROFF_sp)
- post_prevpar(mdoc);
+ post_prevpar(mdoc);
- if (np->tok == ROFF_sp) {
- if (np->child != NULL && np->child->next != NULL)
- mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
- np->child->next->line, np->child->next->pos,
- "sp ... %s", np->child->next->string);
- } else if (np->child != NULL)
+ np = mdoc->last;
+ if (np->child != NULL)
mandoc_vmsg(MANDOCERR_ARG_SKIP,
mdoc->parse, np->line, np->pos, "%s %s",
roff_name[np->tok], np->child->string);
-
- if ((np = mdoc->last->prev) == NULL) {
- np = mdoc->last->parent;
- if (np->tok != MDOC_Sh && np->tok != MDOC_Ss)
- return;
- } else if (np->tok != MDOC_Pp &&
- (mdoc->last->tok != ROFF_br ||
- (np->tok != ROFF_sp && np->tok != ROFF_br)))
- return;
-
- mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
- mdoc->last->line, mdoc->last->pos, "%s after %s",
- roff_name[mdoc->last->tok], roff_name[np->tok]);
- roff_node_delete(mdoc, mdoc->last);
}
static void
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index caed1da5cc5..796c01fb4e1 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.215 2018/11/26 17:44:29 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.216 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -1065,6 +1065,14 @@ roff_node_unlink(struct roff_man *man, struct roff_node *n)
}
void
+roff_node_relink(struct roff_man *man, struct roff_node *n)
+{
+ roff_node_unlink(man, n);
+ n->prev = n->next = NULL;
+ roff_node_append(man, n);
+}
+
+void
roff_node_free(struct roff_node *n)
{
diff --git a/usr.bin/mandoc/roff_int.h b/usr.bin/mandoc/roff_int.h
index 14bf92a9078..8bd32eb597e 100644
--- a/usr.bin/mandoc/roff_int.h
+++ b/usr.bin/mandoc/roff_int.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: roff_int.h,v 1.9 2017/07/08 17:52:42 schwarze Exp $ */
+/* $OpenBSD: roff_int.h,v 1.10 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013, 2014, 2015, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -26,6 +26,7 @@ struct roff_node *roff_block_alloc(struct roff_man *, int, int, int);
struct roff_node *roff_head_alloc(struct roff_man *, int, int, int);
struct roff_node *roff_body_alloc(struct roff_man *, int, int, int);
void roff_node_unlink(struct roff_man *, struct roff_node *);
+void roff_node_relink(struct roff_man *, struct roff_node *);
void roff_node_free(struct roff_node *);
void roff_node_delete(struct roff_man *, struct roff_node *);
diff --git a/usr.bin/mandoc/roff_validate.c b/usr.bin/mandoc/roff_validate.c
index 40b69d0dff8..4d9c7839db8 100644
--- a/usr.bin/mandoc/roff_validate.c
+++ b/usr.bin/mandoc/roff_validate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff_validate.c,v 1.10 2018/08/10 20:40:43 schwarze Exp $ */
+/* $OpenBSD: roff_validate.c,v 1.11 2018/12/04 02:53:45 schwarze Exp $ */
/*
* Copyright (c) 2010, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -29,17 +29,19 @@
typedef void (*roff_valid_fp)(ROFF_VALID_ARGS);
+static void roff_valid_br(ROFF_VALID_ARGS);
static void roff_valid_ft(ROFF_VALID_ARGS);
+static void roff_valid_sp(ROFF_VALID_ARGS);
static const roff_valid_fp roff_valids[ROFF_MAX] = {
- NULL, /* br */
+ roff_valid_br, /* br */
NULL, /* ce */
roff_valid_ft, /* ft */
NULL, /* ll */
NULL, /* mc */
NULL, /* po */
NULL, /* rj */
- NULL, /* sp */
+ roff_valid_sp, /* sp */
NULL, /* ta */
NULL, /* ti */
};
@@ -57,6 +59,31 @@ roff_validate(struct roff_man *man)
}
static void
+roff_valid_br(ROFF_VALID_ARGS)
+{
+ struct roff_node *np;
+
+ if (n->child != NULL)
+ mandoc_vmsg(MANDOCERR_ARG_SKIP, man->parse,
+ n->line, n->pos, "br %s", n->child->string);
+
+ if ((np = n->prev) == NULL)
+ return;
+
+ switch (np->tok) {
+ case ROFF_br:
+ case ROFF_sp:
+ case MDOC_Pp:
+ mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse,
+ n->line, n->pos, "br after %s", roff_name[np->tok]);
+ roff_node_delete(man, n);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
roff_valid_ft(ROFF_VALID_ARGS)
{
const char *cp;
@@ -97,3 +124,32 @@ roff_valid_ft(ROFF_VALID_ARGS)
n->line, n->pos, "ft %s", cp);
roff_node_delete(man, n);
}
+
+static void
+roff_valid_sp(ROFF_VALID_ARGS)
+{
+ struct roff_node *np;
+
+ if (n->child != NULL && n->child->next != NULL)
+ mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse,
+ n->child->next->line, n->child->next->pos,
+ "sp ... %s", n->child->next->string);
+
+ if ((np = n->prev) == NULL)
+ return;
+
+ switch (np->tok) {
+ case ROFF_br:
+ mandoc_msg(MANDOCERR_PAR_SKIP, man->parse,
+ np->line, np->pos, "br before sp");
+ roff_node_delete(man, np);
+ break;
+ case MDOC_Pp:
+ mandoc_msg(MANDOCERR_PAR_SKIP, man->parse,
+ n->line, n->pos, "sp after Pp");
+ roff_node_delete(man, n);
+ break;
+ default:
+ break;
+ }
+}