version 1.305, 2016/08/10 20:17:50 |
version 1.311, 2017/01/08 00:11:24 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2017 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 67 static void post_bf(POST_ARGS); |
|
Line 67 static void post_bf(POST_ARGS); |
|
static void post_bk(POST_ARGS); |
static void post_bk(POST_ARGS); |
static void post_bl(POST_ARGS); |
static void post_bl(POST_ARGS); |
static void post_bl_block(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_head(POST_ARGS); |
static void post_bl_norm(POST_ARGS); |
static void post_bl_norm(POST_ARGS); |
static void post_bx(POST_ARGS); |
static void post_bx(POST_ARGS); |
Line 104 static void post_sh_authors(POST_ARGS); |
|
Line 103 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_xr(POST_ARGS); |
|
|
static v_post mdoc_valids[MDOC_MAX] = { |
static v_post mdoc_valids[MDOC_MAX] = { |
NULL, /* Ap */ |
NULL, /* Ap */ |
Line 146 static v_post mdoc_valids[MDOC_MAX] = { |
|
Line 146 static v_post mdoc_valids[MDOC_MAX] = { |
|
post_st, /* St */ |
post_st, /* St */ |
NULL, /* Va */ |
NULL, /* Va */ |
NULL, /* Vt */ |
NULL, /* Vt */ |
NULL, /* 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. */ |
NULL, /* %D */ |
NULL, /* %D */ |
Line 851 post_nm(POST_ARGS) |
|
Line 851 post_nm(POST_ARGS) |
|
n->last->tok == MDOC_Lp)) |
n->last->tok == MDOC_Lp)) |
mdoc_node_relink(mdoc, n->last); |
mdoc_node_relink(mdoc, n->last); |
|
|
if (mdoc->meta.name != NULL) |
|
return; |
|
|
|
deroff(&mdoc->meta.name, n); |
|
|
|
if (mdoc->meta.name == NULL) |
if (mdoc->meta.name == NULL) |
|
deroff(&mdoc->meta.name, n); |
|
|
|
if (mdoc->meta.name == NULL || |
|
(mdoc->lastsec == SEC_NAME && n->child == NULL)) |
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, |
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, |
n->line, n->pos, "Nm"); |
n->line, n->pos, "Nm"); |
} |
} |
Line 886 post_display(POST_ARGS) |
|
Line 885 post_display(POST_ARGS) |
|
n = mdoc->last; |
n = mdoc->last; |
switch (n->type) { |
switch (n->type) { |
case ROFFT_BODY: |
case ROFFT_BODY: |
if (n->end != ENDBODY_NOT) |
if (n->end != ENDBODY_NOT) { |
break; |
if (n->tok == MDOC_Bd && |
if (n->child == NULL) |
n->body->parent->args == NULL) |
|
roff_node_delete(mdoc, n); |
|
} else 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]); |
else if (n->tok == MDOC_D1) |
else if (n->tok == MDOC_D1) |
Line 1097 post_bl_block(POST_ARGS) |
|
Line 1098 post_bl_block(POST_ARGS) |
|
|
|
post_prevpar(mdoc); |
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 |
|
* specified, but no -width (it must be guessed). The second |
|
* when a -width is specified (macro indicators must be |
|
* rewritten into real lengths). |
|
*/ |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (n->norm->Bl.type == LIST_tag && |
|
n->norm->Bl.width == NULL) { |
|
post_bl_block_tag(mdoc); |
|
assert(n->norm->Bl.width != NULL); |
|
} |
|
|
|
for (ni = n->body->child; ni != NULL; ni = ni->next) { |
for (ni = n->body->child; ni != NULL; ni = ni->next) { |
if (ni->body == NULL) |
if (ni->body == NULL) |
continue; |
continue; |
Line 1170 rewrite_macro2len(char **arg) |
|
Line 1156 rewrite_macro2len(char **arg) |
|
} |
} |
|
|
static void |
static void |
post_bl_block_tag(POST_ARGS) |
|
{ |
|
struct roff_node *n, *nn; |
|
size_t sz, ssz; |
|
int i; |
|
char buf[24]; |
|
|
|
/* |
|
* Calculate the -width for a `Bl -tag' list if it hasn't been |
|
* provided. Uses the first head macro. NOTE AGAIN: this is |
|
* ONLY if the -width argument has NOT been provided. See |
|
* rewrite_macro2len() for converting the -width string. |
|
*/ |
|
|
|
sz = 10; |
|
n = mdoc->last; |
|
|
|
for (nn = n->body->child; nn != NULL; nn = nn->next) { |
|
if (nn->tok != MDOC_It) |
|
continue; |
|
|
|
assert(nn->type == ROFFT_BLOCK); |
|
nn = nn->head->child; |
|
|
|
if (nn == NULL) |
|
break; |
|
|
|
if (nn->type == ROFFT_TEXT) { |
|
sz = strlen(nn->string) + 1; |
|
break; |
|
} |
|
|
|
if (0 != (ssz = macro2len(nn->tok))) |
|
sz = ssz; |
|
|
|
break; |
|
} |
|
|
|
/* Defaults to ten ens. */ |
|
|
|
(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz); |
|
|
|
/* |
|
* We have to dynamically add this to the macro's argument list. |
|
* We're guaranteed that a MDOC_Width doesn't already exist. |
|
*/ |
|
|
|
assert(n->args != NULL); |
|
i = (int)(n->args->argc)++; |
|
|
|
n->args->argv = mandoc_reallocarray(n->args->argv, |
|
n->args->argc, sizeof(struct mdoc_argv)); |
|
|
|
n->args->argv[i].arg = MDOC_Width; |
|
n->args->argv[i].line = n->line; |
|
n->args->argv[i].pos = n->pos; |
|
n->args->argv[i].sz = 1; |
|
n->args->argv[i].value = mandoc_malloc(sizeof(char *)); |
|
n->args->argv[i].value[0] = mandoc_strdup(buf); |
|
|
|
/* Set our width! */ |
|
n->norm->Bl.width = n->args->argv[i].value[0]; |
|
} |
|
|
|
static void |
|
post_bl_head(POST_ARGS) |
post_bl_head(POST_ARGS) |
{ |
{ |
struct roff_node *nbl, *nh, *nch, *nnext; |
struct roff_node *nbl, *nh, *nch, *nnext; |
Line 1327 post_bl(POST_ARGS) |
|
Line 1248 post_bl(POST_ARGS) |
|
return; |
return; |
} |
} |
while (nchild != NULL) { |
while (nchild != NULL) { |
|
nnext = nchild->next; |
if (nchild->tok == MDOC_It || |
if (nchild->tok == MDOC_It || |
(nchild->tok == MDOC_Sm && |
(nchild->tok == MDOC_Sm && |
nchild->next != NULL && |
nnext != NULL && nnext->tok == MDOC_It)) { |
nchild->next->tok == MDOC_It)) { |
nchild = nnext; |
nchild = nchild->next; |
|
continue; |
continue; |
} |
} |
|
|
|
/* |
|
* In .Bl -column, the first rows may be implicit, |
|
* that is, they may not start with .It macros. |
|
* Such rows may be followed by nodes generated on the |
|
* roff level, for example .TS, which cannot be moved |
|
* out of the list. In that case, wrap such roff nodes |
|
* into an implicit row. |
|
*/ |
|
|
|
if (nchild->prev != NULL) { |
|
mdoc->last = nchild; |
|
mdoc->next = ROFF_NEXT_SIBLING; |
|
roff_block_alloc(mdoc, nchild->line, |
|
nchild->pos, MDOC_It); |
|
roff_head_alloc(mdoc, nchild->line, |
|
nchild->pos, MDOC_It); |
|
mdoc->next = ROFF_NEXT_SIBLING; |
|
roff_body_alloc(mdoc, nchild->line, |
|
nchild->pos, MDOC_It); |
|
while (nchild->tok != MDOC_It) { |
|
mdoc_node_relink(mdoc, nchild); |
|
if ((nchild = nnext) == NULL) |
|
break; |
|
nnext = nchild->next; |
|
mdoc->next = ROFF_NEXT_SIBLING; |
|
} |
|
mdoc->last = nbody; |
|
continue; |
|
} |
|
|
mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse, |
mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse, |
nchild->line, nchild->pos, |
nchild->line, nchild->pos, |
mdoc_macronames[nchild->tok]); |
mdoc_macronames[nchild->tok]); |
Line 1347 post_bl(POST_ARGS) |
|
Line 1298 post_bl(POST_ARGS) |
|
nblock = nbody->parent; |
nblock = nbody->parent; |
nprev = nblock->prev; |
nprev = nblock->prev; |
nparent = nblock->parent; |
nparent = nblock->parent; |
nnext = nchild->next; |
|
|
|
/* |
/* |
* Unlink this child. |
* Unlink this child. |
*/ |
*/ |
|
|
assert(nchild->prev == NULL); |
|
nbody->child = nnext; |
nbody->child = nnext; |
if (nnext == NULL) |
if (nnext == NULL) |
nbody->last = NULL; |
nbody->last = NULL; |
Line 1648 post_sh_name(POST_ARGS) |
|
Line 1597 post_sh_name(POST_ARGS) |
|
for (n = mdoc->last->child; n != NULL; n = n->next) { |
for (n = mdoc->last->child; n != NULL; n = n->next) { |
switch (n->tok) { |
switch (n->tok) { |
case MDOC_Nm: |
case MDOC_Nm: |
|
if (hasnm && n->child != NULL) |
|
mandoc_vmsg(MANDOCERR_NAMESEC_PUNCT, |
|
mdoc->parse, n->line, n->pos, |
|
"Nm %s", n->child->string); |
hasnm = 1; |
hasnm = 1; |
break; |
continue; |
case MDOC_Nd: |
case MDOC_Nd: |
hasnd = 1; |
hasnd = 1; |
if (n->next != NULL) |
if (n->next != NULL) |
Line 1657 post_sh_name(POST_ARGS) |
|
Line 1610 post_sh_name(POST_ARGS) |
|
mdoc->parse, n->line, n->pos, NULL); |
mdoc->parse, n->line, n->pos, NULL); |
break; |
break; |
case TOKEN_NONE: |
case TOKEN_NONE: |
if (hasnm) |
if (n->type == ROFFT_TEXT && |
break; |
n->string[0] == ',' && n->string[1] == '\0' && |
|
n->next != NULL && n->next->tok == MDOC_Nm) { |
|
n = n->next; |
|
continue; |
|
} |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
default: |
default: |
mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, |
mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, |
n->line, n->pos, mdoc_macronames[n->tok]); |
n->line, n->pos, mdoc_macronames[n->tok]); |
break; |
continue; |
} |
} |
|
break; |
} |
} |
|
|
if ( ! hasnm) |
if ( ! hasnm) |
Line 1858 post_sh_head(POST_ARGS) |
|
Line 1816 post_sh_head(POST_ARGS) |
|
} |
} |
|
|
static void |
static void |
|
post_xr(POST_ARGS) |
|
{ |
|
struct roff_node *n, *nch; |
|
|
|
n = mdoc->last; |
|
nch = n->child; |
|
if (nch->next == NULL) { |
|
mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse, |
|
n->line, n->pos, "Xr %s", nch->string); |
|
return; |
|
} |
|
assert(nch->next == n->last); |
|
} |
|
|
|
static void |
post_ignpar(POST_ARGS) |
post_ignpar(POST_ARGS) |
{ |
{ |
struct roff_node *np; |
struct roff_node *np; |
Line 2053 post_dt(POST_ARGS) |
|
Line 2026 post_dt(POST_ARGS) |
|
} |
} |
} |
} |
|
|
/* Mandatory second argument: section. */ |
/* Mandatory second argument: section. */ |
|
|
if (nn != NULL) |
if (nn != NULL) |
nn = nn->next; |
nn = nn->next; |