diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-31 07:08:12 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-31 07:08:12 +0000 |
commit | c307b01e3d5709e7d34106b6fe8e98b468bf33f8 (patch) | |
tree | 939b2a1acb043c38c2dacc70855f028e163b6f42 | |
parent | c0cea6817b9d23d8e5e4a752fc1dff8dfb604cdc (diff) | |
download | mandoc-c307b01e3d5709e7d34106b6fe8e98b468bf33f8.tar.gz |
Move parsing of the .nf and .fi (fill mode) requests from the man(7)
parser to the roff(7) parser. As a side effect, .nf and .fi are
now also parsed in mdoc(7) input, though the mdoc(7) formatters
still ignore most of their effect.
-rw-r--r-- | man.c | 22 | ||||
-rw-r--r-- | man_html.c | 34 | ||||
-rw-r--r-- | man_macro.c | 13 | ||||
-rw-r--r-- | man_term.c | 9 | ||||
-rw-r--r-- | man_validate.c | 5 | ||||
-rw-r--r-- | roff.c | 48 | ||||
-rw-r--r-- | roff.h | 6 | ||||
-rw-r--r-- | roff_html.c | 2 | ||||
-rw-r--r-- | roff_int.h | 4 | ||||
-rw-r--r-- | roff_term.c | 4 | ||||
-rw-r--r-- | roff_validate.c | 27 |
11 files changed, 94 insertions, 80 deletions
@@ -103,9 +103,9 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs) int i; char *ep; - /* Literal free-form text whitespace is preserved. */ + /* In no-fill mode, whitespace is preserved on text lines. */ - if (man->flags & MAN_LITERAL) { + if (man->flags & ROFF_NOFILL) { roff_word_alloc(man, line, offs, buf + offs); man_descope(man, line, offs, buf + offs); return 1; @@ -308,7 +308,7 @@ man_breakscope(struct roff_man *man, int tok) */ if (man->flags & MAN_BLINE && - (tok == MAN_nf || tok == MAN_fi) && + (tok == ROFF_nf || tok == ROFF_fi) && (man->last->tok == MAN_SH || man->last->tok == MAN_SS)) { n = man->last; man_unscope(man, n); @@ -322,8 +322,8 @@ man_breakscope(struct roff_man *man, int tok) * Delete the block that is being broken. */ - if (man->flags & MAN_BLINE && (tok < MAN_TH || - man_macro(tok)->flags & MAN_XSCOPE)) { + if (man->flags & MAN_BLINE && tok != ROFF_nf && tok != ROFF_fi && + (tok < MAN_TH || man_macro(tok)->flags & MAN_XSCOPE)) { n = man->last; if (n->type == ROFFT_TEXT) n = n->parent; @@ -349,18 +349,18 @@ man_state(struct roff_man *man, struct roff_node *n) { switch(n->tok) { - case MAN_nf: + case ROFF_nf: case MAN_EX: - if (man->flags & MAN_LITERAL && ! (n->flags & NODE_VALID)) + if (man->flags & ROFF_NOFILL && (n->flags & NODE_VALID) == 0) mandoc_msg(MANDOCERR_NF_SKIP, n->line, n->pos, "nf"); - man->flags |= MAN_LITERAL; + man->flags |= ROFF_NOFILL; break; - case MAN_fi: + case ROFF_fi: case MAN_EE: - if ( ! (man->flags & MAN_LITERAL) && + if ( (man->flags & ROFF_NOFILL) == 0 && ! (n->flags & NODE_VALID)) mandoc_msg(MANDOCERR_FI_SKIP, n->line, n->pos, "fi"); - man->flags &= ~MAN_LITERAL; + man->flags &= ~ROFF_NOFILL; break; default: break; @@ -94,8 +94,6 @@ static const struct man_html_act man_html_acts[MAN_MAX - MAN_TH] = { { man_I_pre, NULL }, /* I */ { man_alt_pre, NULL }, /* IR */ { man_alt_pre, NULL }, /* RI */ - { NULL, NULL }, /* nf */ - { NULL, NULL }, /* fi */ { NULL, NULL }, /* RE */ { man_RS_pre, NULL }, /* RS */ { man_ign_pre, NULL }, /* DT */ @@ -192,7 +190,7 @@ print_man_nodelist(MAN_ARGS) static void print_man_node(MAN_ARGS) { - static int want_fillmode = MAN_fi; + static int want_fillmode = ROFF_fi; static int save_fillmode; struct tag *t; @@ -204,14 +202,14 @@ print_man_node(MAN_ARGS) */ switch (n->tok) { - case MAN_nf: + case ROFF_nf: case MAN_EX: - want_fillmode = MAN_nf; + want_fillmode = ROFF_nf; return; - case MAN_fi: + case ROFF_fi: case MAN_EE: - want_fillmode = MAN_fi; - if (fillmode(h, 0) == MAN_fi) + want_fillmode = ROFF_fi; + if (fillmode(h, 0) == ROFF_fi) print_otag(h, TAG_BR, ""); return; default: @@ -232,20 +230,20 @@ print_man_node(MAN_ARGS) /* FALLTHROUGH */ case MAN_SH: /* Section headers */ case MAN_SS: /* permanently cancel .nf. */ - want_fillmode = MAN_fi; + want_fillmode = ROFF_fi; /* FALLTHROUGH */ case MAN_PP: /* These have no head. */ case MAN_RS: /* They will simply */ case MAN_UR: /* reopen .nf in the body. */ case MAN_MT: - fillmode(h, MAN_fi); + fillmode(h, ROFF_fi); break; default: break; } break; case ROFFT_TBL: - fillmode(h, MAN_fi); + fillmode(h, ROFF_fi); break; case ROFFT_ELEM: /* @@ -258,12 +256,12 @@ print_man_node(MAN_ARGS) fillmode(h, want_fillmode); break; case ROFFT_TEXT: - if (fillmode(h, want_fillmode) == MAN_fi && - want_fillmode == MAN_fi && + if (fillmode(h, want_fillmode) == ROFF_fi && + want_fillmode == ROFF_fi && n->flags & NODE_LINE && *n->string == ' ' && (h->flags & HTML_NONEWLINE) == 0) print_otag(h, TAG_BR, ""); - if (want_fillmode == MAN_nf || *n->string != '\0') + if (want_fillmode == ROFF_nf || *n->string != '\0') break; print_paragraph(h); return; @@ -336,7 +334,7 @@ print_man_node(MAN_ARGS) /* This will automatically close out any font scope. */ print_stagq(h, t); - if (fillmode(h, 0) == MAN_nf && + if (fillmode(h, 0) == ROFF_nf && n->next != NULL && n->next->flags & NODE_LINE) { /* In .nf = <pre>, print even empty lines. */ h->col++; @@ -345,7 +343,7 @@ print_man_node(MAN_ARGS) } /* - * MAN_nf switches to no-fill mode, MAN_fi to fill mode. + * ROFF_nf switches to no-fill mode, ROFF_fi to fill mode. * Other arguments do not switch. * The old mode is returned. */ @@ -359,10 +357,10 @@ fillmode(struct html *h, int want) if (pre->tag == TAG_PRE) break; - had = pre == NULL ? MAN_fi : MAN_nf; + had = pre == NULL ? ROFF_fi : ROFF_nf; if (want && want != had) { - if (want == MAN_nf) + if (want == ROFF_nf) print_otag(h, TAG_PRE, ""); else print_tagq(h, pre); diff --git a/man_macro.c b/man_macro.c index d652a431..4519da6c 100644 --- a/man_macro.c +++ b/man_macro.c @@ -63,8 +63,6 @@ static const struct man_macro man_macros[MAN_MAX - MAN_TH] = { { in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* I */ { in_line_eoln, 0 }, /* IR */ { in_line_eoln, 0 }, /* RI */ - { in_line_eoln, MAN_NSCOPED }, /* nf */ - { in_line_eoln, MAN_NSCOPED }, /* fi */ { blk_close, MAN_XSCOPE }, /* RE */ { blk_exp, MAN_XSCOPE }, /* RS */ { in_line_eoln, 0 }, /* DT */ @@ -340,9 +338,9 @@ blk_imp(MACRO_PROT_ARGS) struct roff_node *n; rew_scope(man, tok); - n = roff_block_alloc(man, line, ppos, tok); - if (n->tok == MAN_SH || n->tok == MAN_SS) - man->flags &= ~MAN_LITERAL; + if (tok == MAN_SH || tok == MAN_SS) + man->flags &= ~ROFF_NOFILL; + roff_block_alloc(man, line, ppos, tok); n = roff_head_alloc(man, line, ppos, tok); /* Add line arguments. */ @@ -384,11 +382,6 @@ in_line_eoln(MACRO_PROT_ARGS) n = man->last; for (;;) { - if (buf[*pos] != '\0' && (tok == MAN_fi || tok == MAN_nf)) { - mandoc_msg(MANDOCERR_ARG_SKIP, line, *pos, - "%s %s", roff_name[tok], buf + *pos); - break; - } if (buf[*pos] != '\0' && man->last != n && tok == MAN_PD) { mandoc_msg(MANDOCERR_ARG_EXCESS, line, *pos, "%s ... %s", roff_name[tok], buf + *pos); @@ -117,8 +117,6 @@ static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = { { pre_I, NULL, 0 }, /* I */ { pre_alternate, NULL, 0 }, /* IR */ { pre_alternate, NULL, 0 }, /* RI */ - { pre_literal, NULL, MAN_NOTEXT }, /* nf */ - { pre_literal, NULL, MAN_NOTEXT }, /* fi */ { NULL, NULL, 0 }, /* RE */ { pre_RS, post_RS, 0 }, /* RS */ { pre_DT, NULL, 0 }, /* DT */ @@ -247,7 +245,7 @@ pre_literal(DECL_ARGS) term_newln(p); - if (n->tok == MAN_nf || n->tok == MAN_EX) + if (n->tok == MAN_EX) mt->fl |= MANT_LITERAL; else mt->fl &= ~MANT_LITERAL; @@ -984,6 +982,11 @@ print_man_node(DECL_ARGS) break; } + if (n->tok == ROFF_nf) + n->tok = MAN_EX; + else if (n->tok == ROFF_fi) + n->tok = MAN_EE; + if (n->tok < ROFF_MAX) { roff_term_pre(p, n); return; diff --git a/man_validate.c b/man_validate.c index fcc28853..2aa6a244 100644 --- a/man_validate.c +++ b/man_validate.c @@ -78,8 +78,6 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = { NULL, /* I */ NULL, /* IR */ NULL, /* RI */ - NULL, /* nf */ - NULL, /* fi */ NULL, /* RE */ check_part, /* RS */ NULL, /* DT */ @@ -153,6 +151,7 @@ man_validate(struct roff_man *man) default: if (n->tok < ROFF_MAX) { roff_validate(man); + man_state(man, n); break; } assert(n->tok >= MAN_TH && n->tok < MAN_MAX); @@ -207,7 +206,7 @@ check_text(CHKARGS) { char *cp, *p; - if (MAN_LITERAL & man->flags) + if (man->flags & ROFF_NOFILL) return; cp = n->string; @@ -181,7 +181,6 @@ static int roff_als(ROFF_ARGS); static int roff_block(ROFF_ARGS); static int roff_block_text(ROFF_ARGS); static int roff_block_sub(ROFF_ARGS); -static int roff_br(ROFF_ARGS); static int roff_cblock(ROFF_ARGS); static int roff_cc(ROFF_ARGS); static int roff_ccond(struct roff *, int, int); @@ -221,6 +220,7 @@ static int roff_line_ignore(ROFF_ARGS); static void roff_man_alloc1(struct roff_man *); static void roff_man_free1(struct roff_man *); static int roff_manyarg(ROFF_ARGS); +static int roff_noarg(ROFF_ARGS); static int roff_nop(ROFF_ARGS); static int roff_nr(ROFF_ARGS); static int roff_onearg(ROFF_ARGS); @@ -257,8 +257,9 @@ static int roff_userdef(ROFF_ARGS); #define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ const char *__roff_name[MAN_MAX + 1] = { - "br", "ce", "ft", "ll", - "mc", "po", "rj", "sp", + "br", "ce", "fi", "ft", + "ll", "mc", "nf", + "po", "rj", "sp", "ta", "ti", NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", @@ -357,7 +358,6 @@ const char *__roff_name[MAN_MAX + 1] = { "HP", "SM", "SB", "BI", "IB", "BR", "RB", "R", "B", "I", "IR", "RI", - "nf", "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", "SY", "YS", "OP", @@ -367,11 +367,13 @@ const char *__roff_name[MAN_MAX + 1] = { const char *const *roff_name = __roff_name; static struct roffmac roffs[TOKEN_NONE] = { - { roff_br, NULL, NULL, 0 }, /* br */ + { roff_noarg, NULL, NULL, 0 }, /* br */ { roff_onearg, NULL, NULL, 0 }, /* ce */ + { roff_noarg, NULL, NULL, 0 }, /* fi */ { roff_onearg, NULL, NULL, 0 }, /* ft */ { roff_onearg, NULL, NULL, 0 }, /* ll */ { roff_onearg, NULL, NULL, 0 }, /* mc */ + { roff_noarg, NULL, NULL, 0 }, /* nf */ { roff_onearg, NULL, NULL, 0 }, /* po */ { roff_onearg, NULL, NULL, 0 }, /* rj */ { roff_onearg, NULL, NULL, 0 }, /* sp */ @@ -401,7 +403,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_unsupp, NULL, NULL, 0 }, /* break */ { roff_line_ignore, NULL, NULL, 0 }, /* breakchar */ { roff_line_ignore, NULL, NULL, 0 }, /* brnl */ - { roff_br, NULL, NULL, 0 }, /* brp */ + { roff_noarg, NULL, NULL, 0 }, /* brp */ { roff_line_ignore, NULL, NULL, 0 }, /* brpnl */ { roff_unsupp, NULL, NULL, 0 }, /* c2 */ { roff_cc, NULL, NULL, 0 }, /* cc */ @@ -3338,6 +3340,26 @@ roff_TS(ROFF_ARGS) } static int +roff_noarg(ROFF_ARGS) +{ + if (r->man->flags & (MAN_BLINE | MAN_ELINE)) + man_breakscope(r->man, tok); + if (tok == ROFF_brp) + tok = ROFF_br; + roff_elem_alloc(r->man, ln, ppos, tok); + if (buf->buf[pos] != '\0') + mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, + "%s %s", roff_name[tok], buf->buf + pos); + if (tok == ROFF_nf) + r->man->flags |= ROFF_NOFILL; + else if (tok == ROFF_fi) + r->man->flags &= ~ROFF_NOFILL; + r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; + r->man->next = ROFF_NEXT_SIBLING; + return ROFF_IGN; +} + +static int roff_onearg(ROFF_ARGS) { struct roff_node *n; @@ -3448,20 +3470,6 @@ roff_als(ROFF_ARGS) } static int -roff_br(ROFF_ARGS) -{ - if (r->man->flags & (MAN_BLINE | MAN_ELINE)) - man_breakscope(r->man, ROFF_br); - roff_elem_alloc(r->man, ln, ppos, ROFF_br); - if (buf->buf[pos] != '\0') - mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, - "%s %s", roff_name[tok], buf->buf + pos); - r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; - r->man->next = ROFF_NEXT_SIBLING; - return ROFF_IGN; -} - -static int roff_cc(ROFF_ARGS) { const char *p; @@ -73,9 +73,11 @@ enum roff_type { enum roff_tok { ROFF_br = 0, ROFF_ce, + ROFF_fi, ROFF_ft, ROFF_ll, ROFF_mc, + ROFF_nf, ROFF_po, ROFF_rj, ROFF_sp, @@ -160,7 +162,6 @@ enum roff_tok { ROFF_fcolor, ROFF_fdeferlig, ROFF_feature, - /* MAN_fi; ignored in mdoc(7) */ ROFF_fkern, ROFF_fl, ROFF_flig, @@ -220,7 +221,6 @@ enum roff_tok { ROFF_mso, ROFF_na, ROFF_ne, - /* MAN_nf; ignored in mdoc(7) */ ROFF_nh, ROFF_nhychar, ROFF_nm, @@ -459,8 +459,6 @@ enum roff_tok { MAN_I, MAN_IR, MAN_RI, - MAN_nf, - MAN_fi, MAN_RE, MAN_RS, MAN_DT, diff --git a/roff_html.c b/roff_html.c index fc0f2e30..809e9ff8 100644 --- a/roff_html.c +++ b/roff_html.c @@ -38,9 +38,11 @@ static void roff_html_pre_sp(ROFF_HTML_ARGS); static const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = { roff_html_pre_br, /* br */ roff_html_pre_ce, /* ce */ + roff_html_pre_br, /* fi */ roff_html_pre_ft, /* ft */ NULL, /* ll */ NULL, /* mc */ + roff_html_pre_br, /* nf */ NULL, /* po */ roff_html_pre_ce, /* rj */ roff_html_pre_sp, /* sp */ @@ -39,7 +39,7 @@ struct roff_man { struct roff_node *last_es; /* The most recent Es node. */ int quick; /* Abort parse early. */ int flags; /* Parse flags. */ -#define MDOC_LITERAL (1 << 1) /* In a literal scope. */ +#define ROFF_NOFILL (1 << 1) /* Fill mode switched off. */ #define MDOC_PBODY (1 << 2) /* In the document body. */ #define MDOC_NEWLINE (1 << 3) /* First macro/text in a line. */ #define MDOC_PHRASE (1 << 4) /* In a Bl -column phrase. */ @@ -54,7 +54,7 @@ struct roff_man { #define MDOC_PHRASEQF (1 << 13) /* Quote first word encountered. */ #define MDOC_PHRASEQL (1 << 14) /* Quote last word of this phrase. */ #define MDOC_PHRASEQN (1 << 15) /* Quote first word of the next phrase. */ -#define MAN_LITERAL MDOC_LITERAL +#define MDOC_LITERAL ROFF_NOFILL #define MAN_NEWLINE MDOC_NEWLINE enum roff_sec lastsec; /* Last section seen. */ enum roff_sec lastnamed; /* Last standard section seen. */ diff --git a/roff_term.c b/roff_term.c index d0acc4f0..e99c5633 100644 --- a/roff_term.c +++ b/roff_term.c @@ -42,9 +42,11 @@ static void roff_term_pre_ti(ROFF_TERM_ARGS); static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = { roff_term_pre_br, /* br */ roff_term_pre_ce, /* ce */ + roff_term_pre_br, /* fi */ roff_term_pre_ft, /* ft */ roff_term_pre_ll, /* ll */ roff_term_pre_mc, /* mc */ + roff_term_pre_br, /* nf */ roff_term_pre_po, /* po */ roff_term_pre_ce, /* rj */ roff_term_pre_sp, /* sp */ @@ -67,7 +69,9 @@ roff_term_pre_br(ROFF_TERM_ARGS) if (p->flags & TERMP_BRIND) { p->tcol->offset = p->tcol->rmargin; p->tcol->rmargin = p->maxrmargin; + p->trailspace = 0; p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); + p->flags |= TERMP_NOSPACE; } } diff --git a/roff_validate.c b/roff_validate.c index 0aaace13..6fb60057 100644 --- a/roff_validate.c +++ b/roff_validate.c @@ -30,15 +30,19 @@ typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); static void roff_valid_br(ROFF_VALID_ARGS); +static void roff_valid_fi(ROFF_VALID_ARGS); static void roff_valid_ft(ROFF_VALID_ARGS); +static void roff_valid_nf(ROFF_VALID_ARGS); static void roff_valid_sp(ROFF_VALID_ARGS); static const roff_valid_fp roff_valids[ROFF_MAX] = { roff_valid_br, /* br */ NULL, /* ce */ + roff_valid_fi, /* fi */ roff_valid_ft, /* ft */ NULL, /* ll */ NULL, /* mc */ + roff_valid_nf, /* nf */ NULL, /* po */ NULL, /* rj */ roff_valid_sp, /* sp */ @@ -63,10 +67,6 @@ roff_valid_br(ROFF_VALID_ARGS) { struct roff_node *np; - if (n->child != NULL) - mandoc_msg(MANDOCERR_ARG_SKIP, - n->line, n->pos, "br %s", n->child->string); - if (n->next != NULL && n->next->type == ROFFT_TEXT && *n->next->string == ' ') { mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos, @@ -92,6 +92,13 @@ roff_valid_br(ROFF_VALID_ARGS) } static void +roff_valid_fi(ROFF_VALID_ARGS) +{ + if ((man->flags & ROFF_NOFILL) == 0) + mandoc_msg(MANDOCERR_FI_SKIP, n->line, n->pos, "fi"); +} + +static void roff_valid_ft(ROFF_VALID_ARGS) { const char *cp; @@ -111,15 +118,17 @@ roff_valid_ft(ROFF_VALID_ARGS) } static void +roff_valid_nf(ROFF_VALID_ARGS) +{ + if (man->flags & ROFF_NOFILL) + mandoc_msg(MANDOCERR_NF_SKIP, n->line, n->pos, "nf"); +} + +static void roff_valid_sp(ROFF_VALID_ARGS) { struct roff_node *np; - if (n->child != NULL && n->child->next != NULL) - mandoc_msg(MANDOCERR_ARG_EXCESS, - n->child->next->line, n->child->next->pos, - "sp ... %s", n->child->next->string); - if ((np = n->prev) == NULL) return; |