diff options
Diffstat (limited to 'bin/ksh/tests')
-rw-r--r-- | bin/ksh/tests/brkcont.t | 195 | ||||
-rw-r--r-- | bin/ksh/tests/cdhist.t | 160 | ||||
-rw-r--r-- | bin/ksh/tests/eglob.t | 138 | ||||
-rw-r--r-- | bin/ksh/tests/glob.t | 96 | ||||
-rw-r--r-- | bin/ksh/tests/heredoc.t | 72 | ||||
-rw-r--r-- | bin/ksh/tests/history.t | 529 | ||||
-rw-r--r-- | bin/ksh/tests/ifs.t | 162 | ||||
-rw-r--r-- | bin/ksh/tests/integer.t | 218 | ||||
-rw-r--r-- | bin/ksh/tests/read.t | 56 | ||||
-rw-r--r-- | bin/ksh/tests/regress.t | 641 | ||||
-rw-r--r-- | bin/ksh/tests/th | 813 | ||||
-rw-r--r-- | bin/ksh/tests/th.sh | 21 | ||||
-rw-r--r-- | bin/ksh/tests/unclass1.t | 97 | ||||
-rw-r--r-- | bin/ksh/tests/unclass2.t | 166 | ||||
-rw-r--r-- | bin/ksh/tests/version.t | 8 |
15 files changed, 3372 insertions, 0 deletions
diff --git a/bin/ksh/tests/brkcont.t b/bin/ksh/tests/brkcont.t new file mode 100644 index 00000000000..1eb9c2581c9 --- /dev/null +++ b/bin/ksh/tests/brkcont.t @@ -0,0 +1,195 @@ +name: break-1 +description: + See if break breaks out of loops +stdin: + for i in a b c; do echo $i; break; echo bad-$i; done + echo end-1 + for i in a b c; do echo $i; break 1; echo bad-$i; done + echo end-2 + for i in a b c; do + for j in x y z; do + echo $i:$j + break + echo bad-$i + done + echo end-$i + done + echo end-3 +expected-stdout: + a + end-1 + a + end-2 + a:x + end-a + b:x + end-b + c:x + end-c + end-3 +--- + +name: break-2 +description: + See if break breaks out of nested loops +stdin: + for i in a b c; do + for j in x y z; do + echo $i:$j + break 2 + echo bad-$i + done + echo end-$i + done + echo end +expected-stdout: + a:x + end +--- + + +name: break-3 +description: + What if break used outside of any loops + (ksh88,ksh93 don't print error messages here) +stdin: + break +expected-stderr-pattern: + /.*break.*/ +--- + + +name: break-4 +description: + What if break N used when only N-1 loops + (ksh88,ksh93 don't print error messages here) +stdin: + for i in a b c; do echo $i; break 2; echo bad-$i; done + echo end +expected-stdout: + a + end +expected-stderr-pattern: + /.*break.*/ +--- + + +name: break-5 +description: + Error if break argument isn't a number +stdin: + for i in a b c; do echo $i; break abc; echo more-$i; done + echo end +expected-stdout: + a +expected-exit: e != 0 +expected-stderr-pattern: + /.*break.*/ +--- + + +name: continue-1 +description: + See if continue continues loops +stdin: + for i in a b c; do echo $i; continue; echo bad-$i ; done + echo end-1 + for i in a b c; do echo $i; continue 1; echo bad-$i; done + echo end-2 + for i in a b c; do + for j in x y z; do + echo $i:$j + continue + echo bad-$i-$j + done + echo end-$i + done + echo end-3 +expected-stdout: + a + b + c + end-1 + a + b + c + end-2 + a:x + a:y + a:z + end-a + b:x + b:y + b:z + end-b + c:x + c:y + c:z + end-c + end-3 +--- + + +name: continue-2 +description: + See if continue breaks out of nested loops +stdin: + for i in a b c; do + for j in x y z; do + echo $i:$j + continue 2 + echo bad-$i-$j + done + echo end-$i + done + echo end +expected-stdout: + a:x + b:x + c:x + end +--- + + +name: continue-3 +description: + What if continue used outside of any loops + (ksh88,ksh93 don't print error messages here) +stdin: + continue +expected-stderr-pattern: + /.*continue.*/ +--- + + +name: continue-4 +description: + What if continue N used when only N-1 loops + (ksh88,ksh93 don't print error messages here) +stdin: + for i in a b c; do echo $i; continue 2; echo bad-$i; done + echo end +expected-stdout: + a + b + c + end +expected-stderr-pattern: + /.*continue.*/ +--- + + +name: continue-5 +description: + Error if continue argument isn't a number +stdin: + for i in a b c; do echo $i; continue abc; echo more-$i; done + echo end +expected-stdout: + a +expected-exit: e != 0 +expected-stderr-pattern: + /.*continue.*/ +--- + + diff --git a/bin/ksh/tests/cdhist.t b/bin/ksh/tests/cdhist.t new file mode 100644 index 00000000000..720f7d60bcc --- /dev/null +++ b/bin/ksh/tests/cdhist.t @@ -0,0 +1,160 @@ +name: cd-history +description: + Test someone's CD history package (uses arrays) +stdin: + # go to known place before doing anything + cd / + + alias cd=_cd + function _cd + { + typeset -i cdlen i + typeset t + + if [ $# -eq 0 ] + then + set -- $HOME + fi + + if [ "$CDHISTFILE" -a -r "$CDHISTFILE" ] # if directory history exists + then + typeset CDHIST + i=-1 + while read -r t # read directory history file + do + CDHIST[i=i+1]=$t + done <$CDHISTFILE + fi + + if [ "${CDHIST[0]}" != "$PWD" -a "$PWD" != "" ] + then + _cdins # insert $PWD into cd history + fi + + cdlen=${#CDHIST[*]} # number of elements in history + + case "$@" in + -) # cd to new dir + if [ "$OLDPWD" = "" ] && ((cdlen>1)) + then + 'print' ${CDHIST[1]} + 'cd' ${CDHIST[1]} + _pwd + else + 'cd' $@ + _pwd + fi + ;; + -l) # print directory list + typeset -R3 num + ((i=cdlen)) + while (((i=i-1)>=0)) + do + num=$i + 'print' "$num ${CDHIST[i]}" + done + return + ;; + -[0-9]|-[0-9][0-9]) # cd to dir in list + if (((i=${1#-})<cdlen)) + then + 'print' ${CDHIST[i]} + 'cd' ${CDHIST[i]} + _pwd + else + 'cd' $@ + _pwd + fi + ;; + -*) # cd to matched dir in list + t=${1#-} + i=1 + while ((i<cdlen)) + do + case ${CDHIST[i]} in + *$t*) + 'print' ${CDHIST[i]} + 'cd' ${CDHIST[i]} + _pwd + break + ;; + esac + ((i=i+1)) + done + if ((i>=cdlen)) + then + 'cd' $@ + _pwd + fi + ;; + *) # cd to new dir + 'cd' $@ + _pwd + ;; + esac + + _cdins # insert $PWD into cd history + + if [ "$CDHISTFILE" ] + then + cdlen=${#CDHIST[*]} # number of elements in history + + i=0 + while ((i<cdlen)) + do + 'print' -r ${CDHIST[i]} # update directory history + ((i=i+1)) + done >$CDHISTFILE + fi + } + + function _cdins # insert $PWD into cd history + { # meant to be called only by _cd + typeset -i i + + ((i=0)) + while ((i<${#CDHIST[*]})) # see if dir is already in list + do + if [ "${CDHIST[$i]}" = "$PWD" ] + then + break + fi + ((i=i+1)) + done + + if ((i>22)) # limit max size of list + then + i=22 + fi + + while (((i=i-1)>=0)) # bump old dirs in list + do + CDHIST[i+1]=${CDHIST[i]} + done + + CDHIST[0]=$PWD # insert new directory in list + } + + + function _pwd + { + if [ -n "$ECD" ] + then + pwd 1>&6 + fi + } + # Start of test + cd /tmp + cd /bin + cd /etc + cd - + cd -2 + cd -l +expected-stdout: + /bin + /tmp + 3 / + 2 /etc + 1 /bin + 0 /tmp +--- diff --git a/bin/ksh/tests/eglob.t b/bin/ksh/tests/eglob.t new file mode 100644 index 00000000000..ea69f635fcf --- /dev/null +++ b/bin/ksh/tests/eglob.t @@ -0,0 +1,138 @@ +name: eglob-bad-1 +description: + Check that globbing isn't done when glob has syntax error +perl-setup: + &touch("abcx", "abcz", "bbc"); +stdin: + echo !([*)* + echo +(a|b[)* +expected-stdout: + !([*)* + +(a|b[)* +--- + +name: eglob-bad-2 +description: + Check that globbing isn't done when glob has syntax error + (at&t ksh fails this test) +perl-setup: + &touch("abcx", "abcz", "bbc"); +stdin: + echo [a*(]*)z +expected-stdout: + [a*(]*)z +--- + +name: eglob-infinite-plus +description: + Check that shell doesn't go into infinite loop expanding +(...) + expressions. +perl-setup: + &touch("abc"); +time-limit: 3 +stdin: + echo +()c + echo +()x + echo +(*)c + echo +(*)x +expected-stdout: + +()c + +()x + abc + +(*)x +--- + +name: eglob-subst-1 +description: + Check that eglobbing isn't done on substitution results +perl-setup: + &touch("abc"); +stdin: + x='@(*)' + echo $x +expected-stdout: + @(*) +--- + +name: eglob-nomatch-1 +description: + Check that the pattern doesn't match +stdin: + echo no-file+(a|b)stuff + echo no-file+(a*(c)|b)stuff +expected-stdout: + no-file+(a|b)stuff + no-file+(a*(c)|b)stuff +--- + +name: eglob-match-1 +description: + Check that the pattern matches correctly +perl-setup: + &touch("abd", "acd"); +stdin: + echo a+(b|c)d + echo a!(@(b|B))d + echo a[b*(foo|bar)]d +expected-stdout: + abd acd + acd + abd +--- + +name: eglob-case-1 +description: + Simple negation tests +stdin: + case foo in !(foo|bar)) echo yes;; *) echo no;; esac + case bar in !(foo|bar)) echo yes;; *) echo no;; esac +expected-stdout: + no + no +--- + +name: eglob-case-2 +description: + Simple kleene tests +stdin: + case foo in *(a|b[)) echo yes;; *) echo no;; esac + case foo in *(a|b[)|f*) echo yes;; *) echo no;; esac + case '*(a|b[)' in *(a|b[)) echo yes;; *) echo no;; esac +expected-stdout: + no + yes + yes +--- + +name: eglob-trim-1 +description: + Eglobing in trim expressions... + (at&t ksh fails this - docs say # matches shortest string, ## matches + longest...) +stdin: + x=abcdef + echo 1: ${x#a|abc} + echo 2: ${x##a|abc} + echo 3: ${x%def|f} + echo 4: ${x%%f|def} +expected-stdout: + 1: bcdef + 2: def + 3: abcde + 4: abc +--- + +name: eglob-trim-2 +description: + Check eglobing works in trims... +stdin: + x=abcdef + echo ${x#*(a|b)cd} + echo "${x#*(a|b)cd}" + echo ${x#"*(a|b)cd"} +expected-stdout: + ef + ef + abcdef +--- + diff --git a/bin/ksh/tests/glob.t b/bin/ksh/tests/glob.t new file mode 100644 index 00000000000..c7d8e26808d --- /dev/null +++ b/bin/ksh/tests/glob.t @@ -0,0 +1,96 @@ +name: glob-bad-1 +description: + Check that globbing isn't done when glob has syntax error +perl-setup: + mkdir("[x", 0777) || die "couldn't make directory [x - $!\n"; + &touch("[x/foo"); +stdin: + echo [* + echo *[x + echo [x/* +expected-stdout: + [* + *[x + [x/foo +--- + +name: glob-bad-2 +description: + Check that symbolic links aren't stat()'d +perl-setup: + mkdir("dir", 0777) || die "couldn't make directory dir - $!\n"; + &touch("dir/abc"); + symlink("non-existent-file", "dir/abc"); +stdin: + echo d*/* + echo d*/abc +expected-stdout: + dir/abc + dir/abc +--- + +name: glob-range-1 +description: + Test range matching +perl-setup: + &touch(".bc", "abc", "bbc", "cbc", "-bc"); +stdin: + echo [ab-]* + echo [-ab]* + echo [!-ab]* + echo [!ab]* + echo []ab]* +expected-stdout: + -bc abc bbc + -bc abc bbc + cbc + -bc cbc + abc bbc +--- + +name: glob-range-2 +description: + Test range matching + (at&t ksh fails this; POSIX says invalid) +perl-setup: + &touch("abc"); +stdin: + echo [a--]* +expected-stdout: + [a--]* +--- + +name: glob-range-3 +description: + Check that globbing matches the right things... +perl-setup: + &touch("a\302c"); +stdin: + echo a[Á-Ú]* +expected-stdout: + aÂc +--- + +name: glob-range-4 +description: + Results unspecified according to POSIX +perl-setup: + &touch(".bc"); +stdin: + echo [a.]* +expected-stdout: + [a.]* +--- + +name: glob-range-5 +description: + Results unspecified according to POSIX + (at&t ksh treats this like [a-cc-e]*) +perl-setup: + &touch("abc", "bbc", "cbc", "dbc", "ebc", "-bc"); +stdin: + echo [a-c-e]* +expected-stdout: + -bc abc bbc cbc ebc +--- + diff --git a/bin/ksh/tests/heredoc.t b/bin/ksh/tests/heredoc.t new file mode 100644 index 00000000000..27c28302258 --- /dev/null +++ b/bin/ksh/tests/heredoc.t @@ -0,0 +1,72 @@ +name: heredoc-1 +description: + Check ordering/content of redundent here documents. +stdin: + cat << EOF1 << EOF2 + hi + EOF1 + there + EOF2 +expected-stdout: + there +--- + +name: heredoc-2 +description: + Check quoted here-doc is protected. +stdin: + a=foo + cat << 'EOF' + hi\ + there$a + stuff + EOF +expected-stdout: + hi\ + there$a + stuff +--- + +name: heredoc-3 +description: + Check quoted here-documents don't have \newline processing done + on them. +stdin: + cat << 'EOF' + hi\ + there + EO\ + F + EOF + true +expected-stdout: + hi\ + there + EO\ + F +--- + +name: heredoc-4 +description: + Check that newline isn't needed after heredoc-delimiter marker. +stdin: ! + cat << EOF + hi + there + EOF +expected-stdout: + hi + there +--- + +name: heredoc-5 +description: + Check that an error occurs if the heredoc-delimiter is missing. +stdin: ! + cat << EOF + hi + there +expected-exit: e > 0 +expected-stderr-pattern: /.*/ +--- + diff --git a/bin/ksh/tests/history.t b/bin/ksh/tests/history.t new file mode 100644 index 00000000000..707327ed37c --- /dev/null +++ b/bin/ksh/tests/history.t @@ -0,0 +1,529 @@ +# Not tested yet: +# - commands in history file are not numbered negatively +# (and a few hundred other things) + +name: history-basic +description: + See if we can test history at all +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo hi + fc -l +expected-stdout: + hi + 1 echo hi +expected-stderr-pattern: + /^X*$/ +--- + +name: history-e-minus-1 +description: + Check if more recent command is executed +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo hi + echo there + fc -e - +expected-stdout: + hi + there + there +expected-stderr-pattern: + /^X*echo there\nX*$/ +--- + +name: history-e-minus-2 +description: + Check that repeated command is printed before command + is re-executed. +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + exec 2>&1 + echo hi + echo there + fc -e - +expected-stdout-pattern: + /X*hi\nX*there\nX*echo there\nthere\nX*/ +expected-stderr-pattern: + /^X*$/ +--- + +name: history-e-minus-3 +description: + fc -e - fails when there is no history + (ksh93 has a bug that causes this to fail) + (ksh88 loops on this) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + fc -e - + echo ok +expected-stdout: + ok +expected-stderr-pattern: + /^X*.*:.*history.*\nX*$/ +--- + +name: history-e-minus-4 +description: + "fc -e | more" works +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc + fc -e - | (read x; echo "A $x") + echo ok +expected-stdout: + abc + A abc + ok +expected-stderr-pattern: + /^X*echo abc\nX*/ +--- + +name: history-e-minus-5 +description: + fc is replaced in history by new command. +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + echo ghi jkl + fc -e - echo + fc -l 2 4 +expected-stdout: + abc def + ghi jkl + ghi jkl + 2 echo ghi jkl + 3 echo ghi jkl + 4 fc -l 2 4 +expected-stderr-pattern: + /^X*echo ghi jkl\nX*$/ +--- + +name: history-list-1 +description: + List lists correct range + (ksh88 fails 'cause it lists the fc command) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + fc -l -- -2 +expected-stdout: + line 1 + line 2 + line 3 + 2 echo line 2 + 3 echo line 3 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-2 +description: + Lists oldest history if given pre-historic number + (ksh93 has a bug that causes this to fail) + (ksh88 fails 'cause it lists the fc command) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + fc -l -- -40 +expected-stdout: + line 1 + line 2 + line 3 + 1 echo line 1 + 2 echo line 2 + 3 echo line 3 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-3 +description: + Can give number `options' to fc +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + fc -l -3 -2 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + 2 echo line 2 + 3 echo line 3 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-4 +description: + -1 refers to previous command +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + fc -l -1 -1 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + 4 echo line 4 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-5 +description: + List command stays in history +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + fc -l -1 -1 + fc -l -2 -1 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + 4 echo line 4 + 4 echo line 4 + 5 fc -l -1 -1 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-6 +description: + HISTSIZE limits about of history kept. + (ksh88 fails 'cause it lists the fc command) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + echo line 5 + fc -l +expected-stdout: + line 1 + line 2 + line 3 + line 4 + line 5 + 4 echo line 4 + 5 echo line 5 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-7 +description: + fc allows too old/new errors in range specification +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + echo line 5 + fc -l 1 30 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + line 5 + 4 echo line 4 + 5 echo line 5 + 6 fc -l 1 30 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-r-1 +description: + test -r flag in history +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + echo line 5 + fc -l -r 2 4 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + line 5 + 4 echo line 4 + 3 echo line 3 + 2 echo line 2 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-r-2 +description: + If first is newer than last, -r is implied. +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + echo line 5 + fc -l 4 2 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + line 5 + 4 echo line 4 + 3 echo line 3 + 2 echo line 2 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-list-r-3 +description: + If first is newer than last, -r is cancelled. +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 + echo line 3 + echo line 4 + echo line 5 + fc -l -r 4 2 +expected-stdout: + line 1 + line 2 + line 3 + line 4 + line 5 + 2 echo line 2 + 3 echo line 3 + 4 echo line 4 +expected-stderr-pattern: + /^X*$/ +--- + +name: history-subst-1 +description: + Basic substitution +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + echo ghi jkl + fc -e - abc=AB 'echo a' +expected-stdout: + abc def + ghi jkl + AB def +expected-stderr-pattern: + /^X*echo AB def\nX*$/ +--- + +name: history-subst-2 +description: + Does subst find previous command? +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + echo ghi jkl + fc -e - jkl=XYZQRT 'echo g' +expected-stdout: + abc def + ghi jkl + ghi XYZQRT +expected-stderr-pattern: + /^X*echo ghi XYZQRT\nX*$/ +--- + +name: history-subst-3 +description: + Does subst find previous command when no arguments given +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + echo ghi jkl + fc -e - jkl=XYZQRT +expected-stdout: + abc def + ghi jkl + ghi XYZQRT +expected-stderr-pattern: + /^X*echo ghi XYZQRT\nX*$/ +--- + +name: history-subst-4 +description: + Global substitutions work + (ksh88 and ksh93 do not have -g option) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def asjj sadjhasdjh asdjhasd + fc -e - -g a=FooBAR +expected-stdout: + abc def asjj sadjhasdjh asdjhasd + FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd +expected-stderr-pattern: + /^X*echo FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd\nX*$/ +--- + +name: history-subst-5 +description: + Make sure searches don't find current (fc) command + (ksh88/ksh93 don't have the ? prefix thing so they fail this test) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + echo ghi jkl + fc -e - abc=AB \?abc +expected-stdout: + abc def + ghi jkl + AB def +expected-stderr-pattern: + /^X*echo AB def\nX*$/ +--- + +name: history-ed-1 +description: + Basic (ed) editing works (assumes you have generic ed editor + that prints no prompts). +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + fc echo + s/abc/FOOBAR/ + w + q +expected-stdout: + abc def + 13 + 16 + FOOBAR def +expected-stderr-pattern: + /^X*echo FOOBAR def\nX*$/ +--- + +name: history-ed-2 +description: + Correct command is edited when number given +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo line 1 + echo line 2 is here + echo line 3 + echo line 4 + fc 2 + s/is here/is changed/ + w + q +expected-stdout: + line 1 + line 2 is here + line 3 + line 4 + 20 + 23 + line 2 is changed +expected-stderr-pattern: + /^X*echo line 2 is changed\nX*$/ +--- + +name: history-ed-3 +description: + Newly created multi line commands show up as single command + in history. + (NOTE: will fail if using COMPLEX HISTORY compile time option) + (ksh88 fails 'cause it lists the fc command) +arguments: !-i! +env-setup: !ENV=./Env!HISTFILE=hist.file! +perl-setup: system("echo PS1=X > Env"); +stdin: + echo abc def + fc echo + s/abc/FOOBAR/ + $a + echo a new line + . + w + q + fc -l +expected-stdout: + abc def + 13 + 32 + FOOBAR def + a new line + 1 echo abc def + 2 echo FOOBAR def + echo a new line +expected-stderr-pattern: + /^X*echo FOOBAR def\necho a new line\nX*$/ +--- diff --git a/bin/ksh/tests/ifs.t b/bin/ksh/tests/ifs.t new file mode 100644 index 00000000000..a927aa301fc --- /dev/null +++ b/bin/ksh/tests/ifs.t @@ -0,0 +1,162 @@ +name: IFS-space-1 +description: + Simple test, default IFS +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + set -- A B C + showargs 1 $* + showargs 2 "$*" + showargs 3 $@ + showargs 4 "$@" +expected-stdout: + <1> <A> <B> <C> + <2> <A B C> + <3> <A> <B> <C> + <4> <A> <B> <C> +--- + +name: IFS-colon-1 +description: + Simple test, IFS=: +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS=: + set -- A B C + showargs 1 $* + showargs 2 "$*" + showargs 3 $@ + showargs 4 "$@" +expected-stdout: + <1> <A> <B> <C> + <2> <A:B:C> + <3> <A> <B> <C> + <4> <A> <B> <C> +--- + +name: IFS-null-1 +description: + Simple test, IFS="" +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="" + set -- A B C + showargs 1 $* + showargs 2 "$*" + showargs 3 $@ + showargs 4 "$@" +expected-stdout: + <1> <A B C> + <2> <ABC> + <3> <A B C> + <4> <A B C> +--- + +name: IFS-space-colon-1 +description: + Simple test, IFS=<white-space>: +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="IFS:" + set -- + showargs 1 $* + showargs 2 "$*" + showargs 3 $@ + showargs 4 "$@" + showargs 5 : "$@" +expected-stdout: + <1> + <2> <> + <3> + <4> + <5> <:> +--- + +name: IFS-space-colon-2 +description: + Simple test, IFS=<white-space>: + At&t ksh fails this, POSIX says the test is correct. +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="IFS:" + set -- + showargs :"$@" +expected-stdout: + <:> +--- + +name: IFS-space-colon-3 +description: + Simple test, IFS=<white-space>: + pdksh fails both of these tests +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="IFS:" + x= + set -- + showargs "$x$@" + showargs "$@$x" +expected-fail: yes +expected-stdout: + <> + <> +--- + +name: IFS-space-colon-4 +description: + Simple test, IFS=<white-space>: +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="IFS:" + set -- + showargs "$@$@" +expected-stdout: + +--- + +name: IFS-space-colon-5 +description: + Simple test, IFS=<white-space>: + Don't know what POSIX thinks of this. at&t ksh does not do this. +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="IFS:" + set -- + showargs "${@:-}" +expected-stdout: + <> +--- + +name: IFS-subst-1 +description: + Simple test, IFS=<white-space>: +stdin: + showargs() { for i; do echo -n " <$i>"; done; echo; } + IFS="$IFS:" + x=":b: :" + echo -n '1:'; for i in $x ; do echo -n " [$i]" ; done ; echo + echo -n '2:'; for i in :b:: ; do echo -n " [$i]" ; done ; echo + showargs 3 $x + showargs 4 :b:: + x="a:b:" + echo -n '5:'; for i in $x ; do echo -n " [$i]" ; done ; echo + showargs 6 $x + x="a::c" + echo -n '7:'; for i in $x ; do echo -n " [$i]" ; done ; echo + showargs 8 $x + echo -n '9:'; for i in ${FOO-`echo -n h:i`th:ere} ; do echo -n " [$i]" ; done ; echo + showargs 10 ${FOO-`echo -n h:i`th:ere} + showargs 11 "${FOO-`echo -n h:i`th:ere}" +expected-stdout: + 1: [] [b] [] [] + 2: [:b::] + <3> <> <b> <> <> + <4> <:b::> + 5: [a] [b] [] + <6> <a> <b> <> + 7: [a] [] [c] + <8> <a> <> <c> + 9: [h] [ith] [ere] + <10> <h> <ith> <ere> + <11> <h:ith:ere> +--- + diff --git a/bin/ksh/tests/integer.t b/bin/ksh/tests/integer.t new file mode 100644 index 00000000000..7e39612b3ff --- /dev/null +++ b/bin/ksh/tests/integer.t @@ -0,0 +1,218 @@ +name: integer-base-err-1 +description: + Can't have 0 base (causes shell to exit) +expected-exit: e != 0 +stdin: + typeset -i i + i=3 + i=0#4 + echo $i +expected-stderr-pattern: + /^.*:.*0#4.*\n$/ +--- + +name: integer-base-err-2 +description: + Can't have multiple bases in a `constant' (causes shell to exit) + (ksh88 fails this test) +expected-exit: e != 0 +stdin: + typeset -i i + i=3 + i=2#110#11 + echo $i +expected-stderr-pattern: + /^.*:.*2#110#11.*\n$/ +--- + +name: integer-base-err-3 +description: + Syntax errors in expressions and effects on bases + (interactive so errors don't cause exits) + (ksh88 fails this test - shell exits, even with -i) +arguments: !-i! +stdin: + PS1= # minimize prompt hassles + typeset -i4 a=10 + typeset -i a=2+ + echo $a + typeset -i4 a=10 + typeset -i2 a=2+ + echo $a +expected-stderr-pattern: + /^([#\$] )?.*:.*2+.*\n.*:.*2+.*\n$/ +expected-stdout: + 4#22 + 4#22 +--- + +name: integer-base-err-4 +description: + Are invalid digits (according to base) errors? + (ksh93 fails this test) +expected-exit: e != 0 +stdin: + typeset -i i; + i=3#4 +expected-stderr-pattern: + /^([#\$] )?.*:.*3#4.*\n$/ +--- + + +name: integer-base-1 +description: + Missing number after base is treated as 0. +stdin: + typeset -i i + i=3 + i=2# + echo $i +expected-stdout: + 0 +--- + +name: integer-base-2 +description: + Check `stickyness' of base in various situations +stdin: + typeset -i i=8 + echo $i + echo ---------- A + typeset -i4 j=8 + echo $j + echo ---------- B + typeset -i k=8 + typeset -i4 k=8 + echo $k + echo ---------- C + typeset -i4 l + l=3#10 + echo $l + echo ---------- D + typeset -i m + m=3#10 + echo $m + echo ---------- E + n=2#11 + typeset -i n + echo $n + n=10 + echo $n + echo ---------- F + typeset -i8 o=12 + typeset -i4 o + echo $o + echo ---------- G + typeset -i p + let p=8#12 + echo $p +expected-stdout: + 8 + ---------- A + 4#20 + ---------- B + 4#20 + ---------- C + 4#3 + ---------- D + 3#10 + ---------- E + 2#11 + 2#1010 + ---------- F + 4#30 + ---------- G + 8#12 +--- + +name: integer-base-3 +description: + More base parsing (hmm doesn't test much..) +stdin: + typeset -i aa + aa=1+12#10+2 + echo $aa + typeset -i bb + bb=1+$aa + echo $bb + typeset -i bb + bb=$aa + echo $bb + typeset -i cc + cc=$aa + echo $cc +expected-stdout: + 15 + 16 + 15 + 15 +--- + +name: integer-base-4 +description: + Check that things not declared as integers are not made integers, + also, check if base is not reset by -i with no arguments. + (ksh93 fails - prints 10#20 - go figure) +stdin: + xx=20 + let xx=10 + typeset -i | grep '^xx=' + typeset -i4 a=10 + typeset -i a=20 + echo $a +expected-stdout: + 4#110 +--- + +name: integer-base-5 +description: + More base stuff +stdin: + typeset -i4 a=3#10 + echo $a + echo -- + typeset -i j=3 + j=~3 + echo $j + echo -- + typeset -i k=1 + x[k=k+1]=3 + echo $k + echo -- + typeset -i l + for l in 1 2+3 4; do echo $l; done +expected-stdout: + 4#3 + -- + -4 + -- + 2 + -- + 1 + 5 + 4 +--- + +name: integer-base-6 +description: + Even more base stuff + (ksh93 fails this test - prints 0) +stdin: + typeset -i7 i + i= + echo $i +expected-stdout: + 7#0 +--- + +name: integer-base-7 +description: + Check that non-integer parameters don't get bases assigned +stdin: + echo $(( zz = 8#100 )) + echo $zz +expected-stdout: + 64 + 64 +--- + diff --git a/bin/ksh/tests/read.t b/bin/ksh/tests/read.t new file mode 100644 index 00000000000..aced86adc32 --- /dev/null +++ b/bin/ksh/tests/read.t @@ -0,0 +1,56 @@ +# +# To test: +# POSIX: +# - if no -r, \ is escape character +# - \newline disappear +# - \<IFS> -> don't break here +# - \<anything-else> -> <anything-else> +# - if -r, backslash is not special +# - if stdin is tty and shell interactive +# - prompt for continuation if \newline (prompt to stderr) +# - a here-document isn't terminated after newline ???? +# - remaining vars set to empty string (not null) +# - check field splitting +# - left over fields and their seperators assigned to last var +# - exit status is normally 0 +# - exit status is > 0 on eof +# - exit status > 0 on error +# - signals interrupt reads +# extra: +# - can't change read-only variables +# - error if var name bogus +# - set -o allexport effects read +# ksh: +# x check default variable: REPLY +# - check -p, -s, -u options +# - check var?prompt stuff +# - "echo a b | read x y" sets x,y in parent shell (at&t) +# +name: read-IFS-1 +description: + Simple test, default IFS +stdin: + echo "A B " > IN + unset x y z + read x y z < IN + echo 1: "x[$x] y[$y] z[$z]" + echo 1a: ${z-z not set} + read x < IN + echo 2: "x[$x]" +expected-stdout: + 1: x[A] y[B] z[] + 1a: + 2: x[A B] +--- + +name: read-ksh-1 +description: + If no var specified, REPLY is used +stdin: + echo "abc" > IN + read < IN + echo "[$REPLY]"; +expected-stdout: + [abc] +--- + diff --git a/bin/ksh/tests/regress.t b/bin/ksh/tests/regress.t new file mode 100644 index 00000000000..95fe97b6b7c --- /dev/null +++ b/bin/ksh/tests/regress.t @@ -0,0 +1,641 @@ +# +# The first 39 of these tests are from the old Bugs script. +# + +name: regression-1 +description: + Lex array code had problems with this. +stdin: + echo foo[ + n=bar + echo "hi[ $n ]=1" +expected-stdout: + foo[ + hi[ bar ]=1 +--- + + +name: regression-2 +description: + When PATH is set before running a command, the new path is + not used in doing the path search + $ echo echo hi > /tmp/q ; chmod a+rx /tmp/q + $ PATH=/tmp q + q: not found + $ + in comexec() the two lines + while (*vp != NULL) + (void) typeset(*vp++, xxx, 0); + need to be moved out of the switch to before findcom() is + called - I don't know what this will break. +stdin: + : ${PWD:-`pwd 2> /dev/null`} + : ${PWD:?"PWD not set - can't do test"} + mkdir Y + cat > Y/xxxscript << EOF + #!/bin/sh + echo hi + exit 0 + EOF + chmod a+rx Y/xxxscript + PATH=$PWD/Y xxxscript + exit $? +expected-stdout: + hi +--- + + +# +# 3. Sun OS 4.0.x (This seems to be a problem with sun's PENDIN not being done +# properly) +# sleep 5^J ls^J ls^J ls [only first ls runs] +# vi ... ZZ (while waiting type) [some of the input gets eaten] +# [not present in SunOS 4.1.x] +#echo " [No automatic test for bug 3 - interactive]" + + +# +# 4. (fixed) +# +#echo " [Don't know what bug 4 was]" + + +# +# 5. Everywhere +# File name completion (^X,*) does not mesh well with cd and +# symbolic links. cd does path simplification wrt $PWD before +# doing the actual chdir(), while file name completion does +# not do the simplification. E.g., you are in directory A +# which has a symbolic link to directory B, you create a file +# called foobar and you then cd to the symlink to B, and type +# $ echo ../foo^X +# and the shell beeps at you. Would be more consistent to +# do the completion after simplifing the `$PWD/..'. +#echo " [No automatic test for bug 5 - interactive]" + + +name: regression-6 +description: + Parsing of $(..) expressions is non-optimal. It is + impossible to have any parentheses inside the expression. + I.e., + $ ksh -c 'echo $(echo \( )' + no closing quote + $ ksh -c 'echo $(echo "(" )' + no closing quote + $ + The solution is to hack the parsing clode in lex.c, the + question is how to hack it: should any parentheses be + escaped by a backslash, or should recursive parsing be done + (so quotes could also be used to hide hem). The former is + easier, the later better... +stdin: + echo $(echo \() +expected-stdout: + ( +--- + + +# +# 7. (fixed) +# +#echo " [Don't know what bug 7 was]" + + +# +# 8. Everywhere - NOT A BUG - this is what at&t ksh88 does +# Strange typset -x behaviour in functions. The following function +# does not set the environment variable BLAH outside the function: +# function blah +# { +# typeset -x BLAH=foobar +# } +# This function does work: +# function blah +# { BLAH=foobar; export BLAH +# } +#echo ' [Bug 8 was bogus]' + + +name: regression-9 +description: + Continue in a for loop does not work right: + for i in a b c ; do + if [ $i = b ] ; then + continue + fi + echo $i + done + Prints a forever... +stdin: + first=yes + for i in a b c ; do + if [ $i = b ] ; then + if [ $first = no ] ; then + echo 'continue in for loop broken' + break # hope break isn't broken too :-) + fi + first=no + continue + fi + done + echo bye +expected-stdout: + bye +--- + + +name: regression-10 +description: + The following: + set -- `false` + echo $? + shoud not print 0. (according to /bin/sh, at&t ksh88, and the + getopt(1) man page - not according to POSIX) +stdin: + set -- `false` + echo $? +expected-stdout: + 1 +--- + + +name: regression-11 +description: + The following: + x=/foo/bar/blah + echo ${x##*/} + should echo blah but on some machines echos /foo/bar/blah. +stdin: + x=/foo/bar/blah + echo ${x##*/} +expected-stdout: + blah +--- + + +name: regression-12 +description: + Both of the following echos produce the same output under sh/ksh.att: + #!/bin/sh + x="foo bar" + echo "`echo \"$x\"`" + echo "`echo "$x"`" + pdksh produces different output for the former (foo instead of foo\tbar) +stdin: + x="foo bar" + echo "`echo \"$x\"`" + echo "`echo "$x"`" +expected-stdout: + foo bar + foo bar +--- + + +name: regression-13 +description: + The following command hangs forever: + $ (: ; cat /etc/termcap) | sleep 2 + This is because the shell forks a shell to run the (..) command + and this shell has the pipe open. When the sleep dies, the cat + doesn't get a SIGPIPE 'cause a process (ie, the second shell) + still has the pipe open. + + NOTE: this test provokes a bizarre bug in ksh93 (shell starts reading + commands from /etc/termcap..) +time-limit: 4 +stdin: + echo A line of text that will be duplicated quite a number of times.> t1 + cat t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 > t2 + cat t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 > t1 + cat t1 t1 t1 t1 > t2 + (: ; cat t2) | sleep 1 +--- + + +name: regression-14 +description: + The command + $ (foobar) 2> /dev/null + generates no output under /bin/sh, but pdksh produces the error + foobar: not found + Also, the command + $ foobar 2> /dev/null + generates an error under /bin/sh and pdksh, but at&t ksh88 produces + no error (redirected to /dev/null). +stdin: + (you/should/not/see/this/error/1) 2> /dev/null + you/should/not/see/this/error/2 2> /dev/null + true +--- + + +name: regression-15 +description: + The command + $ whence foobar + generates a blank line under pdksh and sets the exit status to 0. + at&t ksh88 generates no output and sets the exit status to 1. Also, + the command + $ whence foobar cat + generates no output under at&t ksh88 (pdksh generates a blank line + and /bin/cat). +stdin: + whence does/not/exist > /dev/null + echo 1: $? + echo 2: $(whence does/not/exist | wc -l) + echo 3: $(whence does/not/exist cat | wc -l) +expected-stdout: + 1: 1 + 2: 0 + 3: 0 +--- + + +name: regression-16 +description: + ${var%%expr} seems to be broken in many places. On the mips + the commands + $ read line < /etc/passwd + $ echo $line + root:0:1:... + $ echo ${line%%:*} + root + $ echo $line + root + $ + change the value of line. On sun4s & pas, the echo ${line%%:*} doesn't + work. Haven't checked elsewhere... +script: + read x + y=$x + echo ${x%%:*} + echo $x +stdin: + root:asdjhasdasjhs:0:1:Root:/:/bin/sh +expected-stdout: + root + root:asdjhasdasjhs:0:1:Root:/:/bin/sh +--- + + +name: regression-17 +description: + The command + . /foo/bar + should set the exit status to non-zero (sh and at&t ksh88 do). + XXX doting a non existant file is a fatal error for a script +stdin: + . does/not/exist +expected-exit: e != 0 +expected-stderr-pattern: /.?/ +--- + + +# +# 18. Everywhere +# In vi mode ^X (and *) can dump core: +# $ ab[cd^XMemory fault (core dumped) +#echo " [No automatic test for bug 18 - interactive]" + + +name: regression-19 +description: + Both of the following echos should produce the same thing, but don't: + $ x=foo/bar + $ echo ${x%/*} + foo + $ echo "${x%/*}" + foo/bar +stdin: + x=foo/bar + echo "${x%/*}" +expected-stdout: + foo +--- + + +# +# 20. (same as 18) +# + + +name: regression-21 +description: + backslash does not work as expected in case labels: + $ x='-x' + $ case $x in + -\?) echo hi + esac + hi + $ x='-?' + $ case $x in + -\\?) echo hi + esac + hi + $ +stdin: + case -x in + -\?) echo fail + esac +--- + + +name: regression-22 +description: + Quoting backquotes inside backquotes doesn't work: + $ echo `echo hi \`echo there\` folks` + asks for more info. sh and at&t ksh88 both echo + hi there folks +stdin: + echo `echo hi \`echo there\` folks` +expected-stdout: + hi there folks +--- + + +name: regression-23 +description: + )) is not treated `correctly': + $ (echo hi ; (echo there ; echo folks)) + missing (( + $ + instead of (as sh and ksh.att) + $ (echo hi ; (echo there ; echo folks)) + hi + there + folks + $ +stdin: + ( : ; ( : ; echo hi)) +expected-stdout: + hi +--- + + +# +# 24. strangeness with file name completion involving symlinks to nowhere +# $ mkdir foo foo/bar +# $ ln -s /stuff/junk foo/bar/xx +# $ echo foo/*/xx +# (beep) +# $ +#echo " [No automatic test for bug 24 - interactive]" + + +name: regression-25 +description: + Check reading stdin in a while loop. The read should only read + a single line, not a whole stdio buffer; the cat should get + the rest. +stdin: + (echo a; echo b) | while read x ; do + echo $x + cat > /dev/null + done +expected-stdout: + a +--- + + +name: regression-26 +description: + Check reading stdin in a while loop. The read should read both + lines, not just the first. +script: + a= + while [ "$a" != xxx ] ; do + last=$x + read x + /bin/cat /dev/null | sed 's/x/y/' + a=x$a + done + echo $last +stdin: + a + b +expected-stdout: + b +--- + + +name: regression-27 +description: + The command + . /does/not/exist + should cause a script to exit. +stdin: + . does/not/exist + echo hi +expected-exit: e != 0 +expected-stderr-pattern: /does\/not\/exist/ +--- + + +name: regression-28 +description: + variable assignements not detected well +stdin: + a.x=1 echo hi +expected-exit: e != 0 +expected-stderr-pattern: /a\.x=1/ +--- + + +name: regression-29 +description: + alias expansion different from at&t ksh88 +stdin: + alias a='for ' b='i in' + a b hi ; do echo $i ; done +expected-stdout: + hi +--- + + +name: regression-30 +description: + strange characters allowed inside ${...} +stdin: + echo ${a{b}} +expected-exit: e != 0 +expected-stderr-pattern: /.?/ +--- + + +name: regression-31 +description: + Does read handle partial lines correctly +script: + a= ret= + while [ "$a" != xxx ] ; do + read x y z + ret=$? + a=x$a + done + echo "[$x]" + echo $ret +stdin: ! + a A aA + b B Bb + c +expected-stdout: + [c] + 1 +--- + + +name: regression-32 +description: + Does read set variables to null at eof? +script: + a= + while [ "$a" != xxx ] ; do + read x y z + a=x$a + done + echo 1: ${x-x not set} ${y-y not set} ${z-z not set} + echo 2: ${x:+x not null} ${y:+y not null} ${z:+z not null} +stdin: + a A Aa + b B Bb +expected-stdout: + 1: + 2: +--- + + +name: regression-33 +description: + Does umask print a leading 0 when umask is 3 digits? +stdin: + umask 222 + umask +expected-stdout: + 0222 +--- + + +# +# +# Does umask print a umask of 0 sanely? +# There is lots of variety here (0, 00, 000, and 0000 have all been +# seen in various shells...) +# +#echo ' [Bug 34 was bogus]' + + +name: regression-35 +description: + Tempory files used for here-docs in functions get trashed after + the function is parsed (before it is executed) +stdin: + f1() { + cat <<- EOF + F1 + EOF + f2() { + cat <<- EOF + F2 + EOF + } + } + f1 + f2 + unset -f f1 + f2 +expected-stdout: + F1 + F2 + F2 +--- + + +name: regression-36 +description: + Command substitution breaks reading in while loop + (test from <sjg@void.zen.oz.au>) +stdin: + (echo abcdef; echo; echo 123) | + while read line + do + # the following line breaks it + c=`echo $line | wc -c` + echo $c + done +expected-stdout: + 7 + 1 + 4 +--- + + +name: regression-37 +description: + Machines with broken times() (reported by <sjg@void.zen.oz.au>) + time does not report correct real time +stdin: + time sleep 1 +expected-stderr-pattern: !/^\s*0\.0[\s\d]+real|^\s*real[\s]+0+\.0/ +--- + + +name: regression-38 +description: + set -e doesn't ignore exit codes for if/while/until/&&/||/!. +arguments: !-e! +stdin: + if false; then echo hi ; fi + false || true + false && true + while false; do echo hi; done + echo ok +expected-stdout: + ok +--- + + +name: regression-39 +description: + set -e: errors in command substitutions aren't ignored + Not clear if they should be or not... +expected-fail: yes +arguments: !-e! +stdin: + echo `false; echo hi` +expected-stdout: + hi +--- + +name: regression-40 +description: + This used to cause a core dump +env-setup: !RANDOM=12! +stdin: + echo hi +expected-stdout: + hi +--- + +name: regression-41 +description: + foo should be set to bar (should not be empty) +stdin: + foo=` + echo bar` + echo "($foo)" +expected-stdout: + (bar) +--- + +name: regression-42 +description: + Can't use command line assignments to assign readonly parameters. +stdin: + foo=bar + readonly foo + foo=stuff env | grep '^foo' +expected-exit: e != 0 +expected-stderr-pattern: + /.*read *only.*/ +--- diff --git a/bin/ksh/tests/th b/bin/ksh/tests/th new file mode 100644 index 00000000000..496058ccd4e --- /dev/null +++ b/bin/ksh/tests/th @@ -0,0 +1,813 @@ +#!/usr/local/bin/perl + +# +# Test harness for pdksh tests. +# +# Example test: +# name: a-test +# description: +# a test to show how tests are done +# arguments: !-x!-f! +# stdin: +# echo -n * +# false +# expected-stdout: ! +# * +# expected-stderr: +# + echo -n * +# + false +# expected-exit: 1 +# --- +# This runs the test-program (eg, pdksh) with the arguments -x and -f, +# standard input is a file containing "echo hi*\nfalse\n". The program +# is expected to produce "hi*" (no trailing newline) on standard output, +# "+ echo hi*\n+false\n" on standard error, and an exit code of 1. +# +# +# Format of test files: +# - blank lines and lines starting with # are ignored +# - a test file contains a series of tests +# - a test is a series of tag:value pairs ended with a "---" line +# (leading/trailing spaces are stripped from the first line of value) +# - test tags are: +# Tag Flag Description +# ----- ---- ----------- +# name r The name of the test; should be unique +# description m What test does +# arguments M Arguments to pass to the program; +# default is no arguments. +# script m Value is written to a file which +# is passed as an argument to the program +# (after the arguments arguments) +# stdin m Value is written to a file which is +# used as standard-input for the program; +# default is to use /dev/null. +# perl-setup m Value is a perl script which is executed +# just before the test is run. Try to +# avoid using this... +# perl-cleanup m Value is a perl script which is executed +# just after the test is run. Try to +# avoid using this... +# env-setup M Value is a list of NAME=VALUE elements +# which are put in the environment before +# the test is run. If the =VALUE is +# missing, NAME is removed from the +# environment. Programs are run with +# the following minimal environment: +# USER, LOGNAME, HOME, PATH, SHELL +# (values taken from the environment of +# the test harness). +# time-limit Time limit - the program is sent a +# SIGKILL N seconds. Default is no +# limit. +# expected-fail `yes' if the test is expected to fail. +# expected-exit expected exit code. Can be a number, +# or a C expression using the variables +# e, s and w (exit code, termination +# signal, and status code). +# expected-stdout m What the test should generate on stdout; +# default is to expect no output. +# expected-stdout-pattern m A perl pattern which matches the +# expected output. +# expected-stderr m What the test should generate on stderr; +# default is to expect no output. +# expected-stderr-pattern m A perl pattern which matches the +# expected standard error. +# Flag meanings: +# r tag is required (eg, a test must have a name tag). +# m value can be multiple lines. Lines must be prefixed with +# a tab. If the value part of the initial tag:value line is +# - empty: the initial blank line is stripped. +# - a lone !: the last newline in the value is stripped; +# M value can be multiple lines (prefixed by a tab) and consists +# of multiple fields, delimited by a field seperator character. +# The value must start and end with the f-s-c. +# + +require 'signal.ph'; +require 'errno.ph'; +require 'getopts.pl'; + +($prog = $0) =~ s#.*/##; + +$Usage = <<EOF ; +Usage: $prog [-s test-set] [-p prog] [-v] test-name ... + -p p Use p as the program to test + -s s Read tests from file s; if s is a directory, it is recursively + scaned for test files (which end in .t). + -t t Use t as default time limit for tests (default is unlimited) + -v Verbose mode: print reason test failed. + test-name(s) specifies the name of the test(s) to run; if none are + specified, all tests are run. +EOF + +# +# r - required +# m - can be multi-line +# M - multi-line, but without trailing newline +# +%test_fields = ( + 'name', 'r', + 'description', 'm', + 'arguments', 'M', + 'script', 'm', + 'stdin', 'm', + 'perl-setup', 'm', + 'perl-cleanup', 'm', + 'env-setup', 'M', + 'time-limit', '', + 'expected-fail', '', + 'expected-exit', '', + 'expected-stdout', 'm', + 'expected-stdout-pattern', 'm', + 'expected-stderr', 'm', + 'expected-stderr-pattern', 'm', + ); +# Filled in by read_test() +%internal_test_fields = ( + ':full-name', 1, # file:name + ':long-name', 1, # dir/file:lineno:name + ); + +$temps = "/tmp/rts$$"; +$tempi = "/tmp/rti$$"; +$tempo = "/tmp/rto$$"; +$tempe = "/tmp/rte$$"; +$tempdir = "/tmp/rtd$$"; + +$nfailed = 0; +$nxfailed = 0; +$npassed = 0; +$nxpassed = 0; + +%known_tests = (); + +if (!&Getopts('p:s:t:v')) { + print STDERR $Usage; + exit 1; +} + +die "$prog: no program specified (use -p)\n" if !defined $opt_p; +die "$prog: no test set specified (use -s)\n" if !defined $opt_s; +$test_prog = $opt_p; +$verbose = defined $opt_v && $opt_v; +$test_set = $opt_s; +if (defined $opt_t) { + die "$prog: bad -t argument (should be number > 0): $opt_t\n" + if $opt_t !~ /^\d+$/ || $opt_t <= 0; + $default_time_limit = $opt_t; +} + +# Note which tests are to be run. +%do_test = (); +grep($do_test{$_} = 1, @ARGV); +$all_tests = @ARGV == 0; + +# Set up a very minimal environment +%new_env = (); +foreach $env (('USER', 'LOGNAME', 'HOME', 'PATH', 'SHELL')) { + $new_env{$env} = $ENV{$env} if defined $ENV{$env}; +} +%old_env = %ENV; +%ENV = %new_env; + +die "$prog: couldn't make directory $tempdir - $!\n" if !mkdir($tempdir, 0777); + +chop($pwd = `pwd 2> /dev/null`); +die "$prog: couldn't get current working directory\n" if $pwd eq ''; +die "$prog: couldn't cd to $pwd - $!\n" if !chdir($pwd); + +$test_prog = "$pwd/$test_prog" if substr($test_prog, 0, 1) ne '/'; +die "$prog: $test_prog is not executable - bye\n" if ! -x $test_prog; + +@trap_sigs = ('TERM', 'QUIT', 'INT', 'PIPE', 'HUP'); +@SIG{@trap_sigs} = ('cleanup_exit') x @trap_sigs; +$child_kill_ok = 0; +$SIG{'ALRM'} = 'catch_sigalrm'; + +$| = 1; + +if (-d $test_set) { + $file_prefix_skip = length($test_set) + 1; + $ret = &process_test_dir($test_set); +} else { + $file_prefix_skip = 0; + $ret = &process_test_file($test_set); +} +&cleanup_exit() if !defined $ret; + +$tot_failed = $nfailed + $nxfailed; +$tot_passed = $npassed + $nxpassed; +if ($tot_failed || $tot_passed) { + print "Total failed: $tot_failed"; + print " ($nxfailed unexpected)" if $nxfailed; + print " (as expected)" if $nfailed && !$nxfailed; + print "\nTotal passed: $tot_passed"; + print " ($nxpassed unexpected)" if $nxpassed; + print "\n"; +} + +&cleanup_exit('ok'); + +sub +cleanup_exit +{ + local($sig, $exitcode) = ('', 1); + + if ($_[0] eq 'ok') { + $exitcode = 0; + } elsif ($_[0] ne '') { + $sig = $_[0]; + } + + unlink($tempi, $tempo, $tempe, $temps); + &scrub_dir($tempdir) if defined $tempdir; + rmdir($tempdir) if defined $tempdir; + + if ($sig) { + $SIG{$sig} = 'DEFAULT'; + kill $sig, $$; + return; + } + exit $exitcode; +} + +sub +catch_sigalrm +{ + $SIG{'ALRM'} = 'catch_sigalrm'; + kill(9, $child_pid) if $child_kill_ok; + $child_killed = 1; +} + +sub +process_test_dir +{ + local($dir) = @_; + local($ret, $file); + local(@todo) = (); + + if (!opendir(DIR, $dir)) { + print STDERR "$prog: can't open directory $dir - $!\n"; + return undef; + } + while ($file = readdir(DIR)) { + push(@todo, $file) if $file =~ /^[^.].*\.t$/; + } + closedir(DIR); + + foreach $file (@todo) { + $file = "$dir/$file"; + if (-d $file) { + $ret = &process_test_dir($file); + } elsif (-f _) { + $ret = &process_test_file($file); + } + last if !defined $ret; + } + + return $ret; +} + +sub +process_test_file +{ + local($file) = @_; + local($ret); + + if (!open(IN, $file)) { + die "$prog: can't open $file - $!\n"; + return undef; + } + while (1) { + $ret = &read_test($file, IN, *test); + last if !defined $ret || !$ret; + next if !$all_tests && !$do_test{$test{'name'}}; + $ret = &run_test(*test); + last if !defined $ret; + } + close(IN); + + return $ret; +} + +sub +run_test +{ + local(*test) = @_; + local($name) = $test{':full-name'}; + + #print "Running test $name...\n" if $verbose; + + if (defined $test{'stdin'}) { + return undef if !&write_file($tempi, $test{'stdin'}); + $ifile = $tempi; + } else { + $ifile = '/dev/null'; + } + + if (defined $test{'script'}) { + return undef if !&write_file($temps, $test{'script'}); + } + + return undef if !&scrub_dir($tempdir); + + if (!chdir($tempdir)) { + print STDERR "$prog: couldn't cd to $tempdir - $!\n"; + return undef; + } + + if (defined $test{'perl-setup'}) { + eval $test{'perl-setup'}; + if ($@ ne '') { + print STDERR "$prog:$test{':long-name'}: error running perl-setup - $@\n"; + return undef; + } + } + + $pid = fork; + if (!defined $pid) { + print STDERR "$prog: can't fork - $!\n"; + return undef; + } + if (!$pid) { + @SIG{@trap_sigs} = ('DEFAULT') x @trap_sigs; + $SIG{'ALRM'} = 'DEFAULT'; + if (defined $test{'env-setup'}) { + local($var, $val, $i); + + foreach $var (split(substr($test{'env-setup'}, 0, 1), + $test{'env-setup'})) + { + $i = index($var, '='); + next if $i == 0 || $var eq ''; + if ($i < 0) { + delete $ENV{$var}; + } else { + $ENV{substr($var, 0, $i)} = substr($var, $i + 1); + } + } + } + if (!open(STDIN, "< $ifile")) { + print STDERR "$prog: couldn't open $ifile in child - $!\n"; + kill('TERM', $$); + } + if (!open(STDOUT, "> $tempo")) { + print STDERR "$prog: couldn't open $tempo in child - $!\n"; + kill('TERM', $$); + } + if (!open(STDERR, "> $tempe")) { + print STDOUT "$prog: couldn't open $tempe in child - $!\n"; + kill('TERM', $$); + } + @argv = ($test_prog); + if (defined $test{'arguments'}) { + push(@argv, + split(substr($test{'arguments'}, 0, 1), + substr($test{'arguments'}, 1))); + } + push(@argv, $temps) if defined $test{'script'}; + exec(@argv); + print STDERR "$prog: couldn't execute $test_prog - $!\n"; + kill('TERM', $$); + exit(95); + } + $child_pid = $pid; + $child_killed = 0; + $child_kill_ok = 1; + alarm($test{'time-limit'}) if defined $test{'time-limit'}; + while (1) { + $xpid = waitpid($pid, 0); + $child_kill_ok = 0; + if ($xpid < 0) { + next if $! == &EINTR; + print STDERR "$prog: error waiting for child - $!\n"; + return undef; + } + last; + } + $status = $?; + alarm(0) if defined $test{'time-limit'}; + + $failed = 0; + $why = ''; + + if ($child_killed) { + $failed = 1; + $why .= "\ttest timed out (limit of $test{'time-limit'} seconds)\n"; + } + + $ret = &eval_exit($test{'long-name'}, $status, $test{'expected-exit'}); + return undef if !defined $ret; + if (!$ret) { + local($expl); + + $failed = 1; + if (($status & 0xff) == 0x7f) { + $expl = "stopped"; + } elsif (($status & 0xff)) { + $expl = "signal " . ($status & 0x7f); + } else { + $expl = "exit-code " . (($status >> 8) & 0xff); + } + $why .= + "\tunexpected exit status $status ($expl), expected $test{'expected-exit'}\n"; + } + + $tmp = &check_output($test{'long-name'}, $tempo, 'stdout', + $test{'expected-stdout'}, $test{'expected-stdout-pattern'}); + return undef if !defined $tmp; + if ($tmp ne '') { + $failed = 1; + $why .= $tmp; + } + + $tmp = &check_output($test{'long-name'}, $tempe, 'stderr', + $test{'expected-stderr'}, $test{'expected-stderr-pattern'}); + return undef if !defined $tmp; + if ($tmp ne '') { + $failed = 1; + $why .= $tmp; + } + + if (defined $test{'perl-cleanup'}) { + eval $test{'perl-cleanup'}; + if ($@ ne '') { + print STDERR "$prog:$test{':long-name'}: error running perl-cleanup - $@\n"; + return undef; + } + } + + if (!chdir($pwd)) { + print STDERR "$prog: couldn't cd to $pwd - $!\n"; + return undef; + } + + if ($failed) { + if (!$test{'expected-fail'}) { + print "FAIL $name\n"; + $nxfailed++; + } else { + print "fail $name (as expected)\n"; + $nfailed++; + } + $why = "\tDescription" + . &wrap_lines($test{'description'}, " (missing)\n") + . $why; + } elsif ($test{'expected-fail'}) { + print "PASS $name (unexpectedly)\n"; + $nxpassed++; + } else { + print "pass $name\n"; + $npassed++; + } + print $why if $verbose; + return 0; +} + +sub +scrub_dir +{ + local($dir) = @_; + local(@todo) = (); + local($file); + + if (!opendir(DIR, $dir)) { + print STDERR "$prog: couldn't open direcotry $dir - $!\n"; + return undef; + } + while ($file = readdir(DIR)) { + push(@todo, $file) if $file ne '.' && $file ne '..'; + } + closedir(DIR); + foreach $file (@todo) { + $file = "$dir/$file"; + if (-d $file) { + return undef if !&scrub_dir($file); + if (!rmdir($file)) { + print STDERR "$prog: couldn't rmdir $file - $!\n"; + return undef; + } + } else { + if (!unlink($file)) { + print STDERR "$prog: couldn't unlink $file - $!\n"; + return undef; + } + } + } + return 1; +} + +sub +write_file +{ + local($file, $str) = @_; + + if (!open(TEMP, "> $file")) { + print STDERR "$prog: can't open $file - $!\n"; + return undef; + } + print TEMP $str; + if (!close(TEMP)) { + print STDERR "$prog: error writing $file - $!\n"; + return undef; + } + return 1; +} + +sub +check_output +{ + local($name, $file, $what, $expect, $expect_pat) = @_; + local($got) = ''; + local($why) = ''; + local($ret); + + if (!open(TEMP, "< $file")) { + print STDERR "$prog:$name($what): couldn't open $file after running program - $!\n"; + return undef; + } + while (<TEMP>) { + $got .= $_; + } + close(TEMP); + if (defined $expect_pat) { + $_ = $got; + $ret = eval "$expect_pat"; + if ($@ ne '') { + print STDERR "$prog:$name($what): error evaluating $what pattern: $expect_pat - $@\n"; + return undef; + } + if (!$ret) { + $why = "\tunexpected $what - wanted pattern"; + $why .= &wrap_lines($expect_pat); + $why .= "\tgot"; + $why .= &wrap_lines($got); + } + } else { + $expect = '' if !defined $expect; + if ($got ne $expect) { + $why .= "\tunexpected $what - " . &first_diff($expect, $got) . "\n"; + $why .= "\twanted"; + $why .= &wrap_lines($expect); + $why .= "\tgot"; + $why .= &wrap_lines($got); + } + } + return $why; +} + +sub +wrap_lines +{ + local($str, $empty) = @_; + local($nonl) = substr($str, -1, 1) ne "\n"; + + return (defined $empty ? $empty : " nothing\n") if $str eq ''; + substr($str, 0, 0) = ":\n"; + $str =~ s/\n/\n\t\t/g; + if ($nonl) { + $str .= "\n\t[incomplete last line]\n"; + } else { + chop($str); + chop($str); + } + return $str; +} + +sub +first_diff +{ + local($exp, $got) = @_; + local($lineno, $char) = (1, 1); + local($i, $len); + local($ce, $cg); + + $len = length($exp); + if ($len != length($got)) { + if ($len < length($got)) { + if (substr($got, 0, $len) eq $exp) { + return "got too much output"; + } + } elsif (substr($exp, 0, $len) eq $got) { + return "got too little output"; + } + $len = length($got); + } + for ($i = 0; $i < $len; $i++) { + $ce = substr($exp, $i, 1); + $cg = substr($got, $i, 1); + last if $ce ne $cg; + $char++; + if ($ce eq "\n") { + $lineno++; + $char = 1; + } + } + return "first difference: line $lineno, char $char" +} + +sub +eval_exit +{ + local($name, $status, $expect) = @_; + local($expr); + local($w, $e, $s) = ($status, ($status >> 8) & 0xff, $status & 0x7f); + + $e = -1000 if $status & 0xff; + $s = -1000 if $s == 0x7f; + if (!defined $expect) { + $expr = '$w == 0'; + } elsif ($expect =~ /^(|-)\d+$/) { + $expr = "\$e == $expect"; + } else { + $expr = $expect; + $expr =~ s/\b([wse])\b/\$$1/g; + $expr =~ s/\b(SIG[A-Z0-9]+)\b/&$1/g; + } + $w = eval $expr; + if ($@ ne '') { + print STDERR "$prog:$test{':long-name'}: bad expected-exit expression: $expect ($@)\n"; + return undef; + } + return $w; +} + +sub +read_test +{ + local($file, $in, *test) = @_; + local($field, $val, $flags, $do_chop, $need_redo, $start_lineno); + + %test = (); + while (<$in>) { + next if /^\s*$/; + next if /^ *#/; + last if /^\s*---\s*$/; + $start_lineno = $. if !defined $start_lineno; + if (!/^([-\w]+):\s*(|\S|\S.*\S)\s*$/) { + print STDERR "$prog:$file:$.: unrecognized line\n"; + return undef; + } + ($field, $val) = ($1, $2); + if (defined $test{$field}) { + print STDERR "$prog:$file:$.: multiple \"$field\" fields\n"; + return undef; + } + $flags = $test_fields{$field}; + if (!defined $flags) { + print STDERR "$prog:$file:$.: unrecognized field \"$field\"\n"; + return undef; + } + $do_chop = $flags !~ /m/; + $need_redo = 0; + if ($val eq '' || $val eq '!') { + if ($flags =~ /[Mm]/) { + $do_chop = 1 if $val eq '!'; + $val = ''; + while (<$in>) { + last if !/^\t/; + $val .= $'; + } + chop $val if $do_chop; + $do_chop = 1; + $need_redo = 1; + } elsif ($val eq '') { + print STDERR + "$prog:$file:$.: no value given for field \"$field\"\n"; + return undef; + } + } + $val .= "\n" if !$do_chop; + $test{$field} = $val; + redo if $need_redo; + } + if ($_ eq '') { + if (%test) { + print STDERR + "$prog:$file:$start_lineno: end-of-file while reading test\n"; + return undef; + } + return 0; + } + + while (($field, $val) = each %test_fields) { + if ($val =~ /r/ && !defined $test{$field}) { + print STDERR + "$prog:$file:$start_lineno: required field \"$field\" missing\n"; + return undef; + } + } + + $test{':full-name'} = substr($file, $file_prefix_skip) . ":$test{'name'}"; + $test{':long-name'} = "$file:$start_lineno:$test{'name'}"; + + # Syntax check on specific fields + if (defined $test{'expected-fail'}) { + if ($test{'expected-fail'} !~ /^(yes|no)$/) { + print STDERR + "$prog:$test{':long-name'}: bad value for expected-fail field\n"; + return undef; + } + $test{'expected-fail'} = $1 eq 'yes'; + } else { + $test{'expected-fail'} = 0; + } + if (defined $test{'arguments'}) { + local($firstc) = substr($test{'arguments'}, 0, 1); + + if (substr($test{'arguments'}, -1, 1) ne $firstc) { + print STDERR "$prog:$test{':long-name'}: arguments field doesn't start and end with the same character\n"; + return undef; + } + } + if (defined $test{'env-setup'}) { + local($firstc) = substr($test{'env-setup'}, 0, 1); + + if (substr($test{'env-setup'}, -1, 1) ne $firstc) { + print STDERR "$prog:$test{':long-name'}: env-setup field doesn't start and end with the same character\n"; + return undef; + } + } + if (defined $test{'expected-exit'}) { + local($val) = $test{'expected-exit'}; + + if ($val =~ /^(|-)\d+$/) { + if ($val < 0 || $val > 255) { + print STDERR "$prog:$test{':long-name'}: expected-exit value $val not in 0..255\n"; + return undef; + } + } elsif ($val !~ /^([\s<>+-=*%\/&|!()]|\b[wse]\b|\bSIG[A-Z0-9]+\b)+$/) { + print STDERR "$prog:$test{':long-name'}: bad expected-exit expression: $val\n"; + return undef; + } + } else { + $test{'expected-exit'} = 0; + } + if (defined $test{'expected-stdout'} + && defined $test{'expected-stdout-pattern'}) + { + print STDERR "$prog:$test{':long-name'}: can't use both expected-stdout and expected-stdout-pattern\n"; + return undef; + } + if (defined $test{'expected-stderr'} + && defined $test{'expected-stderr-pattern'}) + { + print STDERR "$prog:$test{':long-name'}: can't use both expected-stderr and expected-stderr-pattern\n"; + return undef; + } + if (defined $test{'time-limit'}) { + if ($test{'time-limit'} !~ /^\d+$/ || $test{'time-limit'} == 0) { + print STDERR + "$prog:$test{':long-name'}: bad value for time-limit field\n"; + return undef; + } + } elsif (defined $default_time_limit) { + $test{'time-limit'} = $default_time_limit; + } + + if (defined $known_tests{$test{'name'}}) { + print STDERR "$prog:$test{':long-name'}: warning: duplicate test name ${test{'name'}}\n"; + } + $known_tests{$test{'name'}} = 1; + + return 1; +} + +sub +touch +{ + local(@files) = @_; + local($file); + + foreach $file (@files) { + if (!open(T, "> $file")) { + die "Couldn't touch $file\n"; + } + close(T); + } + return 1; +} + +sub +tty_msg +{ + local($msg) = @_; + + open(TTY, "> /dev/tty") || return 0; + print TTY $msg; + close(TTY); + return 1; +} + +sub +never_called_funcs +{ + return 0; + &tty_msg("hi\n"); + &touch("/tmp/foo"); + &never_called_funcs(); + &catch_sigalrm(); + $old_env{'foo'} = 'bar'; + $internal_test_fields{'foo'} = 'bar'; +} diff --git a/bin/ksh/tests/th.sh b/bin/ksh/tests/th.sh new file mode 100644 index 00000000000..6e40c19dcf9 --- /dev/null +++ b/bin/ksh/tests/th.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# +# Simple script to find perl and run it +# + +IFS=:$IFS +perl= +for i in $PATH; do + [ X"$i" = X ] && i=. + for j in perl perl4 perl5 ; do + [ -x "$i/$j" ] && perl=$i/$j && break 2 + done +done + +[ X"$perl" = X ] && { + echo "$0: can't find perl - bye\n" 1>&2 + exit 1 + } + +exec $perl "$@" diff --git a/bin/ksh/tests/unclass1.t b/bin/ksh/tests/unclass1.t new file mode 100644 index 00000000000..2e3e88791bf --- /dev/null +++ b/bin/ksh/tests/unclass1.t @@ -0,0 +1,97 @@ +name: xxx-quoted-newline-1 +description: + Check that \<newline> works inside of ${} +stdin: + abc=2 + echo ${ab\ + c} +expected-stdout: + 2 +--- + +name: xxx-quoted-newline-2 +description: + Check that \<newline> works at the start of a here document +stdin: + cat << EO\ + F + hi + EOF +expected-stdout: + hi +--- + +name: xxx-quoted-newline-3 +description: + Check that \<newline> works at the end of a here document +stdin: + cat << EOF + hi + EO\ + F +expected-stdout: + hi +--- + +name: xxx-multi-assignment-cmd +description: + Check that assignments in a command affect subsequent assignments + in the same command +stdin: + FOO=abc + FOO=123 BAR=$FOO + echo $BAR +expected-stdout: + 123 +--- + +name: xxx-exec-environment-1 +description: + Check to see if exec sets it's environment correctly +stdin: + FOO=bar exec printenv +expected-stdout-pattern: + /(^|.*\n)FOO=bar\n/ +--- + +name: xxx-exec-environment-2 +description: + Check to make sure exec doesn't change environment if a program + isn't exec-ed +stdin: + printenv > bar1 + FOO=bar exec; printenv > bar2 + cmp -s bar1 bar2 +--- + +name: xxx-what-do-you-call-this-1 +stdin: + echo "${foo:-"a"}*" +expected-stdout: + a* +--- + +name: xxx-prefix-strip-1 +stdin: + foo='a cdef' + echo ${foo#a c} +expected-stdout: + def +--- + +name: xxx-prefix-strip-2 +stdin: + set a c + x='a cdef' + echo ${x#$*} +expected-stdout: + def +--- + +name: xxx-variable-syntax-1 +stdin: + echo ${:} +expected-stderr-pattern: + /bad substitution/ +expected-exit: 1 +--- diff --git a/bin/ksh/tests/unclass2.t b/bin/ksh/tests/unclass2.t new file mode 100644 index 00000000000..d9e14822e06 --- /dev/null +++ b/bin/ksh/tests/unclass2.t @@ -0,0 +1,166 @@ +name: xxx-subsitution-eval-order +description: + Check order of evaluation of expressions +stdin: + i=1 x= y= + set -A A abc def GHI j G k + echo ${A[x=(i+=1)]#${A[y=(i+=2)]}} + echo $x $y +expected-stdout: + HI + 2 4 +--- + +name: xxx-set-option-1 +description: + Check option parsing in set +stdin: + set -A -vs A 1 3 2 + echo ${A[*]} +expected-stderr: + echo ${A[*]} +expected-stdout: + 1 2 3 +--- + +name: xxx-exec-1 +description: + Check that exec exits for built-ins +arguments: !-i! +stdin: + exec print hi + echo still herre +expected-stdout: + hi +expected-stderr-pattern: /.*/ +--- + +name: xxx-while-1 +description: + Check the return value of while loops + XXX need to do same for for/select/until loops +stdin: + i=x + while [ $i != xxx ] ; do + i=x$i + if [ $i = xxx ] ; then + false + continue + fi + done + echo loop1=$? + + i=x + while [ $i != xxx ] ; do + i=x$i + if [ $i = xxx ] ; then + false + break + fi + done + echo loop2=$? + + i=x + while [ $i != xxx ] ; do + i=x$i + false + done + echo loop3=$? +expected-stdout: + loop1=0 + loop2=0 + loop3=1 +--- + +name: xxx-status-1 +description: + Check that blank lines don't clear $? +arguments: !-i! +stdin: + (exit 1) + echo $? + (exit 1) + + echo $? + true +expected-stdout: + 1 + 1 +expected-stderr-pattern: /.*/ +--- + +name: xxx-status-2 +description: + Check that $? is preserved in subshells, includes, traps. +stdin: + (exit 1) + + echo blank: $? + + (exit 2) + (echo subshell: $?) + + echo 'echo include: $?' > foo + (exit 3) + . ./foo + + trap 'echo trap: $?' ERR + (exit 4) + echo exit: $? +expected-stdout: + blank: 1 + subshell: 2 + include: 3 + trap: 4 + exit: 4 +--- + +name: xxx-clean-chars-1 +description: + Check MAGIC character is stuffed correctly +stdin: + echo `echo [£` +expected-stdout: + [£ +--- + +name: xxx-param-subst-qmark-1 +description: + Check suppresion of error message with null string. According to + POSIX, it shouldn't print the error as `word' isn't ommitted. +stdin: + unset foo + x= + echo x${foo?$x} +expected-exit: 1 +expected-fail: yes +expected-stderr-pattern: !/not set/ +--- + +name: xxx-param-_-1 +description: + Check c flag is set. +arguments: !-c!echo "[$-]"! +expected-stdout-pattern: /^\[.*c.*\]$/ +--- + +name: env-prompt +description: + Check that prompt not printed when processing ENV +env-setup: !ENV=./foo! +perl-setup: + system("cat > foo << EOF + XXX=12 + PS1='X ' + false && echo hmmm + EOF + "); +arguments: !-i! +stdin: + echo hi${XXX}there +expected-stdout: + hi12there +expected-stderr: ! + X X +--- + diff --git a/bin/ksh/tests/version.t b/bin/ksh/tests/version.t new file mode 100644 index 00000000000..aed94d01760 --- /dev/null +++ b/bin/ksh/tests/version.t @@ -0,0 +1,8 @@ +name: version-1 +description: + Check version of shell. +stdin: + echo $KSH_VERSION +expected-stdout: + @(#)PD KSH v5.2.7 96/06/04 +--- |