aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_validate.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2020-02-27 01:43:52 +0000
committerIngo Schwarze <schwarze@openbsd.org>2020-02-27 01:43:52 +0000
commit88750dda2da444fce307d20d33700d72e7c49c7f (patch)
tree140fdcb1a59ea5418ca8046a300e844dadd832d6 /mdoc_validate.c
parent4e9a246966125ec03e481374634f3448a906235b (diff)
downloadmandoc-88750dda2da444fce307d20d33700d72e7c49c7f.tar.gz
mandoc-88750dda2da444fce307d20d33700d72e7c49c7f.tar.zst
mandoc-88750dda2da444fce307d20d33700d72e7c49c7f.zip
Introduce the concept of nodes that are semantically transparent:
they are skipped when looking for previous or following high-level macros. Examples include roff(7) .ft, .ll, and .ta, mdoc(7) .Sm and .Tg, and man(7) .DT and .PD. Use this concept for a variety of improved decisions in various validators and formatters. While here, * remove a few const qualifiers on struct arguments that caused trouble; * get rid of some more Yoda notation in the vicinity; * and apply some other stylistic improvements in the vicinity. I found this class of issues while considering .Tg patches from kn@.
Diffstat (limited to 'mdoc_validate.c')
-rw-r--r--mdoc_validate.c156
1 files changed, 70 insertions, 86 deletions
diff --git a/mdoc_validate.c b/mdoc_validate.c
index b0b6d6f3..0b90cf09 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.377 2020/01/19 18:02:00 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.378 2020/02/27 01:43:52 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -1760,8 +1760,7 @@ post_bl_head(POST_ARGS)
static void
post_bl(POST_ARGS)
{
- struct roff_node *nparent, *nprev; /* of the Bl block */
- struct roff_node *nblock, *nbody; /* of the Bl */
+ struct roff_node *nbody; /* of the Bl */
struct roff_node *nchild, *nnext; /* of the Bl body */
const char *prev_Er;
int order;
@@ -1782,88 +1781,73 @@ post_bl(POST_ARGS)
if (nbody->end != ENDBODY_NOT)
return;
- nchild = nbody->child;
- if (nchild == NULL) {
- mandoc_msg(MANDOCERR_BLK_EMPTY,
- nbody->line, nbody->pos, "Bl");
- return;
+ /*
+ * Up to the first item, move nodes before the list,
+ * but leave transparent nodes where they are
+ * if they precede an item.
+ * The next non-transparent node is kept in nchild.
+ * It only needs to be updated after a non-transparent
+ * node was moved out, and at the very beginning
+ * when no node at all was moved yet.
+ */
+
+ nchild = mdoc->last;
+ for (;;) {
+ if (nchild == mdoc->last)
+ nchild = roff_node_child(nbody);
+ if (nchild == NULL) {
+ mdoc->last = nbody;
+ mandoc_msg(MANDOCERR_BLK_EMPTY,
+ nbody->line, nbody->pos, "Bl");
+ return;
+ }
+ if (nchild->tok == MDOC_It) {
+ mdoc->last = nbody;
+ break;
+ }
+ mandoc_msg(MANDOCERR_BL_MOVE, nbody->child->line,
+ nbody->child->pos, "%s", roff_name[nbody->child->tok]);
+ if (nbody->parent->prev == NULL) {
+ mdoc->last = nbody->parent->parent;
+ mdoc->next = ROFF_NEXT_CHILD;
+ } else {
+ mdoc->last = nbody->parent->prev;
+ mdoc->next = ROFF_NEXT_SIBLING;
+ }
+ roff_node_relink(mdoc, nbody->child);
}
+
+ /*
+ * We have reached the first item,
+ * so moving nodes out is no longer possible.
+ * But 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.
+ * Wrap such roff nodes into an implicit row.
+ */
+
while (nchild != NULL) {
- nnext = nchild->next;
- if (nchild->tok == MDOC_It ||
- ((nchild->tok == MDOC_Sm || nchild->tok == MDOC_Tg) &&
- nnext != NULL && nnext->tok == MDOC_It)) {
- nchild = nnext;
+ if (nchild->tok == MDOC_It) {
+ nchild = roff_node_next(nchild);
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);
+ nnext = nchild->next;
+ mdoc->last = nchild->prev;
+ 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) {
+ roff_node_relink(mdoc, nchild);
+ if (nnext == NULL)
+ break;
+ nchild = nnext;
+ nnext = nchild->next;
mdoc->next = ROFF_NEXT_SIBLING;
- roff_body_alloc(mdoc, nchild->line,
- nchild->pos, MDOC_It);
- while (nchild->tok != MDOC_It) {
- roff_node_relink(mdoc, nchild);
- if ((nchild = nnext) == NULL)
- break;
- nnext = nchild->next;
- mdoc->next = ROFF_NEXT_SIBLING;
- }
- mdoc->last = nbody;
- continue;
}
-
- mandoc_msg(MANDOCERR_BL_MOVE, nchild->line, nchild->pos,
- "%s", roff_name[nchild->tok]);
-
- /*
- * Move the node out of the Bl block.
- * First, collect all required node pointers.
- */
-
- nblock = nbody->parent;
- nprev = nblock->prev;
- nparent = nblock->parent;
-
- /*
- * Unlink this child.
- */
-
- nbody->child = nnext;
- if (nnext == NULL)
- nbody->last = NULL;
- else
- nnext->prev = NULL;
-
- /*
- * Relink this child.
- */
-
- nchild->parent = nparent;
- nchild->prev = nprev;
- nchild->next = nblock;
-
- nblock->prev = nchild;
- if (nprev == NULL)
- nparent->child = nchild;
- else
- nprev->next = nchild;
-
- nchild = nnext;
+ mdoc->last = nbody;
}
if (mdoc->meta.os_e != MANDOC_OS_NETBSD)
@@ -2500,20 +2484,20 @@ post_ignpar(POST_ARGS)
static void
post_prevpar(POST_ARGS)
{
- struct roff_node *n;
+ struct roff_node *n, *np;
n = mdoc->last;
- if (NULL == n->prev)
- return;
if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK)
return;
+ if ((np = roff_node_prev(n)) == NULL)
+ return;
/*
* Don't allow `Pp' prior to a paragraph-type
* block: `Pp' or non-compact `Bd' or `Bl'.
*/
- if (n->prev->tok != MDOC_Pp && n->prev->tok != ROFF_br)
+ if (np->tok != MDOC_Pp && np->tok != ROFF_br)
return;
if (n->tok == MDOC_Bl && n->norm->Bl.comp)
return;
@@ -2522,9 +2506,9 @@ post_prevpar(POST_ARGS)
if (n->tok == MDOC_It && n->parent->norm->Bl.comp)
return;
- mandoc_msg(MANDOCERR_PAR_SKIP, n->prev->line, n->prev->pos,
- "%s before %s", roff_name[n->prev->tok], roff_name[n->tok]);
- roff_node_delete(mdoc, n->prev);
+ mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos,
+ "%s before %s", roff_name[np->tok], roff_name[n->tok]);
+ roff_node_delete(mdoc, np);
}
static void