From c2f35d21380404e32c4920d8084ed33d3ad1c39f Mon Sep 17 00:00:00 2001 From: schwarze Date: Wed, 14 Jun 2017 14:01:34 +0000 Subject: [PATCH] implement the roff(7) d (macro or string defined) conditional --- regress/usr.bin/mandoc/roff/cond/Makefile | 4 +-- regress/usr.bin/mandoc/roff/cond/string.in | 29 +++++++++++++++++++ .../usr.bin/mandoc/roff/cond/string.out_ascii | 20 +++++++++++++ share/man/man7/roff.7 | 13 +++++++-- usr.bin/mandoc/roff.c | 18 ++++++++---- 5 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 regress/usr.bin/mandoc/roff/cond/string.in create mode 100644 regress/usr.bin/mandoc/roff/cond/string.out_ascii 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 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 .\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze @@ -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 * Copyright (c) 2010-2015, 2017 Ingo Schwarze @@ -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; } -- 2.20.1