+ /*
+ * Explicit blocks close out description lines, but
+ * even those can get broken together with a child.
+ */
+
+ if (n->tok == MDOC_Nd) {
+ if (later != NULL)
+ n->flags |= NODE_BROKEN | NODE_ENDED;
+ else
+ rew_last(mdoc, n);
+ continue;
+ }
+
+ /* Breaking an open sub block. */
+
+ break_intermediate(mdoc->last, body);
+ n->flags |= NODE_BROKEN;
+ if (later == NULL)
+ later = n;
+ }
+
+ if (body == NULL) {
+ mandoc_msg(MANDOCERR_BLK_NOTOPEN, line, ppos,
+ "%s", roff_name[tok]);
+ if (maxargs && endbody == NULL) {
+ /*
+ * Stray .Ec without previous .Eo:
+ * Break the output line, keep the arguments.
+ */
+ roff_elem_alloc(mdoc, line, ppos, ROFF_br);
+ rew_elem(mdoc, ROFF_br);
+ }
+ } else if (endbody == NULL) {
+ rew_last(mdoc, body);
+ if (maxargs)
+ mdoc_tail_alloc(mdoc, line, ppos, atok);
+ }
+
+ if ((mdoc_macro(tok)->flags & MDOC_PARSED) == 0) {
+ if (buf[*pos] != '\0')
+ mandoc_msg(MANDOCERR_ARG_SKIP, line, ppos,
+ "%s %s", roff_name[tok], buf + *pos);
+ if (endbody == NULL && n != NULL)
+ rew_pending(mdoc, n);
+
+ /*
+ * Restore the fill mode that was set before the display.
+ * This needs to be done here rather than during validation
+ * such that subsequent nodes get the right flags.
+ */
+
+ if (tok == MDOC_Ed && body != NULL) {
+ if (body->flags & NODE_NOFILL)
+ mdoc->flags |= ROFF_NOFILL;
+ else
+ mdoc->flags &= ~ROFF_NOFILL;
+ }
+ return;
+ }
+
+ if (endbody != NULL)
+ n = endbody;
+
+ ntok = TOKEN_NONE;
+ for (j = 0; ; j++) {
+ lastarg = *pos;
+
+ if (j == maxargs && n != NULL)
+ rew_last(mdoc, n);
+
+ ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
+ if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
+ break;
+
+ ntok = lookup(mdoc, tok, line, lastarg, p);
+
+ if (ntok == TOKEN_NONE) {
+ dword(mdoc, line, lastarg, p, DELIM_MAX,
+ mdoc_macro(tok)->flags & MDOC_JOIN);
+ if (ac == ARGS_ALLOC)
+ free(p);
+ continue;
+ }
+ if (ac == ARGS_ALLOC)
+ free(p);
+
+ if (n != NULL)
+ rew_last(mdoc, n);
+ mdoc->flags &= ~MDOC_NEWLINE;
+ (*mdoc_macro(ntok)->fp)(mdoc, ntok, line, lastarg, pos, buf);
+ break;
+ }
+
+ if (n != NULL) {
+ pending = 0;
+ if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
+ target = n;
+ do
+ target = target->parent;
+ while ( ! (target->flags & NODE_ENDED));
+ pending = find_pending(mdoc, ntok, line, ppos, target);
+ }
+ if ( ! pending)
+ rew_pending(mdoc, n);
+ }
+ if (nl)
+ append_delims(mdoc, line, pos, buf);
+}
+
+static void
+in_line(MACRO_PROT_ARGS)
+{
+ int la, scope, cnt, firstarg, mayopen, nc, nl;
+ enum roff_tok ntok;
+ enum margserr ac;
+ enum mdelim d;
+ struct mdoc_arg *arg;
+ char *p;