summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2017-06-14 14:01:35 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2017-06-14 14:01:35 +0000
commitfe020919d92d7dcd8865b67afb2fd4ce3a5936ea (patch)
tree449cf8698491040b16476c818e125ed40c3ccc81
parent6c9ea8e06dfe6b28db83f7f24c24845b9f4696ff (diff)
implement the roff(7) d (macro or string defined) conditional
-rw-r--r--regress/usr.bin/mandoc/roff/cond/Makefile4
-rw-r--r--regress/usr.bin/mandoc/roff/cond/string.in29
-rw-r--r--regress/usr.bin/mandoc/roff/cond/string.out_ascii20
-rw-r--r--share/man/man7/roff.713
-rw-r--r--usr.bin/mandoc/roff.c18
5 files changed, 73 insertions, 11 deletions
diff --git a/regress/usr.bin/mandoc/roff/cond/Makefile b/regress/usr.bin/mandoc/roff/cond/Makefile
index 68a88694a01..5bdcc14f02f 100644
--- a/regress/usr.bin/mandoc/roff/cond/Makefile
+++ b/regress/usr.bin/mandoc/roff/cond/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.8 2015/05/31 23:12:17 schwarze Exp $
+# $OpenBSD: Makefile,v 1.9 2017/06/14 14:01:34 schwarze Exp $
-REGRESS_TARGETS = if ie close numeric register strcmp before-Dd
+REGRESS_TARGETS = if ie close numeric register strcmp string before-Dd
LINT_TARGETS = if close
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/mandoc/roff/cond/string.in b/regress/usr.bin/mandoc/roff/cond/string.in
new file mode 100644
index 00000000000..6d19f4ce2b8
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/cond/string.in
@@ -0,0 +1,29 @@
+.TH STRING 1 "June 14, 2017" OpenBSD
+.SH NAME
+string \- conditional testing whether a string is defined
+.SH DESCRIPTION
+.ie d mystr OOPS
+.el mystr not yet defined
+.br
+.ds mystr mystrval
+.ie d mystr now defined
+.el OOPS
+.if !d mystr OOPS
+.PP
+.ie d mymac OOPS
+.el mymac not yet defined
+.br
+.de mymac
+mymacval
+..
+.ie dmymac now defined
+.el OOPS
+.if !d mymac OOPS
+.PP
+.ie d myren OOPS
+.el myren not yet defined
+.br
+.rn SM myren
+.ie d myren now defined
+.el OOPS
+.if !d myren OOPS
diff --git a/regress/usr.bin/mandoc/roff/cond/string.out_ascii b/regress/usr.bin/mandoc/roff/cond/string.out_ascii
new file mode 100644
index 00000000000..8df491ac06d
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/cond/string.out_ascii
@@ -0,0 +1,20 @@
+STRING(1) General Commands Manual STRING(1)
+
+
+
+NNAAMMEE
+ string - conditional testing whether a string is defined
+
+DDEESSCCRRIIPPTTIIOONN
+ mystr not yet defined
+ now defined
+
+ mymac not yet defined
+ now defined
+
+ myren not yet defined
+ now defined
+
+
+
+OpenBSD June 14, 2017 STRING(1)
diff --git a/share/man/man7/roff.7 b/share/man/man7/roff.7
index 499d1bb7e1c..a1934569593 100644
--- a/share/man/man7/roff.7
+++ b/share/man/man7/roff.7
@@ -1,4 +1,4 @@
-.\" $OpenBSD: roff.7,v 1.69 2017/06/14 13:00:13 schwarze Exp $
+.\" $OpenBSD: roff.7,v 1.70 2017/06/14 14:01:34 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -1043,8 +1043,6 @@ If the first character of
is
.Sq c
.Pq character available ,
-.Sq d
-.Pq string defined ,
.Sq e
.Pq even page ,
.Sq t
@@ -1057,6 +1055,15 @@ it evaluates to false.
If the first character of
.Ar condition
is
+.Sq d ,
+it evaluates to true if the rest of
+.Ar condition
+is the name of an existing user defined macro or string;
+otherwise, it evaluates to false.
+.It
+If the first character of
+.Ar condition
+is
.Sq r ,
it evaluates to true if the rest of
.Ar condition
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 7da74dd403d..bc99ae530de 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.181 2017/06/14 13:00:13 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.182 2017/06/14 14:01:34 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -2063,7 +2063,7 @@ roff_evalcond(struct roff *r, int ln, char *v, int *pos)
{
char *cp, *name;
size_t sz;
- int number, savepos, wanttrue;
+ int number, savepos, istrue, wanttrue;
if ('!' == v[*pos]) {
wanttrue = 0;
@@ -2079,17 +2079,23 @@ roff_evalcond(struct roff *r, int ln, char *v, int *pos)
(*pos)++;
return wanttrue;
case 'c':
- case 'd':
case 'e':
case 't':
case 'v':
(*pos)++;
return !wanttrue;
+ case 'd':
case 'r':
- cp = name = v + ++*pos;
- sz = roff_getname(r, &cp, ln, *pos);
+ cp = v + *pos + 1;
+ while (*cp == ' ')
+ cp++;
+ name = cp;
+ sz = roff_getname(r, &cp, ln, cp - v);
+ istrue = sz && (v[*pos] == 'r' ? roff_hasregn(r, name, sz) :
+ (roff_getstrn(r, name, sz) != NULL ||
+ roff_getrenn(r, name, sz) != NULL));
*pos = cp - v;
- return (sz && roff_hasregn(r, name, sz)) == wanttrue;
+ return istrue == wanttrue;
default:
break;
}