tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
* r.i.p. MANDOCERR_SYNTLINESCOPE
@ 2011-11-01 21:54 Ingo Schwarze
  2011-11-07  0:55 ` Kristaps Dzonsons
  0 siblings, 1 reply; 2+ messages in thread
From: Ingo Schwarze @ 2011-11-01 21:54 UTC (permalink / raw)
  To: tech; +Cc: jmc

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-11-07  0:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-01 21:54 r.i.p. MANDOCERR_SYNTLINESCOPE Ingo Schwarze
2011-11-07  0:55 ` Kristaps Dzonsons

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).