]> git.cameronkatri.com Git - mandoc.git/commitdiff
Parse for the closing delimiter `\}' for conditionals
authorIngo Schwarze <schwarze@openbsd.org>
Thu, 27 Jun 2013 09:49:47 +0000 (09:49 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Thu, 27 Jun 2013 09:49:47 +0000 (09:49 +0000)
even when the conditional evaluated to false.

While here, reshuffle the code to reduce indentation and make it
more readable; that way, we can even trim down the comments because
it becomes obvious what the code does.

Found in zipinfo(1) - thanks to espie@ and naddy@
for making me look at that manual page.

roff.c

diff --git a/roff.c b/roff.c
index d854b49fba9bc541eb166d6ec0978cbcde6a0a49..303b0333597e0fd4ee55445908d2b9d05d67c97b 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,7 +1,7 @@
-/*     $Id: roff.c,v 1.176 2013/05/31 22:08:09 schwarze Exp $ */
+/*     $Id: roff.c,v 1.177 2013/06/27 09:49:47 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1028,57 +1028,45 @@ roff_cond_sub(ROFF_ARGS)
 
        rr = r->last->rule;
        roffnode_cleanscope(r);
+       t = roff_parse(r, *bufp, &pos);
 
        /*
-        * 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.
+        * Fully handle known macros when they are structurally
+        * required or when the conditional evaluated to true.
         */
 
-       if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos))) {
-               ep = &(*bufp)[pos];
-               for ( ; NULL != (ep = strchr(ep, '\\')); ep++) {
-                       ep++;
-                       if ('}' != *ep)
-                               continue;
-
-                       /*
-                        * Make the \} go away.
-                        * This is a little haphazard, as it's not quite
-                        * clear how nroff does this.
-                        * If we're at the end of line, then just chop
-                        * off the \} and resize the buffer.
-                        * If we aren't, then conver it to spaces.
-                        */
+       if ((ROFF_MAX != t) &&
+           (ROFF_ccond == t || ROFFRULE_ALLOW == rr ||
+            ROFFMAC_STRUCT & roffs[t].flags)) {
+               assert(roffs[t].proc);
+               return((*roffs[t].proc)(r, t, bufp, szp,
+                                       ln, ppos, pos, offs));
+       }
 
-                       if ('\0' == *(ep + 1)) {
-                               *--ep = '\0';
-                               *szp -= 2;
-                       } else
-                               *(ep - 1) = *ep = ' ';
+       /* Always check for the closing delimiter `\}'. */
 
-                       roff_ccond(r, ROFF_ccond, bufp, szp, 
-                                       ln, pos, pos + 2, offs);
-                       break;
-               }
-               return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
-       }
+       ep = &(*bufp)[pos];
+       while (NULL != (ep = strchr(ep, '\\'))) {
+               if ('}' != *(++ep))
+                       continue;
 
-       /*
-        * A denied conditional must evaluate its children if and only
-        * if they're either structurally required (such as loops and
-        * conditionals) or a closing macro.
-        */
+               /*
+                * If we're at the end of line, then just chop
+                * off the \} and resize the buffer.
+                * If we aren't, then convert it to spaces.
+                */
 
-       if (ROFFRULE_DENY == rr)
-               if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
-                       if (ROFF_ccond != t)
-                               return(ROFF_IGN);
+               if ('\0' == *(ep + 1)) {
+                       *--ep = '\0';
+                       *szp -= 2;
+               } else
+                       *(ep - 1) = *ep = ' ';
 
-       assert(roffs[t].proc);
-       return((*roffs[t].proc)(r, t, bufp, szp, 
-                               ln, ppos, pos, offs));
+               roff_ccond(r, ROFF_ccond, bufp, szp, 
+                               ln, pos, pos + 2, offs);
+               break;
+       }
+       return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
 }
 
 /* ARGSUSED */