1*1d3f2ddcSSimon J. Gerraty# $NetBSD: varmod-match.mk,v 1.8 2022/03/27 18:39:01 rillig Exp $ 22c3632d1SSimon J. Gerraty# 32c3632d1SSimon J. Gerraty# Tests for the :M variable modifier, which filters words that match the 42c3632d1SSimon J. Gerraty# given pattern. 5956e45f6SSimon J. Gerraty# 6956e45f6SSimon J. Gerraty# See ApplyModifier_Match and ModifyWord_Match for the implementation. 72c3632d1SSimon J. Gerraty 8956e45f6SSimon J. Gerraty.MAKEFLAGS: -dc 92c3632d1SSimon J. Gerraty 102c3632d1SSimon J. GerratyNUMBERS= One Two Three Four five six seven 112c3632d1SSimon J. Gerraty 12956e45f6SSimon J. Gerraty# Only keep words that start with an uppercase letter. 13956e45f6SSimon J. Gerraty.if ${NUMBERS:M[A-Z]*} != "One Two Three Four" 14956e45f6SSimon J. Gerraty. error 15956e45f6SSimon J. Gerraty.endif 162c3632d1SSimon J. Gerraty 17956e45f6SSimon J. Gerraty# Only keep words that start with a character other than an uppercase letter. 18956e45f6SSimon J. Gerraty.if ${NUMBERS:M[^A-Z]*} != "five six seven" 19956e45f6SSimon J. Gerraty. error 20956e45f6SSimon J. Gerraty.endif 21956e45f6SSimon J. Gerraty 22956e45f6SSimon J. Gerraty# Only keep words that don't start with s and at the same time end with 23956e45f6SSimon J. Gerraty# either of [ex]. 24956e45f6SSimon J. Gerraty# 25956e45f6SSimon J. Gerraty# This test case ensures that the negation from the first character class 26956e45f6SSimon J. Gerraty# does not propagate to the second character class. 27956e45f6SSimon J. Gerraty.if ${NUMBERS:M[^s]*[ex]} != "One Three five" 28956e45f6SSimon J. Gerraty. error 29956e45f6SSimon J. Gerraty.endif 302c3632d1SSimon J. Gerraty 312c3632d1SSimon J. Gerraty# Before 2020-06-13, this expression took quite a long time in Str_Match, 322c3632d1SSimon J. Gerraty# calling itself 601080390 times for 16 asterisks. 33956e45f6SSimon J. Gerraty.if ${:U****************:M****************b} 34956e45f6SSimon J. Gerraty.endif 35956e45f6SSimon J. Gerraty 36956e45f6SSimon J. Gerraty# To match a dollar sign in a word, double it. 37956e45f6SSimon J. Gerraty# 38956e45f6SSimon J. Gerraty# This is different from the :S and :C variable modifiers, where a '$' 39956e45f6SSimon J. Gerraty# has to be escaped as '\$'. 40956e45f6SSimon J. Gerraty.if ${:Ua \$ sign:M*$$*} != "\$" 41956e45f6SSimon J. Gerraty. error 42956e45f6SSimon J. Gerraty.endif 43956e45f6SSimon J. Gerraty 44956e45f6SSimon J. Gerraty# In the :M modifier, '\$' does not escape a dollar. Instead it is 45956e45f6SSimon J. Gerraty# interpreted as a backslash followed by whatever expression the 46956e45f6SSimon J. Gerraty# '$' starts. 47956e45f6SSimon J. Gerraty# 48956e45f6SSimon J. Gerraty# This differs from the :S, :C and several other variable modifiers. 49956e45f6SSimon J. Gerraty${:U*}= asterisk 50956e45f6SSimon J. Gerraty.if ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk" 51956e45f6SSimon J. Gerraty. error 52956e45f6SSimon J. Gerraty.endif 53956e45f6SSimon J. Gerraty 54e2eeea75SSimon J. Gerraty# TODO: ${VAR:M(((}}}} 55e2eeea75SSimon J. Gerraty# TODO: ${VAR:M{{{)))} 56e2eeea75SSimon J. Gerraty# TODO: ${VAR:M${UNBALANCED}} 57e2eeea75SSimon J. Gerraty# TODO: ${VAR:M${:U(((\}\}\}}} 58e2eeea75SSimon J. Gerraty 59*1d3f2ddcSSimon J. Gerraty.MAKEFLAGS: -d0 60*1d3f2ddcSSimon J. Gerraty 61*1d3f2ddcSSimon J. Gerraty# Special characters: 62*1d3f2ddcSSimon J. Gerraty# * matches 0 or more arbitrary characters 63*1d3f2ddcSSimon J. Gerraty# ? matches a single arbitrary character 64*1d3f2ddcSSimon J. Gerraty# \ starts an escape sequence, only outside ranges 65*1d3f2ddcSSimon J. Gerraty# [ starts a set for matching a single character 66*1d3f2ddcSSimon J. Gerraty# ] ends a set for matching a single character 67*1d3f2ddcSSimon J. Gerraty# - in a set, forms a range of characters 68*1d3f2ddcSSimon J. Gerraty# ^ as the first character in a set, negates the set 69*1d3f2ddcSSimon J. Gerraty# ( during parsing of the pattern, starts a nesting level 70*1d3f2ddcSSimon J. Gerraty# ) during parsing of the pattern, ends a nesting level 71*1d3f2ddcSSimon J. Gerraty# { during parsing of the pattern, starts a nesting level 72*1d3f2ddcSSimon J. Gerraty# } during parsing of the pattern, ends a nesting level 73*1d3f2ddcSSimon J. Gerraty# : during parsing of the pattern, finishes the pattern 74*1d3f2ddcSSimon J. Gerraty# $ during parsing of the pattern, starts a nested expression 75*1d3f2ddcSSimon J. Gerraty# # in a line except a shell command, starts a comment 76*1d3f2ddcSSimon J. Gerraty# 77*1d3f2ddcSSimon J. Gerraty# Pattern parts: 78*1d3f2ddcSSimon J. Gerraty# * matches 0 or more arbitrary characters 79*1d3f2ddcSSimon J. Gerraty# ? matches exactly 1 arbitrary character 80*1d3f2ddcSSimon J. Gerraty# \x matches exactly the character 'x' 81*1d3f2ddcSSimon J. Gerraty# [...] matches exactly 1 character from the set 82*1d3f2ddcSSimon J. Gerraty# [^...] matches exactly 1 character outside the set 83*1d3f2ddcSSimon J. Gerraty# [a-z] matches exactly 1 character from the range 'a' to 'z' 84*1d3f2ddcSSimon J. Gerraty# 85*1d3f2ddcSSimon J. Gerraty 86*1d3f2ddcSSimon J. Gerraty# [] matches never 87*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b :L:M[]} != "" 88*1d3f2ddcSSimon J. Gerraty. error 89*1d3f2ddcSSimon J. Gerraty.endif 90*1d3f2ddcSSimon J. Gerraty 91*1d3f2ddcSSimon J. Gerraty# a[]b matches never 92*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b [ ] :L:Ma[]b} != "" 93*1d3f2ddcSSimon J. Gerraty. error 94*1d3f2ddcSSimon J. Gerraty.endif 95*1d3f2ddcSSimon J. Gerraty 96*1d3f2ddcSSimon J. Gerraty# [^] matches exactly 1 arbitrary character 97*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b [ ] :L:M[^]} != "a b [ ]" 98*1d3f2ddcSSimon J. Gerraty. error 99*1d3f2ddcSSimon J. Gerraty.endif 100*1d3f2ddcSSimon J. Gerraty 101*1d3f2ddcSSimon J. Gerraty# a[^]b matches 'a', then exactly 1 arbitrary character, then 'b' 102*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b :L:Ma[^]b} != "a[b" 103*1d3f2ddcSSimon J. Gerraty. error 104*1d3f2ddcSSimon J. Gerraty.endif 105*1d3f2ddcSSimon J. Gerraty 106*1d3f2ddcSSimon J. Gerraty# [Nn0] matches exactly 1 character from the set 'N', 'n', '0' 107*1d3f2ddcSSimon J. Gerraty.if ${ a b N n 0 Nn0 [ ] :L:M[Nn0]} != "N n 0" 108*1d3f2ddcSSimon J. Gerraty. error 109*1d3f2ddcSSimon J. Gerraty.endif 110*1d3f2ddcSSimon J. Gerraty 111*1d3f2ddcSSimon J. Gerraty# [a-c] matches exactly 1 character from the range 'a' to 'c' 112*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d [a-c] [a] :L:M[a-c]} != "a b c" 113*1d3f2ddcSSimon J. Gerraty. error 114*1d3f2ddcSSimon J. Gerraty.endif 115*1d3f2ddcSSimon J. Gerraty 116*1d3f2ddcSSimon J. Gerraty# [c-a] matches the same as [a-c] 117*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d [a-c] [a] :L:M[c-a]} != "a b c" 118*1d3f2ddcSSimon J. Gerraty. error 119*1d3f2ddcSSimon J. Gerraty.endif 120*1d3f2ddcSSimon J. Gerraty 121*1d3f2ddcSSimon J. Gerraty# [^a-c67] 122*1d3f2ddcSSimon J. Gerraty# matches a single character, except for 'a', 'b', 'c', '6' or 123*1d3f2ddcSSimon J. Gerraty# '7' 124*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d 5 6 7 8 [a-c] [a] :L:M[^a-c67]} != "A B C d 5 8" 125*1d3f2ddcSSimon J. Gerraty. error 126*1d3f2ddcSSimon J. Gerraty.endif 127*1d3f2ddcSSimon J. Gerraty 128*1d3f2ddcSSimon J. Gerraty# : terminates the pattern 129*1d3f2ddcSSimon J. Gerraty.if ${ A * :L:M:} != "" 130*1d3f2ddcSSimon J. Gerraty. error 131*1d3f2ddcSSimon J. Gerraty.endif 132*1d3f2ddcSSimon J. Gerraty 133*1d3f2ddcSSimon J. Gerraty# \: matches a colon 134*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\: \:\:} :L:M\:} != ":" 135*1d3f2ddcSSimon J. Gerraty. error 136*1d3f2ddcSSimon J. Gerraty.endif 137*1d3f2ddcSSimon J. Gerraty 138*1d3f2ddcSSimon J. Gerraty# ${:U\:} matches a colon 139*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\:} ${:U\:\:} :L:M${:U\:}} != ":" 140*1d3f2ddcSSimon J. Gerraty. error 141*1d3f2ddcSSimon J. Gerraty.endif 142*1d3f2ddcSSimon J. Gerraty 143*1d3f2ddcSSimon J. Gerraty# [:] matches never since the ':' starts the next modifier 144*1d3f2ddcSSimon J. Gerraty# expect+2: Unknown modifier "]" 145*1d3f2ddcSSimon J. Gerraty# expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":") 146*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":" 147*1d3f2ddcSSimon J. Gerraty. error 148*1d3f2ddcSSimon J. Gerraty.else 149*1d3f2ddcSSimon J. Gerraty. error 150*1d3f2ddcSSimon J. Gerraty.endif 151*1d3f2ddcSSimon J. Gerraty 152*1d3f2ddcSSimon J. Gerraty# [\] matches exactly a backslash; no escaping takes place in 153*1d3f2ddcSSimon J. Gerraty# character ranges 154*1d3f2ddcSSimon J. Gerraty# Without the 'a' in the below expressions, the backslash would end a word and 155*1d3f2ddcSSimon J. Gerraty# thus influence how the string is split into words. 156*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\\a} ${:U\\\\a} :L:M[\]a} != "\\a" 157*1d3f2ddcSSimon J. Gerraty. error 158*1d3f2ddcSSimon J. Gerraty.endif 159*1d3f2ddcSSimon J. Gerraty 160*1d3f2ddcSSimon J. Gerraty#.MAKEFLAGS: -dcv 161*1d3f2ddcSSimon J. Gerraty# 162*1d3f2ddcSSimon J. Gerraty# Incomplete patterns: 163*1d3f2ddcSSimon J. Gerraty# [ matches TODO 164*1d3f2ddcSSimon J. Gerraty# [x matches TODO 165*1d3f2ddcSSimon J. Gerraty# [^ matches TODO 166*1d3f2ddcSSimon J. Gerraty# [- matches TODO 167*1d3f2ddcSSimon J. Gerraty# [xy matches TODO 168*1d3f2ddcSSimon J. Gerraty# [^x matches TODO 169*1d3f2ddcSSimon J. Gerraty# [\ matches TODO 170*1d3f2ddcSSimon J. Gerraty# 171*1d3f2ddcSSimon J. Gerraty# [x- matches exactly 'x', doesn't match 'x-' 172*1d3f2ddcSSimon J. Gerraty# [^x- matches TODO 173*1d3f2ddcSSimon J. Gerraty# \ matches never 174*1d3f2ddcSSimon J. Gerraty 175*1d3f2ddcSSimon J. Gerraty 176*1d3f2ddcSSimon J. Gerraty# The modifier ':tW' prevents splitting at whitespace. Even leading and 177*1d3f2ddcSSimon J. Gerraty# trailing whitespace is preserved. 178*1d3f2ddcSSimon J. Gerraty.if ${ plain string :L:tW:M*} != " plain string " 179*1d3f2ddcSSimon J. Gerraty. error 180*1d3f2ddcSSimon J. Gerraty.endif 181*1d3f2ddcSSimon J. Gerraty 182*1d3f2ddcSSimon J. Gerraty# Without the modifier ':tW', the string is split into words. All whitespace 183*1d3f2ddcSSimon J. Gerraty# around and between the words is normalized to a single space. 184*1d3f2ddcSSimon J. Gerraty.if ${ plain string :L:M*} != "plain string" 185*1d3f2ddcSSimon J. Gerraty. error 186*1d3f2ddcSSimon J. Gerraty.endif 187