From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from scc-mailout-kit-02.scc.kit.edu (scc-mailout-kit-02.scc.kit.edu [129.13.231.82]) by fantadrom.bsd.lv (OpenSMTPD) with ESMTP id 210f4289 for ; Sun, 21 Apr 2019 18:04:02 -0500 (EST) Received: from asta-nat.asta.uni-karlsruhe.de ([172.22.63.82] helo=hekate.usta.de) by scc-mailout-kit-02.scc.kit.edu with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (envelope-from ) id 1hILVA-0007QS-RS; Mon, 22 Apr 2019 01:04:01 +0200 Received: from donnerwolke.usta.de ([172.24.96.3]) by hekate.usta.de with esmtp (Exim 4.77) (envelope-from ) id 1hILV9-0000U9-Ho; Mon, 22 Apr 2019 01:03:59 +0200 Received: from athene.usta.de ([172.24.96.10]) by donnerwolke.usta.de with esmtp (Exim 4.84_2) (envelope-from ) id 1hILV9-000478-E0; Mon, 22 Apr 2019 01:03:59 +0200 Received: from localhost (athene.usta.de [local]) by athene.usta.de (OpenSMTPD) with ESMTPA id 393bce30; Mon, 22 Apr 2019 01:03:59 +0200 (CEST) Date: Mon, 22 Apr 2019 01:03:59 +0200 From: Ingo Schwarze To: Jan Stary Cc: discuss@mdocml.bsd.lv Subject: Re: makewhatis stuck on groffer.1 Message-ID: <20190421230359.GD31325@athene.usta.de> References: <20190420181651.GA58622@www.stare.cz> <20190420181808.GA248@www.stare.cz> <20190420182144.GA13786@www.stare.cz> X-Mailinglist: mandoc-discuss Reply-To: discuss@mandoc.bsd.lv MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: <20190420182144.GA13786@www.stare.cz> User-Agent: Mutt/1.8.0 (2017-02-23) 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: :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 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 */ }; =20 +/* + * 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=3Deol 2=3Dnext line -1=3D\} */ + int rule; /* content is: 1=3Devaluated 0=3Dskipped */ }; =20 #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=20 =20 /* * 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) =20 } =20 +/* + * 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; } =20 +/* + * 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) */ =20 t =3D roff_parse(r, buf->buf, &pos, ln, ppos); - irc |=3D t !=3D 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 =3D=3D ROFF_break) { + if (irc & ROFF_LOOPMASK) + irc =3D ROFF_IGN | ROFF_LOOPEXIT; + else if (rr) { + for (bl =3D r->last; bl !=3D NULL; bl =3D bl->parent) { + bl->rule =3D 0; + if (bl->tok =3D=3D ROFF_while) + break; + } + } + } else if (t !=3D TOKEN_NONE && + (rr || roffs[t].flags & ROFFMAC_STRUCT)) + irc |=3D (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); + else + irc |=3D rr ? ROFF_CONT : ROFF_IGN; return irc; } =20 @@ -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; } =20 Index: Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 $ =20 -REGRESS_TARGETS =3D basic badargs into nesting outof +REGRESS_TARGETS =3D basic badargs break into nesting outof LINT_TARGETS =3D badargs into nesting outof =20 # mandoc defects: --- /dev/null +++ regress/roff/while/break.out_ascii @@ -0,0 +1,9 @@ +WHILE-BREAK(1) General Commands Manual WHILE-BREA= K(1) + +N=08NA=08AM=08ME=08E + w=08wh=08hi=08il=08le=08e-=08-b=08br=08re=08ea=08ak=08k - break reque= st inside a while loop + +D=08DE=08ES=08SC=08CR=08RI=08IP=08PT=08TI=08IO=08ON=08N + initial text 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0 final text + +OpenBSD April 21, 2019 Ope= nBSD --- /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