trip.rc (20371B)
1 # trip.rc -- take a tour of rc 2 # Invoke as "path-to-new-rc < trip.rc" 3 4 rc=$0 5 echo tripping $rc $version 6 7 tmpdir='' 8 fn fail { 9 echo >[1=2] trip took a wrong turn: $* 10 rm -rf $tmpdir 11 fn sigexit 12 exit 1 13 } 14 fn expect { 15 echo >[1=2] -n expect $^*^': ' 16 } 17 fn submatch { 18 if (!~ $#* 3) 19 fail incorrect invocation of submatch 20 got = `` $nl { prompt=$nl $rc -ic $1>[2=1] } 21 if (!~ $got $2) { 22 echo got $got expected $2 23 fail $3 24 } 25 } 26 fn sigexit sigint sigquit sigsegv 27 fn sigexit { 28 echo trip complete 29 } 30 tmpdir=`{ mktemp -d -t rc-trip.XXXXXX } 31 tmp=$tmpdir/tmp 32 nl=' 33 ' 34 35 # 36 # rc -c 37 # 38 39 if ($rc -c >[2]/dev/null) fail 'rc -c didn''t report a bad exit status' 40 x=`{$rc -c 'echo $0 $2 $#*' a b c d e f} 41 if (false) { # WARNING: this differs from sh 42 if (!~ $x(1) a) fail rc -c reports '$0' incorrectly as $x(1) 43 if (!~ $x(2) c) fail rc -c reports '$2' incorrectly as $x(2) 44 if (!~ $x(3) 5) fail rc -c reports '$#' incorrectly as $x(3) 45 } else { 46 if (!~ $x(1) $rc) fail rc -c reports '$0' incorrectly as $x(1) 47 if (!~ $x(2) b) fail rc -c reports '$2' incorrectly as $x(2) 48 if (!~ $x(3) 6) fail rc -c reports '$#' incorrectly as $x(3) 49 } 50 51 # 52 # umask 53 # 54 55 umask 0 56 > $tmp 57 x=`{ls -l $tmp} 58 if (!~ $x(1) -rw-rw-rw-*) fail umask 0 produced incorrect result: $x(1) 59 rm -f $tmp 60 umask 027 61 > $tmp 62 y=`{ls -l $tmp} 63 if (!~ $y(1) -rw-r-----*) fail umask 027 produced incorrect file: $y(1) 64 rm -f $tmp 65 if (!~ `umask 027) fail umask reported bad value: `umask 66 67 submatch 'umask bad' 'bad umask' 'bad umask' 68 submatch 'umask -027' 'bad umask' 'bad umask' 69 submatch 'umask 999999' 'bad umask' 'bad umask' 70 submatch 'umask hi there' 'rc: too many arguments to umask' 'umask arg count' 71 72 if (!~ `umask 027) fail bad umask changed umask value to `umask 73 74 # 75 # redirections 76 # 77 78 fn bytes { for (i) x=`{wc -c $i} echo $x(1) } 79 echo foo > foo > bar 80 if (!~ `{bytes foo} 0) fail double redirection created non-empty empty file 81 if (!~ `{bytes bar} 4) fail double redirection created wrong sized file: `{bytes bar} 82 rm -f foo bar 83 echo -n >1 >[2]2 >[1=2] foo 84 x = `` '' {cat 1} 85 if (!~ $#x 0) fail dup created non-empty empty file: `` '' {cat 1} 86 if (!~ `` '' {cat 2} foo) fail dup put wrong contents in file : `` '' {cat 2} 87 rm -f 1 2 88 89 expect error from cat, closing stdin 90 cat >[0=] 91 92 submatch 'cat>(1 2 3)' 'rc: multi-word filename in redirection' 'redirection error' 93 submatch 'cat>()' 'rc: null filename in redirection' 'redirection error' 94 95 # 96 # blow the input stack 97 # 98 99 if (!~ hi `{ 100 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 101 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 102 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 103 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 104 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 105 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 106 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 107 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 108 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 109 eval eval eval eval eval eval eval eval eval eval eval eval eval \ 110 eval eval eval eval eval eval eval eval eval eval eval echo hi 111 }) 112 fail huge eval 113 114 # 115 # heredocs and herestrings 116 # 117 118 bigfile=$tmpdir/big.$pid 119 od $rc | sed 5000q > $bigfile 120 abc=(this is a) 121 x=() 122 result='this is a heredoc 123 this is an heredoc 124 ' 125 if (!~ `` '' {<<[5] EOF cat <[0=5]} $result) fail unquoted heredoc 126 $abc heredoc$x 127 $abc^n $x^here$x^doc 128 EOF 129 {if (!~ `` $nl cat ' ') fail quoted heredoc} << ' ' 130 131 132 133 <<<[9] ``''{cat $bigfile} \ 134 { 135 if(!~ ``''{cat <[0=9]}``'' cat)fail large herestrings 136 } < \ 137 $bigfile 138 139 rm -f $bigfile 140 141 if (!~ `{cat<<eof 142 $$ 143 eof 144 } '$') 145 fail quoting '$' in heredoc 146 147 submatch 'cat<<eof' 'rc: heredoc incomplete' 'incomplete heredoc' 148 submatch 'cat<<eof 149 ' 'rc: heredoc incomplete' 'incomplete heredoc' 150 151 submatch 'cat<<(eof eof)' 'rc: eof-marker not a single literal word' 'bad heredoc marker' 152 153 # 154 # lexical analysis 155 # 156 157 expect warning 158 ./tripping 0 > $tmp 159 $rc $tmp 160 rm -f $tmp 161 162 echo here_is_a_really_long_word.It_has_got_to_be_longer_than_1000_characters_for_the_lexical_analyzers_buffer_to_overflow_but_that_should_not_be_too_difficult_to_do.Let_me_start_writing_some_Lewis_Carroll.Twas_brillig_and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe.All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.Beware_the_Jabberwock_my_son,The_jaws_that_bite,the_claws_that_catch.Beware_the_Jub-jub_bird,and_shun_The_frumious_Bandersnatch.He_took_his_vorpal_sword_in_hand,Long_time_the_manxome_foe_he_sought,So_rested_he_by_the_Tumtum_tree,And_stood_awhile_in_thought.And_as_in_uffish_thought_he_stood,The_Jabberwock,with_eyes_of_flame,Came_whiffling_through_the_tulgey_wood,And_burbled_as_it_came.One_two,one_two.And_through_and_through_The_vorpal_blade_went_snicker-snack.He_left_it_dead_and_with_its_head,He_went_galumphing_back.And_hast_thou_slain_the_Jabberwock?Come_to_my_arms,my_beamish_boy,Oh_frabjous_day.Callooh_callay.He_chortled_in_his_joy.Twas_brillig,and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe,All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe. > $tmpdir/$pid.lw 163 164 echo 'here_is_a_really_long_word.It_has_got_to_be_longer_than_1000_characters_for_the_lexical_analyzers_buffer_to_overflow_but_that_should_not_be_too_difficult_to_do.Let_me_start_writing_some_Lewis_Carroll.Twas_brillig_and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe.All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.Beware_the_Jabberwock_my_son,The_jaws_that_bite,the_claws_that_catch.Beware_the_Jub-jub_bird,and_shun_The_frumious_Bandersnatch.He_took_his_vorpal_sword_in_hand,Long_time_the_manxome_foe_he_sought,So_rested_he_by_the_Tumtum_tree,And_stood_awhile_in_thought.And_as_in_uffish_thought_he_stood,The_Jabberwock,with_eyes_of_flame,Came_whiffling_through_the_tulgey_wood,And_burbled_as_it_came.One_two,one_two.And_through_and_through_The_vorpal_blade_went_snicker-snack.He_left_it_dead_and_with_its_head,He_went_galumphing_back.And_hast_thou_slain_the_Jabberwock?Come_to_my_arms,my_beamish_boy,Oh_frabjous_day.Callooh_callay.He_chortled_in_his_joy.Twas_brillig,and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe,All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.' > $tmpdir/$pid.lq 165 166 if (!~ ``(){cat $tmpdir/$pid.lw} ``(){cat $tmpdir/$pid.lq}) 167 fail expected long string and long word to be identical 168 if (! x=`{wc -c $tmpdir/$pid.lw} ~ $x(1) 1088) 169 fail expected long word to be 1088 bytes 170 if (! x=`{wc -c $tmpdir/$pid.lq} ~ $x(1) 1088) 171 fail expected long quote to be 1088 bytes 172 173 rm $tmpdir/$pid.lw 174 rm $tmpdir/$pid.lq 175 176 submatch 'echo hi |[2' 'rc: expected ''='' or '']'' after digit' 'scan error' 177 submatch 'echo hi |[92=]' 'rc: expected digit after ''=''' 'scan error' 178 submatch 'echo hi |[a]' 'rc: expected digit after ''[''' 'scan error' 179 submatch 'echo hi |[2-' 'rc: expected ''='' or '']'' after digit' 'scan error' 180 submatch 'echo hi |[2=99a]' 'rc: expected '']'' after digit' 'scan error' 181 submatch 'echo hi |[2=a99]' 'rc: expected digit or '']'' after ''=''' 'scan error' 182 submatch 'echo ''hi' 'rc: eof in quoted string' 'scan error' 183 184 ifs='' { 185 if (!~ 'h i' `{echo -n h\ 186 i}) 187 fail backslash-newline to space conversion 188 if (!~ $rc^\rc `{echo -n $rc\rc}) 189 fail backslash after variable name did not terminate variable name scan 190 if (!~ $rc^' rc' `{echo -n $rc\ 191 rc}) 192 fail backslash-newline after variable name space conversion 193 if (!~ 'h\i' `{echo -n h\i}) 194 fail backslash in the middle of word 195 if (!~ 'h \ i' `{echo -n h \ i}) 196 fail free-standing backslash 197 } 198 199 if (! $rc -c '# eof in comment') 200 fail eof in comment exited with nonzero status 201 202 # test the syntax error printer 203 204 prompt='' if (!~ `` $nl {$rc -cif>[2=1]} 'rc: line 1: '*' error near if') 205 fail print syntax error 206 207 prompt='' if (!~ `` $nl {$rc -icif>[2=1]} *' error') 208 fail print syntax error 209 210 # 211 # builtins 212 # 213 214 fn foo { 215 return sigfpe 216 } 217 218 foo 219 if (!~ $status sigfpe) 220 fail return builtin did not return sigfpe 221 222 fn foo # test deleting of function 223 fn bar { 224 for (i in 1 2 3 4 5) 225 if (~ $i 3) 226 return 227 } 228 229 bar 230 if (!~ $i 3) 231 fail return inside loop inside function failed 232 233 submatch return 'rc: return outside of function' 'return outside of function' 234 submatch 'break 1' 'rc: too many arguments to break' 'break arg count' 235 submatch break 'rc: break outside of loop' 'break outside of loop' 236 237 for (i in 1 2 3 4 5) 238 if (~ $i 2) 239 break 240 if (!~ $i 2) 241 fail break out of loop 242 243 submatch 'wait foo' 'rc: `foo'' is a bad number' 'bogus argument to wait' 244 245 if (~ `{echo -n} ?) 246 fail echo -n 247 if (!~ `` '' {echo --} $nl) 248 fail echo -- 249 250 pwd=`{/bin/pwd -P} cdpath=/ { # some local assignments 251 home=/tmp cd 252 if (!~ `{/bin/pwd -P} `{sh -c 'cd /tmp; /bin/pwd -P'}) 253 fail could not cd to '$home' 254 255 cdpath=/ cd tmp 256 if (!~ `{/bin/pwd -P} `{sh -c 'cd /tmp; /bin/pwd -P'}) 257 fail could not cd to /tmp 258 259 cd $pwd 260 if (!~ `{/bin/pwd -P} `{sh -c 'cd $pwd; /bin/pwd -P'}) 261 fail could not cd to current directory! 262 } 263 264 # Test that cd to a directory found via cdpath produces output 265 # when interactive. 266 submatch 'cdpath=/ cd tmp' /tmp 'cdpath produced wrong output' 267 268 *=(1 2 3 4 5) { 269 expect bad number 270 shift foo 271 expect arg count 272 shift 1 2 3 273 expect shift overflow 274 shift 123 275 shift 3 276 if (!~ $#* 2) 277 fail shift 3 of '(1 2 3 4 5)' failed 278 shift 279 if (!~ $* 5) 280 fail shift failed to shift left-to-right 281 } 282 283 false 284 eval && fail null eval reset '$status' 285 286 if (!~ `{rm=(); fn rm; path=(. /bin); whatis rm} /bin/rm) 287 fail rm isn''''t in bin!? 288 289 expect list of signal handlers 290 whatis -s 291 292 expect list of variables and functions 293 whatis 294 295 submatch 'whatis -x' 'whatis: bad option: -x' 'bad option to whatis' 296 297 submatch 'whatis /frobnatz' '/frobnatz not found' 'search for /frobnatz' 298 299 if (~ `{whatis limit >[2]/dev/null} builtin) { 300 limit coredumpsize 0 301 if (!~ `{limit coredumpsize} 0*) 302 fail failed to set coredumpsize to zero 303 if (!~ `` () {limit coredumpsize} `` () {limit|grep coredumpsize}) 304 fail limit limit 305 submatch 'limit foo' 'no such limit' 'bad limit' 306 } 307 308 fn cd 309 310 submatch 'cd a b c' 'rc: too many arguments to cd' 'cd arg count' 311 $rc -c 'cdpath=() cd /frobnatz' >[2]/dev/null && fail 'cd to /frobnatz succeeded!?' 312 submatch 'cdpath='''' cd frobnatz' 'couldn''t cd to frobnatz' 'cd to frobnatz succeeded!?' 313 314 'if'=keyword { 315 {whatis if | fgrep '''if''=keyword' >/dev/null} || fail whatis of keyword is not quoted 316 } 317 318 # 319 # wait 320 # 321 322 submatch 'wait 1 2 3' 'rc: too many arguments to wait' 'wait arg count' 323 $rc -c 'wait 1' >[2]/dev/null && fail wait 1 324 325 sleep 3& 326 expect $apid 327 echo $apids 328 wait 329 330 if (~ `` '' {wait} ?) 331 fail waiting for nothing 332 333 # 334 # matching 335 # 336 touch $tmpdir/abc.$pid $tmpdir/bbc.$pid 337 mkdir $tmpdir/dir.$pid $tmpdir/dip.$pid 338 touch $tmpdir/dir.$pid/^(a b c) $tmpdir/dip.$pid/^(a b c) 339 340 if (!~ 123 [~x]?[0-9]) 341 fail match 342 if (!~ () *) 343 fail match of null list with '*' 344 if (~ () *v*) 345 fail match of null list with '*v*' succeeded 346 if (!~ (foo bar zar) *****z*****) 347 fail match of list by one pattern failed 348 if (~ (foo bar zar) *c*) 349 fail bad match 350 if (!~ [aaa [aaa) 351 fail bad rangematch 352 if (!~ ']' []]) 353 fail match right bracket 354 if (~ x [y]) 355 fail rangematch out of range 356 if (~ x x?) 357 fail too many characters in pattern 358 359 sh -c 'test -f /////$tmpdir//////a?c.'^$pid || fail glob with many slashes 360 if (!~ /////$tmpdir//////a*.$pid /////$tmpdir//////a?c.$pid) 361 fail glob with many slashes 362 if (!~ ////$tmpdir////di?.$pid////* ////$tmpdir////dir.$pid////*b*) 363 fail glob with more slashes 364 if (! @{cd $tmpdir; ~ *.$pid/a d*/*}) 365 fail glob in current directory 366 if (!~ $tmpdir/?bc.$pid $tmpdir/bbc.$pid) 367 fail match of bbc.$pid against '('abc.$pid bbc.$pid')' 368 369 rm $tmpdir/abc.$pid $tmpdir/bbc.$pid 370 rm -rf $tmpdir/dir.$pid $tmpdir/dip.$pid 371 372 # 373 # signals 374 # 375 fn sigint {eval} 376 kill -2 $pid 377 fn sigint 378 379 # 380 # path searching 381 # 382 $rc -c /frobnatz >[2]/dev/null && fail 'search error' 383 384 touch $tmpdir/noexec.$pid 385 chmod a-x $tmpdir/noexec.$pid 386 $rc -c $tmpdir/noexec.$pid >[2]/dev/null && fail $tmpdir/noexec.$pid is found!? 387 rm $tmpdir/noexec.$pid 388 389 submatch 'path='''' frobnatz' 'rc: cannot find `frobnatz''' 'search error' 390 391 {path=() /bin/sh -c 'exit 0'} || fail abs pathname with path set to null 392 393 # 394 # options 395 # 396 397 # this test is meaningless; not really a trip 398 expect prompt, echo hi 399 home=/frobnatz $rc -nolpeivdxc 'echo hi' 400 if (!~ `` $nl {$rc -c>[2=1]} *': option requires an argument -- c') 401 fail getopt on -c 402 if (!~ `` $nl {$rc -q>[2=1]} *': bad option: -q') 403 fail getopt on -q (bogus option) 404 if (!~ `{echo '#echo' | $rc -v |[2] sed 's/#//'} echo) 405 fail rc -v 406 407 # 408 # dot 409 # 410 411 if (~ `` '' . ?*) 412 fail null dot 413 if (~ `` '' {. -i} ?*) 414 fail null dot -i 415 416 cat > $tmpdir/dot.$pid << eof 417 echo hi 418 eof 419 420 prompt=';' if (!~ `` '' {. -i $tmpdir/dot.$pid>[2=1]} ';hi'^$nl';') 421 fail dot -i 422 submatch .' '$tmpdir/dot.$pid hi dot 423 424 rm $tmpdir/dot.$pid 425 426 $rc -c '. /frobnatz' >[2]/dev/null && fail 'dot of a nonexistent file' 427 428 # 429 # stdin 430 # 431 if (!~ `{echo echo hi | $rc} hi) 432 fail piping stdin to rc 433 434 # 435 # functions, variables & environment 436 # 437 fn --- {for(i)a|[2=3]b>>c<<<e&f>[2=1]} 438 439 if (whatis printenv >/dev/null>[2=1]) { 440 printenv=printenv 441 } else if (whatis env >/dev/null>[2=1]) { 442 printenv=env 443 } else 444 printenv=() 445 446 if (~ $#printenv 1 && !~ `` $nl {$printenv | grep fn___2d__2d__2d} 'fn___2d__2d__2d={for(i in $*)a|[2=3]b >>c <<<e&f >[2=1]}') 447 fail protect_env 448 449 fn --- {replace} 450 ~ `{whatis -- ---} *replace* || fail replace a function definition 451 fn --- 452 whatis -- --- >[2]/dev/null && fail function deletion 453 foo=bar *=bar 454 foo=nest *=nest { 455 ~ $foo nest || fail local assignment 456 ~ $* nest || fail local assignment to '$*' 457 foo=() 458 *=() 459 ~ $foo () || fail local deletion 460 ~ $* () || fail local deletion to '$*' 461 } 462 ~ $foo bar || fail restore of global after local group 463 ~ $* bar || fail restore of '$*' after local group 464 ~ `{exec>[2=1];$rc -xc 'foo=()'} 'foo=()' || fail -x echo of variable deletion 465 466 fn_ff='{' prompt='' if (!~ `` $nl {$rc -cff>[2=1]} 'rc: line 1: '*' error near eof') 467 fail 'bogus function in environment' 468 469 # 470 # statuses 471 # 472 ~ `{$rc -ec 'sleep 10&kill -9 $apid;wait'>[2=1]} killed || 473 fail status diagnostic 474 475 $rc -c 'exit 0 sigfpe' && fail exit of bad pipeline is true 476 477 submatch 'exit foo' 'bad status' 'exit diagnostic' 478 479 # 480 # control structures 481 # 482 if (!~ `{false || echo hi} hi) 483 fail '||' 484 if (!~ `{true && echo hi} hi) 485 fail '&&' 486 if (~ `{true || echo hi} hi) 487 fail '||' 488 if (~ `{false && echo hi} hi) 489 fail '&&' 490 491 while (false) 492 fail false while 493 while (true) { 494 break 495 fail break in while 496 } 497 498 switch (foo) { 499 case bar 500 fail matched bar in switch 501 case foo 502 eval 503 case * 504 fail match foo in switch 505 } 506 507 switch (nothing) { 508 case bar 509 fail matched bar in switch 510 case * 511 i=frobnatz 512 } 513 514 ~ $i frobnatz || fail match '*' in switch 515 516 submatch '()=()' 'rc: null variable name' 'assignment diagnostic' 517 submatch 'fn () {eval}' 'rc: null function name' 'assigning null function name' 518 519 # 520 # prompt 521 # 522 fn prompt {echo hi} 523 prompt=() if (!~ `{$rc -i /dev/null>[2]/dev/null} hi) fail fn prompt 524 fn prompt 525 526 # 527 # history 528 # 529 history=$tmpdir/hist.$pid prompt='' echo 'history=()' | $rc -i 530 531 if (!~ `{cat $tmpdir/hist.$pid} 'history=()') 532 fail output to history file 533 534 history=$tmpdir/hist.$pid prompt='' echo 'history=()' | $rc -i 535 536 if (!~ `` () {cat $tmpdir/hist.$pid} 'history=() 537 history=() 538 ') 539 fail append to history file 540 541 rm $tmpdir/hist.$pid 542 543 if (!~ `{history=/frobnatz/foo prompt='' echo eval | $rc -i >[2=1]} ?*) 544 fail accessing bad history file 545 546 # 547 # regression 548 # 549 550 expect date 551 { date & wait } |cat 552 553 # Making rc's input non-blocking should have no untoward side effects. 554 x=`{ { sleep 1; echo echo foo } | { ./tripping n; $rc >[2=1] } } 555 if (!~ foo $x) 556 fail input file descriptor nonblocking 557 558 # `rc -s' reads from stdin, but should not imply `-i' 559 expect foo bar qux 560 $rc -s foo bar qux <<'eof' 561 echo $* 562 eof 563 564 # Believe it or not, I broke root directory globbing in rc-1.6b1. 565 x=/* 566 ~ '/*' $^x && fail root directory globbing 567 568 # fn sigexit should be cleared in children 569 570 x = () 571 expect rc: cannot find '`nonesuch''' 572 x = `{true | nonesuch}; if (~ $x trip) fail sigexit in children 573 x = `{ < /dev/null wc |grep xxx }; if (~ $x trip) fail sigexit in children 574 x = `{{ wc | wc } < /dev/null }; if (~ $x trip) fail sigexit in children 575 576 # core dumps in glob.c 577 ~ () '*' && fail globber problem 578 ~ () '**' && fail globber problem 579 580 # check for ctrl-a bug 581 x=`{./tripping a} 582 ~ `{$rc -c 'echo $x'} $x || fail ctrl-a bug detected 583 584 # check for hilarious quoting bug introduced while fixing ctrl-a 585 x=('#' '#' '#') 586 eval z^`{whatis -v x} 587 ~ $#zx 3 || fail hilarious quoting bug 588 589 # parens bypass quote detector bug 590 fn x {echo x.y $(x.y)} 591 ~ ``''{whatis -f x} 'fn x {echo x.y $(x^.y)} 592 ' || fail sneaky parens bug 593 594 # before rc-1.7.1, certain glob patterns could fail on broken symlinks 595 mkdir $tmpdir/qux 596 ln -s /frobnatz $tmpdir/qux/foo 597 x=$tmpdir/qux/foo* 598 ~ $x $tmpdir/qux/foo || { rm -rf $tmpdir/qux; fail broken symlink globbing } 599 x=$tmpdir/qux*/foo 600 ~ $x $tmpdir/qux/foo || { rm -rf $tmpdir/qux; fail broken symlink globbing } 601 602 rm -rf $tmpdir 603 604 ############################################################################# 605 ## Check builtin continue in while loop. 606 ############################################################################# 607 q='''' 608 C=$q^while-continue$q 609 L=() 610 611 save_star = * 612 ten = a^(1 2 3 4 5 6 7 8 9 10) 613 * = $ten 614 while (! ~ $#* 0) { 615 n = $1; shift 616 if (~ $n a2 a3) { 617 continue 618 } 619 L=($L $n) 620 } 621 * = $save_star; save_star = () 622 623 if (!~ $#L 8) { 624 fail Wrong length of list from $C: $#L 625 } 626 if (!~ $L(1) a1) { 627 fail First element of $C list is not a1: $L(1) 628 } 629 if (!~ $L(2) a4) { 630 fail Second element of $C list is not a4: $L(2) 631 } 632 C=() L=() 633 634 ############################################################################# 635 ## Check builtin continue in for loop. 636 ############################################################################# 637 C=$q^for-continue$q 638 L=() 639 640 for (x in a b c d e f g) { 641 if (~ $x c f) { 642 continue 643 } 644 L=($L $x) 645 } 646 if (!~ $#L 5) { 647 fail Wrong length of list from $C 648 } 649 if (!~ $L(1) a) { 650 fail First element of $C list is not a: $L(1) 651 } 652 if (!~ $L(3) d) { 653 fail Third element of $C list is not d: $L(3) 654 } 655 if (!~ $L(5) g) { 656 fail Fifth element of $C list is not g: $L(5) 657 } 658 C=() L=() 659 660 submatch continue 'rc: continue outside of loop' 'continue outside of loop' 661 662 ############################################################################# 663 ## check builtin continue in for loop (2) 664 ############################################################################# 665 L=() 666 for (x in a b c d e f g) { 667 if (~ $x b d) { 668 continue 669 } 670 L=($L $x) 671 if (~ $x f) { 672 break; 673 } 674 } 675 676 if (!~ $^L 'a c e f') { 677 fail List should be '(a c e f)', but is $L 678 } 679 680 # test support for unquoted = 681 submatch 'echo foo = bar' 'foo = bar' 'unquoted equals 1' 682 submatch 'echo foo=bar' 'foo=bar' 'unquoted equals 2' 683 submatch 'echo foo=' 'foo=' 'unquoted equals 3' 684 submatch 'echo =bar; whatis -v echo' 'echo=bar' 'unquoted equals 4' 685 686 # test for github issue #34 687 X=`{ $rc -ec 'b=true; while($b){b=false}; echo YYY' } 688 if (! ~ $X YYY) { 689 fail '"rc -e" exits when condition in the while statement fails in the second iteration' 690 } 691 692 # test for counter intuitive redirection parse 693 A=``($nl){ $rc -c 'mkdir / >[2=1] | tr a-z A-Z' } 694 B=``($nl){ $rc -c '>[2=1] mkdir / | tr a-z A-Z' } 695 ~ $A $B || fail counter intuitive redirection bug, $A '!=' $B 696 697 # test for github issue #40 698 $rc -ec 'false | false' 699 if (~ $status 0) { 700 fail '"rc -e" exits with zero status when command in pipeline returns non-zero' 701 } 702 $rc -ec 'X=`{false}' 703 if (~ $status 0) { 704 fail '"rc -e" exits with zero status when backquote command returns non-zero' 705 } 706 707 # exercise "if not" 708 submatch 'if (false) echo foo; if not echo bar' 'bar' 'if not 1' 709 submatch 'if (false) echo -n foo; if not echo -n bar; echo qux' 'barqux' 'if not 2' 710 submatch 'if (false) echo foo; echo qux; if not echo bar' 'rc: `if not'' must follow `if''' 'if not 3' 711 submatch 'if (false) { echo foo } else echo qux; if not echo bar' 'rc: `if not'' must follow `if''' 'if not 4' 712 713 # if-not stack if_state regression 714 s=' 715 L=() 716 if (true) { 717 if (false) { 718 L=($L a1) 719 } 720 if not L=($L a2) 721 } 722 if not L=($L a3) 723 echo $L 724 ' 725 726 m=`{$rc -c $s} 727 if (! ~ $^m a2) { 728 fail '"if not" not correct' 729 } 730 731 # exercise flag builtin 732 submatch 'flag' 'rc: not enough arguments to flag' 'flag no args' 733 submatch 'flag a b c' 'usage: flag f [ + | - ]' 'flag 3 args' 734 submatch 'flag xx' 'usage: flag f [ + | - ]' 'flag wrong first arg' 735 submatch 'flag x x' 'usage: flag f [ + | - ]' 'flag wrong second arg' 736 submatch 'flag c && echo yes' yes 'flag c' 737 submatch 'flag x +; flag x -' 'flag x -' 'setting x flag'