xref: /freebsd/contrib/bmake/unit-tests/char-005c-reverse-solidus.mk (revision 4b15965daa99044daf184221b7c283bf7f2d7e66)
1# $NetBSD: char-005c-reverse-solidus.mk,v 1.2 2025/06/29 11:27:21 rillig Exp $
2#
3# Tests for the character U+005C "REVERSE SOLIDUS".
4#
5# See also:
6#	TODO
7#	TODO
8#	TODO
9
10# TODO: Where is this character used normally?
11# TODO: What are the edge cases?
12
13# TODO: escape '#' in lines
14# TODO: escape '#' in comments
15# TODO: escape ':' in modifiers
16# TODO: escape any character in condition strings
17
18# begin https://gnats.netbsd.org/46139
19
20# Too see the details of parsing, uncomment the following line.
21#.MAKEFLAGS: -dcpv
22
23# This backslash is treated as a line continuation.
24# It does not end up in the variable value.
25LINE_CONTINUATION=foo\
26# This line is still part of the variable assignment
27.if ${LINE_CONTINUATION:C,[^a-z],<>,gW} != "foo"
28.  error
29.endif
30
31# The variable value contains two backslashes.
32TWO_BACKSLASHES_AT_EOL=foo\\
33.if ${TWO_BACKSLASHES_AT_EOL:C,[^a-z],<>,gW} != "foo<><>"
34.  error
35.endif
36
37TRAILING_WHITESPACE=foo\ # trailing space
38.if ${TRAILING_WHITESPACE:C,[^a-z],<>,gW} != "foo<><>"
39.  error
40.endif
41
42# The simplest was to produce a single backslash is the :U modifier.
43BACKSLASH=	${:U\\}
44.if ${BACKSLASH} != "\\"
45.  error
46.endif
47BACKSLASH_C=	${:U1:C,.,\\,}
48.if ${BACKSLASH_C} != "\\"
49.  error
50.endif
51
52# expect+5: Unclosed expression, expecting "}" for modifier "Mx\}"
53# At the point where the unclosed expression is detected, the ":M" modifier
54# has been applied to the expression.  Its pattern is "x}", which doesn't
55# match the single backslash.
56# expect: while evaluating variable "BACKSLASH" with value ""
57.if ${BACKSLASH:Mx\}
58.  error
59.else
60.  error
61.endif
62
63# expect+1: Unclosed expression, expecting "}" for modifier "Mx\\}"
64.if ${BACKSLASH:Mx\\}
65.  error
66.else
67.  error
68.endif
69
70# expect+1: Unclosed expression, expecting "}" for modifier "Mx\\\\\\\\}"
71.if ${BACKSLASH:Mx\\\\\\\\}
72.  error
73.else
74.  error
75.endif
76
77# Adding more text after the backslash adds to the pattern, as the backslash
78# serves to escape the ":" that is otherwise used to separate the modifiers.
79# The result is a single ":M" modifier with the pattern "x:Nzzz".
80.if ${BACKSLASH:Mx\:Nzzz} != ""
81.  error
82.endif
83
84# The pattern ends up as "x\:Nzzz".  Only the sequence "\:" is unescaped, all
85# others, including "\\", are left as-is.
86.if ${BACKSLASH:Mx\\:Nzzz} != ""
87.  error
88.endif
89
90# The pattern for the ":M" modifier ends up as "x\\\\\\\:Nzzz".  Only the
91# sequence "\:" is unescaped, all others, including "\\", are left as-is.
92.if ${BACKSLASH:Mx\\\\\\\\:Nzzz} != ""
93.  error
94.endif
95
96# The ":M" modifier is parsed differently than the other modifiers.  To
97# circumvent the peculiarities of that parser, the pattern can be passed via
98# an expression.  There, the usual escaping rules for modifiers apply.
99# expect+1: Unfinished backslash at the end in pattern "\" of modifier ":M"
100.if ${BACKSLASH:M${BACKSLASH}} != "\\"
101.  error
102.else
103.  error
104.endif
105
106# Trying to bypass the parser by using a direct expression doesn't work, as
107# the parser for the ":M" modifier does not parse the subexpression like in
108# all other places, but instead counts the braces and tries to decode the
109# escaping, which fails in this case.
110# expect+1: Unclosed expression, expecting "}" for modifier "M${:U\\\\}} != "\\""
111.if ${BACKSLASH:M${:U\\\\}} != "\\"
112.  error
113.else
114.  error
115.endif
116
117# Matching a backslash with the pattern matching characters works.
118.if ${BACKSLASH:M?} != "\\"
119.  error
120.endif
121.if ${BACKSLASH:M*} != "\\"
122.  error
123.endif
124.if ${BACKSLASH:M[Z-a]} != "\\"
125.  error
126.endif
127.if ${BACKSLASH:M[\\]} != "\\"
128.  error
129.endif
130
131# end https://gnats.netbsd.org/46139
132