diff options
author | 2015-02-17 17:16:11 +0000 | |
---|---|---|
committer | 2015-02-17 17:16:11 +0000 | |
commit | 3a1681a68c8a4d49bd2765eaba8237ff5136de4f (patch) | |
tree | e30ebbc4a65b8ef9e19813baac034c9385c42565 | |
parent | Mark up email addresses semantically with Mt. (diff) | |
download | wireguard-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.in | 8 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/numeric.out_ascii | 2 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/text.in | 21 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/text.out_ascii | 9 | ||||
-rw-r--r-- | share/man/man7/roff.7 | 17 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 79 |
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); } |