version 1.346, 2017/07/01 09:47:30 |
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 78 static void post_defaults(POST_ARGS); |
|
Line 80 static void post_defaults(POST_ARGS); |
|
static void post_display(POST_ARGS); |
static void post_display(POST_ARGS); |
static void post_dd(POST_ARGS); |
static void post_dd(POST_ARGS); |
static void post_delim(POST_ARGS); |
static void post_delim(POST_ARGS); |
|
static void post_delim_nb(POST_ARGS); |
static void post_dt(POST_ARGS); |
static void post_dt(POST_ARGS); |
static void post_en(POST_ARGS); |
static void post_en(POST_ARGS); |
static void post_es(POST_ARGS); |
static void post_es(POST_ARGS); |
Line 109 static void post_sh_authors(POST_ARGS); |
|
Line 112 static void post_sh_authors(POST_ARGS); |
|
static void post_sm(POST_ARGS); |
static void post_sm(POST_ARGS); |
static void post_st(POST_ARGS); |
static void post_st(POST_ARGS); |
static void post_std(POST_ARGS); |
static void post_std(POST_ARGS); |
|
static void post_sx(POST_ARGS); |
static void post_useless(POST_ARGS); |
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 127 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 131 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
post_bl, /* Bl */ |
post_bl, /* Bl */ |
NULL, /* El */ |
NULL, /* El */ |
post_it, /* It */ |
post_it, /* It */ |
post_delim, /* Ad */ |
post_delim_nb, /* Ad */ |
post_an, /* An */ |
post_an, /* An */ |
NULL, /* Ap */ |
NULL, /* Ap */ |
post_defaults, /* Ar */ |
post_defaults, /* Ar */ |
NULL, /* Cd */ |
NULL, /* Cd */ |
post_delim, /* Cm */ |
post_delim_nb, /* Cm */ |
post_delim, /* Dv */ |
post_delim_nb, /* Dv */ |
post_delim, /* Er */ |
post_delim_nb, /* Er */ |
post_delim, /* Ev */ |
post_delim_nb, /* Ev */ |
post_ex, /* Ex */ |
post_ex, /* Ex */ |
post_fa, /* Fa */ |
post_fa, /* Fa */ |
NULL, /* Fd */ |
NULL, /* Fd */ |
post_delim, /* Fl */ |
post_delim_nb, /* Fl */ |
post_fn, /* Fn */ |
post_fn, /* Fn */ |
post_delim, /* Ft */ |
post_delim_nb, /* Ft */ |
post_delim, /* Ic */ |
post_delim_nb, /* Ic */ |
post_delim, /* In */ |
post_delim_nb, /* In */ |
post_defaults, /* Li */ |
post_defaults, /* Li */ |
post_nd, /* Nd */ |
post_nd, /* Nd */ |
post_nm, /* Nm */ |
post_nm, /* Nm */ |
post_delim, /* 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 */ |
post_delim, /* Va */ |
post_delim_nb, /* Va */ |
post_delim, /* Vt */ |
post_delim_nb, /* Vt */ |
post_xr, /* Xr */ |
post_xr, /* Xr */ |
NULL, /* %A */ |
NULL, /* %A */ |
post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
Line 167 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, /* Ao */ |
NULL, /* Ao */ |
post_delim, /* Aq */ |
post_delim_nb, /* Aq */ |
post_at, /* At */ |
post_at, /* At */ |
NULL, /* Bc */ |
NULL, /* Bc */ |
post_bf, /* Bf */ |
post_bf, /* Bf */ |
post_delim, /* Bo */ |
NULL, /* Bo */ |
NULL, /* Bq */ |
NULL, /* Bq */ |
post_xx, /* Bsx */ |
post_xx, /* Bsx */ |
post_bx, /* Bx */ |
post_bx, /* Bx */ |
Line 182 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
Line 186 static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] |
|
NULL, /* Dq */ |
NULL, /* Dq */ |
NULL, /* Ec */ |
NULL, /* Ec */ |
NULL, /* Ef */ |
NULL, /* Ef */ |
post_delim, /* Em */ |
post_delim_nb, /* Em */ |
NULL, /* Eo */ |
NULL, /* Eo */ |
post_xx, /* Fx */ |
post_xx, /* Fx */ |
post_delim, /* Ms */ |
post_delim_nb, /* Ms */ |
NULL, /* No */ |
NULL, /* No */ |
post_ns, /* Ns */ |
post_ns, /* Ns */ |
post_xx, /* Nx */ |
post_xx, /* Nx */ |
post_xx, /* Ox */ |
post_xx, /* Ox */ |
NULL, /* Pc */ |
NULL, /* Pc */ |
NULL, /* Pf */ |
NULL, /* Pf */ |
post_delim, /* Po */ |
NULL, /* Po */ |
post_delim, /* Pq */ |
post_delim_nb, /* Pq */ |
NULL, /* Qc */ |
NULL, /* Qc */ |
post_delim, /* Ql */ |
post_delim_nb, /* Ql */ |
post_delim, /* Qo */ |
NULL, /* Qo */ |
post_delim, /* Qq */ |
post_delim_nb, /* Qq */ |
NULL, /* Re */ |
NULL, /* Re */ |
post_rs, /* Rs */ |
post_rs, /* Rs */ |
NULL, /* Sc */ |
NULL, /* Sc */ |
post_delim, /* So */ |
NULL, /* So */ |
post_delim, /* Sq */ |
post_delim_nb, /* Sq */ |
post_sm, /* Sm */ |
post_sm, /* Sm */ |
post_hyph, /* Sx */ |
post_sx, /* Sx */ |
post_delim, /* Sy */ |
post_delim_nb, /* Sy */ |
post_useless, /* Tn */ |
post_useless, /* Tn */ |
post_xx, /* Ux */ |
post_xx, /* Ux */ |
NULL, /* Xc */ |
NULL, /* Xc */ |
NULL, /* Xo */ |
NULL, /* Xo */ |
post_fo, /* Fo */ |
post_fo, /* Fo */ |
NULL, /* Fc */ |
NULL, /* Fc */ |
post_delim, /* Oo */ |
NULL, /* Oo */ |
NULL, /* Oc */ |
NULL, /* Oc */ |
post_bk, /* Bk */ |
post_bk, /* Bk */ |
NULL, /* Ek */ |
NULL, /* Ek */ |
Line 221 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, /* Lk */ |
post_delim_nb, /* Lk */ |
post_defaults, /* Mt */ |
post_defaults, /* Mt */ |
post_delim, /* Brq */ |
post_delim_nb, /* Brq */ |
post_delim, /* Bro */ |
NULL, /* Bro */ |
NULL, /* Brc */ |
NULL, /* Brc */ |
NULL, /* %C */ |
NULL, /* %C */ |
post_es, /* Es */ |
post_es, /* Es */ |
Line 235 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 283 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 299 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 335 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 393 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 428 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; |
|
const char *lc; |
|
enum mdelim delim; |
|
enum roff_tok tok; |
|
|
|
tok = mdoc->last->tok; |
|
nch = mdoc->last->last; |
|
if (nch == NULL || nch->type != ROFFT_TEXT) |
|
return; |
|
lc = strchr(nch->string, '\0') - 1; |
|
if (lc < nch->string) |
|
return; |
|
delim = mdoc_isdelim(lc); |
|
if (delim == DELIM_NONE || delim == DELIM_OPEN) |
|
return; |
|
if (*lc == ')' && (tok == MDOC_Nd || tok == MDOC_Sh || |
|
tok == MDOC_Ss || tok == MDOC_Fo)) |
|
return; |
|
|
|
mandoc_vmsg(MANDOCERR_DELIM, mdoc->parse, |
|
nch->line, nch->pos + (lc - nch->string), |
|
"%s%s %s", roff_name[tok], |
|
nch == mdoc->last->child ? "" : " ...", nch->string); |
|
} |
|
|
|
static void |
|
post_delim_nb(POST_ARGS) |
|
{ |
|
const struct roff_node *nch; |
const char *lc, *cp; |
const char *lc, *cp; |
int nw; |
int nw; |
enum mdelim delim; |
enum mdelim delim; |
Line 500 post_delim(POST_ARGS) |
|
Line 612 post_delim(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 516 post_delim(POST_ARGS) |
|
Line 627 post_delim(POST_ARGS) |
|
} |
} |
} |
} |
|
|
mandoc_vmsg(MANDOCERR_DELIM, mdoc->parse, |
mandoc_vmsg(MANDOCERR_DELIM_NB, mdoc->parse, |
nch->line, nch->pos + (lc - nch->string), |
nch->line, nch->pos + (lc - nch->string), |
"%s%s %s", roff_name[tok], |
"%s%s %s", roff_name[tok], |
nch == mdoc->last->child ? "" : " ...", nch->string); |
nch == mdoc->last->child ? "" : " ...", nch->string); |
Line 670 post_bl_norm(POST_ARGS) |
|
Line 781 post_bl_norm(POST_ARGS) |
|
|
|
switch (n->norm->Bl.type) { |
switch (n->norm->Bl.type) { |
case LIST_tag: |
case LIST_tag: |
if (NULL == n->norm->Bl.width) |
if (n->norm->Bl.width == NULL) |
mandoc_msg(MANDOCERR_BL_NOWIDTH, mdoc->parse, |
mandoc_msg(MANDOCERR_BL_NOWIDTH, mdoc->parse, |
n->line, n->pos, "Bl -tag"); |
n->line, n->pos, "Bl -tag"); |
break; |
break; |
Line 679 post_bl_norm(POST_ARGS) |
|
Line 790 post_bl_norm(POST_ARGS) |
|
case LIST_ohang: |
case LIST_ohang: |
case LIST_inset: |
case LIST_inset: |
case LIST_item: |
case LIST_item: |
if (n->norm->Bl.width) |
if (n->norm->Bl.width != NULL) |
mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, |
mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, |
wa->line, wa->pos, "Bl -%s", |
wa->line, wa->pos, "Bl -%s", |
mdoc_argnames[mdoclt]); |
mdoc_argnames[mdoclt]); |
|
n->norm->Bl.width = NULL; |
break; |
break; |
case LIST_bullet: |
case LIST_bullet: |
case LIST_dash: |
case LIST_dash: |
case LIST_hyphen: |
case LIST_hyphen: |
if (NULL == n->norm->Bl.width) |
if (n->norm->Bl.width == NULL) |
n->norm->Bl.width = "2n"; |
n->norm->Bl.width = "2n"; |
break; |
break; |
case LIST_enum: |
case LIST_enum: |
if (NULL == n->norm->Bl.width) |
if (n->norm->Bl.width == NULL) |
n->norm->Bl.width = "3n"; |
n->norm->Bl.width = "3n"; |
break; |
break; |
default: |
default: |
Line 836 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 897 post_lb(POST_ARGS) |
|
Line 1009 post_lb(POST_ARGS) |
|
struct roff_node *n; |
struct roff_node *n; |
const char *p; |
const char *p; |
|
|
post_delim(mdoc); |
post_delim_nb(mdoc); |
|
|
n = mdoc->last; |
n = mdoc->last; |
assert(n->child->type == ROFFT_TEXT); |
assert(n->child->type == ROFFT_TEXT); |
Line 916 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 968 post_std(POST_ARGS) |
|
Line 1080 post_std(POST_ARGS) |
|
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
|
|
|
post_delim(mdoc); |
|
|
n = mdoc->last; |
n = mdoc->last; |
if (n->args && n->args->argc == 1) |
if (n->args && n->args->argc == 1) |
if (n->args->argv[0].arg == MDOC_Std) |
if (n->args->argv[0].arg == MDOC_Std) |
Line 1135 post_fo(POST_ARGS) |
|
Line 1249 post_fo(POST_ARGS) |
|
"Fo ... %s", n->child->next->string); |
"Fo ... %s", n->child->next->string); |
while (n->child != n->last) |
while (n->child != n->last) |
roff_node_delete(mdoc, n->last); |
roff_node_delete(mdoc, n->last); |
} |
} else |
|
post_delim(mdoc); |
|
|
post_fname(mdoc); |
post_fname(mdoc); |
} |
} |
Line 1159 post_fa(POST_ARGS) |
|
Line 1274 post_fa(POST_ARGS) |
|
break; |
break; |
} |
} |
} |
} |
post_delim(mdoc); |
post_delim_nb(mdoc); |
} |
} |
|
|
static void |
static void |
Line 1169 post_nm(POST_ARGS) |
|
Line 1284 post_nm(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (n->last != NULL && |
if (n->sec == SEC_NAME && n->child != NULL && |
(n->last->tok == MDOC_Pp || |
n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL) |
n->last->tok == MDOC_Lp)) |
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1); |
mdoc_node_relink(mdoc, n->last); |
|
|
|
|
if (n->last != NULL && n->last->tok == MDOC_Pp) |
|
roff_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 1182 post_nm(POST_ARGS) |
|
Line 1299 post_nm(POST_ARGS) |
|
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, |
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, |
n->line, n->pos, "Nm"); |
n->line, n->pos, "Nm"); |
|
|
if (n->type == ROFFT_ELEM) |
switch (n->type) { |
|
case ROFFT_ELEM: |
|
post_delim_nb(mdoc); |
|
break; |
|
case ROFFT_HEAD: |
post_delim(mdoc); |
post_delim(mdoc); |
|
break; |
|
default: |
|
return; |
|
} |
|
|
if ((n->type != ROFFT_ELEM && n->type != ROFFT_HEAD) || |
if ((n->child != NULL && n->child->type == ROFFT_TEXT) || |
(n->child != NULL && n->child->type == ROFFT_TEXT) || |
|
mdoc->meta.name == NULL) |
mdoc->meta.name == NULL) |
return; |
return; |
|
|
|
|
post_nd(POST_ARGS) |
post_nd(POST_ARGS) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
size_t sz; |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 1214 post_nd(POST_ARGS) |
|
Line 1337 post_nd(POST_ARGS) |
|
if (n->child == NULL) |
if (n->child == NULL) |
mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse, |
mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse, |
n->line, n->pos, "Nd"); |
n->line, n->pos, "Nd"); |
else if (n->last->type == ROFFT_TEXT && |
else |
(sz = strlen(n->last->string)) != 0 && |
post_delim(mdoc); |
n->last->string[sz - 1] == '.') |
|
mandoc_msg(MANDOCERR_ND_DOT, mdoc->parse, |
|
n->last->line, n->last->pos + sz - 1, NULL); |
|
|
|
post_hyph(mdoc); |
post_hyph(mdoc); |
} |
} |
Line 1248 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 1276 post_defaults(POST_ARGS) |
|
Line 1396 post_defaults(POST_ARGS) |
|
struct roff_node *nn; |
struct roff_node *nn; |
|
|
if (mdoc->last->child != NULL) { |
if (mdoc->last->child != NULL) { |
post_delim(mdoc); |
post_delim_nb(mdoc); |
return; |
return; |
} |
} |
|
|
Line 1351 post_an(POST_ARGS) |
|
Line 1471 post_an(POST_ARGS) |
|
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, |
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, |
np->line, np->pos, "An"); |
np->line, np->pos, "An"); |
else |
else |
post_delim(mdoc); |
post_delim_nb(mdoc); |
} else if (nch != NULL) |
} else if (nch != NULL) |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
nch->line, nch->pos, "An ... %s", nch->string); |
nch->line, nch->pos, "An ... %s", nch->string); |
Line 1379 post_xx(POST_ARGS) |
|
Line 1499 post_xx(POST_ARGS) |
|
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
const char *os; |
const char *os; |
|
char *v; |
|
|
post_delim(mdoc); |
post_delim_nb(mdoc); |
|
|
n = mdoc->last; |
n = mdoc->last; |
switch (n->tok) { |
switch (n->tok) { |
Line 1395 post_xx(POST_ARGS) |
|
Line 1516 post_xx(POST_ARGS) |
|
break; |
break; |
case MDOC_Nx: |
case MDOC_Nx: |
os = "NetBSD"; |
os = "NetBSD"; |
|
if (n->child == NULL) |
|
break; |
|
v = n->child->string; |
|
if ((v[0] != '0' && v[0] != '1') || v[1] != '.' || |
|
v[2] < '0' || v[2] > '9' || |
|
v[3] < 'a' || v[3] > 'z' || v[4] != '\0') |
|
break; |
|
n->child->flags |= NODE_NOPRT; |
|
mdoc->next = ROFF_NEXT_CHILD; |
|
roff_word_alloc(mdoc, n->child->line, n->child->pos, v); |
|
v = mdoc->last->string; |
|
v[3] = toupper((unsigned char)v[3]); |
|
mdoc->last->flags |= NODE_NOSRC; |
|
mdoc->last = n; |
break; |
break; |
case MDOC_Ox: |
case MDOC_Ox: |
os = "OpenBSD"; |
os = "OpenBSD"; |
Line 1506 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 1517 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 1677 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 1796 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 1858 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 1872 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 2009 post_ns(POST_ARGS) |
|
Line 2148 post_ns(POST_ARGS) |
|
} |
} |
|
|
static void |
static void |
|
post_sx(POST_ARGS) |
|
{ |
|
post_delim(mdoc); |
|
post_hyph(mdoc); |
|
} |
|
|
|
static void |
post_sh(POST_ARGS) |
post_sh(POST_ARGS) |
{ |
{ |
|
|
Line 2339 post_xr(POST_ARGS) |
|
Line 2485 post_xr(POST_ARGS) |
|
n->line, n->pos, "Xr %s", nch->string); |
n->line, n->pos, "Xr %s", nch->string); |
} else { |
} else { |
assert(nch->next == n->last); |
assert(nch->next == n->last); |
mandoc_xr_add(nch->next->string, nch->string, |
if(mandoc_xr_add(nch->next->string, nch->string, |
nch->line, nch->pos); |
nch->line, nch->pos)) |
|
mandoc_vmsg(MANDOCERR_XR_SELF, mdoc->parse, |
|
nch->line, nch->pos, "Xr %s %s", |
|
nch->string, nch->next->string); |
} |
} |
post_delim(mdoc); |
post_delim_nb(mdoc); |
} |
} |
|
|
static void |
static void |
Line 2355 post_ignpar(POST_ARGS) |
|
Line 2504 post_ignpar(POST_ARGS) |
|
post_prevpar(mdoc); |
post_prevpar(mdoc); |
return; |
return; |
case ROFFT_HEAD: |
case ROFFT_HEAD: |
|
post_delim(mdoc); |
post_hyph(mdoc); |
post_hyph(mdoc); |
return; |
return; |
case ROFFT_BODY: |
case ROFFT_BODY: |
Line 2364 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 2373 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 2394 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 2420 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 |
Line 2591 post_bx(POST_ARGS) |
|
Line 2720 post_bx(POST_ARGS) |
|
struct roff_node *n, *nch; |
struct roff_node *n, *nch; |
const char *macro; |
const char *macro; |
|
|
post_delim(mdoc); |
post_delim_nb(mdoc); |
|
|
n = mdoc->last; |
n = mdoc->last; |
nch = n->child; |
nch = n->child; |
Line 2656 post_os(POST_ARGS) |
|
Line 2785 post_os(POST_ARGS) |
|
else if (mdoc->flags & MDOC_PBODY) |
else if (mdoc->flags & MDOC_PBODY) |
mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, |
mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, |
n->line, n->pos, "Os"); |
n->line, n->pos, "Os"); |
|
|
|
post_delim(mdoc); |
|
|
/* |
/* |
* Set the operating system by way of the `Os' macro. |
* Set the operating system by way of the `Os' macro. |