diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-01-16 19:27:26 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-01-16 19:27:26 +0000 |
commit | b82ba953905f806ce4e5553c1536579080b7352e (patch) | |
tree | 3c36e823156523bc9abbcf91e0ef94a54893e075 /usr.bin | |
parent | 4cb54dc5d7dbc06a06da71e20b14c15d883a8949 (diff) |
Some improvements to error handling from kristaps@:
* Make out-of-context .fi invocations not cause an error, but just a warning.
* Downgrade -man message about ignored empty paragraph to MANDOC_IGNPAR.
* Avoid syntax tree corruption when removing empty block macros.
Triggered by some reports from brad@.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mandoc/main.c | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/man_macro.c | 18 | ||||
-rw-r--r-- | usr.bin/mandoc/man_validate.c | 53 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_macro.c | 13 |
5 files changed, 48 insertions, 42 deletions
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 5165557e587..1d5d405501f 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.67 2011/01/16 01:11:50 schwarze Exp $ */ +/* $Id: main.c,v 1.68 2011/01/16 19:27:25 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> @@ -143,6 +143,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "list type must come first", "tag lists require a width argument", "missing font type", + "skipping end of block that is not open", /* related to bad macro arguments */ "skipping argument", diff --git a/usr.bin/mandoc/man_macro.c b/usr.bin/mandoc/man_macro.c index a30b585b91a..413cbbd56ee 100644 --- a/usr.bin/mandoc/man_macro.c +++ b/usr.bin/mandoc/man_macro.c @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.26 2011/01/04 22:28:17 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.27 2011/01/16 19:27:25 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -103,19 +103,27 @@ rew_warn(struct man *m, struct man_node *n, enum mandocerr er) * will be used if an explicit block scope is being closed out. */ int -man_unscope(struct man *m, const struct man_node *n, +man_unscope(struct man *m, const struct man_node *to, enum mandocerr er) { + struct man_node *n; - assert(n); + assert(to); /* LINTED */ - while (m->last != n) { + while (m->last != to) { + /* + * Save the parent here, because we may delete the + * m->last node in the post-validation phase and reset + * it to m->last->parent, causing a step in the closing + * out to be lost. + */ + n = m->last->parent; if ( ! rew_warn(m, m->last, er)) return(0); if ( ! man_valid_post(m)) return(0); - m->last = m->last->parent; + m->last = n; assert(m->last); } diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c index 6da4350a1f0..77db6986725 100644 --- a/usr.bin/mandoc/man_validate.c +++ b/usr.bin/mandoc/man_validate.c @@ -1,4 +1,4 @@ -/* $Id: man_validate.c,v 1.38 2011/01/04 22:28:17 schwarze Exp $ */ +/* $Id: man_validate.c,v 1.39 2011/01/16 19:27:25 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> @@ -77,12 +77,12 @@ static const struct man_valid man_valids[MAN_MAX] = { { pres_bline, posts_th }, /* TH */ { pres_bline, posts_sec }, /* SH */ { pres_bline, posts_sec }, /* SS */ - { pres_bline, posts_par }, /* TP */ + { pres_bline, NULL }, /* TP */ { pres_bline, posts_par }, /* LP */ { pres_bline, posts_par }, /* PP */ { pres_bline, posts_par }, /* P */ - { pres_bline, posts_par }, /* IP */ - { pres_bline, posts_par }, /* HP */ + { pres_bline, NULL }, /* IP */ + { pres_bline, NULL }, /* HP */ { NULL, NULL }, /* SM */ { NULL, NULL }, /* SB */ { NULL, NULL }, /* BI */ @@ -356,33 +356,22 @@ static int check_par(CHKARGS) { - if (MAN_BODY == n->type) - switch (n->tok) { - case (MAN_IP): - /* FALLTHROUGH */ - case (MAN_HP): - /* FALLTHROUGH */ - case (MAN_TP): - /* Body-less lists are ok. */ - break; - default: - if (0 == n->nchild) - man_nmsg(m, n, MANDOCERR_NOBODY); - break; - } - if (MAN_HEAD == n->type) - switch (n->tok) { - case (MAN_PP): - /* FALLTHROUGH */ - case (MAN_P): - /* FALLTHROUGH */ - case (MAN_LP): - if (n->nchild) - man_nmsg(m, n, MANDOCERR_ARGSLOST); - break; - default: - break; - } + switch (n->type) { + case (MAN_BLOCK): + if (0 == n->body->nchild) + man_node_delete(m, n); + break; + case (MAN_BODY): + if (0 == n->nchild) + man_nmsg(m, n, MANDOCERR_IGNPAR); + break; + case (MAN_HEAD): + if (n->nchild) + man_nmsg(m, n, MANDOCERR_ARGSLOST); + break; + default: + break; + } return(1); } @@ -486,7 +475,7 @@ post_fi(CHKARGS) { if ( ! (MAN_LITERAL & m->flags)) - man_nmsg(m, n, MANDOCERR_NOSCOPE); + man_nmsg(m, n, MANDOCERR_WNOSCOPE); m->flags &= ~MAN_LITERAL; return(1); diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 55dc636cbc5..923b3f774a7 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.30 2011/01/16 01:11:50 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.31 2011/01/16 19:27:25 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -80,6 +80,7 @@ enum mandocerr { MANDOCERR_LISTFIRST, /* list type must come first */ MANDOCERR_NOWIDTHARG, /* tag lists require a width argument */ MANDOCERR_FONTTYPE, /* missing font type */ + MANDOCERR_WNOSCOPE, /* skipping end of block that is not open */ /* related to bad macro arguments */ MANDOCERR_IGNARGV, /* skipping argument */ diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c index 699ebbb92f6..a638ed9445c 100644 --- a/usr.bin/mandoc/mdoc_macro.c +++ b/usr.bin/mandoc/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.62 2011/01/04 22:28:17 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.63 2011/01/16 19:27:25 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> @@ -248,17 +248,24 @@ lookup_raw(const char *p) static int rew_last(struct mdoc *mdoc, const struct mdoc_node *to) { - struct mdoc_node *n; + struct mdoc_node *n, *np; assert(to); mdoc->next = MDOC_NEXT_SIBLING; /* LINTED */ while (mdoc->last != to) { + /* + * Save the parent here, because we may delete the + * m->last node in the post-validation phase and reset + * it to m->last->parent, causing a step in the closing + * out to be lost. + */ + np = mdoc->last->parent; if ( ! mdoc_valid_post(mdoc)) return(0); n = mdoc->last; - mdoc->last = mdoc->last->parent; + mdoc->last = np; assert(mdoc->last); mdoc->last->last = n; } |