]> git.cameronkatri.com Git - mandoc.git/commitdiff
Fix a TODO to the effect that `.if n \{\ foo .br \}' was failing due to
authorKristaps Dzonsons <kristaps@bsd.lv>
Tue, 24 May 2011 14:00:39 +0000 (14:00 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Tue, 24 May 2011 14:00:39 +0000 (14:00 +0000)
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.

TODO
roff.c

diff --git a/TODO b/TODO
index 91770fd5ab47a72b367fbc2d2e9835190b56bc91..06b9ad21cc99e9d1a4a416cfdfb8a9d982980056 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
 ************************************************************************
 * Official mandoc TODO.
-* $Id: TODO,v 1.107 2011/05/21 21:38:17 schwarze Exp $
+* $Id: TODO,v 1.108 2011/05/24 14:00:39 kristaps Exp $
 ************************************************************************
 
 ************************************************************************
 - .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
 ************************************************************************
diff --git a/roff.c b/roff.c
index e36138c830978084b07ca3c02da3fd34d205e149..35e0f883ef74eaa9ed41ab20c9eed25b2775b85f 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/*     $Id: roff.c,v 1.138 2011/05/14 16:06:08 kristaps Exp $ */
+/*     $Id: roff.c,v 1.139 2011/05/24 14:00:39 kristaps Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -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)