From: Ingo Schwarze <schwarze@usta.de>
To: Jan Stary <hans@stare.cz>
Cc: discuss@mdocml.bsd.lv
Subject: Re: makewhatis stuck on groffer.1
Date: Mon, 22 Apr 2019 01:03:59 +0200 [thread overview]
Message-ID: <20190421230359.GD31325@athene.usta.de> (raw)
In-Reply-To: <20190420182144.GA13786@www.stare.cz>
Hi Jan,
Jan Stary wrote on Sat, Apr 20, 2019 at 08:21:45PM +0200:
> ... and 'man groffer' also never gets to rendering it.
Wow, that ancient version of groffer.1 can barely be called a manual
page. It is low-level groff all over the place. More than 600 lines
of low-level groff code (macro definitions) in a single manual page...
That's insane.
Actually, insanity was to be expected, given that it was written
by Bernd Warken. But i wouldn't have expected it to be *that* bad.
Here is a minimal example of the specific issue you are reporting:
$ echo '.while n .break' | mandoc -Tlint | head -n 1
mandoc: <stdin>:1:10: UNSUPP: unsupported roff request: break
$ echo '.while n .break' | mandoc
[endless loop]
The commit below fixes the endless loop.
There appear to be a few more issues with that manual page that i'm
currently looking at.
Thanks for the report,
Ingo
Log Message:
-----------
Implement the roff .break request (break out of a .while loop).
Jan Stary <hans at stare dot cz> found it in an ancient groffer(1)
manual page (version 1.19) on MacOS X Mojave.
Having .break not implemented wasn't a particularly bright idea
because obviously, it tended to cause infinite loops.
Modified Files:
--------------
mandoc:
roff.7
roff.c
mandoc/regress/roff/while:
Makefile
Added Files:
-----------
mandoc/regress/roff/while:
break.in
break.out_ascii
Revision Data
-------------
Index: roff.7
===================================================================
RCS file: /home/cvs/mandoc/mandoc/roff.7,v
retrieving revision 1.111
retrieving revision 1.112
diff -Lroff.7 -Lroff.7 -u -p -r1.111 -r1.112
--- roff.7
+++ roff.7
@@ -503,10 +503,9 @@ This is a Heirloom extension and current
.It Ic \&br
Break the output line.
.It Ic \&break
-Break out of a
+Break out of the innermost
.Ic \&while
loop.
-Currently unsupported.
.It Ic \&breakchar Ar char ...
Optional line break characters.
This is a Heirloom extension and currently ignored.
Index: roff.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/roff.c,v
retrieving revision 1.363
retrieving revision 1.364
diff -Lroff.c -Lroff.c -u -p -r1.363 -r1.364
--- roff.c
+++ roff.c
@@ -133,15 +133,18 @@ struct roff {
char escape; /* escape character */
};
+/*
+ * A macro definition, condition, or ignored block.
+ */
struct roffnode {
enum roff_tok tok; /* type of node */
struct roffnode *parent; /* up one in stack */
int line; /* parse line */
int col; /* parse col */
char *name; /* node name, e.g. macro name */
- char *end; /* end-rules: custom token */
- int endspan; /* end-rules: next-line or infty */
- int rule; /* current evaluation rule */
+ char *end; /* custom end macro of the block */
+ int endspan; /* scope to: 1=eol 2=next line -1=\} */
+ int rule; /* content is: 1=evaluated 0=skipped */
};
#define ROFF_ARGS struct roff *r, /* parse ctx */ \
@@ -181,6 +184,7 @@ 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_break(ROFF_ARGS);
static int roff_cblock(ROFF_ARGS);
static int roff_cc(ROFF_ARGS);
static int roff_ccond(struct roff *, int, int);
@@ -400,7 +404,7 @@ static struct roffmac roffs[TOKEN_NONE]
{ roff_unsupp, NULL, NULL, 0 }, /* boxa */
{ roff_line_ignore, NULL, NULL, 0 }, /* bp */
{ roff_unsupp, NULL, NULL, 0 }, /* BP */
- { roff_unsupp, NULL, NULL, 0 }, /* break */
+ { roff_break, NULL, NULL, 0 }, /* break */
{ roff_line_ignore, NULL, NULL, 0 }, /* breakchar */
{ roff_line_ignore, NULL, NULL, 0 }, /* brnl */
{ roff_noarg, NULL, NULL, 0 }, /* brp */
@@ -685,7 +689,7 @@ roffhash_find(struct ohash *htab, const
/*
* Pop the current node off of the stack of roff instructions currently
- * pending.
+ * pending. Return 1 if it is a loop or 0 otherwise.
*/
static int
roffnode_pop(struct roff *r)
@@ -2002,6 +2006,10 @@ roff_cblock(ROFF_ARGS)
}
+/*
+ * Pop all nodes ending at the end of the current input line.
+ * Return the number of loops ended.
+ */
static int
roffnode_cleanscope(struct roff *r)
{
@@ -2016,6 +2024,11 @@ roffnode_cleanscope(struct roff *r)
return inloop;
}
+/*
+ * Handle the closing \} of a conditional block.
+ * Apart from generating warnings, this only pops nodes.
+ * Return the number of loops ended.
+ */
static int
roff_ccond(struct roff *r, int ln, int ppos)
{
@@ -2235,6 +2248,7 @@ roff_block_text(ROFF_ARGS)
static int
roff_cond_sub(ROFF_ARGS)
{
+ struct roffnode *bl;
char *ep;
int endloop, irc, rr;
enum roff_tok t;
@@ -2282,9 +2296,21 @@ roff_cond_sub(ROFF_ARGS)
*/
t = roff_parse(r, buf->buf, &pos, ln, ppos);
- irc |= t != TOKEN_NONE && (rr || roffs[t].flags & ROFFMAC_STRUCT) ?
- (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs) :
- rr ? ROFF_CONT : ROFF_IGN;
+ if (t == ROFF_break) {
+ if (irc & ROFF_LOOPMASK)
+ irc = ROFF_IGN | ROFF_LOOPEXIT;
+ else if (rr) {
+ for (bl = r->last; bl != NULL; bl = bl->parent) {
+ bl->rule = 0;
+ if (bl->tok == ROFF_while)
+ break;
+ }
+ }
+ } else if (t != TOKEN_NONE &&
+ (rr || roffs[t].flags & ROFFMAC_STRUCT))
+ irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs);
+ else
+ irc |= rr ? ROFF_CONT : ROFF_IGN;
return irc;
}
@@ -3479,6 +3505,17 @@ roff_als(ROFF_ARGS)
roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0);
roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0);
free(value);
+ return ROFF_IGN;
+}
+
+/*
+ * The .break request only makes sense inside conditionals,
+ * and that case is already handled in roff_cond_sub().
+ */
+static int
+roff_break(ROFF_ARGS)
+{
+ mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, pos, "break");
return ROFF_IGN;
}
Index: Makefile
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/roff/while/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/while/Makefile -Lregress/roff/while/Makefile -u -p -r1.1 -r1.2
--- regress/roff/while/Makefile
+++ regress/roff/while/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.1 2018/08/24 22:56:37 schwarze Exp $
+# $OpenBSD: Makefile,v 1.2 2019/04/21 22:43:00 schwarze Exp $
-REGRESS_TARGETS = basic badargs into nesting outof
+REGRESS_TARGETS = basic badargs break into nesting outof
LINT_TARGETS = badargs into nesting outof
# mandoc defects:
--- /dev/null
+++ regress/roff/while/break.out_ascii
@@ -0,0 +1,9 @@
+WHILE-BREAK(1) General Commands Manual WHILE-BREAK(1)
+
+N\bNA\bAM\bME\bE
+ w\bwh\bhi\bil\ble\be-\b-b\bbr\bre\bea\bak\bk - break request inside a while loop
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+ initial text 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0 final text
+
+OpenBSD April 21, 2019 OpenBSD
--- /dev/null
+++ regress/roff/while/break.in
@@ -0,0 +1,16 @@
+.\" $OpenBSD: break.in,v 1.1 2019/04/21 22:43:00 schwarze Exp $
+.Dd $Mdocdate: April 21 2019 $
+.Dt WHILE-BREAK 1
+.Os
+.Sh NAME
+.Nm while-break
+.Nd break request inside a while loop
+.Sh DESCRIPTION
+initial text
+.nr cnt 11 1
+.while n \{\
+\n-[cnt]
+.if !\n[cnt] .break
+\(en
+.\}
+final text
--
To unsubscribe send an email to discuss+unsubscribe@mandoc.bsd.lv
next prev parent reply other threads:[~2019-04-21 23:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-20 18:16 makewhatis stuck on groff.1 Jan Stary
2019-04-20 18:18 ` makewhatis stuck on groffer.1 Jan Stary
2019-04-20 18:21 ` Jan Stary
2019-04-21 23:03 ` Ingo Schwarze [this message]
2019-04-22 8:32 ` Jan Stary
2019-04-23 12:01 ` Ingo Schwarze
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190421230359.GD31325@athene.usta.de \
--to=schwarze@usta.de \
--cc=discuss@mandoc.bsd.lv \
--cc=discuss@mdocml.bsd.lv \
--cc=hans@stare.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).