1 # trip.rc -- take a tour of rc
2 # Invoke as "path-to-new-rc < trip.rc"
8 echo >[1=2] trip took a wrong turn: $*
13 echo >[1=2] -n expect $^*^': '
17 fail incorrect invocation of submatch
18 prompt=$nl if (!~ `` $nl {$rc -ic $1>[2=1]} $2)
21 fn sigexit sigint sigquit sigsegv
34 if ($rc -c >[2]/dev/null) fail 'rc -c didn''t report a bad exit status'
35 x=`{$rc -c 'echo $0 $2 $#*' a b c d e f}
36 if (false) { # WARNING: this differs from sh
37 if (!~ $x(1) a) fail rc -c reports '$0' incorrectly as $x(1)
38 if (!~ $x(2) c) fail rc -c reports '$2' incorrectly as $x(2)
39 if (!~ $x(3) 5) fail rc -c reports '$#' incorrectly as $x(3)
41 if (!~ $x(1) $rc) fail rc -c reports '$0' incorrectly as $x(1)
42 if (!~ $x(2) b) fail rc -c reports '$2' incorrectly as $x(2)
43 if (!~ $x(3) 6) fail rc -c reports '$#' incorrectly as $x(3)
53 if (!~ $x(1) '-rw-rw-rw-') fail umask 0 produced incorrect result: $x(1)
58 if (!~ $y(1) '-rw-r-----') fail umask 027 produced incorrect file: $y(1)
60 if (!~ `umask 027) fail umask reported bad value: `umask
62 submatch 'umask bad' 'bad umask' 'bad umask'
63 submatch 'umask -027' 'bad umask' 'bad umask'
64 submatch 'umask 999999' 'bad umask' 'bad umask'
65 submatch 'umask hi there' 'too many arguments to umask' 'umask arg count'
67 if (!~ `umask 027) fail bad umask changed umask value to `umask
73 fn bytes { for (i) x=`{wc -c $i} echo $x(1) }
75 if (!~ `{bytes foo} 0) fail double redirection created non-empty empty file
76 if (!~ `{bytes bar} 4) fail double redirection created wrong sized file: `{bytes bar}
78 echo -n >1 >[2]2 >[1=2] foo
80 if (!~ $#x 0) fail dup created non-empty empty file: `` '' {cat 1}
81 if (!~ `` '' {cat 2} foo) fail dup put wrong contents in file : `` '' {cat 2}
84 expect error from cat, closing stdin
87 submatch 'cat>(1 2 3)' 'multi-word filename in redirection' 'redirection error'
88 submatch 'cat>()' 'null filename in redirection' 'redirection error'
91 # blow the input stack
95 eval eval eval eval eval eval eval eval eval eval eval eval eval \
96 eval eval eval eval eval eval eval eval eval eval eval eval eval \
97 eval eval eval eval eval eval eval eval eval eval eval eval eval \
98 eval eval eval eval eval eval eval eval eval eval eval eval eval \
99 eval eval eval eval eval eval eval eval eval eval eval eval eval \
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 echo hi
110 # heredocs and herestrings
113 bigfile=/tmp/big.$pid
114 od $rc | sed 5000q > $bigfile
117 result='this is a heredoc
120 if (!~ `` '' {<<[5] EOF cat <[0=5]} $result) fail unquoted heredoc
124 {if (!~ `` $nl cat ' ') fail quoted heredoc} << ' '
128 <<<[9] ``''{cat $bigfile} \
130 if(!~ ``''{cat <[0=9]}``'' cat)fail large herestrings
140 fail quoting '$' in heredoc
142 submatch 'cat<<eof' 'heredoc incomplete' 'incomplete heredoc'
144 ' 'heredoc incomplete' 'incomplete heredoc'
146 submatch 'cat<<(eof eof)' 'eof-marker not a single literal word' 'bad heredoc marker'
155 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. > /tmp/$pid.lw
157 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.' > /tmp/$pid.lq
159 if (!~ ``(){cat /tmp/$pid.lw} ``(){cat /tmp/$pid.lq})
160 fail expected long string and long word to be identical
161 if (! x=`{wc -c /tmp/$pid.lw} ~ $x(1) 1088)
162 fail expected long word to be 1088 bytes
163 if (! x=`{wc -c /tmp/$pid.lq} ~ $x(1) 1088)
164 fail expected long quote to be 1088 bytes
169 submatch 'echo hi |[2' 'expected ''='' or '']'' after digit' 'scan error'
170 submatch 'echo hi |[92=]' 'expected digit after ''=''' 'scan error'
171 submatch 'echo hi |[a]' 'expected digit after ''[''' 'scan error'
172 submatch 'echo hi |[2-' 'expected ''='' or '']'' after digit' 'scan error'
173 submatch 'echo hi |[2=99a]' 'expected '']'' after digit' 'scan error'
174 submatch 'echo hi |[2=a99]' 'expected digit or '']'' after ''=''' 'scan error'
175 submatch 'echo ''hi' 'eof in quoted string' 'scan error'
178 if (!~ 'h i' `{echo -n h\
180 fail backslash-newline to space conversion
181 if (!~ $rc^\rc `{echo -n $rc\rc})
182 fail backslash after variable name did not terminate variable name scan
183 if (!~ $rc^' rc' `{echo -n $rc\
185 fail backslash-newline after variable name space conversion
186 if (!~ 'h\i' `{echo -n h\i})
187 fail backslash in the middle of word
188 if (!~ 'h \ i' `{echo -n h \ i})
189 fail free-standing backslash
192 if (! $rc -c '# eof in comment')
193 fail eof in comment exited with nonzero status
195 # test the syntax error printer
197 prompt='' if (!~ `` $nl {$rc -cif>[2=1]} 'line 1: '*' error near if')
198 fail print syntax error
200 prompt='' if (!~ `` $nl {$rc -icif>[2=1]} *' error')
201 fail print syntax error
212 if (!~ $status sigfpe)
213 fail return builtin did not return sigfpe
215 fn foo # test deleting of function
224 fail return inside loop inside function failed
226 submatch return 'return outside of function' 'return outside of function'
227 submatch 'break 1' 'too many arguments to break' 'break arg count'
228 submatch break 'break outside of loop' 'break outside of loop'
234 fail break out of loop
236 submatch 'wait foo' 'foo is a bad number' 'bogus argument to wait'
240 if (!~ `` '' {echo --} $nl)
243 pwd=`/bin/pwd cdpath=/ { # some local assignments
245 if (!~ `/bin/pwd `{sh -c 'cd /tmp; /bin/pwd'})
246 fail could not cd to '$home'
249 if (!~ `/bin/pwd `{sh -c 'cd /tmp; /bin/pwd'})
250 fail could not cd to /tmp
253 if (!~ `/bin/pwd `{sh -c 'cd $pwd; /bin/pwd'})
254 fail could not cd to current directory!
262 expect shift overflow
266 fail shift 3 of '(1 2 3 4 5)' failed
269 fail shift failed to shift left-to-right
273 eval && fail null eval reset '$status'
275 if (!~ `{rm=(); fn rm; path=(. /bin); whatis rm} /bin/rm)
276 fail rm isn''''t in bin!?
278 expect list of signal handlers
281 expect list of variables and functions
284 submatch 'whatis -x' 'whatis: bad option: -x' 'bad option to whatis'
286 submatch 'whatis /frobnatz' '/frobnatz not found' 'search for /frobnatz'
288 if (~ `{whatis limit >[2]/dev/null} builtin) {
290 if (!~ `{limit coredumpsize} 0*)
291 fail failed to set coredumpsize to zero
292 if (!~ `` () {limit coredumpsize} `` () {limit|grep coredumpsize})
294 submatch 'limit foo' 'no such limit' 'bad limit'
299 submatch 'cd a b c' 'too many arguments to cd' 'cd arg count'
300 $rc -c 'cdpath=() cd /frobnatz' >[2]/dev/null && fail 'cd to /frobnatz succeeded!?'
301 submatch 'cdpath='''' cd frobnatz' 'couldn''t cd to frobnatz' 'cd to frobnatz succeeded!?'
304 {whatis if | fgrep '''if''=keyword' >/dev/null} || fail whatis of keyword is not quoted
311 submatch 'wait 1 2 3' 'too many arguments to wait' 'arg count'
312 $rc -c 'wait 1' >[2]/dev/null && fail wait 1
319 if (~ `` '' {wait} ?)
320 fail waiting for nothing
326 touch /tmp/abc.$pid /tmp/bbc.$pid
327 mkdir /tmp/dir.$pid /tmp/dip.$pid
328 touch /tmp/dir.$pid/^(a b c) /tmp/dip.$pid/^(a b c)
330 if (!~ 123 [~x]?[0-9])
333 fail match of null list with '*'
335 fail match of null list with '*v*' succeeded
336 if (!~ (foo bar zar) *****z*****)
337 fail match of list by one pattern failed
338 if (~ (foo bar zar) *c*)
343 fail match right bracket
345 fail rangematch out of range
347 fail too many characters in pattern
349 test -f /////tmp//////a?c.$pid || fail glob with many slashes
350 if (!~ /////tmp//////a*.$pid /////tmp//////a?c.$pid)
351 fail glob with many slashes
352 if (!~ ////tmp////di?.$pid////* ////tmp////dir.$pid////*b*)
353 fail glob with more slashes
354 if (! @{cd /; ~ */a*.$pid tmp/a*})
355 fail glob in current directory
356 if (!~ /tmp/?bc.$pid /tmp/bbc.$pid)
357 fail match of bbc.$pid against '('abc.$pid bbc.$pid')'
359 rm /tmp/abc.$pid /tmp/bbc.$pid
360 rm -rf /tmp/dir.$pid /tmp/dip.$pid
374 $rc -c /frobnatz >[2]/dev/null && fail 'search error'
376 touch /tmp/noexec.$pid
377 chmod a-x /tmp/noexec.$pid
378 $rc -c /tmp/noexec.$pid >[2]/dev/null && fail /tmp/noexec.$pid is found!?
381 submatch 'path='''' frobnatz' 'frobnatz not found' 'search error'
383 {path=() /bin/sh -c 'exit 0'} || fail abs pathname with path set to null
389 # this test is meaningless; not really a trip
390 expect prompt, echo hi
391 home=/frobnatz $rc -nolpeivdxc 'echo hi'
392 if (!~ `` $nl {$rc -c>[2=1]} *': option requires an argument -- c')
394 if (!~ `` $nl {$rc -q>[2=1]} *': bad option: -q')
395 fail getopt on -q (bogus option)
396 if (!~ `{echo '#echo' | $rc -v |[2] sed 's/#//'} echo)
405 if (~ `` '' {. -i} ?*)
408 cat > /tmp/dot.$pid << eof
412 prompt=';' if (!~ `` '' {. -i /tmp/dot.$pid>[2=1]} ';hi'^$nl';')
414 submatch .' '/tmp/dot.$pid hi dot
418 $rc -c '. /frobnatz' >[2]/dev/null && fail 'dot of a nonexistent file'
424 if (!~ `{echo echo hi | $rc} hi)
425 fail piping stdin to rc
428 # functions, variables & environment
431 fn --- {for(i)a|[2=3]b>>c<<<'e'&f>[2=1]}
433 if (whatis printenv >/dev/null>[2=1]) {
435 } else if (whatis env >/dev/null>[2=1]) {
440 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]}')
444 ~ `{whatis -- ---} *replace* || fail replace a function definition
446 whatis -- --- >[2]/dev/null && fail function deletion
449 ~ $foo nest || fail local assignment
450 ~ $* nest || fail local assignment to '$*'
453 ~ $foo () || fail local deletion
454 ~ $* () || fail local deletion to '$*'
456 ~ $foo bar || fail restore of global after local group
457 ~ $* bar || fail restore of '$*' after local group
458 ~ `{exec>[2=1];$rc -xc 'foo=()'} 'foo=()' || fail -x echo of variable deletion
460 fn_ff='{' prompt='' if (!~ `` $nl {$rc -cff>[2=1]} 'line 1: '*' error near eof')
461 fail 'bogus function in environment'
467 ~ `{$rc -ec 'sleep 10&kill -9 $apid;wait'>[2=1]} killed ||
468 fail status diagnostic
470 $rc -c 'exit 0 sigfpe' && fail exit of bad pipeline is true
472 submatch 'exit foo' 'bad status' 'exit diagnostic'
478 if (!~ `{false || echo hi} hi)
480 if (!~ `{true && echo hi} hi)
482 if (~ `{true || echo hi} hi)
484 if (~ `{false && echo hi} hi)
496 fail matched bar in switch
500 fail match foo in switch
505 fail matched bar in switch
510 ~ $i frobnatz || fail match '*' in switch
512 submatch '()=()' 'null variable name' 'assignment diagnostic'
513 submatch 'fn () {eval}' 'null function name' 'assigning null function name'
520 prompt=() if (!~ `{$rc -i /dev/null>[2]/dev/null} hi) fail fn prompt
527 history=/tmp/hist.$pid prompt='' echo 'history=()' | $rc -i
529 if (!~ `{cat /tmp/hist.$pid} 'history=()')
530 fail output to history file
532 history=/tmp/hist.$pid prompt='' echo 'history=()' | $rc -i
534 if (!~ `` () {cat /tmp/hist.$pid} 'history=()
537 fail append to history file
541 if (!~ `{history=/frobnatz/foo prompt='' echo eval | $rc -i >[2=1]} ?*)
542 fail accessing bad history file