]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_macro.c
When a full block macro gets closed out by a mismatching
[mandoc.git] / mdoc_macro.c
index 92de591291ca76aece97b29a7064544ba873d950..f46feeb0934553f72c7a61a058e1803336b0ed2f 100644 (file)
@@ -1,7 +1,7 @@
-/*     $Id: mdoc_macro.c,v 1.160 2014/12/20 02:26:57 schwarze Exp $ */
+/*     $Id: mdoc_macro.c,v 1.165 2015/02/02 04:04:45 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -363,7 +363,7 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type,
         * When starting to rewind, skip plain text
         * and nodes that have already been rewound.
         */
-       if (MDOC_TEXT == p->type || MDOC_VALID & p->flags)
+       if (p->type == MDOC_TEXT || p->flags & (MDOC_VALID | MDOC_BREAK))
                return(REWIND_MORE);
 
        /*
@@ -746,7 +746,7 @@ blk_exp_close(MACRO_PROT_ARGS)
        atok = rew_alt(tok);
        body = endbody = later = NULL;
        for (n = mdoc->last; n; n = n->parent) {
-               if (n->flags & MDOC_VALID)
+               if (n->flags & (MDOC_VALID | MDOC_BREAK))
                        continue;
 
                /* Remember the start of our own body. */
@@ -1077,8 +1077,9 @@ blk_full(MACRO_PROT_ARGS)
 {
        int               la, nl, parsed;
        struct mdoc_arg  *arg;
-       struct mdoc_node *head; /* save of head macro */
-       struct mdoc_node *body; /* save of body macro */
+       struct mdoc_node *blk; /* Our own block. */
+       struct mdoc_node *head; /* Our own head. */
+       struct mdoc_node *body; /* Our own body. */
        struct mdoc_node *n;
        enum margserr     ac, lac;
        char             *p;
@@ -1118,7 +1119,7 @@ blk_full(MACRO_PROT_ARGS)
         */
 
        mdoc_argv(mdoc, line, tok, &arg, pos, buf);
-       mdoc_block_alloc(mdoc, line, ppos, tok, arg);
+       blk = mdoc_block_alloc(mdoc, line, ppos, tok, arg);
        head = body = NULL;
 
        /*
@@ -1137,7 +1138,7 @@ blk_full(MACRO_PROT_ARGS)
 
        if (tok == MDOC_Nd) {
                head = mdoc_head_alloc(mdoc, line, ppos, tok);
-               rew_sub(MDOC_HEAD, mdoc, tok, line, ppos);
+               rew_last(mdoc, head);
                body = mdoc_body_alloc(mdoc, line, ppos, tok);
        }
 
@@ -1218,6 +1219,8 @@ blk_full(MACRO_PROT_ARGS)
                        break;
        }
 
+       if (blk->flags & MDOC_VALID)
+               return;
        if (head == NULL)
                head = mdoc_head_alloc(mdoc, line, ppos, tok);
        if (nl)
@@ -1274,8 +1277,7 @@ blk_part_imp(MACRO_PROT_ARGS)
         */
 
        blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
-       mdoc_head_alloc(mdoc, line, ppos, tok);
-       rew_sub(MDOC_HEAD, mdoc, tok, line, ppos);
+       rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok));
 
        /*
         * Open the body scope "on-demand", that is, after we've
@@ -1322,10 +1324,21 @@ blk_part_imp(MACRO_PROT_ARGS)
                }
        }
        assert(n == body);
-       rew_sub(MDOC_BODY, mdoc, tok, line, ppos);
+       rew_last(mdoc, body);
        if (nl)
                append_delims(mdoc, line, pos, buf);
-       rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos);
+       rew_last(mdoc, blk);
+
+       /*
+        * The current block extends an enclosing block.
+        * Now that the current block ends, close the enclosing block, too.
+        */
+
+       while ((blk = blk->pending) != NULL) {
+               rew_last(mdoc, blk);
+               if (blk->type == MDOC_HEAD)
+                       mdoc_body_alloc(mdoc, blk->line, blk->pos, blk->tok);
+       }
 
        /* Move trailing .Ns out of scope. */
 
@@ -1341,7 +1354,6 @@ blk_part_exp(MACRO_PROT_ARGS)
        int               la, nl;
        enum margserr     ac;
        struct mdoc_node *head; /* keep track of head */
-       struct mdoc_node *body; /* keep track of body */
        char             *p;
 
        nl = MDOC_NEWLINE & mdoc->flags;
@@ -1353,7 +1365,8 @@ blk_part_exp(MACRO_PROT_ARGS)
         */
 
        mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
-       for (head = body = NULL; ; ) {
+       head = NULL;
+       for (;;) {
                la = *pos;
                ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
                if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
@@ -1363,32 +1376,19 @@ blk_part_exp(MACRO_PROT_ARGS)
 
                if (head == NULL && ac != ARGS_QWORD &&
                    mdoc_isdelim(p) == DELIM_OPEN) {
-                       assert(NULL == body);
                        dword(mdoc, line, la, p, DELIM_OPEN, 0);
                        continue;
                }
 
                if (head == NULL) {
-                       assert(body == NULL);
                        head = mdoc_head_alloc(mdoc, line, ppos, tok);
-               }
-
-               /*
-                * `Eo' gobbles any data into the head, but most other
-                * macros just immediately close out and begin the body.
-                */
-
-               if (body == NULL) {
-                       assert(head);
-                       /* No check whether it's a macro! */
-                       if (tok == MDOC_Eo)
+                       if (tok == MDOC_Eo)  /* Not parsed. */
                                dword(mdoc, line, la, p, DELIM_MAX, 0);
-                       rew_sub(MDOC_HEAD, mdoc, tok, line, ppos);
-                       body = mdoc_body_alloc(mdoc, line, ppos, tok);
+                       rew_last(mdoc, head);
+                       mdoc_body_alloc(mdoc, line, ppos, tok);
                        if (tok == MDOC_Eo)
                                continue;
                }
-               assert(head != NULL && body != NULL);
 
                if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))
                        break;
@@ -1396,11 +1396,8 @@ blk_part_exp(MACRO_PROT_ARGS)
 
        /* Clean-up to leave in a consistent state. */
 
-       if (head == NULL)
-               mdoc_head_alloc(mdoc, line, ppos, tok);
-
-       if (body == NULL) {
-               rew_sub(MDOC_HEAD, mdoc, tok, line, ppos);
+       if (head == NULL) {
+               rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok));
                mdoc_body_alloc(mdoc, line, ppos, tok);
        }
        if (nl)