summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--regress/roff/ce/Makefile9
-rw-r--r--regress/roff/ce/break.in33
-rw-r--r--regress/roff/ce/break.out_ascii24
-rw-r--r--regress/tbl/macro/Makefile13
-rw-r--r--regress/tbl/macro/nested.out_lint2
-rw-r--r--regress/tbl/macro/req.in30
-rw-r--r--regress/tbl/macro/req.out_ascii18
-rw-r--r--regress/tbl/macro/req.out_lint5
-rw-r--r--roff.c69
9 files changed, 160 insertions, 43 deletions
diff --git a/regress/roff/ce/Makefile b/regress/roff/ce/Makefile
index 2024bdce..2528847e 100644
--- a/regress/roff/ce/Makefile
+++ b/regress/roff/ce/Makefile
@@ -1,5 +1,10 @@
-# $OpenBSD: Makefile,v 1.1 2019/01/04 01:06:44 schwarze Exp $
+# $OpenBSD: Makefile,v 1.2 2022/04/30 18:46:16 schwarze Exp $
-REGRESS_TARGETS = basic
+REGRESS_TARGETS = basic break
+
+# mandoc defect:
+# - For now, high level macros break .ce and .rj blocks.
+
+SKIP_GROFF = break
.include <bsd.regress.mk>
diff --git a/regress/roff/ce/break.in b/regress/roff/ce/break.in
new file mode 100644
index 00000000..69dc99c4
--- /dev/null
+++ b/regress/roff/ce/break.in
@@ -0,0 +1,33 @@
+.\" $OpenBSD: break.in,v 1.1 2022/04/30 18:46:16 schwarze Exp $
+.TH CE-BREAK 1 "April 30, 2022"
+.SH NAME
+ce-break \- centering requests broken by high-level macros
+.SH DESCRIPTION
+initial
+text
+.ce 3
+Text centered with the .ce request is
+.I not
+filled.
+.rj 4
+Text adjusted to the right margin
+works in just the same way and is
+.I not
+filled either.
+.ce
+High-level macros break centering even in a
+.if 1 .I conditional
+block.
+.PP
+.nf
+Now entering
+explicit no-fill mode.
+.ce 3
+Text is still
+.I not
+filled.
+.PP
+.fi
+final
+text
+in fill mode
diff --git a/regress/roff/ce/break.out_ascii b/regress/roff/ce/break.out_ascii
new file mode 100644
index 00000000..8572cc0a
--- /dev/null
+++ b/regress/roff/ce/break.out_ascii
@@ -0,0 +1,24 @@
+CE-BREAK(1) General Commands Manual CE-BREAK(1)
+
+NNAAMMEE
+ ce-break - centering requests broken by high-level macros
+
+DDEESSCCRRIIPPTTIIOONN
+ initial text
+ Text centered with the .ce request is
+ _n_o_t filled.
+ Text adjusted to the right margin
+ works in just the same way and is
+ _n_o_t filled either.
+ High-level macros break centering even in a
+ _c_o_n_d_i_t_i_o_n_a_l block.
+
+ Now entering
+ explicit no-fill mode.
+ Text is still
+ _n_o_t
+ filled.
+
+ final text in fill mode
+
+OpenBSD April 30, 2022 CE-BREAK(1)
diff --git a/regress/tbl/macro/Makefile b/regress/tbl/macro/Makefile
index 70ec1b33..8ea4a0d6 100644
--- a/regress/tbl/macro/Makefile
+++ b/regress/tbl/macro/Makefile
@@ -1,12 +1,15 @@
-# $OpenBSD: Makefile,v 1.2 2016/08/20 14:43:40 schwarze Exp $
+# $OpenBSD: Makefile,v 1.3 2022/04/30 18:46:16 schwarze Exp $
-REGRESS_TARGETS = man nested column
-LINT_TARGETS = man nested
+REGRESS_TARGETS = column man nested req
+LINT_TARGETS = man nested req
-# trivial differences to groff-1.22.3:
+# mandoc defect:
+# mandoc(1) ignores .br inside tbl(7) code.
+
+# trivial differences to groff-1.23.0:
# .TS in a table causes a blank table line in GNU tbl(1), but not in mandoc.
# .TS in a column list causes a blank line in mandoc, but not in GNU tbl(1).
-SKIP_GROFF = nested column
+SKIP_GROFF = column nested req
.include <bsd.regress.mk>
diff --git a/regress/tbl/macro/nested.out_lint b/regress/tbl/macro/nested.out_lint
index dd044ba7..9bffbb0c 100644
--- a/regress/tbl/macro/nested.out_lint
+++ b/regress/tbl/macro/nested.out_lint
@@ -1 +1 @@
-mandoc: nested.in:13:4: UNSUPP: ignoring macro in table: TS
+mandoc: nested.in:13:2: UNSUPP: ignoring macro in table: TS
diff --git a/regress/tbl/macro/req.in b/regress/tbl/macro/req.in
new file mode 100644
index 00000000..30e1fe98
--- /dev/null
+++ b/regress/tbl/macro/req.in
@@ -0,0 +1,30 @@
+.\" $OpenBSD: req.in,v 1.1 2022/04/30 18:46:16 schwarze Exp $
+.TH TBL-MACRO-REQ 1 "April 30, 2022"
+.SH NAME
+tbl-macro-req \- requests generating nodes in a table
+.SH DESCRIPTION
+initial text
+.TS
+box tab(:);
+l | l .
+a:b:stray
+_
+c:T{
+d
+e
+T}
+.ce
+f:T{
+g
+.br
+h
+T}
+.if 1 .ce
+i:T{
+j
+.if 1 .br
+k
+T}
+.TE
+.PP
+final text
diff --git a/regress/tbl/macro/req.out_ascii b/regress/tbl/macro/req.out_ascii
new file mode 100644
index 00000000..168b1ea1
--- /dev/null
+++ b/regress/tbl/macro/req.out_ascii
@@ -0,0 +1,18 @@
+TBL-MACRO-REQ(1) General Commands Manual TBL-MACRO-REQ(1)
+
+NNAAMMEE
+ tbl-macro-req - requests generating nodes in a table
+
+DDEESSCCRRIIPPTTIIOONN
+ initial text
+
+ +--+-----+
+ |a | b |
+ +--+-----+
+ |c | d e |
+ |f | g h |
+ |i | j k |
+ +--+-----+
+ final text
+
+OpenBSD April 30, 2022 TBL-MACRO-REQ(1)
diff --git a/regress/tbl/macro/req.out_lint b/regress/tbl/macro/req.out_lint
new file mode 100644
index 00000000..26af8f71
--- /dev/null
+++ b/regress/tbl/macro/req.out_lint
@@ -0,0 +1,5 @@
+mandoc: req.in:10:5: ERROR: ignoring extra tbl data cells: stray
+mandoc: req.in:16:2: UNSUPP: ignoring macro in table: ce
+mandoc: req.in:19:2: UNSUPP: ignoring macro in table: br
+mandoc: req.in:22:8: UNSUPP: ignoring macro in table: ce
+mandoc: req.in:25:8: UNSUPP: ignoring macro in table: br
diff --git a/roff.c b/roff.c
index 0215bf4c..36587bc3 100644
--- a/roff.c
+++ b/roff.c
@@ -237,6 +237,7 @@ static enum roff_tok roff_parse(struct roff *, char *, int *,
static int roff_parsetext(struct roff *, struct buf *,
int, int *);
static int roff_renamed(ROFF_ARGS);
+static int roff_req_or_macro(ROFF_ARGS);
static int roff_return(ROFF_ARGS);
static int roff_rm(ROFF_ARGS);
static int roff_rn(ROFF_ARGS);
@@ -1905,7 +1906,6 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs, size_t len)
/*
* If a scope is open, go to the child handler for that macro,
* as it may want to preprocess before doing anything with it.
- * Don't do so if an equation is open.
*/
if (r->last) {
@@ -1913,19 +1913,27 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs, size_t len)
return (*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs);
}
- /* No scope is open. This is a new request or macro. */
-
r->options &= ~MPARSE_COMMENT;
spos = pos;
t = roff_parse(r, buf->buf, &pos, ln, ppos);
+ return roff_req_or_macro(r, t, buf, ln, spos, pos, offs);
+}
+
+/*
+ * Handle a new request or macro.
+ * May be called outside any scope or from inside a conditional scope.
+ */
+static int
+roff_req_or_macro(ROFF_ARGS) {
- /* Tables ignore most macros. */
+ /* For now, tables ignore most macros and some request. */
- if (r->tbl != NULL && (t == TOKEN_NONE || t == ROFF_TS ||
- t == ROFF_br || t == ROFF_ce || t == ROFF_rj || t == ROFF_sp)) {
+ if (r->tbl != NULL && (tok == TOKEN_NONE || tok == ROFF_TS ||
+ tok == ROFF_br || tok == ROFF_ce || tok == ROFF_rj ||
+ tok == ROFF_sp)) {
mandoc_msg(MANDOCERR_TBLMACRO,
- ln, pos, "%s", buf->buf + spos);
- if (t != TOKEN_NONE)
+ ln, ppos, "%s", buf->buf + ppos);
+ if (tok != TOKEN_NONE)
return ROFF_IGN;
while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ')
pos++;
@@ -1938,9 +1946,9 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs, size_t len)
/* For now, let high level macros abort .ce mode. */
- if (ctl && roffce_node != NULL &&
- (t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ ||
- t == ROFF_TH || t == ROFF_TS)) {
+ if (roffce_node != NULL &&
+ (tok == TOKEN_NONE || tok == ROFF_Dd || tok == ROFF_EQ ||
+ tok == ROFF_TH || tok == ROFF_TS)) {
r->man->last = roffce_node;
r->man->next = ROFF_NEXT_SIBLING;
roffce_lines = 0;
@@ -1952,12 +1960,12 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs, size_t len)
* Let the standard macro set parsers handle it.
*/
- if (t == TOKEN_NONE)
+ if (tok == TOKEN_NONE)
return ROFF_CONT;
- /* Execute a roff request or a user defined macro. */
+ /* Execute a roff request or a user-defined macro. */
- return (*roffs[t].proc)(r, t, buf, ln, spos, pos, offs);
+ return (*roffs[tok].proc)(r, tok, buf, ln, ppos, pos, offs);
}
/*
@@ -2000,8 +2008,10 @@ roff_endparse(struct roff *r)
}
/*
- * Parse a roff node's type from the input buffer. This must be in the
- * form of ".foo xxx" in the usual way.
+ * Parse the request or macro name at buf[*pos].
+ * Return ROFF_RENAMED, ROFF_USERDEF, or a ROFF_* token value.
+ * For empty, undefined, mdoc(7), and man(7) macros, return TOKEN_NONE.
+ * As a side effect, set r->current_string to the definition or to NULL.
*/
static enum roff_tok
roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos)
@@ -2393,27 +2403,18 @@ static int
roff_cond_sub(ROFF_ARGS)
{
struct roffnode *bl;
- int irc, rr;
+ int irc, rr, spos;
enum roff_tok t;
rr = 0; /* If arguments follow "\}", skip them. */
irc = roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr);
+ spos = pos;
t = roff_parse(r, buf->buf, &pos, ln, ppos);
- /* For now, let high level macros abort .ce mode. */
-
- if (roffce_node != NULL &&
- (t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ ||
- t == ROFF_TH || t == ROFF_TS)) {
- r->man->last = roffce_node;
- r->man->next = ROFF_NEXT_SIBLING;
- roffce_lines = 0;
- roffce_node = NULL;
- }
-
/*
- * Fully handle known macros when they are structurally
- * required or when the conditional evaluated to true.
+ * Handle requests and macros if the conditional evaluated
+ * to true or if they are structurally required.
+ * The .break request is always handled specially.
*/
if (t == ROFF_break) {
@@ -2426,13 +2427,11 @@ roff_cond_sub(ROFF_ARGS)
break;
}
}
- } else if (t != TOKEN_NONE &&
- (rr || roffs[t].flags & ROFFMAC_STRUCT)) {
- irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs);
+ } else if (rr || (t < TOKEN_NONE && roffs[t].flags & ROFFMAC_STRUCT)) {
+ irc |= roff_req_or_macro(r, t, buf, ln, spos, pos, offs);
if (irc & ROFF_WHILE)
irc &= ~(ROFF_LOOPCONT | ROFF_LOOPEXIT);
- } else
- irc |= rr ? ROFF_CONT : ROFF_IGN;
+ }
return irc;
}