summaryrefslogtreecommitdiffstats
path: root/mdoc.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2016-08-20 14:43:50 +0000
committerIngo Schwarze <schwarze@openbsd.org>2016-08-20 14:43:50 +0000
commit1a457596e32c18ed30f233db70ab53845b78da17 (patch)
treeba728d15ea8a7695d8039afc404863c66f42ef6d /mdoc.c
parent77517926723f6ebca20f5b22e648a619216bd012 (diff)
downloadmandoc-1a457596e32c18ed30f233db70ab53845b78da17.tar.gz
If a column list starts with implicit rows (that is, rows without .It)
and roff-level nodes (e.g. tbl or eqn) follow, don't run into an assertion. Instead, wrap the roff-level nodes in their own row. Issue found by tb@ with afl(1).
Diffstat (limited to 'mdoc.c')
-rw-r--r--mdoc.c61
1 files changed, 19 insertions, 42 deletions
diff --git a/mdoc.c b/mdoc.c
index dca556e0..2ab53d7b 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2016 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
@@ -219,29 +219,19 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
struct roff_node *n;
char *c, *ws, *end;
- assert(mdoc->last);
n = mdoc->last;
/*
- * Divert directly to list processing if we're encountering a
- * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry
- * (a ROFFT_BODY means it's already open, in which case we should
- * process within its context in the normal way).
+ * If a column list contains plain text, assume an implicit item
+ * macro. This can happen one or more times at the beginning
+ * of such a list, intermixed with non-It mdoc macros and with
+ * nodes generated on the roff level, for example by tbl.
*/
- if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
- n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
- /* `Bl' is open without any children. */
- mdoc->flags |= MDOC_FREECOL;
- mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
- return 1;
- }
-
- if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
- NULL != n->parent &&
- MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->norm->Bl.type) {
- /* `Bl' has block-level `It' children. */
+ if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+ n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+ (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+ n->parent->norm->Bl.type == LIST_column)) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
return 1;
@@ -393,36 +383,23 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
* into macro processing.
*/
- if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
- mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
- return 1;
- }
-
n = mdoc->last;
- assert(mdoc->last);
-
- /*
- * If the first macro of a `Bl -column', open an `It' block
- * context around the parsed macro.
- */
-
- if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
- n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
- mdoc->flags |= MDOC_FREECOL;
- mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
+ if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
+ mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
return 1;
}
/*
- * If we're following a block-level `It' within a `Bl -column'
- * context (perhaps opened in the above block or in ptext()),
- * then open an `It' block context around the parsed macro.
+ * If a column list contains a non-It macro, assume an implicit
+ * item macro. This can happen one or more times at the
+ * beginning of such a list, intermixed with text lines and
+ * with nodes generated on the roff level, for example by tbl.
*/
- if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
- NULL != n->parent &&
- MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->norm->Bl.type) {
+ if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+ n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+ (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+ n->parent->norm->Bl.type == LIST_column)) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
return 1;