-
- if (REWIND_THIS != rew_dohalt(tok, MDOC_BLOCK, breaker))
- continue;
- if (MDOC_BODY == broken->type)
- broken = broken->parent;
-
- /*
- * Found the breaker.
- * If another, outer breaker is already pending on
- * the *broken block, 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]".
- */
- 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]"
- */
- taker = breaker;
- while (taker->pending)
- taker = taker->pending;
- taker->pending = broken->pending;
- }
- broken->pending = breaker;
- mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
- "%s breaks %s", mdoc_macronames[tok],
- mdoc_macronames[broken->tok]);
- return(1);
- }
-
- /*
- * Found no matching block for tok.
- * Are you trying to close a block that is not open?
- */
- return(0);
-}
-
-
-static int
-rew_sub(enum mdoc_type t, struct mdoc *mdoc,
- enum mdoct tok, int line, int ppos)
-{
- struct mdoc_node *n;
-
- n = mdoc->last;
- while (n) {
- switch (rew_dohalt(tok, t, n)) {
- case (REWIND_NONE):
- return(1);
- case (REWIND_THIS):
- break;
- case (REWIND_FORCE):
- mandoc_vmsg(MANDOCERR_SCOPEBROKEN, mdoc->parse,
- line, ppos, "%s breaks %s",
- mdoc_macronames[tok],
- mdoc_macronames[n->tok]);
- /* FALLTHROUGH */
- case (REWIND_MORE):
- n = n->parent;
- continue;
- case (REWIND_LATER):
- if (make_pending(n, tok, mdoc, line, ppos) ||
- MDOC_BLOCK != t)
- return(1);
- /* FALLTHROUGH */
- case (REWIND_ERROR):
- mdoc_pmsg(mdoc, line, ppos, MANDOCERR_NOSCOPE);
- return(1);
+ if (n->type == ROFFT_BLOCK &&
+ mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
+ irc = 1;
+ n->flags = NODE_BROKEN;
+ if (target->type == ROFFT_HEAD)
+ target->flags = NODE_ENDED;
+ else if ( ! (target->flags & NODE_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);
+ }