=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mdoc_validate.c,v retrieving revision 1.214 retrieving revision 1.215 diff -c -r1.214 -r1.215 *** src/usr.bin/mandoc/mdoc_validate.c 2015/10/20 02:00:49 1.214 --- src/usr.bin/mandoc/mdoc_validate.c 2015/10/21 23:49:05 1.215 *************** *** 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 --- 1,4 ---- ! /* $OpenBSD: mdoc_validate.c,v 1.215 2015/10/21 23:49:05 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze *************** *** 39,45 **** /* FIXME: .Bl -diag can't have non-text children in HEAD. */ - #define PRE_ARGS struct roff_man *mdoc, struct roff_node *n #define POST_ARGS struct roff_man *mdoc enum check_ineq { --- 39,44 ---- *************** *** 48,61 **** CHECK_EQ }; - typedef void (*v_pre)(PRE_ARGS); typedef void (*v_post)(POST_ARGS); - struct valids { - v_pre pre; - v_post post; - }; - static void check_text(struct roff_man *, int, int, char *); static void check_argv(struct roff_man *, struct roff_node *, struct mdoc_argv *); --- 47,54 ---- *************** *** 65,80 **** static void rewrite_macro2len(char **); static void post_an(POST_ARGS); static void post_at(POST_ARGS); static void post_bf(POST_ARGS); static void post_bk(POST_ARGS); static void post_bl(POST_ARGS); static void post_bl_block(POST_ARGS); static void post_bl_block_tag(POST_ARGS); static void post_bl_head(POST_ARGS); static void post_bx(POST_ARGS); - static void post_d1(POST_ARGS); static void post_defaults(POST_ARGS); static void post_dd(POST_ARGS); static void post_dt(POST_ARGS); static void post_en(POST_ARGS); --- 58,76 ---- static void rewrite_macro2len(char **); static void post_an(POST_ARGS); + static void post_an_norm(POST_ARGS); static void post_at(POST_ARGS); + static void post_bd(POST_ARGS); static void post_bf(POST_ARGS); static void post_bk(POST_ARGS); static void post_bl(POST_ARGS); static void post_bl_block(POST_ARGS); static void post_bl_block_tag(POST_ARGS); static void post_bl_head(POST_ARGS); + static void post_bl_norm(POST_ARGS); static void post_bx(POST_ARGS); static void post_defaults(POST_ARGS); + static void post_display(POST_ARGS); static void post_dd(POST_ARGS); static void post_dt(POST_ARGS); static void post_en(POST_ARGS); *************** *** 89,100 **** static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); - static void post_literal(POST_ARGS); static void post_nd(POST_ARGS); static void post_nm(POST_ARGS); static void post_ns(POST_ARGS); static void post_os(POST_ARGS); static void post_par(POST_ARGS); static void post_root(POST_ARGS); static void post_rs(POST_ARGS); static void post_sh(POST_ARGS); --- 85,97 ---- static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); static void post_nd(POST_ARGS); static void post_nm(POST_ARGS); static void post_ns(POST_ARGS); + static void post_obsolete(POST_ARGS); static void post_os(POST_ARGS); static void post_par(POST_ARGS); + static void post_prevpar(POST_ARGS); static void post_root(POST_ARGS); static void post_rs(POST_ARGS); static void post_sh(POST_ARGS); *************** *** 104,242 **** static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); ! 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 */ ! { NULL, NULL }, /* El */ ! { pre_par, post_it }, /* It */ ! { NULL, NULL }, /* Ad */ ! { pre_an, post_an }, /* An */ ! { NULL, post_defaults }, /* Ar */ ! { NULL, NULL }, /* Cd */ ! { NULL, NULL }, /* Cm */ ! { NULL, NULL }, /* Dv */ ! { NULL, NULL }, /* Er */ ! { NULL, NULL }, /* Ev */ ! { pre_std, post_ex }, /* Ex */ ! { NULL, post_fa }, /* Fa */ ! { NULL, NULL }, /* Fd */ ! { NULL, NULL }, /* Fl */ ! { NULL, post_fn }, /* Fn */ ! { NULL, NULL }, /* Ft */ ! { NULL, NULL }, /* Ic */ ! { NULL, NULL }, /* In */ ! { NULL, post_defaults }, /* Li */ ! { NULL, post_nd }, /* Nd */ ! { NULL, post_nm }, /* Nm */ ! { NULL, NULL }, /* Op */ ! { pre_obsolete, NULL }, /* Ot */ ! { NULL, post_defaults }, /* Pa */ ! { pre_std, NULL }, /* Rv */ ! { NULL, post_st }, /* St */ ! { NULL, NULL }, /* Va */ ! { NULL, NULL }, /* Vt */ ! { 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 */ ! { NULL, post_at }, /* At */ ! { NULL, NULL }, /* Bc */ ! { NULL, post_bf }, /* Bf */ ! { NULL, NULL }, /* Bo */ ! { NULL, NULL }, /* Bq */ ! { NULL, NULL }, /* Bsx */ ! { NULL, post_bx }, /* Bx */ ! { pre_obsolete, NULL }, /* Db */ ! { NULL, NULL }, /* Dc */ ! { NULL, NULL }, /* Do */ ! { NULL, NULL }, /* Dq */ ! { NULL, NULL }, /* Ec */ ! { NULL, NULL }, /* Ef */ ! { NULL, NULL }, /* Em */ ! { NULL, NULL }, /* Eo */ ! { NULL, NULL }, /* Fx */ ! { NULL, NULL }, /* Ms */ ! { NULL, NULL }, /* No */ ! { NULL, post_ns }, /* Ns */ ! { NULL, NULL }, /* Nx */ ! { NULL, NULL }, /* Ox */ ! { NULL, NULL }, /* Pc */ ! { NULL, NULL }, /* Pf */ ! { NULL, NULL }, /* Po */ ! { NULL, NULL }, /* Pq */ ! { NULL, NULL }, /* Qc */ ! { NULL, NULL }, /* Ql */ ! { NULL, NULL }, /* Qo */ ! { NULL, NULL }, /* Qq */ ! { NULL, NULL }, /* Re */ ! { NULL, post_rs }, /* Rs */ ! { NULL, NULL }, /* Sc */ ! { NULL, NULL }, /* So */ ! { NULL, NULL }, /* Sq */ ! { NULL, post_sm }, /* Sm */ ! { NULL, post_hyph }, /* Sx */ ! { NULL, NULL }, /* Sy */ ! { NULL, NULL }, /* Tn */ ! { NULL, NULL }, /* Ux */ ! { NULL, NULL }, /* Xc */ ! { NULL, NULL }, /* Xo */ ! { NULL, post_fo }, /* Fo */ ! { NULL, NULL }, /* Fc */ ! { NULL, NULL }, /* Oo */ ! { NULL, NULL }, /* Oc */ ! { NULL, post_bk }, /* Bk */ ! { NULL, NULL }, /* Ek */ ! { NULL, post_eoln }, /* Bt */ ! { NULL, NULL }, /* Hf */ ! { pre_obsolete, NULL }, /* Fr */ ! { NULL, post_eoln }, /* Ud */ ! { NULL, post_lb }, /* Lb */ ! { pre_par, post_par }, /* Lp */ ! { NULL, NULL }, /* Lk */ ! { NULL, post_defaults }, /* Mt */ ! { NULL, NULL }, /* Brq */ ! { NULL, NULL }, /* Bro */ ! { NULL, NULL }, /* Brc */ ! { NULL, NULL }, /* %C */ ! { pre_obsolete, post_es }, /* Es */ ! { pre_obsolete, post_en }, /* En */ ! { NULL, NULL }, /* Dx */ ! { NULL, NULL }, /* %Q */ ! { NULL, post_par }, /* br */ ! { NULL, post_par }, /* sp */ ! { NULL, NULL }, /* %U */ ! { NULL, NULL }, /* Ta */ ! { NULL, NULL }, /* ll */ }; #define RSORD_MAX 14 /* Number of `Rs' blocks. */ --- 101,232 ---- static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); + static void post_std(POST_ARGS); ! static v_post mdoc_valids[MDOC_MAX] = { ! NULL, /* Ap */ ! post_dd, /* Dd */ ! post_dt, /* Dt */ ! post_os, /* Os */ ! post_sh, /* Sh */ ! post_ignpar, /* Ss */ ! post_par, /* Pp */ ! post_display, /* D1 */ ! post_display, /* Dl */ ! post_display, /* Bd */ ! NULL, /* Ed */ ! post_bl, /* Bl */ ! NULL, /* El */ ! post_it, /* It */ ! NULL, /* Ad */ ! post_an, /* An */ ! post_defaults, /* Ar */ ! NULL, /* Cd */ ! NULL, /* Cm */ ! NULL, /* Dv */ ! NULL, /* Er */ ! NULL, /* Ev */ ! post_ex, /* Ex */ ! post_fa, /* Fa */ ! NULL, /* Fd */ ! NULL, /* Fl */ ! post_fn, /* Fn */ ! NULL, /* Ft */ ! NULL, /* Ic */ ! NULL, /* In */ ! post_defaults, /* Li */ ! post_nd, /* Nd */ ! post_nm, /* Nm */ ! NULL, /* Op */ ! post_obsolete, /* Ot */ ! post_defaults, /* Pa */ ! post_std, /* Rv */ ! post_st, /* St */ ! NULL, /* Va */ ! NULL, /* Vt */ ! NULL, /* Xr */ ! NULL, /* %A */ ! post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ ! NULL, /* %D */ ! NULL, /* %I */ ! NULL, /* %J */ ! post_hyph, /* %N */ ! post_hyph, /* %O */ ! NULL, /* %P */ ! post_hyph, /* %R */ ! post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ ! NULL, /* %V */ ! NULL, /* Ac */ ! NULL, /* Ao */ ! NULL, /* Aq */ ! post_at, /* At */ ! NULL, /* Bc */ ! post_bf, /* Bf */ ! NULL, /* Bo */ ! NULL, /* Bq */ ! NULL, /* Bsx */ ! post_bx, /* Bx */ ! post_obsolete, /* Db */ ! NULL, /* Dc */ ! NULL, /* Do */ ! NULL, /* Dq */ ! NULL, /* Ec */ ! NULL, /* Ef */ ! NULL, /* Em */ ! NULL, /* Eo */ ! NULL, /* Fx */ ! NULL, /* Ms */ ! NULL, /* No */ ! post_ns, /* Ns */ ! NULL, /* Nx */ ! NULL, /* Ox */ ! NULL, /* Pc */ ! NULL, /* Pf */ ! NULL, /* Po */ ! NULL, /* Pq */ ! NULL, /* Qc */ ! NULL, /* Ql */ ! NULL, /* Qo */ ! NULL, /* Qq */ ! NULL, /* Re */ ! post_rs, /* Rs */ ! NULL, /* Sc */ ! NULL, /* So */ ! NULL, /* Sq */ ! post_sm, /* Sm */ ! post_hyph, /* Sx */ ! NULL, /* Sy */ ! NULL, /* Tn */ ! NULL, /* Ux */ ! NULL, /* Xc */ ! NULL, /* Xo */ ! post_fo, /* Fo */ ! NULL, /* Fc */ ! NULL, /* Oo */ ! NULL, /* Oc */ ! post_bk, /* Bk */ ! NULL, /* Ek */ ! post_eoln, /* Bt */ ! NULL, /* Hf */ ! post_obsolete, /* Fr */ ! post_eoln, /* Ud */ ! post_lb, /* Lb */ ! post_par, /* Lp */ ! NULL, /* Lk */ ! post_defaults, /* Mt */ ! NULL, /* Brq */ ! NULL, /* Bro */ ! NULL, /* Brc */ ! NULL, /* %C */ ! post_es, /* Es */ ! post_en, /* En */ ! NULL, /* Dx */ ! NULL, /* %Q */ ! post_par, /* br */ ! post_par, /* sp */ ! NULL, /* %U */ ! NULL, /* Ta */ ! NULL, /* ll */ }; #define RSORD_MAX 14 /* Number of `Rs' blocks. */ *************** *** 286,319 **** void - mdoc_valid_pre(struct roff_man *mdoc, struct roff_node *n) - { - v_pre p; - - switch (n->type) { - case ROFFT_TEXT: - if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) - check_text(mdoc, n->line, n->pos, n->string); - return; - case ROFFT_TBL: - case ROFFT_EQN: - case ROFFT_ROOT: - return; - default: - break; - } - - check_args(mdoc, n); - p = mdoc_valids[n->tok].pre; - if (*p) - (*p)(mdoc, n); - } - - void mdoc_node_validate(struct roff_man *mdoc) { struct roff_node *n; ! v_post p; n = mdoc->last; mdoc->last = mdoc->last->child; --- 276,285 ---- void mdoc_node_validate(struct roff_man *mdoc) { struct roff_node *n; ! v_post *p; n = mdoc->last; mdoc->last = mdoc->last->child; *************** *** 329,334 **** --- 295,303 ---- mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: + if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) + check_text(mdoc, n->line, n->pos, n->string); + break; case ROFFT_EQN: case ROFFT_TBL: break; *************** *** 336,341 **** --- 305,311 ---- post_root(mdoc); break; default: + check_args(mdoc, mdoc->last); /* * Closing delimiters are not special at the *************** *** 350,356 **** /* Call the macro's postprocessor. */ ! p = mdoc_valids[n->tok].post; if (*p) (*p)(mdoc); if (mdoc->last == n) --- 320,326 ---- /* Call the macro's postprocessor. */ ! p = mdoc_valids + n->tok; if (*p) (*p)(mdoc); if (mdoc->last == n) *************** *** 395,428 **** } static void ! pre_display(PRE_ARGS) { ! struct roff_node *node; ! ! if (n->type != ROFFT_BLOCK) ! return; ! ! for (node = mdoc->last->parent; node; node = node->parent) ! if (node->type == ROFFT_BLOCK) ! if (MDOC_Bd == node->tok) ! break; ! ! if (node) ! mandoc_vmsg(MANDOCERR_BD_NEST, ! mdoc->parse, n->line, n->pos, ! "%s in Bd", mdoc_macronames[n->tok]); ! } ! ! static void ! pre_bl(PRE_ARGS) ! { struct mdoc_argv *argv, *wa; int i; enum mdocargt mdoclt; enum mdoc_list lt; ! if (n->type != ROFFT_BLOCK) ! return; /* * First figure out which kind of list to use: bind ourselves to --- 365,380 ---- } static void ! post_bl_norm(POST_ARGS) { ! struct roff_node *n; struct mdoc_argv *argv, *wa; int i; enum mdocargt mdoclt; enum mdoc_list lt; ! n = mdoc->last->parent; ! n->norm->Bl.type = LIST__NONE; /* * First figure out which kind of list to use: bind ourselves to *************** *** 586,606 **** default: break; } - pre_par(mdoc, n); } static void ! pre_bd(PRE_ARGS) { struct mdoc_argv *argv; int i; enum mdoc_disp dt; ! pre_display(mdoc, n); ! ! if (n->type != ROFFT_BLOCK) ! return; ! for (i = 0; n->args && i < (int)n->args->argc; i++) { argv = n->args->argv + i; dt = DISP__NONE; --- 538,554 ---- default: break; } } static void ! post_bd(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; int i; enum mdoc_disp dt; ! n = mdoc->last; for (i = 0; n->args && i < (int)n->args->argc; i++) { argv = n->args->argv + i; dt = DISP__NONE; *************** *** 666,680 **** n->line, n->pos, "Bd"); n->norm->Bd.type = DISP_ragged; } - pre_par(mdoc, n); } static void ! pre_an(PRE_ARGS) { struct mdoc_argv *argv; size_t i; if (n->args == NULL) return; --- 614,629 ---- n->line, n->pos, "Bd"); n->norm->Bd.type = DISP_ragged; } } static void ! post_an_norm(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; size_t i; + n = mdoc->last; if (n->args == NULL) return; *************** *** 695,705 **** } static void ! pre_std(PRE_ARGS) { ! if (n->args && 1 == n->args->argc) ! if (MDOC_Std == n->args->argv[0].arg) return; mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, --- 644,656 ---- } static void ! post_std(POST_ARGS) { + struct roff_node *n; ! n = mdoc->last; ! if (n->args && n->args->argc == 1) ! if (n->args->argv[0].arg == MDOC_Std) return; mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, *************** *** 707,715 **** } static void ! pre_obsolete(PRE_ARGS) { if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); --- 658,668 ---- } static void ! post_obsolete(POST_ARGS) { + struct roff_node *n; + n = mdoc->last; if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); *************** *** 916,953 **** } static void ! post_d1(POST_ARGS) { ! struct roff_node *n; n = mdoc->last; ! ! if (n->type != ROFFT_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 roff_node *n; - - 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 post_defaults(POST_ARGS) { struct roff_node *nn; --- 869,909 ---- } static void ! post_display(POST_ARGS) { ! struct roff_node *n, *np; n = mdoc->last; ! switch (n->type) { ! case ROFFT_BODY: ! if (n->end != ENDBODY_NOT) ! break; ! if (n->child == NULL) ! mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, ! n->line, n->pos, mdoc_macronames[n->tok]); ! else if (n->tok == MDOC_D1) ! post_hyph(mdoc); ! break; ! case ROFFT_BLOCK: ! if (n->tok == MDOC_Bd) { ! post_bd(mdoc); ! post_prevpar(mdoc); ! } ! for (np = n->parent; np != NULL; np = np->parent) { ! if (np->type == ROFFT_BLOCK && np->tok == MDOC_Bd) { ! mandoc_vmsg(MANDOCERR_BD_NEST, ! mdoc->parse, n->line, n->pos, ! "%s in Bd", mdoc_macronames[n->tok]); ! break; ! } ! } ! break; ! default: ! break; ! } } static void post_defaults(POST_ARGS) { struct roff_node *nn; *************** *** 1019,1024 **** --- 975,982 ---- { struct roff_node *np, *nch; + post_an_norm(mdoc); + np = mdoc->last; nch = np->child; if (np->norm->An.auth == AUTH__NONE) { *************** *** 1034,1039 **** --- 992,998 ---- post_en(POST_ARGS) { + post_obsolete(mdoc); if (mdoc->last->type == ROFFT_BLOCK) mdoc->last->norm->Es = mdoc->last_es; } *************** *** 1042,1047 **** --- 1001,1007 ---- post_es(POST_ARGS) { + post_obsolete(mdoc); mdoc->last_es = mdoc->last; } *************** *** 1052,1057 **** --- 1012,1019 ---- int i, cols; enum mdoc_list lt; + post_prevpar(mdoc); + nit = mdoc->last; if (nit->type != ROFFT_BLOCK) return; *************** *** 1112,1117 **** --- 1074,1081 ---- { struct roff_node *n, *ni, *nc; + post_prevpar(mdoc); + /* * These are fairly complicated, so we've broken them into two * functions. post_bl_block_tag() is called when a -tag is *************** *** 1256,1263 **** struct mdoc_argv *argv; int i, j; ! nh = mdoc->last; if (nh->norm->Bl.type != LIST_column) { if ((nch = nh->child) == NULL) return; --- 1220,1228 ---- struct mdoc_argv *argv; int i, j; ! post_bl_norm(mdoc); + nh = mdoc->last; if (nh->norm->Bl.type != LIST_column) { if ((nch = nh->child) == NULL) return; *************** *** 1904,1913 **** } static void ! pre_par(PRE_ARGS) { ! if (NULL == mdoc->last) return; if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) return; --- 1869,1880 ---- } static void ! post_prevpar(POST_ARGS) { + struct roff_node *n; ! n = mdoc->last; ! if (NULL == n->prev) return; if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) return; *************** *** 1917,1938 **** * block: `Lp', `Pp', or non-compact `Bd' or `Bl'. */ ! if (MDOC_Pp != mdoc->last->tok && ! MDOC_Lp != mdoc->last->tok && ! MDOC_br != mdoc->last->tok) return; ! if (MDOC_Bl == n->tok && n->norm->Bl.comp) return; ! if (MDOC_Bd == n->tok && n->norm->Bd.comp) return; ! if (MDOC_It == n->tok && n->parent->norm->Bl.comp) return; 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]); ! roff_node_delete(mdoc, mdoc->last); } static void --- 1884,1905 ---- * block: `Lp', `Pp', or non-compact `Bd' or `Bl'. */ ! if (n->prev->tok != MDOC_Pp && ! n->prev->tok != MDOC_Lp && ! n->prev->tok != MDOC_br) return; ! if (n->tok == MDOC_Bl && n->norm->Bl.comp) return; ! if (n->tok == MDOC_Bd && n->norm->Bd.comp) return; ! if (n->tok == MDOC_It && n->parent->norm->Bl.comp) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, ! n->prev->line, n->prev->pos, ! "%s before %s", mdoc_macronames[n->prev->tok], mdoc_macronames[n->tok]); ! roff_node_delete(mdoc, n->prev); } static void *************** *** 1941,1946 **** --- 1908,1915 ---- struct roff_node *np; np = mdoc->last; + if (np->tok != MDOC_br && np->tok != MDOC_sp) + post_prevpar(mdoc); if (np->tok == MDOC_sp) { if (np->nchild > 1) *************** *** 2185,2192 **** { struct roff_node *n; ! n = mdoc->last; if (n->child != NULL) return; --- 2154,2162 ---- { struct roff_node *n; ! post_std(mdoc); + n = mdoc->last; if (n->child != NULL) return;