1# $NetBSD: t_grep.sh,v 1.8 2024/11/23 09:38:02 rillig Exp $ 2# 3# Copyright (c) 2008, 2009, 2021, 2024 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28atf_test_case basic 29basic_head() 30{ 31 atf_set "descr" "Checks basic functionality" 32} 33basic_body() 34{ 35 atf_check -o file:"$(atf_get_srcdir)/d_basic.out" -x \ 36 'jot 10000 | grep 123' 37} 38 39atf_test_case binary 40binary_head() 41{ 42 atf_set "descr" "Checks handling of binary files" 43} 44binary_body() 45{ 46 dd if=/dev/zero count=1 of=test.file 47 echo -n "foobar" >> test.file 48 atf_check -o file:"$(atf_get_srcdir)/d_binary.out" grep foobar test.file 49} 50 51atf_test_case recurse 52recurse_head() 53{ 54 atf_set "descr" "Checks recursive searching" 55} 56recurse_body() 57{ 58 mkdir -p recurse/a/f recurse/d 59 echo -e "cod\ndover sole\nhaddock\nhalibut\npilchard" > recurse/d/fish 60 echo -e "cod\nhaddock\nplaice" > recurse/a/f/favourite-fish 61 62 atf_check -o file:"$(atf_get_srcdir)/d_recurse.out" -x "grep -r haddock recurse | sort" 63} 64 65atf_test_case recurse_noarg 66recurse_noarg_head() 67{ 68 atf_set "descr" "Checks recursive searching without file argument" 69} 70recurse_noarg_body() 71{ 72 mkdir -p recurse/a/f recurse/d 73 echo -e "cod\ndover sole\nhaddock\nhalibut\npilchard" > recurse/d/fish 74 echo -e "cod\nhaddock\nplaice" > recurse/a/f/favourite-fish 75 76 atf_check -o file:"$(atf_get_srcdir)/d_recurse_noarg.out" -x "cd recurse && grep -r haddock | sort" 77} 78 79atf_test_case recurse_symlink 80recurse_symlink_head() 81{ 82 atf_set "descr" "Checks symbolic link recursion" 83} 84recurse_symlink_body() 85{ 86 mkdir -p test/c/d 87 (cd test/c/d && ln -s ../d .) 88 echo "Test string" > test/c/match 89 90 atf_check -o file:"$(atf_get_srcdir)/d_recurse_symlink.out" \ 91 -e file:"$(atf_get_srcdir)/d_recurse_symlink.err" \ 92 grep -r string test 93} 94 95atf_test_case word_regexps 96word_regexps_head() 97{ 98 atf_set "descr" "Checks word-regexps" 99} 100word_regexps_body() 101{ 102 atf_check -o file:"$(atf_get_srcdir)/d_word_regexps.out" \ 103 grep -w separated $(atf_get_srcdir)/d_input 104} 105 106atf_test_case word_locale 107word_locale_head() 108{ 109 atf_set "descr" "Checks word search with locale" 110} 111word_locale_body() 112{ 113 echo "array[]" > "input" 114 115 # In the default locale, word search works. 116 atf_check -o file:"input" \ 117 env LC_ALL=C grep "array" "input" 118 atf_check -o file:"input" \ 119 env LC_ALL=C grep -w "array" "input" 120 121 # XXX: In an UTF-8 locale, GNU Grep treats '[' as a word character. 122 atf_check -s exit:1 -o empty \ 123 env LC_ALL="C.UTF-8" grep -w "array" "input" 124} 125 126atf_test_case word_in_line 127word_in_line_head() 128{ 129 atf_set "descr" "Checks word search in different locations of a line" 130} 131word_in_line_body() 132{ 133 # See usr.bin/grep/util.c, "Check for whole word match", which 134 # looks suspiciously wrong. And indeed, NetBSD grep does not 135 # survive this test. GNU Grep does. 136 137 echo "begin middle end" > "input" 138 139 # A word at the beginning of a line is found. 140 atf_check -o file:"input" \ 141 env LC_ALL=C grep -w "begin" "input" 142 143 # A word in the middle of a line is found. 144 atf_check -o file:"input" \ 145 env LC_ALL=C grep -w "middle" "input" 146 147 # A word at the end of a line is found. 148 atf_check -o file:"input" \ 149 env LC_ALL=C grep -w "end" "input" 150 151 # A subword at the beginning of a line is not found. 152 atf_check -s exit:1 -o empty \ 153 env LC_ALL=C grep -w "be" "input" 154 155 # A subword in the middle of a line is not found. 156 atf_check -s exit:1 -o empty \ 157 env LC_ALL=C grep -w "mid" "input" 158 atf_check -s exit:1 -o empty \ 159 env LC_ALL=C grep -w "dle" "input" 160 161 # A subword at the end of a line is not found. 162 atf_check -s exit:1 -o empty \ 163 env LC_ALL=C grep -w "nd" "input" 164} 165 166atf_test_case word_in_line_utf8 167word_in_line_utf8_head() 168{ 169 atf_set "descr" "Checks word search at the beginning of a line" 170} 171word_in_line_utf8_body() 172{ 173 # See usr.bin/grep/util.c, "Check for whole word match", which 174 # looks suspiciously wrong. And indeed, NetBSD grep does not 175 # survive this test. GNU Grep does. 176 177 echo "begin middle end" > "input" 178 179 # A word at the beginning of a line is found. 180 atf_check -o file:"input" \ 181 env LC_ALL="C.UTF-8" grep -w "begin" "input" 182 183 # A word in the middle of a line is found. 184 atf_check -o file:"input" \ 185 env LC_ALL="C.UTF-8" grep -w "middle" "input" 186 187 # A word at the end of a line is found. 188 atf_check -o file:"input" \ 189 env LC_ALL="C.UTF-8" grep -w "end" "input" 190 191 # A subword at the beginning of a line is not found. 192 atf_check -s exit:1 -o empty \ 193 env LC_ALL="C.UTF-8" grep -w "be" "input" 194 195 # A subword in the middle of a line is not found. 196 atf_check -s exit:1 -o empty \ 197 env LC_ALL="C.UTF-8" grep -w "mid" "input" 198 atf_check -s exit:1 -o empty \ 199 env LC_ALL="C.UTF-8" grep -w "dle" "input" 200 201 # A subword at the end of a line is not found. 202 atf_check -s exit:1 -o empty \ 203 env LC_ALL="C.UTF-8" grep -w "nd" "input" 204} 205 206atf_test_case begin_end 207begin_end_head() 208{ 209 atf_set "descr" "Checks handling of line beginnings and ends" 210} 211begin_end_body() 212{ 213 atf_check -o file:"$(atf_get_srcdir)/d_begin_end_a.out" \ 214 grep ^Front "$(atf_get_srcdir)/d_input" 215 216 atf_check -o file:"$(atf_get_srcdir)/d_begin_end_b.out" \ 217 grep ending$ "$(atf_get_srcdir)/d_input" 218} 219 220atf_test_case ignore_case 221ignore_case_head() 222{ 223 atf_set "descr" "Checks ignore-case option" 224} 225ignore_case_body() 226{ 227 atf_check -o file:"$(atf_get_srcdir)/d_ignore_case.out" \ 228 grep -i Upper "$(atf_get_srcdir)/d_input" 229} 230 231atf_test_case invert 232invert_head() 233{ 234 atf_set "descr" "Checks selecting non-matching lines with -v option" 235} 236invert_body() 237{ 238 atf_check -o file:"$(atf_get_srcdir)/d_invert.out" \ 239 grep -v fish "$(atf_get_srcdir)/d_invert.in" 240} 241 242atf_test_case whole_line 243whole_line_head() 244{ 245 atf_set "descr" "Checks whole-line matching with -x flag" 246} 247whole_line_body() 248{ 249 atf_check -o file:"$(atf_get_srcdir)/d_whole_line.out" \ 250 grep -x matchme "$(atf_get_srcdir)/d_input" 251} 252 253atf_test_case negative 254negative_head() 255{ 256 atf_set "descr" "Checks handling of files with no matches" 257} 258negative_body() 259{ 260 atf_check -s ne:0 grep "not a hope in hell" "$(atf_get_srcdir)/d_input" 261} 262 263atf_test_case context 264context_head() 265{ 266 atf_set "descr" "Checks displaying context with -A, -B and -C flags" 267} 268context_body() 269{ 270 cp $(atf_get_srcdir)/d_context_*.* . 271 272 atf_check -o file:d_context_a.out grep -C2 bamboo d_context_a.in 273 atf_check -o file:d_context_b.out grep -A3 tilt d_context_a.in 274 atf_check -o file:d_context_c.out grep -B4 Whig d_context_a.in 275 atf_check -o file:d_context_d.out grep -C1 pig d_context_a.in d_context_b.in 276} 277 278atf_test_case file_exp 279file_exp_head() 280{ 281 atf_set "descr" "Checks reading expressions from file" 282} 283file_exp_body() 284{ 285 atf_check -o file:"$(atf_get_srcdir)/d_file_exp.out" -x \ 286 'jot 21 -1 1.00 | grep -f '"$(atf_get_srcdir)"'/d_file_exp.in' 287} 288 289atf_test_case egrep 290egrep_head() 291{ 292 atf_set "descr" "Checks matching special characters with egrep" 293} 294egrep_body() 295{ 296 atf_check -o file:"$(atf_get_srcdir)/d_egrep.out" \ 297 egrep '\?|\*$$' "$(atf_get_srcdir)/d_input" 298} 299 300atf_test_case zgrep 301zgrep_head() 302{ 303 atf_set "descr" "Checks handling of gzipped files with zgrep" 304} 305zgrep_body() 306{ 307 cp "$(atf_get_srcdir)/d_input" . 308 gzip d_input || atf_fail "gzip failed" 309 310 atf_check -o file:"$(atf_get_srcdir)/d_zgrep.out" zgrep -h line d_input.gz 311} 312 313atf_test_case nonexistent 314nonexistent_head() 315{ 316 atf_set "descr" "Checks that -s flag suppresses error" \ 317 "messages about nonexistent files" 318} 319nonexistent_body() 320{ 321 atf_check -s ne:0 grep -s foobar nonexistent 322} 323 324atf_test_case context2 325context2_head() 326{ 327 atf_set "descr" "Checks displaying context with -z flag" 328} 329context2_body() 330{ 331 printf "haddock\000cod\000plaice\000" > test1 332 printf "mackeral\000cod\000crab\000" > test2 333 334 atf_check -o file:"$(atf_get_srcdir)/d_context2_a.out" \ 335 grep -z -A1 cod test1 test2 336 337 atf_check -o file:"$(atf_get_srcdir)/d_context2_b.out" \ 338 grep -z -B1 cod test1 test2 339 340 atf_check -o file:"$(atf_get_srcdir)/d_context2_c.out" \ 341 grep -z -C1 cod test1 test2 342} 343 344atf_test_case pr_58849 345pr_58849_head() 346{ 347 atf_set "descr" "Checks overlapping patterns in whole-line search" 348} 349pr_58849_body() 350{ 351 printf '%s\n' __bss_start__ __bss_end__ hello > input 352 353 # The line '__bss_end__' must not occur in the output. 354 atf_check -o inline:'__bss_start__\nhello\n' \ 355 grep -Fvx -e _end -e __bss_end__ input 356 357 # Listing the most specific pattern first works around PR bin/58849. 358 atf_check -o inline:'__bss_start__\nhello\n' \ 359 grep -Fvx -e __bss_end__ -e _end input 360} 361 362atf_init_test_cases() 363{ 364 atf_add_test_case basic 365 atf_add_test_case binary 366 atf_add_test_case recurse 367 atf_add_test_case recurse_noarg 368 atf_add_test_case recurse_symlink 369 atf_add_test_case word_regexps 370 atf_add_test_case word_locale 371 atf_add_test_case word_in_line 372 atf_add_test_case word_in_line_utf8 373 atf_add_test_case begin_end 374 atf_add_test_case ignore_case 375 atf_add_test_case invert 376 atf_add_test_case whole_line 377 atf_add_test_case negative 378 atf_add_test_case context 379 atf_add_test_case file_exp 380 atf_add_test_case egrep 381 atf_add_test_case zgrep 382 atf_add_test_case nonexistent 383 atf_add_test_case context2 384 atf_add_test_case pr_58849 385} 386