[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mandoc-source
Subject:    mdocml: Fix a TODO to the effect that `.if n \{\ foo .br \}' was failing
From:       kristaps () mdocml ! bsd ! lv
Date:       2011-05-24 14:00:40
Message-ID: 201105241400.p4OE0e51016285 () krisdoz ! my ! domain
[Download RAW message or body]

Log Message:
-----------
Fix a TODO to the effect that `.if n \{\ foo .br \}' was failing due to
the `\}' not being directly after the `.br'.  Now we check for `\}' in
arbitrary parts of the line, and account for if it's escaped in funny
ways.

This behaviour diverges somewhat from groff in that the text at and
following the `\}' is lost, while groff keeps it (sort-of).  I'll add a
COMPATIBILITY note to this effect.

Modified Files:
--------------
    mdocml:
        TODO
        roff.c

Revision Data
-------------
Index: TODO
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/TODO,v
retrieving revision 1.107
retrieving revision 1.108
diff -LTODO -LTODO -u -p -r1.107 -r1.108
--- TODO
+++ TODO
@@ -10,12 +10,6 @@
 - .TP before .SH is still FATAL in man(7)
   reported by brad@  Sat, 15 Jan 2011 15:54:54 -0500
 
-- the roff parser doesn't tolerate additional characters between
-  a macro and the \} terminating a conditional block, e.g.
-  .if n \{
-  .br \}
-  reported by ulrich spoerlein  Tue, 19 Oct 2010 20:39:50 +0200
-
 ************************************************************************
 * formatter bugs
 ************************************************************************
Index: roff.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v
retrieving revision 1.138
retrieving revision 1.139
diff -Lroff.c -Lroff.c -u -p -r1.138 -r1.139
--- roff.c
+++ roff.c
@@ -840,21 +840,34 @@ roff_cond_sub(ROFF_ARGS)
 {
 	enum rofft	 t;
 	enum roffrule	 rr;
+	char		*ep;
 
 	rr = r->last->rule;
+	roffnode_cleanscope(r);
 
-	/* 
-	 * Clean out scope.  If we've closed ourselves, then don't
-	 * continue. 
+	/*
+	 * If the macro is unknown, first check if it contains a closing
+	 * delimiter `\}'.  If it does, close out our scope and return
+	 * the currently-scoped rule (ignore or continue).  Else, drop
+	 * into the currently-scoped rule.
 	 */
 
-	roffnode_cleanscope(r);
-
 	if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos))) {
-		if ('\\' == (*bufp)[pos] && '}' == (*bufp)[pos + 1])
-			return(roff_ccond
-				(r, ROFF_ccond, bufp, szp,
-				 ln, pos, pos + 2, offs));
+		/*
+		 * Jump through hoops to detect a \}, because it could
+		 * be (say) \\}, which is something completely
+		 * different.
+		 */
+		ep = &(*bufp)[pos];
+		for ( ; NULL != (ep = strchr(ep, '\\')); ep++) {
+			ep++;
+			if ('}' != *ep)
+				continue;
+			*--ep = '\0';
+			roff_ccond(r, ROFF_ccond, bufp, szp, 
+					ln, pos, pos + 2, offs);
+			break;
+		}
 		return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
 	}
 
@@ -863,6 +876,7 @@ roff_cond_sub(ROFF_ARGS)
 	 * if they're either structurally required (such as loops and
 	 * conditionals) or a closing macro.
 	 */
+
 	if (ROFFRULE_DENY == rr)
 		if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
 			if (ROFF_ccond != t)
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic