Home | History | Annotate | Line # | Download | only in grep
t_grep.sh revision 1.8
      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 
     28 atf_test_case basic
     29 basic_head()
     30 {
     31 	atf_set "descr" "Checks basic functionality"
     32 }
     33 basic_body()
     34 {
     35 	atf_check -o file:"$(atf_get_srcdir)/d_basic.out" -x \
     36 	    'jot 10000 | grep 123'
     37 }
     38 
     39 atf_test_case binary
     40 binary_head()
     41 {
     42 	atf_set "descr" "Checks handling of binary files"
     43 }
     44 binary_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 
     51 atf_test_case recurse
     52 recurse_head()
     53 {
     54 	atf_set "descr" "Checks recursive searching"
     55 }
     56 recurse_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 
     65 atf_test_case recurse_noarg
     66 recurse_noarg_head()
     67 {
     68 	atf_set "descr" "Checks recursive searching without file argument"
     69 }
     70 recurse_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 
     79 atf_test_case recurse_symlink
     80 recurse_symlink_head()
     81 {
     82 	atf_set "descr" "Checks symbolic link recursion"
     83 }
     84 recurse_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 
     95 atf_test_case word_regexps
     96 word_regexps_head()
     97 {
     98 	atf_set "descr" "Checks word-regexps"
     99 }
    100 word_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 
    106 atf_test_case word_locale
    107 word_locale_head()
    108 {
    109 	atf_set "descr" "Checks word search with locale"
    110 }
    111 word_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 
    126 atf_test_case word_in_line
    127 word_in_line_head()
    128 {
    129 	atf_set "descr" "Checks word search in different locations of a line"
    130 }
    131 word_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 
    166 atf_test_case word_in_line_utf8
    167 word_in_line_utf8_head()
    168 {
    169 	atf_set "descr" "Checks word search at the beginning of a line"
    170 }
    171 word_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 
    206 atf_test_case begin_end
    207 begin_end_head()
    208 {
    209 	atf_set "descr" "Checks handling of line beginnings and ends"
    210 }
    211 begin_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 
    220 atf_test_case ignore_case
    221 ignore_case_head()
    222 {
    223 	atf_set "descr" "Checks ignore-case option"
    224 }
    225 ignore_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 
    231 atf_test_case invert
    232 invert_head()
    233 {
    234 	atf_set "descr" "Checks selecting non-matching lines with -v option"
    235 }
    236 invert_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 
    242 atf_test_case whole_line
    243 whole_line_head()
    244 {
    245 	atf_set "descr" "Checks whole-line matching with -x flag"
    246 }
    247 whole_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 
    253 atf_test_case negative
    254 negative_head()
    255 {
    256 	atf_set "descr" "Checks handling of files with no matches"
    257 }
    258 negative_body()
    259 {
    260 	atf_check -s ne:0 grep "not a hope in hell" "$(atf_get_srcdir)/d_input"
    261 }
    262 
    263 atf_test_case context
    264 context_head()
    265 {
    266 	atf_set "descr" "Checks displaying context with -A, -B and -C flags"
    267 }
    268 context_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 
    278 atf_test_case file_exp
    279 file_exp_head()
    280 {
    281 	atf_set "descr" "Checks reading expressions from file"
    282 }
    283 file_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 
    289 atf_test_case egrep
    290 egrep_head()
    291 {
    292 	atf_set "descr" "Checks matching special characters with egrep"
    293 }
    294 egrep_body()
    295 {
    296 	atf_check -o file:"$(atf_get_srcdir)/d_egrep.out" \
    297 		egrep '\?|\*$$' "$(atf_get_srcdir)/d_input"
    298 }
    299 
    300 atf_test_case zgrep
    301 zgrep_head()
    302 {
    303 	atf_set "descr" "Checks handling of gzipped files with zgrep"
    304 }
    305 zgrep_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 
    313 atf_test_case nonexistent
    314 nonexistent_head()
    315 {
    316 	atf_set "descr" "Checks that -s flag suppresses error" \
    317 	                "messages about nonexistent files"
    318 }
    319 nonexistent_body()
    320 {
    321 	atf_check -s ne:0 grep -s foobar nonexistent
    322 }
    323 
    324 atf_test_case context2
    325 context2_head()
    326 {
    327 	atf_set "descr" "Checks displaying context with -z flag"
    328 }
    329 context2_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 
    344 atf_test_case pr_58849
    345 pr_58849_head()
    346 {
    347 	atf_set "descr" "Checks overlapping patterns in whole-line search"
    348 }
    349 pr_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 
    362 atf_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