From: schwarze Date: Sun, 2 Jul 2017 15:31:48 +0000 (+0000) Subject: add warning "cross reference to self"; inspired by mdoclint X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=52d11c96fcb0278e6304df5b6a20e5034ea158a4;p=openbsd add warning "cross reference to self"; inspired by mdoclint --- diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 23e79aa7e05..ed40dff9fa9 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.199 2017/07/01 12:53:56 schwarze Exp $ */ +/* $OpenBSD: main.c,v 1.200 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze @@ -733,8 +733,7 @@ parse(struct curparse *curp, int fd, const char *file) if (man == NULL) return; - if (curp->mmin < MANDOCERR_STYLE) - mandoc_xr_reset(); + mandoc_xr_reset(); if (man->macroset == MACROSET_MDOC) { if (curp->outtype != OUTT_TREE || !curp->outopts->noval) mdoc_validate(man); @@ -786,7 +785,8 @@ parse(struct curparse *curp, int fd, const char *file) break; } } - check_xr(file); + if (curp->mmin < MANDOCERR_STYLE) + check_xr(file); mparse_updaterc(curp->mp, &rc); } @@ -803,6 +803,8 @@ check_xr(const char *file) manpath_base(&paths); for (xr = mandoc_xr_get(); xr != NULL; xr = xr->next) { + if (xr->line == -1) + continue; search.arch = NULL; search.sec = xr->sec; search.outkey = NULL; diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1 index 2e4ceffbe4e..1304a3fae47 100644 --- a/usr.bin/mandoc/mandoc.1 +++ b/usr.bin/mandoc/mandoc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mandoc.1,v 1.134 2017/07/01 09:47:23 schwarze Exp $ +.\" $OpenBSD: mandoc.1,v 1.135 2017/07/02 15:31:48 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2012, 2014-2017 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 1 2017 $ +.Dd $Mdocdate: July 2 2017 $ .Dt MANDOC 1 .Os .Sh NAME @@ -1097,6 +1097,24 @@ The same standard section title occurs more than once. .Pq mdoc A standard section header occurs in a section of the manual where it normally isn't useful. +.It Sy "cross reference to self" +.Pq mdoc +An +.Ic \&Xr +macro refers to a name and section matching the section of the present +manual page and a name mentioned in an +.Ic \&Nm +macro in the NAME or SYNOPSIS section, or in an +.Ic \&Fn +or +.Ic \&Fo +macro in the SYNOPSIS. +Consider using +.Ic \&Nm +or +.Ic \&Fn +instead of +.Ic \&Xr . .It Sy "unusual Xr order" .Pq mdoc In the SEE ALSO section, an diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 72c7fe7e83a..a4443df99d9 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.180 2017/07/01 09:47:23 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.181 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -97,6 +97,7 @@ 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_SELF, /* cross reference to self: Xr name sec */ MANDOCERR_XR_ORDER, /* unusual Xr order: ... after ... */ MANDOCERR_XR_PUNCT, /* unusual Xr punctuation: ... after ... */ MANDOCERR_AN_MISSING, /* AUTHORS section without An macro */ diff --git a/usr.bin/mandoc/mandoc_xr.c b/usr.bin/mandoc/mandoc_xr.c index 178666319f6..a8564693579 100644 --- a/usr.bin/mandoc/mandoc_xr.c +++ b/usr.bin/mandoc/mandoc_xr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc_xr.c,v 1.1 2017/07/01 09:47:23 schwarze Exp $ */ +/* $OpenBSD: mandoc_xr.c,v 1.2 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze * @@ -59,17 +59,18 @@ mandoc_xr_reset(void) xr_first = xr_last = NULL; } -void +int mandoc_xr_add(const char *sec, const char *name, int line, int pos) { - struct mandoc_xr *xr; + struct mandoc_xr *xr, *oxr; const char *pend; size_t ssz, nsz, tsz; unsigned int slot; + int ret; uint32_t hv; if (xr_hash == NULL) - return; + return 0; ssz = strlen(sec) + 1; nsz = strlen(name) + 1; @@ -86,15 +87,21 @@ mandoc_xr_add(const char *sec, const char *name, int line, int pos) pend = xr->hashkey + tsz; hv = ohash_interval(xr->hashkey, &pend); slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv); - if (ohash_find(xr_hash, slot) == NULL) { + if ((oxr = ohash_find(xr_hash, slot)) == NULL) { ohash_insert(xr_hash, slot, xr); if (xr_first == NULL) xr_first = xr; else xr_last->next = xr; xr_last = xr; - } else - free(xr); + return 0; + } + + ret = (oxr->line == -1) ^ (xr->line == -1); + if (xr->line == -1) + oxr->line = -1; + free(xr); + return ret; } struct mandoc_xr * diff --git a/usr.bin/mandoc/mandoc_xr.h b/usr.bin/mandoc/mandoc_xr.h index 1c9b04345d6..4bd8abaf513 100644 --- a/usr.bin/mandoc/mandoc_xr.h +++ b/usr.bin/mandoc/mandoc_xr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc_xr.h,v 1.1 2017/07/01 09:47:23 schwarze Exp $ */ +/* $OpenBSD: mandoc_xr.h,v 1.2 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze * @@ -19,12 +19,12 @@ struct mandoc_xr { struct mandoc_xr *next; char *sec; char *name; - int line; + int line; /* Or -1 for this page's own names. */ int pos; char hashkey[]; }; void mandoc_xr_reset(void); -void mandoc_xr_add(const char *, const char *, int, int); +int mandoc_xr_add(const char *, const char *, int, int); struct mandoc_xr *mandoc_xr_get(void); void mandoc_xr_free(void); diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index f0b1d6fccc3..a8ec7038967 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.261 2017/07/01 09:47:23 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.262 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -1089,6 +1089,8 @@ post_fname(POST_ARGS) if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*'))) mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse, n->line, n->pos + pos, n->string); + if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL) + mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1); } static void @@ -1154,6 +1156,11 @@ post_nm(POST_ARGS) n = mdoc->last; + if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) && + n->child != NULL && n->child->type == ROFFT_TEXT && + mdoc->meta.msec != NULL) + mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1); + if (n->last != NULL && (n->last->tok == MDOC_Pp || n->last->tok == MDOC_Lp)) @@ -2324,8 +2331,11 @@ post_xr(POST_ARGS) n->line, n->pos, "Xr %s", nch->string); } else { assert(nch->next == n->last); - mandoc_xr_add(nch->next->string, nch->string, - nch->line, nch->pos); + if(mandoc_xr_add(nch->next->string, nch->string, + nch->line, nch->pos)) + mandoc_vmsg(MANDOCERR_XR_SELF, mdoc->parse, + nch->line, nch->pos, "Xr %s %s", + nch->string, nch->next->string); } post_delim(mdoc); } diff --git a/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c index 8c848f1a69e..5e341726f81 100644 --- a/usr.bin/mandoc/read.c +++ b/usr.bin/mandoc/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.156 2017/07/01 09:47:23 schwarze Exp $ */ +/* $OpenBSD: read.c,v 1.157 2017/07/02 15:31:48 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -135,6 +135,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "sections out of conventional order", "duplicate section title", "unexpected section", + "cross reference to self", "unusual Xr order", "unusual Xr punctuation", "AUTHORS section without An macro",