aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-05-17 02:01:05 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-05-17 02:01:05 +0000
commit5abca976891730e3c6e4410885db9cc81d83851d (patch)
tree48f9d9957741466ce25f550c86cdc379c7ab7078
parent15243e5cbbfdbf1a9c2e95455a76e9b8df523303 (diff)
downloadmandoc-5abca976891730e3c6e4410885db9cc81d83851d.tar.gz
mandoc-5abca976891730e3c6e4410885db9cc81d83851d.tar.zst
mandoc-5abca976891730e3c6e4410885db9cc81d83851d.zip
Full support for ie/el. This completes the initial roff support.
Added test files for ie/el. Using `if 0' as a baseline for "false" roff instructions instead of `if t'.
-rw-r--r--regress/roff/ie/simple0.in12
-rw-r--r--regress/roff/ie/simple1.in11
-rw-r--r--regress/roff/ie/simple2.in11
-rw-r--r--regress/roff/ie/with-el0.in13
-rw-r--r--regress/roff/ie/with-el1.in15
-rw-r--r--regress/roff/ie/with-el2.in16
-rw-r--r--regress/roff/ie/with-el3.in23
-rw-r--r--regress/roff/ie/with-el4.in29
-rw-r--r--regress/roff/ie/with-el5.in51
-rw-r--r--regress/roff/if/line-nest.in4
-rw-r--r--regress/roff/if/multiline-free0.in4
-rw-r--r--regress/roff/if/multiline-free1.in4
-rw-r--r--regress/roff/if/multiline0.in4
-rw-r--r--regress/roff/if/multiline1.in4
-rw-r--r--regress/roff/if/multiline2.in6
-rw-r--r--regress/roff/if/multiline3.in6
-rw-r--r--regress/roff/if/simple0.in4
-rw-r--r--regress/roff/if/simple1.in4
-rw-r--r--regress/roff/if/simple2.in4
-rw-r--r--regress/roff/ig/cond0.in2
-rw-r--r--regress/roff/ig/redef0.in4
-rw-r--r--regress/roff/ig/simple0.in4
-rw-r--r--regress/roff/ig/simple2.in4
-rw-r--r--roff.77
-rw-r--r--roff.c176
25 files changed, 331 insertions, 91 deletions
diff --git a/regress/roff/ie/simple0.in b/regress/roff/ie/simple0.in
new file mode 100644
index 00000000..e9b561ee
--- /dev/null
+++ b/regress/roff/ie/simple0.in
@@ -0,0 +1,12 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.\}
+fdsa
diff --git a/regress/roff/ie/simple1.in b/regress/roff/ie/simple1.in
new file mode 100644
index 00000000..b0af13bc
--- /dev/null
+++ b/regress/roff/ie/simple1.in
@@ -0,0 +1,11 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \
+1
+fdsa
diff --git a/regress/roff/ie/simple2.in b/regress/roff/ie/simple2.in
new file mode 100644
index 00000000..e4da435f
--- /dev/null
+++ b/regress/roff/ie/simple2.in
@@ -0,0 +1,11 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0
+1
+fdsa
diff --git a/regress/roff/ie/with-el0.in b/regress/roff/ie/with-el0.in
new file mode 100644
index 00000000..ba54605d
--- /dev/null
+++ b/regress/roff/ie/with-el0.in
@@ -0,0 +1,13 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \
+1
+.el \
+2
+fdsa
diff --git a/regress/roff/ie/with-el1.in b/regress/roff/ie/with-el1.in
new file mode 100644
index 00000000..522fba16
--- /dev/null
+++ b/regress/roff/ie/with-el1.in
@@ -0,0 +1,15 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+2
+.\}
+.el \
+3
+fdsa
diff --git a/regress/roff/ie/with-el2.in b/regress/roff/ie/with-el2.in
new file mode 100644
index 00000000..3b8da03e
--- /dev/null
+++ b/regress/roff/ie/with-el2.in
@@ -0,0 +1,16 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
diff --git a/regress/roff/ie/with-el3.in b/regress/roff/ie/with-el3.in
new file mode 100644
index 00000000..951de4a0
--- /dev/null
+++ b/regress/roff/ie/with-el3.in
@@ -0,0 +1,23 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
diff --git a/regress/roff/ie/with-el4.in b/regress/roff/ie/with-el4.in
new file mode 100644
index 00000000..5d0398b6
--- /dev/null
+++ b/regress/roff/ie/with-el4.in
@@ -0,0 +1,29 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
+.el \
+3
+fdsa
+.el \
+3
+fdsa
diff --git a/regress/roff/ie/with-el5.in b/regress/roff/ie/with-el5.in
new file mode 100644
index 00000000..fab16623
--- /dev/null
+++ b/regress/roff/ie/with-el5.in
@@ -0,0 +1,51 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
+.el \
+3
+fdsa
+.el \
+3
+fdsa
diff --git a/regress/roff/if/line-nest.in b/regress/roff/if/line-nest.in
index a1c50ad7..8c56b4d2 100644
--- a/regress/roff/if/line-nest.in
+++ b/regress/roff/if/line-nest.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,6 +6,6 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t .if t \
+.if 0 .if 0 \
fdsa
asdf
diff --git a/regress/roff/if/multiline-free0.in b/regress/roff/if/multiline-free0.in
index f5f1f99a..cdf9f384 100644
--- a/regress/roff/if/multiline-free0.in
+++ b/regress/roff/if/multiline-free0.in
@@ -1,10 +1,10 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
.Nm foo
.Nd bar
.Sh DESCRIPTION
-.if t \{\
+.if 0 \{\
there \} dude
fdsa
diff --git a/regress/roff/if/multiline-free1.in b/regress/roff/if/multiline-free1.in
index 5726e718..2efa12c8 100644
--- a/regress/roff/if/multiline-free1.in
+++ b/regress/roff/if/multiline-free1.in
@@ -1,11 +1,11 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
.Nm foo
.Nd bar
.Sh DESCRIPTION
-.if t \{\
+.if 0 \{\
there \\} dude
.\}
fdsa
diff --git a/regress/roff/if/multiline0.in b/regress/roff/if/multiline0.in
index def3c8df..3d12093a 100644
--- a/regress/roff/if/multiline0.in
+++ b/regress/roff/if/multiline0.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,7 +6,7 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{\
+.if 0 \{\
asdf
.\}
fdsa
diff --git a/regress/roff/if/multiline1.in b/regress/roff/if/multiline1.in
index 549d3b03..0f850cab 100644
--- a/regress/roff/if/multiline1.in
+++ b/regress/roff/if/multiline1.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,7 +6,7 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \
+.if 0 \
\{\
asdf
.\}
diff --git a/regress/roff/if/multiline2.in b/regress/roff/if/multiline2.in
index e7f014ab..f41e4363 100644
--- a/regress/roff/if/multiline2.in
+++ b/regress/roff/if/multiline2.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,9 +6,9 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{\
+.if 0 \{\
asdf
-. if t \{\
+. if 0 \{\
shmoop moop
. \}
.\}
diff --git a/regress/roff/if/multiline3.in b/regress/roff/if/multiline3.in
index 2c6b361b..4526464d 100644
--- a/regress/roff/if/multiline3.in
+++ b/regress/roff/if/multiline3.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,9 +6,9 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{ .if t
+.if 0 \{ .if 0
asdf
-. if t \{\
+. if 0 \{\
shmoop moop
. \}
.\}
diff --git a/regress/roff/if/simple0.in b/regress/roff/if/simple0.in
index d6ebe5b7..cda036cf 100644
--- a/regress/roff/if/simple0.in
+++ b/regress/roff/if/simple0.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -6,5 +6,5 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \
+.if 0 \
asdf
diff --git a/regress/roff/if/simple1.in b/regress/roff/if/simple1.in
index 12e16ed5..e797ee98 100644
--- a/regress/roff/if/simple1.in
+++ b/regress/roff/if/simple1.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -7,5 +7,5 @@
.Sh DESCRIPTION
123
.\" Note this has no whitespace...
-.if t
+.if 0
asdf
diff --git a/regress/roff/if/simple2.in b/regress/roff/if/simple2.in
index fa4ae978..986636b2 100644
--- a/regress/roff/if/simple2.in
+++ b/regress/roff/if/simple2.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -7,5 +7,5 @@
.Sh DESCRIPTION
123
.\" Note that this has whitespace...
-.if t
+.if 0
asdf
diff --git a/regress/roff/ig/cond0.in b/regress/roff/ig/cond0.in
index 993e31a5..80121f11 100644
--- a/regress/roff/ig/cond0.in
+++ b/regress/roff/ig/cond0.in
@@ -10,7 +10,7 @@
.Nd bar
.Sh DESCRIPTION
garglebats!
-.if t \
+.if 0 \
.ig .
foo
..
diff --git a/regress/roff/ig/redef0.in b/regress/roff/ig/redef0.in
index 452dbc31..8e344615 100644
--- a/regress/roff/ig/redef0.in
+++ b/regress/roff/ig/redef0.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -8,6 +8,6 @@
a
.ig if
asdf
-.if t \
+.if 0 \
b
c
diff --git a/regress/roff/ig/simple0.in b/regress/roff/ig/simple0.in
index 2598b392..743de75f 100644
--- a/regress/roff/ig/simple0.in
+++ b/regress/roff/ig/simple0.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -8,5 +8,5 @@
123
.ig
hello
-..
+.0
12124
diff --git a/regress/roff/ig/simple2.in b/regress/roff/ig/simple2.in
index 856debbf..d7ca4f5f 100644
--- a/regress/roff/ig/simple2.in
+++ b/regress/roff/ig/simple2.in
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: May 16 2010 $
+.Dd $Mdocdate: May 17 2010 $
.Dt FOO 1
.Os
.Sh NAME
@@ -8,7 +8,7 @@
123
.ig
hello
-.if t \{\
+.if 0 \{\
hello
.\}
..
diff --git a/roff.7 b/roff.7
index 276704db..4c160d9a 100644
--- a/roff.7
+++ b/roff.7
@@ -1,4 +1,4 @@
-.\" $Id: roff.7,v 1.3 2010/05/17 00:37:26 kristaps Exp $
+.\" $Id: roff.7,v 1.4 2010/05/17 02:01:05 kristaps Exp $
.\"
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -228,6 +228,11 @@ Historic groff did not accept white-space buffering the custom END tag
for the
.Sx \&ig
macro.
+.It
+The
+.Sx \&if
+and family would print funny white-spaces with historic groff when
+depending on next-line syntax.
.El
.Sh AUTHORS
The
diff --git a/roff.c b/roff.c
index a3c9c60b..7c8512d9 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.81 2010/05/17 00:46:35 kristaps Exp $ */
+/* $Id: roff.c,v 1.82 2010/05/17 02:01:05 kristaps Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -26,6 +26,8 @@
#include "mandoc.h"
#include "roff.h"
+#define RSTACK_MAX 128
+
#define ROFF_CTL(c) \
('.' == (c) || '\'' == (c))
@@ -36,26 +38,26 @@ enum rofft {
ROFF_de,
ROFF_dei,
ROFF_de1,
+ ROFF_el,
+ ROFF_ie,
ROFF_if,
ROFF_ig,
ROFF_cblock,
ROFF_ccond,
-#if 0
- ROFF_ie,
- ROFF_el,
-#endif
ROFF_MAX
};
+enum roffrule {
+ ROFFRULE_ALLOW,
+ ROFFRULE_DENY
+};
+
struct roff {
struct roffnode *last; /* leaf of stack */
mandocmsg msg; /* err/warn/fatal messages */
void *data; /* privdata for messages */
-};
-
-enum roffrule {
- ROFFRULE_ALLOW,
- ROFFRULE_DENY
+ enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */
+ int rstackpos; /* position in rstack */
};
struct roffnode {
@@ -65,7 +67,7 @@ struct roffnode {
int col; /* parse col */
char *end; /* end-rules: custom token */
int endspan; /* end-rules: next-line or infty */
- enum roffrule rule;
+ enum roffrule rule; /* current evaluation rule */
};
#define ROFF_ARGS struct roff *r, /* parse ctx */ \
@@ -93,9 +95,9 @@ static enum rofferr roff_block_text(ROFF_ARGS);
static enum rofferr roff_block_sub(ROFF_ARGS);
static enum rofferr roff_cblock(ROFF_ARGS);
static enum rofferr roff_ccond(ROFF_ARGS);
-static enum rofferr roff_if(ROFF_ARGS);
-static enum rofferr roff_if_text(ROFF_ARGS);
-static enum rofferr roff_if_sub(ROFF_ARGS);
+static enum rofferr roff_cond(ROFF_ARGS);
+static enum rofferr roff_cond_text(ROFF_ARGS);
+static enum rofferr roff_cond_sub(ROFF_ARGS);
const struct roffmac roffs[ROFF_MAX] = {
{ "am", roff_block, roff_block_text, roff_block_sub, 0 },
@@ -104,7 +106,9 @@ const struct roffmac roffs[ROFF_MAX] = {
{ "de", roff_block, roff_block_text, roff_block_sub, 0 },
{ "dei", roff_block, roff_block_text, roff_block_sub, 0 },
{ "de1", roff_block, roff_block_text, roff_block_sub, 0 },
- { "if", roff_if, roff_if_text, roff_if_sub, ROFFMAC_STRUCT },
+ { "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
+ { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
+ { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
{ "ig", roff_block, roff_block_text, roff_block_sub, 0 },
{ ".", roff_cblock, NULL, NULL, 0 },
{ "\\}", roff_ccond, NULL, NULL, 0 },
@@ -149,6 +153,11 @@ roffnode_pop(struct roff *r)
assert(r->last);
p = r->last;
+
+ if (ROFF_el == p->tok)
+ if (r->rstackpos > -1)
+ r->rstackpos--;
+
r->last = r->last->parent;
if (p->end)
free(p->end);
@@ -219,6 +228,7 @@ roff_alloc(const mandocmsg msg, void *data)
r->msg = msg;
r->data = data;
+ r->rstackpos = -1;
return(r);
}
@@ -306,7 +316,7 @@ roff_parse(const char *buf, int *pos)
for (j = 0; j < 4; j++, (*pos)++)
if ('\0' == (mac[j] = buf[*pos]))
break;
- else if (' ' == buf[*pos])
+ else if (' ' == buf[*pos] || (j && '\\' == buf[*pos]))
break;
if (j == 4 || j < 1)
@@ -395,7 +405,14 @@ roff_ccond(ROFF_ARGS)
return(ROFF_IGN);
}
- if (ROFF_if != r->last->tok) {
+ switch (r->last->tok) {
+ case (ROFF_el):
+ /* FALLTHROUGH */
+ case (ROFF_ie):
+ /* FALLTHROUGH */
+ case (ROFF_if):
+ break;
+ default:
if ( ! (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL))
return(ROFF_ERR);
return(ROFF_IGN);
@@ -478,36 +495,6 @@ roff_block(ROFF_ARGS)
/* ARGSUSED */
static enum rofferr
-roff_if_sub(ROFF_ARGS)
-{
- enum rofft t;
- enum roffrule rr;
-
- ppos = pos;
- rr = r->last->rule;
- roffnode_cleanscope(r);
-
- if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
- return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
-
- /*
- * 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 (ROFFRULE_DENY == rr)
- if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
- if (ROFF_ccond != t)
- return(ROFF_IGN);
-
- assert(roffs[t].proc);
- return((*roffs[t].proc)
- (r, t, bufp, szp, ln, ppos, pos, offs));
-}
-
-
-/* ARGSUSED */
-static enum rofferr
roff_block_sub(ROFF_ARGS)
{
enum rofft t;
@@ -573,39 +560,86 @@ roff_block_text(ROFF_ARGS)
/* ARGSUSED */
static enum rofferr
-roff_if_text(ROFF_ARGS)
+roff_cond_sub(ROFF_ARGS)
+{
+ enum rofft t;
+ enum roffrule rr;
+
+ ppos = pos;
+ rr = r->last->rule;
+
+ roffnode_cleanscope(r);
+
+ if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
+
+ /*
+ * 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 (ROFFRULE_DENY == rr)
+ if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
+ if (ROFF_ccond != t)
+ return(ROFF_IGN);
+
+ assert(roffs[t].proc);
+ return((*roffs[t].proc)
+ (r, t, bufp, szp, ln, ppos, pos, offs));
+}
+
+
+/* ARGSUSED */
+static enum rofferr
+roff_cond_text(ROFF_ARGS)
{
char *ep, *st;
+ enum roffrule rr;
+
+ rr = r->last->rule;
+
+ /*
+ * We display the value of the text if out current evaluation
+ * scope permits us to do so.
+ */
st = &(*bufp)[pos];
if (NULL == (ep = strstr(st, "\\}"))) {
roffnode_cleanscope(r);
- return(ROFF_IGN);
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
}
if (ep > st && '\\' != *(ep - 1))
roffnode_pop(r);
roffnode_cleanscope(r);
- return(ROFF_IGN);
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
}
/* ARGSUSED */
static enum rofferr
-roff_if(ROFF_ARGS)
+roff_cond(ROFF_ARGS)
{
int sv;
- /*
- * Read ahead past the conditional.
- * FIXME: this does not work, as conditionals don't end on
- * whitespace, but are parsed according to a formal grammar.
- * It's good enough for now, however.
- */
+ /* Stack overflow! */
- while ((*bufp)[pos] && ' ' != (*bufp)[pos])
- pos++;
+ if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) {
+ (*r->msg)(MANDOCERR_MEM, r->data, ln, ppos, NULL);
+ return(ROFF_ERR);
+ }
+
+ if (ROFF_if == tok || ROFF_ie == tok) {
+ /*
+ * Read ahead past the conditional. FIXME: this does
+ * not work, as conditionals don't end on whitespace,
+ * but are parsed according to a formal grammar. It's
+ * good enough for now, however.
+ */
+ while ((*bufp)[pos] && ' ' != (*bufp)[pos])
+ pos++;
+ }
sv = pos;
while (' ' == (*bufp)[pos])
@@ -617,7 +651,6 @@ roff_if(ROFF_ARGS)
* really doing anything. Warn about this. It's probably
* wrong.
*/
-
if ('\0' == (*bufp)[pos] && sv != pos) {
if ( ! (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
return(ROFF_ERR);
@@ -627,7 +660,28 @@ roff_if(ROFF_ARGS)
if ( ! roffnode_push(r, tok, ln, ppos))
return(ROFF_ERR);
- /* Don't evaluate: just assume NO. */
+ /* TODO: here we would evaluate the conditional. */
+
+ if (ROFF_el == tok) {
+ /*
+ * An `.el' will get the value of the current rstack
+ * entry set in prior `ie' calls or defaults to DENY.
+ */
+ if (r->rstackpos < 0)
+ r->last->rule = ROFFRULE_DENY;
+ else
+ r->last->rule = r->rstack[r->rstackpos];
+ } else if (ROFF_ie == tok) {
+ /*
+ * An if-else will put the NEGATION of the current
+ * evaluated conditional into the stack.
+ */
+ r->rstackpos++;
+ if (ROFFRULE_DENY == r->last->rule)
+ r->rstack[r->rstackpos] = ROFFRULE_ALLOW;
+ else
+ r->rstack[r->rstackpos] = ROFFRULE_DENY;
+ }
r->last->endspan = 1;