aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2022-06-08 13:23:57 +0000
committerIngo Schwarze <schwarze@openbsd.org>2022-06-08 13:23:57 +0000
commit88d09deb893505c936316537673cfbf30be47558 (patch)
tree9be83d537e7c6258d68b8336e0e6adff57959bab
parent0e5b172a930a9f03c2f2175cbdd843fa54782a89 (diff)
downloadmandoc-88d09deb893505c936316537673cfbf30be47558.tar.gz
mandoc-88d09deb893505c936316537673cfbf30be47558.tar.zst
mandoc-88d09deb893505c936316537673cfbf30be47558.zip
Surprisingly, every escape sequence can also be used as an argument
delimiter for an outer escape sequence, in which case the delimiting escape sequence retains its syntax but usually ignores its argument and loses its inherent effect. Add rudimentary support for this syntax quirk in order to improve parsing compatibility with groff.
-rw-r--r--regress/char/C/Makefile6
-rw-r--r--regress/char/C/delim.in51
-rw-r--r--regress/char/C/delim.out_ascii30
-rw-r--r--regress/char/C/delim.out_lint6
-rw-r--r--regress/char/Makefile4
-rw-r--r--regress/char/N/Makefile5
-rw-r--r--regress/char/N/basic.out_lint1
-rw-r--r--regress/char/N/delim.in101
-rw-r--r--regress/char/N/delim.out_ascii52
-rw-r--r--regress/char/N/delim.out_lint29
-rw-r--r--regress/roff/esc/A1.in53
-rw-r--r--regress/roff/esc/A1.out_ascii31
-rw-r--r--regress/roff/esc/A1.out_lint5
-rw-r--r--regress/roff/esc/B.in98
-rw-r--r--regress/roff/esc/B.out_ascii49
-rw-r--r--regress/roff/esc/B.out_lint30
-rw-r--r--regress/roff/esc/Makefile7
-rw-r--r--regress/roff/esc/h.in100
-rw-r--r--regress/roff/esc/h.out_ascii50
-rw-r--r--regress/roff/esc/h.out_lint31
-rw-r--r--regress/roff/esc/l.in100
-rw-r--r--regress/roff/esc/l.out_ascii50
-rw-r--r--regress/roff/esc/l.out_lint31
-rw-r--r--regress/roff/esc/o.in40
-rw-r--r--regress/roff/esc/o.out_ascii20
-rw-r--r--regress/roff/esc/w.in38
-rw-r--r--regress/roff/esc/w.out_ascii19
-rw-r--r--regress/roff/esc/w.out_lint5
-rw-r--r--roff_escape.c75
29 files changed, 1059 insertions, 58 deletions
diff --git a/regress/char/C/Makefile b/regress/char/C/Makefile
new file mode 100644
index 00000000..3d938fe7
--- /dev/null
+++ b/regress/char/C/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.1 2022/06/08 13:08:00 schwarze Exp $
+
+REGRESS_TARGETS = delim
+LINT_TARGETS = delim
+
+.include <bsd.regress.mk>
diff --git a/regress/char/C/delim.in b/regress/char/C/delim.in
new file mode 100644
index 00000000..e048e0a8
--- /dev/null
+++ b/regress/char/C/delim.in
@@ -0,0 +1,51 @@
+.\" $OpenBSD: delim.in,v 1.1 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
+.Dt C-DELIM 1
+.Os
+.Sh NAME
+.Nm C-delim
+.Nd argument delimiters for the C escape sequence
+.Sh DESCRIPTION
+empty: \C''
+.br
+single byte: \C'_'\C'-'
+.br
+two bytes: \C'hy'
+.br
+multiple bytes: \C'integral'
+.Ss Argument delimiters
+unsupported \er: \C\rat\ru
+.br
+ignored \e&: \C\&at\&u
+.br
+useless \e.: \C\.at.u
+.br
+invalid \eG: \C\GatGu
+.br
+special \e-: \C\-at\-u
+.br
+break \ep: \C\pat\pu
+.br
+nospace \ec: \C\cat\cu
+.\".br
+.\"XXX skipchar \ec: \C\zat\zu
+.br
+.ds mystr xatxu
+string expansion: \C\*[mystr]
+.br
+.nr myreg 1341
+register expansion: \C\n[myreg]u
+.br
+ignored \eON: \C\O1at\O2u
+.br
+special character: \C\(hyat\(hyu
+.br
+ignored \eZ\(aqstr\(aq: \C\Z'foo'at\Z'bar'u
+.br
+horizontal motion: \C\h'1'at\h'3'u
+.br
+horizontal line: \C\l'4'at\l'2'u
+.br
+overstrike: \C\o'ab'at\o'cd'u
+.br
+unterminated: \C'at
diff --git a/regress/char/C/delim.out_ascii b/regress/char/C/delim.out_ascii
new file mode 100644
index 00000000..7276d7c2
--- /dev/null
+++ b/regress/char/C/delim.out_ascii
@@ -0,0 +1,30 @@
+C-DELIM(1) General Commands Manual C-DELIM(1)
+
+NNAAMMEE
+ CC--ddeelliimm - argument delimiters for the C escape sequence
+
+DDEESSCCRRIIPPTTIIOONN
+ empty:
+ single byte: -
+ two bytes: -
+ multiple bytes: <integral>
+
+ AArrgguummeenntt ddeelliimmiitteerrss
+ unsupported \r: @u
+ ignored \&: @u
+ useless \.: @u
+ invalid \G: @u
+ special \-: @u
+ break \p: @u
+ nospace \c: @u
+ string expansion: @u
+ register expansion: 3/4u
+ ignored \ON: @u
+ special character: @u
+ ignored \Z'str': @u
+ horizontal motion: @u
+ horizontal line: @u
+ overstrike: @u
+ unterminated:
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/char/C/delim.out_lint b/regress/char/C/delim.out_lint
new file mode 100644
index 00000000..2dc23d44
--- /dev/null
+++ b/regress/char/C/delim.out_lint
@@ -0,0 +1,6 @@
+mandoc: delim.in:9:8: ERROR: invalid special character: \C''
+mandoc: delim.in:11:14: ERROR: invalid special character: \C'_'
+mandoc: delim.in:17:20: UNSUPP: unsupported escape sequence: \r
+mandoc: delim.in:17:24: UNSUPP: unsupported escape sequence: \r
+mandoc: delim.in:23:16: WARNING: undefined escape, printing literally: \G
+mandoc: delim.in:51:15: ERROR: incomplete escape sequence: \C'at
diff --git a/regress/char/Makefile b/regress/char/Makefile
index dbd922e0..b3cacfda 100644
--- a/regress/char/Makefile
+++ b/regress/char/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.9 2014/06/20 18:27:51 schwarze Exp $
+# $OpenBSD: Makefile,v 1.10 2022/06/08 13:08:00 schwarze Exp $
-SUBDIR = accent bar hyphen space unicode N
+SUBDIR = accent bar hyphen space unicode C N
.include "../Makefile.sub"
.include <bsd.subdir.mk>
diff --git a/regress/char/N/Makefile b/regress/char/N/Makefile
index 3630b154..30b19147 100644
--- a/regress/char/N/Makefile
+++ b/regress/char/N/Makefile
@@ -1,5 +1,6 @@
-# $OpenBSD: Makefile,v 1.2 2011/11/17 16:28:45 schwarze Exp $
+# $OpenBSD: Makefile,v 1.3 2022/06/08 13:08:00 schwarze Exp $
-REGRESS_TARGETS=basic
+REGRESS_TARGETS = basic delim
+LINT_TARGETS = basic delim
.include <bsd.regress.mk>
diff --git a/regress/char/N/basic.out_lint b/regress/char/N/basic.out_lint
new file mode 100644
index 00000000..2dd8bb90
--- /dev/null
+++ b/regress/char/N/basic.out_lint
@@ -0,0 +1 @@
+mandoc: basic.in:23:14: ERROR: invalid escape argument delimiter: \N6
diff --git a/regress/char/N/delim.in b/regress/char/N/delim.in
new file mode 100644
index 00000000..f9ac0099
--- /dev/null
+++ b/regress/char/N/delim.in
@@ -0,0 +1,101 @@
+.\" $OpenBSD: delim.in,v 1.1 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
+.Dt N-DELIM 1
+.Os
+.Sh NAME
+.Nm N-delim
+.Nd argument delimiters for the N escape sequence
+.Sh DESCRIPTION
+unsupported \e!: \N\!42\!u
+.br
+unsupported \er: \N\r42u
+.br
+ignored \e%: \N\%42\%u
+.br
+ignored \e&: \N\&42\&u
+.br
+ignored \e): \N\)42\)u
+.br
+ignored \e,: \N\,42\,u
+.br
+ignored \e/: \N\/42\/u
+.br
+ignored \e^: \N\^42\^u
+.br
+ignored \ea: \N\a42\au
+.br
+ignored \ed: \N\d42\du
+.br
+ignored \et: \N\t42\tu
+.br
+ignored \eu: \N\u42\uu
+.br
+ignored \e{: \N\{42\{u
+.br
+ignored \e|: \N\|42\|u
+.br
+ignored \e}: \N\}42\}u
+.br
+useless \e.: \N\.42.u
+.\".br
+.\"XXX useless \e\e: \N\\42\\u
+.br
+invalid \eG: \N\G42Gu
+.br
+special \e\ : \N\ 42\ u
+.br
+special \e\(aq: \N\'42\'u
+.br
+special \e-: \N\-42\-u
+.br
+special \e0: \N\042\0u
+.br
+special \e:: \N\:42\:u
+.br
+special \e_: \N\_42\_u
+.br
+special \e\(ga: \N\`42\`u
+.br
+special \ee: \N\e42\eu
+.br
+special \e~: \N\~42\~u
+.br
+break \ep: \N\p42\pu
+.br
+nospace \ec: \N\c42\cu
+.\".br
+.\"XXX skipchar \ez: \N\z42\zu
+.br
+.ds mystr x42xu
+string expansion: \N\*[mystr]
+.br
+.nr myreg 23
+register expansion: \N\n[myreg]u
+.br
+ignored \eO: \N\O142\O2u
+.br
+ignored \eY: \N\Y[mystr]42\Y[mystr]u
+.br
+ignored \ek: \N\k[myreg]42\k[myreg]u
+.br
+special character: \N\(hy42\(hyu
+.br
+ignored \eD: \N\D't 1'42\D't 2'u
+.br
+ignored \eL: \N\L'2'42u
+.br
+ignored \eX: \N\X'foo'42\X'bar'u
+.br
+ignored \eZ: \N\Z'foo'42\Z''u
+.br
+ignored \eb: \N\b'2'42\b''u
+.br
+ignored \ev: \N\v'2'42\v'0'u
+.br
+ignored \ex: \N\x'2'42\v'0'u
+.br
+horizontal motion: \N\h'1'42\h'3'u
+.br
+horizontal line: \N\l'4'42\l'2'u
+.br
+overstrike: \N\o'ab'42\o'cd'u
diff --git a/regress/char/N/delim.out_ascii b/regress/char/N/delim.out_ascii
new file mode 100644
index 00000000..4e7cb1c2
--- /dev/null
+++ b/regress/char/N/delim.out_ascii
@@ -0,0 +1,52 @@
+N-DELIM(1) General Commands Manual N-DELIM(1)
+
+NNAAMMEE
+ NN--ddeelliimm - argument delimiters for the N escape sequence
+
+DDEESSCCRRIIPPTTIIOONN
+ unsupported \!: *u
+ unsupported \r: 42u
+ ignored \%: *u
+ ignored \&: *u
+ ignored \): *u
+ ignored \,: 42u
+ ignored \/: *u
+ ignored \^: 42u
+ ignored \a: 42u
+ ignored \d: 42u
+ ignored \t: 42u
+ ignored \u: 42u
+ ignored \{: *u
+ ignored \|: 42u
+ ignored \}: *u
+ useless \.: 42.u
+ invalid \G: *u
+ special \ : 42 u
+ special \': *u
+ special \-: *u
+ special \0: 42 u
+ special \:: *u
+ special \_: *u
+ special \`: *u
+ special \e: *u
+ special \~: 42 u
+ break \p: *u
+ nospace \c: *u
+ string expansion: *u
+ register expansion: 3u
+ ignored \O: 42u
+ ignored \Y: 42u
+ ignored \k: *u
+ special character: *u
+ ignored \D: 42u
+ ignored \L: 42u
+ ignored \X: 42u
+ ignored \Z: 42u
+ ignored \b: 42u
+ ignored \v: 42u
+ ignored \x: 42u
+ horizontal motion: 42 u
+ horizontal line: 42__u
+ overstrike: 42cdu
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/char/N/delim.out_lint b/regress/char/N/delim.out_lint
new file mode 100644
index 00000000..698c58c3
--- /dev/null
+++ b/regress/char/N/delim.out_lint
@@ -0,0 +1,29 @@
+mandoc: delim.in:9:20: UNSUPP: unsupported escape sequence: \!
+mandoc: delim.in:9:24: UNSUPP: unsupported escape sequence: \!
+mandoc: delim.in:11:20: UNSUPP: unsupported escape sequence: \r
+mandoc: delim.in:11:18: ERROR: invalid escape argument delimiter: \N\r
+mandoc: delim.in:19:14: ERROR: invalid escape argument delimiter: \N\,
+mandoc: delim.in:23:14: ERROR: invalid escape argument delimiter: \N\^
+mandoc: delim.in:25:14: ERROR: invalid escape argument delimiter: \N\a
+mandoc: delim.in:27:14: ERROR: invalid escape argument delimiter: \N\d
+mandoc: delim.in:29:14: ERROR: invalid escape argument delimiter: \N\t
+mandoc: delim.in:31:14: ERROR: invalid escape argument delimiter: \N\u
+mandoc: delim.in:35:14: ERROR: invalid escape argument delimiter: \N\|
+mandoc: delim.in:39:14: ERROR: invalid escape argument delimiter: \N\.
+mandoc: delim.in:43:16: WARNING: undefined escape, printing literally: \G
+mandoc: delim.in:45:15: ERROR: invalid escape argument delimiter: \N\
+mandoc: delim.in:51:14: ERROR: invalid escape argument delimiter: \N\0
+mandoc: delim.in:61:14: ERROR: invalid escape argument delimiter: \N\~
+mandoc: delim.in:73:21: ERROR: invalid escape argument delimiter: \N2
+mandoc: delim.in:75:14: ERROR: invalid escape argument delimiter: \N\O1
+mandoc: delim.in:77:14: ERROR: invalid escape argument delimiter: \N\Y[mystr]
+mandoc: delim.in:83:14: ERROR: invalid escape argument delimiter: \N\D't 1'
+mandoc: delim.in:85:14: ERROR: invalid escape argument delimiter: \N\L'2'
+mandoc: delim.in:87:14: ERROR: invalid escape argument delimiter: \N\X'foo'
+mandoc: delim.in:89:14: ERROR: invalid escape argument delimiter: \N\Z'foo'
+mandoc: delim.in:91:14: ERROR: invalid escape argument delimiter: \N\b'2'
+mandoc: delim.in:93:14: ERROR: invalid escape argument delimiter: \N\v'2'
+mandoc: delim.in:95:14: ERROR: invalid escape argument delimiter: \N\x'2'
+mandoc: delim.in:97:20: ERROR: invalid escape argument delimiter: \N\h'1'
+mandoc: delim.in:99:18: ERROR: invalid escape argument delimiter: \N\l'4'
+mandoc: delim.in:101:13: ERROR: invalid escape argument delimiter: \N\o'ab'
diff --git a/regress/roff/esc/A1.in b/regress/roff/esc/A1.in
new file mode 100644
index 00000000..7d4dccd9
--- /dev/null
+++ b/regress/roff/esc/A1.in
@@ -0,0 +1,53 @@
+.\" $OpenBSD: A1.in,v 1.1 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
+.Dt ESC-A1 1
+.Os
+.Sh NAME
+.Nm esc-A1
+.Nd the roff escape A sequence: identifier syntax validation
+.Sh DESCRIPTION
+empty: \A''
+.br
+letters: \A'word'
+.br
+blank: \A'two words'
+.br
+ASCII non-letters: \AA!"#$%&'()*+,-./0123456789:;<=>?@[\\]^_`{|}~A
+.br
+invalid escapes: \A'\\\.\G'
+.Ss Argument delimiters
+unsupported \er: \A\rword\ru
+.br
+ignored \e&: \A\&word\&u
+.br
+useless \e.: \A\.word.u
+.br
+invalid \eG: \A\GwordGu
+.br
+special \e-: \A\-word\-u
+.br
+break \ep: \A\pword\pu
+.br
+nospace \ec: \A\cword\cu
+.\".br
+.\"skipchar \ez: \A\zword\zu
+.br
+.ds mystr xwordxu
+string expansion: \A\*[mystr]
+.br
+.nr myreg 121
+register expansion: \A\n[myreg]u
+.br
+ignored \eON: \A\O1word\O2u
+.br
+special character: \A\(hyword\(hyu
+.br
+ignored \eZ\(aqstr\(aq: \A\Z'foo'word\Z'bar'u
+.br
+horizontal motion: \A\h'1'word\h'3'u
+.br
+horizontal line: \A\l'4'word\l'2'u
+.br
+overstrike: \A\o'ab'word\o'cd'u
+.br
+unterminated: \A'word
diff --git a/regress/roff/esc/A1.out_ascii b/regress/roff/esc/A1.out_ascii
new file mode 100644
index 00000000..2b431b5b
--- /dev/null
+++ b/regress/roff/esc/A1.out_ascii
@@ -0,0 +1,31 @@
+ESC-A1(1) General Commands Manual ESC-A1(1)
+
+NNAAMMEE
+ eesscc--AA11 - the roff escape A sequence: identifier syntax validation
+
+DDEESSCCRRIIPPTTIIOONN
+ empty: 0
+ letters: 1
+ blank: 0
+ ASCII non-letters: 1
+ invalid escapes: 1
+
+ AArrgguummeenntt ddeelliimmiitteerrss
+ unsupported \r: 1u
+ ignored \&: 1u
+ useless \.: 1u
+ invalid \G: 1u
+ special \-: 1u
+ break \p: 1u
+ nospace \c: 1u
+ string expansion: 1u
+ register expansion: 1u
+ ignored \ON: 1u
+ special character: 1u
+ ignored \Z'str': 1u
+ horizontal motion: 1u
+ horizontal line: 1u
+ overstrike: 1u
+ unterminated: 1
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/A1.out_lint b/regress/roff/esc/A1.out_lint
new file mode 100644
index 00000000..8f7e76d4
--- /dev/null
+++ b/regress/roff/esc/A1.out_lint
@@ -0,0 +1,5 @@
+mandoc: A1.in:17:25: WARNING: undefined escape, printing literally: \G
+mandoc: A1.in:19:20: UNSUPP: unsupported escape sequence: \r
+mandoc: A1.in:19:26: UNSUPP: unsupported escape sequence: \r
+mandoc: A1.in:25:16: WARNING: undefined escape, printing literally: \G
+mandoc: A1.in:53:15: ERROR: incomplete escape sequence: \A'word
diff --git a/regress/roff/esc/B.in b/regress/roff/esc/B.in
index 40cd2ecb..aab552b5 100644
--- a/regress/roff/esc/B.in
+++ b/regress/roff/esc/B.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: B.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $
-.Dd $Mdocdate: July 4 2017 $
+.\" $OpenBSD: B.in,v 1.4 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
.Dt ESC-B 1
.Os
.Sh NAME
@@ -33,5 +33,97 @@ parentheses containing number: \B'(42)'
complex expression: \B'3+(3*(5==5*2)*4)+(3*5)/2'
.br
other delimiter: \Bx1+1x
+.Ss Argument delimiters
+unsupported \e!: \B\!42\!u
.br
-no closing delimiter: \B'1+1
+unsupported \er: \B\r42u
+.br
+ignored \e%: \B\%42\%u
+.br
+ignored \e&: \B\&42\&u
+.br
+ignored \e): \B\)42\)u
+.br
+ignored \e,: \B\,42\,u
+.br
+ignored \e/: \B\/42\/u
+.br
+ignored \e^: \B\^42\^u
+.br
+ignored \ea: \B\a42\au
+.br
+ignored \ed: \B\d42\du
+.br
+ignored \et: \B\t42\tu
+.br
+ignored \eu: \B\u42\uu
+.br
+ignored \e{: \B\{42\{u
+.br
+ignored \e|: \B\|42\|u
+.br
+ignored \e}: \B\}42\}u
+.br
+useless \e.: \B\.42.u
+.\".br
+.\"XXX useless \e\e: \B\\42\\u
+.br
+invalid \eG: \B\G42Gu
+.br
+special \e\ : \B\ 42\ u
+.br
+special \e\(aq: \B\'42\'u
+.br
+special \e-: \B\-42\-u
+.br
+special \e0: \B\042\0u
+.br
+special \e:: \B\:42\:u
+.br
+special \e_: \B\_42\_u
+.br
+special \e\(ga: \B\`42\`u
+.br
+special \ee: \B\e42\eu
+.br
+special \e~: \B\~42\~u
+.br
+break \ep: \B\p42\pu
+.br
+nospace \ec: \B\c42\cu
+.\".br
+.\"XXX skipchar \ec: \B\z42\zu
+.br
+.ds mystr x42xu
+string expansion: \B\*[mystr]
+.br
+.nr myreg 23
+register expansion: \B\n[myreg]u
+.br
+ignored \eO: \B\O142\O2u
+.br
+ignored \eY: \B\Y[mystr]42\Y[mystr]u
+.br
+ignored \ek: \B\k[myreg]42\k[myreg]u
+.br
+special character: \B\(hy42\(hyu
+.br
+ignored \eD: \B\D't 1'42\D't 2'u
+.br
+ignored \eL: \B\L'2'42u
+.br
+ignored \eX: \B\X'foo'42\X'bar'u
+.br
+ignored \eZ: \B\Z'foo'42\Z''u
+.br
+ignored \eb: \B\b'2'42\b''u
+.br
+ignored \ev: \B\v'2'42\v'0'u
+.br
+ignored \ex: \B\x'2'42\v'0'u
+.br
+horizontal motion: \B\h'1'42\h'3'u
+.br
+horizontal line: \B\l'4'42\l'2'u
+.br
+overstrike: \B\o'ab'42\o'cd'u
diff --git a/regress/roff/esc/B.out_ascii b/regress/roff/esc/B.out_ascii
index 805b0641..d42a6901 100644
--- a/regress/roff/esc/B.out_ascii
+++ b/regress/roff/esc/B.out_ascii
@@ -18,6 +18,51 @@ DDEESSCCRRIIPPTTIIOONN
parentheses containing number: 1
complex expression: 1
other delimiter: 1
- no closing delimiter: 0
-OpenBSD July 4, 2017 OpenBSD
+ AArrgguummeenntt ddeelliimmiitteerrss
+ unsupported \!: 1u
+ unsupported \r: 042u
+ ignored \%: 1u
+ ignored \&: 1u
+ ignored \): 1u
+ ignored \,: 042u
+ ignored \/: 1u
+ ignored \^: 042u
+ ignored \a: 042u
+ ignored \d: 042u
+ ignored \t: 042u
+ ignored \u: 042u
+ ignored \{: 1u
+ ignored \|: 042u
+ ignored \}: 1u
+ useless \.: 042.u
+ invalid \G: 1u
+ special \ : 042 u
+ special \': 1u
+ special \-: 1u
+ special \0: 042 u
+ special \:: 1u
+ special \_: 1u
+ special \`: 1u
+ special \e: 1u
+ special \~: 042 u
+ break \p: 1u
+ nospace \c: 1u
+ string expansion: 1u
+ register expansion: 03u
+ ignored \O: 042u
+ ignored \Y: 042u
+ ignored \k: 1u
+ special character: 1u
+ ignored \D: 042u
+ ignored \L: 042u
+ ignored \X: 042u
+ ignored \Z: 042u
+ ignored \b: 042u
+ ignored \v: 042u
+ ignored \x: 042u
+ horizontal motion: 042 u
+ horizontal line: 042__u
+ overstrike: 042cdu
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/B.out_lint b/regress/roff/esc/B.out_lint
index fbaded65..2b8995a1 100644
--- a/regress/roff/esc/B.out_lint
+++ b/regress/roff/esc/B.out_lint
@@ -1 +1,29 @@
-mandoc: B.in:37:23: ERROR: incomplete escape sequence: \B'1+1
+mandoc: B.in:37:20: UNSUPP: unsupported escape sequence: \!
+mandoc: B.in:37:24: UNSUPP: unsupported escape sequence: \!
+mandoc: B.in:39:20: UNSUPP: unsupported escape sequence: \r
+mandoc: B.in:39:18: ERROR: invalid escape argument delimiter: \B\r
+mandoc: B.in:47:14: ERROR: invalid escape argument delimiter: \B\,
+mandoc: B.in:51:14: ERROR: invalid escape argument delimiter: \B\^
+mandoc: B.in:53:14: ERROR: invalid escape argument delimiter: \B\a
+mandoc: B.in:55:14: ERROR: invalid escape argument delimiter: \B\d
+mandoc: B.in:57:14: ERROR: invalid escape argument delimiter: \B\t
+mandoc: B.in:59:14: ERROR: invalid escape argument delimiter: \B\u
+mandoc: B.in:63:14: ERROR: invalid escape argument delimiter: \B\|
+mandoc: B.in:67:14: ERROR: invalid escape argument delimiter: \B\.
+mandoc: B.in:71:16: WARNING: undefined escape, printing literally: \G
+mandoc: B.in:73:15: ERROR: invalid escape argument delimiter: \B\
+mandoc: B.in:79:14: ERROR: invalid escape argument delimiter: \B\0
+mandoc: B.in:89:14: ERROR: invalid escape argument delimiter: \B\~
+mandoc: B.in:101:21: ERROR: invalid escape argument delimiter: \B2
+mandoc: B.in:103:14: ERROR: invalid escape argument delimiter: \B\O1
+mandoc: B.in:105:14: ERROR: invalid escape argument delimiter: \B\Y[mystr]
+mandoc: B.in:111:14: ERROR: invalid escape argument delimiter: \B\D't 1'
+mandoc: B.in:113:14: ERROR: invalid escape argument delimiter: \B\L'2'
+mandoc: B.in:115:14: ERROR: invalid escape argument delimiter: \B\X'foo'
+mandoc: B.in:117:14: ERROR: invalid escape argument delimiter: \B\Z'foo'
+mandoc: B.in:119:14: ERROR: invalid escape argument delimiter: \B\b'2'
+mandoc: B.in:121:14: ERROR: invalid escape argument delimiter: \B\v'2'
+mandoc: B.in:123:14: ERROR: invalid escape argument delimiter: \B\x'2'
+mandoc: B.in:125:20: ERROR: invalid escape argument delimiter: \B\h'1'
+mandoc: B.in:127:18: ERROR: invalid escape argument delimiter: \B\l'4'
+mandoc: B.in:129:13: ERROR: invalid escape argument delimiter: \B\o'ab'
diff --git a/regress/roff/esc/Makefile b/regress/roff/esc/Makefile
index dd816f58..f9d311d2 100644
--- a/regress/roff/esc/Makefile
+++ b/regress/roff/esc/Makefile
@@ -1,10 +1,11 @@
-# $OpenBSD: Makefile,v 1.22 2022/05/30 22:50:40 schwarze Exp $
+# $OpenBSD: Makefile,v 1.23 2022/06/08 13:08:00 schwarze Exp $
REGRESS_TARGETS = one two multi comment
-REGRESS_TARGETS += B bs_man bs_mdoc c c_man E1 e f h hneg l O1 o p r V1 w z
+REGRESS_TARGETS += A1 B bs_man bs_mdoc c c_man E1 e f h hneg
+REGRESS_TARGETS += l O1 o p r V1 w z
REGRESS_TARGETS += ignore invalid unsupp
HTML_TARGETS = f
-LINT_TARGETS = comment B h l O1 r V1 w ignore invalid unsupp
+LINT_TARGETS = comment A1 B h l O1 o r V1 w ignore invalid unsupp
# mandoc defects:
# - \h with a negative argument replaces output characters
diff --git a/regress/roff/esc/h.in b/regress/roff/esc/h.in
index 0dc7f786..73c0841e 100644
--- a/regress/roff/esc/h.in
+++ b/regress/roff/esc/h.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: h.in,v 1.6 2017/07/04 14:53:27 schwarze Exp $
-.Dd $Mdocdate: July 4 2017 $
+.\" $OpenBSD: h.in,v 1.7 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
.Dt ESC-H 1
.Os
.Sh NAME
@@ -19,5 +19,99 @@ escape at the end: >\h'0+\w'\&''<
escape at the beginning: >\h'\w'\&'M+0'<
.br
escape in the middle: >\h'0+\w'\&'+0'<
+.Ss Argument delimiters
+invalid ASCII: >\h-<
.br
-invalid delimiter: >\h-<
+unsupported \e!: \h\!2\!u
+.br
+unsupported \er: \h\r2u
+.br
+ignored \e%: \h\%2\%u
+.br
+ignored \e&: \h\&2\&u
+.br
+ignored \e): \h\)2\)u
+.br
+ignored \e,: \h\,2\,u
+.br
+ignored \e/: \h\/2\/u
+.br
+ignored \e^: \h\^2\^u
+.br
+ignored \ea: \h\a2\au
+.br
+ignored \ed: \h\d2\du
+.br
+ignored \et: \h\t2\tu
+.br
+ignored \eu: \h\u2\uu
+.br
+ignored \e{: \h\{2\{u
+.br
+ignored \e|: \h\|2\|u
+.br
+ignored \e}: \h\}2\}u
+.br
+useless \e.: \h\.2.u
+.\".br
+.\"XXX useless \e\e: \h\\2\\u
+.br
+invalid \eG: \h\G2Gu
+.br
+special \e\ : \h\ 2\ u
+.br
+special \e\(aq: \h\'2\'u
+.br
+special \e-: \h\-2\-u
+.br
+special \e0: \h\02\0u
+.br
+special \e:: \h\:2\:u
+.br
+special \e_: \h\_2\_u
+.br
+special \e\(ga: \h\`2\`u
+.br
+special \ee: \h\e2\eu
+.br
+special \e~: \h\~2\~u
+.br
+break \ep: \h\p2\pu
+.br
+nospace \ec: \h\c2\cu
+.\".br
+.\"XXX skipchar \ec: \h\z2\zu
+.br
+.ds mystr x2xu
+string expansion: \h\*[mystr]
+.br
+.nr myreg 121
+register expansion: \h\n[myreg]u
+.br
+ignored \eO: \h\O12\O2u
+.br
+ignored \eY: \h\Y[mystr]2\Y[mystr]u
+.br
+ignored \ek: \h\k[myreg]2\k[myreg]u
+.br
+special character: \h\(hy2\(hyu
+.br
+ignored \eD: \h\D't 1'2\D't 3'u
+.br
+ignored \eL: \h\L'3'2u
+.br
+ignored \eX: \h\X'foo'2\X'bar'u
+.br
+ignored \eZ: \h\Z'foo'2\Z''u
+.br
+ignored \eb: \h\b'3'2\b''u
+.br
+ignored \ev: \h\v'3'2\v'0'u
+.br
+ignored \ex: \h\x'3'2\v'0'u
+.br
+horizontal motion: \h\h'1'2\h'3'u
+.br
+horizontal line: \h\l'4'2\l'3'u
+.br
+overstrike: \h\o'ab'2\o'cd'u
diff --git a/regress/roff/esc/h.out_ascii b/regress/roff/esc/h.out_ascii
index e232670b..738ec9da 100644
--- a/regress/roff/esc/h.out_ascii
+++ b/regress/roff/esc/h.out_ascii
@@ -11,6 +11,52 @@ DDEESSCCRRIIPPTTIIOONN
escape at the end: ><
escape at the beginning: ><
escape in the middle: ><
- invalid delimiter: ><
-OpenBSD July 4, 2017 OpenBSD
+ AArrgguummeenntt ddeelliimmiitteerrss
+ invalid ASCII: ><
+ unsupported \!: u
+ unsupported \r: 2u
+ ignored \%: u
+ ignored \&: u
+ ignored \): u
+ ignored \,: 2u
+ ignored \/: u
+ ignored \^: 2u
+ ignored \a: 2u
+ ignored \d: 2u
+ ignored \t: 2u
+ ignored \u: 2u
+ ignored \{: u
+ ignored \|: 2u
+ ignored \}: u
+ useless \.: 2.u
+ invalid \G: u
+ special \ : 2 u
+ special \': u
+ special \-: u
+ special \0: 2 u
+ special \:: u
+ special \_: u
+ special \`: u
+ special \e: u
+ special \~: 2 u
+ break \p: u
+ nospace \c: u
+ string expansion: u
+ register expansion: 21u
+ ignored \O: 2u
+ ignored \Y: 2u
+ ignored \k: u
+ special character: u
+ ignored \D: 2u
+ ignored \L: 2u
+ ignored \X: 2u
+ ignored \Z: 2u
+ ignored \b: 2u
+ ignored \v: 2u
+ ignored \x: 2u
+ horizontal motion: 2 u
+ horizontal line: 2___u
+ overstrike: 2cdu
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/h.out_lint b/regress/roff/esc/h.out_lint
index 99d6a1d4..8c2f29ef 100644
--- a/regress/roff/esc/h.out_lint
+++ b/regress/roff/esc/h.out_lint
@@ -1 +1,30 @@
-mandoc: h.in:23:21: ERROR: invalid escape argument delimiter: \h-
+mandoc: h.in:23:17: ERROR: invalid escape argument delimiter: \h-
+mandoc: h.in:25:20: UNSUPP: unsupported escape sequence: \!
+mandoc: h.in:25:23: UNSUPP: unsupported escape sequence: \!
+mandoc: h.in:27:20: UNSUPP: unsupported escape sequence: \r
+mandoc: h.in:27:18: ERROR: invalid escape argument delimiter: \h\r
+mandoc: h.in:35:14: ERROR: invalid escape argument delimiter: \h\,
+mandoc: h.in:39:14: ERROR: invalid escape argument delimiter: \h\^
+mandoc: h.in:41:14: ERROR: invalid escape argument delimiter: \h\a
+mandoc: h.in:43:14: ERROR: invalid escape argument delimiter: \h\d
+mandoc: h.in:45:14: ERROR: invalid escape argument delimiter: \h\t
+mandoc: h.in:47:14: ERROR: invalid escape argument delimiter: \h\u
+mandoc: h.in:51:14: ERROR: invalid escape argument delimiter: \h\|
+mandoc: h.in:55:14: ERROR: invalid escape argument delimiter: \h\.
+mandoc: h.in:59:16: WARNING: undefined escape, printing literally: \G
+mandoc: h.in:61:15: ERROR: invalid escape argument delimiter: \h\
+mandoc: h.in:67:14: ERROR: invalid escape argument delimiter: \h\0
+mandoc: h.in:77:14: ERROR: invalid escape argument delimiter: \h\~
+mandoc: h.in:89:21: ERROR: invalid escape argument delimiter: \h1
+mandoc: h.in:91:14: ERROR: invalid escape argument delimiter: \h\O1
+mandoc: h.in:93:14: ERROR: invalid escape argument delimiter: \h\Y[mystr]
+mandoc: h.in:99:14: ERROR: invalid escape argument delimiter: \h\D't 1'
+mandoc: h.in:101:14: ERROR: invalid escape argument delimiter: \h\L'3'
+mandoc: h.in:103:14: ERROR: invalid escape argument delimiter: \h\X'foo'
+mandoc: h.in:105:14: ERROR: invalid escape argument delimiter: \h\Z'foo'
+mandoc: h.in:107:14: ERROR: invalid escape argument delimiter: \h\b'3'
+mandoc: h.in:109:14: ERROR: invalid escape argument delimiter: \h\v'3'
+mandoc: h.in:111:14: ERROR: invalid escape argument delimiter: \h\x'3'
+mandoc: h.in:113:20: ERROR: invalid escape argument delimiter: \h\h'1'
+mandoc: h.in:115:18: ERROR: invalid escape argument delimiter: \h\l'4'
+mandoc: h.in:117:13: ERROR: invalid escape argument delimiter: \h\o'ab'
diff --git a/regress/roff/esc/l.in b/regress/roff/esc/l.in
index 47b02d8c..c141faa1 100644
--- a/regress/roff/esc/l.in
+++ b/regress/roff/esc/l.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: l.in,v 1.3 2022/06/07 09:51:03 schwarze Exp $
-.Dd $Mdocdate: June 7 2022 $
+.\" $OpenBSD: l.in,v 1.4 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
.Dt ESC-L 1
.Os
.Sh NAME
@@ -19,5 +19,99 @@ explicit scaling unit and escape sequence: >\l'6n\(+-'<
default unit and escape char: >\l'7n\(at'<
.br
rounding: >\l'0.26ix'<
+.Ss Argument delimiters
+invalid ASCII: >\l-<
.br
-invalid delimiter: >\l-<
+unsupported \e!: \l\!2\!u
+.br
+unsupported \er: \l\r2u
+.br
+ignored \e%: \l\%2\%u
+.br
+ignored \e&: \l\&2nx\&u
+.br
+ignored \e): \l\)2nx\)u
+.br
+ignored \e,: \l\,2\,u
+.br
+ignored \e/: \l\/2\/u
+.br
+ignored \e^: \l\^2\^u
+.br
+ignored \ea: \l\a2\au
+.br
+ignored \ed: \l\d2\du
+.br
+ignored \et: \l\t2\tu
+.br
+ignored \eu: \l\u2\uu
+.br
+ignored \e{: \l\{2\{u
+.br
+ignored \e|: \l\|2\|u
+.br
+ignored \e}: \l\}2\}u
+.br
+useless \e.: \l\.2.u
+.\".br
+.\"XXX useless \e\e: \l\\2\\u
+.br
+invalid \eG: \l\G2Gu
+.br
+special \e\ : \l\ 2\ u
+.br
+special \e\(aq: \l\'2nx\'u
+.br
+special \e-: \l\-2nx\-u
+.br
+special \e0: \l\02\0u
+.br
+special \e:: \l\:2\:u
+.br
+special \e_: \l\_2\_u
+.br
+special \e\(ga: \l\`2nx\`u
+.br
+special \ee: \l\e2nx\eu
+.br
+special \e~: \l\~2\~u
+.br
+break \ep: \l\p2\pu
+.br
+nospace \ec: \l\c2\cu
+.\".br
+.\"XXX skipchar \ec: \l\z2\zu
+.br
+.ds mystr x2xu
+string expansion: \l\*[mystr]
+.br
+.nr myreg 121
+register expansion: \l\n[myreg]u
+.br
+ignored \eO: \l\O12\O2u
+.br
+ignored \eY: \l\Y[mystr]2\Y[mystr]u
+.br
+ignored \ek: \l\k[myreg]2\k[myreg]u
+.br
+special character: \l\(hy2nx\(hyu
+.br
+ignored \eD: \l\D't 1'2\D't 3'u
+.br
+ignored \eL: \l\L'3'2u
+.br
+ignored \eX: \l\X'foo'2\X'bar'u
+.br
+ignored \eZ: \l\Z'foo'2\Z''u
+.br
+ignored \eb: \l\b'3'2\b''u
+.br
+ignored \ev: \l\v'3'2\v'0'u
+.br
+ignored \ex: \l\x'3'2\v'0'u
+.br
+horizontal motion: \l\h'1'2\h'3'u
+.br
+horizontal line: \l\l'4'2\l'3'u
+.br
+overstrike: \l\o'ab'2\o'cd'u
diff --git a/regress/roff/esc/l.out_ascii b/regress/roff/esc/l.out_ascii
index 9e34d79b..9f292f42 100644
--- a/regress/roff/esc/l.out_ascii
+++ b/regress/roff/esc/l.out_ascii
@@ -11,6 +11,52 @@ DDEESSCCRRIIPPTTIIOONN
explicit scaling unit and escape sequence: >+-+-+-<
default unit and escape char: >@@@@@@@<
rounding: >xxx<
- invalid delimiter: ><
-OpenBSD June 7, 2022 OpenBSD
+ AArrgguummeenntt ddeelliimmiitteerrss
+ invalid ASCII: ><
+ unsupported \!: __u
+ unsupported \r: 2u
+ ignored \%: __u
+ ignored \&: xxu
+ ignored \): xxu
+ ignored \,: 2u
+ ignored \/: __u
+ ignored \^: 2u
+ ignored \a: 2u
+ ignored \d: 2u
+ ignored \t: 2u
+ ignored \u: 2u
+ ignored \{: __u
+ ignored \|: 2u
+ ignored \}: __u
+ useless \.: 2.u
+ invalid \G: __u
+ special \ : 2 u
+ special \': xxu
+ special \-: xxu
+ special \0: 2 u
+ special \:: __u
+ special \_: __u
+ special \`: xxu
+ special \e: xxu
+ special \~: 2 u
+ break \p: __u
+ nospace \c: __u
+ string expansion: __u
+ register expansion: 21u
+ ignored \O: 2u
+ ignored \Y: 2u
+ ignored \k: __u
+ special character: xxu
+ ignored \D: 2u
+ ignored \L: 2u
+ ignored \X: 2u
+ ignored \Z: 2u
+ ignored \b: 2u
+ ignored \v: 2u
+ ignored \x: 2u
+ horizontal motion: 2 u
+ horizontal line: 2___u
+ overstrike: 2cdu
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/l.out_lint b/regress/roff/esc/l.out_lint
index 87df1bdd..0fac0eb7 100644
--- a/regress/roff/esc/l.out_lint
+++ b/regress/roff/esc/l.out_lint
@@ -1 +1,30 @@
-mandoc: l.in:23:21: ERROR: invalid escape argument delimiter: \l-
+mandoc: l.in:23:17: ERROR: invalid escape argument delimiter: \l-
+mandoc: l.in:25:20: UNSUPP: unsupported escape sequence: \!
+mandoc: l.in:25:23: UNSUPP: unsupported escape sequence: \!
+mandoc: l.in:27:20: UNSUPP: unsupported escape sequence: \r
+mandoc: l.in:27:18: ERROR: invalid escape argument delimiter: \l\r
+mandoc: l.in:35:14: ERROR: invalid escape argument delimiter: \l\,
+mandoc: l.in:39:14: ERROR: invalid escape argument delimiter: \l\^
+mandoc: l.in:41:14: ERROR: invalid escape argument delimiter: \l\a
+mandoc: l.in:43:14: ERROR: invalid escape argument delimiter: \l\d
+mandoc: l.in:45:14: ERROR: invalid escape argument delimiter: \l\t
+mandoc: l.in:47:14: ERROR: invalid escape argument delimiter: \l\u
+mandoc: l.in:51:14: ERROR: invalid escape argument delimiter: \l\|
+mandoc: l.in:55:14: ERROR: invalid escape argument delimiter: \l\.
+mandoc: l.in:59:16: WARNING: undefined escape, printing literally: \G
+mandoc: l.in:61:15: ERROR: invalid escape argument delimiter: \l\
+mandoc: l.in:67:14: ERROR: invalid escape argument delimiter: \l\0
+mandoc: l.in:77:14: ERROR: invalid escape argument delimiter: \l\~
+mandoc: l.in:89:21: ERROR: invalid escape argument delimiter: \l1
+mandoc: l.in:91:14: ERROR: invalid escape argument delimiter: \l\O1
+mandoc: l.in:93:14: ERROR: invalid escape argument delimiter: \l\Y[mystr]
+mandoc: l.in:99:14: ERROR: invalid escape argument delimiter: \l\D't 1'
+mandoc: l.in:101:14: ERROR: invalid escape argument delimiter: \l\L'3'
+mandoc: l.in:103:14: ERROR: invalid escape argument delimiter: \l\X'foo'
+mandoc: l.in:105:14: ERROR: invalid escape argument delimiter: \l\Z'foo'
+mandoc: l.in:107:14: ERROR: invalid escape argument delimiter: \l\b'3'
+mandoc: l.in:109:14: ERROR: invalid escape argument delimiter: \l\v'3'
+mandoc: l.in:111:14: ERROR: invalid escape argument delimiter: \l\x'3'
+mandoc: l.in:113:20: ERROR: invalid escape argument delimiter: \l\h'1'
+mandoc: l.in:115:18: ERROR: invalid escape argument delimiter: \l\l'4'
+mandoc: l.in:117:13: ERROR: invalid escape argument delimiter: \l\o'ab'
diff --git a/regress/roff/esc/o.in b/regress/roff/esc/o.in
index 1f9f5039..aa0ba657 100644
--- a/regress/roff/esc/o.in
+++ b/regress/roff/esc/o.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: o.in,v 1.2 2017/07/04 14:53:27 schwarze Exp $
-.Dd $Mdocdate: July 4 2017 $
+.\" $OpenBSD: o.in,v 1.3 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
.Dt ESC-O 1
.Os
.Sh NAME
@@ -17,3 +17,39 @@ narrow/wide: x\o'|O'x
wide/narrow/narrow: x\o'O-|'x
.br
narrow/narrow/wide: x\o'|-O'x
+.Ss Argument delimiters
+unsupported \er: \o\rxy\ru
+.br
+ignored \e&: \o\&xy\&u
+.br
+useless \e.: \o\.xy.u
+.br
+invalid \eG: \o\GxyGu
+.br
+special \e-: \o\-xy\-u
+.br
+break \ep: \o\pxy\pu
+.br
+nospace \ec: \o\cxy\cu
+.\".br
+.\"XXX skipchar \ec: \o\zxy\zu
+.br
+.ds mystr zx
+string expansion: \o\*[mystr]yzu
+.br
+.nr myreg 12
+register expansion: \o\n[myreg]31u
+.br
+ignored \eON: \o\O1xy\O2u
+.br
+special character: \o\(hyxy\(hyu
+.br
+ignored \eZ\(aqstr\(aq: \o\Z'foo'xy\Z'bar'u
+.br
+horizontal motion: \o\h'1'xy\h'3'u
+.br
+horizontal line: \o\l'4'xy\l'2'u
+.br
+overstrike: \o\o'ab'xy\o'cd'u
+.br
+unterminated: \o'xy
diff --git a/regress/roff/esc/o.out_ascii b/regress/roff/esc/o.out_ascii
index a8c4e0b1..6d990d44 100644
--- a/regress/roff/esc/o.out_ascii
+++ b/regress/roff/esc/o.out_ascii
@@ -11,4 +11,22 @@ DDEESSCCRRIIPPTTIIOONN
wide/narrow/narrow: xO-|x
narrow/narrow/wide: x|-Ox
-OpenBSD July 4, 2017 OpenBSD
+ AArrgguummeenntt ddeelliimmiitteerrss
+ unsupported \r: xyu
+ ignored \&: xyu
+ useless \.: xyu
+ invalid \G: xyu
+ special \-: xyu
+ break \p: xyu
+ nospace \c: xyu
+ string expansion: xyu
+ register expansion: 23u
+ ignored \ON: xyu
+ special character: xyu
+ ignored \Z'str': xyu
+ horizontal motion: xyu
+ horizontal line: xyu
+ overstrike: xyu
+ unterminated: xy
+
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/w.in b/regress/roff/esc/w.in
index a7b32828..e6ee6be7 100644
--- a/regress/roff/esc/w.in
+++ b/regress/roff/esc/w.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: w.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $
-.Dd $Mdocdate: July 4 2017 $
+.\" $OpenBSD: w.in,v 1.4 2022/06/08 13:08:00 schwarze Exp $
+.Dd $Mdocdate: June 8 2022 $
.Dt ESC-W 1
.Os
.Sh NAME
@@ -13,5 +13,39 @@ character: \w'n'
blank: \w' '
.br
text: \w'text'
+.Ss Argument delimiters
+unsupported \er: \w\rM\ru
+.br
+ignored \e&: \w\&M\&u
+.br
+useless \e.: \w\.M.u
+.br
+invalid \eG: \w\GMGu
+.br
+special \e-: \w\-M\-u
+.br
+break \ep: \w\pM\pu
+.br
+nospace \ec: \w\cM\cu
+.\".br
+.\"XXX skipchar \ec: \w\zM\zu
+.br
+.ds mystr xMxu
+string expansion: \w\*[mystr]
+.br
+.nr myreg 121
+register expansion: \w\n[myreg]u
+.br
+ignored \eON: \w\O1M\O2u
+.br
+special character: \w\(hyM\(hyu
+.br
+ignored \eZ\(aqstr\(aq: \w\Z'foo'M\Z'bar'u
+.br
+horizontal motion: \w\h'1'M\h'3'u
+.br
+horizontal line: \w\l'4'M\l'2'u
+.br
+overstrike: \w\o'ab'M\o'cd'u
.br
unterminated: \w'foo
diff --git a/regress/roff/esc/w.out_ascii b/regress/roff/esc/w.out_ascii
index 3b8650a1..7ed32ece 100644
--- a/regress/roff/esc/w.out_ascii
+++ b/regress/roff/esc/w.out_ascii
@@ -8,6 +8,23 @@ DDEESSCCRRIIPPTTIIOONN
character: 24
blank: 24
text: 96
+
+ AArrgguummeenntt ddeelliimmiitteerrss
+ unsupported \r: 24u
+ ignored \&: 24u
+ useless \.: 24u
+ invalid \G: 24u
+ special \-: 24u
+ break \p: 24u
+ nospace \c: 24u
+ string expansion: 24u
+ register expansion: 24u
+ ignored \ON: 24u
+ special character: 24u
+ ignored \Z'str': 24u
+ horizontal motion: 24u
+ horizontal line: 24u
+ overstrike: 24u
unterminated: 72
-OpenBSD July 4, 2017 OpenBSD
+OpenBSD June 8, 2022 OpenBSD
diff --git a/regress/roff/esc/w.out_lint b/regress/roff/esc/w.out_lint
index 11dfbef5..fd2a0948 100644
--- a/regress/roff/esc/w.out_lint
+++ b/regress/roff/esc/w.out_lint
@@ -1 +1,4 @@
-mandoc: w.in:17:15: ERROR: incomplete escape sequence: \w'foo
+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
diff --git a/roff_escape.c b/roff_escape.c
index 333e0e3f..b1a4fbeb 100644
--- a/roff_escape.c
+++ b/roff_escape.c
@@ -1,4 +1,4 @@
-/* $Id: roff_escape.c,v 1.13 2022/06/07 09:54:40 schwarze Exp $ */
+/* $Id: roff_escape.c,v 1.14 2022/06/08 13:23:57 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022
* Ingo Schwarze <schwarze@openbsd.org>
@@ -59,7 +59,7 @@ mandoc_escape(const char **rendarg, const char **rarg, int *rargl)
* sequence are returned in *resc ... *rend.
* Otherwise, *resc is set to aesc and the positions of the escape
* sequence starting at aesc are returned.
- * Diagnostic messages are generated if and only if resc != NULL,
+ * Diagnostic messages are generated if and only if ln != 0,
* that is, if and only if called by roff_expand().
*/
enum mandoc_esc
@@ -72,11 +72,13 @@ roff_escape(const char *buf, const int ln, const int aesc,
int iendarg; /* index right after the argument */
int iend; /* index right after the sequence */
int sesc, snam, sarg, sendarg, send; /* for sub-escape */
+ int escterm; /* whether term is escaped */
int maxl; /* expected length of the argument */
int argl; /* actual length of the argument */
int c, i; /* for \[char...] parsing */
int valid_A; /* for \A parsing */
enum mandoc_esc rval; /* return value */
+ enum mandoc_esc stype; /* for sub-escape */
enum mandocerr err; /* diagnostic code */
char term; /* byte terminating the argument */
@@ -264,13 +266,32 @@ roff_escape(const char *buf, const int ln, const int aesc,
/* Decide how to end the argument. */
+ escterm = 0;
+ stype = ESCAPE_EXPAND;
if ((term == '\b' || (term == '\0' && maxl == INT_MAX)) &&
- buf[iarg] == buf[iesc] && roff_escape(buf, ln, iendarg,
- &sesc, &snam, &sarg, &sendarg, &send) == ESCAPE_EXPAND)
- goto out_sub;
+ buf[iarg] == buf[iesc]) {
+ stype = roff_escape(buf, ln, iendarg,
+ &sesc, &snam, &sarg, &sendarg, &send);
+ if (stype == ESCAPE_EXPAND)
+ goto out_sub;
+ }
if (term == '\b') {
- if (strchr("BDHLRSvxNhl", buf[inam]) != NULL &&
+ if (stype == ESCAPE_UNDEF)
+ iarg++;
+ if (stype != ESCAPE_EXPAND && stype != ESCAPE_UNDEF) {
+ if (strchr("BHLRSNhlvx", buf[inam]) != NULL &&
+ strchr(" ,.0DLOXYZ^abdhlortuvx|~",
+ buf[snam]) != NULL) {
+ err = MANDOCERR_ESC_DELIM;
+ iend = send;
+ iarg = iendarg = sesc;
+ goto out;
+ }
+ escterm = 1;
+ iarg = send;
+ term = buf[snam];
+ } else if (strchr("BDHLRSvxNhl", buf[inam]) != NULL &&
strchr(" %&()*+-./0123456789:<=>", buf[iarg]) != NULL) {
err = MANDOCERR_ESC_DELIM;
if (rval != ESCAPE_EXPAND)
@@ -280,7 +301,8 @@ roff_escape(const char *buf, const int ln, const int aesc,
goto out;
}
}
- term = buf[iarg++];
+ if (term == '\b')
+ term = buf[iarg++];
} else if (term == '\0' && maxl == INT_MAX) {
if (buf[inam] == 'n' && (buf[iarg] == '+' || buf[iarg] == '-'))
iarg++;
@@ -311,34 +333,34 @@ roff_escape(const char *buf, const int ln, const int aesc,
while (maxl > 0) {
if (buf[iendarg] == '\0') {
err = MANDOCERR_ESC_INCOMPLETE;
- if (rval != ESCAPE_EXPAND)
+ if (rval != ESCAPE_EXPAND &&
+ rval != ESCAPE_OVERSTRIKE)
rval = ESCAPE_ERROR;
- /* Ignore an incomplete argument except for \w. */
- if (buf[inam] != 'w')
+ /* Usually, ignore an incomplete argument. */
+ if (strchr("Aow", buf[inam]) == NULL)
iendarg = iarg;
break;
}
- if (buf[iendarg] == term) {
- iend = iendarg + 1;
- break;
- }
- if (buf[inam] == 'N' &&
- isdigit((unsigned char)buf[iendarg]) == 0) {
+ if (escterm == 0 && buf[iendarg] == term) {
iend = iendarg + 1;
break;
}
if (buf[iendarg] == buf[iesc]) {
- switch (roff_escape(buf, ln, iendarg,
- &sesc, &snam, &sarg, &sendarg, &send)) {
- case ESCAPE_EXPAND:
+ stype = roff_escape(buf, ln, iendarg,
+ &sesc, &snam, &sarg, &sendarg, &send);
+ if (stype == ESCAPE_EXPAND)
goto out_sub;
- case ESCAPE_UNDEF:
+ iend = send;
+ if (escterm == 1 &&
+ (buf[snam] == term || buf[inam] == 'N'))
break;
- default:
+ if (stype != ESCAPE_UNDEF)
valid_A = 0;
- break;
- }
- iendarg = iend = send;
+ iendarg = send;
+ } else if (buf[inam] == 'N' &&
+ isdigit((unsigned char)buf[iendarg]) == 0) {
+ iend = iendarg + 1;
+ break;
} else {
if (buf[iendarg] == ' ' || buf[iendarg] == '\t')
valid_A = 0;
@@ -483,6 +505,8 @@ out_sub:
rval = ESCAPE_EXPAND;
out:
+ if (resc != NULL)
+ *resc = iesc;
if (rnam != NULL)
*rnam = inam;
if (rarg != NULL)
@@ -491,7 +515,7 @@ out:
*rendarg = iendarg;
if (rend != NULL)
*rend = iend;
- if (resc == NULL)
+ if (ln == 0)
return rval;
/*
@@ -499,7 +523,6 @@ out:
* from the parser, not when called from the formatters.
*/
- *resc = iesc;
switch (rval) {
case ESCAPE_UNSUPP:
err = MANDOCERR_ESC_UNSUPP;