summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmdoc.h3
-rw-r--r--main.c2
-rw-r--r--mandoc.h3
-rw-r--r--mdoc_action.c62
-rw-r--r--mdoc_html.c9
-rw-r--r--mdoc_validate.c168
6 files changed, 116 insertions, 131 deletions
diff --git a/libmdoc.h b/libmdoc.h
index 7406f40a..11f1a8a5 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -118,8 +118,7 @@ const char *mdoc_a2st(const char *);
const char *mdoc_a2arch(const char *);
const char *mdoc_a2vol(const char *);
const char *mdoc_a2msec(const char *);
-int mdoc_valid_pre(struct mdoc *,
- const struct mdoc_node *);
+int mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
int mdoc_valid_post(struct mdoc *);
int mdoc_action_pre(struct mdoc *,
struct mdoc_node *);
diff --git a/main.c b/main.c
index 129675aa..43b2ac86 100644
--- a/main.c
+++ b/main.c
@@ -141,12 +141,12 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"macro requires body argument(s)",
"macro requires argument(s)",
"no title in document",
+ "missing list type",
"line argument(s) will be lost",
"body argument(s) will be lost",
"column syntax is inconsistent",
"missing font type",
"missing display type",
- "missing list type",
"displays may not be nested",
"no scope to rewind: syntax violated",
"scope broken, syntax violated",
diff --git a/mandoc.h b/mandoc.h
index 79776202..82a7c020 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -73,6 +73,7 @@ enum mandocerr {
MANDOCERR_NOBODY, /* macro requires body argument(s) */
MANDOCERR_NOARGV, /* macro requires argument(s) */
MANDOCERR_NOTITLE, /* no title in document */
+ MANDOCERR_LISTTYPE, /* missing list type */
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
#define MANDOCERR_ERROR MANDOCERR_BODYLOST
@@ -83,8 +84,6 @@ enum mandocerr {
/* FIXME: this should be a MANDOCERR_ERROR */
MANDOCERR_DISPTYPE, /* missing display type */
/* FIXME: this should be a MANDOCERR_ERROR */
- MANDOCERR_LISTTYPE, /* missing list type */
- /* FIXME: this should be a MANDOCERR_ERROR */
MANDOCERR_NESTEDDISP, /* displays may not be nested */
MANDOCERR_SYNTNOSCOPE, /* request scope close w/none open */
MANDOCERR_SYNTSCOPE, /* scope broken, syntax violated */
diff --git a/mdoc_action.c b/mdoc_action.c
index 68e04210..43b92d9c 100644
--- a/mdoc_action.c
+++ b/mdoc_action.c
@@ -948,8 +948,7 @@ pre_offset(PRE_ARGS)
* stipulated by mdoc.samples.
*/
- assert(n->args);
- for (i = 0; i < (int)n->args->argc; i++) {
+ for (i = 0; n->args && i < (int)n->args->argc; i++) {
if (MDOC_Offset != n->args->argv[i].arg)
continue;
if (n->args->argv[i].sz)
@@ -969,63 +968,10 @@ pre_offset(PRE_ARGS)
static int
pre_bl(PRE_ARGS)
{
- int pos;
-
- if (MDOC_BLOCK != n->type) {
- assert(n->parent);
- assert(MDOC_BLOCK == n->parent->type);
- assert(MDOC_Bl == n->parent->tok);
- assert(LIST__NONE != n->parent->data.list);
- n->data.list = n->parent->data.list;
- return(1);
- }
-
- assert(LIST__NONE == n->data.list);
-
- for (pos = 0; pos < (int)n->args->argc; pos++) {
- switch (n->args->argv[pos].arg) {
- case (MDOC_Bullet):
- n->data.list = LIST_bullet;
- break;
- case (MDOC_Dash):
- n->data.list = LIST_dash;
- break;
- case (MDOC_Enum):
- n->data.list = LIST_enum;
- break;
- case (MDOC_Hyphen):
- n->data.list = LIST_hyphen;
- break;
- case (MDOC_Item):
- n->data.list = LIST_item;
- break;
- case (MDOC_Tag):
- n->data.list = LIST_tag;
- break;
- case (MDOC_Diag):
- n->data.list = LIST_diag;
- break;
- case (MDOC_Hang):
- n->data.list = LIST_hang;
- break;
- case (MDOC_Ohang):
- n->data.list = LIST_ohang;
- break;
- case (MDOC_Inset):
- n->data.list = LIST_inset;
- break;
- case (MDOC_Column):
- n->data.list = LIST_column;
- break;
- default:
- break;
- }
- if (LIST__NONE != n->data.list)
- break;
- }
- assert(LIST__NONE != n->data.list);
- return(pre_offset(m, n));
+ if (MDOC_BLOCK == n->type)
+ return(pre_offset(m, n));
+ return(1);
}
diff --git a/mdoc_html.c b/mdoc_html.c
index 686c408a..fde75843 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -832,7 +832,6 @@ mdoc_it_block_pre(MDOC_ARGS, enum mdoc_list type, int comp,
struct roffsu su;
nn = n->parent->parent;
- assert(nn->args);
/* XXX: see notes in mdoc_it_pre(). */
@@ -1014,7 +1013,8 @@ mdoc_it_pre(MDOC_ARGS)
/* Get width, offset, and compact arguments. */
- for (wp = -1, comp = i = 0; i < (int)bl->args->argc; i++)
+ wp = -1;
+ for (comp = i = 0; bl->args && i < (int)bl->args->argc; i++)
switch (bl->args->argv[i].arg) {
case (MDOC_Column):
wp = i; /* Save for later. */
@@ -1322,7 +1322,7 @@ mdoc_bd_pre(MDOC_ARGS)
SCALE_VS_INIT(&su, 0);
type = comp = 0;
- for (i = 0; i < (int)bl->args->argc; i++)
+ for (i = 0; bl->args && i < (int)bl->args->argc; i++)
switch (bl->args->argv[i].arg) {
case (MDOC_Offset):
a2offs(bl->args->argv[i].value[0], &su);
@@ -1997,8 +1997,7 @@ mdoc_bf_pre(MDOC_ARGS)
else if ( ! strcmp("Li", n->head->child->string))
PAIR_CLASS_INIT(&tag[0], "lit");
} else {
- assert(n->args);
- for (i = 0; i < (int)n->args->argc; i++)
+ for (i = 0; n->args && i < (int)n->args->argc; i++)
switch (n->args->argv[i].arg) {
case (MDOC_Symbolic):
PAIR_CLASS_INIT(&tag[0], "symb");
diff --git a/mdoc_validate.c b/mdoc_validate.c
index e2e358a5..9f905b69 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -34,7 +34,7 @@
/* FIXME: .Bl -diag can't have non-text children in HEAD. */
/* TODO: ignoring Pp (it's superfluous in some invocations). */
-#define PRE_ARGS struct mdoc *mdoc, const struct mdoc_node *n
+#define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n
#define POST_ARGS struct mdoc *mdoc
typedef int (*v_pre)(PRE_ARGS);
@@ -273,7 +273,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
int
-mdoc_valid_pre(struct mdoc *mdoc, const struct mdoc_node *n)
+mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
{
v_pre *p;
int line, pos;
@@ -535,79 +535,117 @@ pre_display(PRE_ARGS)
static int
pre_bl(PRE_ARGS)
{
- int pos, type, width, offset;
-
- if (MDOC_BLOCK != n->type)
+ int i, width, offs, cmpt, dupl;
+ enum mdoc_list lt;
+
+ if (MDOC_BLOCK != n->type) {
+ assert(n->parent);
+ assert(MDOC_BLOCK == n->parent->type);
+ assert(MDOC_Bl == n->parent->tok);
+ assert(LIST__NONE != n->parent->data.list);
+ n->data.list = n->parent->data.list;
return(1);
- if (NULL == n->args) {
- mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
- return(0);
}
- /* Make sure that only one type of list is specified. */
+ /*
+ * First figure out which kind of list to use: bind ourselves to
+ * the first mentioned list type and warn about any remaining
+ * ones. If we find no list type, we default to LIST_item.
+ */
- type = offset = width = -1;
+ assert(LIST__NONE == n->data.list);
+ offs = width = cmpt = -1;
/* LINTED */
- for (pos = 0; pos < (int)n->args->argc; pos++)
- switch (n->args->argv[pos].arg) {
+ for (i = 0; n->args && i < (int)n->args->argc; i++) {
+ lt = LIST__NONE;
+ dupl = 0;
+ switch (n->args->argv[i].arg) {
+ /* Set list types. */
case (MDOC_Bullet):
- /* FALLTHROUGH */
+ lt = LIST_bullet;
+ break;
case (MDOC_Dash):
- /* FALLTHROUGH */
+ lt = LIST_dash;
+ break;
case (MDOC_Enum):
- /* FALLTHROUGH */
+ lt = LIST_enum;
+ break;
case (MDOC_Hyphen):
- /* FALLTHROUGH */
+ lt = LIST_hyphen;
+ break;
case (MDOC_Item):
- /* FALLTHROUGH */
+ lt = LIST_item;
+ break;
case (MDOC_Tag):
- /* FALLTHROUGH */
+ lt = LIST_tag;
+ break;
case (MDOC_Diag):
- /* FALLTHROUGH */
+ lt = LIST_diag;
+ break;
case (MDOC_Hang):
- /* FALLTHROUGH */
+ lt = LIST_hang;
+ break;
case (MDOC_Ohang):
- /* FALLTHROUGH */
+ lt = LIST_ohang;
+ break;
case (MDOC_Inset):
- /* FALLTHROUGH */
+ lt = LIST_inset;
+ break;
case (MDOC_Column):
- if (type < 0) {
- type = n->args->argv[pos].arg;
- break;
- }
- if (mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
- break;
- return(0);
+ lt = LIST_column;
+ break;
+ /* Set list arguments. */
case (MDOC_Compact):
- if (type >= 0)
- break;
- if (mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
- break;
- return(0);
+ if (cmpt >= 0)
+ dupl++;
+ cmpt = i;
+ break;
case (MDOC_Width):
if (width >= 0)
- if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
- return(0);
- if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
- return(0);
- width = n->args->argv[pos].arg;
+ dupl++;
+ width = i;
break;
case (MDOC_Offset):
- if (offset >= 0)
- if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
- return(0);
- if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
- return(0);
- offset = n->args->argv[pos].arg;
- break;
- default:
+ if (offs >= 0)
+ dupl++;
+ offs = i;
break;
}
- if (type < 0) {
- mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
- return(0);
+ /* Check: duplicate auxiliary arguments. */
+
+ if (dupl)
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+ return(0);
+
+ /* Check: multiple list types. */
+
+ if (LIST__NONE != lt && n->data.list != LIST__NONE)
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
+ return(0);
+
+ /* Assign list type. */
+
+ if (LIST__NONE != lt && n->data.list == LIST__NONE)
+ n->data.list = lt;
+
+ /* The list type should come first. */
+
+ if (n->data.list == LIST__NONE)
+ if (width >= 0 || offs >= 0 || cmpt >= 0)
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
+ return(0);
+
+ continue;
+ }
+
+ /* Allow lists to default to LIST_item. */
+
+ if (LIST__NONE == n->data.list) {
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE))
+ return(0);
+ n->data.list = LIST_item;
}
/*
@@ -616,23 +654,27 @@ pre_bl(PRE_ARGS)
* and must also be warned.
*/
- switch (type) {
- case (MDOC_Tag):
- if (width < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
- return(0);
- break;
- case (MDOC_Column):
+ switch (n->data.list) {
+ case (LIST_tag):
+ if (width >= 0)
+ break;
+ if (mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
+ break;
+ return(0);
+ case (LIST_column):
/* FALLTHROUGH */
- case (MDOC_Diag):
+ case (LIST_diag):
/* FALLTHROUGH */
- case (MDOC_Ohang):
+ case (LIST_ohang):
/* FALLTHROUGH */
- case (MDOC_Inset):
+ case (LIST_inset):
/* FALLTHROUGH */
- case (MDOC_Item):
- if (width >= 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
- return(0);
- break;
+ case (LIST_item):
+ if (width < 0)
+ break;
+ if (mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
+ break;
+ return(0);
default:
break;
}