=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.309 retrieving revision 1.311 diff -u -p -r1.309 -r1.311 --- mandoc/mdoc_validate.c 2016/10/09 18:16:56 1.309 +++ mandoc/mdoc_validate.c 2017/01/08 00:11:24 1.311 @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.309 2016/10/09 18:16:56 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.311 2017/01/08 00:11:24 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010-2016 Ingo Schwarze + * Copyright (c) 2010-2017 Ingo Schwarze * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -103,6 +103,7 @@ static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); static void post_std(POST_ARGS); +static void post_xr(POST_ARGS); static v_post mdoc_valids[MDOC_MAX] = { NULL, /* Ap */ @@ -145,7 +146,7 @@ static v_post mdoc_valids[MDOC_MAX] = { post_st, /* St */ NULL, /* Va */ NULL, /* Vt */ - NULL, /* Xr */ + post_xr, /* Xr */ NULL, /* %A */ post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ NULL, /* %D */ @@ -850,12 +851,11 @@ post_nm(POST_ARGS) n->last->tok == MDOC_Lp)) mdoc_node_relink(mdoc, n->last); - if (mdoc->meta.name != NULL) - return; - - deroff(&mdoc->meta.name, n); - if (mdoc->meta.name == NULL) + deroff(&mdoc->meta.name, n); + + if (mdoc->meta.name == NULL || + (mdoc->lastsec == SEC_NAME && n->child == NULL)) mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, n->line, n->pos, "Nm"); } @@ -1597,8 +1597,12 @@ post_sh_name(POST_ARGS) for (n = mdoc->last->child; n != NULL; n = n->next) { switch (n->tok) { case MDOC_Nm: + if (hasnm && n->child != NULL) + mandoc_vmsg(MANDOCERR_NAMESEC_PUNCT, + mdoc->parse, n->line, n->pos, + "Nm %s", n->child->string); hasnm = 1; - break; + continue; case MDOC_Nd: hasnd = 1; if (n->next != NULL) @@ -1606,14 +1610,19 @@ post_sh_name(POST_ARGS) mdoc->parse, n->line, n->pos, NULL); break; case TOKEN_NONE: - if (hasnm) - break; + if (n->type == ROFFT_TEXT && + n->string[0] == ',' && n->string[1] == '\0' && + n->next != NULL && n->next->tok == MDOC_Nm) { + n = n->next; + continue; + } /* FALLTHROUGH */ default: mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); - break; + continue; } + break; } if ( ! hasnm) @@ -1807,6 +1816,21 @@ post_sh_head(POST_ARGS) } static void +post_xr(POST_ARGS) +{ + struct roff_node *n, *nch; + + n = mdoc->last; + nch = n->child; + if (nch->next == NULL) { + mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse, + n->line, n->pos, "Xr %s", nch->string); + return; + } + assert(nch->next == n->last); +} + +static void post_ignpar(POST_ARGS) { struct roff_node *np; @@ -2002,7 +2026,7 @@ post_dt(POST_ARGS) } } - /* Mandatory second argument: section. */ + /* Mandatory second argument: section. */ if (nn != NULL) nn = nn->next;