version 1.297, 2015/10/19 20:04:10 |
version 1.298, 2015/10/20 02:01:32 |
Line 63 static void check_argv(struct roff_man *, |
|
Line 63 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 int child_an(const struct roff_node *); |
static int child_an(const struct roff_node *); |
static enum roff_sec a2sec(const char *); |
|
static size_t macro2len(int); |
static size_t macro2len(int); |
static void rewrite_macro2len(char **); |
static void rewrite_macro2len(char **); |
|
|
Line 111 static void post_st(POST_ARGS); |
|
Line 110 static void post_st(POST_ARGS); |
|
static void pre_an(PRE_ARGS); |
static void pre_an(PRE_ARGS); |
static void pre_bd(PRE_ARGS); |
static void pre_bd(PRE_ARGS); |
static void pre_bl(PRE_ARGS); |
static void pre_bl(PRE_ARGS); |
static void pre_dd(PRE_ARGS); |
|
static void pre_display(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_obsolete(PRE_ARGS); |
static void pre_os(PRE_ARGS); |
|
static void pre_par(PRE_ARGS); |
static void pre_par(PRE_ARGS); |
static void pre_std(PRE_ARGS); |
static void pre_std(PRE_ARGS); |
|
|
static const struct valids mdoc_valids[MDOC_MAX] = { |
static const struct valids mdoc_valids[MDOC_MAX] = { |
{ NULL, NULL }, /* Ap */ |
{ NULL, NULL }, /* Ap */ |
{ pre_dd, post_dd }, /* Dd */ |
{ NULL, post_dd }, /* Dd */ |
{ pre_dt, post_dt }, /* Dt */ |
{ NULL, post_dt }, /* Dt */ |
{ pre_os, post_os }, /* Os */ |
{ NULL, post_os }, /* Os */ |
{ NULL, post_sh }, /* Sh */ |
{ NULL, post_sh }, /* Sh */ |
{ NULL, post_ignpar }, /* Ss */ |
{ NULL, post_ignpar }, /* Ss */ |
{ pre_par, post_par }, /* Pp */ |
{ pre_par, post_par }, /* Pp */ |
{ pre_display, post_d1 }, /* D1 */ |
{ pre_display, post_d1 }, /* D1 */ |
{ pre_literal, post_literal }, /* Dl */ |
{ pre_display, post_literal }, /* Dl */ |
{ pre_bd, post_literal }, /* Bd */ |
{ pre_bd, post_literal }, /* Bd */ |
{ NULL, NULL }, /* Ed */ |
{ NULL, NULL }, /* Ed */ |
{ pre_bl, post_bl }, /* Bl */ |
{ pre_bl, post_bl }, /* Bl */ |
Line 317 mdoc_valid_pre(struct roff_man *mdoc, struct roff_node |
|
Line 312 mdoc_valid_pre(struct roff_man *mdoc, struct roff_node |
|
} |
} |
|
|
void |
void |
mdoc_valid_post(struct roff_man *mdoc) |
mdoc_node_validate(struct roff_man *mdoc) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
v_post p; |
v_post p; |
|
|
n = mdoc->last; |
n = mdoc->last; |
if (n->flags & MDOC_VALID) |
mdoc->last = mdoc->last->child; |
return; |
while (mdoc->last != NULL) { |
n->flags |= MDOC_VALID | MDOC_ENDED; |
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) { |
switch (n->type) { |
case ROFFT_TEXT: |
case ROFFT_TEXT: |
case ROFFT_EQN: |
case ROFFT_EQN: |
Line 353 mdoc_valid_post(struct roff_man *mdoc) |
|
Line 355 mdoc_valid_post(struct roff_man *mdoc) |
|
p = mdoc_valids[n->tok].post; |
p = mdoc_valids[n->tok].post; |
if (*p) |
if (*p) |
(*p)(mdoc); |
(*p)(mdoc); |
|
if (mdoc->last == n) |
|
mdoc_state(mdoc, n); |
break; |
break; |
} |
} |
} |
} |
Line 594 pre_bd(PRE_ARGS) |
|
Line 598 pre_bd(PRE_ARGS) |
|
int i; |
int i; |
enum mdoc_disp dt; |
enum mdoc_disp dt; |
|
|
pre_literal(mdoc, n); |
pre_display(mdoc, n); |
|
|
if (n->type != ROFFT_BLOCK) |
if (n->type != ROFFT_BLOCK) |
return; |
return; |
Line 714 pre_obsolete(PRE_ARGS) |
|
Line 718 pre_obsolete(PRE_ARGS) |
|
} |
} |
|
|
static void |
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) |
post_bf(POST_ARGS) |
{ |
{ |
struct roff_node *np, *nch; |
struct roff_node *np, *nch; |
Line 986 post_literal(POST_ARGS) |
|
Line 948 post_literal(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (n->type != ROFFT_BODY) |
if (n->type != ROFFT_BODY || n->end != ENDBODY_NOT) |
return; |
return; |
|
|
if (n->child == NULL) |
if (n->child == NULL) |
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, |
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, |
n->line, n->pos, mdoc_macronames[n->tok]); |
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 |
static void |
Line 1016 post_defaults(POST_ARGS) |
|
Line 971 post_defaults(POST_ARGS) |
|
return; |
return; |
|
|
nn = mdoc->last; |
nn = mdoc->last; |
mdoc->next = ROFF_NEXT_CHILD; |
|
|
|
switch (nn->tok) { |
switch (nn->tok) { |
case MDOC_Ar: |
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, "file"); |
roff_word_alloc(mdoc, nn->line, nn->pos, "..."); |
roff_word_alloc(mdoc, nn->line, nn->pos, "..."); |
break; |
break; |
case MDOC_Pa: |
case MDOC_Pa: |
case MDOC_Mt: |
case MDOC_Mt: |
|
mdoc->next = ROFF_NEXT_CHILD; |
roff_word_alloc(mdoc, nn->line, nn->pos, "~"); |
roff_word_alloc(mdoc, nn->line, nn->pos, "~"); |
break; |
break; |
default: |
default: |
Line 1384 post_bl(POST_ARGS) |
|
Line 1340 post_bl(POST_ARGS) |
|
default: |
default: |
return; |
return; |
} |
} |
|
if (nbody->end != ENDBODY_NOT) |
|
return; |
|
|
nchild = nbody->child; |
nchild = nbody->child; |
if (nchild == NULL) { |
if (nchild == NULL) { |
Line 1828 post_sh_authors(POST_ARGS) |
|
Line 1786 post_sh_authors(POST_ARGS) |
|
static void |
static void |
post_sh_head(POST_ARGS) |
post_sh_head(POST_ARGS) |
{ |
{ |
struct roff_node *n; |
|
const char *goodsec; |
const char *goodsec; |
char *secname; |
|
enum roff_sec sec; |
enum roff_sec sec; |
|
|
/* |
/* |
Line 1840 post_sh_head(POST_ARGS) |
|
Line 1796 post_sh_head(POST_ARGS) |
|
* manual sections. |
* manual sections. |
*/ |
*/ |
|
|
secname = NULL; |
sec = mdoc->last->sec; |
deroff(&secname, mdoc->last); |
|
sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); |
|
|
|
/* The NAME should be first. */ |
/* The NAME should be first. */ |
|
|
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) |
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) |
mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, |
mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"Sh %s", secname); |
"Sh %s", secnames[sec]); |
|
|
/* The SYNOPSIS gets special attention in other areas. */ |
/* The SYNOPSIS gets special attention in other areas. */ |
|
|
if (SEC_SYNOPSIS == sec) { |
if (sec == SEC_SYNOPSIS) { |
roff_setreg(mdoc->roff, "nS", 1, '='); |
roff_setreg(mdoc->roff, "nS", 1, '='); |
mdoc->flags |= MDOC_SYNOPSIS; |
mdoc->flags |= MDOC_SYNOPSIS; |
} else { |
} else { |
Line 1865 post_sh_head(POST_ARGS) |
|
Line 1819 post_sh_head(POST_ARGS) |
|
|
|
mdoc->lastsec = sec; |
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 != NULL; n = n->next) |
|
n->sec = sec; |
|
|
|
/* We don't care about custom sections after this. */ |
/* We don't care about custom sections after this. */ |
|
|
if (SEC_CUSTOM == sec) { |
if (sec == SEC_CUSTOM) |
free(secname); |
|
return; |
return; |
} |
|
|
|
/* |
/* |
* Check whether our non-custom section is being repeated or is |
* Check whether our non-custom section is being repeated or is |
Line 1894 post_sh_head(POST_ARGS) |
|
Line 1832 post_sh_head(POST_ARGS) |
|
if (sec == mdoc->lastnamed) |
if (sec == mdoc->lastnamed) |
mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, |
mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"Sh %s", secname); |
"Sh %s", secnames[sec]); |
|
|
if (sec < mdoc->lastnamed) |
if (sec < mdoc->lastnamed) |
mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, |
mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"Sh %s", secname); |
"Sh %s", secnames[sec]); |
|
|
/* Mark the last named section. */ |
/* Mark the last named section. */ |
|
|
Line 1907 post_sh_head(POST_ARGS) |
|
Line 1845 post_sh_head(POST_ARGS) |
|
|
|
/* Check particular section/manual conventions. */ |
/* Check particular section/manual conventions. */ |
|
|
if (mdoc->meta.msec == NULL) { |
if (mdoc->meta.msec == NULL) |
free(secname); |
|
return; |
return; |
} |
|
|
|
goodsec = NULL; |
goodsec = NULL; |
switch (sec) { |
switch (sec) { |
Line 1935 post_sh_head(POST_ARGS) |
|
Line 1871 post_sh_head(POST_ARGS) |
|
goodsec = "9"; |
goodsec = "9"; |
mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, |
mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"Sh %s for %s only", secname, goodsec); |
"Sh %s for %s only", secnames[sec], goodsec); |
break; |
break; |
default: |
default: |
break; |
break; |
} |
} |
free(secname); |
|
} |
} |
|
|
static void |
static void |
Line 2043 post_par(POST_ARGS) |
|
Line 1978 post_par(POST_ARGS) |
|
} |
} |
|
|
static void |
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(); |
|
} |
|
} |
|
|
|
static void |
|
post_dd(POST_ARGS) |
post_dd(POST_ARGS) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
char *datestr; |
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); |
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 (n->child == NULL || n->child->string[0] == '\0') { |
if (n->child == NULL || n->child->string[0] == '\0') { |
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : |
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : |
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); |
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); |
Line 2108 post_dt(POST_ARGS) |
|
Line 2025 post_dt(POST_ARGS) |
|
char *p; |
char *p; |
|
|
n = mdoc->last; |
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.title); |
free(mdoc->meta.msec); |
free(mdoc->meta.msec); |
free(mdoc->meta.vol); |
free(mdoc->meta.vol); |
Line 2210 post_os(POST_ARGS) |
|
Line 2139 post_os(POST_ARGS) |
|
struct roff_node *n; |
struct roff_node *n; |
|
|
n = mdoc->last; |
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. |
* Set the operating system by way of the `Os' macro. |
Line 2275 post_ex(POST_ARGS) |
|
Line 2210 post_ex(POST_ARGS) |
|
mdoc->last = n; |
mdoc->last = n; |
} |
} |
|
|
static enum roff_sec |
enum roff_sec |
a2sec(const char *p) |
mdoc_a2sec(const char *p) |
{ |
{ |
int i; |
int i; |
|
|