- struct mdoc_node *n;
-
- mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse, line, ppos,
- "%s breaks %s", mdoc_macronames[breaker->tok],
- mdoc_macronames[broken->tok]);
-
- /*
- * If the *broken block (Z) is already broken by a block (B)
- * contained in the breaker (A), make the breaker pending
- * on that inner breaker (B). Graphically,
- *
- * breaker=[A! broken=n=[B!->A (old broken=)[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!).
- */
-
- for (n = broken->parent; ; n = n->parent)
- if (n == broken->pending)
- broken = n;
- else if (n == breaker)
- break;
-
- /*
- * Found the breaker.
- *
- * 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 (A). Graphically,
- *
- * [X! n=breaker=[A!->X broken=[B(->X)->A X] A] B].
- */
-
- if (broken->pending != NULL) {
- n = breaker;
-
- /*
- * 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). Graphically,
- *
- * [X! n=[Y!->X breaker=[A!->Y Y] broken=[B(->X)->A X] A] B]
- */
-
- while (n->pending)
- n = n->pending;
- n->pending = broken->pending;
+ struct roff_node *n;
+ int irc;
+
+ irc = 0;
+ for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
+ if (n->flags & MDOC_ENDED) {
+ if ( ! (n->flags & MDOC_VALID))
+ n->flags |= MDOC_BROKEN;
+ continue;
+ }
+ if (n->type == ROFFT_BLOCK &&
+ mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
+ irc = 1;
+ n->flags = MDOC_BROKEN;
+ if (target->type == ROFFT_HEAD)
+ target->flags = MDOC_ENDED;
+ else if ( ! (target->flags & MDOC_ENDED)) {
+ mandoc_vmsg(MANDOCERR_BLK_NEST,
+ mdoc->parse, line, ppos,
+ "%s breaks %s", mdoc_macronames[tok],
+ mdoc_macronames[n->tok]);
+ mdoc_endbody_alloc(mdoc, line, ppos,
+ tok, target, ENDBODY_NOSPACE);
+ }
+ }