1*490e17a0Skre# $NetBSD: t_patterns.sh,v 1.7 2023/05/11 10:08:34 kre Exp $ 2bdc738b8Skre# 3bdc738b8Skre# Copyright (c) 2018 The NetBSD Foundation, Inc. 4bdc738b8Skre# All rights reserved. 5bdc738b8Skre# 6bdc738b8Skre# Redistribution and use in source and binary forms, with or without 7bdc738b8Skre# modification, are permitted provided that the following conditions 8bdc738b8Skre# are met: 9bdc738b8Skre# 1. Redistributions of source code must retain the above copyright 10bdc738b8Skre# notice, this list of conditions and the following disclaimer. 11bdc738b8Skre# 2. Redistributions in binary form must reproduce the above copyright 12bdc738b8Skre# notice, this list of conditions and the following disclaimer in the 13bdc738b8Skre# documentation and/or other materials provided with the distribution. 14bdc738b8Skre# 15bdc738b8Skre# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16bdc738b8Skre# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17bdc738b8Skre# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18bdc738b8Skre# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19bdc738b8Skre# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20bdc738b8Skre# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21bdc738b8Skre# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22bdc738b8Skre# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23bdc738b8Skre# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24bdc738b8Skre# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25bdc738b8Skre# POSSIBILITY OF SUCH DAMAGE. 26bdc738b8Skre# 27bdc738b8Skre# the implementation of "sh" to test 28bdc738b8Skre: ${TEST_SH:=/bin/sh} 29bdc738b8Skre 30bdc738b8Skre# 31bdc738b8Skre# This file tests pattern matching (glob) 32bdc738b8Skre# 33bdc738b8Skre# Three forms: 34bdc738b8Skre# standard filename expansion (echo *.c) 35bdc738b8Skre# case statements (case word in (*.c) ...;;) 36bdc738b8Skre# var expansions with substring matching ${var%*.c} 37bdc738b8Skre# 38bdc738b8Skre# Note: the emphasis here is on testing the various possible patterns, 39bdc738b8Skre# not that case statements, or var expansions (etc) work in general. 40bdc738b8Skre 41bdc738b8Skre### Helper functions 42bdc738b8Skre 43bdc738b8Skrenl=' 44bdc738b8Skre' 45bdc738b8Skrereset() 46bdc738b8Skre{ 47bdc738b8Skre TEST_NUM=0 48bdc738b8Skre TEST_FAILURES='' 49bdc738b8Skre TEST_FAIL_COUNT=0 50bdc738b8Skre TEST_ID="$1" 51bdc738b8Skre} 52bdc738b8Skre 53bdc738b8Skre# Test run & validate. 54bdc738b8Skre# 55bdc738b8Skre# $1 is the command to run (via sh -c) 56bdc738b8Skre# $2 is the expected output (with any \n's in output replaced by spaces) 57bdc738b8Skre# $3 is the expected exit status from sh 58bdc738b8Skre# 59bdc738b8Skre# Stderr is exxpected to be empty, unless the expected exit code ($3) is != 0 60bdc738b8Skre# in which case some message there is expected (and nothing is a failure). 61bdc738b8Skre# When non-zero exit is expected, we note a different (non-zero) value 62bdc738b8Skre# observed, but do not fail the test because of that. 63bdc738b8Skre 64bdc738b8Skrecheck() 65bdc738b8Skre{ 66bdc738b8Skre fail=false 67bdc738b8Skre # Note TEMP_FILE must not be in the current directory (or nearby). 68bdc738b8Skre TEMP_FILE=$( mktemp /tmp/OUT.XXXXXX ) 69bdc738b8Skre TEST_NUM=$(( $TEST_NUM + 1 )) 70bdc738b8Skre MSG= 71bdc738b8Skre 72bdc738b8Skre # our local shell (ATF_SHELL) better do quoting correctly... 73bdc738b8Skre # some of the tests expect us to expand $nl internally... 74bdc738b8Skre CMD="$1" 75bdc738b8Skre 76bdc738b8Skre result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" 77bdc738b8Skre STATUS=$? 78bdc738b8Skre 79bdc738b8Skre if [ "${STATUS}" -ne "$3" ]; then 80bdc738b8Skre MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 81bdc738b8Skre MSG="${MSG} expected exit code $3, got ${STATUS}" 82bdc738b8Skre 83bdc738b8Skre # don't actually fail just because of wrong exit code 84bdc738b8Skre # unless we either expected, or received "good" 85bdc738b8Skre # or something else is detected as incorrect as well. 86bdc738b8Skre case "$3/${STATUS}" in 87bdc738b8Skre (*/0|0/*) fail=true;; 88bdc738b8Skre esac 89bdc738b8Skre fi 90bdc738b8Skre 91bdc738b8Skre if [ "$3" -eq 0 ]; then 92bdc738b8Skre if [ -s "${TEMP_FILE}" ]; then 93bdc738b8Skre MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 94bdc738b8Skre MSG="${MSG} Messages produced on stderr unexpected..." 95bdc738b8Skre MSG="${MSG}${nl}$( cat "${TEMP_FILE}" )" 96bdc738b8Skre fail=true 97bdc738b8Skre fi 98bdc738b8Skre else 99bdc738b8Skre if ! [ -s "${TEMP_FILE}" ]; then 100bdc738b8Skre MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 101bdc738b8Skre MSG="${MSG} Expected messages on stderr," 102bdc738b8Skre MSG="${MSG} nothing produced" 103bdc738b8Skre fail=true 104bdc738b8Skre fi 105bdc738b8Skre fi 106bdc738b8Skre rm -f "${TEMP_FILE}" 107bdc738b8Skre 108bdc738b8Skre case "${result}" in 109bdc738b8Skre (*[!0-9" $nl"]*) 110bdc738b8Skre # A word of some kind: at least 1 char that is not digit or wsp 111bdc738b8Skre # Remove newlines (use local shell for this) 112bdc738b8Skre result="$( 113bdc738b8Skre set -f 114bdc738b8Skre IFS="$nl" 115bdc738b8Skre set -- $result 116bdc738b8Skre IFS=' ' 117bdc738b8Skre printf '%s' "$*" 118bdc738b8Skre )" 119bdc738b8Skre ;; 120bdc738b8Skre (*[0-9]*) 121bdc738b8Skre # a numeric result, return just the number, trim whitespace 122bdc738b8Skre result=$(( ${result} )) 123bdc738b8Skre ;; 124bdc738b8Skre (*) 125bdc738b8Skre # whitespace only, or empty string: just leave it as is 126bdc738b8Skre ;; 127bdc738b8Skre esac 128bdc738b8Skre 129bdc738b8Skre if [ "$2" != "${result}" ] 130bdc738b8Skre then 131bdc738b8Skre MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 132bdc738b8Skre MSG="${MSG} Expected output '$2', received '$result'" 133bdc738b8Skre fail=true 134bdc738b8Skre fi 135bdc738b8Skre 136bdc738b8Skre if $fail 137bdc738b8Skre then 138bdc738b8Skre MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 139bdc738b8Skre MSG="${MSG} Full command: <<${CMD}>>" 140bdc738b8Skre fi 141bdc738b8Skre 142bdc738b8Skre $fail && test -n "$TEST_ID" && { 143bdc738b8Skre TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+${nl}}" 144bdc738b8Skre TEST_FAILURES="${TEST_FAILURES}${TEST_ID}[$TEST_NUM]:" 145bdc738b8Skre TEST_FAILURES="${TEST_FAILURES} Test of '$1' failed."; 146bdc738b8Skre TEST_FAILURES="${TEST_FAILURES}${nl}${MSG}" 147bdc738b8Skre TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 )) 148bdc738b8Skre return 0 149bdc738b8Skre } 150bdc738b8Skre $fail && atf_fail "Test[$TEST_NUM] failed: $( 151bdc738b8Skre # ATF does not like newlines in messages, so change them... 152bdc738b8Skre printf '%s' "${MSG}" | tr '\n' ';' 153bdc738b8Skre )" 154bdc738b8Skre return 0 155bdc738b8Skre} 156bdc738b8Skre 157bdc738b8Skreresults() 158bdc738b8Skre{ 159bdc738b8Skre test -n "$1" && atf_expect_fail "$1" 160bdc738b8Skre 161bdc738b8Skre test -z "${TEST_ID}" && return 0 162bdc738b8Skre test -z "${TEST_FAILURES}" && return 0 163bdc738b8Skre 164bdc738b8Skre echo >&2 "==========================================" 165bdc738b8Skre echo >&2 "While testing '${TEST_ID}'" 166bdc738b8Skre echo >&2 " - - - - - - - - - - - - - - - - -" 167bdc738b8Skre echo >&2 "${TEST_FAILURES}" 168bdc738b8Skre 169bdc738b8Skre atf_fail \ 170bdc738b8Skre "Test ${TEST_ID}: $TEST_FAIL_COUNT (of $TEST_NUM) subtests failed - see stderr" 171bdc738b8Skre} 172bdc738b8Skre 173bdc738b8Skre####### End helpers 174bdc738b8Skre 175bdc738b8Skreatf_test_case filename_expansion 1767cb4398aSgutteridgefilename_expansion_head() { 177bdc738b8Skre atf_set descr "Test correct operation of filename expansion" 178bdc738b8Skre} 179bdc738b8Skrefilename_expansion_body() { 180bdc738b8Skre atf_require_prog mktemp 181bdc738b8Skre atf_require_prog wc 182bdc738b8Skre atf_require_prog mv 183bdc738b8Skre atf_require_prog rm 184bdc738b8Skre atf_require_prog mkdir 185d903b87aSmartin atf_require_prog df 186d903b87aSmartin atf_require_prog awk 187bdc738b8Skre 188bdc738b8Skre reset filename_expansion 189bdc738b8Skre 190bdc738b8Skre # First create a known set of filenames to match against 191bdc738b8Skre 192bdc738b8Skre # Note: This creates almost 17000 files/directories, so 193bdc738b8Skre # needs at least that many free inodes (only space consumed 194bdc738b8Skre # is for the directory contents, with a 1K frag size, it 195bdc738b8Skre # should be about 1.2MiB). Switching to making links would 196bdc738b8Skre # save inodes, but would require running "ln" many times, so 197bdc738b8Skre # would be a lot slower. 198bdc738b8Skre 199d903b87aSmartin free_inodes=$( df -i . | awk '/^Filesystem/{next}; { print $7 }' ) 200d903b87aSmartin if [ $free_inodes -lt 17000 ]; then 201d903b87aSmartin atf_skip "not enough space" 202d903b87aSmartin fi 203d903b87aSmartin 204bdc738b8Skre # This should work on a case insensitive, but preserving, 205bdc738b8Skre # filesystem - but case sensitive filesystems are preferred. 206bdc738b8Skre 207bdc738b8Skre D=$(mktemp -d "DIR.$$.XXXXXX") || atf_fail "mktemp -d failed" 208bdc738b8Skre cd "${D}" || atf_fail "cd to temp dir '$D' failed" 209bdc738b8Skre 210bdc738b8Skre # we need another level of directory, so we know what 211bdc738b8Skre # files to expect in ".." (ie: in $D) - only ".D". 212bdc738b8Skre mkdir .D && cd .D || atf_fail "failed to make or enter .D in $D" 213bdc738b8Skre 214bdc738b8Skre > Xx || atf_fail "Unable to make files in temporary directory" 215bdc738b8Skre case "$( printf '%s\n' *)" in 216bdc738b8Skre (Xx) rm Xx || atf_fail "Unable to delete file";; 217bdc738b8Skre (\*) atf_fail "Created file vanished";; 218bdc738b8Skre (xx|XX|xX) atf_skip "Case preserving filesystem required";; 219bdc738b8Skre (*) atf_fail "Unexpected file expansion for '*'";; 220bdc738b8Skre esac 221bdc738b8Skre 222bdc738b8Skre # from here on we make files/directories that we will be 223bdc738b8Skre # using in the tests. 224bdc738b8Skre 225bdc738b8Skre # CAUTION: Change *any* of this and the expected results from the 226bdc738b8Skre # tests will all need verifying and updating as well. 227bdc738b8Skre 228bdc738b8Skre mkdir D || atf_fail "mkdir D failed" 229bdc738b8Skre 230bdc738b8Skre for F in a b c e V W X Y 1 2 3 4 5 \\ \] \[ \* \? \- \! \^ \| \# \' \" 231bdc738b8Skre do 232bdc738b8Skre > "${F}" 233bdc738b8Skre > ".${F}" 234bdc738b8Skre > "${F}.${F}" 235bdc738b8Skre > "${F}-${F}" 236bdc738b8Skre > "${F}${F}${F}${F}" 237bdc738b8Skre > "x${F}z" 238bdc738b8Skre > ab"${F}"yz 239bdc738b8Skre > "m${F}n${F}p${F}q" 240bdc738b8Skre 241bdc738b8Skre > "D/${F}" 242bdc738b8Skre > "D/.${F}" 243bdc738b8Skre > "D/${F}${F}${F}${F}" 244bdc738b8Skre 245bdc738b8Skre mkdir "D${F}" || atf_fail "mkdir 'D${F}' failed" 246bdc738b8Skre mkdir ".D${F}" || atf_fail "mkdir '.D${F}' failed" 247bdc738b8Skre 248bdc738b8Skre for G in a b c e W X Y 0 2 4 6 \\ \] \[ \* \? \- \! \^ \| \# 249bdc738b8Skre do 250bdc738b8Skre > "${F}${G}" 251bdc738b8Skre > "${F}${G}${G}" 252bdc738b8Skre > "${F}${G}${F}" 253bdc738b8Skre > "${G}${F}${G}" 254bdc738b8Skre > "${F}${G}${G}${F}" 255bdc738b8Skre > "${G}${F}${F}${G}" 256bdc738b8Skre > "${F}.${G}" 257bdc738b8Skre > "${F}${G}.${G}${G}" 258bdc738b8Skre > "${F}${G}${F}${G}.${G}" 259bdc738b8Skre > "x${F}${G}y" 260bdc738b8Skre > "${F}z${G}" 261bdc738b8Skre > "${G}zz${F}" 262bdc738b8Skre > "${G}+${G}" 263bdc738b8Skre 264bdc738b8Skre > "D${F}/${G}" 265bdc738b8Skre > "D${F}/.${G}" 266bdc738b8Skre > "D${F}/${G}${F}${G}" 267bdc738b8Skre > "D${F}/.${G}${F}${G}" 268bdc738b8Skre 269bdc738b8Skre > ".D${F}/${G}" 270bdc738b8Skre > ".D${F}/.${G}" 271bdc738b8Skre > ".D${F}/${G}${F}${G}" 272bdc738b8Skre > ".D${F}/.${G}${F}${G}" 273bdc738b8Skre 274bdc738b8Skre mkdir "D${F}/D${G}" "D${F}/D${F}${G}" || 275bdc738b8Skre atf_fail \ 276bdc738b8Skre "subdir mkdirs failed D${F}/D${G} D${F}/D${F}${G}" 277bdc738b8Skre 278bdc738b8Skre > "D${F}/D${G}/${G}" 279bdc738b8Skre > "D${F}/D${G}.${G}" 280bdc738b8Skre > "D${F}/D${G}/${F}${G}" 281bdc738b8Skre > "D${F}/D${G}/${G}${F}${G}" 282bdc738b8Skre > "D${F}/D${G}/.${G}${F}${G}" 283bdc738b8Skre > "D${F}/D${G}/.${G}${F}${G}" 284bdc738b8Skre 285bdc738b8Skre > "D${F}/D${F}${G}/${G}" 286bdc738b8Skre > "D${F}/D${F}${G}.${G}" 287bdc738b8Skre > "D${F}/D${F}${G}/${G}${F}" 288bdc738b8Skre > "D${F}/D${F}${G}/${G}${G}${F}" 289bdc738b8Skre > "D${F}/D${F}${G}/.${F}${F}${G}" 290bdc738b8Skre > "D${F}/D${F}${G}/.${G}${F}${F}" 291bdc738b8Skre 292bdc738b8Skre done 293bdc738b8Skre done 294bdc738b8Skre 295bdc738b8Skre # Debug hooks ... run with environment var set to filename 296bdc738b8Skre 297bdc738b8Skre case "${ATF_TEST_SAVE_FILENAMES}" in 298bdc738b8Skre '') ;; 299bdc738b8Skre /*) ls -R >"${ATF_TEST_SAVE_FILENAMES}" ;; 300bdc738b8Skre *) ls -R >"${TMPDIR:-/tmp}/${ATF_TEST_SAVE_FILENAMES}" ;; 301bdc738b8Skre esac 302bdc738b8Skre case "${ATF_TEST_SAVE_FILES}" in 303bdc738b8Skre '') ;; 304*490e17a0Skre /*) (cd ..; tar cf "${ATF_TEST_SAVE_FILES}" .D) ;; 305*490e17a0Skre *) (cd ..; tar cf "${TMPDIR:-/tmp}/${ATF_TEST_SAVE_FILES}" .D) ;; 306bdc738b8Skre esac 307bdc738b8Skre 308bdc738b8Skre # Now we have lots of files, try some matching 309bdc738b8Skre 310bdc738b8Skre # First just check that "printf | wc -l" works properly... 311bdc738b8Skre check 'printf "%s\n" 1 2 3 | wc -l' '3' 0 #1 312bdc738b8Skre 313bdc738b8Skre # Next a whole bunch of elementary patterns 314bdc738b8Skre check 'printf "%s\n" ab* | wc -l' '31' 0 315bdc738b8Skre check 'printf "%s\n" x*y | wc -l' '525' 0 316bdc738b8Skre check 'printf "%s\n" * | wc -l' '5718' 0 317bdc738b8Skre check 'printf "%s\n" ? | wc -l' '26' 0 #5 318bdc738b8Skre check 'printf "%s\n" ?? | wc -l' '550' 0 319bdc738b8Skre check 'printf "%s\n" ??? | wc -l' '2297' 0 320bdc738b8Skre check 'printf "%s\n" ???? | wc -l' '1745' 0 321bdc738b8Skre check 'printf "%s\n" ????? | wc -l' '550' 0 322bdc738b8Skre 323bdc738b8Skre check 'printf "%s\n" ?????? | wc -l' '525' 0 #10 324bdc738b8Skre check 'printf "%s\n" ??????? | wc -l' '25' 0 325bdc738b8Skre check 'printf "%s\n" ???????? | wc -l' '1' 0 326bdc738b8Skre check 'printf "%s\n" ????????' '????????' 0 327bdc738b8Skre check 'printf "%s\n" m* | wc -l' '25' 0 328bdc738b8Skre check 'printf "%s\n" -* | wc -l' '206' 0 #15 329bdc738b8Skre check 'printf "%s\n" *- | wc -l' '227' 0 330bdc738b8Skre check 'printf "%s\n" -? | wc -l' '21' 0 331bdc738b8Skre check 'printf "%s\n" ?- | wc -l' '26' 0 332bdc738b8Skre check 'printf "%s\n" [ab] | wc -l' '2' 0 333bdc738b8Skre 334bdc738b8Skre check 'printf "%s\n" [ab]* | wc -l' '437' 0 #20 335bdc738b8Skre check 'printf "%s\n" [A-Z]* | wc -l' '815' 0 336bdc738b8Skre check 'printf "%s\n" [0-4]* | wc -l' '830' 0 337bdc738b8Skre check 'printf "%s\n" [-04]* | wc -l' '488' 0 338bdc738b8Skre check 'printf "%s\n" [40-]* | wc -l' '488' 0 339bdc738b8Skre check 'printf "%s\n" *[0-9] | wc -l' '1057' 0 #25 340bdc738b8Skre check 'printf "%s\n" *[0-9]* | wc -l' '2109' 0 341bdc738b8Skre check 'printf "%s\n" ?[0-9]* | wc -l' '855' 0 342bdc738b8Skre check 'printf "%s\n" ?[0-9]? | wc -l' '270' 0 343bdc738b8Skre check 'printf "%s\n" *[0-9]? | wc -l' '750' 0 344bdc738b8Skre 345bdc738b8Skre check 'printf "%s\n" [a-c][0-9]? | wc -l' '33' 0 #30 346bdc738b8Skre check 'printf "%s\n" [[:alpha:]] | wc -l' '9' 0 347bdc738b8Skre check 'printf "%s\n" [[:alpha:][:digit:]] | wc -l' '14' 0 348bdc738b8Skre check 'printf "%s\n" [[:alpha:]][[:digit:]] | wc -l' '37' 0 349bdc738b8Skre check \ 350bdc738b8Skre 'printf "%s\n" [[:alpha:][:digit:]][[:alpha:][:digit:]] | wc -l' \ 351bdc738b8Skre '156' 0 352bdc738b8Skre check 'printf "%s\n" D*/*a | wc -l' '152' 0 #35 353bdc738b8Skre check 'printf "%s\n" D?/*a | wc -l' '150' 0 354bdc738b8Skre check 'printf "%s\n" D*/?a | wc -l' '25' 0 355bdc738b8Skre check 'printf "%s\n" D?/?a | wc -l' '25' 0 356bdc738b8Skre check 'printf "%s\n" */*a | wc -l' '152' 0 357bdc738b8Skre 358bdc738b8Skre check 'printf "%s\n" [A-Z]*/*a | wc -l' '152' 0 #40 359bdc738b8Skre check 'printf "%s\n" ??/*a | wc -l' '150' 0 360bdc738b8Skre check 'printf "%s\n" .*/*a | wc -l' '277' 0 361bdc738b8Skre check 'printf "%s\n" .?*/*a | wc -l' '50' 0 362bdc738b8Skre check 'printf "%s\n" *-/-* | wc -l' '2' 0 363bdc738b8Skre check 'printf "%s\n" *-/-*' 'D-/- D-/---' 0 #45 364bdc738b8Skre 365bdc738b8Skre # now some literal magic chars 366bdc738b8Skre check 'printf "%s\n" \?* | wc -l' '206' 0 367bdc738b8Skre check 'printf "%s\n" *\?* | wc -l' '471' 0 368bdc738b8Skre check 'printf "%s\n" \*? | wc -l' '21' 0 369bdc738b8Skre check 'printf "%s\n" \** | wc -l' '206' 0 370bdc738b8Skre 371bdc738b8Skre check 'printf "%s\n" *\?* | wc -l' '471' 0 #50 372bdc738b8Skre check 'printf "%s\n" \[?] | wc -l' '3' 0 373bdc738b8Skre check 'printf "%s\n" \[?]' '[.] []] [z]' 0 374bdc738b8Skre check 'printf "%s\n" *\[* | wc -l' '471' 0 375bdc738b8Skre check 'printf "%s\n" \?\?* | wc -l' '5' 0 376bdc738b8Skre check 'printf "%s\n" \?\?*' '?? ??.?? ??? ???? ????.?' 0 #55 377bdc738b8Skre check 'printf "%s\n" [A\-C]* | wc -l' '206' 0 378bdc738b8Skre check 'printf "%s\n" [-AC]* | wc -l' '206' 0 379bdc738b8Skre check 'printf "%s\n" [CA-]* | wc -l' '206' 0 380bdc738b8Skre check 'printf "%s\n" [A\]-]? | wc -l' '42' 0 381bdc738b8Skre 382bdc738b8Skre check 'printf "%s\n" []A\-]? | wc -l' '42' 0 #60 383bdc738b8Skre check 'printf "%s\n" []A-]? | wc -l' '42' 0 384bdc738b8Skre check 'printf "%s\n" \\* | wc -l' '206' 0 385bdc738b8Skre check 'printf "%s\n" [[-\]]?\?* | wc -l' '12' 0 386bdc738b8Skre check 'printf "%s\n" []\\[]?\? | wc -l' '9' 0 387bdc738b8Skre check 'printf "%s\n" *\\\\ | wc -l' '52' 0 #65 388bdc738b8Skre check 'printf "%s\n" [*][?]* | wc -l' '6' 0 389bdc738b8Skre check 'printf "%s\n" "*?"* | wc -l' '6' 0 390bdc738b8Skre check "printf '%s\\n' '\\'*\\\\ | wc -l" '61' 0 391bdc738b8Skre check 'printf "%s\n" ["a-b"]* | wc -l' '643' 0 392bdc738b8Skre 393bdc738b8Skre check 'printf "%s\n" ["A-C"]z[[] | wc -l' '1' 0 #70 394bdc738b8Skre check 'printf "%s\n" ["A-C"]z[[]' '-z[' 0 395bdc738b8Skre check 'printf "%s\n" ?"??"* | wc -l' '54' 0 396bdc738b8Skre check 'printf "%s\n" \??\?* | wc -l' '52' 0 397bdc738b8Skre check 'printf "%s\n" [?][\?]* | wc -l' '5' 0 398bdc738b8Skre check 'printf "%s\n" [?][\?]*' '?? ??.?? ??? ???? ????.?' 0 #75 399bdc738b8Skre check 'printf "%s\n" [!ab] | wc -l' '24' 0 400bdc738b8Skre check 'printf "%s\n" [!ab]* | wc -l' '5281' 0 401bdc738b8Skre check 'printf "%s\n" [!A-D]* | wc -l' '5692' 0 402bdc738b8Skre check 'printf "%s\n" [!0-3]* | wc -l' '5094' 0 403bdc738b8Skre 404bdc738b8Skre check 'printf "%s\n" [!-03]* | wc -l' '5265' 0 #80 405bdc738b8Skre check 'printf "%s\n" [!30-]* | wc -l' '5265' 0 406bdc738b8Skre check 'printf "%s\n" [!0\-3]* | wc -l' '5265' 0 407bdc738b8Skre check 'printf "%s\n" [\!0-3]* | wc -l' '830' 0 408bdc738b8Skre check 'printf "%s\n" [0-3!]* | wc -l' '830' 0 409bdc738b8Skre check 'printf "%s\n" [0!-3]* | wc -l' '1790' 0 #85 410bdc738b8Skre check 'printf "%s\n" *[!0-3] | wc -l' '5156' 0 411bdc738b8Skre check 'printf "%s\n" *[!0-3]* | wc -l' '5680' 0 412bdc738b8Skre check 'printf "%s\n" ?[!0-3]* | wc -l' '5231' 0 413bdc738b8Skre check 'printf "%s\n" ?[!0-3]? | wc -l' '2151' 0 414bdc738b8Skre 415bdc738b8Skre check 'printf "%s\n" *[!0-3]? | wc -l' '5284' 0 #90 416bdc738b8Skre check 'printf "%s\n" [!a-c][!0-3]? | wc -l' '1899' 0 417bdc738b8Skre check 'printf "%s\n" [![:alpha:]] | wc -l' '17' 0 418bdc738b8Skre check 'printf "%s\n" [![:alpha:][:digit:]] | wc -l' '12' 0 419bdc738b8Skre check 'printf "%s\n" [![:alpha:]][[:digit:]] | wc -l' '68' 0 420bdc738b8Skre check 'printf "%s\n" [[:alpha:]][![:digit:]] | wc -l' '156' 0 #95 421bdc738b8Skre check 'printf "%s\n" [![:alpha:]][![:digit:]] | wc -l' '289' 0 422bdc738b8Skre check 'printf "%s\n" [!A-Z]*/*a | wc -l' '1' 0 423bdc738b8Skre check 'printf "%s\n" [!A-Z]*/*a' '[!A-Z]*/*a' 0 424bdc738b8Skre check 'printf "%s\n" [!A\-D]* | wc -l' '5486' 0 425bdc738b8Skre 426bdc738b8Skre check 'printf "%s\n" [!-AD]* | wc -l' '5486' 0 #100 427bdc738b8Skre check 'printf "%s\n" [!DA-]* | wc -l' '5486' 0 428bdc738b8Skre check 'printf "%s\n" [!A\]-]? | wc -l' '508' 0 429bdc738b8Skre check 'printf "%s\n" [!]A\-]? | wc -l' '508' 0 430bdc738b8Skre check 'printf "%s\n" [!]A-]? | wc -l' '508' 0 431bdc738b8Skre check 'printf "%s\n" [![-\]]?\?* | wc -l' '164' 0 #105 432bdc738b8Skre check 'printf "%s\n" [!]\\[]?\? | wc -l' '93' 0 433bdc738b8Skre check 'printf "%s\n" [!*][?]* | wc -l' '171' 0 434bdc738b8Skre check 'printf "%s\n" [*][!?]* | wc -l' '199' 0 435bdc738b8Skre check 'printf "%s\n" [!*][!?]* | wc -l' '5316' 0 436bdc738b8Skre 437bdc738b8Skre check 'printf "%s\n" [!"a-b"]* | wc -l' '5075' 0 #110 438bdc738b8Skre check 'printf "%s\n" ["!a-b"]* | wc -l' '849' 0 439bdc738b8Skre check 'printf "%s\n" [!"A-D"]z[[] | wc -l' '24' 0 440bdc738b8Skre check 'printf "%s\n" ["!A-D"]z[[] | wc -l' '2' 0 441bdc738b8Skre check 'printf "%s\n" ["!A-D"]z[[]' '!z[ -z[' 0 442bdc738b8Skre check 'printf "%s\n" ["A-D"]z[![] | wc -l' '20' 0 #115 443bdc738b8Skre check 'printf "%s\n" [!"A-D"]z[![] | wc -l' '480' 0 444bdc738b8Skre check 'printf "%s\n" ["!A-D"]z[![] | wc -l' '40' 0 445bdc738b8Skre check 'printf "%s\n" [!?][\?]* | wc -l' '172' 0 446bdc738b8Skre check 'printf "%s\n" [?][!\?]* | wc -l' '200' 0 447bdc738b8Skre 448bdc738b8Skre check 'printf "%s\n" [!?][!\?]* | wc -l' '5315' 0 #120 449bdc738b8Skre check 'printf "%s\n" [!?][?!]* | wc -l' '343' 0 450bdc738b8Skre check 'printf "%s\n" [?][\?!]* | wc -l' '11' 0 451bdc738b8Skre check "printf '%s\\n' [\']*[!#] | wc -l" '164' 0 452bdc738b8Skre check 'printf "%s\n" [\"]*[\|] | wc -l' '6' 0 453bdc738b8Skre check 'printf "%s\n" [\"]*[\|]' '".| "z| "| "|"|.| "|.|| "||' 0 #125 454bdc738b8Skre check "printf '%s\\n' '\"['* | wc -l" '6' 0 455bdc738b8Skre check "printf '%s\\n' '\"['*" '"[ "[" "["[.[ "[.[[ "[[ "[["' 0 456bdc738b8Skre 457bdc738b8Skre # Now test cases where the pattern is the result of a 458bdc738b8Skre # variable expansion (will assume, for now, that cmdsub & arith 459bdc738b8Skre # work the same way, so omit tests using those) 460bdc738b8Skre # we need to check both unquoted & quoted var expansions, 461bdc738b8Skre # expansions that result from ${xxx-xxx} and ${xxx%yyy} 462bdc738b8Skre # and expansions that form just part of the eventual pattern. 463bdc738b8Skre 464bdc738b8Skre check 'var="x*y";printf "%s\n" ${var} | wc -l' '525' 0 465bdc738b8Skre check 'var="[a-e]?[0-9]";printf "%s\n" ${var} | wc -l' '48' 0 466bdc738b8Skre 467bdc738b8Skre check 'var="[a-e]?.*";printf "%s\n" ${var} | wc -l' '84' 0 #130 468bdc738b8Skre check 'var="[a-e]\?.*";printf "%s\n" ${var} | wc -l' '4' 0 469bdc738b8Skre check 'var="[a-e]\?.*";printf "%s\n" ${var}' 'a?.?? b?.?? c?.?? e?.??' 0 470bdc738b8Skre 471bdc738b8Skre # and if you're looking for truly weird... 472bdc738b8Skre 473bdc738b8Skre check 'set -- a b; IFS=\?; printf "%s\n" "$*" | wc -l' '1' 0 474bdc738b8Skre check 'set -- a b; IFS=\?; printf "%s\n" "$*"' 'a?b' 0 475bdc738b8Skre check 'set -- a b; IFS=\?; printf "%s\n" $* | wc -l' '2' 0 #boring #135 476bdc738b8Skre check 'set -- a b; IFS=\?; var=$*; unset IFS; printf "%s\n" ${var}' \ 477bdc738b8Skre 'a.b abb azb' 0 478bdc738b8Skre check 'set -- a b; IFS=\?; var=$*; unset IFS; printf "%s\n" "${var}"' \ 479bdc738b8Skre 'a?b' 0 480bdc738b8Skre check 'set -- a \?; IFS=\\; printf "%s\n" "$*"' 'a\?' 0 481bdc738b8Skre check 'set -- a \?; IFS=\\; var=$*; unset IFS; printf "%s\n" "${var}"' \ 482bdc738b8Skre 'a\?' 0 483bdc738b8Skre 484bdc738b8Skre check 'set -- a \?; IFS=\\; var=$*; unset IFS; printf "%s\n" ${var}' \ 485bdc738b8Skre 'a?' 0 #140 486bdc738b8Skre mv 'a?' 'a@' 487bdc738b8Skre check 'set -- a \?; IFS=\\; var=$*; unset IFS; printf "%s\n" ${var}' \ 488bdc738b8Skre 'a\?' 0 489bdc738b8Skre mv 'a@' 'a?' 490bdc738b8Skre 491bdc738b8Skre # This is unspecified by POSIX, but everyone (sane) does it this way 492bdc738b8Skre check 'printf "%s\n" D*[/*] | wc -l' '6' 0 493bdc738b8Skre check 'printf "%s\n" D*[\/*] | wc -l' '6' 0 494bdc738b8Skre check 'printf "%s\n" D*\[/*] | wc -l' '6' 0 495bdc738b8Skre check 'printf "%s\n" D*\[\/*] | wc -l' '6' 0 #145 496bdc738b8Skre check 'printf "%s\n" D*[/*]' \ 497bdc738b8Skre 'D[/D[] D[/D[].] D[/D] D[/D].] D[/] D[/][]' 0 498bdc738b8Skre 499bdc738b8Skre # '^' as the first char in a bracket expr is unspecified by POSIX, 500bdc738b8Skre # but for compat with REs everyone (sane) makes it the same as ! 501fd909972Skre 502fd909972Skre # But just in case we are testing an insane shell ... 503fd909972Skre ${TEST_SH} -c 'case "^" in ([^V^]) exit 1;; (*) exit 0;; esac' && { 504fd909972Skre 505bdc738b8Skre check 'printf "%s\n" [^ab] | wc -l' '24' 0 506bdc738b8Skre check 'printf "%s\n" [^ab]* | wc -l' '5281' 0 507bdc738b8Skre check 'printf "%s\n" [^A-D]* | wc -l' '5692' 0 508bdc738b8Skre 509bdc738b8Skre check 'printf "%s\n" [^0-3]* | wc -l' '5094' 0 #150 510bdc738b8Skre check 'printf "%s\n" [^-03]* | wc -l' '5265' 0 511bdc738b8Skre check 'printf "%s\n" [^0\-3]* | wc -l' '5265' 0 512bdc738b8Skre check 'printf "%s\n" [^-a3]* | wc -l' '5110' 0 513bdc738b8Skre check 'printf "%s\n" [\^-a3]* | wc -l' '608' 0 514bdc738b8Skre check 'printf "%s\n" [\^0-3]* | wc -l' '830' 0 #155 515bdc738b8Skre check 'printf "%s\n" [0-3^]* | wc -l' '830' 0 516bdc738b8Skre check 'printf "%s\n" [0^-a]* | wc -l' '513' 0 517bdc738b8Skre check 'printf "%s\n" *[^0-3] | wc -l' '5156' 0 518bdc738b8Skre check 'printf "%s\n" [!^]? | wc -l' '529' 0 519bdc738b8Skre 520bdc738b8Skre check 'printf "%s\n" [^!]? | wc -l' '529' 0 #160 521bdc738b8Skre check 'printf "%s\n" [!!^]? | wc -l' '508' 0 522bdc738b8Skre check 'printf "%s\n" [!^!]? | wc -l' '508' 0 523bdc738b8Skre check 'printf "%s\n" [^!]? | wc -l' '529' 0 524bdc738b8Skre check 'printf "%s\n" [^!^]? | wc -l' '508' 0 525bdc738b8Skre check 'printf "%s\n" [^^!]? | wc -l' '508' 0 #165 526bdc738b8Skre check 'printf "%s\n" [!^-b]? | wc -l' '487' 0 527bdc738b8Skre check 'printf "%s\n" [^!-b]? | wc -l' '63' 0 528bdc738b8Skre 529fd909972Skre } 530fd909972Skre 531bdc738b8Skre # No need to clean up the directory, we're in the ATF working 532bdc738b8Skre # directory, and ATF cleans up for us. 533bdc738b8Skre 534bdc738b8Skre results 535bdc738b8Skre} 536bdc738b8Skre 537bdc738b8Skreatf_test_case case_matching 538bdc738b8Skrecase_matching_head() { 539bdc738b8Skre atf_set descr "Test expansion of vars with embedded cmdsub" 540bdc738b8Skre} 541bdc738b8Skre 542bdc738b8Skre# helper functions for case matching 543bdc738b8Skre# 544bdc738b8Skre# usage: cm word [ pattern ] [ preamble ] (expect word to match pattern) 545bdc738b8Skre# cf word [ pattern ] [ preamble ] (expect word to fail to match) 546bdc738b8Skre# 547bdc738b8Skre# The last used (non-null) pattern, and the last used preamble, are 548bdc738b8Skre# remembered and used again if only the word is given. To give a 549bdc738b8Skre# new preamble while using the last pattern, give '' as the pattern. 550bdc738b8Skre# 551bdc738b8Skre# nb: a null (empty) pattern is a syntax error, to get '' use "''" 552bdc738b8Skre# 553bdc738b8Skrecm() { 554bdc738b8Skre case "$2" in 555bdc738b8Skre '') set -- "$1" "${LAST_PATTERN}" "${3:-${LAST_PFX}}";; 556bdc738b8Skre *) LAST_PATTERN="$2";; 557bdc738b8Skre esac 558bdc738b8Skre LAST_PFX="$3" 559bdc738b8Skre 560bdc738b8Skre check \ 561bdc738b8Skre "${3:+${3}; }case $1 in ($2) printf M;; (*) printf X;; esac" M 0 562bdc738b8Skre} 563bdc738b8Skrecf() { 564bdc738b8Skre case "$2" in 565bdc738b8Skre '') set -- "$1" "${LAST_PATTERN}" "${3:-${LAST_PFX}}";; 566bdc738b8Skre *) LAST_PATTERN="$2";; 567bdc738b8Skre esac 568bdc738b8Skre LAST_PFX="$3" 569bdc738b8Skre 570bdc738b8Skre check \ 571bdc738b8Skre "${3:+${3}; }case $1 in ($2) printf M;; (*) printf X;; esac" X 0 572bdc738b8Skre} 573bdc738b8Skre 574bdc738b8Skrecase_matching_body() { 575bdc738b8Skre 576bdc738b8Skre # nb: we are not testing execution of case, so no ;& or alternate 577bdc738b8Skre # patterns (etc) are needed here, we just want to validate the 578bdc738b8Skre # case variant of pattern matching, so simple one word, one pattern 579bdc738b8Skre # match or not match. 580bdc738b8Skre 581bdc738b8Skre reset case_matching 582bdc738b8Skre 583bdc738b8Skre cm abcd 'ab*'; cf bcda; cf aabce; cm ab # 4 584bdc738b8Skre cm abcd '$var' 'var="ab*"'; cf abcd '"$var"' 'var="ab*"' # 6 585bdc738b8Skre 586bdc738b8Skre cm xy 'x*y'; cm xyxy; cm '"x*y"'; cf xxyz # 10 587bdc738b8Skre 588bdc738b8Skre cm '""' '*'; cm '\*'; cm '\?'; cm -; cm 12345 # 15 589bdc738b8Skre cm abcd '$var' 'var="*"'; cf abcd '"$var"' 'var="*"' # 17 590bdc738b8Skre cm '"*"' '\*'; cm '"*"' '"*"'; cm '"*"' '"$var"' 'var="*"' # 20 591bdc738b8Skre 592bdc738b8Skre cm X '?'; cf XX '?'; cf X '"?"'; cm Y '$var' 'var="?"' # 24 593bdc738b8Skre cf Z '"$var"' 'var="?"'; cm '"?"' '"$var"' 'var="?"' # 26 594bdc738b8Skre 595bdc738b8Skre cm XA '??'; cf X '??'; cf XX '"??"'; cm YZ '$var' 'var="??"' # 30 596bdc738b8Skre cf ZZ '"$var"' 'var="??"'; cm '"??"' '"$var"' 'var="??"' # 32 597bdc738b8Skre 598bdc738b8Skre cm a '[ab]'; cm b; cf c; cf aa; cf '"[ab]"' # 37 599bdc738b8Skre cm '"[ab]"' '"[ab]"'; cm '"[ab]"' '\[ab]' # 39 600bdc738b8Skre cm a '$var' 'var="[ab]"'; cf a '"$var"' 'var="[ab]"' # 41 601bdc738b8Skre cm '"[ab]"' '"$var"' 'var="[ab]"'; cm a '["$var"]' 'var=ab' # 43 602bdc738b8Skre 603bdc738b8Skre cm b '[a-c]'; cm a '[a-c]'; cm c '[a-c]'; cf d '[a-c]' # 47 604bdc738b8Skre cf '"[a-c]"' '[a-c]'; cm '"[a-c]"' '"[a-c]"' # 49 605bdc738b8Skre cm '"[a-c]"' '\[a-c]'; cm '"[a-c]"' '[a-c\]' # 51 606bdc738b8Skre cm a '$var' 'var="[a-c]"'; cf a '"$var"' 'var="[a-c]"' # 53 607bdc738b8Skre cm '"[a-c]"' '"$var"' 'var="[a-c]"'; cf b '["$var"]' 'var=a-c' # 55 608bdc738b8Skre 609bdc738b8Skre cm 2 '[0-4]'; cm 0 '[0-4]'; cf - '[0-4]'; cm 0 '[-04]' # 59 610bdc738b8Skre cf 2 '[-04]'; cf 2 '[40-]'; cm 0 '[40-]'; cm - '[-04]' # 63 611bdc738b8Skre cf 2 '[0\-4]'; cm - '[0\-4]'; cf 2 '["0-4"]'; cm - '["0-4"]' # 67 612bdc738b8Skre cf 2 "[0'-'4]"; cm - "[0'-'4]"; cm 4 "[0'-'4]" # 70 613bdc738b8Skre cm 0 "['0'-'4']"; cf '"\\"' '[0\-4]'; cm '"\\"' '[\\0-\\4]' # 73 614bdc738b8Skre 615bdc738b8Skre cm a '[[:alpha:]]'; cf 0; cf '"["'; cm Z; cf aa; cf .; cf '""' # 80 616bdc738b8Skre cf a '[[:digit:]]'; cm 0; cf '"["'; cm 9; cf 10; cf .; cf '""' # 87 617bdc738b8Skre cm '"["' '[][:alpha:][]'; cf a '[\[:alpha:]]'; cf a '[[\:alpha:]]' #90 618bdc738b8Skre cm a '[$var]' 'var="[:alpha:]"'; cm a '[[$var]]' 'var=":alpha:"' # 92 619bdc738b8Skre cm a '[[:$var:]]' 'var=alpha'; cm B '[[:"$var":]]' 'var=alpha' # 94 620bdc738b8Skre cf B '["$var"]' 'var="[:alpha:]"'; cf B '[["$var"]]' 'var=":alpha:"' #96 621bdc738b8Skre cm '"["' '["$var"]' 'var="[:alpha:]"' # 97 622bdc738b8Skre cm '"[]"' '[["$var"]]' 'var=":alpha:"'; # 98 623bdc738b8Skre cm A3 '[[:alpha:]][[:digit:]]'; cf '"[["' #100 624bdc738b8Skre cm 3 '[[:alpha:][:digit:]]'; cf '"["'; cm A; cf '":"' #104 625bdc738b8Skre for W in AA A7 8x 77; do 626bdc738b8Skre cm "$W" '[[:alpha:][:digit:]][[:alpha:][:digit:]]' #108 627bdc738b8Skre done 628bdc738b8Skre 629bdc738b8Skre cm dir/file '*/*'; cm /dir/file; cm /dir/file '*/file' #111 630bdc738b8Skre for W in aa/bcd /x/y/z .x/.abc --/--- '\\//\\//' '[]/[][]' 631bdc738b8Skre do 632bdc738b8Skre cm "'$W'" '??/*'; cm "'$W'" '[-a/.\\[]?/??*[]dzc/-]' 633bdc738b8Skre done #123 634bdc738b8Skre 635bdc738b8Skre cm '"?abc"' '\?*'; cf '"\\abc"'; cm '"?"' #126 636bdc738b8Skre 637bdc738b8Skre cm '\\z' '"\\z"'; cf '\z'; cf z; cf '"\\"' #130 638bdc738b8Skre 639bdc738b8Skre cm '"[x?abc"' '[[-\]]?\?*'; cm '"]x?abc"'; cm '"\\x?abc"' #133 640bdc738b8Skre cf '"-x?abc"'; cf '"[xyzabc"'; cm '"[]?"' #136 641bdc738b8Skre 642bdc738b8Skre cm '"[x?"' '[]\\[]?\?'; cm '"]x?"'; cm '"\\y?"'; cm '"[]?"' #140 643bdc738b8Skre 644bdc738b8Skre cm "'\z'" '"\z"'; cf z; cm '\\z'; cm '$var' '' 'var="\z"' #144 645bdc738b8Skre cm '${var}' '' "var='\z'"; cm '"${var}"' #146 646fd909972Skre cf '${var}' '${var}' "var='\z'"; cm '${var}' '"${var}"' "var='\z'" #148 647bdc738b8Skre cf "'${var}'"; cm "'${var}'" "'${var}'" "var='\z'" #150 648bdc738b8Skre 649bdc738b8Skre cf abc '"$*"' 'IFS=?; set -- a c';cf '"a c"';cm "'a?c'";cm '"$*"' #154 650bdc738b8Skre cf abc '"$*"' 'IFS=*; set -- a c';cf '"a c"';cm "'a*c'";cm '"$*"' #158 651bdc738b8Skre cf abc '"$*"' 'IFS=\\;set -- a c';cf '"a c"';cm "'a\c'";cm '"$*"' #162 652bdc738b8Skre cf abc '"$*"' 'IFS="";set -- a c';cf '"a c"';cm "'ac'"; cm '"$*"' #166 653bdc738b8Skre 654bdc738b8Skre cm a '["$*"]' 'IFS=-; set -- a c';cf b;cm c;cm '-'; cf "']'" #171 655bdc738b8Skre cm a '["$*"]' 'IFS=?; set -- a c';cf b;cm c;cm '"?"'; cf "'['" #176 656bdc738b8Skre cm a '["$*"]' 'IFS=*; set -- a c';cf b;cm c;cm '"*"'; cf - #181 657bdc738b8Skre cm a '["$*"]' 'IFS=\\;set -- a c';cf b;cm c;cm "'\\'";cf "'$'" #186 658bdc738b8Skre cm a '["$*"]' 'IFS="";set -- a c';cf b;cm c #189 659bdc738b8Skre 660bdc738b8Skre 661bdc738b8Skre # Now repeat the ones using bracket expressions, adding ! 662bdc738b8Skre 663bdc738b8Skre cf a '[!ab]'; cf b; cm c; cf aa; cf '"[!ab]"'; cm a '[ab!]'; cm ! #196 664bdc738b8Skre cf a '$var' 'var="[!ab]"';cm x;cf a '"$var"' 'var="[!ab]"'; cf x #200 665bdc738b8Skre cm '"[!ab]"' '"$var"' 'var="[!ab]"'; cf a; cf b; cf !; cf "'['" #205 666bdc738b8Skre cf a '[!"$var"]' 'var=ab'; cm x; cm a '["!$var"]' 'var=ab' #208 667bdc738b8Skre cf x; cm !; cm a '["$var"]' 'var=!ab'; cf x #212 668bdc738b8Skre cf a '[$var]' 'var=!ab'; cm ! #214 669bdc738b8Skre 670bdc738b8Skre cf b '[!a-c]'; cf a; cf c; cm d; cm !; cm -; cm _; cm '\\' #222 671bdc738b8Skre cf a '$var' 'var="[!a-c]"'; cf b; cf c; cm d; cm !; cm - #228 672bdc738b8Skre 673bdc738b8Skre cf 2 '[!0-4]'; cf 0; cm -; cf 4; cm !; cm "'['"; cm "']'" #235 674bdc738b8Skre cm 2 '[!-04]'; cm 2 '[!40-]'; cf 0; cf -; cm !; #240 675bdc738b8Skre cm 2 '[!0\-4]'; cf -; cm 2 '[!"0-4"]'; cf - #244 676bdc738b8Skre 677bdc738b8Skre cf a '[![:alpha:]]'; cm 0; cm '"["'; cf aa; cm .; cf '""' #250 678bdc738b8Skre cf '"["' '[!][:alpha:][!]'; cf a; cm 0; cf !; cf "']'"; cm % #256 679bdc738b8Skre cf a '[$var]' 'var="![:alpha:]"'; cm 0; cm !; cm "']'"; cm @ #261 680bdc738b8Skre 6810ebdf0f8Skre # Next some tests of patterns containing (intended literal) '\' 6820ebdf0f8Skre # The first of the "set" tests pair was reported as broken bu 6830ebdf0f8Skre # Martijn Dekker (private mail) (Nov 2018). 6840ebdf0f8Skre 685fa836fadSkre cm "'\\'" "'\\'"; cf "'\\'" "'\\\\'" #263 686fa836fadSkre cm "'\\'" '"$var"' "var='\\'"; cf "'\\'" '$var' "var='\\'" #265 687fa836fadSkre cm '$1' '"$2"' 'set -- \\ \\'; cf '$1' '$2' 'set -- \\ \\' #267 688fa836fadSkre cf '$1' '"$2"' 'set -- \\ \\\\'; cm '$1' '$2' 'set -- \\ \\\\' #269 689fa836fadSkre cm "'\\'" "\$( echo '\\\\' )"; cf "'\\'" "\$( echo '\\' )" #271 690fa836fadSkre cm "'\\'" "\"\$( echo '\\' )\"" #272 691fa836fadSkre cf "'\\'" "\"\$( echo '\\\\' )\"" #273 692fa836fadSkre 693fa836fadSkre if X=$( ${TEST_SH} -c 'printf %s '"\$'\\\\'" 2>/dev/null ) && 694fa836fadSkre [ "$X" = '\' ] 695fa836fadSkre then 696fa836fadSkre # TEST_SH supports $'...' so we can test it as well 697fa836fadSkre # note these are $'\\' and $'\\\\' as patterns. 698fa836fadSkre # They should be identical to '\' and '\\' 699fa836fadSkre cm "'\\'" "\$'\\\\'"; cf "'\\'" "\$'\\\\\\\\'" #275 700fa836fadSkre else 701fa836fadSkre # uncomment this if we need to keep sub-test numbering sane 702fa836fadSkre # it isn't needed as long as this remains last. 703fa836fadSkre # (nb: this is just a repeat of sub-test 263) 704fa836fadSkre 705fa836fadSkre # cm "'\\'" "'\\'"; cf "'\\'" "'\\\\'" #275 706fa836fadSkre fi 7070ebdf0f8Skre 708bdc738b8Skre results 709bdc738b8Skre} 710bdc738b8Skre 711bdc738b8Skreatf_test_case var_substring_matching 712bdc738b8Skrevar_substring_matching_head() { 713bdc738b8Skre atf_set descr 'Test pattern matching in var expansions' 714bdc738b8Skre} 715bdc738b8Skre 716bdc738b8Skre# Helper function for var substring matching 717bdc738b8Skre# $1 is the input string 718bdc738b8Skre# $2 the substring matching operator (# % ## or %%) 719bdc738b8Skre# $3 is the pattern to match (or reference to one) 720bdc738b8Skre# $4 is the expected output (result of applying op($2) with pat($3) to $1 721bdc738b8Skre# $5 (if given, and not null) is a command (or commands) to run first 722bdc738b8Skre# $6 (if given, and not null) cause the var expansion to be quoted 723bdc738b8Skre# (ie "${var%pattern}" instead of just ${var%pattern}) 724bdc738b8Skre# any quotes needed in "pattern" should be in $3 725bdc738b8Skre# Note: a variable called "var" is used (set to $1, then expanded). 726bdc738b8Skrevm() 727bdc738b8Skre{ 728bdc738b8Skre check "${5:+${5}; }var='$1';printf '%s\n' ${6:+\"}\${var$2$3}${6:+\"}" \ 729bdc738b8Skre "$4" 0 730bdc738b8Skre} 731bdc738b8Skre 732bdc738b8Skrevar_substring_matching_body() { 733bdc738b8Skre 734bdc738b8Skre reset var_substring_matching 735bdc738b8Skre 736bdc738b8Skre vm abc \# a bc; vm aaab \# a aab; vm aaab \## 'a*a' b # 3 737fd909972Skre vm aaab % ab aa; vm xawab %% 'a*ab' x; vm abcd \# xyz abcd 738fd909972Skre vm file.c % .c 'f le' IFS=i ; vm file.c % .c file IFS=i Q 739fd909972Skre vm file.c % ?c file ; vm file.c % '"?c"' file.c # 9 10 740bdc738b8Skre 741fd909972Skre vm abcabcabcded \# 'a*b' cabcabcded; vm abcabcabcded \## 'a*b' cded 742fd909972Skre vm abcabcabcded % 'c*d' abcabcab; vm abcabcabcded %% 'c*d' ab 743bdc738b8Skre 744bdc738b8Skre vm abc.jpg % '.[a-z][!0-9]?' abc # 15 745bdc738b8Skre 746fd909972Skre vm xxxyyy \# '${P}' yyy P=xxx; vm xxxyyy \# '${P}' yyy 'P=x?x' 747fd909972Skre vm xxxyyy \# '${P}' yyy 'P=x?x' Q 748fd909972Skre vm 'x?xyyy' \# '${P}' yyy 'P=x[?]x' 749fd909972Skre vm xxxyyy \# '${P}' xxxyyy 'P=x[?]x' # 20 750fd909972Skre vm 'x?xyyy' \# '${P}' yyy 'P=x?x' Q 751fd909972Skre vm xxxyyy \# '${P}' yyy 'P=x?x' Q 752fd909972Skre vm 'x?xyyy' \# '${P}' yyy 'P="x\?x"' 753fd909972Skre vm 'x?xyyy' \# '${P}' yyy 'P="x\?x"' Q 754bdc738b8Skre vm 'x?xyyy' \# '${P}' yyy 'P="x?x"' # 25 755fd909972Skre vm 'x?xyyy' \# '${P}' yyy 'P="x?x"' Q 756fd909972Skre vm 'x?xyyy' \# '"${P}"' 'x?xyyy' 'P="x\?x"' 757fd909972Skre vm 'x?xyyy' \# '"${P}"' 'x?xyyy' 'P="x\?x"' Q 758fd909972Skre vm 'x?xyyy' \# '"${P}"' yyy 'P="x?x"' 759fd909972Skre vm 'x?xyyy' \# '"${P}"' yyy 'P="x?x"' Q # 30 760fd909972Skre vm 'x%xyyy' \# '${P}' 'x%xyyy' 'P="x\?x"' 761fd909972Skre vm 'x%xyyy' \# '${P}' 'x%xyyy' 'P="x\?x"' Q 762fd909972Skre vm 'x%xyyy' \# '${P}' yyy 'P="x?x"' 763fd909972Skre vm 'x%xyyy' \# '${P}' yyy 'P="x?x"' Q 764fd909972Skre vm 'x%xyyy' \# '"${P}"' 'x%xyyy' 'P="x\?x"' # 35 765fd909972Skre vm 'x%xyyy' \# '"${P}"' 'x%xyyy' 'P="x\?x"' Q 766fd909972Skre vm 'x%xyyy' \# '"${P}"' 'x%xyyy' 'P="x?x"' 767fd909972Skre vm 'x%xyyy' \# '"${P}"' 'x%xyyy' 'P="x?x"' Q 768bdc738b8Skre 769fd909972Skre vm abc \# '*' abc; vm abc \# '*' abc '' Q # 39 40 770fd909972Skre vm abc \# '"*"' abc; vm abc \# '"*"' abc '' Q 771fd909972Skre vm abc \# '"a"' bc; vm abc \# '"a"' bc '' Q 772fd909972Skre vm abc \## '*' ''; vm abc \## '*' '' '' Q 773fd909972Skre vm abc % '*' abc; vm abc % '*' abc '' Q 774fd909972Skre vm abc %% '*' ''; vm abc %% '*' '' '' Q # 49 50 775fd909972Skre vm abc \# '$P' abc 'P="*"'; vm abc \# '$P' abc 'P="*"' Q 776fd909972Skre vm abc \# '"$P"' abc 'P="*"'; vm abc \# '"$P"' abc 'P="*"' Q 777fd909972Skre vm abc \# '$P' bc 'P="[a]"'; vm abc \# '$P' bc 'P="[a]"' Q 778fd909972Skre vm abc \# '"$P"' abc 'P="[a]"'; vm abc \# '"$P"' abc 'P="[a]"' Q 779fd909972Skre vm '[a]bc' \# '$P' '[a]bc' 'P="[a]"' 780fd909972Skre vm '[a]bc' \# '"$P"' bc 'P="[a]"' # 60 781fd909972Skre vm '[a]bc' \# '"$P"' bc 'P="[a]"' Q 782bdc738b8Skre 783fd909972Skre # The following two (62 & 63) are actually the same test. 784fd909972Skre # The double \\ turns into a single \ when parsed. 785fd909972Skre vm '[a]bc' \# '$P' bc 'P="\[a]"'; vm '[a]bc' \# '$P' bc 'P="\\[a]"' 786fd909972Skre vm '[a]bc' \# '"$P"' '[a]bc' 'P="\[a]"' 787fd909972Skre vm '\[a]bc' \# '"$P"' bc 'P="\[a]"' # 65 788bdc738b8Skre 789fd909972Skre vm ababcdabcd \# '[ab]*[ab]' abcdabcd 790fd909972Skre vm ababcdabcd \## '[ab]*[ab]' cd 791fd909972Skre vm ababcdabcd \# '$P' abcdabcd 'P="[ab]*[ab]"' 792fd909972Skre vm ababcdabcd \## '$P' cd "P='[ab]*[ab]'" 793fd909972Skre vm ababcdabcd \# '$P' 'ab dab d' 'P="[ab]*[ab]"; IFS=c' # 70 794fd909972Skre vm ababcdabcd \# '$P' abcdabcd 'P="[ab]*[ab]"; IFS=c' Q 795bdc738b8Skre 796fd909972Skre vm ababcdabcd \# '[ab]*[ba]' abcdabcd 797fd909972Skre vm ababcdabcd \# '[ab]*[a-b]' abcdabcd 798fd909972Skre vm ababcdabcd \## '[ba]*[ba]' cd 799fd909972Skre vm ababcdabcd \## '[a-b]*[ab]' cd # 75 800bdc738b8Skre 801fd909972Skre vm abcde \# '?[b-d]?' de; vm abcde \## '?[b-d]?' de 802fd909972Skre vm abcde % '?[b-d]?' ab; vm abcde %% '?[b-d]?' ab 803bdc738b8Skre 804fd909972Skre vm .123. \# '.[0-9][1-8]' 3.; vm .123. % '[0-9][1-8].' .1 # 80 81 805fd909972Skre vm .123. \# '?[0-9][1-8]' 3.; vm .123. % '[0-9][1-8]?' .1 806fd909972Skre vm .123. \# '*[0-9][1-8]' 3.; vm .123. % '[0-9][1-8]*' .1 # 85 807fd909972Skre vm .123. \## '*[0-9][1-8]' .; vm .123. %% '[0-9][1-8]*' . 808fd909972Skre vm .123. \# '[.][1][2]' 3. ; vm .123. % '[2][3][.]' .1 809fd909972Skre vm .123. \# '[?]1[2]' .123. ; vm .123. % '2[3][?]' .123. # 90 91 810fd909972Skre vm .123. \# '\.[0-9][1-8]' 3.;vm .123. % '[0-9][1-8]\.' .1 811bdc738b8Skre 812fd909972Skre vm '[a-c]d-f' \# '[a-c\]' d-f 813fd909972Skre vm '[abcd]' \# '[[:alpha:]]' '[abcd]' # 95 814fd909972Skre vm '[1?234' \# '[[-\]]?\?' 234 815fd909972Skre vm '1-2-3-\?' % '-${P}' '1-2-3-\?' 'P="\\?"' 816fd909972Skre vm '1-2-3-\?' % '${P}' '1-2-3-\' 'P="\\?"' 817fd909972Skre vm '1-2-3-\?' % '-"${P}"' 1-2-3 'P="\\?"' # 99 818bdc738b8Skre 819bdc738b8Skre results 820bdc738b8Skre} 821bdc738b8Skre 822bdc738b8Skre 823bdc738b8Skreatf_init_test_cases() { 824bdc738b8Skre # Listed here in the order ATF runs them, not the order from above 825bdc738b8Skre 826bdc738b8Skre atf_add_test_case filename_expansion 827bdc738b8Skre atf_add_test_case case_matching 828bdc738b8Skre atf_add_test_case var_substring_matching 829bdc738b8Skre} 830