=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.261 retrieving revision 1.269 diff -u -p -r1.261 -r1.269 --- mandoc/mdoc_validate.c 2014/11/28 18:09:01 1.261 +++ mandoc/mdoc_validate.c 2015/02/04 19:20:12 1.269 @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.261 2014/11/28 18:09:01 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.269 2015/02/04 19:20:12 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010-2014 Ingo Schwarze + * Copyright (c) 2010-2015 Ingo Schwarze * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -48,11 +48,6 @@ enum check_ineq { CHECK_EQ }; -enum check_lvl { - CHECK_WARN, - CHECK_ERROR, -}; - typedef void (*v_pre)(PRE_ARGS); typedef void (*v_post)(POST_ARGS); @@ -62,7 +57,7 @@ struct valids { }; static void check_count(struct mdoc *, enum mdoc_type, - enum check_lvl, enum check_ineq, int); + 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 *); @@ -210,7 +205,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Nx */ { NULL, NULL }, /* Ox */ { NULL, NULL }, /* Pc */ - { NULL, ewarn_eq1 }, /* Pf */ + { NULL, NULL }, /* Pf */ { NULL, NULL }, /* Po */ { NULL, NULL }, /* Pq */ { NULL, NULL }, /* Qc */ @@ -374,10 +369,9 @@ mdoc_valid_post(struct mdoc *mdoc) static void check_count(struct mdoc *mdoc, enum mdoc_type type, - enum check_lvl lvl, enum check_ineq ineq, int val) + enum check_ineq ineq, int val) { const char *p; - enum mandocerr t; if (mdoc->last->type != type) return; @@ -403,8 +397,7 @@ check_count(struct mdoc *mdoc, enum mdoc_type type, /* NOTREACHED */ } - t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT; - mandoc_vmsg(t, mdoc->parse, mdoc->last->line, + mandoc_vmsg(MANDOCERR_ARGCWARN, mdoc->parse, mdoc->last->line, mdoc->last->pos, "want %s%d children (have %d)", p, val, mdoc->last->nchild); } @@ -412,25 +405,25 @@ check_count(struct mdoc *mdoc, enum mdoc_type type, static void bwarn_ge1(POST_ARGS) { - check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0); + check_count(mdoc, MDOC_BODY, CHECK_GT, 0); } static void ewarn_eq1(POST_ARGS) { - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1); + check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1); } static void ewarn_ge1(POST_ARGS) { - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0); + check_count(mdoc, MDOC_ELEM, CHECK_GT, 0); } static void hwarn_eq0(POST_ARGS) { - check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0); + check_count(mdoc, MDOC_HEAD, CHECK_EQ, 0); } static void @@ -941,7 +934,7 @@ post_lb(POST_ARGS) const char *stdlibname; char *libname; - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1); + check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1); n = mdoc->last->child; assert(MDOC_TEXT == n->type); @@ -995,7 +988,7 @@ static void post_fo(POST_ARGS) { - check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 1); + check_count(mdoc, MDOC_HEAD, CHECK_EQ, 1); bwarn_ge1(mdoc); if (mdoc->last->type == MDOC_HEAD && mdoc->last->nchild) post_fname(mdoc); @@ -1047,22 +1040,39 @@ post_vt(POST_ARGS) static void post_nm(POST_ARGS) { + struct mdoc_node *n; + n = mdoc->last; + + if (n->last != NULL && + (n->last->tok == MDOC_Pp || + n->last->tok == MDOC_Lp)) + mdoc_node_relink(mdoc, n->last); + if (NULL != mdoc->meta.name) return; - mdoc_deroff(&mdoc->meta.name, mdoc->last); + mdoc_deroff(&mdoc->meta.name, n); if (NULL == mdoc->meta.name) mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, - mdoc->last->line, mdoc->last->pos, "Nm"); + n->line, n->pos, "Nm"); } static void post_nd(POST_ARGS) { + struct mdoc_node *n; - check_count(mdoc, MDOC_BODY, CHECK_ERROR, CHECK_GT, 0); + n = mdoc->last; + + if (n->type != MDOC_BODY) + return; + + if (n->child == NULL) + mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse, + n->line, n->pos, "Nd"); + post_hyph(mdoc); } @@ -1164,14 +1174,15 @@ post_at(POST_ARGS) static void post_an(POST_ARGS) { - struct mdoc_node *np; + struct mdoc_node *np, *nch; np = mdoc->last; if (AUTH__NONE == np->norm->An.auth) { if (0 == np->child) - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0); - } else if (np->child) - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0); + check_count(mdoc, MDOC_ELEM, CHECK_GT, 0); + } else if ((nch = np->child) != NULL) + mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, + nch->line, nch->pos, "An ... %s", nch->string); } static void @@ -1197,7 +1208,7 @@ post_it(POST_ARGS) struct mdoc_node *nbl, *nit, *nch; nit = mdoc->last; - if (MDOC_BLOCK != nit->type) + if (nit->type != MDOC_BLOCK) return; nbl = nit->parent->parent; @@ -1213,7 +1224,7 @@ post_it(POST_ARGS) case LIST_inset: /* FALLTHROUGH */ case LIST_diag: - if (NULL == nit->head->child) + if (nit->head->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOHEAD, mdoc->parse, nit->line, nit->pos, "Bl -%s It", @@ -1226,14 +1237,14 @@ post_it(POST_ARGS) case LIST_enum: /* FALLTHROUGH */ case LIST_hyphen: - if (NULL == nit->body->child) + if (nit->body == NULL || nit->body->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOBODY, mdoc->parse, nit->line, nit->pos, "Bl -%s It", mdoc_argnames[nbl->args->argv[0].arg]); /* FALLTHROUGH */ case LIST_item: - if (NULL != nit->head->child) + if (nit->head->child != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, nit->line, nit->pos, "It %s", nit->head->child->string); @@ -1241,10 +1252,10 @@ post_it(POST_ARGS) case LIST_column: cols = (int)nbl->norm->Bl.ncols; - assert(NULL == nit->head->child); + assert(nit->head->child == NULL); for (i = 0, nch = nit->child; nch; nch = nch->next) - if (MDOC_BODY == nch->type) + if (nch->type == MDOC_BODY) i++; if (i < cols || i > cols + 1) @@ -1484,7 +1495,10 @@ post_bl(POST_ARGS) nchild = nbody->child; while (NULL != nchild) { - if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) { + if (nchild->tok == MDOC_It || + (nchild->tok == MDOC_Sm && + nchild->next != NULL && + nchild->next->tok == MDOC_It)) { nchild = nchild->next; continue; } @@ -1645,20 +1659,18 @@ post_st(POST_ARGS) static void post_rs(POST_ARGS) { - struct mdoc_node *nn, *next, *prev; + struct mdoc_node *np, *nch, *next, *prev; int i, j; - switch (mdoc->last->type) { - case MDOC_HEAD: - check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0); + np = mdoc->last; + + if (np->type != MDOC_BODY) return; - case MDOC_BODY: - if (mdoc->last->child) - break; - check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0); + + if (np->child == NULL) { + mandoc_msg(MANDOCERR_RS_EMPTY, mdoc->parse, + np->line, np->pos, "Rs"); return; - default: - return; } /* @@ -1668,38 +1680,38 @@ post_rs(POST_ARGS) */ next = NULL; - for (nn = mdoc->last->child->next; nn; nn = next) { - /* Determine order of `nn'. */ + for (nch = np->child->next; nch != NULL; nch = next) { + /* Determine order number of this child. */ for (i = 0; i < RSORD_MAX; i++) - if (rsord[i] == nn->tok) + if (rsord[i] == nch->tok) break; if (i == RSORD_MAX) { mandoc_msg(MANDOCERR_RS_BAD, - mdoc->parse, nn->line, nn->pos, - mdoc_macronames[nn->tok]); + mdoc->parse, nch->line, nch->pos, + mdoc_macronames[nch->tok]); i = -1; - } else if (MDOC__J == nn->tok || MDOC__B == nn->tok) - mdoc->last->norm->Rs.quote_T++; + } else if (nch->tok == MDOC__J || nch->tok == MDOC__B) + np->norm->Rs.quote_T++; /* - * Remove `nn' from the chain. This somewhat + * Remove this child from the chain. This somewhat * repeats mdoc_node_unlink(), but since we're * just re-ordering, there's no need for the * full unlink process. */ - if (NULL != (next = nn->next)) - next->prev = nn->prev; + if ((next = nch->next) != NULL) + next->prev = nch->prev; - if (NULL != (prev = nn->prev)) - prev->next = nn->next; + if ((prev = nch->prev) != NULL) + prev->next = nch->next; - nn->prev = nn->next = NULL; + nch->prev = nch->next = NULL; /* * Scan back until we reach a node that's - * ordered before `nn'. + * to be ordered before this child. */ for ( ; prev ; prev = prev->prev) { @@ -1715,21 +1727,21 @@ post_rs(POST_ARGS) } /* - * Set `nn' back into its correct place in front - * of the `prev' node. + * Set this child back into its correct place + * in front of the `prev' node. */ - nn->prev = prev; + nch->prev = prev; - if (prev) { - if (prev->next) - prev->next->prev = nn; - nn->next = prev->next; - prev->next = nn; + if (prev == NULL) { + np->child->prev = nch; + nch->next = np->child; + np->child = nch; } else { - mdoc->last->child->prev = nn; - nn->next = mdoc->last->child; - mdoc->last->child = nn; + if (prev->next) + prev->next->prev = nch; + nch->next = prev->next; + prev->next = nch; } } } @@ -2061,7 +2073,7 @@ post_ignpar(POST_ARGS) { struct mdoc_node *np; - check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_GT, 0); + check_count(mdoc, MDOC_HEAD, CHECK_GT, 0); post_hyph(mdoc); if (MDOC_BODY != mdoc->last->type) @@ -2123,14 +2135,17 @@ post_par(POST_ARGS) { struct mdoc_node *np; - if (mdoc->last->tok == MDOC_sp) - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2); - else - check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0); + np = mdoc->last; - if (MDOC_ELEM != mdoc->last->type && - MDOC_BLOCK != mdoc->last->type) - return; + if (np->tok == MDOC_sp) { + if (np->nchild > 1) + mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, + np->child->next->line, np->child->next->pos, + "sp ... %s", np->child->next->string); + } else if (np->child != NULL) + mandoc_vmsg(MANDOCERR_ARG_SKIP, + mdoc->parse, np->line, np->pos, "%s %s", + mdoc_macronames[np->tok], np->child->string); if (NULL == (np = mdoc->last->prev)) { np = mdoc->last->parent; @@ -2280,19 +2295,9 @@ post_dt(POST_ARGS) mdoc->meta.msec = mandoc_strdup(nn->string); } - if (NULL == (nn = nn->next)) - goto out; + /* Handle an optional architecture */ - /* - * If the third argument is a volume name, format is, - * otherwise assume it's an architecture. - */ - - cp = mdoc_a2vol(nn->string); - if (cp) { - free(mdoc->meta.vol); - mdoc->meta.vol = mandoc_strdup(cp); - } else { + if ((nn = nn->next) != NULL) { for (p = nn->string; *p; p++) *p = tolower((unsigned char)*p); mdoc->meta.arch = mandoc_strdup(nn->string);