summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-12-31 07:08:12 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-12-31 07:08:12 +0000
commitc307b01e3d5709e7d34106b6fe8e98b468bf33f8 (patch)
tree939b2a1acb043c38c2dacc70855f028e163b6f42
parentc0cea6817b9d23d8e5e4a752fc1dff8dfb604cdc (diff)
downloadmandoc-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.c22
-rw-r--r--man_html.c34
-rw-r--r--man_macro.c13
-rw-r--r--man_term.c9
-rw-r--r--man_validate.c5
-rw-r--r--roff.c48
-rw-r--r--roff.h6
-rw-r--r--roff_html.c2
-rw-r--r--roff_int.h4
-rw-r--r--roff_term.c4
-rw-r--r--roff_validate.c27
11 files changed, 94 insertions, 80 deletions
diff --git a/man.c b/man.c
index 1fabb7b4..01b87835 100644
--- a/man.c
+++ b/man.c
@@ -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;
diff --git a/man_html.c b/man_html.c
index 4dd6b34a..6f102f54 100644
--- a/man_html.c
+++ b/man_html.c
@@ -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);
diff --git a/man_term.c b/man_term.c
index df8eb63e..f7e6c896 100644
--- a/man_term.c
+++ b/man_term.c
@@ -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;
diff --git a/roff.c b/roff.c
index 10cefea0..960e26b8 100644
--- a/roff.c
+++ b/roff.c
@@ -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;
diff --git a/roff.h b/roff.h
index 1cd71a08..4e485750 100644
--- a/roff.h
+++ b/roff.h
@@ -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 */
diff --git a/roff_int.h b/roff_int.h
index 9c540817..ed38f3c7 100644
--- a/roff_int.h
+++ b/roff_int.h
@@ -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;