summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/break.in21
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii12
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/break.out_lint12
-rw-r--r--usr.bin/mandoc/mdoc.h3
-rw-r--r--usr.bin/mandoc/mdoc_macro.c53
5 files changed, 73 insertions, 28 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.in b/regress/usr.bin/mandoc/mdoc/Bl/break.in
index a397042d27b..4fe9246b5bf 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/break.in
+++ b/regress/usr.bin/mandoc/mdoc/Bl/break.in
@@ -1,4 +1,4 @@
-.Dd November 16, 2012
+.Dd December 18, 2014
.Dt BL-BREAK 1
.Os OpenBSD
.Sh NAME
@@ -13,6 +13,15 @@ before bracket
.El
after list
.Bc
+in between
+.Bl -enum -offset indent
+.It
+before bracket
+.Bo inside both
+.El
+.It
+stray item
+.Bc
after both
.Sh EXAMPLES
.Bl -enum -offset indent
@@ -23,6 +32,16 @@ inside both
.El
after display
.Ed
+in between
+.Bl -enum -offset indent
+.It
+before display
+.Bd -ragged -offset indent
+inside both
+.El
+.It
+stray item
+.Ed
after both
.Sh CAVEATS
.Bl -hang
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii b/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii
index 46218053f9d..ed14c25d910 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii
+++ b/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii
@@ -7,15 +7,25 @@ DDEESSCCRRIIPPTTIIOONN
before both
1. before bracket [inside both after list]
+ in between
+
+ 1. before bracket [inside both
+ stray item]
after both
EEXXAAMMPPLLEESS
1. before display
inside both after display
+ in between
+
+ 1. before display
+
+ inside both
+ stray item
after both
CCAAVVEEAATTSS
before broken block [inside both after list]
-OpenBSD November 16, 2012 OpenBSD
+OpenBSD December 18, 2014 OpenBSD
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint b/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint
index b99744f21b2..70b3c986446 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint
+++ b/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint
@@ -1,5 +1,9 @@
mandoc: break.in:13:2: WARNING: blocks badly nested: El breaks Bo
-mandoc: break.in:23:2: WARNING: blocks badly nested: El breaks Bd
-mandoc: break.in:30:2: WARNING: blocks badly nested: El breaks It
-mandoc: break.in:29:25: ERROR: appending missing end of block: Bo
-mandoc: break.in:28:2: ERROR: appending missing end of block: Bl
+mandoc: break.in:21:2: WARNING: blocks badly nested: El breaks Bo
+mandoc: break.in:22:2: ERROR: skipping item outside list: It
+mandoc: break.in:32:2: WARNING: blocks badly nested: El breaks Bd
+mandoc: break.in:41:2: WARNING: blocks badly nested: El breaks Bd
+mandoc: break.in:42:2: ERROR: skipping item outside list: It
+mandoc: break.in:49:2: WARNING: blocks badly nested: El breaks It
+mandoc: break.in:48:25: ERROR: appending missing end of block: Bo
+mandoc: break.in:47:2: ERROR: appending missing end of block: Bl
diff --git a/usr.bin/mandoc/mdoc.h b/usr.bin/mandoc/mdoc.h
index f19a8054d4b..24c257935c9 100644
--- a/usr.bin/mandoc/mdoc.h
+++ b/usr.bin/mandoc/mdoc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc.h,v 1.57 2014/11/28 19:25:03 schwarze Exp $ */
+/* $OpenBSD: mdoc.h,v 1.58 2014/12/18 03:09:42 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -356,6 +356,7 @@ struct mdoc_node {
enum mdoct tok; /* tok or MDOC__MAX if none */
int flags;
#define MDOC_VALID (1 << 0) /* has been validated */
+#define MDOC_BREAK (1 << 1) /* has broken another block */
#define MDOC_EOS (1 << 2) /* at sentence boundary */
#define MDOC_LINE (1 << 3) /* first macro/text on line */
#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index b71a1fbc4e1..3dbd6602e8c 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.113 2014/12/13 13:13:26 schwarze Exp $ */
+/* $OpenBSD: mdoc_macro.c,v 1.114 2014/12/18 03:09:42 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -476,12 +476,16 @@ make_pending(struct mdoc_node *broken, enum mdoct tok,
for (breaker = broken->parent; breaker; breaker = breaker->parent) {
/*
- * If the *broken block had already been broken before
- * and we encounter its breaker, make the tok block
- * pending on the inner breaker.
- * Graphically, "[A breaker=[B broken=[C->B B] tok=A] C]"
- * becomes "[A broken=[B [C->B B] tok=A] C]"
- * and finally "[A [B->A [C->B B] A] C]".
+ * If the *broken block (Z) is already broken and we
+ * encounter its breaker (B), make the tok block (A)
+ * pending on that inner breaker (B).
+ * Graphically, [A breaker=[B! broken=[Z->B B] tok=A] Z]
+ * becomes breaker=[A broken=[B! [Z->B B] tok=A] Z]
+ * and finally [A! [B!->A [Z->B B] A] Z].
+ * In these graphics, "->" indicates the "pending"
+ * pointer and "!" indicates the MDOC_BREAK flag.
+ * Each of the cases gets one additional pointer (B->A)
+ * and one additional flag (A!).
*/
if (breaker == broken->pending) {
broken = breaker;
@@ -495,31 +499,38 @@ make_pending(struct mdoc_node *broken, enum mdoct tok,
/*
* Found the breaker.
- * If another, outer breaker is already pending on
- * the *broken block, we must not clobber the link
+ * If another, outer breaker (X) is already pending on
+ * the *broken block (B), we must not clobber the link
* to the outer breaker, but make it pending on the
- * new, now inner breaker.
- * Graphically, "[A breaker=[B broken=[C->A A] tok=B] C]"
- * becomes "[A breaker=[B->A broken=[C A] tok=B] C]"
- * and finally "[A [B->A [C->B A] B] C]".
+ * new, now inner breaker (A).
+ * Graphically, [X! breaker=[A broken=[B->X X] tok=A] B]
+ * becomes [X! breaker=[A->X broken=[B X] tok=A] B]
+ * and finally [X! [A!->X [B->A X] A] B].
*/
if (broken->pending) {
struct mdoc_node *taker;
/*
- * If the breaker had also been broken before,
- * it cannot take on the outer breaker itself,
- * but must hand it on to its own breakers.
- * Graphically, this is the following situation:
- * "[A [B breaker=[C->B B] broken=[D->A A] tok=C] D]"
- * "[A taker=[B->A breaker=[C->B B] [D->C A] C] D]"
+ * If the inner breaker (A) is already broken,
+ * too, it cannot take on the outer breaker (X)
+ * but must hand it on to its own breakers (Y):
+ * [X! [Y! breaker=[A->Y Y] broken=[B->X X] tok=A] B]
+ * [X! take=[Y!->X brea=[A->Y Y] brok=[B X] tok=A] B]
+ * and finally [X! [Y!->X [A!->Y Y] [B->A X] A] B].
*/
taker = breaker;
while (taker->pending)
taker = taker->pending;
taker->pending = broken->pending;
}
+
+ /*
+ * Now we have reduced the situation to the simplest
+ * case, which is just breaker=[A broken=[B tok=A] B]
+ * and becomes [A! [B->A A] B].
+ */
broken->pending = breaker;
+ breaker->flags |= MDOC_BREAK;
mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse, line, ppos,
"%s breaks %s", mdoc_macronames[tok],
mdoc_macronames[broken->tok]);
@@ -1065,8 +1076,8 @@ blk_full(MACRO_PROT_ARGS)
if (tok == MDOC_It) {
for (n = mdoc->last; n; n = n->parent)
- if (n->tok == MDOC_Bl &&
- ! (n->flags & MDOC_VALID))
+ if (n->tok == MDOC_Bl && n->type == MDOC_BLOCK &&
+ ! (n->flags & (MDOC_VALID | MDOC_BREAK)))
break;
if (n == NULL) {
mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,