diff options
author | 2012-05-31 01:36:56 +0000 | |
---|---|---|
committer | 2012-05-31 01:36:56 +0000 | |
commit | 44f8358d10f045ee4adc5c3fbc485bf9464fc052 (patch) | |
tree | 989fc4c1aafb7eba068b38e26b8cd8b7df512d6c | |
parent | ansi (diff) | |
download | wireguard-openbsd-44f8358d10f045ee4adc5c3fbc485bf9464fc052.tar.xz wireguard-openbsd-44f8358d10f045ee4adc5c3fbc485bf9464fc052.zip |
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.
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/if.in | 18 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/if.out_ascii | 9 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 59 |
3 files changed, 50 insertions, 36 deletions
diff --git a/regress/usr.bin/mandoc/roff/cond/if.in b/regress/usr.bin/mandoc/roff/cond/if.in index 9365444b686..a9a5779d9b1 100644 --- a/regress/usr.bin/mandoc/roff/cond/if.in +++ b/regress/usr.bin/mandoc/roff/cond/if.in @@ -1,9 +1,20 @@ -.TH IF 1 "April 25, 2010" OpenBSD +.TH IF 1 "May 30, 2012" OpenBSD .SH NAME if \- the roff conditional instruction .SH DESCRIPTION .if n One-line true condition. .if t One-line false condition. +.if n +Next-line empty true condition. +.if t +Next-line empty false condition. +.br +False condition with whitespace: +.if t +True condition with whitespace: +.if n +.if n \{One-line true condition with block.\} +.if t \{One-line false condition with block.\} .br .if n \{Two-line true condition without continuation and macros.\} @@ -19,6 +30,11 @@ Two-line false condition with continuation and macros. .\} .br +.if n \{ +Two-line true condition with blank line.\} +.if t \{ +Two-line false condition with blank line.\} +.br .if n \{Outer true condition. .br .if n Inner one-line true condition. diff --git a/regress/usr.bin/mandoc/roff/cond/if.out_ascii b/regress/usr.bin/mandoc/roff/cond/if.out_ascii index dcf68bda630..3e6b5e98257 100644 --- a/regress/usr.bin/mandoc/roff/cond/if.out_ascii +++ b/regress/usr.bin/mandoc/roff/cond/if.out_ascii @@ -7,8 +7,15 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN One-line true condition. + + Next-line empty true condition. + False condition with whitespace: True condition with whitespace: + + One-line true condition with block. Two-line true condition without continuation and macros. Two-line true condition with continuation and macros. + + Two-line true condition with blank line. Outer true condition. Inner one-line true condition. Inner two-line true condition without continuation and macros. @@ -16,4 +23,4 @@ DDEESSCCRRIIPPTTIIOONN -OpenBSD April 25, 2010 IF(1) +OpenBSD May 30, 2012 IF(1) diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index fb4f7c18d7a..5dee1a8f32b 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.45 2011/10/24 21:38:56 schwarze Exp $ */ +/* $Id: roff.c,v 1.46 2012/05/31 01:36:56 schwarze Exp $ */ /* * 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 @@ -774,7 +774,7 @@ roffnode_cleanscope(struct roff *r) { while (r->last) { - if (--r->last->endspan < 0) + if (--r->last->endspan != 0) break; roffnode_pop(r); } @@ -1094,8 +1094,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 @@ -1105,31 +1105,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. @@ -1152,28 +1132,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); } |