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