version 1.358, 2018/04/11 17:11:13 |
version 1.364, 2018/12/04 02:53:51 |
Line 64 static size_t macro2len(enum roff_tok); |
|
Line 64 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 116 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 151 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 224 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 */ |
Line 238 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 286 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, *np; |
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 302 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) { |
Line 344 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 437 check_text_em(struct roff_man *mdoc, int ln, int pos, |
|
Line 455 check_text_em(struct roff_man *mdoc, int ln, int pos, |
|
isalpha((unsigned char)cp[-3]) : |
isalpha((unsigned char)cp[-3]) : |
np != NULL && |
np != NULL && |
np->type == ROFFT_TEXT && |
np->type == ROFFT_TEXT && |
np->string != '\0' && |
*np->string != '\0' && |
isalpha((unsigned char)np->string[ |
isalpha((unsigned char)np->string[ |
strlen(np->string) - 1])) || |
strlen(np->string) - 1])) || |
(cp[2] != '\0' ? |
(cp[1] != '\0' && cp[2] != '\0' ? |
isalpha((unsigned char)cp[2]) : |
isalpha((unsigned char)cp[2]) : |
nn != NULL && |
nn != NULL && |
nn->type == ROFFT_TEXT && |
nn->type == ROFFT_TEXT && |
nn->string != '\0' && |
|
isalpha((unsigned char)*nn->string))) { |
isalpha((unsigned char)*nn->string))) { |
mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse, |
mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse, |
ln, pos + (int)(cp - p) - 1, NULL); |
ln, pos + (int)(cp - p) - 1, NULL); |
Line 489 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 925 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 1265 post_nm(POST_ARGS) |
|
Line 1288 post_nm(POST_ARGS) |
|
n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL) |
n->child->type == ROFFT_TEXT && 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 1347 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 1620 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 1631 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 1791 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 1910 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 1992 post_root(POST_ARGS) |
|
Line 2012 post_root(POST_ARGS) |
|
while (n != NULL && |
while (n != NULL && |
(n->type == ROFFT_COMMENT || |
(n->type == ROFFT_COMMENT || |
(n->tok >= MDOC_Dd && |
(n->tok >= MDOC_Dd && |
mdoc_macros[n->tok].flags & MDOC_PROLOGUE))) |
mdoc_macro(n->tok)->flags & MDOC_PROLOGUE))) |
n = n->next; |
n = n->next; |
|
|
if (n == NULL) |
if (n == NULL) |
Line 2494 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 2503 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 2524 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 2550 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 |