aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_validate.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2013-10-06 13:32:46 +0000
committerIngo Schwarze <schwarze@openbsd.org>2013-10-06 13:32:46 +0000
commitd53ffcc35f4d12dc5e03d33f5ee1fd0a9fdc364a (patch)
treeb9aabf182b2bbc997e303df0a239aae7c51db395 /mdoc_validate.c
parent7d8c02235ea3f2578abde25a58940051c970d356 (diff)
downloadmandoc-d53ffcc35f4d12dc5e03d33f5ee1fd0a9fdc364a.tar.gz
mandoc-d53ffcc35f4d12dc5e03d33f5ee1fd0a9fdc364a.tar.zst
mandoc-d53ffcc35f4d12dc5e03d33f5ee1fd0a9fdc364a.zip
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.
Diffstat (limited to 'mdoc_validate.c')
-rw-r--r--mdoc_validate.c79
1 files changed, 59 insertions, 20 deletions
diff --git a/mdoc_validate.c b/mdoc_validate.c
index b4d60315..c13422f2 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.194 2013/10/05 22:08:12 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.195 2013/10/06 13:32:46 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
@@ -1590,32 +1590,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);