diff options
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | mandoc.1 | 18 | ||||
-rw-r--r-- | mandoc.h | 1 | ||||
-rw-r--r-- | mandoc_xr.c | 19 | ||||
-rw-r--r-- | mandoc_xr.h | 4 | ||||
-rw-r--r-- | mdoc_validate.c | 14 | ||||
-rw-r--r-- | read.c | 1 |
7 files changed, 52 insertions, 13 deletions
@@ -763,8 +763,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); @@ -816,7 +815,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); } @@ -833,6 +833,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; @@ -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 @@ -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/mandoc_xr.c b/mandoc_xr.c index d69c9c80..4d6b7825 100644 --- a/mandoc_xr.c +++ b/mandoc_xr.c @@ -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/mandoc_xr.h b/mandoc_xr.h index 81601cdb..182dc1ad 100644 --- a/mandoc_xr.h +++ b/mandoc_xr.h @@ -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/mdoc_validate.c b/mdoc_validate.c index a15ce33e..79fbe420 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1104,6 +1104,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 @@ -1169,6 +1171,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)) @@ -2339,8 +2346,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); } @@ -139,6 +139,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", |