diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-04 02:53:51 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-04 02:53:51 +0000 |
commit | b8c7224b007d9673c637669ba26ff55f38effe12 (patch) | |
tree | 27d1ed6e0ae499cceea05feaef09d6f683d86fdd /roff_validate.c | |
parent | 820b4d56427ff6a0f1e3399ac7e4aea447dd5c20 (diff) | |
download | mandoc-b8c7224b007d9673c637669ba26ff55f38effe12.tar.gz mandoc-b8c7224b007d9673c637669ba26ff55f38effe12.tar.zst mandoc-b8c7224b007d9673c637669ba26ff55f38effe12.zip |
Clean up the validation of .Pp, .PP, .sp, and .br. Make sure all
combinations are handled, and are handled in a systematic manner.
This resolves some erratic duplicate handling, handles a number of
missing cases, and improves diagnostics in various respects.
Move validation of .br and .sp to the roff validation module
rather than doing that twice in the mdoc and man validation modules.
Move the node relinking function to the roff library where it belongs.
In validation functions, only look at the node itself, at previous
nodes, and at descendants, not at following nodes or ancestors,
such that only nodes are inspected which are already validated.
Diffstat (limited to 'roff_validate.c')
-rw-r--r-- | roff_validate.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/roff_validate.c b/roff_validate.c index 6a76a1fb..3e301c05 100644 --- a/roff_validate.c +++ b/roff_validate.c @@ -1,4 +1,4 @@ -/* $Id: roff_validate.c,v 1.10 2018/08/10 20:40:45 schwarze Exp $ */ +/* $Id: roff_validate.c,v 1.11 2018/12/04 02:53:51 schwarze Exp $ */ /* * Copyright (c) 2010, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * @@ -29,17 +29,19 @@ typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); +static void roff_valid_br(ROFF_VALID_ARGS); static void roff_valid_ft(ROFF_VALID_ARGS); +static void roff_valid_sp(ROFF_VALID_ARGS); static const roff_valid_fp roff_valids[ROFF_MAX] = { - NULL, /* br */ + roff_valid_br, /* br */ NULL, /* ce */ roff_valid_ft, /* ft */ NULL, /* ll */ NULL, /* mc */ NULL, /* po */ NULL, /* rj */ - NULL, /* sp */ + roff_valid_sp, /* sp */ NULL, /* ta */ NULL, /* ti */ }; @@ -57,6 +59,31 @@ roff_validate(struct roff_man *man) } static void +roff_valid_br(ROFF_VALID_ARGS) +{ + struct roff_node *np; + + if (n->child != NULL) + mandoc_vmsg(MANDOCERR_ARG_SKIP, man->parse, + n->line, n->pos, "br %s", n->child->string); + + if ((np = n->prev) == NULL) + return; + + switch (np->tok) { + case ROFF_br: + case ROFF_sp: + case MDOC_Pp: + mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, + n->line, n->pos, "br after %s", roff_name[np->tok]); + roff_node_delete(man, n); + break; + default: + break; + } +} + +static void roff_valid_ft(ROFF_VALID_ARGS) { const char *cp; @@ -97,3 +124,32 @@ roff_valid_ft(ROFF_VALID_ARGS) n->line, n->pos, "ft %s", cp); roff_node_delete(man, n); } + +static void +roff_valid_sp(ROFF_VALID_ARGS) +{ + struct roff_node *np; + + if (n->child != NULL && n->child->next != NULL) + mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, + n->child->next->line, n->child->next->pos, + "sp ... %s", n->child->next->string); + + if ((np = n->prev) == NULL) + return; + + switch (np->tok) { + case ROFF_br: + mandoc_msg(MANDOCERR_PAR_SKIP, man->parse, + np->line, np->pos, "br before sp"); + roff_node_delete(man, np); + break; + case MDOC_Pp: + mandoc_msg(MANDOCERR_PAR_SKIP, man->parse, + n->line, n->pos, "sp after Pp"); + roff_node_delete(man, n); + break; + default: + break; + } +} |