diff options
author | 2014-04-08 01:36:50 +0000 | |
---|---|---|
committer | 2014-04-08 01:36:50 +0000 | |
commit | 778fe90ee91eee78af523366f76904973295235b (patch) | |
tree | 9b7d31e7e90d7abb711bace16d088bf105f963ed | |
parent | driver pages shouldn't be mentioning ukphy. (diff) | |
download | wireguard-openbsd-778fe90ee91eee78af523366f76904973295235b.tar.xz wireguard-openbsd-778fe90ee91eee78af523366f76904973295235b.zip |
Fully implement the \B (validate numerical expression) and
partially implement the \w (measure text width) escape sequence
in a way that makes them usable in numerical expressions and in
conditional requests, similar to how \n (interpolate number register)
and \* (expand user-defined string) are implemented.
This lets mandoc(1) handle the baroque low-level roff code
found at the beginning of the ggrep(1) manual.
Thanks to pascal@ for the report.
-rw-r--r-- | regress/usr.bin/mandoc/roff/esc/B.in | 34 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/esc/B.out_ascii | 22 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/esc/Makefile | 4 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/esc/w.in | 14 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/esc/w.out_ascii | 12 | ||||
-rw-r--r-- | share/man/man7/roff.7 | 25 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.c | 9 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 99 |
8 files changed, 175 insertions, 44 deletions
diff --git a/regress/usr.bin/mandoc/roff/esc/B.in b/regress/usr.bin/mandoc/roff/esc/B.in new file mode 100644 index 00000000000..84b0f9f157c --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/B.in @@ -0,0 +1,34 @@ +.Dd April 8, 2014 +.Dt ESC-B 1 +.Os OpenBSD +.Sh NAME +.Nm esc-B +.Nd the roff escape B sequence: validate numerical expression +.Sh DESCRIPTION +empty: \B'' +.br +digit: \B'0' +.br +no number: \B'no number' +.br +trailing garbage: \B'1X' +.br +trailing operator: \B'1+' +.br +infix operator: \B'1+1' +.br +infix and trailing operator: \B'1+1+' +.br +chain of operations: \B'1+2+3+4' +.br +trailing para: \B'1+(' +.br +unclosed para: \B'(1' +.br +empty pair of parentheses: \B'()' +.br +parentheses containing number: \B'(42)' +.br +complex expression: \B'3+(3*(5==5*2)*4)+(3*5)/2' +.br +other delimiter: \Bx1+1x diff --git a/regress/usr.bin/mandoc/roff/esc/B.out_ascii b/regress/usr.bin/mandoc/roff/esc/B.out_ascii new file mode 100644 index 00000000000..6ea3246655d --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/B.out_ascii @@ -0,0 +1,22 @@ +ESC-B(1) OpenBSD Reference Manual ESC-B(1) + +NNAAMMEE + eesscc--BB - the roff escape B sequence: validate numerical expression + +DDEESSCCRRIIPPTTIIOONN + empty: 0 + digit: 1 + no number: 0 + trailing garbage: 0 + trailing operator: 0 + infix operator: 1 + infix and trailing operator: 0 + chain of operations: 1 + trailing para: 0 + unclosed para: 0 + empty pair of parentheses: 0 + parentheses containing number: 1 + complex expression: 1 + other delimiter: 1 + +OpenBSD April 8, 2014 OpenBSD diff --git a/regress/usr.bin/mandoc/roff/esc/Makefile b/regress/usr.bin/mandoc/roff/esc/Makefile index e9705972a80..4fb16774431 100644 --- a/regress/usr.bin/mandoc/roff/esc/Makefile +++ b/regress/usr.bin/mandoc/roff/esc/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.3 2012/05/28 22:45:34 schwarze Exp $ +# $OpenBSD: Makefile,v 1.4 2014/04/08 01:36:50 schwarze Exp $ -REGRESS_TARGETS=one two multi c f h z ignore +REGRESS_TARGETS = one two multi B c f h w z ignore # Postprocessing to remove "character backspace" sequences # unless they are foolowed by the same character again. diff --git a/regress/usr.bin/mandoc/roff/esc/w.in b/regress/usr.bin/mandoc/roff/esc/w.in new file mode 100644 index 00000000000..bd93623e464 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/w.in @@ -0,0 +1,14 @@ +.Dd April 8, 2014 +.Dt ESC-W 1 +.Os OpenBSD +.Sh NAME +.Nm esc-w +.Nd the roff escape w sequence: text width +.Sh DESCRIPTION +empty: \w'' +.br +character: \w'n' +.br +blank: \w' ' +.br +text: \w'text' diff --git a/regress/usr.bin/mandoc/roff/esc/w.out_ascii b/regress/usr.bin/mandoc/roff/esc/w.out_ascii new file mode 100644 index 00000000000..4b11f621f51 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/w.out_ascii @@ -0,0 +1,12 @@ +ESC-W(1) OpenBSD Reference Manual ESC-W(1) + +NNAAMMEE + eesscc--ww - the roff escape w sequence: text width + +DDEESSCCRRIIPPTTIIOONN + empty: 0 + character: 24 + blank: 24 + text: 96 + +OpenBSD April 8, 2014 OpenBSD diff --git a/share/man/man7/roff.7 b/share/man/man7/roff.7 index 39019cd2195..577817788fb 100644 --- a/share/man/man7/roff.7 +++ b/share/man/man7/roff.7 @@ -1,4 +1,4 @@ -.\" $OpenBSD: roff.7,v 1.32 2014/04/07 15:05:12 schwarze Exp $ +.\" $OpenBSD: roff.7,v 1.33 2014/04/08 01:36:50 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: April 7 2014 $ +.Dd $Mdocdate: April 8 2014 $ .Dt ROFF 7 .Os .Sh NAME @@ -1170,10 +1170,15 @@ Digit width space character. Anchor definition; ignored by .Xr mandoc 1 . .Ss \eB\(aq Ns Ar string Ns \(aq -Test whether +Interpolate +.Sq 1 +if .Ar string -is a numerical expession; ignored by -.Xr mandoc 1 . +conforms to the syntax of +.Sx Numerical expressions +explained above and +.Sq 0 +otherwise. .Ss \eb\(aq Ns Ar string Ns \(aq Bracket building function; ignored by .Xr mandoc 1 . @@ -1297,9 +1302,13 @@ Vertical motion; ignored by .Xr mandoc 1 . .Ss \ew\(aq Ns Ar string Ns \(aq Interpolate the width of the -.Ar string ; -ignored by -.Xr mandoc 1 . +.Ar string . +The +.Xr mandoc 1 +implementation assumes that after expansion of user-defined strings, the +.Ar string +only contains normal characters, no escape sequences, and that each +character has a width of 24 basic units. .Ss \eX\(aq Ns Ar string Ns \(aq Output .Ar string diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c index f7a70ee0ae0..627f64e6be9 100644 --- a/usr.bin/mandoc/mandoc.c +++ b/usr.bin/mandoc/mandoc.c @@ -1,7 +1,7 @@ -/* $Id: mandoc.c,v 1.46 2014/04/07 17:50:43 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.47 2014/04/08 01:36:50 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -157,21 +157,18 @@ mandoc_escape(const char **end, const char **start, int *sz) /* * These escapes are of the form \X'Y', where 'X' is the trigger * and 'Y' is any string. These have opaque sub-strings. + * The \B and \w escapes are handled in roff.c, roff_res(). */ case ('A'): /* FALLTHROUGH */ case ('b'): /* FALLTHROUGH */ - case ('B'): - /* FALLTHROUGH */ case ('D'): /* FALLTHROUGH */ case ('o'): /* FALLTHROUGH */ case ('R'): /* FALLTHROUGH */ - case ('w'): - /* FALLTHROUGH */ case ('X'): /* FALLTHROUGH */ case ('Z'): diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index d80d6cf5986..1320bf7d111 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.78 2014/04/07 21:00:00 schwarze Exp $ */ +/* $Id: roff.c,v 1.79 2014/04/08 01:36:50 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org> @@ -481,9 +481,9 @@ roff_alloc(struct mparse *parse, int options) } /* - * In the current line, expand user-defined strings ("\*") - * and references to number registers ("\n"). - * Also check the syntax of other escape sequences. + * In the current line, expand escape sequences that tend to get + * used in numerical expressions and conditional requests. + * Also check the syntax of the remaining escape sequences. */ static enum rofferr roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) @@ -499,6 +499,9 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) size_t naml; /* actual length of the escape name */ size_t ressz; /* size of the replacement string */ int expand_count; /* to avoid infinite loops */ + int npos; /* position in numeric expression */ + int irc; /* return code from roff_evalnum() */ + char term; /* character terminating the escape */ expand_count = 0; start = *bufp + pos; @@ -521,16 +524,19 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) continue; } - /* - * Everything except user-defined strings and number - * registers is only checked, not expanded. - */ + /* Decide whether to expand or to check only. */ + term = '\0'; cp = stesc + 1; switch (*cp) { case ('*'): res = NULL; break; + case ('B'): + /* FALLTHROUGH */ + case ('w'): + term = cp[1]; + /* FALLTHROUGH */ case ('n'): res = ubuf; break; @@ -553,20 +559,27 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) * Save a pointer to the name. */ - switch (*++cp) { - case ('\0'): - continue; - case ('('): - cp++; - maxl = 2; - break; - case ('['): - cp++; + if ('\0' == term) { + switch (*++cp) { + case ('\0'): + maxl = 0; + break; + case ('('): + cp++; + maxl = 2; + break; + case ('['): + cp++; + term = ']'; + maxl = 0; + break; + default: + maxl = 1; + break; + } + } else { + cp += 2; maxl = 0; - break; - default: - maxl = 1; - break; } stnam = cp; @@ -578,10 +591,12 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) (MANDOCERR_BADESCAPE, r->parse, ln, (int)(stesc - *bufp), NULL); - continue; + break; } - if (0 == maxl && ']' == *cp) + if (0 == maxl && *cp == term) { + cp++; break; + } } /* @@ -589,11 +604,26 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) * undefined, resume searching for escapes. */ - if (NULL == res) + switch (stesc[1]) { + case ('*'): res = roff_getstrn(r, stnam, naml); - else + break; + case ('B'): + npos = 0; + irc = roff_evalnum(stnam, &npos, NULL, 0); + ubuf[0] = irc && stnam + npos + 1 == cp + ? '1' : '0'; + ubuf[1] = '\0'; + break; + case ('n'): snprintf(ubuf, sizeof(ubuf), "%d", roff_getregn(r, stnam, naml)); + break; + case ('w'): + snprintf(ubuf, sizeof(ubuf), "%d", + 24 * (int)naml); + break; + } if (NULL == res) { mandoc_msg @@ -610,7 +640,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); strlcat(nbuf, res, *szp); - strlcat(nbuf, cp + (maxl ? 0 : 1), *szp); + strlcat(nbuf, cp, *szp); /* Prepare for the next replacement. */ @@ -1122,7 +1152,10 @@ roff_cond_text(ROFF_ARGS) static int roff_getnum(const char *v, int *pos, int *res) { - int p, n; + int myres, n, p; + + if (NULL == res) + res = &myres; p = *pos; n = v[p] == '-'; @@ -1426,9 +1459,16 @@ roff_evalpar(const char *v, int *pos, int *res) if ( ! roff_evalnum(v, pos, res, 1)) return(0); - /* If the trailing parenthesis is missing, ignore the error. */ + /* + * Omission of the closing parenthesis + * is an error in validation mode, + * but ignored in evaluation mode. + */ + if (')' == v[*pos]) (*pos)++; + else if (NULL == res) + return(0); return(1); } @@ -1474,6 +1514,9 @@ roff_evalnum(const char *v, int *pos, int *res, int skipwhite) while (isspace((unsigned char)v[*pos])) (*pos)++; + if (NULL == res) + continue; + switch (operator) { case ('+'): *res += operand2; |