version 1.350, 2017/07/20 12:54:02 |
version 1.364, 2018/12/04 02:53:51 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> |
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 53 enum check_ineq { |
|
Line 53 enum check_ineq { |
|
typedef void (*v_post)(POST_ARGS); |
typedef void (*v_post)(POST_ARGS); |
|
|
static int build_list(struct roff_man *, int); |
static int build_list(struct roff_man *, int); |
static void check_text(struct roff_man *, int, int, char *); |
|
static void check_argv(struct roff_man *, |
static void check_argv(struct roff_man *, |
struct roff_node *, struct mdoc_argv *); |
struct roff_node *, struct mdoc_argv *); |
static void check_args(struct roff_man *, struct roff_node *); |
static void check_args(struct roff_man *, struct roff_node *); |
|
static void check_text(struct roff_man *, int, int, char *); |
|
static void check_text_em(struct roff_man *, int, int, char *); |
static void check_toptext(struct roff_man *, int, int, const char *); |
static void check_toptext(struct roff_man *, int, int, const char *); |
static int child_an(const struct roff_node *); |
static int child_an(const struct roff_node *); |
static size_t macro2len(enum roff_tok); |
static size_t macro2len(enum roff_tok); |
static void rewrite_macro2len(struct roff_man *, char **); |
static void rewrite_macro2len(struct roff_man *, char **); |
static int similar(const char *, const char *); |
static int similar(const char *, const char *); |
|
|
|
static void post_abort(POST_ARGS); |
static void post_an(POST_ARGS); |
static void post_an(POST_ARGS); |
static void post_an_norm(POST_ARGS); |
static void post_an_norm(POST_ARGS); |
static void post_at(POST_ARGS); |
static void post_at(POST_ARGS); |
Line 115 static void post_useless(POST_ARGS); |
|
Line 117 static void post_useless(POST_ARGS); |
|
static void post_xr(POST_ARGS); |
static void post_xr(POST_ARGS); |
static void post_xx(POST_ARGS); |
static void post_xx(POST_ARGS); |
|
|
static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { |
static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = { |
post_dd, /* Dd */ |
post_dd, /* Dd */ |
post_dt, /* Dt */ |
post_dt, /* Dt */ |
post_os, /* Os */ |
post_os, /* Os */ |
Line 150 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 152 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
post_nd, /* Nd */ |
post_nd, /* Nd */ |
post_nm, /* Nm */ |
post_nm, /* Nm */ |
post_delim_nb, /* Op */ |
post_delim_nb, /* Op */ |
post_obsolete, /* Ot */ |
post_abort, /* Ot */ |
post_defaults, /* Pa */ |
post_defaults, /* Pa */ |
post_rv, /* Rv */ |
post_rv, /* Rv */ |
post_st, /* St */ |
post_st, /* St */ |
Line 169 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 171 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
NULL, /* %V */ |
NULL, /* %V */ |
NULL, /* Ac */ |
NULL, /* Ac */ |
post_delim_nb, /* Ao */ |
NULL, /* Ao */ |
post_delim_nb, /* Aq */ |
post_delim_nb, /* Aq */ |
post_at, /* At */ |
post_at, /* At */ |
NULL, /* Bc */ |
NULL, /* Bc */ |
post_bf, /* Bf */ |
post_bf, /* Bf */ |
post_delim_nb, /* Bo */ |
NULL, /* Bo */ |
NULL, /* Bq */ |
NULL, /* Bq */ |
post_xx, /* Bsx */ |
post_xx, /* Bsx */ |
post_bx, /* Bx */ |
post_bx, /* Bx */ |
Line 194 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 196 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
post_xx, /* Ox */ |
post_xx, /* Ox */ |
NULL, /* Pc */ |
NULL, /* Pc */ |
NULL, /* Pf */ |
NULL, /* Pf */ |
post_delim_nb, /* Po */ |
NULL, /* Po */ |
post_delim_nb, /* Pq */ |
post_delim_nb, /* Pq */ |
NULL, /* Qc */ |
NULL, /* Qc */ |
post_delim_nb, /* Ql */ |
post_delim_nb, /* Ql */ |
post_delim_nb, /* Qo */ |
NULL, /* Qo */ |
post_delim_nb, /* Qq */ |
post_delim_nb, /* Qq */ |
NULL, /* Re */ |
NULL, /* Re */ |
post_rs, /* Rs */ |
post_rs, /* Rs */ |
NULL, /* Sc */ |
NULL, /* Sc */ |
post_delim_nb, /* So */ |
NULL, /* So */ |
post_delim_nb, /* Sq */ |
post_delim_nb, /* Sq */ |
post_sm, /* Sm */ |
post_sm, /* Sm */ |
post_sx, /* Sx */ |
post_sx, /* Sx */ |
Line 214 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 216 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
NULL, /* Xo */ |
NULL, /* Xo */ |
post_fo, /* Fo */ |
post_fo, /* Fo */ |
NULL, /* Fc */ |
NULL, /* Fc */ |
post_delim_nb, /* Oo */ |
NULL, /* Oo */ |
NULL, /* Oc */ |
NULL, /* Oc */ |
post_bk, /* Bk */ |
post_bk, /* Bk */ |
NULL, /* Ek */ |
NULL, /* Ek */ |
Line 223 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 225 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
post_obsolete, /* Fr */ |
post_obsolete, /* Fr */ |
post_eoln, /* Ud */ |
post_eoln, /* Ud */ |
post_lb, /* Lb */ |
post_lb, /* Lb */ |
post_par, /* Lp */ |
post_abort, /* Lp */ |
post_delim_nb, /* Lk */ |
post_delim_nb, /* Lk */ |
post_defaults, /* Mt */ |
post_defaults, /* Mt */ |
post_delim_nb, /* Brq */ |
post_delim_nb, /* Brq */ |
post_delim_nb, /* Bro */ |
NULL, /* Bro */ |
NULL, /* Brc */ |
NULL, /* Brc */ |
NULL, /* %C */ |
NULL, /* %C */ |
post_es, /* Es */ |
post_es, /* Es */ |
Line 237 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 239 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
NULL, /* %U */ |
NULL, /* %U */ |
NULL, /* Ta */ |
NULL, /* Ta */ |
}; |
}; |
static const v_post *const mdoc_valids = __mdoc_valids - MDOC_Dd; |
|
|
|
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
|
|
Line 285 static const char * const secnames[SEC__MAX] = { |
|
Line 286 static const char * const secnames[SEC__MAX] = { |
|
}; |
}; |
|
|
|
|
|
/* Validate the subtree rooted at mdoc->last. */ |
void |
void |
mdoc_node_validate(struct roff_man *mdoc) |
mdoc_node_validate(struct roff_man *mdoc) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n, *np; |
const v_post *p; |
const v_post *p; |
|
|
|
/* |
|
* Translate obsolete macros to modern macros first |
|
* such that later code does not need to look |
|
* for the obsolete versions. |
|
*/ |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
switch (n->tok) { |
|
case MDOC_Lp: |
|
n->tok = MDOC_Pp; |
|
break; |
|
case MDOC_Ot: |
|
post_obsolete(mdoc); |
|
n->tok = MDOC_Ft; |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
/* |
|
* Iterate over all children, recursing into each one |
|
* in turn, depth-first. |
|
*/ |
|
|
mdoc->last = mdoc->last->child; |
mdoc->last = mdoc->last->child; |
while (mdoc->last != NULL) { |
while (mdoc->last != NULL) { |
mdoc_node_validate(mdoc); |
mdoc_node_validate(mdoc); |
Line 301 mdoc_node_validate(struct roff_man *mdoc) |
|
Line 326 mdoc_node_validate(struct roff_man *mdoc) |
|
mdoc->last = mdoc->last->next; |
mdoc->last = mdoc->last->next; |
} |
} |
|
|
|
/* Finally validate the macro itself. */ |
|
|
mdoc->last = n; |
mdoc->last = n; |
mdoc->next = ROFF_NEXT_SIBLING; |
mdoc->next = ROFF_NEXT_SIBLING; |
switch (n->type) { |
switch (n->type) { |
case ROFFT_TEXT: |
case ROFFT_TEXT: |
|
np = n->parent; |
if (n->sec != SEC_SYNOPSIS || |
if (n->sec != SEC_SYNOPSIS || |
(n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd)) |
(np->tok != MDOC_Cd && np->tok != MDOC_Fd)) |
check_text(mdoc, n->line, n->pos, n->string); |
check_text(mdoc, n->line, n->pos, n->string); |
if (n->parent->tok == MDOC_It || |
if (np->tok != MDOC_Ql && np->tok != MDOC_Dl && |
(n->parent->type == ROFFT_BODY && |
(np->tok != MDOC_Bd || |
(n->parent->tok == MDOC_Sh || |
(mdoc->flags & MDOC_LITERAL) == 0) && |
n->parent->tok == MDOC_Ss))) |
(np->tok != MDOC_It || np->type != ROFFT_HEAD || |
|
np->parent->parent->norm->Bl.type != LIST_diag)) |
|
check_text_em(mdoc, n->line, n->pos, n->string); |
|
if (np->tok == MDOC_It || (np->type == ROFFT_BODY && |
|
(np->tok == MDOC_Sh || np->tok == MDOC_Ss))) |
check_toptext(mdoc, n->line, n->pos, n->string); |
check_toptext(mdoc, n->line, n->pos, n->string); |
break; |
break; |
|
case ROFFT_COMMENT: |
case ROFFT_EQN: |
case ROFFT_EQN: |
case ROFFT_TBL: |
case ROFFT_TBL: |
break; |
break; |
Line 337 mdoc_node_validate(struct roff_man *mdoc) |
|
Line 370 mdoc_node_validate(struct roff_man *mdoc) |
|
/* Call the macro's postprocessor. */ |
/* Call the macro's postprocessor. */ |
|
|
if (n->tok < ROFF_MAX) { |
if (n->tok < ROFF_MAX) { |
switch(n->tok) { |
roff_validate(mdoc); |
case ROFF_br: |
|
case ROFF_sp: |
|
post_par(mdoc); |
|
break; |
|
default: |
|
roff_validate(mdoc); |
|
break; |
|
} |
|
break; |
break; |
} |
} |
|
|
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); |
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); |
p = mdoc_valids + n->tok; |
p = mdoc_valids + (n->tok - MDOC_Dd); |
if (*p) |
if (*p) |
(*p)(mdoc); |
(*p)(mdoc); |
if (mdoc->last == n) |
if (mdoc->last == n) |
Line 395 check_text(struct roff_man *mdoc, int ln, int pos, cha |
|
Line 420 check_text(struct roff_man *mdoc, int ln, int pos, cha |
|
} |
} |
|
|
static void |
static void |
|
check_text_em(struct roff_man *mdoc, int ln, int pos, char *p) |
|
{ |
|
const struct roff_node *np, *nn; |
|
char *cp; |
|
|
|
np = mdoc->last->prev; |
|
nn = mdoc->last->next; |
|
|
|
/* Look for em-dashes wrongly encoded as "--". */ |
|
|
|
for (cp = p; *cp != '\0'; cp++) { |
|
if (cp[0] != '-' || cp[1] != '-') |
|
continue; |
|
cp++; |
|
|
|
/* Skip input sequences of more than two '-'. */ |
|
|
|
if (cp[1] == '-') { |
|
while (cp[1] == '-') |
|
cp++; |
|
continue; |
|
} |
|
|
|
/* Skip "--" directly attached to something else. */ |
|
|
|
if ((cp - p > 1 && cp[-2] != ' ') || |
|
(cp[1] != '\0' && cp[1] != ' ')) |
|
continue; |
|
|
|
/* Require a letter right before or right afterwards. */ |
|
|
|
if ((cp - p > 2 ? |
|
isalpha((unsigned char)cp[-3]) : |
|
np != NULL && |
|
np->type == ROFFT_TEXT && |
|
*np->string != '\0' && |
|
isalpha((unsigned char)np->string[ |
|
strlen(np->string) - 1])) || |
|
(cp[1] != '\0' && cp[2] != '\0' ? |
|
isalpha((unsigned char)cp[2]) : |
|
nn != NULL && |
|
nn->type == ROFFT_TEXT && |
|
isalpha((unsigned char)*nn->string))) { |
|
mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse, |
|
ln, pos + (int)(cp - p) - 1, NULL); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
static void |
check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p) |
check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p) |
{ |
{ |
const char *cp, *cpr; |
const char *cp, *cpr; |
Line 430 check_toptext(struct roff_man *mdoc, int ln, int pos, |
|
Line 506 check_toptext(struct roff_man *mdoc, int ln, int pos, |
|
} |
} |
|
|
static void |
static void |
|
post_abort(POST_ARGS) |
|
{ |
|
abort(); |
|
} |
|
|
|
static void |
post_delim(POST_ARGS) |
post_delim(POST_ARGS) |
{ |
{ |
const struct roff_node *nch; |
const struct roff_node *nch; |
Line 530 post_delim_nb(POST_ARGS) |
|
Line 612 post_delim_nb(POST_ARGS) |
|
|
|
/* At least three alphabetic words with a sentence ending. */ |
/* At least three alphabetic words with a sentence ending. */ |
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em || |
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em || |
tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq || |
tok == MDOC_Li || tok == MDOC_Pq || tok == MDOC_Sy)) { |
tok == MDOC_Sy)) { |
|
nw = 0; |
nw = 0; |
for (cp = lc - 1; cp >= nch->string; cp--) { |
for (cp = lc - 1; cp >= nch->string; cp--) { |
if (*cp == ' ') { |
if (*cp == ' ') { |
Line 867 build_list(struct roff_man *mdoc, int tok) |
|
Line 948 build_list(struct roff_man *mdoc, int tok) |
|
for (ic = 1;; ic++) { |
for (ic = 1;; ic++) { |
roff_elem_alloc(mdoc, n->line, n->pos, tok); |
roff_elem_alloc(mdoc, n->line, n->pos, tok); |
mdoc->last->flags |= NODE_NOSRC; |
mdoc->last->flags |= NODE_NOSRC; |
mdoc_node_relink(mdoc, n); |
roff_node_relink(mdoc, n); |
n = mdoc->last = mdoc->last->parent; |
n = mdoc->last = mdoc->last->parent; |
mdoc->next = ROFF_NEXT_SIBLING; |
mdoc->next = ROFF_NEXT_SIBLING; |
if (n->next == NULL) |
if (n->next == NULL) |
Line 947 post_lb(POST_ARGS) |
|
Line 1028 post_lb(POST_ARGS) |
|
|
|
roff_word_alloc(mdoc, n->line, n->pos, "library"); |
roff_word_alloc(mdoc, n->line, n->pos, "library"); |
mdoc->last->flags = NODE_NOSRC; |
mdoc->last->flags = NODE_NOSRC; |
roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq"); |
roff_word_alloc(mdoc, n->line, n->pos, "\\(lq"); |
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC; |
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC; |
mdoc->last = mdoc->last->next; |
mdoc->last = mdoc->last->next; |
roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq"); |
roff_word_alloc(mdoc, n->line, n->pos, "\\(rq"); |
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC; |
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC; |
mdoc->last = n; |
mdoc->last = n; |
} |
} |
Line 1137 post_fname(POST_ARGS) |
|
Line 1218 post_fname(POST_ARGS) |
|
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*'))) |
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*'))) |
mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse, |
mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse, |
n->line, n->pos + pos, n->string); |
n->line, n->pos + pos, n->string); |
if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL) |
|
mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1); |
|
} |
} |
|
|
static void |
static void |
Line 1205 post_nm(POST_ARGS) |
|
Line 1284 post_nm(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) && |
if (n->sec == SEC_NAME && n->child != NULL && |
n->child != NULL && n->child->type == ROFFT_TEXT && |
n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL) |
mdoc->meta.msec != NULL) |
|
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1); |
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1); |
|
|
if (n->last != NULL && |
if (n->last != NULL && n->last->tok == MDOC_Pp) |
(n->last->tok == MDOC_Pp || |
roff_node_relink(mdoc, n->last); |
n->last->tok == MDOC_Lp)) |
|
mdoc_node_relink(mdoc, n->last); |
|
|
|
if (mdoc->meta.name == NULL) |
if (mdoc->meta.name == NULL) |
deroff(&mdoc->meta.name, n); |
deroff(&mdoc->meta.name, n); |
Line 1292 post_display(POST_ARGS) |
|
Line 1368 post_display(POST_ARGS) |
|
mdoc->parse, n->line, n->pos, "Bd"); |
mdoc->parse, n->line, n->pos, "Bd"); |
mdoc->next = ROFF_NEXT_SIBLING; |
mdoc->next = ROFF_NEXT_SIBLING; |
while (n->body->child != NULL) |
while (n->body->child != NULL) |
mdoc_node_relink(mdoc, |
roff_node_relink(mdoc, |
n->body->child); |
n->body->child); |
roff_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
break; |
break; |
Line 1565 post_bl_block(POST_ARGS) |
|
Line 1641 post_bl_block(POST_ARGS) |
|
while (nc != NULL) { |
while (nc != NULL) { |
switch (nc->tok) { |
switch (nc->tok) { |
case MDOC_Pp: |
case MDOC_Pp: |
case MDOC_Lp: |
|
case ROFF_br: |
case ROFF_br: |
break; |
break; |
default: |
default: |
Line 1576 post_bl_block(POST_ARGS) |
|
Line 1651 post_bl_block(POST_ARGS) |
|
mandoc_msg(MANDOCERR_PAR_MOVE, |
mandoc_msg(MANDOCERR_PAR_MOVE, |
mdoc->parse, nc->line, nc->pos, |
mdoc->parse, nc->line, nc->pos, |
roff_name[nc->tok]); |
roff_name[nc->tok]); |
mdoc_node_relink(mdoc, nc); |
roff_node_relink(mdoc, nc); |
} else if (n->norm->Bl.comp == 0 && |
} else if (n->norm->Bl.comp == 0 && |
n->norm->Bl.type != LIST_column) { |
n->norm->Bl.type != LIST_column) { |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
Line 1736 post_bl(POST_ARGS) |
|
Line 1811 post_bl(POST_ARGS) |
|
roff_body_alloc(mdoc, nchild->line, |
roff_body_alloc(mdoc, nchild->line, |
nchild->pos, MDOC_It); |
nchild->pos, MDOC_It); |
while (nchild->tok != MDOC_It) { |
while (nchild->tok != MDOC_It) { |
mdoc_node_relink(mdoc, nchild); |
roff_node_relink(mdoc, nchild); |
if ((nchild = nnext) == NULL) |
if ((nchild = nnext) == NULL) |
break; |
break; |
nnext = nchild->next; |
nnext = nchild->next; |
Line 1855 post_sm(POST_ARGS) |
|
Line 1930 post_sm(POST_ARGS) |
|
mandoc_vmsg(MANDOCERR_SM_BAD, |
mandoc_vmsg(MANDOCERR_SM_BAD, |
mdoc->parse, nch->line, nch->pos, |
mdoc->parse, nch->line, nch->pos, |
"%s %s", roff_name[mdoc->last->tok], nch->string); |
"%s %s", roff_name[mdoc->last->tok], nch->string); |
mdoc_node_relink(mdoc, nch); |
roff_node_relink(mdoc, nch); |
return; |
return; |
} |
} |
|
|
Line 1917 post_root(POST_ARGS) |
|
Line 1992 post_root(POST_ARGS) |
|
arch++; |
arch++; |
if (*arch == NULL) { |
if (*arch == NULL) { |
n = mdoc->first->child; |
n = mdoc->first->child; |
while (n->tok != MDOC_Dt) |
while (n->tok != MDOC_Dt || |
|
n->child == NULL || |
|
n->child->next == NULL || |
|
n->child->next->next == NULL) |
n = n->next; |
n = n->next; |
n = n->child->next->next; |
n = n->child->next->next; |
mandoc_vmsg(MANDOCERR_ARCH_BAD, |
mandoc_vmsg(MANDOCERR_ARCH_BAD, |
Line 1931 post_root(POST_ARGS) |
|
Line 2009 post_root(POST_ARGS) |
|
/* Check that we begin with a proper `Sh'. */ |
/* Check that we begin with a proper `Sh'. */ |
|
|
n = mdoc->first->child; |
n = mdoc->first->child; |
while (n != NULL && n->tok != TOKEN_NONE && |
while (n != NULL && |
mdoc_macros[n->tok].flags & MDOC_PROLOGUE) |
(n->type == ROFFT_COMMENT || |
|
(n->tok >= MDOC_Dd && |
|
mdoc_macro(n->tok)->flags & MDOC_PROLOGUE))) |
n = n->next; |
n = n->next; |
|
|
if (n == NULL) |
if (n == NULL) |
Line 2434 post_ignpar(POST_ARGS) |
|
Line 2514 post_ignpar(POST_ARGS) |
|
} |
} |
|
|
if ((np = mdoc->last->child) != NULL) |
if ((np = mdoc->last->child) != NULL) |
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { |
if (np->tok == MDOC_Pp || |
|
np->tok == ROFF_br || np->tok == ROFF_sp) { |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
mdoc->parse, np->line, np->pos, |
mdoc->parse, np->line, np->pos, |
"%s after %s", roff_name[np->tok], |
"%s after %s", roff_name[np->tok], |
Line 2443 post_ignpar(POST_ARGS) |
|
Line 2524 post_ignpar(POST_ARGS) |
|
} |
} |
|
|
if ((np = mdoc->last->last) != NULL) |
if ((np = mdoc->last->last) != NULL) |
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { |
if (np->tok == MDOC_Pp || np->tok == ROFF_br) { |
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
np->line, np->pos, "%s at the end of %s", |
np->line, np->pos, "%s at the end of %s", |
roff_name[np->tok], |
roff_name[np->tok], |
Line 2464 post_prevpar(POST_ARGS) |
|
Line 2545 post_prevpar(POST_ARGS) |
|
return; |
return; |
|
|
/* |
/* |
* Don't allow prior `Lp' or `Pp' prior to a paragraph-type |
* Don't allow `Pp' prior to a paragraph-type |
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'. |
* block: `Pp' or non-compact `Bd' or `Bl'. |
*/ |
*/ |
|
|
if (n->prev->tok != MDOC_Pp && |
if (n->prev->tok != MDOC_Pp && n->prev->tok != ROFF_br) |
n->prev->tok != MDOC_Lp && |
|
n->prev->tok != ROFF_br) |
|
return; |
return; |
if (n->tok == MDOC_Bl && n->norm->Bl.comp) |
if (n->tok == MDOC_Bl && n->norm->Bl.comp) |
return; |
return; |
Line 2490 post_par(POST_ARGS) |
|
Line 2569 post_par(POST_ARGS) |
|
{ |
{ |
struct roff_node *np; |
struct roff_node *np; |
|
|
np = mdoc->last; |
post_prevpar(mdoc); |
if (np->tok != ROFF_br && np->tok != ROFF_sp) |
|
post_prevpar(mdoc); |
|
|
|
if (np->tok == ROFF_sp) { |
np = mdoc->last; |
if (np->child != NULL && np->child->next != NULL) |
if (np->child != NULL) |
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, |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
mdoc->parse, np->line, np->pos, "%s %s", |
mdoc->parse, np->line, np->pos, "%s %s", |
roff_name[np->tok], np->child->string); |
roff_name[np->tok], np->child->string); |
|
|
if ((np = mdoc->last->prev) == NULL) { |
|
np = mdoc->last->parent; |
|
if (np->tok != MDOC_Sh && np->tok != MDOC_Ss) |
|
return; |
|
} else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp && |
|
(mdoc->last->tok != ROFF_br || |
|
(np->tok != ROFF_sp && np->tok != ROFF_br))) |
|
return; |
|
|
|
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
|
mdoc->last->line, mdoc->last->pos, "%s after %s", |
|
roff_name[mdoc->last->tok], roff_name[np->tok]); |
|
roff_node_delete(mdoc, mdoc->last); |
|
} |
} |
|
|
static void |
static void |