version 1.284, 2015/04/02 21:36:50 |
version 1.305, 2016/08/10 20:17:50 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2016 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 |
|
|
#include "roff.h" |
#include "roff.h" |
#include "mdoc.h" |
#include "mdoc.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
|
#include "roff_int.h" |
#include "libmdoc.h" |
#include "libmdoc.h" |
|
|
/* FIXME: .Bl -diag can't have non-text children in HEAD. */ |
/* FIXME: .Bl -diag can't have non-text children in HEAD. */ |
|
|
#define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n |
#define POST_ARGS struct roff_man *mdoc |
#define POST_ARGS struct mdoc *mdoc |
|
|
|
enum check_ineq { |
enum check_ineq { |
CHECK_LT, |
CHECK_LT, |
Line 49 enum check_ineq { |
|
Line 49 enum check_ineq { |
|
CHECK_EQ |
CHECK_EQ |
}; |
}; |
|
|
typedef void (*v_pre)(PRE_ARGS); |
|
typedef void (*v_post)(POST_ARGS); |
typedef void (*v_post)(POST_ARGS); |
|
|
struct valids { |
static void check_text(struct roff_man *, int, int, char *); |
v_pre pre; |
static void check_argv(struct roff_man *, |
v_post post; |
struct roff_node *, struct mdoc_argv *); |
}; |
static void check_args(struct roff_man *, struct roff_node *); |
|
static int child_an(const struct roff_node *); |
static void check_text(struct mdoc *, int, int, char *); |
static size_t macro2len(int); |
static void check_argv(struct mdoc *, |
|
struct mdoc_node *, struct mdoc_argv *); |
|
static void check_args(struct mdoc *, struct mdoc_node *); |
|
static int child_an(const struct mdoc_node *); |
|
static enum mdoc_sec a2sec(const char *); |
|
static size_t macro2len(enum mdoct); |
|
static void rewrite_macro2len(char **); |
static void rewrite_macro2len(char **); |
|
|
static void post_an(POST_ARGS); |
static void post_an(POST_ARGS); |
|
static void post_an_norm(POST_ARGS); |
static void post_at(POST_ARGS); |
static void post_at(POST_ARGS); |
|
static void post_bd(POST_ARGS); |
static void post_bf(POST_ARGS); |
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_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_bx(POST_ARGS); |
static void post_bx(POST_ARGS); |
static void post_d1(POST_ARGS); |
|
static void post_defaults(POST_ARGS); |
static void post_defaults(POST_ARGS); |
|
static void post_display(POST_ARGS); |
static void post_dd(POST_ARGS); |
static void post_dd(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); |
Line 91 static void post_hyph(POST_ARGS); |
|
Line 87 static void post_hyph(POST_ARGS); |
|
static void post_ignpar(POST_ARGS); |
static void post_ignpar(POST_ARGS); |
static void post_it(POST_ARGS); |
static void post_it(POST_ARGS); |
static void post_lb(POST_ARGS); |
static void post_lb(POST_ARGS); |
static void post_literal(POST_ARGS); |
|
static void post_nd(POST_ARGS); |
static void post_nd(POST_ARGS); |
static void post_nm(POST_ARGS); |
static void post_nm(POST_ARGS); |
static void post_ns(POST_ARGS); |
static void post_ns(POST_ARGS); |
|
static void post_obsolete(POST_ARGS); |
static void post_os(POST_ARGS); |
static void post_os(POST_ARGS); |
static void post_par(POST_ARGS); |
static void post_par(POST_ARGS); |
|
static void post_prevpar(POST_ARGS); |
static void post_root(POST_ARGS); |
static void post_root(POST_ARGS); |
static void post_rs(POST_ARGS); |
static void post_rs(POST_ARGS); |
static void post_sh(POST_ARGS); |
static void post_sh(POST_ARGS); |
Line 106 static void post_sh_see_also(POST_ARGS); |
|
Line 103 static void post_sh_see_also(POST_ARGS); |
|
static void post_sh_authors(POST_ARGS); |
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_vt(POST_ARGS); |
static void post_std(POST_ARGS); |
|
|
static void pre_an(PRE_ARGS); |
static v_post mdoc_valids[MDOC_MAX] = { |
static void pre_bd(PRE_ARGS); |
NULL, /* Ap */ |
static void pre_bl(PRE_ARGS); |
post_dd, /* Dd */ |
static void pre_dd(PRE_ARGS); |
post_dt, /* Dt */ |
static void pre_display(PRE_ARGS); |
post_os, /* Os */ |
static void pre_dt(PRE_ARGS); |
post_sh, /* Sh */ |
static void pre_literal(PRE_ARGS); |
post_ignpar, /* Ss */ |
static void pre_obsolete(PRE_ARGS); |
post_par, /* Pp */ |
static void pre_os(PRE_ARGS); |
post_display, /* D1 */ |
static void pre_par(PRE_ARGS); |
post_display, /* Dl */ |
static void pre_std(PRE_ARGS); |
post_display, /* Bd */ |
|
NULL, /* Ed */ |
static const struct valids mdoc_valids[MDOC_MAX] = { |
post_bl, /* Bl */ |
{ NULL, NULL }, /* Ap */ |
NULL, /* El */ |
{ pre_dd, post_dd }, /* Dd */ |
post_it, /* It */ |
{ pre_dt, post_dt }, /* Dt */ |
NULL, /* Ad */ |
{ pre_os, post_os }, /* Os */ |
post_an, /* An */ |
{ NULL, post_sh }, /* Sh */ |
post_defaults, /* Ar */ |
{ NULL, post_ignpar }, /* Ss */ |
NULL, /* Cd */ |
{ pre_par, post_par }, /* Pp */ |
NULL, /* Cm */ |
{ pre_display, post_d1 }, /* D1 */ |
NULL, /* Dv */ |
{ pre_literal, post_literal }, /* Dl */ |
NULL, /* Er */ |
{ pre_bd, post_literal }, /* Bd */ |
NULL, /* Ev */ |
{ NULL, NULL }, /* Ed */ |
post_ex, /* Ex */ |
{ pre_bl, post_bl }, /* Bl */ |
post_fa, /* Fa */ |
{ NULL, NULL }, /* El */ |
NULL, /* Fd */ |
{ pre_par, post_it }, /* It */ |
NULL, /* Fl */ |
{ NULL, NULL }, /* Ad */ |
post_fn, /* Fn */ |
{ pre_an, post_an }, /* An */ |
NULL, /* Ft */ |
{ NULL, post_defaults }, /* Ar */ |
NULL, /* Ic */ |
{ NULL, NULL }, /* Cd */ |
NULL, /* In */ |
{ NULL, NULL }, /* Cm */ |
post_defaults, /* Li */ |
{ NULL, NULL }, /* Dv */ |
post_nd, /* Nd */ |
{ NULL, NULL }, /* Er */ |
post_nm, /* Nm */ |
{ NULL, NULL }, /* Ev */ |
NULL, /* Op */ |
{ pre_std, post_ex }, /* Ex */ |
post_obsolete, /* Ot */ |
{ NULL, post_fa }, /* Fa */ |
post_defaults, /* Pa */ |
{ NULL, NULL }, /* Fd */ |
post_std, /* Rv */ |
{ NULL, NULL }, /* Fl */ |
post_st, /* St */ |
{ NULL, post_fn }, /* Fn */ |
NULL, /* Va */ |
{ NULL, NULL }, /* Ft */ |
NULL, /* Vt */ |
{ NULL, NULL }, /* Ic */ |
NULL, /* Xr */ |
{ NULL, NULL }, /* In */ |
NULL, /* %A */ |
{ NULL, post_defaults }, /* Li */ |
post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, post_nd }, /* Nd */ |
NULL, /* %D */ |
{ NULL, post_nm }, /* Nm */ |
NULL, /* %I */ |
{ NULL, NULL }, /* Op */ |
NULL, /* %J */ |
{ pre_obsolete, NULL }, /* Ot */ |
post_hyph, /* %N */ |
{ NULL, post_defaults }, /* Pa */ |
post_hyph, /* %O */ |
{ pre_std, NULL }, /* Rv */ |
NULL, /* %P */ |
{ NULL, post_st }, /* St */ |
post_hyph, /* %R */ |
{ NULL, NULL }, /* Va */ |
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, post_vt }, /* Vt */ |
NULL, /* %V */ |
{ NULL, NULL }, /* Xr */ |
NULL, /* Ac */ |
{ NULL, NULL }, /* %A */ |
NULL, /* Ao */ |
{ NULL, post_hyph }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
NULL, /* Aq */ |
{ NULL, NULL }, /* %D */ |
post_at, /* At */ |
{ NULL, NULL }, /* %I */ |
NULL, /* Bc */ |
{ NULL, NULL }, /* %J */ |
post_bf, /* Bf */ |
{ NULL, post_hyph }, /* %N */ |
NULL, /* Bo */ |
{ NULL, post_hyph }, /* %O */ |
NULL, /* Bq */ |
{ NULL, NULL }, /* %P */ |
NULL, /* Bsx */ |
{ NULL, post_hyph }, /* %R */ |
post_bx, /* Bx */ |
{ NULL, post_hyph }, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
post_obsolete, /* Db */ |
{ NULL, NULL }, /* %V */ |
NULL, /* Dc */ |
{ NULL, NULL }, /* Ac */ |
NULL, /* Do */ |
{ NULL, NULL }, /* Ao */ |
NULL, /* Dq */ |
{ NULL, NULL }, /* Aq */ |
NULL, /* Ec */ |
{ NULL, post_at }, /* At */ |
NULL, /* Ef */ |
{ NULL, NULL }, /* Bc */ |
NULL, /* Em */ |
{ NULL, post_bf }, /* Bf */ |
NULL, /* Eo */ |
{ NULL, NULL }, /* Bo */ |
NULL, /* Fx */ |
{ NULL, NULL }, /* Bq */ |
NULL, /* Ms */ |
{ NULL, NULL }, /* Bsx */ |
NULL, /* No */ |
{ NULL, post_bx }, /* Bx */ |
post_ns, /* Ns */ |
{ pre_obsolete, NULL }, /* Db */ |
NULL, /* Nx */ |
{ NULL, NULL }, /* Dc */ |
NULL, /* Ox */ |
{ NULL, NULL }, /* Do */ |
NULL, /* Pc */ |
{ NULL, NULL }, /* Dq */ |
NULL, /* Pf */ |
{ NULL, NULL }, /* Ec */ |
NULL, /* Po */ |
{ NULL, NULL }, /* Ef */ |
NULL, /* Pq */ |
{ NULL, NULL }, /* Em */ |
NULL, /* Qc */ |
{ NULL, NULL }, /* Eo */ |
NULL, /* Ql */ |
{ NULL, NULL }, /* Fx */ |
NULL, /* Qo */ |
{ NULL, NULL }, /* Ms */ |
NULL, /* Qq */ |
{ NULL, NULL }, /* No */ |
NULL, /* Re */ |
{ NULL, post_ns }, /* Ns */ |
post_rs, /* Rs */ |
{ NULL, NULL }, /* Nx */ |
NULL, /* Sc */ |
{ NULL, NULL }, /* Ox */ |
NULL, /* So */ |
{ NULL, NULL }, /* Pc */ |
NULL, /* Sq */ |
{ NULL, NULL }, /* Pf */ |
post_sm, /* Sm */ |
{ NULL, NULL }, /* Po */ |
post_hyph, /* Sx */ |
{ NULL, NULL }, /* Pq */ |
NULL, /* Sy */ |
{ NULL, NULL }, /* Qc */ |
NULL, /* Tn */ |
{ NULL, NULL }, /* Ql */ |
NULL, /* Ux */ |
{ NULL, NULL }, /* Qo */ |
NULL, /* Xc */ |
{ NULL, NULL }, /* Qq */ |
NULL, /* Xo */ |
{ NULL, NULL }, /* Re */ |
post_fo, /* Fo */ |
{ NULL, post_rs }, /* Rs */ |
NULL, /* Fc */ |
{ NULL, NULL }, /* Sc */ |
NULL, /* Oo */ |
{ NULL, NULL }, /* So */ |
NULL, /* Oc */ |
{ NULL, NULL }, /* Sq */ |
post_bk, /* Bk */ |
{ NULL, post_sm }, /* Sm */ |
NULL, /* Ek */ |
{ NULL, post_hyph }, /* Sx */ |
post_eoln, /* Bt */ |
{ NULL, NULL }, /* Sy */ |
NULL, /* Hf */ |
{ NULL, NULL }, /* Tn */ |
post_obsolete, /* Fr */ |
{ NULL, NULL }, /* Ux */ |
post_eoln, /* Ud */ |
{ NULL, NULL }, /* Xc */ |
post_lb, /* Lb */ |
{ NULL, NULL }, /* Xo */ |
post_par, /* Lp */ |
{ NULL, post_fo }, /* Fo */ |
NULL, /* Lk */ |
{ NULL, NULL }, /* Fc */ |
post_defaults, /* Mt */ |
{ NULL, NULL }, /* Oo */ |
NULL, /* Brq */ |
{ NULL, NULL }, /* Oc */ |
NULL, /* Bro */ |
{ NULL, post_bk }, /* Bk */ |
NULL, /* Brc */ |
{ NULL, NULL }, /* Ek */ |
NULL, /* %C */ |
{ NULL, post_eoln }, /* Bt */ |
post_es, /* Es */ |
{ NULL, NULL }, /* Hf */ |
post_en, /* En */ |
{ pre_obsolete, NULL }, /* Fr */ |
NULL, /* Dx */ |
{ NULL, post_eoln }, /* Ud */ |
NULL, /* %Q */ |
{ NULL, post_lb }, /* Lb */ |
post_par, /* br */ |
{ pre_par, post_par }, /* Lp */ |
post_par, /* sp */ |
{ NULL, NULL }, /* Lk */ |
NULL, /* %U */ |
{ NULL, post_defaults }, /* Mt */ |
NULL, /* Ta */ |
{ NULL, NULL }, /* Brq */ |
NULL, /* ll */ |
{ NULL, NULL }, /* Bro */ |
|
{ NULL, NULL }, /* Brc */ |
|
{ NULL, NULL }, /* %C */ |
|
{ pre_obsolete, post_es }, /* Es */ |
|
{ pre_obsolete, post_en }, /* En */ |
|
{ NULL, NULL }, /* Dx */ |
|
{ NULL, NULL }, /* %Q */ |
|
{ NULL, post_par }, /* br */ |
|
{ NULL, post_par }, /* sp */ |
|
{ NULL, NULL }, /* %U */ |
|
{ NULL, NULL }, /* Ta */ |
|
{ NULL, NULL }, /* ll */ |
|
}; |
}; |
|
|
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
|
|
static const enum mdoct rsord[RSORD_MAX] = { |
static const int rsord[RSORD_MAX] = { |
MDOC__A, |
MDOC__A, |
MDOC__T, |
MDOC__T, |
MDOC__B, |
MDOC__B, |
Line 293 static const char * const secnames[SEC__MAX] = { |
|
Line 278 static const char * const secnames[SEC__MAX] = { |
|
|
|
|
|
void |
void |
mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
mdoc_node_validate(struct roff_man *mdoc) |
{ |
{ |
v_pre p; |
struct roff_node *n; |
|
v_post *p; |
|
|
|
n = mdoc->last; |
|
mdoc->last = mdoc->last->child; |
|
while (mdoc->last != NULL) { |
|
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: |
if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) |
if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) |
check_text(mdoc, n->line, n->pos, n->string); |
check_text(mdoc, n->line, n->pos, n->string); |
/* FALLTHROUGH */ |
|
case ROFFT_TBL: |
|
/* FALLTHROUGH */ |
|
case ROFFT_EQN: |
|
/* FALLTHROUGH */ |
|
case ROFFT_ROOT: |
|
return; |
|
default: |
|
break; |
break; |
} |
|
|
|
check_args(mdoc, n); |
|
p = mdoc_valids[n->tok].pre; |
|
if (*p) |
|
(*p)(mdoc, n); |
|
} |
|
|
|
void |
|
mdoc_valid_post(struct mdoc *mdoc) |
|
{ |
|
struct mdoc_node *n; |
|
v_post p; |
|
|
|
n = mdoc->last; |
|
if (n->flags & MDOC_VALID) |
|
return; |
|
n->flags |= MDOC_VALID | MDOC_ENDED; |
|
|
|
switch (n->type) { |
|
case ROFFT_TEXT: |
|
/* FALLTHROUGH */ |
|
case ROFFT_EQN: |
case ROFFT_EQN: |
/* FALLTHROUGH */ |
|
case ROFFT_TBL: |
case ROFFT_TBL: |
break; |
break; |
case ROFFT_ROOT: |
case ROFFT_ROOT: |
post_root(mdoc); |
post_root(mdoc); |
break; |
break; |
default: |
default: |
|
check_args(mdoc, mdoc->last); |
|
|
/* |
/* |
* Closing delimiters are not special at the |
* Closing delimiters are not special at the |
Line 354 mdoc_valid_post(struct mdoc *mdoc) |
|
Line 322 mdoc_valid_post(struct mdoc *mdoc) |
|
|
|
/* Call the macro's postprocessor. */ |
/* Call the macro's postprocessor. */ |
|
|
p = mdoc_valids[n->tok].post; |
p = mdoc_valids + n->tok; |
if (*p) |
if (*p) |
(*p)(mdoc); |
(*p)(mdoc); |
|
if (mdoc->last == n) |
|
mdoc_state(mdoc, n); |
break; |
break; |
} |
} |
} |
} |
|
|
static void |
static void |
check_args(struct mdoc *mdoc, struct mdoc_node *n) |
check_args(struct roff_man *mdoc, struct roff_node *n) |
{ |
{ |
int i; |
int i; |
|
|
Line 375 check_args(struct mdoc *mdoc, struct mdoc_node *n) |
|
Line 345 check_args(struct mdoc *mdoc, struct mdoc_node *n) |
|
} |
} |
|
|
static void |
static void |
check_argv(struct mdoc *mdoc, struct mdoc_node *n, struct mdoc_argv *v) |
check_argv(struct roff_man *mdoc, struct roff_node *n, struct mdoc_argv *v) |
{ |
{ |
int i; |
int i; |
|
|
Line 384 check_argv(struct mdoc *mdoc, struct mdoc_node *n, str |
|
Line 354 check_argv(struct mdoc *mdoc, struct mdoc_node *n, str |
|
} |
} |
|
|
static void |
static void |
check_text(struct mdoc *mdoc, int ln, int pos, char *p) |
check_text(struct roff_man *mdoc, int ln, int pos, char *p) |
{ |
{ |
char *cp; |
char *cp; |
|
|
Line 397 check_text(struct mdoc *mdoc, int ln, int pos, char *p |
|
Line 367 check_text(struct mdoc *mdoc, int ln, int pos, char *p |
|
} |
} |
|
|
static void |
static void |
pre_display(PRE_ARGS) |
post_bl_norm(POST_ARGS) |
{ |
{ |
struct mdoc_node *node; |
struct roff_node *n; |
|
|
if (n->type != ROFFT_BLOCK) |
|
return; |
|
|
|
for (node = mdoc->last->parent; node; node = node->parent) |
|
if (node->type == ROFFT_BLOCK) |
|
if (MDOC_Bd == node->tok) |
|
break; |
|
|
|
if (node) |
|
mandoc_vmsg(MANDOCERR_BD_NEST, |
|
mdoc->parse, n->line, n->pos, |
|
"%s in Bd", mdoc_macronames[n->tok]); |
|
} |
|
|
|
static void |
|
pre_bl(PRE_ARGS) |
|
{ |
|
struct mdoc_argv *argv, *wa; |
struct mdoc_argv *argv, *wa; |
int i; |
int i; |
enum mdocargt mdoclt; |
enum mdocargt mdoclt; |
enum mdoc_list lt; |
enum mdoc_list lt; |
|
|
if (n->type != ROFFT_BLOCK) |
n = mdoc->last->parent; |
return; |
n->norm->Bl.type = LIST__NONE; |
|
|
/* |
/* |
* First figure out which kind of list to use: bind ourselves to |
* First figure out which kind of list to use: bind ourselves to |
Line 550 pre_bl(PRE_ARGS) |
|
Line 502 pre_bl(PRE_ARGS) |
|
mandoc_msg(MANDOCERR_BL_NOTYPE, mdoc->parse, |
mandoc_msg(MANDOCERR_BL_NOTYPE, mdoc->parse, |
n->line, n->pos, "Bl"); |
n->line, n->pos, "Bl"); |
n->norm->Bl.type = LIST_item; |
n->norm->Bl.type = LIST_item; |
|
mdoclt = MDOC_Item; |
} |
} |
|
|
/* |
/* |
Line 566 pre_bl(PRE_ARGS) |
|
Line 519 pre_bl(PRE_ARGS) |
|
n->line, n->pos, "Bl -tag"); |
n->line, n->pos, "Bl -tag"); |
break; |
break; |
case LIST_column: |
case LIST_column: |
/* FALLTHROUGH */ |
|
case LIST_diag: |
case LIST_diag: |
/* FALLTHROUGH */ |
|
case LIST_ohang: |
case LIST_ohang: |
/* FALLTHROUGH */ |
|
case LIST_inset: |
case LIST_inset: |
/* FALLTHROUGH */ |
|
case LIST_item: |
case LIST_item: |
if (n->norm->Bl.width) |
if (n->norm->Bl.width) |
mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, |
mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, |
Line 580 pre_bl(PRE_ARGS) |
|
Line 529 pre_bl(PRE_ARGS) |
|
mdoc_argnames[mdoclt]); |
mdoc_argnames[mdoclt]); |
break; |
break; |
case LIST_bullet: |
case LIST_bullet: |
/* FALLTHROUGH */ |
|
case LIST_dash: |
case LIST_dash: |
/* FALLTHROUGH */ |
|
case LIST_hyphen: |
case LIST_hyphen: |
if (NULL == n->norm->Bl.width) |
if (NULL == n->norm->Bl.width) |
n->norm->Bl.width = "2n"; |
n->norm->Bl.width = "2n"; |
Line 594 pre_bl(PRE_ARGS) |
|
Line 541 pre_bl(PRE_ARGS) |
|
default: |
default: |
break; |
break; |
} |
} |
pre_par(mdoc, n); |
|
} |
} |
|
|
static void |
static void |
pre_bd(PRE_ARGS) |
post_bd(POST_ARGS) |
{ |
{ |
|
struct roff_node *n; |
struct mdoc_argv *argv; |
struct mdoc_argv *argv; |
int i; |
int i; |
enum mdoc_disp dt; |
enum mdoc_disp dt; |
|
|
pre_literal(mdoc, n); |
n = mdoc->last; |
|
|
if (n->type != ROFFT_BLOCK) |
|
return; |
|
|
|
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
argv = n->args->argv + i; |
argv = n->args->argv + i; |
dt = DISP__NONE; |
dt = DISP__NONE; |
Line 657 pre_bd(PRE_ARGS) |
|
Line 600 pre_bd(PRE_ARGS) |
|
break; |
break; |
default: |
default: |
abort(); |
abort(); |
/* NOTREACHED */ |
|
} |
} |
if (DISP__NONE == dt) |
if (DISP__NONE == dt) |
continue; |
continue; |
Line 675 pre_bd(PRE_ARGS) |
|
Line 617 pre_bd(PRE_ARGS) |
|
n->line, n->pos, "Bd"); |
n->line, n->pos, "Bd"); |
n->norm->Bd.type = DISP_ragged; |
n->norm->Bd.type = DISP_ragged; |
} |
} |
pre_par(mdoc, n); |
|
} |
} |
|
|
static void |
static void |
pre_an(PRE_ARGS) |
post_an_norm(POST_ARGS) |
{ |
{ |
|
struct roff_node *n; |
struct mdoc_argv *argv; |
struct mdoc_argv *argv; |
size_t i; |
size_t i; |
|
|
|
n = mdoc->last; |
if (n->args == NULL) |
if (n->args == NULL) |
return; |
return; |
|
|
Line 704 pre_an(PRE_ARGS) |
|
Line 647 pre_an(PRE_ARGS) |
|
} |
} |
|
|
static void |
static void |
pre_std(PRE_ARGS) |
post_std(POST_ARGS) |
{ |
{ |
|
struct roff_node *n; |
|
|
if (n->args && 1 == n->args->argc) |
n = mdoc->last; |
if (MDOC_Std == n->args->argv[0].arg) |
if (n->args && n->args->argc == 1) |
|
if (n->args->argv[0].arg == MDOC_Std) |
return; |
return; |
|
|
mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, |
mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, |
Line 716 pre_std(PRE_ARGS) |
|
Line 661 pre_std(PRE_ARGS) |
|
} |
} |
|
|
static void |
static void |
pre_obsolete(PRE_ARGS) |
post_obsolete(POST_ARGS) |
{ |
{ |
|
struct roff_node *n; |
|
|
|
n = mdoc->last; |
if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) |
if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) |
mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, |
mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, |
n->line, n->pos, mdoc_macronames[n->tok]); |
n->line, n->pos, mdoc_macronames[n->tok]); |
} |
} |
|
|
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 mdoc_node *np, *nch; |
struct roff_node *np, *nch; |
enum mdocargt arg; |
|
|
|
/* |
/* |
* Unlike other data pointers, these are "housed" by the HEAD |
* Unlike other data pointers, these are "housed" by the HEAD |
Line 782 post_bf(POST_ARGS) |
|
Line 686 post_bf(POST_ARGS) |
|
return; |
return; |
|
|
assert(np->parent->type == ROFFT_BLOCK); |
assert(np->parent->type == ROFFT_BLOCK); |
assert(MDOC_Bf == np->parent->tok); |
assert(np->parent->tok == MDOC_Bf); |
|
|
/* Check the number of arguments. */ |
/* Check the number of arguments. */ |
|
|
nch = np->child; |
nch = np->child; |
if (NULL == np->parent->args) { |
if (np->parent->args == NULL) { |
if (NULL == nch) { |
if (nch == NULL) { |
mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse, |
mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse, |
np->line, np->pos, "Bf"); |
np->line, np->pos, "Bf"); |
return; |
return; |
} |
} |
nch = nch->next; |
nch = nch->next; |
} |
} |
if (NULL != nch) |
if (nch != NULL) |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
nch->line, nch->pos, "Bf ... %s", nch->string); |
nch->line, nch->pos, "Bf ... %s", nch->string); |
|
|
/* Extract argument into data. */ |
/* Extract argument into data. */ |
|
|
if (np->parent->args) { |
if (np->parent->args != NULL) { |
arg = np->parent->args->argv[0].arg; |
switch (np->parent->args->argv[0].arg) { |
if (MDOC_Emphasis == arg) |
case MDOC_Emphasis: |
np->norm->Bf.font = FONT_Em; |
np->norm->Bf.font = FONT_Em; |
else if (MDOC_Literal == arg) |
break; |
|
case MDOC_Literal: |
np->norm->Bf.font = FONT_Li; |
np->norm->Bf.font = FONT_Li; |
else if (MDOC_Symbolic == arg) |
break; |
|
case MDOC_Symbolic: |
np->norm->Bf.font = FONT_Sy; |
np->norm->Bf.font = FONT_Sy; |
else |
break; |
|
default: |
abort(); |
abort(); |
|
} |
return; |
return; |
} |
} |
|
|
/* Extract parameter into data. */ |
/* Extract parameter into data. */ |
|
|
if (0 == strcmp(np->child->string, "Em")) |
if ( ! strcmp(np->child->string, "Em")) |
np->norm->Bf.font = FONT_Em; |
np->norm->Bf.font = FONT_Em; |
else if (0 == strcmp(np->child->string, "Li")) |
else if ( ! strcmp(np->child->string, "Li")) |
np->norm->Bf.font = FONT_Li; |
np->norm->Bf.font = FONT_Li; |
else if (0 == strcmp(np->child->string, "Sy")) |
else if ( ! strcmp(np->child->string, "Sy")) |
np->norm->Bf.font = FONT_Sy; |
np->norm->Bf.font = FONT_Sy; |
else |
else |
mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse, |
mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse, |
Line 831 post_bf(POST_ARGS) |
|
Line 739 post_bf(POST_ARGS) |
|
static void |
static void |
post_lb(POST_ARGS) |
post_lb(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
const char *stdlibname; |
const char *stdlibname; |
char *libname; |
char *libname; |
|
|
Line 851 post_lb(POST_ARGS) |
|
Line 759 post_lb(POST_ARGS) |
|
static void |
static void |
post_eoln(POST_ARGS) |
post_eoln(POST_ARGS) |
{ |
{ |
const struct mdoc_node *n; |
const struct roff_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
if (n->child) |
if (n->child != NULL) |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
mdoc->parse, n->line, n->pos, |
mdoc->parse, n->line, n->pos, |
"%s %s", mdoc_macronames[n->tok], |
"%s %s", mdoc_macronames[n->tok], |
Line 864 post_eoln(POST_ARGS) |
|
Line 772 post_eoln(POST_ARGS) |
|
static void |
static void |
post_fname(POST_ARGS) |
post_fname(POST_ARGS) |
{ |
{ |
const struct mdoc_node *n; |
const struct roff_node *n; |
const char *cp; |
const char *cp; |
size_t pos; |
size_t pos; |
|
|
Line 887 post_fn(POST_ARGS) |
|
Line 795 post_fn(POST_ARGS) |
|
static void |
static void |
post_fo(POST_ARGS) |
post_fo(POST_ARGS) |
{ |
{ |
const struct mdoc_node *n; |
const struct roff_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 904 post_fo(POST_ARGS) |
|
Line 812 post_fo(POST_ARGS) |
|
n->child->next->line, n->child->next->pos, |
n->child->next->line, n->child->next->pos, |
"Fo ... %s", n->child->next->string); |
"Fo ... %s", n->child->next->string); |
while (n->child != n->last) |
while (n->child != n->last) |
mdoc_node_delete(mdoc, n->last); |
roff_node_delete(mdoc, n->last); |
} |
} |
|
|
post_fname(mdoc); |
post_fname(mdoc); |
Line 913 post_fo(POST_ARGS) |
|
Line 821 post_fo(POST_ARGS) |
|
static void |
static void |
post_fa(POST_ARGS) |
post_fa(POST_ARGS) |
{ |
{ |
const struct mdoc_node *n; |
const struct roff_node *n; |
const char *cp; |
const char *cp; |
|
|
for (n = mdoc->last->child; n != NULL; n = n->next) { |
for (n = mdoc->last->child; n != NULL; n = n->next) { |
Line 932 post_fa(POST_ARGS) |
|
Line 840 post_fa(POST_ARGS) |
|
} |
} |
|
|
static void |
static void |
post_vt(POST_ARGS) |
|
{ |
|
const struct mdoc_node *n; |
|
|
|
/* |
|
* The Vt macro comes in both ELEM and BLOCK form, both of which |
|
* have different syntaxes (yet more context-sensitive |
|
* behaviour). ELEM types must have a child, which is already |
|
* guaranteed by the in_line parsing routine; BLOCK types, |
|
* specifically the BODY, should only have TEXT children. |
|
*/ |
|
|
|
if (mdoc->last->type != ROFFT_BODY) |
|
return; |
|
|
|
for (n = mdoc->last->child; n; n = n->next) |
|
if (n->type != ROFFT_TEXT) |
|
mandoc_msg(MANDOCERR_VT_CHILD, mdoc->parse, |
|
n->line, n->pos, mdoc_macronames[n->tok]); |
|
} |
|
|
|
static void |
|
post_nm(POST_ARGS) |
post_nm(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 965 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 (NULL != mdoc->meta.name) |
if (mdoc->meta.name != NULL) |
return; |
return; |
|
|
mdoc_deroff(&mdoc->meta.name, n); |
deroff(&mdoc->meta.name, n); |
|
|
if (NULL == mdoc->meta.name) |
if (mdoc->meta.name == 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 978 post_nm(POST_ARGS) |
|
Line 864 post_nm(POST_ARGS) |
|
static void |
static void |
post_nd(POST_ARGS) |
post_nd(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 993 post_nd(POST_ARGS) |
|
Line 879 post_nd(POST_ARGS) |
|
} |
} |
|
|
static void |
static void |
post_d1(POST_ARGS) |
post_display(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n, *np; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
switch (n->type) { |
if (n->type != ROFFT_BODY) |
case ROFFT_BODY: |
return; |
if (n->end != ENDBODY_NOT) |
|
break; |
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, "D1"); |
n->line, n->pos, mdoc_macronames[n->tok]); |
|
else if (n->tok == MDOC_D1) |
post_hyph(mdoc); |
post_hyph(mdoc); |
|
break; |
|
case ROFFT_BLOCK: |
|
if (n->tok == MDOC_Bd) { |
|
if (n->args == NULL) { |
|
mandoc_msg(MANDOCERR_BD_NOARG, |
|
mdoc->parse, n->line, n->pos, "Bd"); |
|
mdoc->next = ROFF_NEXT_SIBLING; |
|
while (n->body->child != NULL) |
|
mdoc_node_relink(mdoc, |
|
n->body->child); |
|
roff_node_delete(mdoc, n); |
|
break; |
|
} |
|
post_bd(mdoc); |
|
post_prevpar(mdoc); |
|
} |
|
for (np = n->parent; np != NULL; np = np->parent) { |
|
if (np->type == ROFFT_BLOCK && np->tok == MDOC_Bd) { |
|
mandoc_vmsg(MANDOCERR_BD_NEST, |
|
mdoc->parse, n->line, n->pos, |
|
"%s in Bd", mdoc_macronames[n->tok]); |
|
break; |
|
} |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
} |
} |
|
|
static void |
static void |
post_literal(POST_ARGS) |
|
{ |
|
struct mdoc_node *n; |
|
|
|
n = mdoc->last; |
|
|
|
if (n->type != ROFFT_BODY) |
|
return; |
|
|
|
if (n->child == NULL) |
|
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, |
|
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 |
|
post_defaults(POST_ARGS) |
post_defaults(POST_ARGS) |
{ |
{ |
struct mdoc_node *nn; |
struct roff_node *nn; |
|
|
/* |
/* |
* The `Ar' defaults to "file ..." if no value is provided as an |
* The `Ar' defaults to "file ..." if no value is provided as an |
Line 1042 post_defaults(POST_ARGS) |
|
Line 934 post_defaults(POST_ARGS) |
|
* gets an empty string. |
* gets an empty string. |
*/ |
*/ |
|
|
if (mdoc->last->child) |
if (mdoc->last->child != NULL) |
return; |
return; |
|
|
nn = mdoc->last; |
nn = mdoc->last; |
mdoc->next = MDOC_NEXT_CHILD; |
|
|
|
switch (nn->tok) { |
switch (nn->tok) { |
case MDOC_Ar: |
case MDOC_Ar: |
mdoc_word_alloc(mdoc, nn->line, nn->pos, "file"); |
mdoc->next = ROFF_NEXT_CHILD; |
mdoc_word_alloc(mdoc, nn->line, nn->pos, "..."); |
roff_word_alloc(mdoc, nn->line, nn->pos, "file"); |
|
roff_word_alloc(mdoc, nn->line, nn->pos, "..."); |
break; |
break; |
case MDOC_Pa: |
case MDOC_Pa: |
/* FALLTHROUGH */ |
|
case MDOC_Mt: |
case MDOC_Mt: |
mdoc_word_alloc(mdoc, nn->line, nn->pos, "~"); |
mdoc->next = ROFF_NEXT_CHILD; |
|
roff_word_alloc(mdoc, nn->line, nn->pos, "~"); |
break; |
break; |
default: |
default: |
abort(); |
abort(); |
/* NOTREACHED */ |
|
} |
} |
mdoc->last = nn; |
mdoc->last = nn; |
} |
} |
Line 1068 post_defaults(POST_ARGS) |
|
Line 959 post_defaults(POST_ARGS) |
|
static void |
static void |
post_at(POST_ARGS) |
post_at(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
const char *std_att; |
const char *std_att; |
char *att; |
char *att; |
|
|
n = mdoc->last; |
n = mdoc->last; |
if (n->child == NULL) { |
if (n->child == NULL) { |
mdoc->next = MDOC_NEXT_CHILD; |
mdoc->next = ROFF_NEXT_CHILD; |
mdoc_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); |
roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); |
mdoc->last = n; |
mdoc->last = n; |
return; |
return; |
} |
} |
Line 1088 post_at(POST_ARGS) |
|
Line 979 post_at(POST_ARGS) |
|
|
|
n = n->child; |
n = n->child; |
assert(n->type == ROFFT_TEXT); |
assert(n->type == ROFFT_TEXT); |
if (NULL == (std_att = mdoc_a2att(n->string))) { |
if ((std_att = mdoc_a2att(n->string)) == NULL) { |
mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse, |
mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse, |
n->line, n->pos, "At %s", n->string); |
n->line, n->pos, "At %s", n->string); |
mandoc_asprintf(&att, "AT&T UNIX %s", n->string); |
mandoc_asprintf(&att, "AT&T UNIX %s", n->string); |
Line 1102 post_at(POST_ARGS) |
|
Line 993 post_at(POST_ARGS) |
|
static void |
static void |
post_an(POST_ARGS) |
post_an(POST_ARGS) |
{ |
{ |
struct mdoc_node *np, *nch; |
struct roff_node *np, *nch; |
|
|
|
post_an_norm(mdoc); |
|
|
np = mdoc->last; |
np = mdoc->last; |
nch = np->child; |
nch = np->child; |
if (np->norm->An.auth == AUTH__NONE) { |
if (np->norm->An.auth == AUTH__NONE) { |
|
|
post_en(POST_ARGS) |
post_en(POST_ARGS) |
{ |
{ |
|
|
|
post_obsolete(mdoc); |
if (mdoc->last->type == ROFFT_BLOCK) |
if (mdoc->last->type == ROFFT_BLOCK) |
mdoc->last->norm->Es = mdoc->last_es; |
mdoc->last->norm->Es = mdoc->last_es; |
} |
} |
|
|
post_es(POST_ARGS) |
post_es(POST_ARGS) |
{ |
{ |
|
|
|
post_obsolete(mdoc); |
mdoc->last_es = mdoc->last; |
mdoc->last_es = mdoc->last; |
} |
} |
|
|
static void |
static void |
post_it(POST_ARGS) |
post_it(POST_ARGS) |
{ |
{ |
|
struct roff_node *nbl, *nit, *nch; |
int i, cols; |
int i, cols; |
enum mdoc_list lt; |
enum mdoc_list lt; |
struct mdoc_node *nbl, *nit, *nch; |
|
|
|
|
post_prevpar(mdoc); |
|
|
nit = mdoc->last; |
nit = mdoc->last; |
if (nit->type != ROFFT_BLOCK) |
if (nit->type != ROFFT_BLOCK) |
return; |
return; |
Line 1146 post_it(POST_ARGS) |
|
Line 1043 post_it(POST_ARGS) |
|
|
|
switch (lt) { |
switch (lt) { |
case LIST_tag: |
case LIST_tag: |
/* FALLTHROUGH */ |
|
case LIST_hang: |
case LIST_hang: |
/* FALLTHROUGH */ |
|
case LIST_ohang: |
case LIST_ohang: |
/* FALLTHROUGH */ |
|
case LIST_inset: |
case LIST_inset: |
/* FALLTHROUGH */ |
|
case LIST_diag: |
case LIST_diag: |
if (nit->head->child == NULL) |
if (nit->head->child == NULL) |
mandoc_vmsg(MANDOCERR_IT_NOHEAD, |
mandoc_vmsg(MANDOCERR_IT_NOHEAD, |
Line 1161 post_it(POST_ARGS) |
|
Line 1054 post_it(POST_ARGS) |
|
mdoc_argnames[nbl->args->argv[0].arg]); |
mdoc_argnames[nbl->args->argv[0].arg]); |
break; |
break; |
case LIST_bullet: |
case LIST_bullet: |
/* FALLTHROUGH */ |
|
case LIST_dash: |
case LIST_dash: |
/* FALLTHROUGH */ |
|
case LIST_enum: |
case LIST_enum: |
/* FALLTHROUGH */ |
|
case LIST_hyphen: |
case LIST_hyphen: |
if (nit->body == NULL || nit->body->child == NULL) |
if (nit->body == NULL || nit->body->child == NULL) |
mandoc_vmsg(MANDOCERR_IT_NOBODY, |
mandoc_vmsg(MANDOCERR_IT_NOBODY, |
Line 1174 post_it(POST_ARGS) |
|
Line 1064 post_it(POST_ARGS) |
|
mdoc_argnames[nbl->args->argv[0].arg]); |
mdoc_argnames[nbl->args->argv[0].arg]); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case LIST_item: |
case LIST_item: |
if (nit->head->child != NULL) |
if ((nch = nit->head->child) != NULL) |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
mdoc->parse, nit->line, nit->pos, |
mdoc->parse, nit->line, nit->pos, |
"It %s", nit->head->child->string); |
"It %s", nch->string == NULL ? |
|
mdoc_macronames[nch->tok] : nch->string); |
break; |
break; |
case LIST_column: |
case LIST_column: |
cols = (int)nbl->norm->Bl.ncols; |
cols = (int)nbl->norm->Bl.ncols; |
|
|
assert(nit->head->child == NULL); |
assert(nit->head->child == NULL); |
|
|
for (i = 0, nch = nit->child; nch; nch = nch->next) |
i = 0; |
|
for (nch = nit->child; nch != NULL; nch = nch->next) |
if (nch->type == ROFFT_BODY) |
if (nch->type == ROFFT_BODY) |
i++; |
i++; |
|
|
Line 1201 post_it(POST_ARGS) |
|
Line 1093 post_it(POST_ARGS) |
|
static void |
static void |
post_bl_block(POST_ARGS) |
post_bl_block(POST_ARGS) |
{ |
{ |
struct mdoc_node *n, *ni, *nc; |
struct roff_node *n, *ni, *nc; |
|
|
|
post_prevpar(mdoc); |
|
|
/* |
/* |
* These are fairly complicated, so we've broken them into two |
* These are fairly complicated, so we've broken them into two |
* functions. post_bl_block_tag() is called when a -tag is |
* functions. post_bl_block_tag() is called when a -tag is |
Line 1213 post_bl_block(POST_ARGS) |
|
Line 1107 post_bl_block(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (LIST_tag == n->norm->Bl.type && |
if (n->norm->Bl.type == LIST_tag && |
NULL == n->norm->Bl.width) { |
n->norm->Bl.width == NULL) { |
post_bl_block_tag(mdoc); |
post_bl_block_tag(mdoc); |
assert(n->norm->Bl.width); |
assert(n->norm->Bl.width != NULL); |
} |
} |
|
|
for (ni = n->body->child; ni; ni = ni->next) { |
for (ni = n->body->child; ni != NULL; ni = ni->next) { |
if (NULL == ni->body) |
if (ni->body == NULL) |
continue; |
continue; |
nc = ni->body->last; |
nc = ni->body->last; |
while (NULL != nc) { |
while (nc != NULL) { |
switch (nc->tok) { |
switch (nc->tok) { |
case MDOC_Pp: |
case MDOC_Pp: |
/* FALLTHROUGH */ |
|
case MDOC_Lp: |
case MDOC_Lp: |
/* FALLTHROUGH */ |
|
case MDOC_br: |
case MDOC_br: |
break; |
break; |
default: |
default: |
nc = NULL; |
nc = NULL; |
continue; |
continue; |
} |
} |
if (NULL == ni->next) { |
if (ni->next == NULL) { |
mandoc_msg(MANDOCERR_PAR_MOVE, |
mandoc_msg(MANDOCERR_PAR_MOVE, |
mdoc->parse, nc->line, nc->pos, |
mdoc->parse, nc->line, nc->pos, |
mdoc_macronames[nc->tok]); |
mdoc_macronames[nc->tok]); |
mdoc_node_relink(mdoc, nc); |
mdoc_node_relink(mdoc, nc); |
} else if (0 == n->norm->Bl.comp && |
} else if (n->norm->Bl.comp == 0 && |
LIST_column != n->norm->Bl.type) { |
n->norm->Bl.type != LIST_column) { |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
mdoc->parse, nc->line, nc->pos, |
mdoc->parse, nc->line, nc->pos, |
"%s before It", |
"%s before It", |
mdoc_macronames[nc->tok]); |
mdoc_macronames[nc->tok]); |
mdoc_node_delete(mdoc, nc); |
roff_node_delete(mdoc, nc); |
} else |
} else |
break; |
break; |
nc = ni->body->last; |
nc = ni->body->last; |
|
|
rewrite_macro2len(char **arg) |
rewrite_macro2len(char **arg) |
{ |
{ |
size_t width; |
size_t width; |
enum mdoct tok; |
int tok; |
|
|
if (*arg == NULL) |
if (*arg == NULL) |
return; |
return; |
else if ( ! strcmp(*arg, "Ds")) |
else if ( ! strcmp(*arg, "Ds")) |
width = 6; |
width = 6; |
else if ((tok = mdoc_hash_find(*arg)) == MDOC_MAX) |
else if ((tok = mdoc_hash_find(*arg)) == TOKEN_NONE) |
return; |
return; |
else |
else |
width = macro2len(tok); |
width = macro2len(tok); |
Line 1280 rewrite_macro2len(char **arg) |
|
Line 1172 rewrite_macro2len(char **arg) |
|
static void |
static void |
post_bl_block_tag(POST_ARGS) |
post_bl_block_tag(POST_ARGS) |
{ |
{ |
struct mdoc_node *n, *nn; |
struct roff_node *n, *nn; |
size_t sz, ssz; |
size_t sz, ssz; |
int i; |
int i; |
char buf[24]; |
char buf[24]; |
Line 1295 post_bl_block_tag(POST_ARGS) |
|
Line 1187 post_bl_block_tag(POST_ARGS) |
|
sz = 10; |
sz = 10; |
n = mdoc->last; |
n = mdoc->last; |
|
|
for (nn = n->body->child; nn; nn = nn->next) { |
for (nn = n->body->child; nn != NULL; nn = nn->next) { |
if (MDOC_It != nn->tok) |
if (nn->tok != MDOC_It) |
continue; |
continue; |
|
|
assert(nn->type == ROFFT_BLOCK); |
assert(nn->type == ROFFT_BLOCK); |
Line 1325 post_bl_block_tag(POST_ARGS) |
|
Line 1217 post_bl_block_tag(POST_ARGS) |
|
* We're guaranteed that a MDOC_Width doesn't already exist. |
* We're guaranteed that a MDOC_Width doesn't already exist. |
*/ |
*/ |
|
|
assert(n->args); |
assert(n->args != NULL); |
i = (int)(n->args->argc)++; |
i = (int)(n->args->argc)++; |
|
|
n->args->argv = mandoc_reallocarray(n->args->argv, |
n->args->argv = mandoc_reallocarray(n->args->argv, |
Line 1345 post_bl_block_tag(POST_ARGS) |
|
Line 1237 post_bl_block_tag(POST_ARGS) |
|
static void |
static void |
post_bl_head(POST_ARGS) |
post_bl_head(POST_ARGS) |
{ |
{ |
struct mdoc_node *nbl, *nh, *nch, *nnext; |
struct roff_node *nbl, *nh, *nch, *nnext; |
struct mdoc_argv *argv; |
struct mdoc_argv *argv; |
int i, j; |
int i, j; |
|
|
nh = mdoc->last; |
post_bl_norm(mdoc); |
|
|
|
nh = mdoc->last; |
if (nh->norm->Bl.type != LIST_column) { |
if (nh->norm->Bl.type != LIST_column) { |
if ((nch = nh->child) == NULL) |
if ((nch = nh->child) == NULL) |
return; |
return; |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
nch->line, nch->pos, "Bl ... %s", nch->string); |
nch->line, nch->pos, "Bl ... %s", nch->string); |
while (nch != NULL) { |
while (nch != NULL) { |
mdoc_node_delete(mdoc, nch); |
roff_node_delete(mdoc, nch); |
nch = nh->child; |
nch = nh->child; |
} |
} |
return; |
return; |
Line 1387 post_bl_head(POST_ARGS) |
|
Line 1280 post_bl_head(POST_ARGS) |
|
|
|
argv = nbl->args->argv + j; |
argv = nbl->args->argv + j; |
i = argv->sz; |
i = argv->sz; |
argv->sz += nh->nchild; |
for (nch = nh->child; nch != NULL; nch = nch->next) |
|
argv->sz++; |
argv->value = mandoc_reallocarray(argv->value, |
argv->value = mandoc_reallocarray(argv->value, |
argv->sz, sizeof(char *)); |
argv->sz, sizeof(char *)); |
|
|
Line 1398 post_bl_head(POST_ARGS) |
|
Line 1292 post_bl_head(POST_ARGS) |
|
argv->value[i++] = nch->string; |
argv->value[i++] = nch->string; |
nch->string = NULL; |
nch->string = NULL; |
nnext = nch->next; |
nnext = nch->next; |
mdoc_node_delete(NULL, nch); |
roff_node_delete(NULL, nch); |
} |
} |
nh->nchild = 0; |
|
nh->child = NULL; |
nh->child = NULL; |
} |
} |
|
|
static void |
static void |
post_bl(POST_ARGS) |
post_bl(POST_ARGS) |
{ |
{ |
struct mdoc_node *nparent, *nprev; /* of the Bl block */ |
struct roff_node *nparent, *nprev; /* of the Bl block */ |
struct mdoc_node *nblock, *nbody; /* of the Bl */ |
struct roff_node *nblock, *nbody; /* of the Bl */ |
struct mdoc_node *nchild, *nnext; /* of the Bl body */ |
struct roff_node *nchild, *nnext; /* of the Bl body */ |
|
|
nbody = mdoc->last; |
nbody = mdoc->last; |
switch (nbody->type) { |
switch (nbody->type) { |
Line 1424 post_bl(POST_ARGS) |
|
Line 1317 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 1458 post_bl(POST_ARGS) |
|
Line 1353 post_bl(POST_ARGS) |
|
* Unlink this child. |
* Unlink this child. |
*/ |
*/ |
|
|
assert(NULL == nchild->prev); |
assert(nchild->prev == NULL); |
if (0 == --nbody->nchild) { |
nbody->child = nnext; |
nbody->child = NULL; |
if (nnext == NULL) |
nbody->last = NULL; |
nbody->last = NULL; |
assert(NULL == nnext); |
else |
} else { |
|
nbody->child = nnext; |
|
nnext->prev = NULL; |
nnext->prev = NULL; |
} |
|
|
|
/* |
/* |
* Relink this child. |
* Relink this child. |
Line 1477 post_bl(POST_ARGS) |
|
Line 1369 post_bl(POST_ARGS) |
|
nchild->next = nblock; |
nchild->next = nblock; |
|
|
nblock->prev = nchild; |
nblock->prev = nchild; |
nparent->nchild++; |
if (nprev == NULL) |
if (NULL == nprev) |
|
nparent->child = nchild; |
nparent->child = nchild; |
else |
else |
nprev->next = nchild; |
nprev->next = nchild; |
Line 1490 post_bl(POST_ARGS) |
|
Line 1381 post_bl(POST_ARGS) |
|
static void |
static void |
post_bk(POST_ARGS) |
post_bk(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (n->type == ROFFT_BLOCK && n->body->child == NULL) { |
if (n->type == ROFFT_BLOCK && n->body->child == NULL) { |
mandoc_msg(MANDOCERR_BLK_EMPTY, |
mandoc_msg(MANDOCERR_BLK_EMPTY, |
mdoc->parse, n->line, n->pos, "Bk"); |
mdoc->parse, n->line, n->pos, "Bk"); |
mdoc_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
} |
} |
} |
} |
|
|
static void |
static void |
post_sm(struct mdoc *mdoc) |
post_sm(POST_ARGS) |
{ |
{ |
struct mdoc_node *nch; |
struct roff_node *nch; |
|
|
nch = mdoc->last->child; |
nch = mdoc->last->child; |
|
|
Line 1534 post_sm(struct mdoc *mdoc) |
|
Line 1425 post_sm(struct mdoc *mdoc) |
|
static void |
static void |
post_root(POST_ARGS) |
post_root(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
/* Add missing prologue data. */ |
/* Add missing prologue data. */ |
|
|
Line 1561 post_root(POST_ARGS) |
|
Line 1452 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 && mdoc_macros[n->tok].flags & MDOC_PROLOGUE) |
while (n != NULL && n->tok != TOKEN_NONE && |
|
mdoc_macros[n->tok].flags & MDOC_PROLOGUE) |
n = n->next; |
n = n->next; |
|
|
if (n == NULL) |
if (n == NULL) |
Line 1574 post_root(POST_ARGS) |
|
Line 1466 post_root(POST_ARGS) |
|
static void |
static void |
post_st(POST_ARGS) |
post_st(POST_ARGS) |
{ |
{ |
struct mdoc_node *n, *nch; |
struct roff_node *n, *nch; |
const char *p; |
const char *p; |
|
|
n = mdoc->last; |
n = mdoc->last; |
Line 1582 post_st(POST_ARGS) |
|
Line 1474 post_st(POST_ARGS) |
|
|
|
assert(nch->type == ROFFT_TEXT); |
assert(nch->type == ROFFT_TEXT); |
|
|
if (NULL == (p = mdoc_a2st(nch->string))) { |
if ((p = mdoc_a2st(nch->string)) == NULL) { |
mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, |
mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, |
nch->line, nch->pos, "St %s", nch->string); |
nch->line, nch->pos, "St %s", nch->string); |
mdoc_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
} else { |
} else { |
free(nch->string); |
free(nch->string); |
nch->string = mandoc_strdup(p); |
nch->string = mandoc_strdup(p); |
Line 1595 post_st(POST_ARGS) |
|
Line 1487 post_st(POST_ARGS) |
|
static void |
static void |
post_rs(POST_ARGS) |
post_rs(POST_ARGS) |
{ |
{ |
struct mdoc_node *np, *nch, *next, *prev; |
struct roff_node *np, *nch, *next, *prev; |
int i, j; |
int i, j; |
|
|
np = mdoc->last; |
np = mdoc->last; |
Line 1632 post_rs(POST_ARGS) |
|
Line 1524 post_rs(POST_ARGS) |
|
|
|
/* |
/* |
* Remove this child from the chain. This somewhat |
* Remove this child from the chain. This somewhat |
* repeats mdoc_node_unlink(), but since we're |
* repeats roff_node_unlink(), but since we're |
* just re-ordering, there's no need for the |
* just re-ordering, there's no need for the |
* full unlink process. |
* full unlink process. |
*/ |
*/ |
Line 1689 post_rs(POST_ARGS) |
|
Line 1581 post_rs(POST_ARGS) |
|
static void |
static void |
post_hyph(POST_ARGS) |
post_hyph(POST_ARGS) |
{ |
{ |
struct mdoc_node *nch; |
struct roff_node *nch; |
char *cp; |
char *cp; |
|
|
for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { |
for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { |
|
|
post_ns(POST_ARGS) |
post_ns(POST_ARGS) |
{ |
{ |
|
|
if (MDOC_LINE & mdoc->last->flags) |
if (mdoc->last->flags & MDOC_LINE) |
mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse, |
mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, NULL); |
mdoc->last->line, mdoc->last->pos, NULL); |
} |
} |
Line 1748 post_sh(POST_ARGS) |
|
Line 1640 post_sh(POST_ARGS) |
|
static void |
static void |
post_sh_name(POST_ARGS) |
post_sh_name(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
int hasnm, hasnd; |
int hasnm, hasnd; |
|
|
hasnm = hasnd = 0; |
hasnm = hasnd = 0; |
Line 1764 post_sh_name(POST_ARGS) |
|
Line 1656 post_sh_name(POST_ARGS) |
|
mandoc_msg(MANDOCERR_NAMESEC_ND, |
mandoc_msg(MANDOCERR_NAMESEC_ND, |
mdoc->parse, n->line, n->pos, NULL); |
mdoc->parse, n->line, n->pos, NULL); |
break; |
break; |
case MDOC_MAX: |
case TOKEN_NONE: |
if (hasnm) |
if (hasnm) |
break; |
break; |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
Line 1786 post_sh_name(POST_ARGS) |
|
Line 1678 post_sh_name(POST_ARGS) |
|
static void |
static void |
post_sh_see_also(POST_ARGS) |
post_sh_see_also(POST_ARGS) |
{ |
{ |
const struct mdoc_node *n; |
const struct roff_node *n; |
const char *name, *sec; |
const char *name, *sec; |
const char *lastname, *lastsec, *lastpunct; |
const char *lastname, *lastsec, *lastpunct; |
int cmp; |
int cmp; |
Line 1794 post_sh_see_also(POST_ARGS) |
|
Line 1686 post_sh_see_also(POST_ARGS) |
|
n = mdoc->last->child; |
n = mdoc->last->child; |
lastname = lastsec = lastpunct = NULL; |
lastname = lastsec = lastpunct = NULL; |
while (n != NULL) { |
while (n != NULL) { |
if (n->tok != MDOC_Xr || n->nchild < 2) |
if (n->tok != MDOC_Xr || |
|
n->child == NULL || |
|
n->child->next == NULL) |
break; |
break; |
|
|
/* Process one .Xr node. */ |
/* Process one .Xr node. */ |
Line 1846 post_sh_see_also(POST_ARGS) |
|
Line 1740 post_sh_see_also(POST_ARGS) |
|
} |
} |
|
|
static int |
static int |
child_an(const struct mdoc_node *n) |
child_an(const struct roff_node *n) |
{ |
{ |
|
|
for (n = n->child; n != NULL; n = n->next) |
for (n = n->child; n != NULL; n = n->next) |
if ((n->tok == MDOC_An && n->nchild) || child_an(n)) |
if ((n->tok == MDOC_An && n->child != NULL) || child_an(n)) |
return(1); |
return 1; |
return(0); |
return 0; |
} |
} |
|
|
static void |
static void |
Line 1867 post_sh_authors(POST_ARGS) |
|
Line 1761 post_sh_authors(POST_ARGS) |
|
static void |
static void |
post_sh_head(POST_ARGS) |
post_sh_head(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *nch; |
const char *goodsec; |
const char *goodsec; |
char *secname; |
enum roff_sec sec; |
enum mdoc_sec sec; |
|
|
|
/* |
/* |
* Process a new section. Sections are either "named" or |
* Process a new section. Sections are either "named" or |
Line 1879 post_sh_head(POST_ARGS) |
|
Line 1772 post_sh_head(POST_ARGS) |
|
* manual sections. |
* manual sections. |
*/ |
*/ |
|
|
secname = NULL; |
sec = mdoc->last->sec; |
sec = SEC_CUSTOM; |
|
mdoc_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 != SEC_NAME && mdoc->lastnamed == SEC_NONE) |
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", |
"Sh %s", secname); |
sec != SEC_CUSTOM ? secnames[sec] : |
|
(nch = mdoc->last->child) == NULL ? "" : |
|
nch->type == ROFFT_TEXT ? nch->string : |
|
mdoc_macronames[nch->tok]); |
|
|
/* 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 1905 post_sh_head(POST_ARGS) |
|
Line 1798 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; 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 1934 post_sh_head(POST_ARGS) |
|
Line 1811 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 1947 post_sh_head(POST_ARGS) |
|
Line 1824 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 1960 post_sh_head(POST_ARGS) |
|
Line 1835 post_sh_head(POST_ARGS) |
|
goodsec = "2, 3, 4, 9"; |
goodsec = "2, 3, 4, 9"; |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case SEC_RETURN_VALUES: |
case SEC_RETURN_VALUES: |
/* FALLTHROUGH */ |
|
case SEC_LIBRARY: |
case SEC_LIBRARY: |
if (*mdoc->meta.msec == '2') |
if (*mdoc->meta.msec == '2') |
break; |
break; |
Line 1976 post_sh_head(POST_ARGS) |
|
Line 1850 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 |
post_ignpar(POST_ARGS) |
post_ignpar(POST_ARGS) |
{ |
{ |
struct mdoc_node *np; |
struct roff_node *np; |
|
|
switch (mdoc->last->type) { |
switch (mdoc->last->type) { |
case ROFFT_HEAD: |
case ROFFT_HEAD: |
Line 1999 post_ignpar(POST_ARGS) |
|
Line 1872 post_ignpar(POST_ARGS) |
|
return; |
return; |
} |
} |
|
|
if (NULL != (np = mdoc->last->child)) |
if ((np = mdoc->last->child) != NULL) |
if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { |
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { |
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", mdoc_macronames[np->tok], |
"%s after %s", mdoc_macronames[np->tok], |
mdoc_macronames[mdoc->last->tok]); |
mdoc_macronames[mdoc->last->tok]); |
mdoc_node_delete(mdoc, np); |
roff_node_delete(mdoc, np); |
} |
} |
|
|
if (NULL != (np = mdoc->last->last)) |
if ((np = mdoc->last->last) != NULL) |
if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { |
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { |
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", |
mdoc_macronames[np->tok], |
mdoc_macronames[np->tok], |
mdoc_macronames[mdoc->last->tok]); |
mdoc_macronames[mdoc->last->tok]); |
mdoc_node_delete(mdoc, np); |
roff_node_delete(mdoc, np); |
} |
} |
} |
} |
|
|
static void |
static void |
pre_par(PRE_ARGS) |
post_prevpar(POST_ARGS) |
{ |
{ |
|
struct roff_node *n; |
|
|
if (NULL == mdoc->last) |
n = mdoc->last; |
|
if (NULL == n->prev) |
return; |
return; |
if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) |
if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) |
return; |
return; |
Line 2032 pre_par(PRE_ARGS) |
|
Line 1907 pre_par(PRE_ARGS) |
|
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'. |
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'. |
*/ |
*/ |
|
|
if (MDOC_Pp != mdoc->last->tok && |
if (n->prev->tok != MDOC_Pp && |
MDOC_Lp != mdoc->last->tok && |
n->prev->tok != MDOC_Lp && |
MDOC_br != mdoc->last->tok) |
n->prev->tok != MDOC_br) |
return; |
return; |
if (MDOC_Bl == n->tok && n->norm->Bl.comp) |
if (n->tok == MDOC_Bl && n->norm->Bl.comp) |
return; |
return; |
if (MDOC_Bd == n->tok && n->norm->Bd.comp) |
if (n->tok == MDOC_Bd && n->norm->Bd.comp) |
return; |
return; |
if (MDOC_It == n->tok && n->parent->norm->Bl.comp) |
if (n->tok == MDOC_It && n->parent->norm->Bl.comp) |
return; |
return; |
|
|
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
n->prev->line, n->prev->pos, |
"%s before %s", mdoc_macronames[mdoc->last->tok], |
"%s before %s", mdoc_macronames[n->prev->tok], |
mdoc_macronames[n->tok]); |
mdoc_macronames[n->tok]); |
mdoc_node_delete(mdoc, mdoc->last); |
roff_node_delete(mdoc, n->prev); |
} |
} |
|
|
static void |
static void |
post_par(POST_ARGS) |
post_par(POST_ARGS) |
{ |
{ |
struct mdoc_node *np; |
struct roff_node *np; |
|
|
np = mdoc->last; |
np = mdoc->last; |
|
if (np->tok != MDOC_br && np->tok != MDOC_sp) |
|
post_prevpar(mdoc); |
|
|
if (np->tok == MDOC_sp) { |
if (np->tok == MDOC_sp) { |
if (np->nchild > 1) |
if (np->child != NULL && np->child->next != NULL) |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, |
np->child->next->line, np->child->next->pos, |
np->child->next->line, np->child->next->pos, |
"sp ... %s", np->child->next->string); |
"sp ... %s", np->child->next->string); |
Line 2067 post_par(POST_ARGS) |
|
Line 1944 post_par(POST_ARGS) |
|
mdoc->parse, np->line, np->pos, "%s %s", |
mdoc->parse, np->line, np->pos, "%s %s", |
mdoc_macronames[np->tok], np->child->string); |
mdoc_macronames[np->tok], np->child->string); |
|
|
if (NULL == (np = mdoc->last->prev)) { |
if ((np = mdoc->last->prev) == NULL) { |
np = mdoc->last->parent; |
np = mdoc->last->parent; |
if (MDOC_Sh != np->tok && MDOC_Ss != np->tok) |
if (np->tok != MDOC_Sh && np->tok != MDOC_Ss) |
return; |
return; |
} else if (MDOC_Pp != np->tok && MDOC_Lp != np->tok && |
} else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp && |
(MDOC_br != mdoc->last->tok || |
(mdoc->last->tok != MDOC_br || |
(MDOC_sp != np->tok && MDOC_br != np->tok))) |
(np->tok != MDOC_sp && np->tok != MDOC_br))) |
return; |
return; |
|
|
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"%s after %s", mdoc_macronames[mdoc->last->tok], |
"%s after %s", mdoc_macronames[mdoc->last->tok], |
mdoc_macronames[np->tok]); |
mdoc_macronames[np->tok]); |
mdoc_node_delete(mdoc, mdoc->last); |
roff_node_delete(mdoc, mdoc->last); |
} |
} |
|
|
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(); |
|
/* NOTREACHED */ |
|
} |
|
} |
|
|
|
static void |
|
post_dd(POST_ARGS) |
post_dd(POST_ARGS) |
{ |
{ |
struct mdoc_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 (NULL == n->child || '\0' == n->child->string[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); |
goto out; |
goto out; |
} |
} |
|
|
datestr = NULL; |
datestr = NULL; |
mdoc_deroff(&datestr, n); |
deroff(&datestr, n); |
if (mdoc->quick) |
if (mdoc->quick) |
mdoc->meta.date = datestr; |
mdoc->meta.date = datestr; |
else { |
else { |
Line 2139 post_dd(POST_ARGS) |
|
Line 1997 post_dd(POST_ARGS) |
|
free(datestr); |
free(datestr); |
} |
} |
out: |
out: |
mdoc_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
} |
} |
|
|
static void |
static void |
post_dt(POST_ARGS) |
post_dt(POST_ARGS) |
{ |
{ |
struct mdoc_node *nn, *n; |
struct roff_node *nn, *n; |
const char *cp; |
const char *cp; |
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 2224 post_dt(POST_ARGS) |
|
Line 2094 post_dt(POST_ARGS) |
|
nn->line, nn->pos, "Dt ... %s", nn->string); |
nn->line, nn->pos, "Dt ... %s", nn->string); |
|
|
out: |
out: |
mdoc_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
} |
} |
|
|
static void |
static void |
post_bx(POST_ARGS) |
post_bx(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
/* |
/* |
* Make `Bx's second argument always start with an uppercase |
* Make `Bx's second argument always start with an uppercase |
Line 2238 post_bx(POST_ARGS) |
|
Line 2108 post_bx(POST_ARGS) |
|
* uppercase blindly. |
* uppercase blindly. |
*/ |
*/ |
|
|
n = mdoc->last->child; |
if ((n = mdoc->last->child) != NULL && (n = n->next) != NULL) |
if (n && NULL != (n = n->next)) |
|
*n->string = (char)toupper((unsigned char)*n->string); |
*n->string = (char)toupper((unsigned char)*n->string); |
} |
} |
|
|
Line 2250 post_os(POST_ARGS) |
|
Line 2119 post_os(POST_ARGS) |
|
struct utsname utsname; |
struct utsname utsname; |
static char *defbuf; |
static char *defbuf; |
#endif |
#endif |
struct mdoc_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 2265 post_os(POST_ARGS) |
|
Line 2140 post_os(POST_ARGS) |
|
|
|
free(mdoc->meta.os); |
free(mdoc->meta.os); |
mdoc->meta.os = NULL; |
mdoc->meta.os = NULL; |
mdoc_deroff(&mdoc->meta.os, n); |
deroff(&mdoc->meta.os, n); |
if (mdoc->meta.os) |
if (mdoc->meta.os) |
goto out; |
goto out; |
|
|
Line 2277 post_os(POST_ARGS) |
|
Line 2152 post_os(POST_ARGS) |
|
#ifdef OSNAME |
#ifdef OSNAME |
mdoc->meta.os = mandoc_strdup(OSNAME); |
mdoc->meta.os = mandoc_strdup(OSNAME); |
#else /*!OSNAME */ |
#else /*!OSNAME */ |
if (NULL == defbuf) { |
if (defbuf == NULL) { |
if (-1 == uname(&utsname)) { |
if (uname(&utsname) == -1) { |
mandoc_msg(MANDOCERR_OS_UNAME, mdoc->parse, |
mandoc_msg(MANDOCERR_OS_UNAME, mdoc->parse, |
n->line, n->pos, "Os"); |
n->line, n->pos, "Os"); |
defbuf = mandoc_strdup("UNKNOWN"); |
defbuf = mandoc_strdup("UNKNOWN"); |
Line 2290 post_os(POST_ARGS) |
|
Line 2165 post_os(POST_ARGS) |
|
#endif /*!OSNAME*/ |
#endif /*!OSNAME*/ |
|
|
out: |
out: |
mdoc_node_delete(mdoc, n); |
roff_node_delete(mdoc, n); |
} |
} |
|
|
/* |
/* |
|
|
static void |
static void |
post_ex(POST_ARGS) |
post_ex(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct roff_node *n; |
|
|
n = mdoc->last; |
post_std(mdoc); |
|
|
if (n->child) |
n = mdoc->last; |
|
if (n->child != NULL) |
return; |
return; |
|
|
if (mdoc->meta.name == NULL) { |
if (mdoc->meta.name == NULL) { |
Line 2313 post_ex(POST_ARGS) |
|
Line 2189 post_ex(POST_ARGS) |
|
return; |
return; |
} |
} |
|
|
mdoc->next = MDOC_NEXT_CHILD; |
mdoc->next = ROFF_NEXT_CHILD; |
mdoc_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); |
roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); |
mdoc->last = n; |
mdoc->last = n; |
} |
} |
|
|
static enum mdoc_sec |
enum roff_sec |
a2sec(const char *p) |
mdoc_a2sec(const char *p) |
{ |
{ |
int i; |
int i; |
|
|
for (i = 0; i < (int)SEC__MAX; i++) |
for (i = 0; i < (int)SEC__MAX; i++) |
if (secnames[i] && 0 == strcmp(p, secnames[i])) |
if (secnames[i] && 0 == strcmp(p, secnames[i])) |
return((enum mdoc_sec)i); |
return (enum roff_sec)i; |
|
|
return(SEC_CUSTOM); |
return SEC_CUSTOM; |
} |
} |
|
|
static size_t |
static size_t |
macro2len(enum mdoct macro) |
macro2len(int macro) |
{ |
{ |
|
|
switch (macro) { |
switch (macro) { |
case MDOC_Ad: |
case MDOC_Ad: |
return(12); |
return 12; |
case MDOC_Ao: |
case MDOC_Ao: |
return(12); |
return 12; |
case MDOC_An: |
case MDOC_An: |
return(12); |
return 12; |
case MDOC_Aq: |
case MDOC_Aq: |
return(12); |
return 12; |
case MDOC_Ar: |
case MDOC_Ar: |
return(12); |
return 12; |
case MDOC_Bo: |
case MDOC_Bo: |
return(12); |
return 12; |
case MDOC_Bq: |
case MDOC_Bq: |
return(12); |
return 12; |
case MDOC_Cd: |
case MDOC_Cd: |
return(12); |
return 12; |
case MDOC_Cm: |
case MDOC_Cm: |
return(10); |
return 10; |
case MDOC_Do: |
case MDOC_Do: |
return(10); |
return 10; |
case MDOC_Dq: |
case MDOC_Dq: |
return(12); |
return 12; |
case MDOC_Dv: |
case MDOC_Dv: |
return(12); |
return 12; |
case MDOC_Eo: |
case MDOC_Eo: |
return(12); |
return 12; |
case MDOC_Em: |
case MDOC_Em: |
return(10); |
return 10; |
case MDOC_Er: |
case MDOC_Er: |
return(17); |
return 17; |
case MDOC_Ev: |
case MDOC_Ev: |
return(15); |
return 15; |
case MDOC_Fa: |
case MDOC_Fa: |
return(12); |
return 12; |
case MDOC_Fl: |
case MDOC_Fl: |
return(10); |
return 10; |
case MDOC_Fo: |
case MDOC_Fo: |
return(16); |
return 16; |
case MDOC_Fn: |
case MDOC_Fn: |
return(16); |
return 16; |
case MDOC_Ic: |
case MDOC_Ic: |
return(10); |
return 10; |
case MDOC_Li: |
case MDOC_Li: |
return(16); |
return 16; |
case MDOC_Ms: |
case MDOC_Ms: |
return(6); |
return 6; |
case MDOC_Nm: |
case MDOC_Nm: |
return(10); |
return 10; |
case MDOC_No: |
case MDOC_No: |
return(12); |
return 12; |
case MDOC_Oo: |
case MDOC_Oo: |
return(10); |
return 10; |
case MDOC_Op: |
case MDOC_Op: |
return(14); |
return 14; |
case MDOC_Pa: |
case MDOC_Pa: |
return(32); |
return 32; |
case MDOC_Pf: |
case MDOC_Pf: |
return(12); |
return 12; |
case MDOC_Po: |
case MDOC_Po: |
return(12); |
return 12; |
case MDOC_Pq: |
case MDOC_Pq: |
return(12); |
return 12; |
case MDOC_Ql: |
case MDOC_Ql: |
return(16); |
return 16; |
case MDOC_Qo: |
case MDOC_Qo: |
return(12); |
return 12; |
case MDOC_So: |
case MDOC_So: |
return(12); |
return 12; |
case MDOC_Sq: |
case MDOC_Sq: |
return(12); |
return 12; |
case MDOC_Sy: |
case MDOC_Sy: |
return(6); |
return 6; |
case MDOC_Sx: |
case MDOC_Sx: |
return(16); |
return 16; |
case MDOC_Tn: |
case MDOC_Tn: |
return(10); |
return 10; |
case MDOC_Va: |
case MDOC_Va: |
return(12); |
return 12; |
case MDOC_Vt: |
case MDOC_Vt: |
return(12); |
return 12; |
case MDOC_Xr: |
case MDOC_Xr: |
return(10); |
return 10; |
default: |
default: |
break; |
break; |
}; |
}; |
return(0); |
return 0; |
} |
} |