summaryrefslogtreecommitdiffstats
path: root/mdoc_man.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-02-12 12:24:33 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-02-12 12:24:33 +0000
commit33da493a191d7c9f4dd1e96d178eeb11d1218abc (patch)
tree686aa38a2482948a55f21b52b23fc267ac7c729f /mdoc_man.c
parenta5ec4b155fd2b5756e3494144f8347f3ad03d4c1 (diff)
downloadmandoc-33da493a191d7c9f4dd1e96d178eeb11d1218abc.tar.gz
Delete the mdoc_node.pending pointer and the function calculating
it, make_pending(), which was the most difficult function of the whole mdoc(7) parser. After almost five years of maintaining this hellhole, i just noticed the pointer isn't needed after all. Blocks are always rewound in the reverse order they were opened; that even holds for broken blocks. Consequently, it is sufficient to just mark broken blogs with the flag MDOC_BROKEN and breaking blocks with the flag MDOC_ENDED. When rewinding, instead of iterating the pending pointers, just iterate from each broken block to its parents, rewinding all that are MDOC_ENDED and stopping after processing the first ancestor that it not MDOC_BROKEN. For ENDBODY markers, use the mdoc_node.body pointer in place of the former mdoc_node.pending. This also fixes an assertion failure found by jsg@ with afl, test case #467 (Bo Bl It Bd Bc It), where (surprise surprise) the pending pointer got corrupted. Improved functionality, minus one function, minus one struct field, minus 50 lines of code.
Diffstat (limited to 'mdoc_man.c')
-rw-r--r--mdoc_man.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/mdoc_man.c b/mdoc_man.c
index 6bf832e5..5af2bb04 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -29,8 +29,7 @@
#include "mdoc.h"
#include "main.h"
-#define DECL_ARGS const struct mdoc_meta *meta, \
- const struct mdoc_node *n
+#define DECL_ARGS const struct mdoc_meta *meta, struct mdoc_node *n
struct manact {
int (*cond)(DECL_ARGS); /* DON'T run actions */
@@ -548,10 +547,10 @@ void
man_mdoc(void *arg, const struct mdoc *mdoc)
{
const struct mdoc_meta *meta;
- const struct mdoc_node *n;
+ struct mdoc_node *n;
meta = mdoc_meta(mdoc);
- n = mdoc_node(mdoc);
+ n = mdoc_node(mdoc)->child;
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
meta->title,
@@ -567,15 +566,18 @@ man_mdoc(void *arg, const struct mdoc *mdoc)
fontqueue.head = fontqueue.tail = mandoc_malloc(8);
*fontqueue.tail = 'R';
}
- print_node(meta, n);
+ while (n != NULL) {
+ print_node(meta, n);
+ n = n->next;
+ }
putchar('\n');
}
static void
print_node(DECL_ARGS)
{
- const struct mdoc_node *sub;
const struct manact *act;
+ struct mdoc_node *sub;
int cond, do_sub;
/*
@@ -588,6 +590,7 @@ print_node(DECL_ARGS)
act = NULL;
cond = 0;
do_sub = 1;
+ n->flags &= ~MDOC_ENDED;
if (MDOC_TEXT == n->type) {
/*
@@ -635,7 +638,7 @@ print_node(DECL_ARGS)
(*act->post)(meta, n);
if (ENDBODY_NOT != n->end)
- n->pending->flags |= MDOC_ENDED;
+ n->body->flags |= MDOC_ENDED;
if (ENDBODY_NOSPACE == n->end)
outflags &= ~(MMAN_spc | MMAN_nl);