=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.216 retrieving revision 1.222 diff -u -p -r1.216 -r1.222 --- mandoc/mdoc_validate.c 2014/06/20 23:02:31 1.216 +++ mandoc/mdoc_validate.c 2014/07/02 19:55:10 1.222 @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.216 2014/06/20 23:02:31 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.222 2014/07/02 19:55:10 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -98,6 +98,8 @@ static int post_bx(POST_ARGS); static int post_defaults(POST_ARGS); static int post_dd(POST_ARGS); static int post_dt(POST_ARGS); +static int post_en(POST_ARGS); +static int post_es(POST_ARGS); static int post_eoln(POST_ARGS); static int post_hyph(POST_ARGS); static int post_ignpar(POST_ARGS); @@ -125,6 +127,7 @@ static int pre_display(PRE_ARGS); static int pre_dt(PRE_ARGS); static int pre_it(PRE_ARGS); static int pre_literal(PRE_ARGS); +static int pre_obsolete(PRE_ARGS); static int pre_os(PRE_ARGS); static int pre_par(PRE_ARGS); static int pre_sh(PRE_ARGS); @@ -145,6 +148,8 @@ static v_post posts_d1[] = { bwarn_ge1, post_hyph, NU static v_post posts_dd[] = { post_dd, post_prol, NULL }; static v_post posts_dl[] = { post_literal, bwarn_ge1, NULL }; static v_post posts_dt[] = { post_dt, post_prol, NULL }; +static v_post posts_en[] = { post_en, NULL }; +static v_post posts_es[] = { post_es, NULL }; static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL }; static v_post posts_hyph[] = { post_hyph, NULL }; static v_post posts_hyphtext[] = { ewarn_ge1, post_hyph, NULL }; @@ -173,6 +178,7 @@ static v_pre pres_dl[] = { pre_literal, pre_display, static v_pre pres_dd[] = { pre_dd, NULL }; static v_pre pres_dt[] = { pre_dt, NULL }; static v_pre pres_it[] = { pre_it, pre_par, NULL }; +static v_pre pres_obsolete[] = { pre_obsolete, NULL }; static v_pre pres_os[] = { pre_os, NULL }; static v_pre pres_pp[] = { pre_par, NULL }; static v_pre pres_sh[] = { pre_sh, NULL }; @@ -214,7 +220,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_nd }, /* Nd */ { NULL, posts_nm }, /* Nm */ { NULL, NULL }, /* Op */ - { NULL, NULL }, /* Ot */ + { pres_obsolete, NULL }, /* Ot */ { NULL, posts_defaults }, /* Pa */ { pres_std, posts_std }, /* Rv */ { NULL, posts_st }, /* St */ @@ -284,7 +290,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Ek */ { NULL, posts_eoln }, /* Bt */ { NULL, NULL }, /* Hf */ - { NULL, NULL }, /* Fr */ + { pres_obsolete, NULL }, /* Fr */ { NULL, posts_eoln }, /* Ud */ { NULL, posts_lb }, /* Lb */ { pres_pp, posts_pp }, /* Lp */ @@ -294,8 +300,8 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Bro */ { NULL, NULL }, /* Brc */ { NULL, posts_text }, /* %C */ - { NULL, NULL }, /* Es */ - { NULL, NULL }, /* En */ + { pres_obsolete, posts_es }, /* Es */ + { pres_obsolete, posts_en }, /* En */ { NULL, NULL }, /* Dx */ { NULL, posts_text }, /* %Q */ { NULL, posts_pp }, /* br */ @@ -585,7 +591,9 @@ pre_display(PRE_ARGS) break; if (node) - mdoc_nmsg(mdoc, n, MANDOCERR_NESTEDDISP); + mandoc_vmsg(MANDOCERR_BD_NEST, + mdoc->parse, n->line, n->pos, + "%s in Bd", mdoc_macronames[n->tok]); return(1); } @@ -931,14 +939,26 @@ pre_std(PRE_ARGS) } static int +pre_obsolete(PRE_ARGS) +{ + + if (MDOC_ELEM == n->type || MDOC_BLOCK == n->type) + mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); + return(1); +} + +static int pre_dt(PRE_ARGS) { if (NULL == mdoc->meta.date || mdoc->meta.os) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dt"); if (mdoc->meta.title) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dt"); return(1); } @@ -948,10 +968,12 @@ pre_os(PRE_ARGS) { if (NULL == mdoc->meta.title || NULL == mdoc->meta.date) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Os"); if (mdoc->meta.os) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Os"); return(1); } @@ -961,10 +983,12 @@ pre_dd(PRE_ARGS) { if (mdoc->meta.title || mdoc->meta.os) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dd"); if (mdoc->meta.date) - mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dd"); return(1); } @@ -1093,7 +1117,8 @@ post_vt(POST_ARGS) for (n = mdoc->last->child; n; n = n->next) if (MDOC_TEXT != n->type) - mdoc_nmsg(mdoc, n, MANDOCERR_CHILD); + mandoc_msg(MANDOCERR_VT_CHILD, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); return(1); } @@ -1224,6 +1249,23 @@ post_an(POST_ARGS) } static int +post_en(POST_ARGS) +{ + + if (MDOC_BLOCK == mdoc->last->type) + mdoc->last->norm->Es = mdoc->last_es; + return(1); +} + +static int +post_es(POST_ARGS) +{ + + mdoc->last_es = mdoc->last; + return(1); +} + +static int post_it(POST_ARGS) { int i, cols; @@ -1346,12 +1388,17 @@ post_bl_block(POST_ARGS) continue; } if (NULL == ni->next) { - mdoc_nmsg(mdoc, nc, MANDOCERR_MOVEPAR); + mandoc_msg(MANDOCERR_PAR_MOVE, + mdoc->parse, nc->line, nc->pos, + mdoc_macronames[nc->tok]); if ( ! mdoc_node_relink(mdoc, nc)) return(0); } else if (0 == n->norm->Bl.comp && LIST_column != n->norm->Bl.type) { - mdoc_nmsg(mdoc, nc, MANDOCERR_IGNPAR); + mandoc_vmsg(MANDOCERR_PAR_SKIP, + mdoc->parse, nc->line, nc->pos, + "%s before It", + mdoc_macronames[nc->tok]); mdoc_node_delete(mdoc, nc); } else break; @@ -1567,7 +1614,9 @@ post_bl(POST_ARGS) continue; } - mdoc_nmsg(mdoc, nchild, MANDOCERR_CHILD); + mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse, + nchild->line, nchild->pos, + mdoc_macronames[nchild->tok]); /* * Move the node out of the Bl block. @@ -1619,12 +1668,13 @@ ebool(struct mdoc *mdoc) { if (NULL == mdoc->last->child) { - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_MACROEMPTY); - mdoc_node_delete(mdoc, mdoc->last); + if (MDOC_Sm == mdoc->last->tok) + mdoc->flags ^= MDOC_SMOFF; return(1); } - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1); + check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2); + assert(MDOC_TEXT == mdoc->last->child->type); if (0 == strcmp(mdoc->last->child->string, "on")) { @@ -1664,9 +1714,10 @@ post_root(POST_ARGS) if (NULL == n->child) mdoc_nmsg(mdoc, n, MANDOCERR_DOC_EMPTY); - else if (MDOC_BLOCK != n->child->type || - MDOC_Sh != n->child->tok) - mdoc_nmsg(mdoc, n->child, MANDOCERR_SEC_BEFORE); + else if (MDOC_Sh != n->child->tok) + mandoc_msg(MANDOCERR_SEC_BEFORE, mdoc->parse, + n->child->line, n->child->pos, + mdoc_macronames[n->child->tok]); return(ret); } @@ -1735,7 +1786,8 @@ post_rs(POST_ARGS) } next = nn->next; - mdoc_nmsg(mdoc, nn, MANDOCERR_CHILD); + mandoc_msg(MANDOCERR_RS_SKIP, mdoc->parse, + nn->line, nn->pos, mdoc_macronames[nn->tok]); mdoc_node_delete(mdoc, nn); } @@ -1858,7 +1910,7 @@ post_ns(POST_ARGS) { if (MDOC_LINE & mdoc->last->flags) - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNNS); + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NS_SKIP); return(1); } @@ -1889,7 +1941,8 @@ post_sh_body(POST_ARGS) */ if (NULL == (n = mdoc->last->child)) { - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC); + mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, + mdoc->last->line, mdoc->last->pos, "empty"); return(1); } @@ -1898,14 +1951,16 @@ post_sh_body(POST_ARGS) continue; if (MDOC_TEXT == n->type) continue; - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC); + mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); } assert(n); if (MDOC_BLOCK == n->type && MDOC_Nd == n->tok) return(1); - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC); + mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); return(1); } @@ -1913,6 +1968,7 @@ static int post_sh_head(POST_ARGS) { struct mdoc_node *n; + const char *goodsec; char *secname; enum mdoc_sec sec; @@ -1931,7 +1987,8 @@ post_sh_head(POST_ARGS) /* The NAME should be first. */ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NAMESECFIRST); + mandoc_msg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, + mdoc->last->line, mdoc->last->pos, secname); /* The SYNOPSIS gets special attention in other areas. */ @@ -1974,10 +2031,12 @@ post_sh_head(POST_ARGS) */ if (sec == mdoc->lastnamed) - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECREP); + mandoc_msg(MANDOCERR_SEC_REP, mdoc->parse, + mdoc->last->line, mdoc->last->pos, secname); if (sec < mdoc->lastnamed) - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECOOO); + mandoc_msg(MANDOCERR_SEC_ORDER, mdoc->parse, + mdoc->last->line, mdoc->last->pos, secname); /* Mark the last named section. */ @@ -1987,10 +2046,12 @@ post_sh_head(POST_ARGS) assert(mdoc->meta.msec); + goodsec = NULL; switch (sec) { case SEC_ERRORS: if (*mdoc->meta.msec == '4') break; + goodsec = "2, 3, 4, 9"; /* FALLTHROUGH */ case SEC_RETURN_VALUES: /* FALLTHROUGH */ @@ -1999,12 +2060,17 @@ post_sh_head(POST_ARGS) break; if (*mdoc->meta.msec == '3') break; + if (NULL == goodsec) + goodsec = "2, 3, 9"; /* FALLTHROUGH */ case SEC_CONTEXT: if (*mdoc->meta.msec == '9') break; - mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse, - mdoc->last->line, mdoc->last->pos, secname); + if (NULL == goodsec) + goodsec = "9"; + mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, + mdoc->last->line, mdoc->last->pos, + "%s for %s only", secname, goodsec); break; default: break; @@ -2024,13 +2090,19 @@ post_ignpar(POST_ARGS) if (NULL != (np = mdoc->last->child)) if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { - mdoc_nmsg(mdoc, np, MANDOCERR_IGNPAR); + mandoc_vmsg(MANDOCERR_PAR_SKIP, + mdoc->parse, np->line, np->pos, + "%s after %s", mdoc_macronames[np->tok], + mdoc_macronames[mdoc->last->tok]); mdoc_node_delete(mdoc, np); } if (NULL != (np = mdoc->last->last)) if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { - mdoc_nmsg(mdoc, np, MANDOCERR_IGNPAR); + mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, + np->line, np->pos, "%s at the end of %s", + mdoc_macronames[np->tok], + mdoc_macronames[mdoc->last->tok]); mdoc_node_delete(mdoc, np); } @@ -2062,7 +2134,10 @@ pre_par(PRE_ARGS) if (MDOC_It == n->tok && n->parent->norm->Bl.comp) return(1); - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNPAR); + mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, + mdoc->last->line, mdoc->last->pos, + "%s before %s", mdoc_macronames[mdoc->last->tok], + mdoc_macronames[n->tok]); mdoc_node_delete(mdoc, mdoc->last); return(1); } @@ -2070,25 +2145,27 @@ pre_par(PRE_ARGS) static int post_par(POST_ARGS) { + struct mdoc_node *np; if (MDOC_ELEM != mdoc->last->type && MDOC_BLOCK != mdoc->last->type) return(1); - if (NULL == mdoc->last->prev) { - if (MDOC_Sh != mdoc->last->parent->tok && - MDOC_Ss != mdoc->last->parent->tok) + if (NULL == (np = mdoc->last->prev)) { + np = mdoc->last->parent; + if (MDOC_Sh != np->tok && MDOC_Ss != np->tok) return(1); } else { - if (MDOC_Pp != mdoc->last->prev->tok && - MDOC_Lp != mdoc->last->prev->tok && + if (MDOC_Pp != np->tok && MDOC_Lp != np->tok && (MDOC_br != mdoc->last->tok || - (MDOC_sp != mdoc->last->prev->tok && - MDOC_br != mdoc->last->prev->tok))) + (MDOC_sp != np->tok && MDOC_br != np->tok))) return(1); } - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNPAR); + mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, + mdoc->last->line, mdoc->last->pos, + "%s after %s", mdoc_macronames[mdoc->last->tok], + mdoc_macronames[np->tok]); mdoc_node_delete(mdoc, mdoc->last); return(1); } @@ -2169,18 +2246,16 @@ post_dt(POST_ARGS) mdoc->meta.title = mdoc->meta.vol = mdoc->meta.arch = NULL; - /* First make all characters uppercase. */ + /* First check that all characters are uppercase. */ if (NULL != (nn = n->child)) for (p = nn->string; *p; p++) { if (toupper((unsigned char)*p) == *p) continue; - - /* - * FIXME: don't be lazy: have this make all - * characters be uppercase and just warn once. - */ - mdoc_nmsg(mdoc, nn, MANDOCERR_TITLE_CASE); + mandoc_msg(MANDOCERR_TITLE_CASE, + mdoc->parse, nn->line, + nn->pos + (p - nn->string), + nn->string); break; } @@ -2224,7 +2299,8 @@ post_dt(POST_ARGS) mdoc->meta.vol = mandoc_strdup(cp); mdoc->meta.msec = mandoc_strdup(nn->string); } else { - mdoc_nmsg(mdoc, n, MANDOCERR_MSEC_BAD); + mandoc_msg(MANDOCERR_MSEC_BAD, mdoc->parse, + nn->line, nn->pos, nn->string); mdoc->meta.vol = mandoc_strdup(nn->string); mdoc->meta.msec = mandoc_strdup(nn->string); } @@ -2246,7 +2322,8 @@ post_dt(POST_ARGS) } else { cp = mdoc_a2arch(nn->string); if (NULL == cp) { - mdoc_nmsg(mdoc, nn, MANDOCERR_ARCH_BAD); + mandoc_msg(MANDOCERR_ARCH_BAD, mdoc->parse, + nn->line, nn->pos, nn->string); free(mdoc->meta.vol); mdoc->meta.vol = mandoc_strdup(nn->string); } else