implement the roff(7) d (macro or string defined) conditional
authorschwarze <schwarze@openbsd.org>
Wed, 14 Jun 2017 14:01:34 +0000 (14:01 +0000)
committerschwarze <schwarze@openbsd.org>
Wed, 14 Jun 2017 14:01:34 +0000 (14:01 +0000)
regress/usr.bin/mandoc/roff/cond/Makefile
regress/usr.bin/mandoc/roff/cond/string.in [new file with mode: 0644]
regress/usr.bin/mandoc/roff/cond/string.out_ascii [new file with mode: 0644]
share/man/man7/roff.7
usr.bin/mandoc/roff.c

index 68a8869..5bdcc14 100644 (file)
@@ -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 (file)
index 0000000..6d19f4c
--- /dev/null
@@ -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 (file)
index 0000000..8df491a
--- /dev/null
@@ -0,0 +1,20 @@
+STRING(1)                   General Commands Manual                  STRING(1)
+
+
+
+N\bNA\bAM\bME\bE
+       string - conditional testing whether a string is defined
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       mystr not yet defined
+       now defined
+
+       mymac not yet defined
+       now defined
+
+       myren not yet defined
+       now defined
+
+
+
+OpenBSD                          June 14, 2017                       STRING(1)
index 499d1bb..a193456 100644 (file)
@@ -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
index 7da74dd..bc99ae5 100644 (file)
@@ -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;
        }