]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_validate.c
The termination condition of the iteration logic in page_bymacro()
[mandoc.git] / mdoc_validate.c
index 832832fbc9a4dc2ba5d318b662f9c99838bed114..803d5bce8ed3db67deee005397eb5ccb535150c1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.305 2016/08/10 20:17:50 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.309 2016/10/09 18:16:56 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
@@ -67,7 +67,6 @@ static        void     post_bf(POST_ARGS);
 static void     post_bk(POST_ARGS);
 static void     post_bl(POST_ARGS);
 static void     post_bl_block(POST_ARGS);
-static void     post_bl_block_tag(POST_ARGS);
 static void     post_bl_head(POST_ARGS);
 static void     post_bl_norm(POST_ARGS);
 static void     post_bx(POST_ARGS);
@@ -886,9 +885,11 @@ post_display(POST_ARGS)
        n = mdoc->last;
        switch (n->type) {
        case ROFFT_BODY:
-               if (n->end != ENDBODY_NOT)
-                       break;
-               if (n->child == NULL)
+               if (n->end != ENDBODY_NOT) {
+                       if (n->tok == MDOC_Bd &&
+                           n->body->parent->args == NULL)
+                               roff_node_delete(mdoc, n);
+               } else if (n->child == NULL)
                        mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
                            n->line, n->pos, mdoc_macronames[n->tok]);
                else if (n->tok == MDOC_D1)
@@ -1097,22 +1098,7 @@ post_bl_block(POST_ARGS)
 
        post_prevpar(mdoc);
 
-       /*
-        * These are fairly complicated, so we've broken them into two
-        * functions.  post_bl_block_tag() is called when a -tag is
-        * specified, but no -width (it must be guessed).  The second
-        * when a -width is specified (macro indicators must be
-        * rewritten into real lengths).
-        */
-
        n = mdoc->last;
-
-       if (n->norm->Bl.type == LIST_tag &&
-           n->norm->Bl.width == NULL) {
-               post_bl_block_tag(mdoc);
-               assert(n->norm->Bl.width != NULL);
-       }
-
        for (ni = n->body->child; ni != NULL; ni = ni->next) {
                if (ni->body == NULL)
                        continue;
@@ -1169,71 +1155,6 @@ rewrite_macro2len(char **arg)
        mandoc_asprintf(arg, "%zun", width);
 }
 
-static void
-post_bl_block_tag(POST_ARGS)
-{
-       struct roff_node *n, *nn;
-       size_t            sz, ssz;
-       int               i;
-       char              buf[24];
-
-       /*
-        * Calculate the -width for a `Bl -tag' list if it hasn't been
-        * provided.  Uses the first head macro.  NOTE AGAIN: this is
-        * ONLY if the -width argument has NOT been provided.  See
-        * rewrite_macro2len() for converting the -width string.
-        */
-
-       sz = 10;
-       n = mdoc->last;
-
-       for (nn = n->body->child; nn != NULL; nn = nn->next) {
-               if (nn->tok != MDOC_It)
-                       continue;
-
-               assert(nn->type == ROFFT_BLOCK);
-               nn = nn->head->child;
-
-               if (nn == NULL)
-                       break;
-
-               if (nn->type == ROFFT_TEXT) {
-                       sz = strlen(nn->string) + 1;
-                       break;
-               }
-
-               if (0 != (ssz = macro2len(nn->tok)))
-                       sz = ssz;
-
-               break;
-       }
-
-       /* Defaults to ten ens. */
-
-       (void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz);
-
-       /*
-        * We have to dynamically add this to the macro's argument list.
-        * We're guaranteed that a MDOC_Width doesn't already exist.
-        */
-
-       assert(n->args != NULL);
-       i = (int)(n->args->argc)++;
-
-       n->args->argv = mandoc_reallocarray(n->args->argv,
-           n->args->argc, sizeof(struct mdoc_argv));
-
-       n->args->argv[i].arg = MDOC_Width;
-       n->args->argv[i].line = n->line;
-       n->args->argv[i].pos = n->pos;
-       n->args->argv[i].sz = 1;
-       n->args->argv[i].value = mandoc_malloc(sizeof(char *));
-       n->args->argv[i].value[0] = mandoc_strdup(buf);
-
-       /* Set our width! */
-       n->norm->Bl.width = n->args->argv[i].value[0];
-}
-
 static void
 post_bl_head(POST_ARGS)
 {
@@ -1327,11 +1248,41 @@ post_bl(POST_ARGS)
                return;
        }
        while (nchild != NULL) {
+               nnext = nchild->next;
                if (nchild->tok == MDOC_It ||
                    (nchild->tok == MDOC_Sm &&
-                    nchild->next != NULL &&
-                    nchild->next->tok == MDOC_It)) {
-                       nchild = nchild->next;
+                    nnext != NULL && nnext->tok == MDOC_It)) {
+                       nchild = nnext;
+                       continue;
+               }
+
+               /*
+                * In .Bl -column, the first rows may be implicit,
+                * that is, they may not start with .It macros.
+                * Such rows may be followed by nodes generated on the
+                * roff level, for example .TS, which cannot be moved
+                * out of the list.  In that case, wrap such roff nodes
+                * into an implicit row.
+                */
+
+               if (nchild->prev != NULL) {
+                       mdoc->last = nchild;
+                       mdoc->next = ROFF_NEXT_SIBLING;
+                       roff_block_alloc(mdoc, nchild->line,
+                           nchild->pos, MDOC_It);
+                       roff_head_alloc(mdoc, nchild->line,
+                           nchild->pos, MDOC_It);
+                       mdoc->next = ROFF_NEXT_SIBLING;
+                       roff_body_alloc(mdoc, nchild->line,
+                           nchild->pos, MDOC_It);
+                       while (nchild->tok != MDOC_It) {
+                               mdoc_node_relink(mdoc, nchild);
+                               if ((nchild = nnext) == NULL)
+                                       break;
+                               nnext = nchild->next;
+                               mdoc->next = ROFF_NEXT_SIBLING;
+                       }
+                       mdoc->last = nbody;
                        continue;
                }
 
@@ -1347,13 +1298,11 @@ post_bl(POST_ARGS)
                nblock  = nbody->parent;
                nprev   = nblock->prev;
                nparent = nblock->parent;
-               nnext   = nchild->next;
 
                /*
                 * Unlink this child.
                 */
 
-               assert(nchild->prev == NULL);
                nbody->child = nnext;
                if (nnext == NULL)
                        nbody->last  = NULL;