=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.291 retrieving revision 1.298 diff -u -p -r1.291 -r1.298 --- mandoc/mdoc_validate.c 2015/04/23 16:17:44 1.291 +++ mandoc/mdoc_validate.c 2015/10/20 02:01:32 1.298 @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.291 2015/04/23 16:17:44 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.298 2015/10/20 02:01:32 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -63,7 +63,6 @@ static void check_argv(struct roff_man *, 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 **); @@ -107,30 +106,25 @@ static void post_sh_see_also(POST_ARGS); static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); -static void post_vt(POST_ARGS); 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_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_literal, post_literal }, /* Dl */ + { pre_display, post_literal }, /* Dl */ { pre_bd, post_literal }, /* Bd */ { NULL, NULL }, /* Ed */ { pre_bl, post_bl }, /* Bl */ @@ -161,7 +155,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { pre_std, NULL }, /* Rv */ { NULL, post_st }, /* St */ { NULL, NULL }, /* Va */ - { NULL, post_vt }, /* Vt */ + { NULL, NULL }, /* Vt */ { NULL, NULL }, /* Xr */ { NULL, NULL }, /* %A */ { NULL, post_hyph }, /* %B */ /* FIXME: can be used outside Rs/Re. */ @@ -302,11 +296,9 @@ mdoc_valid_pre(struct roff_man *mdoc, struct roff_node case ROFFT_TEXT: if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) check_text(mdoc, n->line, n->pos, n->string); - /* FALLTHROUGH */ + return; case ROFFT_TBL: - /* FALLTHROUGH */ case ROFFT_EQN: - /* FALLTHROUGH */ case ROFFT_ROOT: return; default: @@ -320,21 +312,26 @@ mdoc_valid_pre(struct roff_man *mdoc, struct roff_node } void -mdoc_valid_post(struct roff_man *mdoc) +mdoc_node_validate(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; + 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: - /* FALLTHROUGH */ case ROFFT_EQN: - /* FALLTHROUGH */ case ROFFT_TBL: break; case ROFFT_ROOT: @@ -358,6 +355,8 @@ mdoc_valid_post(struct roff_man *mdoc) p = mdoc_valids[n->tok].post; if (*p) (*p)(mdoc); + if (mdoc->last == n) + mdoc_state(mdoc, n); break; } } @@ -567,13 +566,9 @@ pre_bl(PRE_ARGS) n->line, n->pos, "Bl -tag"); break; case LIST_column: - /* FALLTHROUGH */ case LIST_diag: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_item: if (n->norm->Bl.width) mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, @@ -581,9 +576,7 @@ pre_bl(PRE_ARGS) mdoc_argnames[mdoclt]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: if (NULL == n->norm->Bl.width) n->norm->Bl.width = "2n"; @@ -605,7 +598,7 @@ pre_bd(PRE_ARGS) int i; enum mdoc_disp dt; - pre_literal(mdoc, n); + pre_display(mdoc, n); if (n->type != ROFFT_BLOCK) return; @@ -658,7 +651,6 @@ pre_bd(PRE_ARGS) break; default: abort(); - /* NOTREACHED */ } if (DISP__NONE == dt) continue; @@ -726,52 +718,9 @@ pre_obsolete(PRE_ARGS) } 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; - enum mdocargt arg; /* * Unlike other data pointers, these are "housed" by the HEAD @@ -783,45 +732,49 @@ post_bf(POST_ARGS) return; assert(np->parent->type == ROFFT_BLOCK); - assert(MDOC_Bf == np->parent->tok); + assert(np->parent->tok == MDOC_Bf); /* Check the number of arguments. */ nch = np->child; - if (NULL == np->parent->args) { - if (NULL == nch) { + if (np->parent->args == NULL) { + if (nch == NULL) { mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse, np->line, np->pos, "Bf"); return; } nch = nch->next; } - if (NULL != nch) + if (nch != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bf ... %s", nch->string); /* Extract argument into data. */ - if (np->parent->args) { - arg = np->parent->args->argv[0].arg; - if (MDOC_Emphasis == arg) + if (np->parent->args != NULL) { + switch (np->parent->args->argv[0].arg) { + case MDOC_Emphasis: np->norm->Bf.font = FONT_Em; - else if (MDOC_Literal == arg) + break; + case MDOC_Literal: np->norm->Bf.font = FONT_Li; - else if (MDOC_Symbolic == arg) + break; + case MDOC_Symbolic: np->norm->Bf.font = FONT_Sy; - else + break; + default: abort(); + } return; } /* Extract parameter into data. */ - if (0 == strcmp(np->child->string, "Em")) + if ( ! strcmp(np->child->string, "Em")) np->norm->Bf.font = FONT_Em; - else if (0 == strcmp(np->child->string, "Li")) + else if ( ! strcmp(np->child->string, "Li")) np->norm->Bf.font = FONT_Li; - else if (0 == strcmp(np->child->string, "Sy")) + else if ( ! strcmp(np->child->string, "Sy")) np->norm->Bf.font = FONT_Sy; else mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse, @@ -855,7 +808,7 @@ post_eoln(POST_ARGS) const struct roff_node *n; n = mdoc->last; - if (n->child) + if (n->child != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, n->line, n->pos, "%s %s", mdoc_macronames[n->tok], @@ -933,28 +886,6 @@ post_fa(POST_ARGS) } static void -post_vt(POST_ARGS) -{ - const struct roff_node *n; - - /* - * The Vt macro comes in both ELEM and BLOCK form, both of which - * have different syntaxes (yet more context-sensitive - * behaviour). ELEM types must have a child, which is already - * guaranteed by the in_line parsing routine; BLOCK types, - * specifically the BODY, should only have TEXT children. - */ - - if (mdoc->last->type != ROFFT_BODY) - return; - - for (n = mdoc->last->child; n; n = n->next) - if (n->type != ROFFT_TEXT) - mandoc_msg(MANDOCERR_VT_CHILD, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); -} - -static void post_nm(POST_ARGS) { struct roff_node *n; @@ -966,12 +897,12 @@ post_nm(POST_ARGS) n->last->tok == MDOC_Lp)) mdoc_node_relink(mdoc, n->last); - if (NULL != mdoc->meta.name) + if (mdoc->meta.name != NULL) return; deroff(&mdoc->meta.name, n); - if (NULL == mdoc->meta.name) + if (mdoc->meta.name == NULL) mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, n->line, n->pos, "Nm"); } @@ -1017,19 +948,12 @@ post_literal(POST_ARGS) n = mdoc->last; - if (n->type != ROFFT_BODY) + 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]); - - if (n->tok == MDOC_Bd && - n->norm->Bd.type != DISP_literal && - n->norm->Bd.type != DISP_unfilled) - return; - - mdoc->flags &= ~MDOC_LITERAL; } static void @@ -1043,25 +967,24 @@ post_defaults(POST_ARGS) * gets an empty string. */ - if (mdoc->last->child) + if (mdoc->last->child != NULL) return; nn = mdoc->last; - mdoc->next = ROFF_NEXT_CHILD; 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: - /* FALLTHROUGH */ case MDOC_Mt: + mdoc->next = ROFF_NEXT_CHILD; roff_word_alloc(mdoc, nn->line, nn->pos, "~"); break; default: abort(); - /* NOTREACHED */ } mdoc->last = nn; } @@ -1089,7 +1012,7 @@ post_at(POST_ARGS) n = n->child; assert(n->type == ROFFT_TEXT); - if (NULL == (std_att = mdoc_a2att(n->string))) { + if ((std_att = mdoc_a2att(n->string)) == NULL) { mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse, n->line, n->pos, "At %s", n->string); mandoc_asprintf(&att, "AT&T UNIX %s", n->string); @@ -1147,13 +1070,9 @@ post_it(POST_ARGS) switch (lt) { case LIST_tag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_diag: if (nit->head->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOHEAD, @@ -1162,11 +1081,8 @@ post_it(POST_ARGS) mdoc_argnames[nbl->args->argv[0].arg]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_hyphen: if (nit->body == NULL || nit->body->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOBODY, @@ -1185,7 +1101,8 @@ post_it(POST_ARGS) assert(nit->head->child == NULL); - for (i = 0, nch = nit->child; nch; nch = nch->next) + i = 0; + for (nch = nit->child; nch != NULL; nch = nch->next) if (nch->type == ROFFT_BODY) i++; @@ -1214,35 +1131,33 @@ post_bl_block(POST_ARGS) n = mdoc->last; - if (LIST_tag == n->norm->Bl.type && - NULL == n->norm->Bl.width) { + if (n->norm->Bl.type == LIST_tag && + n->norm->Bl.width == NULL) { post_bl_block_tag(mdoc); - assert(n->norm->Bl.width); + assert(n->norm->Bl.width != NULL); } - for (ni = n->body->child; ni; ni = ni->next) { - if (NULL == ni->body) + for (ni = n->body->child; ni != NULL; ni = ni->next) { + if (ni->body == NULL) continue; nc = ni->body->last; - while (NULL != nc) { + while (nc != NULL) { switch (nc->tok) { case MDOC_Pp: - /* FALLTHROUGH */ case MDOC_Lp: - /* FALLTHROUGH */ case MDOC_br: break; default: nc = NULL; continue; } - if (NULL == ni->next) { + if (ni->next == NULL) { mandoc_msg(MANDOCERR_PAR_MOVE, mdoc->parse, nc->line, nc->pos, mdoc_macronames[nc->tok]); mdoc_node_relink(mdoc, nc); - } else if (0 == n->norm->Bl.comp && - LIST_column != n->norm->Bl.type) { + } else if (n->norm->Bl.comp == 0 && + n->norm->Bl.type != LIST_column) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, nc->line, nc->pos, "%s before It", @@ -1296,8 +1211,8 @@ post_bl_block_tag(POST_ARGS) sz = 10; n = mdoc->last; - for (nn = n->body->child; nn; nn = nn->next) { - if (MDOC_It != nn->tok) + for (nn = n->body->child; nn != NULL; nn = nn->next) { + if (nn->tok != MDOC_It) continue; assert(nn->type == ROFFT_BLOCK); @@ -1326,7 +1241,7 @@ post_bl_block_tag(POST_ARGS) * We're guaranteed that a MDOC_Width doesn't already exist. */ - assert(n->args); + assert(n->args != NULL); i = (int)(n->args->argc)++; n->args->argv = mandoc_reallocarray(n->args->argv, @@ -1425,6 +1340,8 @@ post_bl(POST_ARGS) default: return; } + if (nbody->end != ENDBODY_NOT) + return; nchild = nbody->child; if (nchild == NULL) { @@ -1459,11 +1376,11 @@ post_bl(POST_ARGS) * Unlink this child. */ - assert(NULL == nchild->prev); - if (0 == --nbody->nchild) { + assert(nchild->prev == NULL); + if (--nbody->nchild == 0) { nbody->child = NULL; nbody->last = NULL; - assert(NULL == nnext); + assert(nnext == NULL); } else { nbody->child = nnext; nnext->prev = NULL; @@ -1479,7 +1396,7 @@ post_bl(POST_ARGS) nblock->prev = nchild; nparent->nchild++; - if (NULL == nprev) + if (nprev == NULL) nparent->child = nchild; else nprev->next = nchild; @@ -1503,7 +1420,7 @@ post_bk(POST_ARGS) } static void -post_sm(struct roff_man *mdoc) +post_sm(POST_ARGS) { struct roff_node *nch; @@ -1584,7 +1501,7 @@ post_st(POST_ARGS) assert(nch->type == ROFFT_TEXT); - if (NULL == (p = mdoc_a2st(nch->string))) { + if ((p = mdoc_a2st(nch->string)) == NULL) { mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, nch->line, nch->pos, "St %s", nch->string); roff_node_delete(mdoc, n); @@ -1712,7 +1629,7 @@ static void post_ns(POST_ARGS) { - if (MDOC_LINE & mdoc->last->flags) + if (mdoc->last->flags & MDOC_LINE) mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse, mdoc->last->line, mdoc->last->pos, NULL); } @@ -1853,8 +1770,8 @@ child_an(const struct roff_node *n) for (n = n->child; n != NULL; n = n->next) if ((n->tok == MDOC_An && n->nchild) || child_an(n)) - return(1); - return(0); + return 1; + return 0; } static void @@ -1869,9 +1786,7 @@ post_sh_authors(POST_ARGS) static void post_sh_head(POST_ARGS) { - struct roff_node *n; const char *goodsec; - char *secname; enum roff_sec sec; /* @@ -1881,21 +1796,18 @@ post_sh_head(POST_ARGS) * manual sections. */ - secname = NULL; - sec = SEC_CUSTOM; - deroff(&secname, mdoc->last); - sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); + 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", secname); + "Sh %s", secnames[sec]); /* The SYNOPSIS gets special attention in other areas. */ - if (SEC_SYNOPSIS == sec) { + if (sec == SEC_SYNOPSIS) { roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { @@ -1907,26 +1819,10 @@ post_sh_head(POST_ARGS) 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; n = n->next) - n->sec = sec; - /* We don't care about custom sections after this. */ - if (SEC_CUSTOM == sec) { - free(secname); + if (sec == SEC_CUSTOM) return; - } /* * Check whether our non-custom section is being repeated or is @@ -1936,12 +1832,12 @@ post_sh_head(POST_ARGS) if (sec == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); if (sec < mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); /* Mark the last named section. */ @@ -1949,10 +1845,8 @@ post_sh_head(POST_ARGS) /* Check particular section/manual conventions. */ - if (mdoc->meta.msec == NULL) { - free(secname); + if (mdoc->meta.msec == NULL) return; - } goodsec = NULL; switch (sec) { @@ -1962,7 +1856,6 @@ post_sh_head(POST_ARGS) goodsec = "2, 3, 4, 9"; /* FALLTHROUGH */ case SEC_RETURN_VALUES: - /* FALLTHROUGH */ case SEC_LIBRARY: if (*mdoc->meta.msec == '2') break; @@ -1978,12 +1871,11 @@ post_sh_head(POST_ARGS) goodsec = "9"; mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s for %s only", secname, goodsec); + "Sh %s for %s only", secnames[sec], goodsec); break; default: break; } - free(secname); } static void @@ -2001,8 +1893,8 @@ post_ignpar(POST_ARGS) return; } - if (NULL != (np = mdoc->last->child)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->child) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s after %s", mdoc_macronames[np->tok], @@ -2010,8 +1902,8 @@ post_ignpar(POST_ARGS) roff_node_delete(mdoc, np); } - if (NULL != (np = mdoc->last->last)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->last) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s at the end of %s", mdoc_macronames[np->tok], @@ -2069,13 +1961,13 @@ post_par(POST_ARGS) mdoc->parse, np->line, np->pos, "%s %s", mdoc_macronames[np->tok], np->child->string); - if (NULL == (np = mdoc->last->prev)) { + if ((np = mdoc->last->prev) == NULL) { np = mdoc->last->parent; - if (MDOC_Sh != np->tok && MDOC_Ss != np->tok) + if (np->tok != MDOC_Sh && np->tok != MDOC_Ss) return; - } else if (MDOC_Pp != np->tok && MDOC_Lp != np->tok && - (MDOC_br != mdoc->last->tok || - (MDOC_sp != np->tok && MDOC_br != np->tok))) + } else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp && + (mdoc->last->tok != MDOC_br || + (np->tok != MDOC_sp && np->tok != MDOC_br))) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, @@ -2086,46 +1978,27 @@ post_par(POST_ARGS) } 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(); - /* NOTREACHED */ - } -} - -static void post_dd(POST_ARGS) { struct roff_node *n; char *datestr; - if (mdoc->meta.date) + 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"); - n = mdoc->last; - if (NULL == n->child || '\0' == n->child->string[0]) { + 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); goto out; @@ -2152,7 +2025,19 @@ post_dt(POST_ARGS) 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); @@ -2240,8 +2125,7 @@ post_bx(POST_ARGS) * uppercase blindly. */ - n = mdoc->last->child; - if (n && NULL != (n = n->next)) + if ((n = mdoc->last->child) != NULL && (n = n->next) != NULL) *n->string = (char)toupper((unsigned char)*n->string); } @@ -2255,6 +2139,12 @@ post_os(POST_ARGS) 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. @@ -2279,8 +2169,8 @@ post_os(POST_ARGS) #ifdef OSNAME mdoc->meta.os = mandoc_strdup(OSNAME); #else /*!OSNAME */ - if (NULL == defbuf) { - if (-1 == uname(&utsname)) { + if (defbuf == NULL) { + if (uname(&utsname) == -1) { mandoc_msg(MANDOCERR_OS_UNAME, mdoc->parse, n->line, n->pos, "Os"); defbuf = mandoc_strdup("UNKNOWN"); @@ -2306,7 +2196,7 @@ post_ex(POST_ARGS) n = mdoc->last; - if (n->child) + if (n->child != NULL) return; if (mdoc->meta.name == NULL) { @@ -2320,16 +2210,16 @@ post_ex(POST_ARGS) mdoc->last = n; } -static enum roff_sec -a2sec(const char *p) +enum roff_sec +mdoc_a2sec(const char *p) { int i; for (i = 0; i < (int)SEC__MAX; i++) if (secnames[i] && 0 == strcmp(p, secnames[i])) - return((enum roff_sec)i); + return (enum roff_sec)i; - return(SEC_CUSTOM); + return SEC_CUSTOM; } static size_t @@ -2338,89 +2228,89 @@ macro2len(int macro) switch (macro) { case MDOC_Ad: - return(12); + return 12; case MDOC_Ao: - return(12); + return 12; case MDOC_An: - return(12); + return 12; case MDOC_Aq: - return(12); + return 12; case MDOC_Ar: - return(12); + return 12; case MDOC_Bo: - return(12); + return 12; case MDOC_Bq: - return(12); + return 12; case MDOC_Cd: - return(12); + return 12; case MDOC_Cm: - return(10); + return 10; case MDOC_Do: - return(10); + return 10; case MDOC_Dq: - return(12); + return 12; case MDOC_Dv: - return(12); + return 12; case MDOC_Eo: - return(12); + return 12; case MDOC_Em: - return(10); + return 10; case MDOC_Er: - return(17); + return 17; case MDOC_Ev: - return(15); + return 15; case MDOC_Fa: - return(12); + return 12; case MDOC_Fl: - return(10); + return 10; case MDOC_Fo: - return(16); + return 16; case MDOC_Fn: - return(16); + return 16; case MDOC_Ic: - return(10); + return 10; case MDOC_Li: - return(16); + return 16; case MDOC_Ms: - return(6); + return 6; case MDOC_Nm: - return(10); + return 10; case MDOC_No: - return(12); + return 12; case MDOC_Oo: - return(10); + return 10; case MDOC_Op: - return(14); + return 14; case MDOC_Pa: - return(32); + return 32; case MDOC_Pf: - return(12); + return 12; case MDOC_Po: - return(12); + return 12; case MDOC_Pq: - return(12); + return 12; case MDOC_Ql: - return(16); + return 16; case MDOC_Qo: - return(12); + return 12; case MDOC_So: - return(12); + return 12; case MDOC_Sq: - return(12); + return 12; case MDOC_Sy: - return(6); + return 6; case MDOC_Sx: - return(16); + return 16; case MDOC_Tn: - return(10); + return 10; case MDOC_Va: - return(12); + return 12; case MDOC_Vt: - return(12); + return 12; case MDOC_Xr: - return(10); + return 10; default: break; }; - return(0); + return 0; }