1#!/bin/ksh -p 2# 3# Copyright (c) 1992 Diomidis Spinellis. 4# Copyright (c) 1992, 1993 5# The Regents of the University of California. All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 3. Neither the name of the University nor the names of its contributors 16# may be used to endorse or promote products derived from this software 17# without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29# SUCH DAMAGE. 30# 31# @(#)sed.test 8.1 (Berkeley) 6/6/93 32# 33# $FreeBSD$ 34# 35 36# sed Regression Tests 37# 38# The directory regress.test.out contains the expected test results 39# 40# These are the regression tests mostly created during the development 41# of the BSD sed. Each test should have a unique mark name, which is 42# used for naming the corresponding file in regress.multitest.out. 43 44SRCDIR=$(dirname $0) 45 46SED=${SED:=/usr/bin/sed} 47 48# 49# Sanitize the environment so we're able to operate with known good 50# defaults. Note, tests such as 7.1 require that we're in the C locale. 51# 52unalias -a 53export LANG=C 54 55typeset -i err=0 56typeset -i pass=0 57typeset -i fail=0 58 59fatal() { 60 echo "[FATAL] $*" > /dev/stderr 61 exit 1 62} 63 64main() 65{ 66 REGRESS=${SRCDIR}/regress.multitest.out 67 [[ -d $REGRESS ]] || fatal "Could not locate regress directory" 68 69 DICT=/usr/share/lib/dict/words 70 [[ -r $DICT ]] || fatal "Coult not read dictionary $DICT" 71 72 OPDIR=$(mktemp -d) 73 [[ -n "$OPDIR" && -d "$OPDIR" ]] || \ 74 fatal "Could not create output directory" 75 76 awk 'END { for (i = 1; i < 15; i++) print "l1_" i}' \ 77 </dev/null >$OPDIR/lines1 78 awk 'END { for (i = 1; i < 10; i++) print "l2_" i}' \ 79 </dev/null >$OPDIR/lines2 80 [[ -s $OPDIR/lines1 && -s $OPDIR/lines2 ]] || \ 81 fatal "Could not seed lines files" 82 83 lines1=$OPDIR/lines1 84 lines2=$OPDIR/lines2 85 lines3=$OPDIR/lines3 86 lines4=$OPDIR/lines4 87 script1=$OPDIR/script1 88 script2=$OPDIR/script2 89 90 exec 4>&1 5>&2 91 tests 92 exec 1>&4 2>&5 93 94 # Remove temporary files 95 rm -rf $OPDIR/ 96} 97 98tests() 99{ 100 MARK=0 101 102 test_args 103 test_addr 104 test_group 105 test_acid 106 test_branch 107 test_pattern 108 test_print 109 test_subst 110 test_error 111 # Handle the result of the last test 112 result 113} 114 115# Display a test's result 116result() 117{ 118 if [ "$TODO" = '1' ] ; then 119 TODO='TODO ' 120 else 121 TODO='' 122 fi 123 if ! [ -r $REGRESS/${TESTNAME} ] ; then 124 echo "Seeding $REGRESS/${TESTNAME} with current result" 1>&2 125 cp $OPDIR/current.out $REGRESS/${TESTNAME} 126 fi 127 if cmp -s $REGRESS/${TESTNAME} $OPDIR/current.out ; then 128 echo "[PASS] $MARK $TESTNAME # $TODO$OCOMMENT" 129 ((pass++)) 130 else 131 echo "[FAIL] $MARK $TESTNAME # $TODO$OCOMMENT" 132 if [[ -z "$TODO" ]]; then 133 diff -u $REGRESS/${TESTNAME} $OPDIR/current.out 134 ((fail++)) 135 err=1 136 fi 137 fi 1>&4 2>&5 138} 139 140# Mark the beginning of each test 141mark() 142{ 143 [ $MARK -gt 0 ] && result 144 OCOMMENT=$COMMENT 145 MARK=`expr $MARK + 1` 146 TESTNAME=$1 147 exec 1>&4 2>&5 148 exec >"$OPDIR/current.out" 149} 150 151test_args() 152{ 153 COMMENT='Argument parsing - first type' 154 mark '1.1' 155 $SED 's/^/e1_/p' $lines1 156 mark '1.2' ; $SED -n 's/^/e1_/p' $lines1 157 mark '1.3' 158 $SED 's/^/e1_/p' <$lines1 159 mark '1.4' ; $SED -n 's/^/e1_/p' <$lines1 160 COMMENT='Argument parsing - second type' 161 mark '1.4.1' 162 $SED -e '' <$lines1 163 echo 's/^/s1_/p' >$script1 164 echo 's/^/s2_/p' >$script2 165 mark '1.5' 166 $SED -f $script1 $lines1 167 mark '1.6' 168 $SED -f $script1 <$lines1 169 mark '1.7' 170 $SED -e 's/^/e1_/p' $lines1 171 mark '1.8' 172 $SED -e 's/^/e1_/p' <$lines1 173 mark '1.9' ; $SED -n -f $script1 $lines1 174 mark '1.10' ; $SED -n -f $script1 <$lines1 175 mark '1.11' ; $SED -n -e 's/^/e1_/p' $lines1 176 mark '1.12' 177 $SED -n -e 's/^/e1_/p' <$lines1 178 mark '1.13' 179 $SED -e 's/^/e1_/p' -e 's/^/e2_/p' $lines1 180 mark '1.14' 181 $SED -f $script1 -f $script2 $lines1 182 mark '1.15' 183 $SED -e 's/^/e1_/p' -f $script1 $lines1 184 mark '1.16' 185 $SED -e 's/^/e1_/p' $lines1 $lines1 186 # POSIX D11.2:11251 187 mark '1.17' ; $SED p <$lines1 $lines1 188cat >$script1 <<EOF 189#n 190# A comment 191 192p 193EOF 194 mark '1.18' ; $SED -f $script1 <$lines1 $lines1 195} 196 197test_addr() 198{ 199 COMMENT='Address ranges' 200 mark '2.1' ; $SED -n -e '4p' $lines1 201 mark '2.2' ; $SED -n -e '20p' $lines1 $lines2 202 mark '2.3' ; $SED -n -e '$p' $lines1 203 mark '2.4' ; $SED -n -e '$p' $lines1 $lines2 204 mark '2.5' ; $SED -n -e '$a\ 205hello' /dev/null 206 mark '2.6' ; $SED -n -e '$p' $lines1 /dev/null $lines2 207 # Should not print anything 208 mark '2.7' ; $SED -n -e '20p' $lines1 209 mark '2.8' ; $SED -n -e '/NOTFOUND/p' $lines1 210 mark '2.9' ; $SED -n '/l1_7/p' $lines1 211 mark '2.10' ; $SED -n ' /l1_7/ p' $lines1 212 mark '2.11' ; $SED -n '\_l1\_7_p' $lines1 213 mark '2.12' ; $SED -n '1,4p' $lines1 214 mark '2.13' ; $SED -n '1,$p' $lines1 $lines2 215 mark '2.14' ; $SED -n '1,/l2_9/p' $lines1 $lines2 216 mark '2.15' ; $SED -n '/4/,$p' $lines1 $lines2 217 mark '2.16' ; $SED -n '/4/,20p' $lines1 $lines2 218 mark '2.17' ; $SED -n '/4/,/10/p' $lines1 $lines2 219 mark '2.18' ; $SED -n '/l2_3/,/l1_8/p' $lines1 $lines2 220 mark '2.19' ; $SED -n '12,3p' $lines1 $lines2 221 mark '2.20' ; $SED -n '/l1_7/,3p' $lines1 $lines2 222 mark '2.21' ; $SED -n '13,+4p' $lines1 $lines2 223 mark '2.22' ; $SED -n '/l1_6/,+2p' $lines1 $lines2 224 # For PR bin/192108 225 mark '2.23'; $SED -n '12,+1p' $lines1 226} 227 228test_group() 229{ 230 COMMENT='Brace and other grouping' 231 mark '3.1' ; $SED -e ' 2324,12 { 233 s/^/^/ 234 s/$/$/ 235 s/_/T/ 236}' $lines1 237 mark '3.2' ; $SED -e ' 2384,12 { 239 s/^/^/ 240 /6/,/10/ { 241 s/$/$/ 242 /8/ s/_/T/ 243 } 244}' $lines1 245 mark '3.3' ; $SED -e ' 2464,12 !{ 247 s/^/^/ 248 /6/,/10/ !{ 249 s/$/$/ 250 /8/ !s/_/T/ 251 } 252}' $lines1 253 mark '3.4' ; $SED -e '4,12!s/^/^/' $lines1 254} 255 256test_acid() 257{ 258 COMMENT='Commands a c d and i' 259 mark '4.1' ; $SED -n -e ' 260s/^/before_i/p 26120i\ 262inserted 263s/^/after_i/p 264' $lines1 $lines2 265 mark '4.2' ; $SED -n -e ' 2665,12s/^/5-12/ 267s/^/before_a/p 268/5-12/a\ 269appended 270s/^/after_a/p 271' $lines1 $lines2 272 mark '4.3' 273 $SED -n -e ' 274s/^/^/p 275/l1_/a\ 276appended 2778,10N 278s/$/$/p 279' $lines1 $lines2 280 mark '4.4' ; $SED -n -e ' 281c\ 282hello 283' $lines1 284 mark '4.5' ; $SED -n -e ' 2858c\ 286hello 287' $lines1 288 mark '4.6' ; $SED -n -e ' 2893,14c\ 290hello 291' $lines1 292# SunOS and GNU sed behave differently. We follow POSIX 293 mark '4.7' ; $SED -n -e ' 2948,3c\ 295hello 296' $lines1 297 mark '4.8' ; $SED d <$lines1 298} 299 300test_branch() 301{ 302 COMMENT='Labels and branching' 303 mark '5.1' ; $SED -n -e ' 304b label4 305:label3 306s/^/label3_/p 307b end 308:label4 3092,12b label1 310b label2 311:label1 312s/^/label1_/p 313b 314:label2 315s/^/label2_/p 316b label3 317:end 318' $lines1 319 mark '5.2' 320 $SED -n -e ' 321s/l1_/l2_/ 322t ok 323b 324:ok 325s/^/tested /p 326' $lines1 $lines2 327# SunOS and GNU sed behave as follows: lines 9-$ aren't printed at all 328 mark '5.3' ; $SED -n -e ' 3295,8b inside 3301,5 { 331 s/^/^/p 332 :inside 333 s/$/$/p 334} 335' $lines1 336# Check that t clears the substitution done flag 337 mark '5.4' ; $SED -n -e ' 3381,8s/^/^/ 339t l1 340:l1 341t l2 342s/$/$/p 343b 344:l2 345s/^/ERROR/ 346' $lines1 347# Check that reading a line clears the substitution done flag 348 mark '5.5' 349 $SED -n -e ' 350t l2 3511,8s/^/^/p 3522,7N 353b 354:l2 355s/^/ERROR/p 356' $lines1 357 mark '5.6' ; $SED 5q $lines1 358 mark '5.7' ; $SED -e ' 3595i\ 360hello 3615q' $lines1 362# Branch across block boundary 363 mark '5.8' ; $SED -e ' 364{ 365:b 366} 367s/l/m/ 368tb' $lines1 369} 370 371test_pattern() 372{ 373COMMENT='Pattern space commands' 374# Check that the pattern space is deleted 375 mark '6.1' ; $SED -n -e ' 376c\ 377changed 378p 379' $lines1 380 mark '6.2' ; $SED -n -e ' 3814d 382p 383' $lines1 384 mark '6.3' 385 $SED -e 'N;N;N;D' $lines1 386 mark '6.4' ; $SED -e ' 3872h 3883H 3894g 3905G 3916x 3926p 3936x 3946p 395' $lines1 396 mark '6.5' ; $SED -e '4n' $lines1 397 mark '6.6' ; $SED -n -e '4n' $lines1 398} 399 400test_print() 401{ 402 COMMENT='Print and file routines' 403 awk 'END {for (i = 1; i < 256; i++) printf("%c", i);print "\n"}' \ 404 </dev/null >$lines3 405 # GNU and SunOS sed behave differently here 406 mark '7.1' 407 $SED -n l $lines3 408 mark '7.2' ; $SED -e '/l2_/=' $lines1 $lines2 409 rm -f $lines4 410 mark '7.3' ; $SED -e "3,12w $lines4" $lines1 411 COMMENT='w results' 412 cat $lines4 413 mark '7.4' ; $SED -e "4r $lines2" $lines1 414 mark '7.5' ; $SED -e '5r /dev/dds' $lines1 415 mark '7.6' ; $SED -e '6r /dev/null' $lines1 416 mark '7.7' 417 $SED '200q' $DICT | $SED 's$.*$s/^/&/w tmpdir/&$' >$script1 418 rm -rf tmpdir 419 mkdir tmpdir 420 $SED -f $script1 $lines1 421 cat tmpdir/* 422 rm -rf tmpdir 423 mark '7.8' 424 echo line1 > $lines3 425 echo "" >> $lines3 426 $SED -n -e '$p' $lines3 /dev/null 427 428} 429 430test_subst() 431{ 432 COMMENT='Substitution commands' 433 mark '8.1' ; $SED -e 's/./X/g' $lines1 434 mark '8.2' ; $SED -e 's,.,X,g' $lines1 435# SunOS sed thinks we are escaping . as wildcard, not as separator 436 mark '8.3' 437 $SED -e 's.\..X.g' $lines1 438 mark '8.4' ; $SED -e 's/[\/]/Q/' $lines1 439 mark '8.5' ; $SED -e 's_\__X_' $lines1 440 mark '8.6' ; $SED -e 's/./(&)/g' $lines1 441 mark '8.7' ; $SED -e 's/./(\&)/g' $lines1 442 mark '8.8' ; $SED -e 's/\(.\)\(.\)\(.\)/x\3x\2x\1/g' $lines1 443 mark '8.9' ; $SED -e 's/_/u0\ 444u1\ 445u2/g' $lines1 446 mark '8.10' 447 $SED -e 's/./X/4' $lines1 448 rm -f $lines4 449 mark '8.11' ; $SED -e "s/1/X/w $lines4" $lines1 450 COMMENT='s wfile results' 451 cat $lines4 452 mark '8.12' ; $SED -e 's/[123]/X/g' $lines1 453 mark '8.13' ; $SED -e 'y/0123456789/9876543210/' $lines1 454 mark '8.14' ; 455 $SED -e 'y10\123456789198765432\101' $lines1 456 mark '8.15' ; $SED -e '1N;2y/\n/X/' $lines1 457 mark '8.16' 458 echo 'eeefff' | $SED -e ' 459 p 460 s/e/X/p 461 :x 462 s//Y/p 463 # Establish limit counter in the hold space 464 # GNU sed version 3.02 enters into an infinite loop here 465 x 466 /.\{10\}/ { 467 s/.*/ERROR/ 468 b 469 } 470 s/.*/&./ 471 x 472 /f/bx 473 ' 474 # POSIX does not say that this should work, 475 # but it does for GNU, BSD, and SunOS 476 mark '8.17' ; $SED -e 's/[/]/Q/' $lines1 477 478 COMMENT='[ as an s delimiter and its escapes' 479 mark '8.18' ; $SED -e 's[_[X[' $lines1 480 # This is a matter of interpretation 481 # POSIX 1003.1, 2004 says "Within the BRE and the replacement, 482 # the BRE delimiter itself can be used as a *literal* character 483 # if it is preceded by a backslash" 484 # SunOS 5.1 /usr/bin/sed and Mac OS X follow the literal POSIX 485 # interpretation. 486 # GNU sed version 4.1.5 treats \[ as the beginning of a character 487 # set specification (both with --posix and without). 488 mark '8.19' ; $SED 's/l/[/' $lines1 | $SED -e 's[\[.[X[' 489 mark '8.20' ; $SED 's/l/[/' $lines1 | $SED -e 's[\[.[X\[[' 490 COMMENT='\\ in y command' 491 mark '8.21' 492 echo 'a\\b(c' | \ 493 $SED 'y%ABCDEFGHIJKLMNOPQRSTUVWXYZ, /\\()"%abcdefghijklmnopqrstuvwxyz,------%' 494 COMMENT='\\n in a character class' 495 mark '8.22' ; (echo 1; echo 2) | $SED -n '1{;N;s/[\n]/X/;p;}' 496 COMMENT='\\n in a BRE' 497 mark '8.23' ; (echo 1; echo 2) | $SED -n '1{;N;s/\n/X/;p;}' 498} 499 500test_error() 501{ 502 COMMENT='Error cases' 503 mark '9.1' ; $SED -x 2>/dev/null ; echo $? 504 mark '9.2' ; $SED -f 2>/dev/null ; echo $? 505 mark '9.3' ; $SED -e 2>/dev/null ; echo $? 506 mark '9.4' ; $SED -f /dev/xyzzyxyzy 2>/dev/null ; echo $? 507 mark '9.5' ; $SED p /dev/xyzzyxyzy 2>/dev/null ; echo $? 508 mark '9.6' ; $SED -f /bin/sh 2>/dev/null ; echo $? 509 mark '9.7' ; $SED '{' 2>/dev/null ; echo $? 510 mark '9.8' ; $SED '{' 2>/dev/null ; echo $? 511 mark '9.9' ; $SED '/hello/' 2>/dev/null ; echo $? 512 mark '9.10' ; $SED '1,/hello/' 2>/dev/null ; echo $? 513 mark '9.11' ; $SED -e '-5p' 2>/dev/null ; echo $? 514 mark '9.12' ; $SED '/jj' 2>/dev/null ; echo $? 515 mark '9.13' ; $SED 'a hello' 2>/dev/null ; echo $? 516 mark '9.14' ; $SED 'a \ hello' 2>/dev/null ; echo $? 517 mark '9.15' ; $SED 'b foo' 2>/dev/null ; echo $? 518 mark '9.16' ; $SED 'd hello' 2>/dev/null ; echo $? 519 mark '9.17' ; $SED 's/aa' 2>/dev/null ; echo $? 520 mark '9.18' ; $SED 's/aa/' 2>/dev/null ; echo $? 521 mark '9.19' ; $SED 's/a/b' 2>/dev/null ; echo $? 522 mark '9.20' ; $SED 's/a/b/c/d' 2>/dev/null ; echo $? 523 mark '9.21' ; $SED 's/a/b/ 1 2' 2>/dev/null ; echo $? 524 mark '9.22' ; $SED 's/a/b/ 1 g' 2>/dev/null ; echo $? 525 mark '9.23' ; $SED 's/a/b/w' 2>/dev/null ; echo $? 526 mark '9.24' ; $SED 'y/aa' 2>/dev/null ; echo $? 527 mark '9.25' ; $SED 'y/aa/b/' 2>/dev/null ; echo $? 528 mark '9.26' ; $SED 'y/aa/' 2>/dev/null ; echo $? 529 mark '9.27' ; $SED 'y/a/b' 2>/dev/null ; echo $? 530 mark '9.28' ; $SED 'y/a/b/c/d' 2>/dev/null ; echo $? 531 mark '9.29' ; $SED '!' 2>/dev/null ; echo $? 532 mark '9.30' ; $SED supercalifrangolisticexprialidociussupercalifrangolisticexcius 2>/dev/null ; echo $? 533 mark '9.31' ; $SED '' /dev/null 2>/dev/null ; echo $? 534} 535 536main 537echo "Pass/fail - $pass/$fail" 538exit $err 539