From 29d7f67c05e949fa36851e9abd8b82edf18268da Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Thu, 11 Sep 2014 23:52:48 +0000 Subject: warn about botched .Xr ordering and punctuation below SEE ALSO; inspired by mdoclint(1) --- usr.bin/mandoc/mandoc.h | 4 ++- usr.bin/mandoc/mdoc_validate.c | 68 +++++++++++++++++++++++++++++++++++++++++- usr.bin/mandoc/read.c | 4 ++- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index ccaaa32fe01..881b65aab91 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.98 2014/09/07 23:24:33 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.99 2014/09/11 23:52:47 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -72,6 +72,8 @@ enum mandocerr { MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */ MANDOCERR_SEC_REP, /* duplicate section title: Sh title */ MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */ + MANDOCERR_XR_ORDER, /* unusual Xr order: ... after ... */ + MANDOCERR_XR_PUNCT, /* unusual Xr punctuation: ... after ... */ MANDOCERR_AN_MISSING, /* AUTHORS section without An macro */ /* related to macros and nesting */ diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index f0c76d64146..2c5c7e1f149 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_validate.c,v 1.164 2014/09/07 23:24:33 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.165 2014/09/11 23:52:47 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -116,6 +116,7 @@ static int post_rs(POST_ARGS); static int post_sh(POST_ARGS); static int post_sh_head(POST_ARGS); static int post_sh_name(POST_ARGS); +static int post_sh_see_also(POST_ARGS); static int post_sh_authors(POST_ARGS); static int post_st(POST_ARGS); static int post_vt(POST_ARGS); @@ -1855,6 +1856,8 @@ post_sh(POST_ARGS) switch (mdoc->lastsec) { case SEC_NAME: return(post_sh_name(mdoc)); + case SEC_SEE_ALSO: + return(post_sh_see_also(mdoc)); case SEC_AUTHORS: return(post_sh_authors(mdoc)); default: @@ -1903,6 +1906,69 @@ post_sh_name(POST_ARGS) return(1); } +static int +post_sh_see_also(POST_ARGS) +{ + const struct mdoc_node *n; + const char *name, *sec; + const char *lastname, *lastsec, *lastpunct; + int cmp; + + n = mdoc->last->child; + lastname = lastsec = lastpunct = NULL; + while (n != NULL) { + if (n->tok != MDOC_Xr || n->nchild < 2) + break; + + /* Process one .Xr node. */ + + name = n->child->string; + sec = n->child->next->string; + if (lastsec != NULL) { + if (lastpunct[0] != ',' || lastpunct[1] != '\0') + mandoc_vmsg(MANDOCERR_XR_PUNCT, + mdoc->parse, n->line, n->pos, + "%s before %s(%s)", lastpunct, + name, sec); + cmp = strcmp(lastsec, sec); + if (cmp > 0) + mandoc_vmsg(MANDOCERR_XR_ORDER, + mdoc->parse, n->line, n->pos, + "%s(%s) after %s(%s)", name, + sec, lastname, lastsec); + else if (cmp == 0 && + strcasecmp(lastname, name) > 0) + mandoc_vmsg(MANDOCERR_XR_ORDER, + mdoc->parse, n->line, n->pos, + "%s after %s", name, lastname); + } + lastname = name; + lastsec = sec; + + /* Process the following node. */ + + n = n->next; + if (n == NULL) + break; + if (n->tok == MDOC_Xr) { + lastpunct = "none"; + continue; + } + if (n->type != MDOC_TEXT) + break; + for (name = n->string; *name != '\0'; name++) + if (isalpha((const unsigned char)*name)) + return(1); + lastpunct = n->string; + if (n->next == NULL) + mandoc_vmsg(MANDOCERR_XR_PUNCT, mdoc->parse, + n->line, n->pos, "%s after %s(%s)", + lastpunct, lastname, lastsec); + n = n->next; + } + return(1); +} + static int child_an(const struct mdoc_node *n) { diff --git a/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c index 0ead04577dc..1d452671fff 100644 --- a/usr.bin/mandoc/read.c +++ b/usr.bin/mandoc/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.62 2014/09/07 23:24:33 schwarze Exp $ */ +/* $OpenBSD: read.c,v 1.63 2014/09/11 23:52:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -111,6 +111,8 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "sections out of conventional order", "duplicate section title", "unexpected section", + "unusual Xr order", + "unusual Xr punctuation", "AUTHORS section without An macro", /* related to macros and nesting */ -- cgit v1.2.3