=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mdoc_validate.c,v retrieving revision 1.213 retrieving revision 1.214 diff -c -r1.213 -r1.214 *** src/usr.bin/mandoc/mdoc_validate.c 2015/10/19 20:03:57 1.213 --- src/usr.bin/mandoc/mdoc_validate.c 2015/10/20 02:00:49 1.214 *************** *** 1,4 **** ! /* $OpenBSD: mdoc_validate.c,v 1.213 2015/10/19 20:03:57 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: mdoc_validate.c,v 1.214 2015/10/20 02:00:49 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze *************** *** 61,67 **** struct roff_node *, struct mdoc_argv *); static void check_args(struct roff_man *, struct roff_node *); static int child_an(const struct roff_node *); - static enum roff_sec a2sec(const char *); static size_t macro2len(int); static void rewrite_macro2len(char **); --- 61,66 ---- *************** *** 109,133 **** static void pre_an(PRE_ARGS); static void pre_bd(PRE_ARGS); static void pre_bl(PRE_ARGS); - static void pre_dd(PRE_ARGS); static void pre_display(PRE_ARGS); - static void pre_dt(PRE_ARGS); - static void pre_literal(PRE_ARGS); static void pre_obsolete(PRE_ARGS); - static void pre_os(PRE_ARGS); static void pre_par(PRE_ARGS); static void pre_std(PRE_ARGS); static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Ap */ ! { pre_dd, post_dd }, /* Dd */ ! { pre_dt, post_dt }, /* Dt */ ! { pre_os, post_os }, /* Os */ { NULL, post_sh }, /* Sh */ { NULL, post_ignpar }, /* Ss */ { pre_par, post_par }, /* Pp */ { pre_display, post_d1 }, /* D1 */ ! { pre_literal, post_literal }, /* Dl */ { pre_bd, post_literal }, /* Bd */ { NULL, NULL }, /* Ed */ { pre_bl, post_bl }, /* Bl */ --- 108,128 ---- static void pre_an(PRE_ARGS); static void pre_bd(PRE_ARGS); static void pre_bl(PRE_ARGS); static void pre_display(PRE_ARGS); static void pre_obsolete(PRE_ARGS); static void pre_par(PRE_ARGS); static void pre_std(PRE_ARGS); static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Ap */ ! { NULL, post_dd }, /* Dd */ ! { NULL, post_dt }, /* Dt */ ! { NULL, post_os }, /* Os */ { NULL, post_sh }, /* Sh */ { NULL, post_ignpar }, /* Ss */ { pre_par, post_par }, /* Pp */ { pre_display, post_d1 }, /* D1 */ ! { pre_display, post_literal }, /* Dl */ { pre_bd, post_literal }, /* Bd */ { NULL, NULL }, /* Ed */ { pre_bl, post_bl }, /* Bl */ *************** *** 315,330 **** } void ! mdoc_valid_post(struct roff_man *mdoc) { struct roff_node *n; v_post p; n = mdoc->last; ! if (n->flags & MDOC_VALID) ! return; ! n->flags |= MDOC_VALID | MDOC_ENDED; switch (n->type) { case ROFFT_TEXT: case ROFFT_EQN: --- 310,332 ---- } void ! mdoc_node_validate(struct roff_man *mdoc) { struct roff_node *n; v_post p; n = mdoc->last; ! mdoc->last = mdoc->last->child; ! while (mdoc->last != NULL) { ! mdoc_node_validate(mdoc); ! if (mdoc->last == n) ! mdoc->last = mdoc->last->child; ! else ! mdoc->last = mdoc->last->next; ! } + mdoc->last = n; + mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: case ROFFT_EQN: *************** *** 351,356 **** --- 353,360 ---- p = mdoc_valids[n->tok].post; if (*p) (*p)(mdoc); + if (mdoc->last == n) + mdoc_state(mdoc, n); break; } } *************** *** 592,598 **** int i; enum mdoc_disp dt; ! pre_literal(mdoc, n); if (n->type != ROFFT_BLOCK) return; --- 596,602 ---- int i; enum mdoc_disp dt; ! pre_display(mdoc, n); if (n->type != ROFFT_BLOCK) return; *************** *** 712,759 **** } static void - pre_dt(PRE_ARGS) - { - - if (mdoc->meta.title != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Dt"); - else if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dt after Os"); - } - - static void - pre_os(PRE_ARGS) - { - - if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Os"); - else if (mdoc->flags & MDOC_PBODY) - mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, - n->line, n->pos, "Os"); - } - - static void - pre_dd(PRE_ARGS) - { - - if (mdoc->meta.date != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Dd"); - else if (mdoc->flags & MDOC_PBODY) - mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, - n->line, n->pos, "Dd"); - else if (mdoc->meta.title != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dd after Dt"); - else if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dd after Os"); - } - - static void post_bf(POST_ARGS) { struct roff_node *np, *nch; --- 716,721 ---- *************** *** 977,995 **** n = mdoc->last; ! if (n->type != ROFFT_BODY) return; 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 --- 939,950 ---- n = mdoc->last; ! if (n->type != ROFFT_BODY || n->end != ENDBODY_NOT) return; if (n->child == NULL) mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); } static void *************** *** 1007,1021 **** return; nn = mdoc->last; - mdoc->next = ROFF_NEXT_CHILD; switch (nn->tok) { case MDOC_Ar: roff_word_alloc(mdoc, nn->line, nn->pos, "file"); roff_word_alloc(mdoc, nn->line, nn->pos, "..."); break; case MDOC_Pa: case MDOC_Mt: roff_word_alloc(mdoc, nn->line, nn->pos, "~"); break; default: --- 962,977 ---- return; nn = mdoc->last; switch (nn->tok) { case MDOC_Ar: + mdoc->next = ROFF_NEXT_CHILD; roff_word_alloc(mdoc, nn->line, nn->pos, "file"); roff_word_alloc(mdoc, nn->line, nn->pos, "..."); break; case MDOC_Pa: case MDOC_Mt: + mdoc->next = ROFF_NEXT_CHILD; roff_word_alloc(mdoc, nn->line, nn->pos, "~"); break; default: *************** *** 1375,1380 **** --- 1331,1338 ---- default: return; } + if (nbody->end != ENDBODY_NOT) + return; nchild = nbody->child; if (nchild == NULL) { *************** *** 1819,1827 **** static void post_sh_head(POST_ARGS) { - struct roff_node *n; const char *goodsec; - char *secname; enum roff_sec sec; /* --- 1777,1783 ---- *************** *** 1831,1850 **** * manual sections. */ ! secname = NULL; ! deroff(&secname, mdoc->last); ! sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); /* The NAME should be first. */ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secname); /* The SYNOPSIS gets special attention in other areas. */ ! if (SEC_SYNOPSIS == sec) { roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { --- 1787,1804 ---- * manual sections. */ ! sec = mdoc->last->sec; /* The NAME should be first. */ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secnames[sec]); /* The SYNOPSIS gets special attention in other areas. */ ! if (sec == SEC_SYNOPSIS) { roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { *************** *** 1856,1881 **** mdoc->lastsec = sec; - /* - * Set the section attribute for the current HEAD, for its - * parent BLOCK, and for the HEAD children; the latter can - * only be TEXT nodes, so no recursion is needed. - * For other blocks and elements, including .Sh BODY, this is - * done when allocating the node data structures, but for .Sh - * BLOCK and HEAD, the section is still unknown at that time. - */ - - mdoc->last->parent->sec = sec; - mdoc->last->sec = sec; - for (n = mdoc->last->child; n != NULL; n = n->next) - n->sec = sec; - /* We don't care about custom sections after this. */ ! if (SEC_CUSTOM == sec) { ! free(secname); return; - } /* * Check whether our non-custom section is being repeated or is --- 1810,1819 ---- mdoc->lastsec = sec; /* We don't care about custom sections after this. */ ! if (sec == SEC_CUSTOM) return; /* * Check whether our non-custom section is being repeated or is *************** *** 1885,1896 **** if (sec == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secname); if (sec < mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secname); /* Mark the last named section. */ --- 1823,1834 ---- if (sec == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secnames[sec]); if (sec < mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s", secnames[sec]); /* Mark the last named section. */ *************** *** 1898,1907 **** /* Check particular section/manual conventions. */ ! if (mdoc->meta.msec == NULL) { ! free(secname); return; - } goodsec = NULL; switch (sec) { --- 1836,1843 ---- /* Check particular section/manual conventions. */ ! if (mdoc->meta.msec == NULL) return; goodsec = NULL; switch (sec) { *************** *** 1926,1937 **** goodsec = "9"; mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s for %s only", secname, goodsec); break; default: break; } - free(secname); } static void --- 1862,1872 ---- goodsec = "9"; mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, mdoc->last->line, mdoc->last->pos, ! "Sh %s for %s only", secnames[sec], goodsec); break; default: break; } } static void *************** *** 2034,2077 **** } static void - pre_literal(PRE_ARGS) - { - - pre_display(mdoc, n); - - if (n->type != ROFFT_BODY) - return; - - /* - * The `Dl' (note "el" not "one") and `Bd -literal' and `Bd - * -unfilled' macros set MDOC_LITERAL on entrance to the body. - */ - - switch (n->tok) { - case MDOC_Dl: - mdoc->flags |= MDOC_LITERAL; - break; - case MDOC_Bd: - if (DISP_literal == n->norm->Bd.type) - mdoc->flags |= MDOC_LITERAL; - if (DISP_unfilled == n->norm->Bd.type) - mdoc->flags |= MDOC_LITERAL; - break; - default: - abort(); - } - } - - static void post_dd(POST_ARGS) { struct roff_node *n; char *datestr; ! if (mdoc->meta.date) free(mdoc->meta.date); - n = mdoc->last; if (n->child == NULL || n->child->string[0] == '\0') { mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); --- 1969,1994 ---- } static void post_dd(POST_ARGS) { struct roff_node *n; char *datestr; ! n = mdoc->last; ! if (mdoc->meta.date != NULL) { ! mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, ! n->line, n->pos, "Dd"); free(mdoc->meta.date); + } else if (mdoc->flags & MDOC_PBODY) + mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, + n->line, n->pos, "Dd"); + else if (mdoc->meta.title != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dd after Dt"); + else if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dd after Os"); if (n->child == NULL || n->child->string[0] == '\0') { mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); *************** *** 2099,2105 **** --- 2016,2034 ---- char *p; n = mdoc->last; + if (mdoc->flags & MDOC_PBODY) { + mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse, + n->line, n->pos, "Dt"); + goto out; + } + if (mdoc->meta.title != NULL) + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dt"); + else if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dt after Os"); + free(mdoc->meta.title); free(mdoc->meta.msec); free(mdoc->meta.vol); *************** *** 2201,2206 **** --- 2130,2141 ---- struct roff_node *n; n = mdoc->last; + if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Os"); + else if (mdoc->flags & MDOC_PBODY) + mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, + n->line, n->pos, "Os"); /* * Set the operating system by way of the `Os' macro. *************** *** 2266,2273 **** mdoc->last = n; } ! static enum roff_sec ! a2sec(const char *p) { int i; --- 2201,2208 ---- mdoc->last = n; } ! enum roff_sec ! mdoc_a2sec(const char *p) { int i;