summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2013-10-06 13:27:50 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2013-10-06 13:27:50 +0000
commit5849e3c7e5931eaac0102be731275919c6dd190c (patch)
tree7cd7181adf3b5b7c4ca0c210c9f8b5b2854c843a
parent1f05b920f382faabc98ad0cfbac1cce390bc75ec (diff)
If there is random stuff inside a .Bl block body before the first .It,
do not throw a FATAL error and do not die, but just throw a WARNING and move the stuff out of the .Bl block. This bug felt completely 2008-ish; meanwhile, such bugs from the Kristaps-doesnt-like-syntax-errors-so-lets-just-give-up--Era are becoming rare, but this was one of the last survivors. Thanks to bentley@ for reminding me to finally fix this.
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/Makefile4
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/noIt.in22
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/noIt.out_ascii15
-rw-r--r--usr.bin/mandoc/mdoc_validate.c79
4 files changed, 98 insertions, 22 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/Makefile b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
index 6e3472a8d2d..54a2bfe8f9e 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/Makefile
+++ b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.15 2012/11/19 22:28:35 schwarze Exp $
+# $OpenBSD: Makefile,v 1.16 2013/10/06 13:27:48 schwarze Exp $
REGRESS_TARGETS = item inset diag ohang bullet dash enum hang tag
REGRESS_TARGETS += column extend nested
-REGRESS_TARGETS += multitype multitag empty bareTa unclosed break broken
+REGRESS_TARGETS += multitype multitag empty noIt bareTa unclosed break broken
# groff-1.20.1 defects:
# - empty lists ruin indentation and sometimes cause empty lines
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/noIt.in b/regress/usr.bin/mandoc/mdoc/Bl/noIt.in
new file mode 100644
index 00000000000..5e5b4b473a3
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bl/noIt.in
@@ -0,0 +1,22 @@
+.Dd October 6, 2013
+.Dt BL-NOIT 1
+.Os OpenBSD
+.Sh NAME
+.Nm Bl-noIt
+.Nd list missing item macros
+.Sh DESCRIPTION
+.Bl -tag -width Ds
+Stray text.
+.Em More stray text.
+.It tag
+Tagged text.
+.El
+.Bl -bullet
+Stray text.
+.Em More stray text.
+.It
+Bullet point.
+.El
+.Bl -dash
+Stray text only.
+.El
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/noIt.out_ascii b/regress/usr.bin/mandoc/mdoc/Bl/noIt.out_ascii
new file mode 100644
index 00000000000..474d13ac11c
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bl/noIt.out_ascii
@@ -0,0 +1,15 @@
+BL-NOIT(1) OpenBSD Reference Manual BL-NOIT(1)
+
+NNAAMMEE
+ BBll--nnooIItt - list missing item macros
+
+DDEESSCCRRIIPPTTIIOONN
+ Stray text. _M_o_r_e _s_t_r_a_y _t_e_x_t_.
+
+ tag Tagged text.
+ Stray text. _M_o_r_e _s_t_r_a_y _t_e_x_t_.
+
+ oo Bullet point.
+ Stray text only.
+
+OpenBSD October 6, 2013 OpenBSD
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index da611d924cf..19be22d8f62 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.112 2013/10/03 19:32:25 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.113 2013/10/06 13:27:47 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
@@ -1586,32 +1586,71 @@ post_bl_head(POST_ARGS)
static int
post_bl(POST_ARGS)
{
- struct mdoc_node *n;
+ struct mdoc_node *nparent, *nprev; /* of the Bl block */
+ struct mdoc_node *nblock, *nbody; /* of the Bl */
+ struct mdoc_node *nchild, *nnext; /* of the Bl body */
- if (MDOC_HEAD == mdoc->last->type)
- return(post_bl_head(mdoc));
- if (MDOC_BLOCK == mdoc->last->type)
+ nbody = mdoc->last;
+ switch (nbody->type) {
+ case (MDOC_BLOCK):
return(post_bl_block(mdoc));
- if (MDOC_BODY != mdoc->last->type)
+ case (MDOC_HEAD):
+ return(post_bl_head(mdoc));
+ case (MDOC_BODY):
+ break;
+ default:
return(1);
+ }
- for (n = mdoc->last->child; n; n = n->next) {
- switch (n->tok) {
- case (MDOC_Lp):
- /* FALLTHROUGH */
- case (MDOC_Pp):
- mdoc_nmsg(mdoc, n, MANDOCERR_CHILD);
- /* FALLTHROUGH */
- case (MDOC_It):
- /* FALLTHROUGH */
- case (MDOC_Sm):
+ nchild = nbody->child;
+ while (NULL != nchild) {
+ if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) {
+ nchild = nchild->next;
continue;
- default:
- break;
}
- mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD);
- return(0);
+ mdoc_nmsg(mdoc, nchild, MANDOCERR_CHILD);
+
+ /*
+ * Move the node out of the Bl block.
+ * First, collect all required node pointers.
+ */
+
+ nblock = nbody->parent;
+ nprev = nblock->prev;
+ nparent = nblock->parent;
+ nnext = nchild->next;
+
+ /*
+ * Unlink this child.
+ */
+
+ assert(NULL == nchild->prev);
+ if (0 == --nbody->nchild) {
+ nbody->child = NULL;
+ nbody->last = NULL;
+ assert(NULL == nnext);
+ } else {
+ nbody->child = nnext;
+ nnext->prev = NULL;
+ }
+
+ /*
+ * Relink this child.
+ */
+
+ nchild->parent = nparent;
+ nchild->prev = nprev;
+ nchild->next = nblock;
+
+ nblock->prev = nchild;
+ nparent->nchild++;
+ if (NULL == nprev)
+ nparent->child = nchild;
+ else
+ nprev->next = nchild;
+
+ nchild = nnext;
}
return(1);