From 95b4d6a31f5255987db5f8005f557bb63aa3a2cb Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Sun, 18 Nov 2007 21:57:32 +0000 Subject: Merge of 23460/23461: fix longstanding problem with multios attached to a subshell process. --- Test/E01options.ztst | 1012 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1012 insertions(+) create mode 100644 Test/E01options.ztst (limited to 'Test') diff --git a/Test/E01options.ztst b/Test/E01options.ztst new file mode 100644 index 000000000..da75f98ee --- /dev/null +++ b/Test/E01options.ztst @@ -0,0 +1,1012 @@ +# Test various shell options. +# Interactive options not tested here: +# ALWAYS_LAST_PROMPT +# ALWAYS_TO_END +# APPEND_HISTORY (history not maintained) +# AUTO_LIST +# AUTO_MENU +# AUTO_NAME_DIRS (named directory table not maintained) +# AUTO_PARAM_KEYS +# AUTO_PARAM_SLASH +# AUTO_REMOVE_SLASH +# AUTO_RESUME +# BANG_HIST +# BASH_AUTO_LIST +# BEEP (!) +# BG_NICE +# CHECK_JOBS +# COMPLETE_ALIASES +# COMPLETE_IN_WORD +# CORRECT +# CORRECT_ALL +# CSH_JUNKIE_HISTORY +# DVORAK +# EXTENDED_HISTORY +# FLOW_CONTROL +# GLOB_COMPLETE +# HIST_ALLOW_CLOBBER +# HIST_BEEP +# HIST_EXPIRE_DUPS_FIRST +# HIST_FIND_NO_DUPS +# HIST_IGNORE_ALL_DUPS +# HIST_IGNORE_DUPS (-h) +# HIST_IGNORE_SPACE (-g) +# HIST_NO_FUNCTIONS +# HIST_NO_STORE +# HIST_REDUCE_BLANKS +# HIST_SAVE_NO_DUPS +# HIST_VERIFY +# HUP +# IGNORE_EOF +# INC_APPEND_HISTORY +# INTERACTIVE +# INTERACTIVE_COMMENTS +# LIST_AMBIGUOUS +# LIST_BEEP +# LIST_PACKED +# LIST_ROWS_FIRST +# LIST_TYPES +# LOGIN +# LONG_LIST_JOBS +# MAIL_WARNING +# MENU_COMPLETE +# MONITOR +# NOTIFY +# OVERSTRIKE +# PRINT_EIGHT_BIT +# PROMPT_CR +# PUSHD_SILENT +# REC_EXACT +# RM_STAR_SILENT +# RM_STAR_WAIT +# SHARE_HISTORY +# SINGLE_LINE_ZLE +# SUN_KEYBOARD_HACK +# ZLE +# The following require SHINSTDIN and are not (yet) tested: +# AUTO_CD +# SHINSTDIN +# +# Other difficult things I haven't done: +# GLOBAL_RCS (uses fixed files outside build area) +# HASH_CMDS ) +# HASH_DIRS ) fairly seriously internal, hard to test at all +# HASH_LIST_ALL ) +# PRINT_EXIT_STATUS haven't worked out what this does yet, although +# Bart suggested a fix. +# PRIVILEGED (similar to GLOBAL_RCS) +# RCS ( " " " " ) +# SH_OPTION_LETTERS even I found this too dull to set up a test for +# SINGLE_COMMAND kills shell +# VERBOSE hard because done on input (c.f. SHINSTDIN). + +%prep + mkdir options.tmp && cd options.tmp + + mkdir tmpcd + + touch tmpfile1 tmpfile2 + + mydir=$PWD + mydirt=`print -P %~` + catpath=$(which cat) + lspath==ls + +%test + + alias echo='print foo' + unsetopt aliases + # use eval else aliases are all parsed at start + eval echo bar + setopt aliases + eval echo bar + unalias echo +0:ALIASES option +>bar +>foo bar + + setopt allexport + testpm1=exported + unsetopt allexport + testpm2=unexported + print ${(t)testpm1} + print ${(t)testpm2} +0:ALL_EXPORT option +>scalar-export +>scalar + + # Count the number of directories on the stack. Don't care what they are. + dircount() { dirs -v | tail -1 | awk '{ print $1 + 1}'; } + unsetopt autopushd + cd tmpcd + dircount + cd .. + setopt autopushd + cd tmpcd + dircount + unsetopt autopushd + popd >/dev/null +0:AUTO_PUSHD option +>1 +>2 + + unsetopt badpattern + print [a + setopt badpattern + print [b +1:BAD_PATTERN option +>[a +?(eval):4: bad pattern: [b + + unsetopt bareglobqual nomatch + print *(.) + setopt bareglobqual nomatch + print *(.) +0:BARE_GLOB_QUAL option +>*(.) +>tmpfile1 tmpfile2 + + setopt braceccl + print {abcd} + unsetopt braceccl + print {abcd} +0:BRACE_CCL option +>a b c d +>{abcd} + +# Don't use NUL as a field separator in the following. + setopt braceccl + print {$'\0'-$'\5'} | IFS=' ' read -A chars + for c in $chars; do print $(( #c )); done + unsetopt braceccl +0:BRACE_CCL option starting from NUL +>0 +>1 +>2 +>3 +>4 +>5 + + setopt bsdecho + echo "histon\nimpington" + echo -e "girton\ncottenham" + unsetopt bsdecho + echo "newnham\ncomberton" +0:BSD_ECHO option +>histon\nimpington +>girton +>cottenham +>newnham +>comberton + + unsetopt c_bases + print $(( [#16]15 )) + print $(( [#8]9 )) + setopt c_bases + print $(( [#16]31 )) + print $(( [#8]17 )) + setopt octal_zeroes + print $(( [#8]19 )) + unsetopt c_bases octal_zeroes +0:C_BASES option +>16#F +>8#11 +>0x1F +>8#21 +>023 + + setopt cdablevars + # only absolute paths are eligible for ~-expansion + cdablevar1=tmpcd + (cd cdablevar1) + cdablevar2=$PWD/tmpcd + cd cdablevar2 + cd .. + print back in ${PWD:t} + unsetopt cdablevars + cd cdablevar2 +1q:CDABLE_VARS option +>back in options.tmp +?(eval):cd:4: no such file or directory: cdablevar1 +?(eval):cd:10: no such file or directory: cdablevar2 + +# CHASE_DOTS should go with CHASE_LINKS in B01cd.ztst +# which saves me having to write it here. + + setopt noclobber + rm -f foo1 bar1 rod1 + echo waterbeach >foo1 + (echo landbeach >foo1) + cat foo1 + (echo lode >>bar1) + [[ -f bar1 ]] && print That shouldn\'t be there. + echo denny >rod1 + echo wicken >>rod1 + cat rod1 + unsetopt noclobber + rm -f foo2 bar2 rod2 + echo ely >foo2 + echo march >foo2 + cat foo2 + echo wimpole >>bar2 + cat bar2 + echo royston >rod2 + echo foxton >>rod2 + cat rod2 + rm -f foo* bar* rod* +0:CLOBBER option +>waterbeach +>denny +>wicken +>march +>wimpole +>royston +>foxton +?(eval):4: file exists: foo1 +?(eval):6: no such file or directory: bar1 + + setopt cshjunkieloops + eval 'for f in swaffham bulbeck; print $f; end' + print next one should fail >&2 + unsetopt cshjunkieloops + eval 'for f in chesterton arbury; print $f; end' +1:CSH_JUNKIE_LOOPS option (for loop) +>swaffham +>bulbeck +?next one should fail +?(eval):1: parse error near `end' + + setopt cshjunkiequotes + print this should cause an error >&2 + eval "print 'line one + line two'" + print this should not >&2 + eval "print 'line three\\ + line four'" + unsetopt cshjunkiequotes +0:CSH_JUNKIE_QUOTES option +>line three +> line four +?this should cause an error +?(eval):1: unmatched ' +?this should not + + nullcmd() { print '$NULLCMD run'; } + readnullcmd() { print 'Running $READNULLCMD'; cat; } + NULLCMD=nullcmd + READNULLCMD=readnullcmd + setopt cshnullcmd + rm -f foo + print "This should fail" >&2 + (>foo) + print "This should succeed" >&2 + print "These are the contents of foo" >foo + cat foo + print "This should also fail" >&2 + (foo + These are the contents of foo +>Running $READNULLCMD +>$NULLCMD run +?This should fail +?(eval):8: redirection with no command +?This should succeed +?This should also fail +?(eval):13: redirection with no command + +# nomatch should be overridden by cshnullglob + setopt nomatch cshnullglob + print tmp* nothing* blah + print -n 'hoping for no match: ' >&2 + (print nothing* blah) + print >&2 + unsetopt cshnullglob nomatch + print tmp* nothing* blah + print nothing* blah +0:CSH_NULL_GLOB option +>tmpcd tmpfile1 tmpfile2 blah +>tmpcd tmpfile1 tmpfile2 nothing* blah +>nothing* blah +?hoping for no match: (eval):4: no match +? + +# The trick is to avoid =cat being expanded in the output while $catpath is. + setopt NO_equals + print -n trick; print =cat + setopt equals + print -n trick; print =cat +0q:EQUALS option +>trick=cat +>trick$catpath + +# explanation of expected TRAPZERR output: from false and from +# testfn() with ERR_EXIT on (hmm, should we really get a second one from +# the function exiting?), then from the false only with ERR_EXIT off. + TRAPZERR() { print ZERR trapped; } + testfn() { setopt localoptions $2; print $1 before; false; print $1 after; } + (testfn on errexit) + testfn off + unfunction TRAPZERR testfn +0:ERR_EXIT option +>on before +>ZERR trapped +>ZERR trapped +>off before +>ZERR trapped +>off after + + (print before; setopt noexec; print after) +0:NO_EXEC option +>before + + setopt NO_eval_lineno + eval 'print $LINENO' + setopt eval_lineno + eval 'print $LINENO' +0:EVAL_LINENO option +>2 +>1 + + # The EXTENDED_GLOB test doesn't test globbing fully --- it just tests + # that certain patterns are treated literally with the option off + # and as patterns with the option on. + testfn() { print -n "$1 $2 $3 "; if [[ $1 = ${~2} ]]; + then print yes; else print no; fi; } + tests=('a#' '?~b' '^aa') + strings=('a' 'aa' 'b' 'a#' '?~b' '^aa') + for opt in noextendedglob extendedglob; do + setopt $opt + for test in $tests; do + for string in $strings; do + testfn $string $test $opt + done + done + done +0:EXTENDED_GLOB option +>a a# noextendedglob no +>aa a# noextendedglob no +>b a# noextendedglob no +>a# a# noextendedglob yes +>?~b a# noextendedglob no +>^aa a# noextendedglob no +>a ?~b noextendedglob no +>aa ?~b noextendedglob no +>b ?~b noextendedglob no +>a# ?~b noextendedglob no +>?~b ?~b noextendedglob yes +>^aa ?~b noextendedglob no +>a ^aa noextendedglob no +>aa ^aa noextendedglob no +>b ^aa noextendedglob no +>a# ^aa noextendedglob no +>?~b ^aa noextendedglob no +>^aa ^aa noextendedglob yes +>a a# extendedglob yes +>aa a# extendedglob yes +>b a# extendedglob no +>a# a# extendedglob no +>?~b a# extendedglob no +>^aa a# extendedglob no +>a ?~b extendedglob yes +>aa ?~b extendedglob no +>b ?~b extendedglob no +>a# ?~b extendedglob no +>?~b ?~b extendedglob no +>^aa ?~b extendedglob no +>a ^aa extendedglob yes +>aa ^aa extendedglob no +>b ^aa extendedglob yes +>a# ^aa extendedglob yes +>?~b ^aa extendedglob yes +>^aa ^aa extendedglob yes + + foo() { print My name is $0; } + unsetopt functionargzero + foo + setopt functionargzero + foo + unfunction foo +0:FUNCTION_ARGZERO option +>My name is ZTST_execchunk +>My name is foo + + setopt _NO_glob_ + print tmp* + set -o glob + print tmp* +0:GLOB option +>tmp* +>tmpcd tmpfile1 tmpfile2 + + showit() { local v; + for v in first second third; do + eval print \$$v \$\{\(t\)$v\} + done; + } + setit() { typeset -x first=inside1; + typeset +g -x second=inside2; + typeset -g -x third=inside3; + showit; + } + first=outside1 second=outside2 third=outside3 + unsetopt globalexport + setit + showit + setopt globalexport + setit + showit + unfunction setit showit +0:GLOBAL_EXPORT option +>inside1 scalar-local-export +>inside2 scalar-local-export +>inside3 scalar-export +>outside1 scalar +>outside2 scalar +>inside3 scalar-export +>inside1 scalar-export +>inside2 scalar-local-export +>inside3 scalar-export +>inside1 scalar-export +>outside2 scalar +>inside3 scalar-export + + setopt globassign + foo=tmp* + print $foo + unsetopt globassign + foo=tmp* + print $foo +0:GLOB_ASSIGN option +>tmpcd tmpfile1 tmpfile2 +>tmp* + + mkdir onlysomefiles + touch onlysomefiles/.thisfile onlysomefiles/thatfile + setopt globdots + print onlysomefiles/* + unsetopt globdots + print onlysomefiles/* + rm -rf onlysomefiles +0:GLOB_DOTS option +>onlysomefiles/.thisfile onlysomefiles/thatfile +>onlysomefiles/thatfile + + # we've tested this enough times already... + # could add some stuff for other sorts of expansion + foo='tmp*' + setopt globsubst + print ${foo} + unsetopt globsubst + print ${foo} +0:GLOB_SUBST option +>tmpcd tmpfile1 tmpfile2 +>tmp* + + setopt ignorebraces + echo X{a,b}Y + unsetopt ignorebraces + echo X{a,b}Y +0:IGNORE_BRACES option +>X{a,b}Y +>XaY XbY + + setopt ksh_arrays + array=(one two three) + print $array $array[2] + print ${array[0]} ${array[1]} ${array[2]} ${array[3]} + unsetopt ksh_arrays + print $array $array[2] + print ${array[0]} ${array[1]} ${array[2]} ${array[3]} + unset array +0:KSH_ARRAYS option +>one one[2] +>one two three +>one two three two +>one one two three + + fpath=(.) + echo >foo 'echo foo loaded; foo() { echo foo run; }' + echo >bar 'bar() { echo bar run; }' + setopt kshautoload + autoload foo bar + foo + bar + unfunction foo bar + unsetopt kshautoload + autoload foo bar + foo + bar +0:KSH_AUTOLOAD option +>foo loaded +>foo run +>bar run +>foo loaded +>bar run + +# ksh_glob is tested by the glob tests. + + setopt kshoptionprint globassign + print set + setopt | grep kshoptionprint + setopt | grep globassign + unsetopt kshoptionprint + print unset + setopt | grep kshoptionprint + setopt | grep globassign + unsetopt globassign +0:KSH_OPTION_PRINT option +>set +>kshoptionprint on +>globassign on +>unset +>globassign + + setopt kshtypeset + ktvars=(ktv1 ktv2) + typeset ktfoo=`echo arg1 arg2` $ktvars + print $+ktv1 $+ktv2 $+ktv3 + print $ktfoo + unsetopt kshtypeset + typeset noktfoo=`echo noktarg1 noktarg2` + print $noktfoo + print $+noktarg1 $+noktarg2 + unset ktfoo ktv1 ktv2 noktfoo noktarg2 +0:KSH_TYPESET option +>1 1 0 +>arg1 arg2 +>noktarg1 +>0 1 + + showopt() { setopt | egrep 'localoptions|ksharrays'; } + f1() { setopt localoptions ksharrays; showopt } + f2() { setopt ksharrays; showopt } + setopt kshoptionprint + showopt + f1 + showopt + f2 + showopt + unsetopt ksh_arrays +0:LOCAL_OPTIONS option +>ksharrays off +>localoptions off +>ksharrays on +>localoptions on +>ksharrays off +>localoptions off +>ksharrays on +>localoptions off +>ksharrays on +>localoptions off + +# LOCAL_TRAPS was tested in C03traps (phew). + + fn() { + local HOME=/any/old/name + print -l var=~ 'anything goes/here'=~ split=`echo maybe not`; + } + setopt magicequalsubst + fn + setopt kshtypeset + fn + unsetopt magicequalsubst kshtypeset + fn +0:MAGIC_EQUAL_SUBST option +>var=/any/old/name +>anything goes/here=/any/old/name +>split=maybe +>not +>var=/any/old/name +>anything goes/here=/any/old/name +>split=maybe not +>var=~ +>anything goes/here=~ +>split=maybe +>not + + setopt MARK_DIRS + print tmp* + unsetopt MARK_DIRS + print tmp* +0:MARK_DIRS option +>tmpcd/ tmpfile1 tmpfile2 +>tmpcd tmpfile1 tmpfile2 + +# maybe should be in A04redirect + print "This is in1" >in1 + print "This is in2" >in2 + unsetopt multios + print Test message >foo1 >foo2 + print foo1: $(foo1 >foo2 + sleep 1 # damn, race in multios + print foo1: $(foo1: +>foo2: Test message +>This is in2 +>foo1: Test message +>foo2: Test message +>This is in1 +>This is in2 + +# This is trickier than it looks. There's a hack at the end of +# execcmd() to catch the multio processes attached to the +# subshell, which otherwise sort of get lost in the general turmoil. +# Without that, the multios aren't synchronous with the subshell +# or the main shell starting the "cat", so the output files appear +# empty. + setopt multios + ( echo hello ) >multio_out1 >multio_out2 && cat multio_out* +0:Multios attached to a subshell +>hello +>hello + +# This tests for another race in multios. + print 'This test hangs the shell when it fails...' >&8 + setopt multios + echo These are the contents of the file >multio_race.out + multio_race_fn() { cat; } + multio_race_fn <$(echo multio_race.out multio_race.out) +0:Fix for race with input multios +>These are the contents of the file +>These are the contents of the file + +# tried this with other things, but not on its own, so much. + unsetopt nomatch + print with nonomatch: flooble* + setopt nomatch + print with nomatch flooble* +1:NOMATCH option +>with nonomatch: flooble* +?(eval):4: no matches found: flooble* + +# NULL_GLOB should override NONOMATCH... + setopt nullglob nomatch + print frooble* tmp* + unsetopt nullglob nomatch + print frooble* tmp* +0:NULL_GLOB option +>tmpcd tmpfile1 tmpfile2 +>frooble* tmpcd tmpfile1 tmpfile2 + + touch ngs1.txt ngs2.txt ngs10.txt ngs20.txt ngs100.txt ngs200.txt + setopt numericglobsort + print -l ngs* + unsetopt numericglobsort + print -l ngs* +0:NUMERIC_GLOB_SORT option +>ngs1.txt +>ngs2.txt +>ngs10.txt +>ngs20.txt +>ngs100.txt +>ngs200.txt +>ngs1.txt +>ngs10.txt +>ngs100.txt +>ngs2.txt +>ngs20.txt +>ngs200.txt + + typeset -i 10 oznum + setopt octalzeroes + (( oznum = 012 + 013 )) + print $oznum + unsetopt octalzeroes + (( oznum = 012 + 013 )) + print $oznum + unset oznum +0:OCTAL_ZEROES options +>21 +>25 + + typeset -a oldpath + oldpath=($path) + mkdir pdt_topdir pathtestdir pdt_topdir/pathtestdir + print "#!/bin/sh\necho File in upper dir" >pathtestdir/findme + print "#!/bin/sh\necho File in lower dir" >pdt_topdir/pathtestdir/findme + chmod u+x pathtestdir/findme pdt_topdir/pathtestdir/findme + pathtestdir/findme + rm -f pathtestdir/findme + setopt pathdirs + path=($PWD $PWD/pdt_topdir) + pathtestdir/findme + print unsetting option... + unsetopt pathdirs + pathtestdir/findme + path=($oldpath) + unset $oldpath + rm -rf pdt_topdir pathtestdir +0:PATH_DIRS option +>File in upper dir +>File in lower dir +>unsetting option... +?(eval):14: no such file or directory: pathtestdir/findme + + setopt posixbuiltins + PATH= command -v print + PATH= command -V print + PATH= command print foo + unsetopt posixbuiltins + print unsetting... + PATH= command -V print + PATH= command print foo +127:POSIX_BUILTINS option +>print +>print is a shell builtin +>foo +>unsetting... +>print is a shell builtin +?(eval):8: command not found: print + +# This option seems to be problematic. I don't quite know how it works. +## func() { +## setopt localoptions printexitvalue +## false +## } +## func +## 1:PRINT_EXIT_VALUE option +## ?(eval):2: exit 1 + + setopt promptbang + print -P ! + setopt nopromptbang + print -P ! +0:PROMPT_BANG option +>0 +>! + + unsetopt promptpercent + print -P '%/' + setopt promptpercent + print -P '%/' +0q:PROMPT_PERCENT option +>%/ +>$mydir + + setopt promptsubst + print -P '`echo waaah`' + unsetopt promptsubst + print -P '`echo waaah`' +0:PROMPT_SUBST option +>waaah +>`echo waaah` + + dirs + pushd $mydir/tmpcd + dirs + pushd $mydir/tmpcd + dirs + setopt pushdignoredups + pushd $mydir/tmpcd + dirs + unsetopt pushdignoredups + popd >/dev/null + popd >/dev/null +0q:PUSHD_IGNOREDUPS option +>$mydirt +>$mydirt/tmpcd $mydirt +>$mydirt/tmpcd $mydirt/tmpcd $mydirt +>$mydirt/tmpcd $mydirt/tmpcd $mydirt + + mkdir newcd + cd $mydir + pushd $mydir/tmpcd + pushd $mydir/newcd + dirs + pushd -0 + dirs + setopt pushdminus pushdsilent + pushd -0 + dirs + unsetopt pushdminus + popd >/dev/null + popd >/dev/null + cd $mydir +0q:PUSHD_MINUS option +>$mydirt/newcd $mydirt/tmpcd $mydirt +>$mydirt $mydirt/newcd $mydirt/tmpcd +>$mydirt $mydirt/newcd $mydirt/tmpcd + +# Do you have any idea how dull this is? + + pushd $mydir/tmpcd + pushd + dirs + setopt pushdtohome + pushd + dirs + unsetopt pushdtohome + popd + pushd + popd + dirs +0q:PUSHD_TO_HOME option +>$mydirt $mydirt/tmpcd +>~ $mydirt $mydirt/tmpcd +>$mydirt + + array=(one two three four) + setopt rcexpandparam + print aa${array}bb + unsetopt rcexpandparam + print aa${array}bb +0:RC_EXPAND_PARAM option +>aaonebb aatwobb aathreebb aafourbb +>aaone two three fourbb + + setopt rcquotes + # careful, this is done when parsing a complete block + eval "print 'one''quoted''expression'" + unsetopt rcquotes + eval "print 'another''quoted''expression'" +0:RC_QUOTES option +>one'quoted'expression +>anotherquotedexpression + +# too lazy to test jobs -Z and ARGV0. + (setopt restricted; cd /) + (setopt restricted; PATH=/bin:/usr/bin) + (setopt restricted; /bin/ls) + (setopt restricted; hash ls=/bin/ls) + (setopt restricted; print ha >outputfile) + (setopt restricted; exec ls) + (setopt restricted; unsetopt restricted) + : +0:RESTRICTED option +?(eval):cd:1: restricted +?(eval):2: PATH: restricted +?(eval):3: /bin/ls: restricted +?(eval):hash:4: restricted: /bin/ls +?(eval):5: writing redirection not allowed in restricted mode +?(eval):exec:6: ls: restricted +?(eval):unsetopt:7: can't change option: restricted + + fn() { + print =ls ={ls,} + local foo='=ls' + print ${~foo} + } + setopt shfileexpansion + fn + unsetopt shfileexpansion + fn +0q:SH_FILE_EXPANSION option +>$lspath =ls = +>=ls +>$lspath $lspath = +>$lspath + + testpat() { + if [[ $1 = ${~2} ]]; then print $1 $2 yes; else print $1 $2 no; fi + } + print option on + setopt shglob + repeat 2; do + for str in 'a(b|c)' ab; do + testpat $str 'a(b|c)' + done + for str in 'a<1-10>' a9; do + testpat $str 'a<1-10>' + done + [[ ! -o shglob ]] && break + print option off + unsetopt shglob + done +0:SH_GLOB option +>option on +>a(b|c) a(b|c) yes +>ab a(b|c) no +>a<1-10> a<1-10> yes +>a9 a<1-10> no +>option off +>a(b|c) a(b|c) no +>ab a(b|c) yes +>a<1-10> a<1-10> no +>a9 a<1-10> yes + + print this is bar >bar + fn() { + local NULLCMD=cat READNULLCMD=cat + echo hello | >foo + cat foo + option set +>option unset +>hello +>this is bar + + fn() { + eval 'for f in foo bar; print $f' + eval 'for f (word1 word2) print $f' + eval 'repeat 3 print nonsense' + } + unsetopt shortloops + print option unset + fn + setopt shortloops + print option set + fn +0:SHORT_LOOPS option +>option unset +>option set +>foo +>bar +>word1 +>word2 +>nonsense +>nonsense +>nonsense +?(eval):1: parse error near `print' +?(eval):1: parse error near `print' +?(eval):1: parse error near `print' + + fn() { print -l $*; } + setopt shwordsplit + print option set + repeat 2; do + foo='two words' + fn $foo + fn "${=foo}" + [[ ! -o shwordsplit ]] && break + unsetopt shwordsplit + print option unset + done +0:SH_WORD_SPLIT option +>option set +>two +>words +>two +>words +>option unset +>two words +>two +>words + + fn() { unset foo; print $foo; } + setopt nounset + print option unset unset by setting nounset + eval fn + print option unset reset + setopt unset + fn +0:UNSET option +>option unset unset by setting nounset +>option unset reset +> +?fn: foo: parameter not set + +# This really just tests if XTRACE is egregiously broken. +# To test it properly would need a full set of its own. + fn() { print message; } + setopt xtrace + fn + unsetopt xtrace + fn +0:XTRACE option +>message +>message +?+(eval):3> fn +?+fn:0> print message +?+(eval):4> unsetopt xtrace -- cgit 1.4.1