aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-05-24 14:00:39 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-05-24 14:00:39 +0000
commit99de3aa8f6c69f02b989060a0aa3ce3559333dd1 (patch)
treedd7dbf3e88a4a75b26a0ef3fbcedef06c9200043 /roff.c
parent59e079c4f7326f228823bf0f1edc8f4c969ec7d0 (diff)
downloadmandoc-99de3aa8f6c69f02b989060a0aa3ce3559333dd1.tar.gz
mandoc-99de3aa8f6c69f02b989060a0aa3ce3559333dd1.tar.zst
mandoc-99de3aa8f6c69f02b989060a0aa3ce3559333dd1.zip
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.
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/roff.c b/roff.c
index e36138c8..35e0f883 100644
--- 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)