diff options
-rw-r--r-- | regress/roff/esc/w.in | 16 | ||||
-rw-r--r-- | regress/roff/esc/w.out_ascii | 9 | ||||
-rw-r--r-- | regress/roff/esc/w.out_lint | 9 | ||||
-rw-r--r-- | roff.7 | 5 | ||||
-rw-r--r-- | roff.c | 33 |
5 files changed, 61 insertions, 11 deletions
diff --git a/regress/roff/esc/w.in b/regress/roff/esc/w.in index c30a31ac..59a9bdb5 100644 --- a/regress/roff/esc/w.in +++ b/regress/roff/esc/w.in @@ -1,4 +1,4 @@ -.\" $OpenBSD: w.in,v 1.4 2022/06/08 13:08:00 schwarze Exp $ +.\" $OpenBSD: w.in,v 1.5 2023/10/23 20:07:19 schwarze Exp $ .Dd $Mdocdate$ .Dt ESC-W 1 .Os @@ -13,6 +13,20 @@ character: \w'n' blank: \w' ' .br text: \w'text' +.br +special: \w'\(bu' +.br +numbered: \w'\N'100'' +.br +Unicode: \w'\[u2013]' +.br +overstrike: \w'\o'ab'' +.br +undefined: \w'\G' +.br +zero-width: \w'\fB\&\fP' +.br +skipchar: \w'a\zb\z\(buc' .Ss Argument delimiters unsupported \er: \w\rM\ru .br diff --git a/regress/roff/esc/w.out_ascii b/regress/roff/esc/w.out_ascii index 7ed32ece..a8fdce54 100644 --- a/regress/roff/esc/w.out_ascii +++ b/regress/roff/esc/w.out_ascii @@ -8,6 +8,13 @@ DDEESSCCRRIIPPTTIIOONN character: 24 blank: 24 text: 96 + special: 24 + numbered: 24 + Unicode: 24 + overstrike: 24 + undefined: 24 + zero-width: 0 + skipchar: 48 AArrgguummeenntt ddeelliimmiitteerrss unsupported \r: 24u @@ -27,4 +34,4 @@ DDEESSCCRRIIPPTTIIOONN overstrike: 24u unterminated: 72 -OpenBSD June 8, 2022 OpenBSD +OpenBSD October 23, 2023 OpenBSD diff --git a/regress/roff/esc/w.out_lint b/regress/roff/esc/w.out_lint index fd2a0948..9c6417c5 100644 --- a/regress/roff/esc/w.out_lint +++ b/regress/roff/esc/w.out_lint @@ -1,4 +1,5 @@ -mandoc: w.in:17:20: UNSUPP: unsupported escape sequence: \r -mandoc: w.in:17:23: UNSUPP: unsupported escape sequence: \r -mandoc: w.in:23:16: WARNING: undefined escape, printing literally: \G -mandoc: w.in:51:15: ERROR: incomplete escape sequence: \w'foo +mandoc: w.in:25:15: WARNING: undefined escape, printing literally: \G +mandoc: w.in:31:20: UNSUPP: unsupported escape sequence: \r +mandoc: w.in:31:23: UNSUPP: unsupported escape sequence: \r +mandoc: w.in:37:16: WARNING: undefined escape, printing literally: \G +mandoc: w.in:65:15: ERROR: incomplete escape sequence: \w'foo @@ -1,6 +1,6 @@ .\" $Id$ .\" -.\" Copyright (c) 2010-2019, 2022 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010-2019, 2022-2023 Ingo Schwarze <schwarze@openbsd.org> .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> .\" .\" Permission to use, copy, modify, and distribute this software for any @@ -2224,7 +2224,8 @@ 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 +only contains normal characters, characters expressed as escape sequences, +and zero-width escape sequences, and that each character has a width of 24 basic units. .It Ic \eX\(aq Ns Ar string Ns Ic \(aq Output @@ -1,6 +1,6 @@ /* $Id$ */ /* - * Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2015, 2017-2023 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any @@ -1362,6 +1362,7 @@ roff_expand(struct roff *r, struct buf *buf, int ln, int pos, char ec) const char *res; /* the string to be pasted */ const char *src; /* source for copying */ char *dst; /* destination for copying */ + enum mandoc_esc subtype; /* return value from roff_escape */ int iesc; /* index of leading escape char */ int inam; /* index of the escape name */ int iarg; /* index beginning the argument */ @@ -1551,8 +1552,34 @@ roff_expand(struct roff *r, struct buf *buf, int ln, int pos, char ec) res = ubuf; break; case 'w': - (void)snprintf(ubuf, sizeof(ubuf), - "%d", (iendarg - iarg) * 24); + rsz = 0; + subtype = ESCAPE_UNDEF; + while (iarg < iendarg) { + asz = subtype == ESCAPE_SKIPCHAR ? 0 : 1; + if (buf->buf[iarg] != '\\') { + rsz += asz; + iarg++; + continue; + } + switch ((subtype = roff_escape(buf->buf, 0, + iarg, NULL, NULL, NULL, NULL, &iarg))) { + case ESCAPE_SPECIAL: + case ESCAPE_NUMBERED: + case ESCAPE_UNICODE: + case ESCAPE_OVERSTRIKE: + case ESCAPE_UNDEF: + break; + case ESCAPE_DEVICE: + asz *= 8; + break; + case ESCAPE_EXPAND: + abort(); + default: + continue; + } + rsz += asz; + } + (void)snprintf(ubuf, sizeof(ubuf), "%d", rsz * 24); res = ubuf; break; default: |