From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from scc-mailout.scc.kit.edu (scc-mailout.scc.kit.edu [129.13.185.202]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id pA1M3VqM005285 for ; Tue, 1 Nov 2011 18:03:32 -0400 (EDT) Received: from hekate.usta.de (asta-nat.asta.uni-karlsruhe.de [172.22.63.82]) by scc-mailout-02 with esmtp (Exim 4.72 #1) id 1RLMQa-0005Jy-QC; Tue, 01 Nov 2011 23:03:28 +0100 Received: from donnerwolke.usta.de ([172.24.96.3]) by hekate.usta.de with esmtp (Exim 4.72) (envelope-from ) id 1RLMQa-0008FT-Tv; Tue, 01 Nov 2011 23:03:28 +0100 Received: from iris.usta.de ([172.24.96.5] helo=usta.de) by donnerwolke.usta.de with esmtp (Exim 4.72) (envelope-from ) id 1RLNMr-00010l-Nj; Wed, 02 Nov 2011 00:03:41 +0100 Received: from schwarze by usta.de with local (Exim 4.72) (envelope-from ) id 1RLMIG-0007Xx-6V; Tue, 01 Nov 2011 22:54:52 +0100 Date: Tue, 1 Nov 2011 22:54:51 +0100 From: Ingo Schwarze To: tech@mdocml.bsd.lv Cc: jmc@openbsd.org Subject: r.i.p. MANDOCERR_SYNTLINESCOPE Message-ID: <20111101215451.GW6817@iris.usta.de> X-Mailinglist: mdocml-tech Reply-To: tech@mdocml.bsd.lv MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, here is a long-awaited patch to fix one of the last needless fatal errors that sometimes haunt us in real-world manuals: When breaking a man(7) BLINE scope, do not error out, but instead just delete the clobbered macro from the AST. This fixes rendition(4) in Xenocara. I see no regressions. The patch is mildly tricky. In man_validate, it is too late to fix this. Consider: .SH FOO lots of stuff .TP .SH BAR That produces this AST: .SH BLOCK .SH HEAD: FOO .SH BODY lots of stuff .TP BLOCK .TP HEAD (empty, and BODY is missing, ouch) .SH BLOCK .SH HEAD: BAR The current check_bline is called while parsing the BAR BLOCK. So m->last is already pointing to BAR, and there is no reasonable way to get back to the utterly broken, incomplete TP block: prev -> child -> next -> child, and iterate the next pointers until the last? Certainly not. So the interrupted BLINE block has to be killed when starting the interrupting macro parse sequence in man_pmacro, just like it is done for interrupted ELINE macros. That gets rid of lots of hooks in man_validate.c, but requires a new parse flag for those macros losing the check_bline hook. OK? Ingo Index: libman.h =================================================================== RCS file: /cvs/src/usr.bin/mandoc/libman.h,v retrieving revision 1.30 diff -u -p -r1.30 libman.h --- libman.h 18 Sep 2011 10:25:28 -0000 1.30 +++ libman.h 1 Nov 2011 21:33:04 -0000 @@ -54,6 +54,7 @@ struct man_macro { #define MAN_FSCOPED (1 << 2) /* See blk_imp(). */ #define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */ #define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */ +#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */ }; extern const struct man_macro *const man_macros; Index: man.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/man.c,v retrieving revision 1.62 diff -u -p -r1.62 man.c --- man.c 9 Oct 2011 17:59:56 -0000 1.62 +++ man.c 1 Nov 2011 21:33:04 -0000 @@ -539,10 +539,37 @@ man_pmacro(struct man *m, int ln, char * n = n->parent; mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line, - n->pos, "%s", man_macronames[n->tok]); + n->pos, "%s breaks %s", man_macronames[tok], + man_macronames[n->tok]); man_node_delete(m, n); m->flags &= ~MAN_ELINE; + } + + /* + * Remove prior BLINE macro that is being clobbered. + */ + if ((m->flags & MAN_BLINE) && + (MAN_BSCOPE & man_macros[tok].flags)) { + n = m->last; + assert(MAN_TEXT != n->type); + + /* Remove element that didn't end BLINE, if any. */ + + if ( ! (MAN_BSCOPE & man_macros[n->tok].flags)) + n = n->parent; + + assert(MAN_HEAD == n->type); + n = n->parent; + assert(MAN_BLOCK == n->type); + assert(MAN_SCOPED & man_macros[n->tok].flags); + + mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line, + n->pos, "%s breaks %s", man_macronames[tok], + man_macronames[n->tok]); + + man_node_delete(m, n); + m->flags &= ~MAN_BLINE; } /* Index: man_macro.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/man_macro.c,v retrieving revision 1.31 diff -u -p -r1.31 man_macro.c --- man_macro.c 7 Jul 2011 04:08:01 -0000 1.31 +++ man_macro.c 1 Nov 2011 21:33:05 -0000 @@ -48,15 +48,15 @@ static void rew_warn(struct man *, const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, MAN_NSCOPED }, /* br */ - { in_line_eoln, 0 }, /* TH */ - { blk_imp, MAN_SCOPED }, /* SH */ - { blk_imp, MAN_SCOPED }, /* SS */ - { blk_imp, MAN_SCOPED | MAN_FSCOPED }, /* TP */ - { blk_imp, 0 }, /* LP */ - { blk_imp, 0 }, /* PP */ - { blk_imp, 0 }, /* P */ - { blk_imp, 0 }, /* IP */ - { blk_imp, 0 }, /* HP */ + { in_line_eoln, MAN_BSCOPE }, /* TH */ + { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */ + { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */ + { blk_imp, MAN_BSCOPE | MAN_SCOPED | MAN_FSCOPED }, /* TP */ + { blk_imp, MAN_BSCOPE }, /* LP */ + { blk_imp, MAN_BSCOPE }, /* PP */ + { blk_imp, MAN_BSCOPE }, /* P */ + { blk_imp, MAN_BSCOPE }, /* IP */ + { blk_imp, MAN_BSCOPE }, /* HP */ { in_line_eoln, MAN_SCOPED }, /* SM */ { in_line_eoln, MAN_SCOPED }, /* SB */ { in_line_eoln, 0 }, /* BI */ @@ -70,8 +70,8 @@ const struct man_macro __man_macros[MAN_ { in_line_eoln, 0 }, /* RI */ { in_line_eoln, MAN_NSCOPED }, /* na */ { in_line_eoln, MAN_NSCOPED }, /* sp */ - { in_line_eoln, 0 }, /* nf */ - { in_line_eoln, 0 }, /* fi */ + { in_line_eoln, MAN_BSCOPE }, /* nf */ + { in_line_eoln, MAN_BSCOPE }, /* fi */ { blk_close, 0 }, /* RE */ { blk_exp, MAN_EXPLICIT }, /* RS */ { in_line_eoln, 0 }, /* DT */ Index: man_validate.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/man_validate.c,v retrieving revision 1.48 diff -u -p -r1.48 man_validate.c --- man_validate.c 16 Oct 2011 12:18:32 -0000 1.48 +++ man_validate.c 1 Nov 2011 21:33:05 -0000 @@ -40,7 +40,6 @@ struct man_valid { v_check *posts; }; -static int check_bline(CHKARGS); static int check_eq0(CHKARGS); static int check_le1(CHKARGS); static int check_ge2(CHKARGS); @@ -72,20 +71,19 @@ static v_check posts_sec[] = { post_se static v_check posts_sp[] = { post_vs, check_le1, NULL }; static v_check posts_th[] = { check_ge2, check_le5, post_TH, NULL }; static v_check posts_uc[] = { post_UC, NULL }; -static v_check pres_bline[] = { check_bline, NULL }; -static v_check pres_sec[] = { check_bline, pre_sec, NULL}; +static v_check pres_sec[] = { pre_sec, NULL }; static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_br }, /* br */ - { pres_bline, posts_th }, /* TH */ + { NULL, posts_th }, /* TH */ { pres_sec, posts_sec }, /* SH */ { pres_sec, posts_sec }, /* SS */ - { pres_bline, NULL }, /* TP */ - { pres_bline, posts_par }, /* LP */ - { pres_bline, posts_par }, /* PP */ - { pres_bline, posts_par }, /* P */ - { pres_bline, NULL }, /* IP */ - { pres_bline, NULL }, /* HP */ + { NULL, NULL }, /* TP */ + { NULL, posts_par }, /* LP */ + { NULL, posts_par }, /* PP */ + { NULL, posts_par }, /* P */ + { NULL, NULL }, /* IP */ + { NULL, NULL }, /* HP */ { NULL, NULL }, /* SM */ { NULL, NULL }, /* SB */ { NULL, NULL }, /* BI */ @@ -99,8 +97,8 @@ static const struct man_valid man_valids { NULL, NULL }, /* RI */ { NULL, posts_eq0 }, /* na */ /* FIXME: should warn only. */ { NULL, posts_sp }, /* sp */ /* FIXME: should warn only. */ - { pres_bline, posts_nf }, /* nf */ - { pres_bline, posts_fi }, /* fi */ + { NULL, posts_nf }, /* nf */ + { NULL, posts_fi }, /* fi */ { NULL, NULL }, /* RE */ { NULL, posts_part }, /* RS */ { NULL, NULL }, /* DT */ @@ -346,19 +344,6 @@ check_par(CHKARGS) return(1); } - -static int -check_bline(CHKARGS) -{ - - assert( ! (MAN_ELINE & m->flags)); - if (MAN_BLINE & m->flags) { - man_nmsg(m, n, MANDOCERR_SYNTLINESCOPE); - return(0); - } - - return(1); -} static int post_TH(CHKARGS) Index: mandoc.h =================================================================== RCS file: /cvs/src/usr.bin/mandoc/mandoc.h,v retrieving revision 1.41 diff -u -p -r1.41 mandoc.h --- mandoc.h 9 Oct 2011 17:59:56 -0000 1.41 +++ mandoc.h 1 Nov 2011 21:33:05 -0000 @@ -150,7 +150,6 @@ enum mandocerr { MANDOCERR_NOTMANUAL, /* manual isn't really a manual */ MANDOCERR_COLUMNS, /* column syntax is inconsistent */ MANDOCERR_BADDISP, /* NOT IMPLEMENTED: .Bd -file */ - MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */ MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */ MANDOCERR_SYNTCHILD, /* child violates parent syntax */ MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */ Index: read.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/read.c,v retrieving revision 1.4 diff -u -p -r1.4 read.c --- read.c 9 Oct 2011 17:59:56 -0000 1.4 +++ read.c 1 Nov 2011 21:33:07 -0000 @@ -182,7 +182,6 @@ static const char * const mandocerrs[MAN "not a manual", "column syntax is inconsistent", "NOT IMPLEMENTED: .Bd -file", - "line scope broken, syntax violated", "argument count wrong, violates syntax", "child violates parent syntax", "argument count wrong, violates syntax", -- To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv