=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.271 retrieving revision 1.276 diff -u -p -r1.271 -r1.276 --- mandoc/mdoc_validate.c 2015/02/05 01:46:56 1.271 +++ mandoc/mdoc_validate.c 2015/02/06 16:06:25 1.276 @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.271 2015/02/05 01:46:56 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.276 2015/02/06 16:06:25 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -56,8 +56,6 @@ struct valids { v_post post; }; -static void check_count(struct mdoc *, enum mdoc_type, - enum check_ineq, int); static void check_text(struct mdoc *, int, int, char *); static void check_argv(struct mdoc *, struct mdoc_node *, struct mdoc_argv *); @@ -67,10 +65,6 @@ static enum mdoc_sec a2sec(const char *); static size_t macro2len(enum mdoct); static void rewrite_macro2len(char **); -static void bwarn_ge1(POST_ARGS); -static void ewarn_eq1(POST_ARGS); -static void ewarn_ge1(POST_ARGS); - static void post_an(POST_ARGS); static void post_at(POST_ARGS); static void post_bf(POST_ARGS); @@ -93,7 +87,6 @@ static void post_fn(POST_ARGS); static void post_fname(POST_ARGS); static void post_fo(POST_ARGS); static void post_hyph(POST_ARGS); -static void post_hyphtext(POST_ARGS); static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); @@ -151,12 +144,12 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Ev */ { pre_std, post_ex }, /* Ex */ { NULL, post_fa }, /* Fa */ - { NULL, ewarn_ge1 }, /* Fd */ + { NULL, NULL }, /* Fd */ { NULL, NULL }, /* Fl */ { NULL, post_fn }, /* Fn */ { NULL, NULL }, /* Ft */ { NULL, NULL }, /* Ic */ - { NULL, ewarn_eq1 }, /* In */ + { NULL, NULL }, /* In */ { NULL, post_defaults }, /* Li */ { NULL, post_nd }, /* Nd */ { NULL, post_nm }, /* Nm */ @@ -167,18 +160,18 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, post_st }, /* St */ { NULL, NULL }, /* Va */ { NULL, post_vt }, /* Vt */ - { NULL, ewarn_ge1 }, /* Xr */ - { NULL, ewarn_ge1 }, /* %A */ - { NULL, post_hyphtext }, /* %B */ /* FIXME: can be used outside Rs/Re. */ - { NULL, ewarn_ge1 }, /* %D */ - { NULL, ewarn_ge1 }, /* %I */ - { NULL, ewarn_ge1 }, /* %J */ - { NULL, post_hyphtext }, /* %N */ - { NULL, post_hyphtext }, /* %O */ - { NULL, ewarn_ge1 }, /* %P */ - { NULL, post_hyphtext }, /* %R */ - { NULL, post_hyphtext }, /* %T */ /* FIXME: can be used outside Rs/Re. */ - { NULL, ewarn_ge1 }, /* %V */ + { NULL, NULL }, /* Xr */ + { NULL, NULL }, /* %A */ + { NULL, post_hyph }, /* %B */ /* FIXME: can be used outside Rs/Re. */ + { NULL, NULL }, /* %D */ + { NULL, NULL }, /* %I */ + { NULL, NULL }, /* %J */ + { NULL, post_hyph }, /* %N */ + { NULL, post_hyph }, /* %O */ + { NULL, NULL }, /* %P */ + { NULL, post_hyph }, /* %R */ + { NULL, post_hyph }, /* %T */ /* FIXME: can be used outside Rs/Re. */ + { NULL, NULL }, /* %V */ { NULL, NULL }, /* Ac */ { NULL, NULL }, /* Ao */ { NULL, NULL }, /* Aq */ @@ -240,14 +233,14 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Brq */ { NULL, NULL }, /* Bro */ { NULL, NULL }, /* Brc */ - { NULL, ewarn_ge1 }, /* %C */ + { NULL, NULL }, /* %C */ { pre_obsolete, post_es }, /* Es */ { pre_obsolete, post_en }, /* En */ { NULL, NULL }, /* Dx */ - { NULL, ewarn_ge1 }, /* %Q */ + { NULL, NULL }, /* %Q */ { NULL, post_par }, /* br */ { NULL, post_par }, /* sp */ - { NULL, ewarn_eq1 }, /* %U */ + { NULL, NULL }, /* %U */ { NULL, NULL }, /* Ta */ { NULL, NULL }, /* ll */ }; @@ -367,59 +360,6 @@ mdoc_valid_post(struct mdoc *mdoc) } static void -check_count(struct mdoc *mdoc, enum mdoc_type type, - enum check_ineq ineq, int val) -{ - const char *p; - - if (mdoc->last->type != type) - return; - - switch (ineq) { - case CHECK_LT: - p = "less than "; - if (mdoc->last->nchild < val) - return; - break; - case CHECK_GT: - p = "more than "; - if (mdoc->last->nchild > val) - return; - break; - case CHECK_EQ: - p = ""; - if (val == mdoc->last->nchild) - return; - break; - default: - abort(); - /* NOTREACHED */ - } - - mandoc_vmsg(MANDOCERR_ARGCWARN, mdoc->parse, mdoc->last->line, - mdoc->last->pos, "want %s%d children (have %d)", - p, val, mdoc->last->nchild); -} - -static void -bwarn_ge1(POST_ARGS) -{ - check_count(mdoc, MDOC_BODY, CHECK_GT, 0); -} - -static void -ewarn_eq1(POST_ARGS) -{ - check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1); -} - -static void -ewarn_ge1(POST_ARGS) -{ - check_count(mdoc, MDOC_ELEM, CHECK_GT, 0); -} - -static void check_args(struct mdoc *mdoc, struct mdoc_node *n) { int i; @@ -927,7 +867,6 @@ post_lb(POST_ARGS) const char *stdlibname; char *libname; - check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1); n = mdoc->last->child; assert(MDOC_TEXT == n->type); @@ -980,11 +919,27 @@ post_fn(POST_ARGS) static void post_fo(POST_ARGS) { + const struct mdoc_node *n; - check_count(mdoc, MDOC_HEAD, CHECK_EQ, 1); - bwarn_ge1(mdoc); - if (mdoc->last->type == MDOC_HEAD && mdoc->last->nchild) - post_fname(mdoc); + n = mdoc->last; + + if (n->type != MDOC_HEAD) + return; + + if (n->child == NULL) { + mandoc_msg(MANDOCERR_FO_NOHEAD, mdoc->parse, + n->line, n->pos, "Fo"); + return; + } + if (n->child != n->last) { + mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, + n->child->next->line, n->child->next->pos, + "Fo ... %s", n->child->next->string); + while (n->child != n->last) + mdoc_node_delete(mdoc, n->last); + } + + post_fname(mdoc); } static void @@ -1072,26 +1027,40 @@ post_nd(POST_ARGS) static void post_d1(POST_ARGS) { + struct mdoc_node *n; - bwarn_ge1(mdoc); + n = mdoc->last; + + if (n->type != MDOC_BODY) + return; + + if (n->child == NULL) + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, + n->line, n->pos, "D1"); + post_hyph(mdoc); } static void post_literal(POST_ARGS) { + struct mdoc_node *n; - bwarn_ge1(mdoc); + n = mdoc->last; - /* - * The `Dl' (note "el" not "one") and `Bd' macros unset the - * MDOC_LITERAL flag as they leave. Note that `Bd' only sets - * this in literal mode, but it doesn't hurt to just switch it - * off in general since displays can't be nested. - */ + if (n->type != MDOC_BODY) + return; - if (MDOC_BODY == mdoc->last->type) - mdoc->flags &= ~MDOC_LITERAL; + if (n->child == NULL) + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); + + if (n->tok == MDOC_Bd && + n->norm->Bd.type != DISP_literal && + n->norm->Bd.type != DISP_unfilled) + return; + + mdoc->flags &= ~MDOC_LITERAL; } static void @@ -1252,9 +1221,9 @@ post_it(POST_ARGS) i++; if (i < cols || i > cols + 1) - mandoc_vmsg(MANDOCERR_ARGCOUNT, + mandoc_vmsg(MANDOCERR_BL_COL, mdoc->parse, nit->line, nit->pos, - "columns == %d (have %d)", cols, i); + "%d columns, %d cells", cols, i); break; default: abort(); @@ -1488,10 +1457,13 @@ post_bl(POST_ARGS) return; } - bwarn_ge1(mdoc); - nchild = nbody->child; - while (NULL != nchild) { + if (nchild == NULL) { + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, + nbody->line, nbody->pos, "Bl"); + return; + } + while (nchild != NULL) { if (nchild->tok == MDOC_It || (nchild->tok == MDOC_Sm && nchild->next != NULL && @@ -1555,7 +1527,7 @@ post_bk(POST_ARGS) n = mdoc->last; if (n->type == MDOC_BLOCK && n->body->child == NULL) { - mandoc_msg(MANDOCERR_MACRO_EMPTY, + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, n->line, n->pos, "Bk"); mdoc_node_delete(mdoc, n); } @@ -1640,13 +1612,6 @@ post_st(POST_ARGS) n = mdoc->last; nch = n->child; - if (NULL == nch) { - mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); - mdoc_node_delete(mdoc, n); - return; - } - assert(MDOC_TEXT == nch->type); if (NULL == (p = mdoc_a2st(nch->string))) { @@ -1756,33 +1721,17 @@ post_rs(POST_ARGS) static void post_hyph(POST_ARGS) { - struct mdoc_node *n, *nch; + struct mdoc_node *nch; char *cp; - n = mdoc->last; - switch (n->type) { - case MDOC_HEAD: - if (MDOC_Sh == n->tok || MDOC_Ss == n->tok) - break; - return; - case MDOC_BODY: - if (MDOC_D1 == n->tok || MDOC_Nd == n->tok) - break; - return; - case MDOC_ELEM: - break; - default: - return; - } - - for (nch = n->child; nch; nch = nch->next) { - if (MDOC_TEXT != nch->type) + for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { + if (nch->type != MDOC_TEXT) continue; cp = nch->string; - if ('\0' == *cp) + if (*cp == '\0') continue; - while ('\0' != *(++cp)) - if ('-' == *cp && + while (*(++cp) != '\0') + if (*cp == '-' && isalpha((unsigned char)cp[-1]) && isalpha((unsigned char)cp[1])) *cp = ASCII_HYPH; @@ -1790,14 +1739,6 @@ post_hyph(POST_ARGS) } static void -post_hyphtext(POST_ARGS) -{ - - ewarn_ge1(mdoc); - post_hyph(mdoc); -} - -static void post_ns(POST_ARGS) { @@ -2076,11 +2017,15 @@ post_ignpar(POST_ARGS) { struct mdoc_node *np; - check_count(mdoc, MDOC_HEAD, CHECK_GT, 0); - post_hyph(mdoc); - - if (MDOC_BODY != mdoc->last->type) + switch (mdoc->last->type) { + case MDOC_HEAD: + post_hyph(mdoc); return; + case MDOC_BODY: + break; + default: + return; + } if (NULL != (np = mdoc->last->child)) if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) {