=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.284 retrieving revision 1.319 diff -u -p -r1.284 -r1.319 --- mandoc/mdoc_validate.c 2015/04/02 21:36:50 1.284 +++ mandoc/mdoc_validate.c 2017/03/06 17:26:04 1.319 @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.284 2015/04/02 21:36:50 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.319 2017/03/06 17:26:04 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010-2015 Ingo Schwarze + * Copyright (c) 2010-2017 Ingo Schwarze * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -36,12 +36,12 @@ #include "roff.h" #include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" #include "libmdoc.h" /* 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 mdoc *mdoc +#define POST_ARGS struct roff_man *mdoc enum check_ineq { CHECK_LT, @@ -49,34 +49,30 @@ enum check_ineq { CHECK_EQ }; -typedef void (*v_pre)(PRE_ARGS); typedef void (*v_post)(POST_ARGS); -struct valids { - v_pre pre; - v_post post; -}; - -static void check_text(struct mdoc *, int, int, char *); -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 int build_list(struct roff_man *, int); +static void check_text(struct roff_man *, int, int, char *); +static void check_argv(struct roff_man *, + 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 size_t macro2len(int); static void rewrite_macro2len(char **); static void post_an(POST_ARGS); +static void post_an_norm(POST_ARGS); static void post_at(POST_ARGS); +static void post_bd(POST_ARGS); static void post_bf(POST_ARGS); static void post_bk(POST_ARGS); static void post_bl(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_norm(POST_ARGS); static void post_bx(POST_ARGS); -static void post_d1(POST_ARGS); static void post_defaults(POST_ARGS); +static void post_display(POST_ARGS); static void post_dd(POST_ARGS); static void post_dt(POST_ARGS); static void post_en(POST_ARGS); @@ -91,14 +87,16 @@ static void post_hyph(POST_ARGS); static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); -static void post_literal(POST_ARGS); static void post_nd(POST_ARGS); static void post_nm(POST_ARGS); static void post_ns(POST_ARGS); +static void post_obsolete(POST_ARGS); static void post_os(POST_ARGS); static void post_par(POST_ARGS); +static void post_prevpar(POST_ARGS); static void post_root(POST_ARGS); static void post_rs(POST_ARGS); +static void post_rv(POST_ARGS); static void post_sh(POST_ARGS); static void post_sh_head(POST_ARGS); static void post_sh_name(POST_ARGS); @@ -106,149 +104,139 @@ static void post_sh_see_also(POST_ARGS); static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); -static void post_vt(POST_ARGS); +static void post_std(POST_ARGS); +static void post_xr(POST_ARGS); +static void post_xx(POST_ARGS); -static void pre_an(PRE_ARGS); -static void pre_bd(PRE_ARGS); -static void pre_bl(PRE_ARGS); -static void pre_dd(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_os(PRE_ARGS); -static void pre_par(PRE_ARGS); -static void pre_std(PRE_ARGS); - -static const struct valids mdoc_valids[MDOC_MAX] = { - { NULL, NULL }, /* Ap */ - { pre_dd, post_dd }, /* Dd */ - { pre_dt, post_dt }, /* Dt */ - { pre_os, post_os }, /* Os */ - { NULL, post_sh }, /* Sh */ - { NULL, post_ignpar }, /* Ss */ - { pre_par, post_par }, /* Pp */ - { pre_display, post_d1 }, /* D1 */ - { pre_literal, post_literal }, /* Dl */ - { pre_bd, post_literal }, /* Bd */ - { NULL, NULL }, /* Ed */ - { pre_bl, post_bl }, /* Bl */ - { NULL, NULL }, /* El */ - { pre_par, post_it }, /* It */ - { NULL, NULL }, /* Ad */ - { pre_an, post_an }, /* An */ - { NULL, post_defaults }, /* Ar */ - { NULL, NULL }, /* Cd */ - { NULL, NULL }, /* Cm */ - { NULL, NULL }, /* Dv */ - { NULL, NULL }, /* Er */ - { NULL, NULL }, /* Ev */ - { pre_std, post_ex }, /* Ex */ - { NULL, post_fa }, /* Fa */ - { NULL, NULL }, /* Fd */ - { NULL, NULL }, /* Fl */ - { NULL, post_fn }, /* Fn */ - { NULL, NULL }, /* Ft */ - { NULL, NULL }, /* Ic */ - { NULL, NULL }, /* In */ - { NULL, post_defaults }, /* Li */ - { NULL, post_nd }, /* Nd */ - { NULL, post_nm }, /* Nm */ - { NULL, NULL }, /* Op */ - { pre_obsolete, NULL }, /* Ot */ - { NULL, post_defaults }, /* Pa */ - { pre_std, NULL }, /* Rv */ - { NULL, post_st }, /* St */ - { NULL, NULL }, /* Va */ - { NULL, post_vt }, /* Vt */ - { NULL, NULL }, /* Xr */ - { NULL, NULL }, /* %A */ - { NULL, post_hyph }, /* %B */ /* FIXME: can be used outside Rs/Re. */ - { NULL, NULL }, /* %D */ - { NULL, NULL }, /* %I */ - { NULL, NULL }, /* %J */ - { NULL, post_hyph }, /* %N */ - { NULL, post_hyph }, /* %O */ - { NULL, NULL }, /* %P */ - { NULL, post_hyph }, /* %R */ - { NULL, post_hyph }, /* %T */ /* FIXME: can be used outside Rs/Re. */ - { NULL, NULL }, /* %V */ - { NULL, NULL }, /* Ac */ - { NULL, NULL }, /* Ao */ - { NULL, NULL }, /* Aq */ - { NULL, post_at }, /* At */ - { NULL, NULL }, /* Bc */ - { NULL, post_bf }, /* Bf */ - { NULL, NULL }, /* Bo */ - { NULL, NULL }, /* Bq */ - { NULL, NULL }, /* Bsx */ - { NULL, post_bx }, /* Bx */ - { pre_obsolete, NULL }, /* Db */ - { NULL, NULL }, /* Dc */ - { NULL, NULL }, /* Do */ - { NULL, NULL }, /* Dq */ - { NULL, NULL }, /* Ec */ - { NULL, NULL }, /* Ef */ - { NULL, NULL }, /* Em */ - { NULL, NULL }, /* Eo */ - { NULL, NULL }, /* Fx */ - { NULL, NULL }, /* Ms */ - { NULL, NULL }, /* No */ - { NULL, post_ns }, /* Ns */ - { NULL, NULL }, /* Nx */ - { NULL, NULL }, /* Ox */ - { NULL, NULL }, /* Pc */ - { NULL, NULL }, /* Pf */ - { NULL, NULL }, /* Po */ - { NULL, NULL }, /* Pq */ - { NULL, NULL }, /* Qc */ - { NULL, NULL }, /* Ql */ - { NULL, NULL }, /* Qo */ - { NULL, NULL }, /* Qq */ - { NULL, NULL }, /* Re */ - { NULL, post_rs }, /* Rs */ - { NULL, NULL }, /* Sc */ - { NULL, NULL }, /* So */ - { NULL, NULL }, /* Sq */ - { NULL, post_sm }, /* Sm */ - { NULL, post_hyph }, /* Sx */ - { NULL, NULL }, /* Sy */ - { NULL, NULL }, /* Tn */ - { NULL, NULL }, /* Ux */ - { NULL, NULL }, /* Xc */ - { NULL, NULL }, /* Xo */ - { NULL, post_fo }, /* Fo */ - { NULL, NULL }, /* Fc */ - { NULL, NULL }, /* Oo */ - { NULL, NULL }, /* Oc */ - { NULL, post_bk }, /* Bk */ - { NULL, NULL }, /* Ek */ - { NULL, post_eoln }, /* Bt */ - { NULL, NULL }, /* Hf */ - { pre_obsolete, NULL }, /* Fr */ - { NULL, post_eoln }, /* Ud */ - { NULL, post_lb }, /* Lb */ - { pre_par, post_par }, /* Lp */ - { NULL, NULL }, /* Lk */ - { NULL, post_defaults }, /* Mt */ - { NULL, NULL }, /* Brq */ - { 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 */ +static v_post mdoc_valids[MDOC_MAX] = { + NULL, /* Ap */ + post_dd, /* Dd */ + post_dt, /* Dt */ + post_os, /* Os */ + post_sh, /* Sh */ + post_ignpar, /* Ss */ + post_par, /* Pp */ + post_display, /* D1 */ + post_display, /* Dl */ + post_display, /* Bd */ + NULL, /* Ed */ + post_bl, /* Bl */ + NULL, /* El */ + post_it, /* It */ + NULL, /* Ad */ + post_an, /* An */ + post_defaults, /* Ar */ + NULL, /* Cd */ + NULL, /* Cm */ + NULL, /* Dv */ + NULL, /* Er */ + NULL, /* Ev */ + post_ex, /* Ex */ + post_fa, /* Fa */ + NULL, /* Fd */ + NULL, /* Fl */ + post_fn, /* Fn */ + NULL, /* Ft */ + NULL, /* Ic */ + NULL, /* In */ + post_defaults, /* Li */ + post_nd, /* Nd */ + post_nm, /* Nm */ + NULL, /* Op */ + post_obsolete, /* Ot */ + post_defaults, /* Pa */ + post_rv, /* Rv */ + post_st, /* St */ + NULL, /* Va */ + NULL, /* Vt */ + post_xr, /* Xr */ + NULL, /* %A */ + post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ + NULL, /* %D */ + NULL, /* %I */ + NULL, /* %J */ + post_hyph, /* %N */ + post_hyph, /* %O */ + NULL, /* %P */ + post_hyph, /* %R */ + post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ + NULL, /* %V */ + NULL, /* Ac */ + NULL, /* Ao */ + NULL, /* Aq */ + post_at, /* At */ + NULL, /* Bc */ + post_bf, /* Bf */ + NULL, /* Bo */ + NULL, /* Bq */ + post_xx, /* Bsx */ + post_bx, /* Bx */ + post_obsolete, /* Db */ + NULL, /* Dc */ + NULL, /* Do */ + NULL, /* Dq */ + NULL, /* Ec */ + NULL, /* Ef */ + NULL, /* Em */ + NULL, /* Eo */ + post_xx, /* Fx */ + NULL, /* Ms */ + NULL, /* No */ + post_ns, /* Ns */ + post_xx, /* Nx */ + post_xx, /* Ox */ + NULL, /* Pc */ + NULL, /* Pf */ + NULL, /* Po */ + NULL, /* Pq */ + NULL, /* Qc */ + NULL, /* Ql */ + NULL, /* Qo */ + NULL, /* Qq */ + NULL, /* Re */ + post_rs, /* Rs */ + NULL, /* Sc */ + NULL, /* So */ + NULL, /* Sq */ + post_sm, /* Sm */ + post_hyph, /* Sx */ + NULL, /* Sy */ + NULL, /* Tn */ + post_xx, /* Ux */ + NULL, /* Xc */ + NULL, /* Xo */ + post_fo, /* Fo */ + NULL, /* Fc */ + NULL, /* Oo */ + NULL, /* Oc */ + post_bk, /* Bk */ + NULL, /* Ek */ + post_eoln, /* Bt */ + NULL, /* Hf */ + post_obsolete, /* Fr */ + post_eoln, /* Ud */ + post_lb, /* Lb */ + post_par, /* Lp */ + NULL, /* Lk */ + post_defaults, /* Mt */ + NULL, /* Brq */ + NULL, /* Bro */ + NULL, /* Brc */ + NULL, /* %C */ + post_es, /* Es */ + post_en, /* En */ + post_xx, /* Dx */ + NULL, /* %Q */ + post_par, /* br */ + post_par, /* sp */ + NULL, /* %U */ + NULL, /* Ta */ + NULL, /* ll */ }; #define RSORD_MAX 14 /* Number of `Rs' blocks. */ -static const enum mdoct rsord[RSORD_MAX] = { +static const int rsord[RSORD_MAX] = { MDOC__A, MDOC__T, MDOC__B, @@ -293,53 +281,37 @@ static const char * const secnames[SEC__MAX] = { 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; - switch (n->type) { - case ROFFT_TEXT: - if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) - check_text(mdoc, n->line, n->pos, n->string); - /* FALLTHROUGH */ - case ROFFT_TBL: - /* FALLTHROUGH */ - case ROFFT_EQN: - /* FALLTHROUGH */ - case ROFFT_ROOT: - return; - default: - break; + 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; } - 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; - + mdoc->last = n; + mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: - /* FALLTHROUGH */ + if (n->sec != SEC_SYNOPSIS || + (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd)) + check_text(mdoc, n->line, n->pos, n->string); + break; case ROFFT_EQN: - /* FALLTHROUGH */ case ROFFT_TBL: break; case ROFFT_ROOT: post_root(mdoc); break; default: + check_args(mdoc, mdoc->last); /* * Closing delimiters are not special at the @@ -348,21 +320,23 @@ mdoc_valid_post(struct mdoc *mdoc) */ if (n->child != NULL) - n->child->flags &= ~MDOC_DELIMC; + n->child->flags &= ~NODE_DELIMC; if (n->last != NULL) - n->last->flags &= ~MDOC_DELIMO; + n->last->flags &= ~NODE_DELIMO; /* Call the macro's postprocessor. */ - p = mdoc_valids[n->tok].post; + p = mdoc_valids + n->tok; if (*p) (*p)(mdoc); + if (mdoc->last == n) + mdoc_state(mdoc, n); break; } } static void -check_args(struct mdoc *mdoc, struct mdoc_node *n) +check_args(struct roff_man *mdoc, struct roff_node *n) { int i; @@ -375,7 +349,7 @@ check_args(struct mdoc *mdoc, struct mdoc_node *n) } 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; @@ -384,7 +358,7 @@ check_argv(struct mdoc *mdoc, struct mdoc_node *n, str } 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; @@ -397,34 +371,16 @@ check_text(struct mdoc *mdoc, int ln, int pos, char *p } static void -pre_display(PRE_ARGS) +post_bl_norm(POST_ARGS) { - struct mdoc_node *node; - - 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 roff_node *n; struct mdoc_argv *argv, *wa; int i; enum mdocargt mdoclt; enum mdoc_list lt; - if (n->type != ROFFT_BLOCK) - return; + n = mdoc->last->parent; + n->norm->Bl.type = LIST__NONE; /* * First figure out which kind of list to use: bind ourselves to @@ -550,6 +506,7 @@ pre_bl(PRE_ARGS) mandoc_msg(MANDOCERR_BL_NOTYPE, mdoc->parse, n->line, n->pos, "Bl"); n->norm->Bl.type = LIST_item; + mdoclt = MDOC_Item; } /* @@ -566,13 +523,9 @@ pre_bl(PRE_ARGS) n->line, n->pos, "Bl -tag"); break; case LIST_column: - /* FALLTHROUGH */ case LIST_diag: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_item: if (n->norm->Bl.width) mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, @@ -580,9 +533,7 @@ pre_bl(PRE_ARGS) mdoc_argnames[mdoclt]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: if (NULL == n->norm->Bl.width) n->norm->Bl.width = "2n"; @@ -594,21 +545,17 @@ pre_bl(PRE_ARGS) default: break; } - pre_par(mdoc, n); } static void -pre_bd(PRE_ARGS) +post_bd(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; int i; enum mdoc_disp dt; - pre_literal(mdoc, n); - - if (n->type != ROFFT_BLOCK) - return; - + n = mdoc->last; for (i = 0; n->args && i < (int)n->args->argc; i++) { argv = n->args->argv + i; dt = DISP__NONE; @@ -657,7 +604,6 @@ pre_bd(PRE_ARGS) break; default: abort(); - /* NOTREACHED */ } if (DISP__NONE == dt) continue; @@ -675,15 +621,20 @@ pre_bd(PRE_ARGS) n->line, n->pos, "Bd"); n->norm->Bd.type = DISP_ragged; } - pre_par(mdoc, n); } +/* + * Stand-alone line macros. + */ + static void -pre_an(PRE_ARGS) +post_an_norm(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; size_t i; + n = mdoc->last; if (n->args == NULL) return; @@ -704,73 +655,214 @@ pre_an(PRE_ARGS) } static void -pre_std(PRE_ARGS) +post_eoln(POST_ARGS) { + struct roff_node *n; - if (n->args && 1 == n->args->argc) - if (MDOC_Std == n->args->argv[0].arg) - return; + n = mdoc->last; + if (n->child != NULL) + mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, + n->line, n->pos, "%s %s", + mdoc_macronames[n->tok], n->child->string); - mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); + while (n->child != NULL) + roff_node_delete(mdoc, n->child); + + roff_word_alloc(mdoc, n->line, n->pos, n->tok == MDOC_Bt ? + "is currently in beta test." : "currently under development."); + mdoc->last->flags |= NODE_EOS | NODE_NOSRC; + mdoc->last = n; } +static int +build_list(struct roff_man *mdoc, int tok) +{ + struct roff_node *n; + int ic; + + n = mdoc->last->next; + for (ic = 1;; ic++) { + roff_elem_alloc(mdoc, n->line, n->pos, tok); + mdoc->last->flags |= NODE_NOSRC; + mdoc_node_relink(mdoc, n); + n = mdoc->last = mdoc->last->parent; + mdoc->next = ROFF_NEXT_SIBLING; + if (n->next == NULL) + return ic; + if (ic > 1 || n->next->next != NULL) { + roff_word_alloc(mdoc, n->line, n->pos, ","); + mdoc->last->flags |= NODE_DELIMC | NODE_NOSRC; + } + n = mdoc->last->next; + if (n->next == NULL) { + roff_word_alloc(mdoc, n->line, n->pos, "and"); + mdoc->last->flags |= NODE_NOSRC; + } + } +} + static void -pre_obsolete(PRE_ARGS) +post_ex(POST_ARGS) { + struct roff_node *n; + int ic; - if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) - mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); + post_std(mdoc); + + n = mdoc->last; + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, "The"); + mdoc->last->flags |= NODE_NOSRC; + + if (mdoc->last->next != NULL) + ic = build_list(mdoc, MDOC_Nm); + else if (mdoc->meta.name != NULL) { + roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Nm); + mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = mdoc->last->parent; + mdoc->next = ROFF_NEXT_SIBLING; + ic = 1; + } else { + mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse, + n->line, n->pos, "Ex"); + ic = 0; + } + + roff_word_alloc(mdoc, n->line, n->pos, + ic > 1 ? "utilities exit\\~0" : "utility exits\\~0"); + mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, + "on success, and\\~>0 if an error occurs."); + mdoc->last->flags |= NODE_EOS | NODE_NOSRC; + mdoc->last = n; } static void -pre_dt(PRE_ARGS) +post_lb(POST_ARGS) { + struct roff_node *n; + const char *p; - 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"); + n = mdoc->last; + assert(n->child->type == ROFFT_TEXT); + mdoc->next = ROFF_NEXT_CHILD; + + if ((p = mdoc_a2lib(n->child->string)) != NULL) { + n->child->flags |= NODE_NOPRT; + roff_word_alloc(mdoc, n->line, n->pos, p); + mdoc->last->flags = NODE_NOSRC; + mdoc->last = n; + return; + } + + roff_word_alloc(mdoc, n->line, n->pos, "library"); + mdoc->last->flags = NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq"); + mdoc->last->flags = NODE_DELIMO | NODE_NOSRC; + mdoc->last = mdoc->last->next; + roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq"); + mdoc->last->flags = NODE_DELIMC | NODE_NOSRC; + mdoc->last = n; } static void -pre_os(PRE_ARGS) +post_rv(POST_ARGS) { + struct roff_node *n; + int ic; - 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"); + post_std(mdoc); + + n = mdoc->last; + mdoc->next = ROFF_NEXT_CHILD; + if (n->child != NULL) { + roff_word_alloc(mdoc, n->line, n->pos, "The"); + mdoc->last->flags |= NODE_NOSRC; + ic = build_list(mdoc, MDOC_Fn); + roff_word_alloc(mdoc, n->line, n->pos, + ic > 1 ? "functions return" : "function returns"); + mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, + "the value\\~0 if successful;"); + } else + roff_word_alloc(mdoc, n->line, n->pos, "Upon successful " + "completion, the value\\~0 is returned;"); + mdoc->last->flags |= NODE_NOSRC; + + roff_word_alloc(mdoc, n->line, n->pos, "otherwise " + "the value\\~\\-1 is returned and the global variable"); + mdoc->last->flags |= NODE_NOSRC; + roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Va); + mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, "errno"); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = mdoc->last->parent; + mdoc->next = ROFF_NEXT_SIBLING; + roff_word_alloc(mdoc, n->line, n->pos, + "is set to indicate the error."); + mdoc->last->flags |= NODE_EOS | NODE_NOSRC; + mdoc->last = n; } static void -pre_dd(PRE_ARGS) +post_std(POST_ARGS) { + struct roff_node *n; - 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"); + n = mdoc->last; + if (n->args && n->args->argc == 1) + if (n->args->argv[0].arg == MDOC_Std) + return; + + mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); } static void +post_st(POST_ARGS) +{ + struct roff_node *n, *nch; + const char *p; + + n = mdoc->last; + nch = n->child; + assert(nch->type == ROFFT_TEXT); + + if ((p = mdoc_a2st(nch->string)) == NULL) { + mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, + nch->line, nch->pos, "St %s", nch->string); + roff_node_delete(mdoc, n); + return; + } + + nch->flags |= NODE_NOPRT; + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, nch->line, nch->pos, p); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last= n; +} + +static void +post_obsolete(POST_ARGS) +{ + struct roff_node *n; + + n = mdoc->last; + if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) + mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); +} + +/* + * Block macros. + */ + +static void post_bf(POST_ARGS) { - struct mdoc_node *np, *nch; - enum mdocargt arg; + struct roff_node *np, *nch; /* * Unlike other data pointers, these are "housed" by the HEAD @@ -782,45 +874,49 @@ post_bf(POST_ARGS) return; assert(np->parent->type == ROFFT_BLOCK); - assert(MDOC_Bf == np->parent->tok); + assert(np->parent->tok == MDOC_Bf); /* Check the number of arguments. */ nch = np->child; - if (NULL == np->parent->args) { - if (NULL == nch) { + if (np->parent->args == NULL) { + if (nch == NULL) { mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse, np->line, np->pos, "Bf"); return; } nch = nch->next; } - if (NULL != nch) + if (nch != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bf ... %s", nch->string); /* Extract argument into data. */ - if (np->parent->args) { - arg = np->parent->args->argv[0].arg; - if (MDOC_Emphasis == arg) + if (np->parent->args != NULL) { + switch (np->parent->args->argv[0].arg) { + case MDOC_Emphasis: np->norm->Bf.font = FONT_Em; - else if (MDOC_Literal == arg) + break; + case MDOC_Literal: np->norm->Bf.font = FONT_Li; - else if (MDOC_Symbolic == arg) + break; + case MDOC_Symbolic: np->norm->Bf.font = FONT_Sy; - else + break; + default: abort(); + } return; } /* Extract parameter into data. */ - if (0 == strcmp(np->child->string, "Em")) + if ( ! strcmp(np->child->string, "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; - else if (0 == strcmp(np->child->string, "Sy")) + else if ( ! strcmp(np->child->string, "Sy")) np->norm->Bf.font = FONT_Sy; else mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse, @@ -829,42 +925,9 @@ post_bf(POST_ARGS) } static void -post_lb(POST_ARGS) -{ - struct mdoc_node *n; - const char *stdlibname; - char *libname; - - n = mdoc->last->child; - assert(n->type == ROFFT_TEXT); - - if (NULL == (stdlibname = mdoc_a2lib(n->string))) - mandoc_asprintf(&libname, - "library \\(Lq%s\\(Rq", n->string); - else - libname = mandoc_strdup(stdlibname); - - free(n->string); - n->string = libname; -} - -static void -post_eoln(POST_ARGS) -{ - const struct mdoc_node *n; - - n = mdoc->last; - if (n->child) - mandoc_vmsg(MANDOCERR_ARG_SKIP, - mdoc->parse, n->line, n->pos, - "%s %s", mdoc_macronames[n->tok], - n->child->string); -} - -static void post_fname(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *cp; size_t pos; @@ -887,7 +950,7 @@ post_fn(POST_ARGS) static void post_fo(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; n = mdoc->last; @@ -904,7 +967,7 @@ post_fo(POST_ARGS) n->child->next->line, n->child->next->pos, "Fo ... %s", n->child->next->string); while (n->child != n->last) - mdoc_node_delete(mdoc, n->last); + roff_node_delete(mdoc, n->last); } post_fname(mdoc); @@ -913,7 +976,7 @@ post_fo(POST_ARGS) static void post_fa(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *cp; for (n = mdoc->last->child; n != NULL; n = n->next) { @@ -932,31 +995,9 @@ post_fa(POST_ARGS) } 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) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; @@ -965,26 +1006,39 @@ post_nm(POST_ARGS) n->last->tok == MDOC_Lp)) mdoc_node_relink(mdoc, n->last); - if (NULL != mdoc->meta.name) - return; + if (mdoc->meta.name == NULL) + deroff(&mdoc->meta.name, n); - mdoc_deroff(&mdoc->meta.name, n); - - if (NULL == mdoc->meta.name) + if (mdoc->meta.name == NULL || + (mdoc->lastsec == SEC_NAME && n->child == NULL)) mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, n->line, n->pos, "Nm"); + + if ((n->type != ROFFT_ELEM && n->type != ROFFT_HEAD) || + (n->child != NULL && n->child->type == ROFFT_TEXT) || + mdoc->meta.name == NULL) + return; + + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = n; } static void post_nd(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; if (n->type != ROFFT_BODY) return; + if (n->sec != SEC_NAME) + mandoc_msg(MANDOCERR_ND_LATE, mdoc->parse, + n->line, n->pos, "Nd"); + if (n->child == NULL) mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse, n->line, n->pos, "Nd"); @@ -993,48 +1047,56 @@ post_nd(POST_ARGS) } static void -post_d1(POST_ARGS) +post_display(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n, *np; n = mdoc->last; - - if (n->type != ROFFT_BODY) - return; - - if (n->child == NULL) - mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, - n->line, n->pos, "D1"); - - post_hyph(mdoc); + switch (n->type) { + case ROFFT_BODY: + if (n->end != ENDBODY_NOT) { + if (n->tok == MDOC_Bd && + n->body->parent->args == NULL) + roff_node_delete(mdoc, n); + } else if (n->child == NULL) + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); + else if (n->tok == MDOC_D1) + 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 -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) { - struct mdoc_node *nn; + struct roff_node *nn; /* * The `Ar' defaults to "file ..." if no value is provided as an @@ -1042,25 +1104,27 @@ post_defaults(POST_ARGS) * gets an empty string. */ - if (mdoc->last->child) + if (mdoc->last->child != NULL) return; nn = mdoc->last; - mdoc->next = MDOC_NEXT_CHILD; switch (nn->tok) { case MDOC_Ar: - mdoc_word_alloc(mdoc, nn->line, nn->pos, "file"); - mdoc_word_alloc(mdoc, nn->line, nn->pos, "..."); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, nn->line, nn->pos, "file"); + mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, nn->line, nn->pos, "..."); + mdoc->last->flags |= NODE_NOSRC; break; case MDOC_Pa: - /* FALLTHROUGH */ case MDOC_Mt: - mdoc_word_alloc(mdoc, nn->line, nn->pos, "~"); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, nn->line, nn->pos, "~"); + mdoc->last->flags |= NODE_NOSRC; break; default: abort(); - /* NOTREACHED */ } mdoc->last = nn; } @@ -1068,17 +1132,11 @@ post_defaults(POST_ARGS) static void post_at(POST_ARGS) { - struct mdoc_node *n; - const char *std_att; - char *att; + struct roff_node *n, *nch; + const char *att; n = mdoc->last; - if (n->child == NULL) { - mdoc->next = MDOC_NEXT_CHILD; - mdoc_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); - mdoc->last = n; - return; - } + nch = n->child; /* * If we have a child, look it up in the standard keys. If a @@ -1086,24 +1144,28 @@ post_at(POST_ARGS) * prefix "AT&T UNIX " to the existing data. */ - n = n->child; - assert(n->type == ROFFT_TEXT); - if (NULL == (std_att = mdoc_a2att(n->string))) { + att = NULL; + if (nch != NULL && ((att = mdoc_a2att(nch->string)) == NULL)) mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse, - n->line, n->pos, "At %s", n->string); - mandoc_asprintf(&att, "AT&T UNIX %s", n->string); - } else - att = mandoc_strdup(std_att); + nch->line, nch->pos, "At %s", nch->string); - free(n->string); - n->string = att; + mdoc->next = ROFF_NEXT_CHILD; + if (att != NULL) { + roff_word_alloc(mdoc, nch->line, nch->pos, att); + nch->flags |= NODE_NOPRT; + } else + roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = n; } static void post_an(POST_ARGS) { - struct mdoc_node *np, *nch; + struct roff_node *np, *nch; + post_an_norm(mdoc); + np = mdoc->last; nch = np->child; if (np->norm->An.auth == AUTH__NONE) { @@ -1119,6 +1181,7 @@ static void post_en(POST_ARGS) { + post_obsolete(mdoc); if (mdoc->last->type == ROFFT_BLOCK) mdoc->last->norm->Es = mdoc->last_es; } @@ -1127,16 +1190,54 @@ static void post_es(POST_ARGS) { + post_obsolete(mdoc); mdoc->last_es = mdoc->last; } static void +post_xx(POST_ARGS) +{ + struct roff_node *n; + const char *os; + + n = mdoc->last; + switch (n->tok) { + case MDOC_Bsx: + os = "BSD/OS"; + break; + case MDOC_Dx: + os = "DragonFly"; + break; + case MDOC_Fx: + os = "FreeBSD"; + break; + case MDOC_Nx: + os = "NetBSD"; + break; + case MDOC_Ox: + os = "OpenBSD"; + break; + case MDOC_Ux: + os = "UNIX"; + break; + default: + abort(); + } + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, os); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = n; +} + +static void post_it(POST_ARGS) { + struct roff_node *nbl, *nit, *nch; int i, cols; enum mdoc_list lt; - struct mdoc_node *nbl, *nit, *nch; + post_prevpar(mdoc); + nit = mdoc->last; if (nit->type != ROFFT_BLOCK) return; @@ -1146,13 +1247,9 @@ post_it(POST_ARGS) switch (lt) { case LIST_tag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_diag: if (nit->head->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOHEAD, @@ -1161,11 +1258,8 @@ post_it(POST_ARGS) mdoc_argnames[nbl->args->argv[0].arg]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_hyphen: if (nit->body == NULL || nit->body->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOBODY, @@ -1174,17 +1268,19 @@ post_it(POST_ARGS) mdoc_argnames[nbl->args->argv[0].arg]); /* FALLTHROUGH */ case LIST_item: - if (nit->head->child != NULL) + if ((nch = nit->head->child) != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, nit->line, nit->pos, - "It %s", nit->head->child->string); + "It %s", nch->string == NULL ? + mdoc_macronames[nch->tok] : nch->string); break; case LIST_column: cols = (int)nbl->norm->Bl.ncols; 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) i++; @@ -1201,52 +1297,37 @@ post_it(POST_ARGS) static void post_bl_block(POST_ARGS) { - struct mdoc_node *n, *ni, *nc; + struct roff_node *n, *ni, *nc; - /* - * 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). - */ + post_prevpar(mdoc); n = mdoc->last; - - if (LIST_tag == n->norm->Bl.type && - NULL == n->norm->Bl.width) { - post_bl_block_tag(mdoc); - assert(n->norm->Bl.width); - } - - for (ni = n->body->child; ni; ni = ni->next) { - if (NULL == ni->body) + for (ni = n->body->child; ni != NULL; ni = ni->next) { + if (ni->body == NULL) continue; nc = ni->body->last; - while (NULL != nc) { + while (nc != NULL) { switch (nc->tok) { case MDOC_Pp: - /* FALLTHROUGH */ case MDOC_Lp: - /* FALLTHROUGH */ case MDOC_br: break; default: nc = NULL; continue; } - if (NULL == ni->next) { + if (ni->next == NULL) { mandoc_msg(MANDOCERR_PAR_MOVE, mdoc->parse, nc->line, nc->pos, mdoc_macronames[nc->tok]); mdoc_node_relink(mdoc, nc); - } else if (0 == n->norm->Bl.comp && - LIST_column != n->norm->Bl.type) { + } else if (n->norm->Bl.comp == 0 && + n->norm->Bl.type != LIST_column) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, nc->line, nc->pos, "%s before It", mdoc_macronames[nc->tok]); - mdoc_node_delete(mdoc, nc); + roff_node_delete(mdoc, nc); } else break; nc = ni->body->last; @@ -1262,13 +1343,13 @@ void rewrite_macro2len(char **arg) { size_t width; - enum mdoct tok; + int tok; if (*arg == NULL) return; else if ( ! strcmp(*arg, "Ds")) width = 6; - else if ((tok = mdoc_hash_find(*arg)) == MDOC_MAX) + else if ((tok = mdoc_hash_find(*arg)) == TOKEN_NONE) return; else width = macro2len(tok); @@ -1278,86 +1359,22 @@ rewrite_macro2len(char **arg) } static void -post_bl_block_tag(POST_ARGS) -{ - struct mdoc_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; nn = nn->next) { - if (MDOC_It != nn->tok) - 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); - 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) { - struct mdoc_node *nbl, *nh, *nch, *nnext; + struct roff_node *nbl, *nh, *nch, *nnext; struct mdoc_argv *argv; int i, j; - nh = mdoc->last; + post_bl_norm(mdoc); + nh = mdoc->last; if (nh->norm->Bl.type != LIST_column) { if ((nch = nh->child) == NULL) return; mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bl ... %s", nch->string); while (nch != NULL) { - mdoc_node_delete(mdoc, nch); + roff_node_delete(mdoc, nch); nch = nh->child; } return; @@ -1387,7 +1404,8 @@ post_bl_head(POST_ARGS) argv = nbl->args->argv + j; 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->sz, sizeof(char *)); @@ -1398,18 +1416,17 @@ post_bl_head(POST_ARGS) argv->value[i++] = nch->string; nch->string = NULL; nnext = nch->next; - mdoc_node_delete(NULL, nch); + roff_node_delete(NULL, nch); } - nh->nchild = 0; nh->child = NULL; } static void post_bl(POST_ARGS) { - struct mdoc_node *nparent, *nprev; /* of the Bl block */ - struct mdoc_node *nblock, *nbody; /* of the Bl */ - struct mdoc_node *nchild, *nnext; /* of the Bl body */ + struct roff_node *nparent, *nprev; /* of the Bl block */ + struct roff_node *nblock, *nbody; /* of the Bl */ + struct roff_node *nchild, *nnext; /* of the Bl body */ nbody = mdoc->last; switch (nbody->type) { @@ -1424,6 +1441,8 @@ post_bl(POST_ARGS) default: return; } + if (nbody->end != ENDBODY_NOT) + return; nchild = nbody->child; if (nchild == NULL) { @@ -1432,14 +1451,44 @@ post_bl(POST_ARGS) return; } while (nchild != NULL) { + nnext = nchild->next; if (nchild->tok == MDOC_It || (nchild->tok == MDOC_Sm && - nchild->next != NULL && - nchild->next->tok == MDOC_It)) { - nchild = nchild->next; + nnext != NULL && nnext->tok == MDOC_It)) { + nchild = nnext; 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, nchild->line, nchild->pos, mdoc_macronames[nchild->tok]); @@ -1452,21 +1501,16 @@ post_bl(POST_ARGS) nblock = nbody->parent; nprev = nblock->prev; nparent = nblock->parent; - nnext = nchild->next; /* * Unlink this child. */ - assert(NULL == nchild->prev); - if (0 == --nbody->nchild) { - nbody->child = NULL; + nbody->child = nnext; + if (nnext == NULL) nbody->last = NULL; - assert(NULL == nnext); - } else { - nbody->child = nnext; + else nnext->prev = NULL; - } /* * Relink this child. @@ -1477,8 +1521,7 @@ post_bl(POST_ARGS) nchild->next = nblock; nblock->prev = nchild; - nparent->nchild++; - if (NULL == nprev) + if (nprev == NULL) nparent->child = nchild; else nprev->next = nchild; @@ -1490,21 +1533,21 @@ post_bl(POST_ARGS) static void post_bk(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; if (n->type == ROFFT_BLOCK && n->body->child == NULL) { mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, n->line, n->pos, "Bk"); - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } } static void -post_sm(struct mdoc *mdoc) +post_sm(POST_ARGS) { - struct mdoc_node *nch; + struct roff_node *nch; nch = mdoc->last->child; @@ -1534,7 +1577,7 @@ post_sm(struct mdoc *mdoc) static void post_root(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; /* Add missing prologue data. */ @@ -1561,7 +1604,8 @@ post_root(POST_ARGS) /* Check that we begin with a proper `Sh'. */ 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; if (n == NULL) @@ -1572,30 +1616,9 @@ post_root(POST_ARGS) } static void -post_st(POST_ARGS) -{ - struct mdoc_node *n, *nch; - const char *p; - - n = mdoc->last; - nch = n->child; - - assert(nch->type == ROFFT_TEXT); - - if (NULL == (p = mdoc_a2st(nch->string))) { - mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, - nch->line, nch->pos, "St %s", nch->string); - mdoc_node_delete(mdoc, n); - } else { - free(nch->string); - nch->string = mandoc_strdup(p); - } -} - -static void post_rs(POST_ARGS) { - struct mdoc_node *np, *nch, *next, *prev; + struct roff_node *np, *nch, *next, *prev; int i, j; np = mdoc->last; @@ -1632,7 +1655,7 @@ post_rs(POST_ARGS) /* * 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 * full unlink process. */ @@ -1689,7 +1712,7 @@ post_rs(POST_ARGS) static void post_hyph(POST_ARGS) { - struct mdoc_node *nch; + struct roff_node *nch; char *cp; for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { @@ -1710,7 +1733,7 @@ static void post_ns(POST_ARGS) { - if (MDOC_LINE & mdoc->last->flags) + if (mdoc->last->flags & NODE_LINE) mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse, mdoc->last->line, mdoc->last->pos, NULL); } @@ -1748,7 +1771,7 @@ post_sh(POST_ARGS) static void post_sh_name(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; int hasnm, hasnd; hasnm = hasnd = 0; @@ -1756,23 +1779,32 @@ post_sh_name(POST_ARGS) for (n = mdoc->last->child; n != NULL; n = n->next) { switch (n->tok) { 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; - break; + continue; case MDOC_Nd: hasnd = 1; if (n->next != NULL) mandoc_msg(MANDOCERR_NAMESEC_ND, mdoc->parse, n->line, n->pos, NULL); break; - case MDOC_MAX: - if (hasnm) - break; + case TOKEN_NONE: + if (n->type == ROFFT_TEXT && + n->string[0] == ',' && n->string[1] == '\0' && + n->next != NULL && n->next->tok == MDOC_Nm) { + n = n->next; + continue; + } /* FALLTHROUGH */ default: mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); - break; + continue; } + break; } if ( ! hasnm) @@ -1786,7 +1818,7 @@ post_sh_name(POST_ARGS) static void post_sh_see_also(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *name, *sec; const char *lastname, *lastsec, *lastpunct; int cmp; @@ -1794,7 +1826,9 @@ post_sh_see_also(POST_ARGS) n = mdoc->last->child; lastname = lastsec = lastpunct = 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; /* Process one .Xr node. */ @@ -1846,13 +1880,13 @@ post_sh_see_also(POST_ARGS) } 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) - if ((n->tok == MDOC_An && n->nchild) || child_an(n)) - return(1); - return(0); + if ((n->tok == MDOC_An && n->child != NULL) || child_an(n)) + return 1; + return 0; } static void @@ -1867,10 +1901,9 @@ post_sh_authors(POST_ARGS) static void post_sh_head(POST_ARGS) { - struct mdoc_node *n; - const char *goodsec; - char *secname; - enum mdoc_sec sec; + struct roff_node *nch; + const char *goodsec; + enum roff_sec sec; /* * Process a new section. Sections are either "named" or @@ -1879,21 +1912,21 @@ post_sh_head(POST_ARGS) * manual sections. */ - secname = NULL; - sec = SEC_CUSTOM; - mdoc_deroff(&secname, mdoc->last); - sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); + sec = mdoc->last->sec; /* 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, - mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + mdoc->last->line, mdoc->last->pos, "Sh %s", + 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. */ - if (SEC_SYNOPSIS == sec) { + if (sec == SEC_SYNOPSIS) { roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { @@ -1905,26 +1938,10 @@ post_sh_head(POST_ARGS) 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. */ - if (SEC_CUSTOM == sec) { - free(secname); + if (sec == SEC_CUSTOM) return; - } /* * Check whether our non-custom section is being repeated or is @@ -1934,12 +1951,12 @@ post_sh_head(POST_ARGS) if (sec == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); if (sec < mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); /* Mark the last named section. */ @@ -1947,10 +1964,8 @@ post_sh_head(POST_ARGS) /* Check particular section/manual conventions. */ - if (mdoc->meta.msec == NULL) { - free(secname); + if (mdoc->meta.msec == NULL) return; - } goodsec = NULL; switch (sec) { @@ -1960,7 +1975,6 @@ post_sh_head(POST_ARGS) goodsec = "2, 3, 4, 9"; /* FALLTHROUGH */ case SEC_RETURN_VALUES: - /* FALLTHROUGH */ case SEC_LIBRARY: if (*mdoc->meta.msec == '2') break; @@ -1976,18 +1990,32 @@ post_sh_head(POST_ARGS) goodsec = "9"; mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s for %s only", secname, goodsec); + "Sh %s for %s only", secnames[sec], goodsec); break; default: break; } - free(secname); } 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) { - struct mdoc_node *np; + struct roff_node *np; switch (mdoc->last->type) { case ROFFT_HEAD: @@ -1999,30 +2027,32 @@ post_ignpar(POST_ARGS) return; } - if (NULL != (np = mdoc->last->child)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->child) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s after %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } - if (NULL != (np = mdoc->last->last)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->last) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s at the end of %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } } 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; if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) return; @@ -2032,33 +2062,35 @@ pre_par(PRE_ARGS) * block: `Lp', `Pp', or non-compact `Bd' or `Bl'. */ - if (MDOC_Pp != mdoc->last->tok && - MDOC_Lp != mdoc->last->tok && - MDOC_br != mdoc->last->tok) + if (n->prev->tok != MDOC_Pp && + n->prev->tok != MDOC_Lp && + n->prev->tok != MDOC_br) return; - if (MDOC_Bl == n->tok && n->norm->Bl.comp) + if (n->tok == MDOC_Bl && n->norm->Bl.comp) return; - if (MDOC_Bd == n->tok && n->norm->Bd.comp) + if (n->tok == MDOC_Bd && n->norm->Bd.comp) return; - if (MDOC_It == n->tok && n->parent->norm->Bl.comp) + if (n->tok == MDOC_It && n->parent->norm->Bl.comp) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, - mdoc->last->line, mdoc->last->pos, - "%s before %s", mdoc_macronames[mdoc->last->tok], + n->prev->line, n->prev->pos, + "%s before %s", mdoc_macronames[n->prev->tok], mdoc_macronames[n->tok]); - mdoc_node_delete(mdoc, mdoc->last); + roff_node_delete(mdoc, n->prev); } static void post_par(POST_ARGS) { - struct mdoc_node *np; + struct roff_node *np; np = mdoc->last; + if (np->tok != MDOC_br && np->tok != MDOC_sp) + post_prevpar(mdoc); if (np->tok == MDOC_sp) { - if (np->nchild > 1) + if (np->child != NULL && np->child->next != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, np->child->next->line, np->child->next->pos, "sp ... %s", np->child->next->string); @@ -2067,70 +2099,53 @@ post_par(POST_ARGS) mdoc->parse, np->line, np->pos, "%s %s", mdoc_macronames[np->tok], np->child->string); - if (NULL == (np = mdoc->last->prev)) { + if ((np = mdoc->last->prev) == NULL) { np = mdoc->last->parent; - if (MDOC_Sh != np->tok && MDOC_Ss != np->tok) + if (np->tok != MDOC_Sh && np->tok != MDOC_Ss) return; - } else if (MDOC_Pp != np->tok && MDOC_Lp != np->tok && - (MDOC_br != mdoc->last->tok || - (MDOC_sp != np->tok && MDOC_br != np->tok))) + } else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp && + (mdoc->last->tok != MDOC_br || + (np->tok != MDOC_sp && np->tok != MDOC_br))) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, mdoc->last->line, mdoc->last->pos, "%s after %s", mdoc_macronames[mdoc->last->tok], mdoc_macronames[np->tok]); - mdoc_node_delete(mdoc, mdoc->last); + roff_node_delete(mdoc, mdoc->last); } 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) { - struct mdoc_node *n; + struct roff_node *n; char *datestr; - if (mdoc->meta.date) + n = mdoc->last; + n->flags |= NODE_NOPRT; + + if (mdoc->meta.date != NULL) { + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dd"); 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 (NULL == n->child || '\0' == n->child->string[0]) { + if (n->child == NULL || n->child->string[0] == '\0') { mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); - goto out; + return; } datestr = NULL; - mdoc_deroff(&datestr, n); + deroff(&datestr, n); if (mdoc->quick) mdoc->meta.date = datestr; else { @@ -2138,19 +2153,31 @@ post_dd(POST_ARGS) datestr, n->line, n->pos); free(datestr); } -out: - mdoc_node_delete(mdoc, n); } static void post_dt(POST_ARGS) { - struct mdoc_node *nn, *n; + struct roff_node *nn, *n; const char *cp; char *p; n = mdoc->last; + n->flags |= NODE_NOPRT; + if (mdoc->flags & MDOC_PBODY) { + mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse, + n->line, n->pos, "Dt"); + return; + } + + 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.msec); free(mdoc->meta.vol); @@ -2183,7 +2210,7 @@ post_dt(POST_ARGS) } } - /* Mandatory second argument: section. */ + /* Mandatory second argument: section. */ if (nn != NULL) nn = nn->next; @@ -2193,7 +2220,7 @@ post_dt(POST_ARGS) mdoc->parse, n->line, n->pos, "Dt %s", mdoc->meta.title); mdoc->meta.vol = mandoc_strdup("LOCAL"); - goto out; /* msec and arch remain NULL. */ + return; /* msec and arch remain NULL. */ } mdoc->meta.msec = mandoc_strdup(nn->string); @@ -2211,7 +2238,7 @@ post_dt(POST_ARGS) /* Optional third argument: architecture. */ if ((nn = nn->next) == NULL) - goto out; + return; for (p = nn->string; *p != '\0'; p++) *p = tolower((unsigned char)*p); @@ -2222,25 +2249,49 @@ post_dt(POST_ARGS) if ((nn = nn->next) != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nn->line, nn->pos, "Dt ... %s", nn->string); - -out: - mdoc_node_delete(mdoc, n); } static void post_bx(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n, *nch; + n = mdoc->last; + nch = n->child; + + if (nch != NULL) { + mdoc->last = nch; + nch = nch->next; + mdoc->next = ROFF_NEXT_SIBLING; + roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns); + mdoc->last->flags |= NODE_NOSRC; + mdoc->next = ROFF_NEXT_SIBLING; + } else + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, "BSD"); + mdoc->last->flags |= NODE_NOSRC; + + if (nch == NULL) { + mdoc->last = n; + return; + } + + roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns); + mdoc->last->flags |= NODE_NOSRC; + mdoc->next = ROFF_NEXT_SIBLING; + roff_word_alloc(mdoc, n->line, n->pos, "-"); + mdoc->last->flags |= NODE_NOSRC; + roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns); + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = n; + /* * Make `Bx's second argument always start with an uppercase * letter. Groff checks if it's an "accepted" term, but we just * uppercase blindly. */ - n = mdoc->last->child; - if (n && NULL != (n = n->next)) - *n->string = (char)toupper((unsigned char)*n->string); + *nch->string = (char)toupper((unsigned char)*nch->string); } static void @@ -2250,10 +2301,18 @@ post_os(POST_ARGS) struct utsname utsname; static char *defbuf; #endif - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; + n->flags |= NODE_NOPRT; + 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. * The order of precedence is: @@ -2265,20 +2324,20 @@ post_os(POST_ARGS) free(mdoc->meta.os); mdoc->meta.os = NULL; - mdoc_deroff(&mdoc->meta.os, n); + deroff(&mdoc->meta.os, n); if (mdoc->meta.os) - goto out; + return; if (mdoc->defos) { mdoc->meta.os = mandoc_strdup(mdoc->defos); - goto out; + return; } #ifdef OSNAME mdoc->meta.os = mandoc_strdup(OSNAME); #else /*!OSNAME */ - if (NULL == defbuf) { - if (-1 == uname(&utsname)) { + if (defbuf == NULL) { + if (uname(&utsname) == -1) { mandoc_msg(MANDOCERR_OS_UNAME, mdoc->parse, n->line, n->pos, "Os"); defbuf = mandoc_strdup("UNKNOWN"); @@ -2288,137 +2347,109 @@ post_os(POST_ARGS) } mdoc->meta.os = mandoc_strdup(defbuf); #endif /*!OSNAME*/ - -out: - mdoc_node_delete(mdoc, n); } -/* - * If no argument is provided, - * fill in the name of the current manual page. - */ -static void -post_ex(POST_ARGS) +enum roff_sec +mdoc_a2sec(const char *p) { - struct mdoc_node *n; - - n = mdoc->last; - - if (n->child) - return; - - if (mdoc->meta.name == NULL) { - mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse, - n->line, n->pos, "Ex"); - return; - } - - mdoc->next = MDOC_NEXT_CHILD; - mdoc_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); - mdoc->last = n; -} - -static enum mdoc_sec -a2sec(const char *p) -{ int i; for (i = 0; i < (int)SEC__MAX; 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 -macro2len(enum mdoct macro) +macro2len(int macro) { switch (macro) { case MDOC_Ad: - return(12); + return 12; case MDOC_Ao: - return(12); + return 12; case MDOC_An: - return(12); + return 12; case MDOC_Aq: - return(12); + return 12; case MDOC_Ar: - return(12); + return 12; case MDOC_Bo: - return(12); + return 12; case MDOC_Bq: - return(12); + return 12; case MDOC_Cd: - return(12); + return 12; case MDOC_Cm: - return(10); + return 10; case MDOC_Do: - return(10); + return 10; case MDOC_Dq: - return(12); + return 12; case MDOC_Dv: - return(12); + return 12; case MDOC_Eo: - return(12); + return 12; case MDOC_Em: - return(10); + return 10; case MDOC_Er: - return(17); + return 17; case MDOC_Ev: - return(15); + return 15; case MDOC_Fa: - return(12); + return 12; case MDOC_Fl: - return(10); + return 10; case MDOC_Fo: - return(16); + return 16; case MDOC_Fn: - return(16); + return 16; case MDOC_Ic: - return(10); + return 10; case MDOC_Li: - return(16); + return 16; case MDOC_Ms: - return(6); + return 6; case MDOC_Nm: - return(10); + return 10; case MDOC_No: - return(12); + return 12; case MDOC_Oo: - return(10); + return 10; case MDOC_Op: - return(14); + return 14; case MDOC_Pa: - return(32); + return 32; case MDOC_Pf: - return(12); + return 12; case MDOC_Po: - return(12); + return 12; case MDOC_Pq: - return(12); + return 12; case MDOC_Ql: - return(16); + return 16; case MDOC_Qo: - return(12); + return 12; case MDOC_So: - return(12); + return 12; case MDOC_Sq: - return(12); + return 12; case MDOC_Sy: - return(6); + return 6; case MDOC_Sx: - return(16); + return 16; case MDOC_Tn: - return(10); + return 10; case MDOC_Va: - return(12); + return 12; case MDOC_Vt: - return(12); + return 12; case MDOC_Xr: - return(10); + return 10; default: break; }; - return(0); + return 0; }