summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2015-02-17 17:16:11 +0000
committerschwarze <schwarze@openbsd.org>2015-02-17 17:16:11 +0000
commit3a1681a68c8a4d49bd2765eaba8237ff5136de4f (patch)
treee30ebbc4a65b8ef9e19813baac034c9385c42565
parentMark up email addresses semantically with Mt. (diff)
downloadwireguard-openbsd-3a1681a68c8a4d49bd2765eaba8237ff5136de4f.tar.xz
wireguard-openbsd-3a1681a68c8a4d49bd2765eaba8237ff5136de4f.zip
Let .it accept numerical expressions, not just numerical constants.
For .it, ignore scaling units in roff_getnum(). Inside parentheses, skip whitespace after a sign in roff_getnum(). Parse and ignore unary plus in roff_getnum(). As a bonus, get rid of the only call to mandoc_strntoi() in roff.c.
-rw-r--r--regress/usr.bin/mandoc/roff/cond/numeric.in8
-rw-r--r--regress/usr.bin/mandoc/roff/cond/numeric.out_ascii2
-rw-r--r--regress/usr.bin/mandoc/roff/it/text.in21
-rw-r--r--regress/usr.bin/mandoc/roff/it/text.out_ascii9
-rw-r--r--share/man/man7/roff.717
-rw-r--r--usr.bin/mandoc/roff.c79
6 files changed, 85 insertions, 51 deletions
diff --git a/regress/usr.bin/mandoc/roff/cond/numeric.in b/regress/usr.bin/mandoc/roff/cond/numeric.in
index d28fcb9e8a2..e96f30873a5 100644
--- a/regress/usr.bin/mandoc/roff/cond/numeric.in
+++ b/regress/usr.bin/mandoc/roff/cond/numeric.in
@@ -127,6 +127,14 @@ operator ":":
.ie 1:1 (t)
.el (f)
.PP
+with scaling units:
+1i>2c
+.ie 1i>2c (t)
+.el (f)
+1i-6P
+.ie 1i-6P (t)
+.el (f)
+.PP
unmatched parenthesis:
.ie (
(t)
diff --git a/regress/usr.bin/mandoc/roff/cond/numeric.out_ascii b/regress/usr.bin/mandoc/roff/cond/numeric.out_ascii
index b8155caafc9..35973672f01 100644
--- a/regress/usr.bin/mandoc/roff/cond/numeric.out_ascii
+++ b/regress/usr.bin/mandoc/roff/cond/numeric.out_ascii
@@ -30,6 +30,8 @@ DDEESSCCRRIIPPTTIIOONN
operator ":": 00 (f) 01 (t) 10 (t) 11 (t)
+ with scaling units: 1i>2c (t) 1i-6P (f)
+
unmatched parenthesis: (f) one (t)
negated unmatched parenthesis: (f) zero (t)
diff --git a/regress/usr.bin/mandoc/roff/it/text.in b/regress/usr.bin/mandoc/roff/it/text.in
index 4eeac2bdf44..b3384180d4a 100644
--- a/regress/usr.bin/mandoc/roff/it/text.in
+++ b/regress/usr.bin/mandoc/roff/it/text.in
@@ -1,18 +1,27 @@
-.Dd $Mdocdate: July 13 2013 $
+.Dd February 17, 2015
.Dt IT-TEXT 1
.Os OpenBSD
.Sh NAME
.Nm it-text
.Nd what an input line trap counts as text
.Sh DESCRIPTION
-.de mytrap
+.de trap
traptext
..
initial text
-.it 1 mytrap
-plain text line
-another plain text line
-.it 1 mytrap
+.it 1trap
+first line after 1trap
+second line after 1trap
+.Pp
+.it 1vtrap
+first line after 1vtrap
+second line after 1vtrap
+.Pp
+.it ( + 1c + 1i)trap
+first line after ( + 1c + 1i)trap
+second line after ( + 1c + 1i)trap
+third line after ( + 1c + 1i)trap
+.it 1 trap
.Pp
first line after .Pp
second line after .Pp
diff --git a/regress/usr.bin/mandoc/roff/it/text.out_ascii b/regress/usr.bin/mandoc/roff/it/text.out_ascii
index 0d494707af1..bfc89842a2c 100644
--- a/regress/usr.bin/mandoc/roff/it/text.out_ascii
+++ b/regress/usr.bin/mandoc/roff/it/text.out_ascii
@@ -4,8 +4,13 @@ NNAAMMEE
iitt--tteexxtt - what an input line trap counts as text
DDEESSCCRRIIPPTTIIOONN
- initial text plain text line traptext another plain text line
+ initial text first line after 1trap traptext second line after 1trap
+
+ first line after 1vtrap traptext second line after 1vtrap
+
+ first line after ( + 1c + 1i)trap second line after ( + 1c + 1i)trap
+ traptext third line after ( + 1c + 1i)trap
first line after .Pp traptext second line after .Pp
-OpenBSD July 13, 2013 OpenBSD
+OpenBSD February 17, 2015 OpenBSD
diff --git a/share/man/man7/roff.7 b/share/man/man7/roff.7
index fc7a4f9555b..432ff0339d6 100644
--- a/share/man/man7/roff.7
+++ b/share/man/man7/roff.7
@@ -1,4 +1,4 @@
-.\" $OpenBSD: roff.7,v 1.49 2015/01/29 00:33:14 schwarze Exp $
+.\" $OpenBSD: roff.7,v 1.50 2015/02/17 17:16:11 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 29 2015 $
+.Dd $Mdocdate: February 17 2015 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -1194,13 +1194,18 @@ This is a Heirloom extension and currently unsupported.
Set an input line trap.
Its syntax is as follows:
.Pp
-.D1 Pf . Cm it Ar number macro
+.D1 Pf . Cm it Ar expression macro
.Pp
The named
.Ar macro
-will be invoked after processing the specified
-.Ar number
-of input text lines.
+will be invoked after processing the number of input text lines
+specified by the numerical
+.Ar expression .
+While evaluating the
+.Ar expression ,
+the unit suffixes described below
+.Sx Scaling Widths
+are ignored.
.Ss \&itc
Set an input line trap, not counting lines ending with \ec.
Currently unsupported.
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index f9df10f4429..5c6a12aeb3e 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.132 2015/02/06 16:05:51 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.133 2015/02/17 17:16:12 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -394,13 +394,13 @@ static int roff_evalcond(struct roff *r, int,
static int roff_evalnum(struct roff *, int,
const char *, int *, int *, int);
static int roff_evalpar(struct roff *, int,
- const char *, int *, int *);
+ const char *, int *, int *, int);
static int roff_evalstrcond(const char *, int *);
static void roff_free1(struct roff *);
static void roff_freereg(struct roffreg *);
static void roff_freestr(struct roffkv *);
static size_t roff_getname(struct roff *, char **, int, int);
-static int roff_getnum(const char *, int *, int *);
+static int roff_getnum(const char *, int *, int *, int);
static int roff_getop(const char *, int *, char *);
static int roff_getregn(const struct roff *,
const char *, size_t);
@@ -439,6 +439,9 @@ static enum rofferr roff_userdef(ROFF_ARGS);
#define ASCII_LO 33
#define HASHWIDTH (ASCII_HI - ASCII_LO + 1)
+#define ROFFNUM_SCALE (1 << 0) /* Honour scaling in roff_getnum(). */
+#define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */
+
static struct roffmac *hash[HASHWIDTH];
static struct roffmac roffs[ROFF_MAX] = {
@@ -1048,7 +1051,8 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
case 'B':
npos = 0;
ubuf[0] = arg_complete &&
- roff_evalnum(r, ln, stnam, &npos, NULL, 0) &&
+ roff_evalnum(r, ln, stnam, &npos,
+ NULL, ROFFNUM_SCALE) &&
stnam + npos + 1 == cp ? '1' : '0';
ubuf[1] = '\0';
break;
@@ -1626,18 +1630,22 @@ roff_cond_text(ROFF_ARGS)
* Ignore overflows, treat them just like the C language.
*/
static int
-roff_getnum(const char *v, int *pos, int *res)
+roff_getnum(const char *v, int *pos, int *res, int flags)
{
- int myres, n, p;
+ int myres, scaled, n, p;
if (NULL == res)
res = &myres;
p = *pos;
n = v[p] == '-';
- if (n)
+ if (n || v[p] == '+')
p++;
+ if (flags & ROFFNUM_WHITE)
+ while (isspace((unsigned char)v[p]))
+ p++;
+
for (*res = 0; isdigit((unsigned char)v[p]); p++)
*res = 10 * *res + v[p] - '0';
if (p == *pos + n)
@@ -1650,39 +1658,40 @@ roff_getnum(const char *v, int *pos, int *res)
switch (v[p]) {
case 'f':
- *res *= 65536;
+ scaled = *res * 65536;
break;
case 'i':
- *res *= 240;
+ scaled = *res * 240;
break;
case 'c':
- *res *= 240;
- *res /= 2.54;
+ scaled = *res * 240 / 2.54;
break;
case 'v':
/* FALLTROUGH */
case 'P':
- *res *= 40;
+ scaled = *res * 40;
break;
case 'm':
/* FALLTROUGH */
case 'n':
- *res *= 24;
+ scaled = *res * 24;
break;
case 'p':
- *res *= 10;
- *res /= 3;
+ scaled = *res * 10 / 3;
break;
case 'u':
+ scaled = *res;
break;
case 'M':
- *res *= 6;
- *res /= 25;
+ scaled = *res * 6 / 25;
break;
default:
+ scaled = *res;
p--;
break;
}
+ if (flags & ROFFNUM_SCALE)
+ *res = scaled;
*pos = p + 1;
return(1);
@@ -1772,7 +1781,7 @@ roff_evalcond(struct roff *r, int ln, const char *v, int *pos)
}
savepos = *pos;
- if (roff_evalnum(r, ln, v, pos, &number, 0))
+ if (roff_evalnum(r, ln, v, pos, &number, ROFFNUM_SCALE))
return((number > 0) == wanttrue);
else if (*pos == savepos)
return(roff_evalstrcond(v, pos) == wanttrue);
@@ -1995,14 +2004,14 @@ roff_getop(const char *v, int *pos, char *res)
*/
static int
roff_evalpar(struct roff *r, int ln,
- const char *v, int *pos, int *res)
+ const char *v, int *pos, int *res, int flags)
{
if ('(' != v[*pos])
- return(roff_getnum(v, pos, res));
+ return(roff_getnum(v, pos, res, flags));
(*pos)++;
- if ( ! roff_evalnum(r, ln, v, pos, res, 1))
+ if ( ! roff_evalnum(r, ln, v, pos, res, flags | ROFFNUM_WHITE))
return(0);
/*
@@ -2025,7 +2034,7 @@ roff_evalpar(struct roff *r, int ln,
*/
static int
roff_evalnum(struct roff *r, int ln, const char *v,
- int *pos, int *res, int skipwhite)
+ int *pos, int *res, int flags)
{
int mypos, operand2;
char operator;
@@ -2035,29 +2044,29 @@ roff_evalnum(struct roff *r, int ln, const char *v,
pos = &mypos;
}
- if (skipwhite)
+ if (flags & ROFFNUM_WHITE)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
- if ( ! roff_evalpar(r, ln, v, pos, res))
+ if ( ! roff_evalpar(r, ln, v, pos, res, flags))
return(0);
while (1) {
- if (skipwhite)
+ if (flags & ROFFNUM_WHITE)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
if ( ! roff_getop(v, pos, &operator))
break;
- if (skipwhite)
+ if (flags & ROFFNUM_WHITE)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
- if ( ! roff_evalpar(r, ln, v, pos, &operand2))
+ if ( ! roff_evalpar(r, ln, v, pos, &operand2, flags))
return(0);
- if (skipwhite)
+ if (flags & ROFFNUM_WHITE)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
@@ -2261,7 +2270,7 @@ roff_nr(ROFF_ARGS)
if (sign == '+' || sign == '-')
val++;
- if (roff_evalnum(r, ln, val, NULL, &iv, 0))
+ if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE))
roff_setreg(r, key, iv, sign);
return(ROFF_IGN);
@@ -2316,24 +2325,20 @@ roff_rm(ROFF_ARGS)
static enum rofferr
roff_it(ROFF_ARGS)
{
- char *cp;
- size_t len;
int iv;
/* Parse the number of lines. */
- cp = buf->buf + pos;
- len = strcspn(cp, " \t");
- cp[len] = '\0';
- if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) {
+
+ if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) {
mandoc_msg(MANDOCERR_IT_NONUM, r->parse,
ln, ppos, buf->buf + 1);
return(ROFF_IGN);
}
- cp += len + 1;
/* Arm the input line trap. */
+
roffit_lines = iv;
- roffit_macro = mandoc_strdup(cp);
+ roffit_macro = mandoc_strdup(buf->buf + pos);
return(ROFF_IGN);
}