summaryrefslogtreecommitdiffstats
path: root/roff.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2012-05-31 22:41:19 +0000
committerIngo Schwarze <schwarze@openbsd.org>2012-05-31 22:41:19 +0000
commitfcb1831f437dffe12c02a91668195e01a11fdc86 (patch)
treee597aa397ad28ab4826d3886b7d692c689d2c608 /roff.c
parentfc95c84fecdc7bc91c5a4d605c1558e1bbe6e381 (diff)
downloadmandoc-fcb1831f437dffe12c02a91668195e01a11fdc86.tar.gz
Fix blank line handling in .if.
In particular, two cases were wrong: - single-line .if with trailing whitespace gave no blank line - multiline .if with \{ but without \{\ gave no blank line While here, simplify roff_cond() by partially reordering the code. "good one" kristaps@
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/roff.c b/roff.c
index f62028ad..4f0a392a 100644
--- a/roff.c
+++ b/roff.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2011, 2012 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
@@ -778,7 +778,7 @@ roffnode_cleanscope(struct roff *r)
{
while (r->last) {
- if (--r->last->endspan < 0)
+ if (--r->last->endspan != 0)
break;
roffnode_pop(r);
}
@@ -1098,8 +1098,8 @@ roff_line_ignore(ROFF_ARGS)
static enum rofferr
roff_cond(ROFF_ARGS)
{
- int sv;
- enum roffrule rule;
+
+ roffnode_push(r, tok, NULL, ln, ppos);
/*
* An `.el' has no conditional body: it will consume the value
@@ -1109,31 +1109,11 @@ roff_cond(ROFF_ARGS)
* If we're not an `el', however, then evaluate the conditional.
*/
- rule = ROFF_el == tok ?
+ r->last->rule = ROFF_el == tok ?
(r->rstackpos < 0 ?
ROFFRULE_DENY : r->rstack[r->rstackpos--]) :
roff_evalcond(*bufp, &pos);
- sv = pos;
- while (' ' == (*bufp)[pos])
- pos++;
-
- /*
- * Roff is weird. If we have just white-space after the
- * conditional, it's considered the BODY and we exit without
- * really doing anything. Warn about this. It's probably
- * wrong.
- */
-
- if ('\0' == (*bufp)[pos] && sv != pos) {
- mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);
- return(ROFF_IGN);
- }
-
- roffnode_push(r, tok, NULL, ln, ppos);
-
- r->last->rule = rule;
-
/*
* An if-else will put the NEGATION of the current evaluated
* conditional into the stack of rules.
@@ -1156,28 +1136,39 @@ roff_cond(ROFF_ARGS)
r->last->rule = ROFFRULE_DENY;
/*
- * Determine scope. If we're invoked with "\{" trailing the
- * conditional, then we're in a multiline scope. Else our scope
- * expires on the next line.
+ * Determine scope.
+ * If there is nothing on the line after the conditional,
+ * not even whitespace, use next-line scope.
*/
- r->last->endspan = 1;
+ if ('\0' == (*bufp)[pos]) {
+ r->last->endspan = 2;
+ goto out;
+ }
+
+ while (' ' == (*bufp)[pos])
+ pos++;
+
+ /* An opening brace requests multiline scope. */
if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
r->last->endspan = -1;
pos += 2;
+ goto out;
}
/*
- * If there are no arguments on the line, the next-line scope is
- * assumed.
+ * Anything else following the conditional causes
+ * single-line scope. Warn if the scope contains
+ * nothing but trailing whitespace.
*/
if ('\0' == (*bufp)[pos])
- return(ROFF_IGN);
+ mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);
- /* Otherwise re-run the roff parser after recalculating. */
+ r->last->endspan = 1;
+out:
*offs = pos;
return(ROFF_RERUN);
}