=================================================================== RCS file: /cvs/mandoc/man_macro.c,v retrieving revision 1.117 retrieving revision 1.132 diff -u -p -r1.117 -r1.132 --- mandoc/man_macro.c 2017/05/04 17:48:28 1.117 +++ mandoc/man_macro.c 2018/08/18 20:41:54 1.132 @@ -1,7 +1,7 @@ -/* $Id: man_macro.c,v 1.117 2017/05/04 17:48:28 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.132 2018/08/18 20:41:54 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2012-2015, 2017 Ingo Schwarze + * Copyright (c) 2012-2015, 2017, 2018 Ingo Schwarze * Copyright (c) 2013 Franco Fichtner * * Permission to use, copy, modify, and distribute this software for any @@ -40,11 +40,12 @@ static int man_args(struct roff_man *, int, int *, char *, char **); static void rew_scope(struct roff_man *, enum roff_tok); -const struct man_macro __man_macros[MAN_MAX - MAN_TH] = { +static const struct man_macro man_macros[MAN_MAX - MAN_TH] = { { in_line_eoln, MAN_BSCOPE }, /* TH */ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* TP */ + { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* TQ */ { blk_imp, MAN_BSCOPE }, /* LP */ { blk_imp, MAN_BSCOPE }, /* PP */ { blk_imp, MAN_BSCOPE }, /* P */ @@ -61,7 +62,6 @@ const struct man_macro __man_macros[MAN_MAX - MAN_TH] { in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* I */ { in_line_eoln, 0 }, /* IR */ { in_line_eoln, 0 }, /* RI */ - { in_line_eoln, MAN_NSCOPED }, /* sp */ { in_line_eoln, MAN_NSCOPED }, /* nf */ { in_line_eoln, MAN_NSCOPED }, /* fi */ { blk_close, MAN_BSCOPE }, /* RE */ @@ -70,18 +70,26 @@ const struct man_macro __man_macros[MAN_MAX - MAN_TH] { in_line_eoln, 0 }, /* UC */ { in_line_eoln, MAN_NSCOPED }, /* PD */ { in_line_eoln, 0 }, /* AT */ - { in_line_eoln, 0 }, /* in */ - { in_line_eoln, 0 }, /* ft */ + { in_line_eoln, MAN_NSCOPED }, /* in */ + { blk_imp, MAN_BSCOPE }, /* SY */ + { blk_close, MAN_BSCOPE }, /* YS */ { in_line_eoln, 0 }, /* OP */ { in_line_eoln, MAN_BSCOPE }, /* EX */ { in_line_eoln, MAN_BSCOPE }, /* EE */ { blk_exp, MAN_BSCOPE }, /* UR */ { blk_close, MAN_BSCOPE }, /* UE */ - { in_line_eoln, 0 }, /* ll */ + { blk_exp, MAN_BSCOPE }, /* MT */ + { blk_close, MAN_BSCOPE }, /* ME */ }; -const struct man_macro *const man_macros = __man_macros - MAN_TH; +const struct man_macro * +man_macro(enum roff_tok tok) +{ + assert(tok >= MAN_TH && tok <= MAN_MAX); + return man_macros + (tok - MAN_TH); +} + void man_unscope(struct roff_man *man, const struct roff_node *to) { @@ -95,7 +103,7 @@ man_unscope(struct roff_man *man, const struct roff_no if (to == NULL && ! (n->flags & NODE_VALID)) { if (man->flags & (MAN_BLINE | MAN_ELINE) && - man_macros[n->tok].flags & MAN_SCOPED) { + man_macro(n->tok)->flags & MAN_SCOPED) { mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line, n->pos, "EOF breaks %s", roff_name[n->tok]); @@ -112,7 +120,7 @@ man_unscope(struct roff_man *man, const struct roff_no continue; } if (n->type == ROFFT_BLOCK && - man_macros[n->tok].fp == blk_exp) + man_macro(n->tok)->fp == blk_exp) mandoc_msg(MANDOCERR_BLK_NOEND, man->parse, n->line, n->pos, roff_name[n->tok]); @@ -176,7 +184,7 @@ rew_scope(struct roff_man *man, enum roff_tok tok) } if (tok != MAN_SH && (n->tok == MAN_SH || (tok != MAN_SS && (n->tok == MAN_SS || - man_macros[n->tok].fp == blk_exp)))) + man_macro(n->tok)->fp == blk_exp)))) return; man_unscope(man, n); n = man->last; @@ -190,10 +198,10 @@ rew_scope(struct roff_man *man, enum roff_tok tok) void blk_close(MACRO_PROT_ARGS) { - enum roff_tok ntok; + enum roff_tok ctok, ntok; const struct roff_node *nn; char *p; - int nrew, target; + int cline, cpos, nrew, target; nrew = 1; switch (tok) { @@ -217,9 +225,15 @@ blk_close(MACRO_PROT_ARGS) return; } break; + case MAN_YS: + ntok = MAN_SY; + break; case MAN_UE: ntok = MAN_UR; break; + case MAN_ME: + ntok = MAN_MT; + break; default: abort(); } @@ -232,19 +246,45 @@ blk_close(MACRO_PROT_ARGS) mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse, line, ppos, roff_name[tok]); rew_scope(man, MAN_PP); - } else { - line = man->last->line; - ppos = man->last->pos; - ntok = man->last->tok; - man_unscope(man, nn); + if (tok == MAN_RE) { + roff_elem_alloc(man, line, ppos, ROFF_br); + man->last->flags |= NODE_LINE | + NODE_VALID | NODE_ENDED; + man->next = ROFF_NEXT_SIBLING; + } + return; + } - /* Move a trailing paragraph behind the block. */ + cline = man->last->line; + cpos = man->last->pos; + ctok = man->last->tok; + man_unscope(man, nn); - if (ntok == MAN_LP || ntok == MAN_PP || ntok == MAN_P) { - *pos = strlen(buf); - blk_imp(man, ntok, line, ppos, pos, buf); - } + if (tok == MAN_RE && nn->head->aux > 0) + roff_setreg(man->roff, "an-margin", nn->head->aux, '-'); + + /* Trailing text. */ + + if (buf[*pos] != '\0') { + roff_word_alloc(man, line, ppos, buf + *pos); + man->last->flags |= NODE_DELIMC; + if (mandoc_eos(man->last->string, strlen(man->last->string))) + man->last->flags |= NODE_EOS; } + + /* Move a trailing paragraph behind the block. */ + + if (ctok == MAN_LP || ctok == MAN_PP || ctok == MAN_P) { + *pos = strlen(buf); + blk_imp(man, ctok, cline, cpos, pos, buf); + } + + /* Synopsis blocks need an explicit end marker for spacing. */ + + if (tok == MAN_YS && man->last == nn) { + roff_elem_alloc(man, line, ppos, tok); + man_unscope(man, man->last); + } } void @@ -254,13 +294,23 @@ blk_exp(MACRO_PROT_ARGS) char *p; int la; - rew_scope(man, tok); + if (tok == MAN_RS) + rew_scope(man, tok); roff_block_alloc(man, line, ppos, tok); head = roff_head_alloc(man, line, ppos, tok); la = *pos; - if (man_args(man, line, pos, buf, &p)) + if (man_args(man, line, pos, buf, &p)) { roff_word_alloc(man, line, la, p); + if (tok == MAN_RS) { + if (roff_getreg(man->roff, "an-margin") == 0) + roff_setreg(man->roff, "an-margin", + 7 * 24, '='); + if ((head->aux = strtod(p, NULL) * 24.0) > 0) + roff_setreg(man->roff, "an-margin", + head->aux, '+'); + } + } if (buf[*pos] != '\0') mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line, @@ -304,8 +354,8 @@ blk_imp(MACRO_PROT_ARGS) * For `TP', always keep the head open. */ - if (man_macros[tok].flags & MAN_SCOPED && - (tok == MAN_TP || n == man->last)) { + if (man_macro(tok)->flags & MAN_SCOPED && + (tok == MAN_TP || tok == MAN_TQ || n == man->last)) { man->flags |= MAN_BLINE; return; } @@ -333,8 +383,7 @@ in_line_eoln(MACRO_PROT_ARGS) roff_name[tok], buf + *pos); break; } - if (buf[*pos] != '\0' && man->last != n && - (tok == MAN_PD || tok == MAN_ft || tok == MAN_sp)) { + if (buf[*pos] != '\0' && man->last != n && tok == MAN_PD) { mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line, *pos, "%s ... %s", roff_name[tok], buf + *pos); @@ -343,7 +392,7 @@ in_line_eoln(MACRO_PROT_ARGS) la = *pos; if ( ! man_args(man, line, pos, buf, &p)) break; - if (man_macros[tok].flags & MAN_JOIN && + if (man_macro(tok)->flags & MAN_JOIN && man->last->type == ROFFT_TEXT) roff_word_append(man, p); else @@ -365,8 +414,8 @@ in_line_eoln(MACRO_PROT_ARGS) * waiting for terms to load into our context. */ - if (n == man->last && man_macros[tok].flags & MAN_SCOPED) { - assert( ! (man_macros[tok].flags & MAN_NSCOPED)); + if (n == man->last && man_macro(tok)->flags & MAN_SCOPED) { + assert((man_macro(tok)->flags & MAN_NSCOPED) == 0); man->flags |= MAN_ELINE; return; }