From 9c83052f48b0469d8af5d6f1ee0f86956ca9db3c Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Wed, 4 Oct 2023 15:04:31 -0400 Subject: [PATCH] changes to several error messages; more test suite additions --- CWRU/CWRU.chlog | 12 +++ MANIFEST | 7 ++ builtins/alias.def | 6 +- builtins/exec.def | 5 +- builtins/history.def | 2 +- builtins/pushd.def | 24 +++++ builtins/read.def | 2 +- builtins/type.def | 1 + builtins/ulimit.def | 2 + general.c | 2 + subst.c | 14 ++- subst.h | 3 +- tests/alias.right | 1 + tests/alias4.sub | 7 ++ tests/array.right | 17 +-- tests/array.tests | 5 + tests/array33.sub | 5 + tests/assoc.right | 2 + tests/assoc.tests | 5 + tests/builtins.right | 48 ++++++++- tests/builtins.tests | 14 ++- tests/builtins1.sub | 4 + tests/builtins10.sub | 7 ++ tests/builtins11.sub | 45 ++++++++ tests/builtins12.sub | 40 +++++++ tests/builtins2.sub | 4 + tests/builtins8.sub | 4 + tests/case.right | 3 + tests/case.tests | 9 ++ tests/casemod.right | 2 + tests/casemod.tests | 7 +- tests/complete.right | 104 +++++++++++++++++- tests/complete.tests | 19 ++++ tests/comsub2.right | 7 ++ tests/comsub23.sub | 16 +++ tests/cond-error1.sub | 8 ++ tests/cond.right | 8 ++ tests/cond.tests | 11 ++ tests/dbg-support.right | 137 +++++++++++------------ tests/dbg-support.tests | 4 + tests/errors.right | 234 +++++++++++++++++++++------------------- tests/errors.tests | 16 +++ tests/exec.right | 19 ++-- tests/execscript | 24 +++++ tests/func.right | 32 +++++- tests/func.tests | 11 ++ tests/func5.sub | 32 +++++- tests/history.right | 22 +++- tests/history.tests | 1 + tests/history3.sub | 3 + tests/history5.sub | 16 +++ tests/invocation.right | 14 +++ tests/invocation.tests | 9 ++ tests/invocation3.sub | 25 +++++ tests/jobs.right | 39 ++++--- tests/jobs.tests | 29 ++++- tests/jobs9.sub | 14 +++ tests/lastpipe.tests | 3 + tests/nameref.right | 7 +- tests/nameref23.sub | 1 + tests/new-exp.right | 11 +- tests/new-exp10.sub | 45 ++++++-- tests/printf.right | 33 ++++-- tests/printf.tests | 11 ++ tests/printf1.sub | 6 +- tests/printf6.sub | 21 ++++ tests/read.right | 2 + tests/read2.sub | 5 + tests/read3.sub | 4 + tests/redir.right | 25 ++++- tests/redir.tests | 10 +- tests/redir12.sub | 64 ++++++++++- tests/redir13.in | 5 + tests/rsh.right | 15 +-- tests/rsh.tests | 1 + tests/run-set-x | 2 +- tests/set-x.right | 9 ++ tests/set-x.tests | 3 + tests/set-x1.sub | 3 + tests/set-x2.sub | 15 +++ tests/tilde.right | 1 + tests/tilde.tests | 1 + tests/time.tests | 14 ++- tests/trap.right | 2 + tests/trap.tests | 9 ++ tests/type.right | 1 + tests/type5.sub | 18 ++++ tests/varenv.right | 7 ++ tests/varenv14.sub | 43 ++++++++ tests/varenv21.sub | 1 + tests/vredir.right | 22 +++- tests/vredir.tests | 2 +- tests/vredir1.sub | 17 +++ tests/vredir4.sub | 18 ++++ tests/vredir7.sub | 6 ++ 95 files changed, 1332 insertions(+), 294 deletions(-) create mode 100644 tests/builtins11.sub create mode 100644 tests/builtins12.sub create mode 100644 tests/invocation3.sub create mode 100644 tests/jobs9.sub create mode 100644 tests/printf6.sub create mode 100644 tests/redir13.in create mode 100644 tests/set-x2.sub diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 7c204a1a..63145c3d 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -7693,3 +7693,15 @@ builtins/shift.def builtins/break.def - break_builtin,continue_builtin: ditto with get_numeric_arg and `--' + + 9/28 + ---- +builtins/history.def + - history_builtin: changed error message if the numeric argument to -d + is invalid + + 9/29 + ---- +subst.c + - array_length_reference: include the open bracket in the error message + passed to err_badarraysub; it looks cleaner diff --git a/MANIFEST b/MANIFEST index 16eac82f..aa96a069 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1026,6 +1026,7 @@ tests/builtins7.sub f tests/builtins8.sub f tests/builtins9.sub f tests/builtins10.sub f +tests/builtins11.sub f tests/source1.sub f tests/source2.sub f tests/source3.sub f @@ -1281,6 +1282,8 @@ tests/intl.right f tests/invocation.tests f tests/invocation.right f tests/invocation1.sub f +tests/invocation2.sub f +tests/invocation3.sub f tests/iquote.tests f tests/iquote.right f tests/iquote1.sub f @@ -1295,6 +1298,7 @@ tests/jobs5.sub f tests/jobs6.sub f tests/jobs7.sub f tests/jobs8.sub f +tests/jobs9.sub f tests/jobs.right f tests/lastpipe.right f tests/lastpipe.tests f @@ -1444,6 +1448,8 @@ tests/redir8.sub f tests/redir9.sub f tests/redir10.sub f tests/redir11.sub f +tests/redir12.sub f +tests/redir13.in f tests/rhs-exp.tests f tests/rhs-exp.right f tests/rhs-exp1.sub f @@ -1547,6 +1553,7 @@ tests/set-e3a.sub f tests/set-e.right f tests/set-x.tests f tests/set-x1.sub f +tests/set-x2.sub f tests/set-x.right f tests/shopt.tests f tests/shopt1.sub f diff --git a/builtins/alias.def b/builtins/alias.def index b75262c5..6ff4a7df 100644 --- a/builtins/alias.def +++ b/builtins/alias.def @@ -208,11 +208,7 @@ unalias_builtin (WORD_LIST *list) aflag = 0; while (list) { - alias = find_alias (list->word->word); - - if (alias) - remove_alias (alias->name); - else + if (remove_alias (list->word->word) < 0) { sh_notfound (list->word->word); aflag++; diff --git a/builtins/exec.def b/builtins/exec.def index 54dc6645..fc7bc672 100644 --- a/builtins/exec.def +++ b/builtins/exec.def @@ -98,12 +98,13 @@ mkdashname (char *name) int exec_builtin (WORD_LIST *list) { - int exit_value = EXECUTION_FAILURE; + int exit_value; int cleanenv, login, opt, orig_job_control; char *argv0, *command, **args, **env, *newname, *com2; cleanenv = login = orig_job_control = 0; exec_argv0 = argv0 = (char *)NULL; + exit_value = EXECUTION_FAILURE; reset_internal_getopt (); while ((opt = internal_getopt (list, "cla:")) != -1) @@ -227,6 +228,7 @@ exec_builtin (WORD_LIST *list) sync_buffered_stream (default_buffered_input); exit_value = shell_execve (command, args, env); + opt = errno; /* We have to set this to NULL because shell_execve has called realloc() to stuff more items at the front of the array, which may have caused @@ -239,6 +241,7 @@ exec_builtin (WORD_LIST *list) goto failed_exec; else if (executable_file (command) == 0) { + errno = opt; builtin_error (_("%s: cannot execute: %s"), command, strerror (errno)); exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */ } diff --git a/builtins/history.def b/builtins/history.def index 2b0dfdd4..7c0013bd 100644 --- a/builtins/history.def +++ b/builtins/history.def @@ -226,7 +226,7 @@ history_builtin (WORD_LIST *list) { if (legal_number (delete_arg, &delete_offset) == 0) { - sh_erange (delete_arg, _("history position")); + sh_invalidnum (delete_arg); return (EXECUTION_FAILURE); } /* check for negative offsets, count back from end of list */ diff --git a/builtins/pushd.def b/builtins/pushd.def index cc9e5d62..b328c825 100644 --- a/builtins/pushd.def +++ b/builtins/pushd.def @@ -363,6 +363,30 @@ popd_builtin (WORD_LIST *list) break; } +#if 0 + /* If we didn't find `which' but there are arguments remaining, assume we + got `--' */ + if (which_word == 0 && list) + { + if (((direction = list->word->word[0]) == '+') || direction == '-') + { + if (legal_number (list->word->word + 1, &which) == 0) + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + which_word = list->word->word; + } + else + { + builtin_error (_("%s: invalid argument"), list->word->word); + builtin_usage (); + return (EX_USAGE); + } + } +#endif + if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0)) { pushd_error (directory_list_offset, which_word ? which_word : ""); diff --git a/builtins/read.def b/builtins/read.def index 8496fe47..981f5a2f 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -459,7 +459,7 @@ read_builtin (WORD_LIST *list) #endif if (input_is_tty == 0) #ifndef __CYGWIN__ - input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); + input_is_pipe = fd_ispipe (fd); #else input_is_pipe = 1; #endif diff --git a/builtins/type.def b/builtins/type.def index ad67a938..a0d31929 100644 --- a/builtins/type.def +++ b/builtins/type.def @@ -367,6 +367,7 @@ describe_command (char *command, int dflags) probably doesn't exist. Check whether or not the command is an executable file. If it's not, don't report a match. This is the default posix mode behavior */ + /* This code path isn't executed any more as of 3/2023. */ if (STREQ (full_path, command) || posixly_correct) { f = file_status (full_path); diff --git a/builtins/ulimit.def b/builtins/ulimit.def index 11c55c91..fa527ad7 100644 --- a/builtins/ulimit.def +++ b/builtins/ulimit.def @@ -746,6 +746,7 @@ printone (int limind, RLIMTYPE curlim, int pdesc) print_rlimtype ((curlim / factor), 1); } +#ifdef NOTYET /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which causes all limits to be set as high as possible depending on mode (like csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits @@ -783,5 +784,6 @@ set_all_limits (int mode, RLIMTYPE newlim) } return retval; } +#endif /* NOTYET */ #endif /* !_MINIX */ diff --git a/general.c b/general.c index 0ca51b7d..aa965661 100644 --- a/general.c +++ b/general.c @@ -177,6 +177,8 @@ string_to_rlimtype (char *s) ret = 0; neg = 0; + /* ulimit_builtin doesn't allow leading whitespace or an optional + leading `+' or `-'. */ while (s && *s && whitespace (*s)) s++; if (s && (*s == '-' || *s == '+')) diff --git a/subst.c b/subst.c index 9f4c4e54..52ab5a9f 100644 --- a/subst.c +++ b/subst.c @@ -3449,7 +3449,7 @@ do_compound_assignment (const char *name, char *value, int flags) v = make_local_assoc_variable (newname, 0); else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context) v = make_local_array_variable (newname, 0); - r = v? assign_compound_array_list (v, list, flags) : 0; + r = v ? assign_compound_array_list (v, list, flags) : 0; if (list) dispose_words (list); if (r == 0) /* compound assignment error */ @@ -7416,11 +7416,14 @@ array_length_reference (const char *s) if (assoc_p (var)) { t[len - 1] = '\0'; - akey = expand_subscript_string (t, 0); /* [ */ + akey = expand_subscript_string (t, 0); t[len - 1] = RBRACK; if (akey == 0 || *akey == 0) { - err_badarraysub (t); + char *t1; + + t1 = (t > s) ? t - 1 : t; /* get the left bracket */ + err_badarraysub (t1); FREE (akey); return (-1); } @@ -7435,7 +7438,10 @@ array_length_reference (const char *s) ind = array_max_index (array_cell (var)) + 1 + ind; if (ind < 0) { - err_badarraysub (t); + char *t1; + + t1 = (t > s) ? t - 1 : t; /* get the left bracket */ + err_badarraysub (t1); return (-1); } if (array_p (var)) diff --git a/subst.h b/subst.h index 4ac602fb..c83bf5a2 100644 --- a/subst.h +++ b/subst.h @@ -44,7 +44,7 @@ #define Q_ARRAYSUB 0x200 /* expanding indexed array subscript */ /* Flag values controlling how assignment statements are treated. */ -#define ASS_APPEND 0x0001 +#define ASS_APPEND 0x0001 /* a+=b */ #define ASS_MKLOCAL 0x0002 #define ASS_MKASSOC 0x0004 #define ASS_MKGLOBAL 0x0008 /* force global assignment */ @@ -58,6 +58,7 @@ #define ASS_ALLOWALLSUB 0x0800 /* allow * and @ as associative array keys */ #define ASS_ONEWORD 0x1000 /* don't check array subscripts, assume higher level has done that */ #define ASS_NOTEMPENV 0x2000 /* don't assign into temporary environment */ +#define ASS_XTRACE 0x4000 /* print trace after compound assignment expansion */ /* Flags for the string extraction functions. */ #define SX_NOALLOC 0x0001 /* just skip; don't return substring */ diff --git a/tests/alias.right b/tests/alias.right index b6cc7ea6..3ab73512 100644 --- a/tests/alias.right +++ b/tests/alias.right @@ -35,6 +35,7 @@ a b a a b ok 3 ok 4 +line with escaped newline bar bad 0 diff --git a/tests/alias4.sub b/tests/alias4.sub index 0864a3c4..cd2cb1d4 100644 --- a/tests/alias4.sub +++ b/tests/alias4.sub @@ -82,6 +82,12 @@ long_comment text after # comment comment foo bar +# make sure escaped newlines in alias bodies are processed correctly +alias xx='echo line with \ +escaped newline' +xx +unalias xx + # alias ending in a tab alias foo="\ echo \"bar\" \ @@ -98,3 +104,4 @@ foo>&2 alias a='printf "<%s>\n" \' a|cat + diff --git a/tests/array.right b/tests/array.right index 846e05f7..fb08a5c1 100644 --- a/tests/array.right +++ b/tests/array.right @@ -123,15 +123,17 @@ argv[1] = 55 49 6 -- 6 +./array.tests: line 232: [-10]: bad array subscript +0 42 14 44 grep [ 123 ] * 6 7 9 6 7 9 5 length = 3 value = new1 new2 new3 -./array.tests: line 256: syntax error near unexpected token `&' -./array.tests: line 256: `badarray=( metacharacters like & need to be quoted in compound assignments)' -./array.tests: line 260: narray: unbound variable +./array.tests: line 261: syntax error near unexpected token `&' +./array.tests: line 261: `badarray=( metacharacters like & need to be quoted in compound assignments)' +./array.tests: line 265: narray: unbound variable ./array1.sub: line 1: syntax error near unexpected token `(' ./array1.sub: line 1: `printf "%s\n" -a a=(a 'b c')' ./array2.sub: line 1: declare: `[]=asdf': not a valid identifier @@ -158,10 +160,10 @@ for case if then else 12 14 16 18 20 4414758999202 aaa bbb -./array.tests: line 310: syntax error near unexpected token `<>' -./array.tests: line 310: `metas=( <> < > ! )' -./array.tests: line 311: syntax error near unexpected token `<>' -./array.tests: line 311: `metas=( [1]=<> [2]=< [3]=> [4]=! )' +./array.tests: line 315: syntax error near unexpected token `<>' +./array.tests: line 315: `metas=( <> < > ! )' +./array.tests: line 316: syntax error near unexpected token `<>' +./array.tests: line 316: `metas=( [1]=<> [2]=< [3]=> [4]=! )' abc 3 case 4 abc case if then else 5 @@ -846,3 +848,4 @@ declare -a A=([0]="x" [1]="x") declare -a A=([0]="x" [1]="x") ./array33.sub: line 46: A: cannot convert indexed to associative array declare -a A=([0]="x" [1]="x") +./array33.sub: line 52: read: A: not an indexed array diff --git a/tests/array.tests b/tests/array.tests index 10f60555..bd2ee566 100644 --- a/tests/array.tests +++ b/tests/array.tests @@ -228,6 +228,11 @@ unset xpath[nelem-1] nelem=${#xpath[@]} echo ${#xpath[@]} -- $nelem +# error +echo ${#xpath[-10]} +# zero length for unset elements +echo ${#xpath[42]} + # arrays and things that look like index assignments array=(42 [1]=14 [2]=44) diff --git a/tests/array33.sub b/tests/array33.sub index 383fc019..5eb40a46 100644 --- a/tests/array33.sub +++ b/tests/array33.sub @@ -45,3 +45,8 @@ declare -p A # error to convert indexed to associative declare -A A=([1]=1) declare -p A + +# can't read into an associative array +unset -v A +declare -A A +read -a A argv[1] = declare -A wheat=([six]="6" ["foo bar"]="qux qix" ) argv[1] = <2> +./assoc.tests: line 99: [$unset]: bad array subscript +0 argv[1] = <7> argv[1] = argv[2] = diff --git a/tests/assoc.tests b/tests/assoc.tests index 5055d5ca..07fc9b59 100644 --- a/tests/assoc.tests +++ b/tests/assoc.tests @@ -95,6 +95,11 @@ wheat=([six]=6 [foo bar]="qux qix" ) recho ${#wheat[@]} +# and error +echo ${#wheat[$unset]} +# zero length for unset element +echo ${#wheat[unset]} + recho ${#wheat[foo bar]} # TEST - appending assignment operator diff --git a/tests/builtins.right b/tests/builtins.right index 94185909..1f788774 100644 --- a/tests/builtins.right +++ b/tests/builtins.right @@ -1,4 +1,3 @@ -1000 a end-1 a @@ -84,7 +83,10 @@ enable times enable trap enable unset enable -n test worked +enable -n test enable test worked +./builtins.tests: line 126: enable: notbuiltin: not a shell builtin +./builtins.tests: line 127: enable: test: not dynamically loaded specialname -specialname FOO=BAR @@ -107,6 +109,7 @@ m n o p /tmp/bash-dir-a /tmp/bash-dir-a /tmp/bash-dir-a +/ ./source5.sub: line 23: /tmp/source-notthere: No such file or directory after bad source 1 ./source5.sub: line 30: /tmp/source-notthere: No such file or directory @@ -157,6 +160,8 @@ a b +-p +a b c before: f = 4 inside after: f = 8 bar = 4 @@ -296,6 +301,7 @@ u=rwx,g=rx,o=rx u=rwx,g=rx,o=rx u=rwx,g=rx,o=rx u=rwx,g=rx,o=rx +u=rwx,g=rx,o=x hash: hash table empty ./builtins9.sub: line 19: hash: notthere: not found 1 @@ -379,6 +385,16 @@ Shell commands matching keyword `read*' read: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] readarray: readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array] readonly: readonly [-aAf] [name[=value] ...] or readonly -p +read: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] +readarray: readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array] +readonly: readonly [-aAf] [name[=value] ...] or readonly -p +:: : + Null command. + + No effect; the command does nothing. + + Exit Status: + Always succeeds. NAME : - Null command. @@ -445,4 +461,32 @@ A star (*) next to a name means that the command is disabled. getopts optstring name [arg ...] while COMMANDS; do COMMANDS-2; done hash [-lr] [-p pathname] [-dt] [name > { COMMANDS ; } help [-dms] [pattern ...] -./builtins.tests: line 316: exit: status: numeric argument required +./builtins10.sub: line 39: help: no help topics match `bash'. Try `help help' or `man -k bash' or `info bash'. +unlimited +unlimited +./builtins11.sub: line 27: ulimit: +1999: invalid number +0 +0 +./builtins11.sub: line 37: ulimit: -q: invalid option +ulimit: usage: ulimit [-SHabcdefiklmnpqrstuvxPRT] [limit] +./builtins11.sub: line 39: ulimit: max user processes: cannot modify limit: Operation not permitted +/tmp /bin +/tmp /bin +/bin /tmp +./builtins12.sub: line 21: pushd: -x: invalid number +pushd: usage: pushd [-n] [+N | -N | dir] +/tmp +./builtins12.sub: line 24: popd: -x: invalid number +popd: usage: popd [-n] [+N | -N] +/ /tmp +./builtins12.sub: line 27: popd: dir: invalid argument +popd: usage: popd [-n] [+N | -N] +/ +/tmp +/tmp / +/bin /tmp / +./builtins12.sub: line 35: popd: -8: directory stack index out of range +./builtins12.sub: line 36: popd: +8: directory stack index out of range +/tmp / +/ +./builtins.tests: line 322: exit: status: numeric argument required diff --git a/tests/builtins.tests b/tests/builtins.tests index 781c021c..f3a8fc2b 100644 --- a/tests/builtins.tests +++ b/tests/builtins.tests @@ -15,10 +15,6 @@ set +p set +o posix -ulimit -S -c 0 2>/dev/null -ulimit -c -S -- 1000 2>/dev/null -ulimit -c 2>/dev/null - # check that break breaks loops for i in a b c; do echo $i; break; echo bad-$i; done echo end-1 @@ -119,6 +115,7 @@ case "$(type -t test)" in builtin) echo oops -- enable -n test failed ;; *) echo enable -n test worked ;; esac +enable -n | grep test enable test case "$(type -t test)" in @@ -126,6 +123,9 @@ builtin) echo enable test worked ;; *) echo oops -- enable test failed ;; esac +enable -d notbuiltin +enable -d test + # test options to exec (exec -a specialname ${THIS_SH} -c 'echo $0' ) (exec -l -a specialname ${THIS_SH} -c 'echo $0' ) @@ -307,6 +307,12 @@ ${THIS_SH} ./builtins9.sub # help tests ${THIS_SH} ./builtins10.sub +# ulimit tests +${THIS_SH} ./builtins11.sub + +# pushd/popd/dirs +${THIS_SH} ./builtins12.sub + shift 0 # succeeds silently options=$(set -o -B 2>&1 | wc -l) diff --git a/tests/builtins1.sub b/tests/builtins1.sub index 52185b54..ae3defb8 100644 --- a/tests/builtins1.sub +++ b/tests/builtins1.sub @@ -12,3 +12,7 @@ echo $PWD cd "$MYDIR" rmdir $FULLDIR + +cd / +cd /tmp +cd - # should print / diff --git a/tests/builtins10.sub b/tests/builtins10.sub index 4b9e6659..e8413f81 100644 --- a/tests/builtins10.sub +++ b/tests/builtins10.sub @@ -25,8 +25,15 @@ help -s builtin shift # this hasn't ever been very useful help -s 'read*' +# but prefix matching is +help -s rea + +help : help -m : | grep -v version LC_ALL=en_US.UTF-8 help -- | sed 1d + +# maybe sometime in the future this will do something +help -- bash diff --git a/tests/builtins11.sub b/tests/builtins11.sub new file mode 100644 index 00000000..ec841cbe --- /dev/null +++ b/tests/builtins11.sub @@ -0,0 +1,45 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ulimit tests + +ulimit unlimited # default to -f +ulimit -f # better be unlimited +ulimit -Sf hard + +corelim=${ ulimit -c; } + +# pick -c because everyone's going to have it +ulimit -Sc unlimited +ulimit -c soft +ulimit -c # unlimited +# maybe someday the leading `+' will be accepted, but not today +ulimit -c -S -- +1999 +ulimit -c -S -- 1999 +ulimit -c 0 +ulimit -Hc # hard and soft 0 +ulimit -Sc hard # should be 0 +ulimit -c + +ulimit -a >/dev/null # just make sure we have no errors + +# these are errors +ulimit -q +# have to see about this one +ulimit -u $(( 2**31 - 1 )) + +lim=$(ulimit -Sn) +ulimit -n $lim +lim2=$(ulimit -n) + +[[ $lim -eq $lim2 ]] || echo 'ulimit: setting to soft limit fails' >&2 diff --git a/tests/builtins12.sub b/tests/builtins12.sub new file mode 100644 index 00000000..89e23ec1 --- /dev/null +++ b/tests/builtins12.sub @@ -0,0 +1,40 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# pushd/popd/dirs tests + +cd /bin +pushd /tmp +dirs -- + +pushd -- +pushd -x + +popd -- +popd -x + +pushd / +popd dir # error + +dirs -p +pushd -- + +pushd /bin + +# out of range errors +popd -8 +popd +8 + +# this needs a fix to work right +popd -- +8 +popd -- -8 diff --git a/tests/builtins2.sub b/tests/builtins2.sub index e4cb32ae..9b6cb73e 100644 --- a/tests/builtins2.sub +++ b/tests/builtins2.sub @@ -8,3 +8,7 @@ echo 'a\n\n\nb' shopt -s xpg_echo echo 'a\n\n\nb' + +echo -p +set -o posix +echo 'a\tb\tc' diff --git a/tests/builtins8.sub b/tests/builtins8.sub index ffe9869b..6b35e795 100644 --- a/tests/builtins8.sub +++ b/tests/builtins8.sub @@ -79,3 +79,7 @@ umask -S umask 022 umask g+x,o+x umask -S + +umask 022 +umask u+g,g+o,o-rw +umask -S diff --git a/tests/case.right b/tests/case.right index d33c8c5a..3ff3eaf5 100644 --- a/tests/case.right +++ b/tests/case.right @@ -15,6 +15,9 @@ no no ok esac +unset word ok 1 +unset word ok 2 +unset word ok 3 ok 1 ok 2 ok 3 diff --git a/tests/case.tests b/tests/case.tests index 7ad4c683..2bb0922d 100644 --- a/tests/case.tests +++ b/tests/case.tests @@ -66,6 +66,15 @@ case " " in ( [" "] ) echo ok;; ( * ) echo no;; esac case esac in (esac) echo esac;; esac case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac +# null words and patterns +var=value +case $unset in +'') echo unset word ok 1 ;;& +$unset|$var) echo unset word ok 2 ;;& +unset|$unset) echo unset word ok 3 ;; +*) echo unset word bad ;; +esac + # tests of quote removal and pattern matching ${THIS_SH} ./case1.sub ${THIS_SH} ./case2.sub diff --git a/tests/casemod.right b/tests/casemod.right index df124754..55081a59 100644 --- a/tests/casemod.right +++ b/tests/casemod.right @@ -43,5 +43,7 @@ Be Conservative in what you send and Liberal in what you accept BE CONSERVATIVE IN WHAT YOU SEND AND LIBERAL IN WHAT YOU ACCEPT Be conservative in what you send and liberal in what you accept BE CONSERVATIVE IN WHAT YOU SEND AND LIBERAL IN WHAT YOU ACCEPT +acKnowledGEmEnt +oENoPHiLe abcdexyz ABCDEXYZ diff --git a/tests/casemod.tests b/tests/casemod.tests index 56ab20d9..a7709a5f 100644 --- a/tests/casemod.tests +++ b/tests/casemod.tests @@ -114,8 +114,11 @@ echo ${TEXT2^^} M1=${S1^^[aeiou]} M2=${U2,,[AEIOU]} -#echo ${M1} ${M1~} -#echo ${M2} ${M2~~} +# case-toggling modifiers are still in there for now +Z1=AcKnowledGEmEnt +Z2=OenOphIlE +echo ${Z1~} +echo ${Z2~~} declare -l lower=aBcDe lower+=XyZ diff --git a/tests/complete.right b/tests/complete.right index 500ec8f7..d933a22d 100644 --- a/tests/complete.right +++ b/tests/complete.right @@ -61,6 +61,13 @@ complete -d rmdir complete -f more complete -f -X '!*.+(gz|tgz)' gzcat ./complete.tests: line 123: complete: notthere: no completion specification +./complete.tests: line 130: complete: -V: invalid option +complete: usage: complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...] +./complete.tests: line 132: compgen: `invalid-name': not a valid identifier +. +unalias -- fee +unalias -- fi +unalias -- fum ! % (( ... )) @@ -138,6 +145,91 @@ variables wait while { ... } +allexport +braceexpand +emacs +errexit +errtrace +functrace +hashall +histexpand +history +ignoreeof +interactive-comments +keyword +monitor +noclobber +noexec +noglob +nolog +notify +nounset +onecmd +physical +pipefail +posix +privileged +verbose +vi +xtrace +autocd +array_expand_once +assoc_expand_once +cdable_vars +cdspell +checkhash +checkjobs +checkwinsize +cmdhist +compat31 +compat32 +compat40 +compat41 +compat42 +compat43 +compat44 +complete_fullquote +direxpand +dirspell +dotglob +execfail +expand_aliases +extdebug +extglob +extquote +failglob +force_fignore +globasciiranges +globskipdots +globstar +gnu_errfmt +histappend +histreedit +histverify +hostcomplete +huponexit +inherit_errexit +interactive_comments +lastpipe +lithist +localvar_inherit +localvar_unset +login_shell +mailwarn +no_empty_cmd_completion +nocaseglob +nocasematch +noexpand_translation +nullglob +patsub_replacement +progcomp +progcomp_alias +promptvars +restricted_shell +shift_verbose +sourcepath +varredir_close +xpg_echo . : [ @@ -282,9 +374,13 @@ time [[ ]] coproc -./complete.tests: line 136: compgen: -r: invalid option +./complete.tests: line 152: complete: -z: invalid option +complete: usage: complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...] +complete: usage: complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...] +./complete.tests: line 154: compgen: -r: invalid option compgen: usage: compgen [-V varname] [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word] -./complete.tests: line 137: compgen: noaction: invalid action name -./complete.tests: line 138: compgen: -D: invalid option +./complete.tests: line 155: compgen: noaction: invalid action name +./complete.tests: line 156: compgen: -D: invalid option compgen: usage: compgen [-V varname] [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word] -./complete.tests: line 140: compopt: nooption: invalid option name +./complete.tests: line 157: compgen: nooption: invalid option name +./complete.tests: line 159: compopt: nooption: invalid option name diff --git a/tests/complete.tests b/tests/complete.tests index e4c655ce..adb7761a 100644 --- a/tests/complete.tests +++ b/tests/complete.tests @@ -125,16 +125,35 @@ complete -r notthere complete -r complete +# new complete/compgen -V option +# doesn't work for complete +complete -V name + +compgen -V invalid-name -b +compgen -V array -b +echo ${array[0]} + +# a more complicated example +unalias -a +alias fee=one fi=two fo=three fum=four +compgen -a -X 'fo*' -V vv -P 'unalias -- ' f +printf '%s\n' "${vv[@]}" + # some random compgen topics compgen -A helptopic +builtin compgen -A setopt +compgen -A shopt command compgen -b compgen -A enabled compgen -k # and some errors +complete -z +complete -b compgen -r compgen -A noaction compgen -D +compgen -o nooption compopt -o nooption diff --git a/tests/comsub2.right b/tests/comsub2.right index cdfb27c8..3588cca7 100644 --- a/tests/comsub2.right +++ b/tests/comsub2.right @@ -92,6 +92,13 @@ after here-doc: 1 [2]+ Running sleep 1 & 17772 26794 17772 26794 +we should try rhs +comsub +and +funsub +in here-documents +after all they work here +and work here a b c == 1 2 3 == 1 2 3 before return diff --git a/tests/comsub23.sub b/tests/comsub23.sub index 8a4a5743..2edda3bf 100644 --- a/tests/comsub23.sub +++ b/tests/comsub23.sub @@ -61,3 +61,19 @@ echo $RANDOM ${ echo $RANDOM; } RANDOM=42 echo $RANDOM $RANDOM + +# here-documents and other word expansions with comsub/funsub on the rhs + +exec 4< 7 ]] diff --git a/tests/cond.tests b/tests/cond.tests index 68f16864..110f702f 100644 --- a/tests/cond.tests +++ b/tests/cond.tests @@ -229,6 +229,17 @@ del=$'\177' # allow reserved words after a conditional command just because if [[ str ]] then [[ str ]] fi +# make sure pattern matching does the right thing with CTLESC +var=$'ab\001' +[[ $var == $var ]] && echo ok c1 +[[ $var == a* ]] && echo ok c2 +[[ $var == $'ab\001' ]] && echo ok c3 + +var=$'ab\001c' +[[ $var == $var ]] && echo ok c4 +[[ $var == a* ]] && echo ok c5 +[[ $var == $'ab\001'* ]] && echo ok c6 + ${THIS_SH} ./cond-regexp1.sub ${THIS_SH} ./cond-regexp2.sub ${THIS_SH} ./cond-regexp3.sub diff --git a/tests/dbg-support.right b/tests/dbg-support.right index 6e2194aa..f5027011 100644 --- a/tests/dbg-support.right +++ b/tests/dbg-support.right @@ -1,7 +1,10 @@ -debug lineno: 74 main -debug lineno: 77 main -FUNCNAME main +0 NULL +./dbg-support.tests: line 72: caller: -z: invalid option +caller: usage: caller [expr] +debug lineno: 78 main debug lineno: 81 main +FUNCNAME main +debug lineno: 85 main debug lineno: 30 fn1 debug lineno: 31 fn1 LINENO 31 @@ -12,9 +15,9 @@ BASH_SOURCE[0] ./dbg-support.tests debug lineno: 34 fn1 FUNCNAME[0] fn1 debug lineno: 35 fn1 -debug lineno: 35 fn1 81 ./dbg-support.tests +debug lineno: 35 fn1 85 ./dbg-support.tests debug lineno: 36 fn1 -debug lineno: 36 fn1 81 main ./dbg-support.tests +debug lineno: 36 fn1 85 main ./dbg-support.tests debug lineno: 37 fn1 debug lineno: 37 fn1 debug lineno: 38 fn1 @@ -26,7 +29,7 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 30 fn1 debug lineno: 27 print_return_trap -debug lineno: 82 main +debug lineno: 86 main debug lineno: 41 fn2 debug lineno: 42 fn2 fn2 here. Calling fn1... @@ -45,7 +48,7 @@ debug lineno: 35 fn1 43 ./dbg-support.tests debug lineno: 36 fn1 debug lineno: 36 fn1 43 fn2 ./dbg-support.tests debug lineno: 37 fn1 -debug lineno: 37 fn1 82 main ./dbg-support.tests +debug lineno: 37 fn1 86 main ./dbg-support.tests debug lineno: 38 fn1 ./dbg-support.tests: line 38: caller: foo: invalid number caller: usage: caller [expr] @@ -60,7 +63,7 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 41 fn2 debug lineno: 27 print_return_trap -debug lineno: 83 main +debug lineno: 87 main debug lineno: 46 fn3 debug lineno: 47 fn3 LINENO 47 @@ -112,7 +115,7 @@ debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn debug lineno: 25 sourced_fn debug lineno: 26 sourced_fn -FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 83 +FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 87 debug lineno: 23 sourced_fn debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn @@ -137,7 +140,7 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 46 fn3 debug lineno: 27 print_return_trap -debug lineno: 84 main +debug lineno: 88 main debug lineno: 31 source SOURCED LINENO 31 debug lineno: 32 source @@ -160,7 +163,7 @@ debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn debug lineno: 25 sourced_fn debug lineno: 26 sourced_fn -FUNCNAME[1]: source called from ./dbg-support.tests at line 84 +FUNCNAME[1]: source called from ./dbg-support.tests at line 88 debug lineno: 23 sourced_fn debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn @@ -175,24 +178,24 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 16 sourced_fn debug lineno: 27 print_return_trap -debug lineno: 84 main +debug lineno: 88 main debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap -return lineno: 84 main +return lineno: 88 main debug lineno: 27 print_return_trap -debug lineno: 87 main -debug lineno: 90 main +debug lineno: 91 main +debug lineno: 94 main LINENO 31 LINENO 32 BASH_SOURCE[0] ./dbg-support.tests FUNCNAME[0] fn1 -90 ./dbg-support.tests -90 main ./dbg-support.tests +94 ./dbg-support.tests +94 main ./dbg-support.tests ./dbg-support.tests: line 38: caller: foo: invalid number caller: usage: caller [expr] -debug lineno: 91 main +debug lineno: 95 main fn2 here. Calling fn1... LINENO 31 LINENO 32 @@ -200,11 +203,11 @@ BASH_SOURCE[0] ./dbg-support.tests FUNCNAME[0] fn1 43 ./dbg-support.tests 43 fn2 ./dbg-support.tests -91 main ./dbg-support.tests +95 main ./dbg-support.tests ./dbg-support.tests: line 38: caller: foo: invalid number caller: usage: caller [expr] -debug lineno: 92 main +debug lineno: 96 main LINENO 47 BASH_SOURCE[0] ./dbg-support.tests fn3 called from file `./dbg-support.tests' at line 0 @@ -214,13 +217,13 @@ SOURCED BASH_SOURCE[0] ./dbg-support.sub SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33 FUNCNAME[1]: source called from ./dbg-support.tests at line 59 -FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 92 +FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 96 FUNCNAME[3]: main called from ./dbg-support.tests at line 0 -debug lineno: 93 main +debug lineno: 97 main fn4 here. Calling fn3... LINENO 47 BASH_SOURCE[0] ./dbg-support.tests -fn3 called from file `./dbg-support.tests' at line 93 +fn3 called from file `./dbg-support.tests' at line 97 fn4 called from file `./dbg-support.tests' at line 0 main called from file `./dbg-support.tests' at line 0 SOURCED LINENO 31 @@ -229,18 +232,18 @@ SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33 FUNCNAME[1]: source called from ./dbg-support.tests at line 59 FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 64 -FUNCNAME[3]: fn4 called from ./dbg-support.tests at line 93 +FUNCNAME[3]: fn4 called from ./dbg-support.tests at line 97 FUNCNAME[4]: main called from ./dbg-support.tests at line 0 -debug lineno: 94 main +debug lineno: 98 main SOURCED LINENO 31 SOURCED BASH_SOURCE[0] ./dbg-support.sub SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33 -FUNCNAME[1]: source called from ./dbg-support.tests at line 94 +FUNCNAME[1]: source called from ./dbg-support.tests at line 98 FUNCNAME[2]: main called from ./dbg-support.tests at line 0 -return lineno: 94 main -debug lineno: 97 main -debug lineno: 100 main +return lineno: 98 main +debug lineno: 101 main +debug lineno: 104 main debug lineno: 31 source SOURCED LINENO 31 debug lineno: 32 source @@ -263,7 +266,7 @@ debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn debug lineno: 25 sourced_fn debug lineno: 26 sourced_fn -FUNCNAME[1]: source called from ./dbg-support.tests at line 100 +FUNCNAME[1]: source called from ./dbg-support.tests at line 104 debug lineno: 23 sourced_fn debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn @@ -278,39 +281,39 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 16 sourced_fn debug lineno: 27 print_return_trap -debug lineno: 100 main +debug lineno: 104 main debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap -return lineno: 100 main +return lineno: 104 main debug lineno: 27 print_return_trap -debug lineno: 101 main -debug lineno: 104 main -debug lineno: 104 main debug lineno: 105 main debug lineno: 108 main -debug lineno: 104 main -debug lineno: 104 main -debug lineno: 105 main debug lineno: 108 main -debug lineno: 104 main -debug lineno: 104 main -debug lineno: 105 main -debug lineno: 106 main +debug lineno: 109 main +debug lineno: 112 main +debug lineno: 108 main +debug lineno: 108 main +debug lineno: 109 main +debug lineno: 112 main +debug lineno: 108 main +debug lineno: 108 main +debug lineno: 109 main +debug lineno: 110 main Hit 2 +debug lineno: 112 main debug lineno: 108 main -debug lineno: 104 main -debug lineno: 104 main -debug lineno: 114 main -SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 114 FUNCNAME[1]: main called from ./dbg-support.tests at line 0 -debug lineno: 115 main -SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 115 FUNCNAME[1]: main called from ./dbg-support.tests at line 0 -debug lineno: 116 main -debug lineno: 117 main -SOURCED FN LINENO 18 -FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 117 -FUNCNAME[1]: main called from ./dbg-support.tests at line 0 +debug lineno: 108 main +debug lineno: 118 main +SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 118 FUNCNAME[1]: main called from ./dbg-support.tests at line 0 +debug lineno: 119 main +SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 119 FUNCNAME[1]: main called from ./dbg-support.tests at line 0 +debug lineno: 120 main debug lineno: 121 main -debug lineno: 122 main +SOURCED FN LINENO 18 +FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 121 +FUNCNAME[1]: main called from ./dbg-support.tests at line 0 +debug lineno: 125 main +debug lineno: 126 main debug lineno: 16 sourced_fn debug lineno: 17 sourced_fn debug lineno: 18 sourced_fn @@ -322,7 +325,7 @@ debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn debug lineno: 25 sourced_fn debug lineno: 26 sourced_fn -FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 122 +FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 126 debug lineno: 23 sourced_fn debug lineno: 23 sourced_fn debug lineno: 24 sourced_fn @@ -337,21 +340,21 @@ debug lineno: 25 print_return_trap debug lineno: 26 print_return_trap return lineno: 16 sourced_fn debug lineno: 27 print_return_trap -debug lineno: 125 main -debug lineno: 130 main +debug lineno: 129 main debug lineno: 134 main +debug lineno: 138 main got it -debug lineno: 142 main -debug lineno: 143 main -debug lineno: 144 main -debug lineno: 143 main -debug lineno: 144 main -debug lineno: 142 main -debug lineno: 143 main -debug lineno: 144 main -debug lineno: 143 main -debug lineno: 144 main +debug lineno: 146 main +debug lineno: 147 main debug lineno: 148 main +debug lineno: 147 main +debug lineno: 148 main +debug lineno: 146 main +debug lineno: 147 main +debug lineno: 148 main +debug lineno: 147 main +debug lineno: 148 main +debug lineno: 152 main main: calling f1 f1: calling f2 f2: calling f3 diff --git a/tests/dbg-support.tests b/tests/dbg-support.tests index b4a58e4b..d07d928c 100644 --- a/tests/dbg-support.tests +++ b/tests/dbg-support.tests @@ -67,6 +67,10 @@ fn4() { # # Test of support for debugging facilities in bash # + +caller +caller -z + # Test debugger set option functrace - set on. Not in vanilla Bash 2.05 # set -o functrace diff --git a/tests/errors.right b/tests/errors.right index 76bfbf32..d8a6a17c 100644 --- a/tests/errors.right +++ b/tests/errors.right @@ -1,140 +1,150 @@ -./errors.tests: line 30: alias: -x: invalid option -alias: usage: alias [-p] [name[=value] ... ] -./errors.tests: line 31: unalias: -x: invalid option unalias: usage: unalias [-a] name [name ...] -./errors.tests: line 32: alias: hoowah: not found -./errors.tests: line 33: unalias: hoowah: not found -./errors.tests: line 36: `1': not a valid identifier -./errors.tests: line 37: `f\1': not a valid identifier -./errors.tests: line 41: `invalid-name': not a valid identifier -./errors.tests: line 43: `f\1': not a valid identifier -./errors.tests: line 46: `1': not a valid identifier -./errors.tests: line 47: `f\1': not a valid identifier -./errors.tests: line 48: `invalid-name': not a valid identifier -./errors.tests: line 50: `1': not a valid identifier -./errors.tests: line 51: `f\1': not a valid identifier -./errors.tests: line 55: `$1': not a valid identifier +./errors.tests: line 31: alias: -x: invalid option +alias: usage: alias [-p] [name[=value] ... ] +./errors.tests: line 32: unalias: -x: invalid option +unalias: usage: unalias [-a] name [name ...] +./errors.tests: line 33: alias: hoowah: not found +./errors.tests: line 34: unalias: hoowah: not found +./errors.tests: line 37: `1': not a valid identifier +./errors.tests: line 38: `f\1': not a valid identifier +./errors.tests: line 42: `invalid-name': not a valid identifier +./errors.tests: line 44: `f\1': not a valid identifier +./errors.tests: line 47: `1': not a valid identifier +./errors.tests: line 48: `f\1': not a valid identifier +./errors.tests: line 49: `invalid-name': not a valid identifier +./errors.tests: line 51: `1': not a valid identifier +./errors.tests: line 52: `f\1': not a valid identifier +./errors.tests: line 56: `$1': not a valid identifier declare -fr func -./errors.tests: line 72: func: readonly function -./errors.tests: line 75: unset: -x: invalid option +./errors.tests: line 73: func: readonly function +./errors.tests: line 76: unset: -x: invalid option unset: usage: unset [-f] [-v] [-n] [name ...] -./errors.tests: line 78: unset: func: cannot unset: readonly function -./errors.tests: line 81: declare: func: readonly function -./errors.tests: line 85: declare: -a: invalid option -./errors.tests: line 86: declare: -i: invalid option -./errors.tests: line 90: unset: XPATH: cannot unset: readonly variable -./errors.tests: line 96: unset: cannot simultaneously unset a function and a variable -./errors.tests: line 99: declare: -z: invalid option +./errors.tests: line 79: unset: func: cannot unset: readonly function +./errors.tests: line 82: declare: func: readonly function +./errors.tests: line 86: declare: -a: invalid option +./errors.tests: line 87: declare: -i: invalid option +./errors.tests: line 91: unset: XPATH: cannot unset: readonly variable +./errors.tests: line 97: unset: cannot simultaneously unset a function and a variable +./errors.tests: line 100: declare: -z: invalid option declare: usage: declare [-aAfFgiIlnrtux] [name[=value] ...] or declare -p [-aAfFilnrtux] [name ...] -./errors.tests: line 101: declare: `-z': not a valid identifier -./errors.tests: line 102: declare: `/bin/sh': not a valid identifier -./errors.tests: line 106: declare: cannot use `-f' to make functions -./errors.tests: line 109: exec: -i: invalid option +./errors.tests: line 102: declare: `-z': not a valid identifier +./errors.tests: line 103: declare: `/bin/sh': not a valid identifier +./errors.tests: line 107: declare: cannot use `-f' to make functions +./errors.tests: line 110: exec: -i: invalid option exec: usage: exec [-cl] [-a name] [command [argument ...]] [redirection ...] -./errors.tests: line 113: export: XPATH: not a function -./errors.tests: line 116: break: only meaningful in a `for', `while', or `until' loop -./errors.tests: line 117: continue: only meaningful in a `for', `while', or `until' loop -./errors.tests: line 120: shift: label: numeric argument required -./errors.tests: line 125: shift: too many arguments -./errors.tests: line 131: let: expression expected -./errors.tests: line 134: local: can only be used in a function -./errors.tests: line 137: logout: not login shell: use `exit' -./errors.tests: line 140: hash: notthere: not found -./errors.tests: line 143: hash: -v: invalid option +./errors.tests: line 117: export: XPATH: not a function +./errors.tests: line 120: break: only meaningful in a `for', `while', or `until' loop +./errors.tests: line 121: continue: only meaningful in a `for', `while', or `until' loop +./errors.tests: line 124: shift: label: numeric argument required +./errors.tests: line 129: shift: too many arguments +./errors.tests: line 135: let: expression expected +./errors.tests: line 138: local: can only be used in a function +./errors.tests: line 141: logout: not login shell: use `exit' +./errors.tests: line 144: hash: notthere: not found +./errors.tests: line 147: hash: -v: invalid option hash: usage: hash [-lr] [-p pathname] [-dt] [name ...] -./errors.tests: line 147: hash: hashing disabled -./errors.tests: line 150: export: `AA[4]': not a valid identifier -./errors.tests: line 151: readonly: `AA[4]': not a valid identifier -./errors.tests: line 152: export: `invalid-var=4': not a valid identifier -./errors.tests: line 153: readonly: `invalid-var=4': not a valid identifier -./errors.tests: line 154: export: `invalid-var': not a valid identifier -./errors.tests: line 155: readonly: `invalid-var': not a valid identifier -./errors.tests: line 158: unset: [-2]: bad array subscript -./errors.tests: line 162: AA: readonly variable -./errors.tests: line 166: AA: readonly variable -./errors.tests: line 174: shift: 5: shift count out of range -./errors.tests: line 175: shift: -2: shift count out of range -./errors.tests: line 178: shopt: no_such_option: invalid shell option name -./errors.tests: line 179: shopt: no_such_option: invalid shell option name -./errors.tests: line 180: shopt: no_such_option: invalid option name -./errors.tests: line 183: umask: 09: octal number out of range -./errors.tests: line 184: umask: `:': invalid symbolic mode character -./errors.tests: line 185: umask: `:': invalid symbolic mode operator -./errors.tests: line 188: umask: -i: invalid option +./errors.tests: line 150: hash: -d: option requires an argument +./errors.tests: line 154: hash: hashing disabled +./errors.tests: line 157: export: `AA[4]': not a valid identifier +./errors.tests: line 158: readonly: `AA[4]': not a valid identifier +./errors.tests: line 159: export: `invalid-var=4': not a valid identifier +./errors.tests: line 160: readonly: `invalid-var=4': not a valid identifier +./errors.tests: line 161: export: `invalid-var': not a valid identifier +./errors.tests: line 162: readonly: `invalid-var': not a valid identifier +./errors.tests: line 165: unset: [-2]: bad array subscript +./errors.tests: line 169: AA: readonly variable +./errors.tests: line 173: AA: readonly variable +./errors.tests: line 181: shift: 5: shift count out of range +./errors.tests: line 182: shift: -2: shift count out of range +./errors.tests: line 183: shift: 5: shift count out of range +./errors.tests: line 184: shift: -2: shift count out of range +./errors.tests: line 187: shopt: no_such_option: invalid shell option name +./errors.tests: line 188: shopt: no_such_option: invalid shell option name +./errors.tests: line 189: shopt: no_such_option: invalid option name +./errors.tests: line 192: umask: 09: octal number out of range +./errors.tests: line 193: umask: `:': invalid symbolic mode character +./errors.tests: line 194: umask: `:': invalid symbolic mode operator +./errors.tests: line 197: umask: -i: invalid option umask: usage: umask [-p] [-S] [mode] -./errors.tests: line 192: umask: `p': invalid symbolic mode character -./errors.tests: line 201: VAR: readonly variable -./errors.tests: line 204: declare: VAR: readonly variable -./errors.tests: line 205: declare: VAR: readonly variable -./errors.tests: line 207: declare: unset: not found +./errors.tests: line 201: umask: `p': invalid symbolic mode character ./errors.tests: line 210: VAR: readonly variable +./errors.tests: line 213: declare: VAR: readonly variable +./errors.tests: line 214: declare: VAR: readonly variable +./errors.tests: line 216: declare: unset: not found +./errors.tests: line 219: VAR: readonly variable comsub: -c: line 1: syntax error near unexpected token `)' comsub: -c: line 1: `: $( for z in 1 2 3; do )' comsub: -c: line 1: syntax error near unexpected token `done' comsub: -c: line 1: `: $( for z in 1 2 3; done )' -./errors.tests: line 217: cd: HOME not set -./errors.tests: line 218: cd: /tmp/xyz.bash: No such file or directory -./errors.tests: line 220: cd: OLDPWD not set -./errors.tests: line 221: cd: /bin/sh: Not a directory -./errors.tests: line 223: cd: /tmp/cd-notthere: No such file or directory -./errors.tests: line 225: cd: too many arguments +./errors.tests: line 226: cd: HOME not set +./errors.tests: line 227: cd: /tmp/xyz.bash: No such file or directory +./errors.tests: line 229: cd: OLDPWD not set +./errors.tests: line 230: cd: /bin/sh: Not a directory +./errors.tests: line 232: cd: /tmp/cd-notthere: No such file or directory +./errors.tests: line 234: cd: too many arguments bash: line 1: PWD: readonly variable 1 -./errors.tests: line 230: .: filename argument required +bash: line 1: OLDPWD: readonly variable +1 +./errors.tests: line 241: .: filename argument required .: usage: . filename [arguments] -./errors.tests: line 231: source: filename argument required +./errors.tests: line 242: source: filename argument required source: usage: source filename [arguments] -./errors.tests: line 234: .: -i: invalid option +./errors.tests: line 245: .: -i: invalid option .: usage: . filename [arguments] -./errors.tests: line 237: set: -q: invalid option +./errors.tests: line 248: set: -q: invalid option set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...] -./errors.tests: line 240: enable: sh: not a shell builtin -./errors.tests: line 240: enable: bash: not a shell builtin -./errors.tests: line 243: shopt: cannot set and unset shell options simultaneously -./errors.tests: line 246: read: -x: invalid option +./errors.tests: line 251: enable: sh: not a shell builtin +./errors.tests: line 251: enable: bash: not a shell builtin +./errors.tests: line 254: shopt: cannot set and unset shell options simultaneously +./errors.tests: line 257: read: -x: invalid option read: usage: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] -./errors.tests: line 249: read: var: invalid timeout specification -./errors.tests: line 252: read: `/bin/sh': not a valid identifier -./errors.tests: line 253: read: `/bin/sh': not a valid identifier -./errors.tests: line 256: VAR: readonly variable -./errors.tests: line 259: read: XX: invalid file descriptor specification -./errors.tests: line 260: read: 42: invalid file descriptor: Bad file descriptor -./errors.tests: line 263: mapfile: XX: invalid file descriptor specification -./errors.tests: line 264: mapfile: 42: invalid file descriptor: Bad file descriptor -./errors.tests: line 268: mapfile: empty array variable name -./errors.tests: line 269: mapfile: `invalid-var': not a valid identifier -./errors.tests: line 272: readonly: -x: invalid option +./errors.tests: line 260: read: var: invalid timeout specification +./errors.tests: line 263: read: `/bin/sh': not a valid identifier +./errors.tests: line 264: read: `/bin/sh': not a valid identifier +./errors.tests: line 265: read: `invalid-name': not a valid identifier +./errors.tests: line 268: VAR: readonly variable +./errors.tests: line 271: read: XX: invalid file descriptor specification +./errors.tests: line 272: read: 42: invalid file descriptor: Bad file descriptor +./errors.tests: line 275: mapfile: XX: invalid file descriptor specification +./errors.tests: line 276: mapfile: 42: invalid file descriptor: Bad file descriptor +./errors.tests: line 280: mapfile: empty array variable name +./errors.tests: line 281: mapfile: `invalid-var': not a valid identifier +./errors.tests: line 284: readonly: -x: invalid option readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p -./errors.tests: line 275: eval: -i: invalid option +./errors.tests: line 287: eval: -i: invalid option eval: usage: eval [arg ...] -./errors.tests: line 276: command: -i: invalid option +./errors.tests: line 288: command: -i: invalid option command: usage: command [-pVv] command [arg ...] -./errors.tests: line 279: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0") -./errors.tests: line 280: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0") -./errors.tests: line 283: trap: NOSIG: invalid signal specification -./errors.tests: line 286: trap: -s: invalid option +./errors.tests: line 291: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0") +./errors.tests: line 292: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0") +./errors.tests: line 295: trap: NOSIG: invalid signal specification +./errors.tests: line 298: trap: -s: invalid option trap: usage: trap [-Plp] [[action] signal_spec ...] -./errors.tests: line 292: return: can only `return' from a function or sourced script -./errors.tests: line 296: break: 0: loop count out of range -./errors.tests: line 300: continue: 0: loop count out of range -./errors.tests: line 305: builtin: bash: not a shell builtin -./errors.tests: line 309: bg: no job control -./errors.tests: line 310: fg: no job control -./errors.tests: line 313: kill: -s: option requires an argument -./errors.tests: line 315: kill: S: invalid signal specification -./errors.tests: line 317: kill: `': not a pid or valid job spec +./errors.tests: line 304: return: can only `return' from a function or sourced script +./errors.tests: line 308: break: 0: loop count out of range +./errors.tests: line 312: continue: 0: loop count out of range +./errors.tests: line 317: builtin: -x: invalid option +builtin: usage: builtin [shell-builtin [arg ...]] +./errors.tests: line 320: builtin: bash: not a shell builtin +./errors.tests: line 324: bg: no job control +./errors.tests: line 325: fg: no job control kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] -./errors.tests: line 321: kill: SIGBAD: invalid signal specification -./errors.tests: line 323: kill: BAD: invalid signal specification -./errors.tests: line 325: kill: @12: arguments must be process or job IDs -./errors.tests: line 328: unset: BASH_LINENO: cannot unset -./errors.tests: line 328: unset: BASH_SOURCE: cannot unset -./errors.tests: line 331: set: trackall: invalid option name -./errors.tests: line 332: set: -q: invalid option +./errors.tests: line 329: kill: -s: option requires an argument +./errors.tests: line 331: kill: S: invalid signal specification +./errors.tests: line 333: kill: `': not a pid or valid job spec +kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] +./errors.tests: line 337: kill: SIGBAD: invalid signal specification +./errors.tests: line 339: kill: BAD: invalid signal specification +./errors.tests: line 341: kill: @12: arguments must be process or job IDs +./errors.tests: line 344: unset: BASH_LINENO: cannot unset +./errors.tests: line 344: unset: BASH_SOURCE: cannot unset +./errors.tests: line 347: set: trackall: invalid option name +./errors.tests: line 348: set: -q: invalid option set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...] -./errors.tests: line 333: set: -i: invalid option +./errors.tests: line 349: set: -i: invalid option set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...] -./errors.tests: line 337: xx: readonly variable +./errors.tests: line 353: xx: readonly variable 1 ./errors1.sub: line 14: .: -i: invalid option .: usage: . filename [arguments] @@ -267,4 +277,4 @@ sh: line 1: unset: `a-b': not a valid identifier sh: line 1: /nosuchfile: No such file or directory sh: line 1: trap: SIGNOSIG: invalid signal specification after trap -./errors.tests: line 376: `!!': not a valid identifier +./errors.tests: line 392: `!!': not a valid identifier diff --git a/tests/errors.tests b/tests/errors.tests index 5f45cfd3..d33bfa08 100644 --- a/tests/errors.tests +++ b/tests/errors.tests @@ -24,6 +24,7 @@ set +e set +o posix # various alias/unalias errors +unalias # at some point, this may mean to `export' an alias, like ksh, but # for now it is an error @@ -108,6 +109,9 @@ declare -f func='() { echo "this is func"; }' # bad option to exec -- this should not exit the script exec -i /bin/sh +# trying to exec non-executable file is a fatal error +( exec ./errors1.sub 2>/dev/null ; echo after failed exec ) + # try to export -f something that is not a function -- this should be # an error, not create an `invisible function' export -f XPATH @@ -142,6 +146,9 @@ hash notthere # bad option to hash, although it may mean `verbose' at some future point hash -v +# hash -d requires an argument +hash -d + # turn off hashing, then try to hash something set +o hashall hash -p ${THIS_SH} ${THIS_SH##*/} @@ -173,6 +180,8 @@ AA=(one two three) shopt -s shift_verbose shift $(( $# + 5 )) shift -2 +shift -- $(( $# + 5 )) +shift -- -2 # bad shell options shopt -s no_such_option @@ -225,6 +234,8 @@ cd - cd one two three # cd doesn't like it if PWD is readonly ${THIS_SH} -c 'readonly PWD ; cd / ; echo $?' bash +# or if OLDPWD is readonly +${THIS_SH} -c 'readonly OLDPWD ; cd / ; echo $?' bash # various `source/.' errors . @@ -251,6 +262,7 @@ read -t var < /dev/null # try to read into an invalid identifier read /bin/sh < /dev/null read A /bin/sh < /dev/null +read -a invalid-name < /dev/null # try to read into a readonly variable read VAR < /dev/null @@ -301,6 +313,9 @@ for z in 1 2 3; do echo $x done +# invalid option +builtin -x + # builtin with non-builtin builtin bash @@ -310,6 +325,7 @@ bg fg # argument required +kill kill -s # bad argument kill -S diff --git a/tests/exec.right b/tests/exec.right index 3a246999..dd191330 100644 --- a/tests/exec.right +++ b/tests/exec.right @@ -5,13 +5,14 @@ after exec1.sub with args: 0 after exec1.sub without args: 0 after exec1.sub: one two three -./execscript: line 21: notthere: command not found +./execscript: line 37: notthere: command not found 127 +we would do something here with notthere /tmp/bash: notthere: No such file or directory 127 /bin/sh: /bin/sh: cannot execute binary file 126 -./execscript: line 40: /: Is a directory +./execscript: line 64: /: Is a directory 126 /: /: Is a directory 126 @@ -19,7 +20,7 @@ bash: line 1: exec: .: cannot execute: Is a directory posix-bash: line 1: exec: .: cannot execute: Is a directory bash: line 1: exec: .: cannot execute: Is a directory posix-bash: line 1: exec: .: cannot execute: Is a directory -./execscript: line 55: .: /: is a directory +./execscript: line 79: .: /: is a directory 1 126 0 @@ -35,17 +36,17 @@ trap -- '' SIGTERM trap -- 'echo USR1' SIGUSR1 USR1 EXIT -./execscript: line 79: notthere: command not found +./execscript: line 103: notthere: command not found 127 -./execscript: line 81: notthere: command not found +./execscript: line 105: notthere: command not found 127 -./execscript: line 83: notthere: command not found +./execscript: line 107: notthere: command not found 127 -./execscript: line 89: notthere: command not found +./execscript: line 113: notthere: command not found 127 -./execscript: line 91: notthere: command not found +./execscript: line 115: notthere: command not found 127 -./execscript: line 93: notthere: command not found +./execscript: line 117: notthere: command not found 127 this is sh this is sh diff --git a/tests/execscript b/tests/execscript index e797c9fc..1e2117e6 100644 --- a/tests/execscript +++ b/tests/execscript @@ -1,3 +1,16 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# export LC_ALL=C export LANG=C @@ -5,6 +18,9 @@ if [ $UID -eq 0 ]; then echo "execscript: the test suite should not be run as root" >&2 fi +# this should succeed silently +$cmd & + set -- one two three echo before exec1.sub: "$@" echo calling exec1.sub @@ -21,6 +37,14 @@ export PATH notthere echo $? +# now let's set up a command-not-found hook +command_not_found_handle() +{ + echo we would do something here with $1 +} +notthere a b c +unset -f command_not_found_handle + # this is iffy, since the error messages may vary from system to system # and /tmp might not exist ln -s ${THIS_SH} /tmp/bash 2>/dev/null diff --git a/tests/func.right b/tests/func.right index f5341351..9cbb34d1 100644 --- a/tests/func.right +++ b/tests/func.right @@ -184,11 +184,41 @@ function a=2 () printf "FUNCNAME: %s\n" $FUNCNAME } FUNCNAME: a=2 +<(:) +<(:) is a function +<(:) () +{ + echo $FUNCNAME +} break is a function break () { echo FUNCNAME: $FUNCNAME } FUNCNAME: break -./func5.sub: line 54: `break': is a special builtin +break is a function +break () +{ + echo FUNCNAME: $FUNCNAME +} +break +./func5.sub: line 69: `break': is a special builtin +./func5.sub: line 75: `!!': not a valid identifier +!! is a function +!! () +{ + fc -s "$@" +} +!! is a function +function !! () +{ + fc -s "$@" +} 5 +rfunc () +{ + local -; + local var; + local -p +} +declare -fr rfunc diff --git a/tests/func.tests b/tests/func.tests index 2c0746cf..1a753af7 100644 --- a/tests/func.tests +++ b/tests/func.tests @@ -199,4 +199,15 @@ segv() segv echo $? +# functions can have attributes +rfunc() +{ + local - + local var + + local -p +} +readonly -f rfunc +readonly -f + exit 0 diff --git a/tests/func5.sub b/tests/func5.sub index ef43de21..43e2c522 100644 --- a/tests/func5.sub +++ b/tests/func5.sub @@ -37,6 +37,13 @@ set +o posix a\=2 +<(:) () +{ + echo $FUNCNAME +} +\<\(:\) +type '<(:)' + break() { echo FUNCNAME: $FUNCNAME @@ -44,11 +51,32 @@ break() type break \break +# you can print them in posix mode +set -o posix +# posix mode should find special builtins first +type break +declare -F break +set +o posix unset -f break -# but in posix mode, declaring such a function is an error -set -o posix +# but in posix mode, declaring such a function is a fatal error +( set -o posix break() { echo FUNCNAME: $FUNCNAME } +echo after +) + +# in posix mode, functions whose names are invalid identifiers are fatal errors +( set -o posix +!! () { fc -s "$@" ; } +type \!\! +) + +# but you can create such functions and print them in posix mode +!! () { fc -s "$@" ; } +type '!!' +set -o posix +type '!!' +set +o posix diff --git a/tests/history.right b/tests/history.right index 7402bacd..46b12ed3 100644 --- a/tests/history.right +++ b/tests/history.right @@ -97,7 +97,7 @@ line 2 for history 6 HISTFILE=$TMPDIR/newhistory 7 echo displaying \$HISTFILE after history -a 8 cat $HISTFILE -./history.tests: line 90: fc: no command found +./history.tests: line 91: fc: no command found 15 echo line 2 for history 16 unset HISTSIZE 17 unset HISTFILE @@ -107,7 +107,7 @@ echo xx xb xc xx xb xc echo 44 48 4c 44 48 4c -./history.tests: line 105: fc: no command found +./history.tests: line 106: fc: no command found aa bb cc @@ -180,6 +180,8 @@ i 4 echo g 5 echo h +./history3.sub: line 48: history: @42: invalid number +./history3.sub: line 49: history: @42: numeric argument required 0 1 @@ -266,6 +268,22 @@ out of range 3 12 echo out of range 3 out of range 4 13 fc -l 1 99 +a +b +c +# out of range specs aren't errors +echo a +a +d +e +1 echo a +2 echo b +3 echo c +4 # out of range specs aren't errors +5 # out of range specs aren't errors +6 echo a +7 echo d +8 echo e 1 2 3 diff --git a/tests/history.tests b/tests/history.tests index 4cc078dd..baa835d5 100644 --- a/tests/history.tests +++ b/tests/history.tests @@ -50,6 +50,7 @@ history -s "echo line for history" history history -p '!!' +history -p # this succeeds silently fc -nl diff --git a/tests/history3.sub b/tests/history3.sub index d8a22038..6bc06757 100644 --- a/tests/history3.sub +++ b/tests/history3.sub @@ -45,5 +45,8 @@ history -d 5-0xaf history ; echo +history -d @42 +history @42 + unset HISTFILE exit 0 diff --git a/tests/history5.sub b/tests/history5.sub index 245c28d0..5a89c79f 100644 --- a/tests/history5.sub +++ b/tests/history5.sub @@ -54,4 +54,20 @@ fc -l 1 99 echo out of range 4 fc -l -20 -40 +HISTSIZE=10 +history -c + +echo a +echo b +echo c + +# out of range specs aren't errors +fc -e - 48 +fc -s -- -42 + +echo d +echo e + +fc -l + unset HISTFILE # suppress writing history file diff --git a/tests/invocation.right b/tests/invocation.right index 885a4df1..6f2a3d7f 100644 --- a/tests/invocation.right +++ b/tests/invocation.right @@ -83,7 +83,21 @@ hashall:interactive-comments braceexpand:hashall:interactive-comments:noglob braceexpand:hashall:interactive-comments:noglob ./invocation2.sub: line 50: SHELLOPTS: readonly variable +for i in 1 2 3; +do + select var in a b c; + do + echo $REPLY; + done <<< a; echo answer was $REPLY; +done + +for ((i=1; i <= 3; i++ )) +do + echo $(( 2**$i )); +done + a a bad-interp ./invocation.tests: ./x23: nosuchfile: bad interpreter: No such file or directory +cannot execute binary file diff --git a/tests/invocation.tests b/tests/invocation.tests index 84c908ea..4f9cab37 100644 --- a/tests/invocation.tests +++ b/tests/invocation.tests @@ -38,6 +38,11 @@ ${THIS_SH} ./invocation1.sub # SHELLOPTS ${THIS_SH} ./invocation2.sub +# rudimentary pretty-print tests +${THIS_SH} ./invocation3.sub + +${THIS_SH} --login -c 'logout' + : ${TMPDIR:=/tmp} TDIR=$TMPDIR/invocation-$$ mkdir $TDIR || exit 1 @@ -63,5 +68,9 @@ command cd -L $TDIR # but this results in a bad-interpreter error ./x23 +# this should result in a cannot execute binary file error since ls is in $PATH +PATH=/bin:/usr/bin +${THIS_SH} ls |& sed 's|^.*: ||' + cd $SAVEPWD rm -rf $TDIR diff --git a/tests/invocation3.sub b/tests/invocation3.sub new file mode 100644 index 00000000..d764a1e0 --- /dev/null +++ b/tests/invocation3.sub @@ -0,0 +1,25 @@ +: ${THIS_SH:=./bash} ${TMPDIR:=/tmp} + +# start at tests for pretty-print mode +# so far these are cases that aren't handled by the printing code anywhere +# else in the test suite + +SCRIPT=$TMPDIR/pretty-print-$$ + +cat >$SCRIPT <<\EOF +for i in 1 2 3 +{ + select var in a b c; { echo $REPLY; } <<&2 exec 2>/dev/null -kill -n 9 $pid -wait # make sure we reap the processes while stderr is still redirected -exec 2>&5 +kill -n9 $pid +wait $pid # make sure we reap the processes while stderr is still redirected +sleep 30 & +pid2=$! +kill -sHUP $pid2 +wait $pid2 +exec 2>&5 +unset -v pid pid2 + +# echo wait-for-pid sleep 4 & wait $! @@ -210,5 +220,14 @@ kill -STOP %1 sleep 2 # give time for the shell to get the stop notification echo after KILL -STOP, foregrounding %1 fg %1 - echo done + +# these are all errors + +set +m + +jobs -q + +suspend -z +suspend +suspend -- diff --git a/tests/jobs9.sub b/tests/jobs9.sub new file mode 100644 index 00000000..74d2d2c2 --- /dev/null +++ b/tests/jobs9.sub @@ -0,0 +1,14 @@ +# When the shell is waiting, by means of the wait utility, for asynchronous +# commands to complete, the reception of a signal for which a trap has been +# set shall cause the wait utility to return immediately with an exit status +# >128, immediately after which the trap associated with that signal shall be +# taken. + +trap 'echo got $(kill -l $BASH_TRAPSIG)' USR1 + +sleep 10 & +( sleep 2 ; kill -USR1 $$ ) & + +# should be interrupted by the signal +wait +[[ $? -gt 128 ]] || echo 'wait status not greater than 128' diff --git a/tests/lastpipe.tests b/tests/lastpipe.tests index f9d669dd..2fc5e8e6 100644 --- a/tests/lastpipe.tests +++ b/tests/lastpipe.tests @@ -65,6 +65,9 @@ echo $? -- ${PIPESTATUS[@]} true | binfalse | true echo $? -- ${PIPESTATUS[@]} + +binfalse | true | true | VAR=42 +echo $? $VAR set +o pipefail ${THIS_SH} ./lastpipe1.sub diff --git a/tests/nameref.right b/tests/nameref.right index 419bbe14..31b84afd 100644 --- a/tests/nameref.right +++ b/tests/nameref.right @@ -533,17 +533,18 @@ declare -a array=([0]="zero") declare -a array=([0]="one" [1]="two" [2]="three") declare -ai a=([0]="5") declare -ai a=([0]="6") +declare -ai a=([0]="42") declare -ai a=([0]="1") -./nameref23.sub: line 15: declare: b: not found +./nameref23.sub: line 16: declare: b: not found declare -ai a=([0]="1") declare -- b="1" declare -ai a=([0]="1") declare -- b="11" declare -ai a=([0]="1") declare -- b="110" -./nameref23.sub: line 25: declare: `1': invalid variable name for name reference +./nameref23.sub: line 26: declare: `1': invalid variable name for name reference declare -ai a=([0]="1") -./nameref23.sub: line 27: declare: b: not found +./nameref23.sub: line 28: declare: b: not found declare -ai a=([0]="4") declare -in b="a[0]" declare -ai a=([0]="6") diff --git a/tests/nameref23.sub b/tests/nameref23.sub index 358c381e..f751bb6e 100644 --- a/tests/nameref23.sub +++ b/tests/nameref23.sub @@ -5,6 +5,7 @@ declare -n b='a[0]' b+=1 ; declare -p a declare b+=1 ; declare -p a +declare b=42 ; declare -p a unset a b unset -n b diff --git a/tests/new-exp.right b/tests/new-exp.right index 8aa4b324..971bba34 100644 --- a/tests/new-exp.right +++ b/tests/new-exp.right @@ -626,7 +626,6 @@ bash: line 1: ${x@C}: bad substitution <'ab cd'> <'4'> <'ab cd'> <> -argv[1] = < > <' \t\n'> @@ -649,7 +648,15 @@ i declare -i foo A declare -A foo -./new-exp10.sub: line 118: ${V@}: bad substitution +LOWER +Lower +argv[1] = +argv[1] = <~$ > +argv[1] = <^A[0]~$ > +argv[1] = <^A^G^B[0:1]~\$ > +argv[1] = +argv[1] = <1^J/ bash$ > +./new-exp10.sub: line 149: ${V@}: bad substitution abcxxxdef abcÃ¥def ḅć diff --git a/tests/new-exp10.sub b/tests/new-exp10.sub index 5b199d4f..03f1b695 100644 --- a/tests/new-exp10.sub +++ b/tests/new-exp10.sub @@ -42,13 +42,6 @@ printf "<%s> " "${z@Q}" ; echo # empty string? recho ${z@Q} # this disappears -# -HOST=host -SHELL_LEVEL=2 -NPS1='\[\]${HOST}($SHELL_LEVEL)[\v]\$ ' - -recho "${NPS1@P}" - # D=' \t\n' printf "<%s>" "${D@E}" ; echo @@ -114,5 +107,43 @@ echo ${foo@a} declare -p foo +unset -v foo +foo=lower +echo ${foo@U} +echo ${foo@u} + +# framework for testing prompt expansions using @P transformation +cd /tmp + +HOST=host +SHELL_LEVEL=2 +HOME=$PWD + +NPS1='\[\]${HOST}($SHELL_LEVEL)[\v]\$ ' +recho "${NPS1@P}" + +NPS1='\[\]\W\$\040' +recho "${NPS1@P}" + +NPS1='\[\001\][\j]\w\$\040' +recho "${NPS1@P}" + +NPS1='\[\a\][\j:\!]\w\\\$\040' +set -o emacs +recho "${NPS1@P}" +set +o emacs + +cd / +# no longer abbreviate as ~ +NPS1='\W \s\$\040' +recho "${NPS1@P}" + +set -o posix +NPS1='!\n\W \s\$\040' +recho "${NPS1@P}" + +cd $OLDPWD + +# this must be last, fatal error V=42 echo ${V@} # error diff --git a/tests/printf.right b/tests/printf.right index b5765c91..9253ef61 100644 --- a/tests/printf.right +++ b/tests/printf.right @@ -1,5 +1,10 @@ printf: usage: printf [-v var] format [arguments] printf: usage: printf [-v var] format [arguments] +./printf.tests: line 26: printf: -x: invalid option +printf: usage: printf [-v var] format [arguments] +./printf.tests: line 29: printf: `invalid-var': not a valid identifier +abc +./printf.tests: line 30: printf: `invalid-var': not a valid identifier 10 one one\ctwo @@ -33,7 +38,7 @@ A7 --\"abcd\"-- --\'abcd\'-- --a\x-- -./printf.tests: line 105: printf: missing hex digit for \x +./printf.tests: line 112: printf: missing hex digit for \x --\x-- ---- ---- @@ -94,12 +99,12 @@ A7 26 26 26 -./printf.tests: line 229: printf: `%10': missing format character -./printf.tests: line 230: printf: `M': invalid format character -ab./printf.tests: line 233: printf: `y': invalid format character -./printf.tests: line 236: printf: GNU: invalid number +./printf.tests: line 236: printf: `%10': missing format character +./printf.tests: line 237: printf: `M': invalid format character +ab./printf.tests: line 240: printf: `y': invalid format character +./printf.tests: line 243: printf: GNU: invalid number 0 -./printf.tests: line 237: printf: GNU: invalid number +./printf.tests: line 244: printf: GNU: invalid number 0 - (foo )(bar ) @@ -152,9 +157,9 @@ b xx xx < >< > -./printf.tests: line 341: printf: 9223372036854775825: Result too large +./printf.tests: line 348: printf: 9223372036854775825: Result too large 9223372036854775807 -./printf.tests: line 342: printf: -9223372036854775815: Result too large +./printf.tests: line 349: printf: -9223372036854775815: Result too large -9223372036854775808 one one\ctwo @@ -325,3 +330,15 @@ hello -- hello -- 123 -- 6 -- +M-^GಳಿM-^UM-^FM-^WಳM-^A +M-^Gಳ +M-^G +M-^Gಳ + M-^Gಳ +M-^Gಳ --- +M-^G +M-^G +M-^G +M-^G + M-^G +M-^G --- diff --git a/tests/printf.tests b/tests/printf.tests index ee668cc9..f334f8b1 100644 --- a/tests/printf.tests +++ b/tests/printf.tests @@ -22,6 +22,13 @@ printf -- printf "" printf -- "" +# this is an error +printf -x + +# these are errors +printf -v invalid-var 'abc\n' +printf '%s\n%n' abc invalid-var + # in the future this may mean to put the output into VAR, but for # now it is an error # 2005-03-15 no longer an error @@ -341,9 +348,13 @@ TOOSMALL=-9223372036854775815 printf '%d\n' "$TOOBIG" printf '%d\n' "$TOOSMALL" +# invalid variable name + # tests variable assignment with -v ${THIS_SH} ./printf1.sub ${THIS_SH} ./printf2.sub ${THIS_SH} ./printf3.sub ${THIS_SH} ./printf4.sub ${THIS_SH} ./printf5.sub +# multibyte characters with %ls/%S and %lc/%C +${THIS_SH} ./printf6.sub diff --git a/tests/printf1.sub b/tests/printf1.sub index 7a18a5c6..38c5c4e4 100644 --- a/tests/printf1.sub +++ b/tests/printf1.sub @@ -162,7 +162,7 @@ printf "%s" "$vv" printf -v vv "%*b\n" 6 4.4BSD printf "%s" "$vv" -# we handle this crap with homemade code in printf -v vv.def +# we handle this crap with homemade code in printf printf -v vv "%10b\n" 4.4BSD printf "%s" "$vv" printf -v vv -- "--%-10b--\n" 4.4BSD @@ -228,7 +228,7 @@ printf "%s" "$vv" printf -v vv "%6.2g\n" 4.2 printf "%s" "$vv" -# test some of the more esoteric features of POSIX.1 printf -v vv +# test some of the more esoteric features of POSIX.1 printf printf -v vv "%d\n" "'string'" printf "%s" "$vv" printf -v vv "%d\n" '"string"' @@ -297,7 +297,7 @@ printf "%s" "$vv" printf -v vv "%10" printf -v vv "ab%Mcd\n" -# this caused an infinite loop in older versions of printf -v vv +# this caused an infinite loop in older versions of printf printf -v vv "%y" 0 # these should print a warning and `0', according to POSIX.2 diff --git a/tests/printf6.sub b/tests/printf6.sub new file mode 100644 index 00000000..09ee689e --- /dev/null +++ b/tests/printf6.sub @@ -0,0 +1,21 @@ +# test %ls and %lc with multibyte characters + +V=ಇಳಿಕೆಗಳು +V2=${V:0:2} +V3=${V:0:1} + +printf "%ls\n" "$V" +printf "%ls\n" "$V2" +printf "%lc\n" "$V" +printf "%.2ls\n" "$V" + +printf "%4.2ls\n" "$V" +printf "%-4.2ls---\n" "$V" + +printf "%ls\n" "$V3" +printf "%S\n" "$V3" +printf "%lc\n" "$V3" +printf "%C\n" "$V3" + +printf "%4.2lc\n" "$V3" +printf "%-4.2lc---\n" "$V3" diff --git a/tests/read.right b/tests/read.right index 5f672679..557d47e6 100644 --- a/tests/read.right +++ b/tests/read.right @@ -45,6 +45,7 @@ unset or null 3 ./read2.sub: line 45: read: -3: invalid timeout specification 1 +abcde abcde abcde ./read3.sub: line 17: read: -1: invalid number @@ -53,6 +54,7 @@ defg ab abc # +0 while read -u 3 var do echo "$var" diff --git a/tests/read2.sub b/tests/read2.sub index 9d666c4b..bc26ac6d 100644 --- a/tests/read2.sub +++ b/tests/read2.sub @@ -70,3 +70,8 @@ done cd $OLDPWD rm -f $TMPDIR/a.pipe # paranoia + +TMOUT=.001 +read a <</dev/null 2>&1 + echo abc > /tmp/redir-test cat /tmp/redir-test @@ -205,7 +208,7 @@ ${THIS_SH} ./redir7.sub ${THIS_SH} ./redir8.sub exec 9>&2 -command exec 2>$TMPDIR/foo-$$ +command exec 2>>$TMPDIR/foo-$$ echo whatsis >&2 echo cat /tmp/foo cat $TMPDIR/foo-$$ @@ -214,7 +217,8 @@ exec 2>&9 exec 9>&- ${THIS_SH} ./redir9.sub - ${THIS_SH} ./redir10.sub - ${THIS_SH} ./redir11.sub +${THIS_SH} ./redir12.sub + +${THIS_SH} < ./redir13.in diff --git a/tests/redir12.sub b/tests/redir12.sub index 66376235..7e1f3eea 100644 --- a/tests/redir12.sub +++ b/tests/redir12.sub @@ -1,5 +1,59 @@ -umask 0777 -cat <<' HERE' -look ma, no permissions -HERE -cat <<<"it's a miracle" +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# failing redirections with various compound commands and their effect on +# set -e and the ERR trap + +: ${TMPDIR:=/tmp} +TDIR=$TMPDIR/redir-fail-$$ +mkdir $TDIR +cd $TDIR || exit 1 + +touch unwritable-file unreadable-file +chmod a-w unwritable-file +chmod a-r unreadable-file + +while [ -z "x" ]; do x=4; done > unwritable-file +echo $? x = $x + +set -o noclobber +while [ -z "x" ]; do x=4; done > unwritable-file +echo $? x = $x +# test priority of noclobber and permission denied +while [ -z "x" ]; do x=4; done >| unwritable-file +echo $? x = $x +set +o noclobber + +while [ -z "x" ]; do x=4; done < unreadable-file + +# ERR trap is not fatal unless set -e is also enabled +(trap 'echo got error ERR' ERR +# have to undo redirections on redirection error +while [ -z "x" ]; do x=4; done unwritable-file +echo after ERR trap: $?) + +(set -e +for f in 1 2; do x=4; done > unwritable-file +echo after set -e: $?) + +(set -e +trap 'echo got error ERR' ERR +for f in 1 2; do x=4; done < unreadable-file +echo after set -e with ERR trap: $?) + +# the subshell never gets executed +( echo wow this is bad ) < unreadable-file + +cd $OLDPWD +rm -rf $TDIR diff --git a/tests/redir13.in b/tests/redir13.in new file mode 100644 index 00000000..bbcf84cf --- /dev/null +++ b/tests/redir13.in @@ -0,0 +1,5 @@ +# this should be used as standard input to the shell +exec 4<&0 +cd /tmp +command pwd +exec 4<&- diff --git a/tests/rsh.right b/tests/rsh.right index 5f64049b..e9a4ae6a 100644 --- a/tests/rsh.right +++ b/tests/rsh.right @@ -8,12 +8,13 @@ ./rsh.tests: line 26: PATH: readonly variable ./rsh.tests: line 27: SHELL: readonly variable ./rsh.tests: line 28: /bin/sh: restricted: cannot specify `/' in command names -./rsh.tests: line 30: .: ./source.sub3: restricted -./rsh.tests: line 33: /tmp/restricted: restricted: cannot redirect output -./rsh.tests: line 37: /tmp/restricted: restricted: cannot redirect output -./rsh.tests: line 42: command: -p: restricted -./rsh.tests: line 44: set: +r: invalid option +./rsh.tests: line 29: /bin/cat: restricted: cannot specify `/' in command names +./rsh.tests: line 31: .: ./source.sub3: restricted +./rsh.tests: line 34: /tmp/restricted: restricted: cannot redirect output +./rsh.tests: line 38: /tmp/restricted: restricted: cannot redirect output +./rsh.tests: line 43: command: -p: restricted +./rsh.tests: line 45: set: +r: invalid option set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...] -./rsh.tests: line 45: set: restricted: invalid option name -./rsh.tests: line 47: exec: restricted +./rsh.tests: line 46: set: restricted: invalid option name +./rsh.tests: line 48: exec: restricted ./rsh.tests: after exec diff --git a/tests/rsh.tests b/tests/rsh.tests index 0d06fa1e..491608bf 100644 --- a/tests/rsh.tests +++ b/tests/rsh.tests @@ -26,6 +26,7 @@ cd / PATH=$PATH:/usr/local/bin SHELL=/bin/sh /bin/sh -c 'echo /bin/sh executed' +/bin/cat foo | cat . ./source.sub3 diff --git a/tests/run-set-x b/tests/run-set-x index b999e698..e6e2c49f 100644 --- a/tests/run-set-x +++ b/tests/run-set-x @@ -2,7 +2,7 @@ #$Id: run-set-x,v 1.1 2002/12/09 13:12:37 rockyb Exp $ TEST_NAME='set-x' -TEST_FILE="/tmp/${TEST_NAME}.check" +TEST_FILE="${BASH_TSTOUT}" ${THIS_SH} ./${TEST_NAME}.tests > $TEST_FILE 2>&1 < /dev/null set -f diff $TEST_FILE ${TEST_NAME}.right && rm -f $TEST_FILE diff --git a/tests/set-x.right b/tests/set-x.right index 230b1df1..7b14626d 100644 --- a/tests/set-x.right +++ b/tests/set-x.right @@ -34,10 +34,12 @@ onetwo + echo onetwo onetwo + set +x +./set-x1.sub: line 18: BASH_XTRACEFD: 4: invalid value for trace file descriptor 1 2 3 4 ++ exec + for f in a b c d e + echo a a @@ -61,3 +63,10 @@ TRACEFILE: + echo 4 + unset BASH_XTRACEFD ===== ++ metas=(\| \& \; \( \) \< \> ' ' ' ' ' +') ++ n=($@) ++ : '|' '&' ';' '(' ')' '<' '>' ' ' $'\t' $'\n' ++ DEFAULT_IFS=$' \t\n' ++ set +x +declare -a metas=([0]="|" [1]="&" [2]=";" [3]="(" [4]=")" [5]="<" [6]=">" [7]=" " [8]=$'\t' [9]=$'\n') diff --git a/tests/set-x.tests b/tests/set-x.tests index 74523bd4..b0b2ccca 100644 --- a/tests/set-x.tests +++ b/tests/set-x.tests @@ -38,3 +38,6 @@ set +x # test BASH_XTRACEFD ${THIS_SH} ./set-x1.sub + +# compound assignment printing +${THIS_SH} ./set-x2.sub diff --git a/tests/set-x1.sub b/tests/set-x1.sub index cb7fa827..04265268 100644 --- a/tests/set-x1.sub +++ b/tests/set-x1.sub @@ -15,6 +15,8 @@ TRACEFILE=$TMPDIR/bash-trace-$$ trap 'rm -f $TRACEFILE' 0 1 2 3 6 15 +BASH_XTRACEFD=4 # error, invalid FD + exec 4>$TRACEFILE BASH_XTRACEFD=4 @@ -26,6 +28,7 @@ echo 3 echo 4 unset BASH_XTRACEFD +exec 4<&- # no unset hooks yet for f in a b c d e; do echo $f ; done diff --git a/tests/set-x2.sub b/tests/set-x2.sub new file mode 100644 index 00000000..ca27cb3e --- /dev/null +++ b/tests/set-x2.sub @@ -0,0 +1,15 @@ +declare -a metas +set a b c + +set -x +# some time we will have better compound assignment printing (after expansion) +metas=( \| \& \; \( \) \< \> $' ' $'\t' $'\n' ) +n=( $@ ) + +# like regular expansions +: "${metas[@]}" + +DEFAULT_IFS=$' \t\n' + +set +x +declare -p metas diff --git a/tests/tilde.right b/tests/tilde.right index 1301c0b0..dc7dcb57 100644 --- a/tests/tilde.right +++ b/tests/tilde.right @@ -1,4 +1,5 @@ ~chet +~chet/foo /usr/xyz/foo ~chet/foo ~chet/foo diff --git a/tests/tilde.tests b/tests/tilde.tests index 20268a73..f3228b08 100644 --- a/tests/tilde.tests +++ b/tests/tilde.tests @@ -21,6 +21,7 @@ set +o posix HOME=/usr/xyz SHELL=~/bash echo ~ch\et +echo ~ch\et/foo echo ~/"foo" echo "~chet"/"foo" echo \~chet/"foo" diff --git a/tests/time.tests b/tests/time.tests index f47cfc02..9c4e4a34 100644 --- a/tests/time.tests +++ b/tests/time.tests @@ -11,6 +11,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +: ${THIS_SH:=./bash} + +printf "time -c : :\n" +time ${THIS_SH} -c : + printf "time /dev/null:\n" time ${THIS_SH} /dev/null @@ -27,10 +32,17 @@ time ${THIS_SH} /dev/null printf "\nksh time /dev/null:\n" TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS' -time ${THIS_SH} /dev/null +time ${THIS_SH} < /dev/null + +time (:) +(time :) + +times -x printf "\ntimes:\n" times +echo +times -- printf "\ntime standalone:\n" { time ; echo after; } |& wc -l diff --git a/tests/trap.right b/tests/trap.right index 7eab4752..4f322534 100644 --- a/tests/trap.right +++ b/tests/trap.right @@ -132,4 +132,6 @@ trap: usage: trap [-Plp] [[action] signal_spec ...] trap -- 'echo exiting' EXIT trap -- 'echo aborting' SIGABRT trap -- 'echo caught a child death' SIGCHLD +trap: usage: trap [-Plp] [[action] signal_spec ...] +echo exiting exiting diff --git a/tests/trap.tests b/tests/trap.tests index 8f4a0955..8e38cb35 100644 --- a/tests/trap.tests +++ b/tests/trap.tests @@ -128,3 +128,12 @@ trap trap - SIGCHLD wait + +trap 512 # error +trap 0 # revert +trap -p EXIT + +trap 'echo exiting' 0 +trap -P EXIT + +exit diff --git a/tests/type.right b/tests/type.right index a3fd4b9b..e7ecbe24 100644 --- a/tests/type.right +++ b/tests/type.right @@ -139,3 +139,4 @@ cat is aliased to `echo cat' /bin/cat break is a shell builtin break is a special shell builtin +./e diff --git a/tests/type5.sub b/tests/type5.sub index 1bd879e0..42489b05 100644 --- a/tests/type5.sub +++ b/tests/type5.sub @@ -14,6 +14,7 @@ # make sure . is not in $PATH PATH=/bin:/usr/bin:/usr/local/bin +OPATH=$PATH # test type -P @@ -37,5 +38,22 @@ type -P cat type break set -o posix; type break; set +o posix +# test with PATH empty and unset +realdir=$(pwd -P) +touch e ; chmod +x e + +PATH= +type -p e +unset PATH +z=$(type -p e) + +case $z in +*/e) ;; +*) echo 'type: unset PATH does not prefix with physical path to $PWD' ;; +esac +PATH=$OPATH + +rm -f e + cd "$OLDPWD" rm -rf "$TDIR" diff --git a/tests/varenv.right b/tests/varenv.right index 48b0abd2..f1af2ab1 100644 --- a/tests/varenv.right +++ b/tests/varenv.right @@ -186,6 +186,12 @@ declare -a a=([0]="X" [1]="Y") declare -a s=([0]="X" [1]="Y") declare -a a=([0]="XY") declare -a s=([0]="XY") +declare -A v=([1]="one" [0]="7" ) +declare -a v=([0]="7" [1]="1") +./varenv14.sub: line 77: declare: array: cannot convert indexed to associative array +declare -a array=([0]="1" [1]="2" [2]="3" [3]="list" [4]="of" [5]="four" [6]="words") +./varenv14.sub: line 85: declare: assoc: cannot convert associative to indexed array +declare -A assoc=([four]="words" [two]="2" [three]="3" [one]="1" [list]="of" ) f: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 f1: after: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 done: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 @@ -263,6 +269,7 @@ ignoreeof on ignoreeof off ignoreeof on 10 +local - match 1 trap -- 'echo trap:$FUNCNAME' EXIT trap:f diff --git a/tests/varenv14.sub b/tests/varenv14.sub index 091c4700..f943d6e1 100644 --- a/tests/varenv14.sub +++ b/tests/varenv14.sub @@ -44,3 +44,46 @@ f f() { local -a a+=Y s+=Y; declare -p a s; } f + +# inherit from different array types/variable types +unset -v v +unset -f f + +v=7 + +f() +{ + declare -A v + v+=(1 one) + declare -p v +} +f + +f() +{ + declare -a v + v+=(1) + declare -p v +} +f + +unset -v array assoc + +declare -a array=(1 2 3) +declare -A assoc=(one 1 two 2 three 3) + +f() +{ + declare -A array + array+=(list of four words) + declare -p array +} +f + +f() +{ + declare -a assoc + assoc+=(list of four words) + declare -p assoc +} +f diff --git a/tests/varenv21.sub b/tests/varenv21.sub index 613e4759..45d2d86c 100644 --- a/tests/varenv21.sub +++ b/tests/varenv21.sub @@ -34,6 +34,7 @@ f() local - set -m -H +B set -u + local -p # make sure it prints `local -' } before="$-|$SHELLOPTS" diff --git a/tests/vredir.right b/tests/vredir.right index f14fa5ef..d0a76a48 100644 --- a/tests/vredir.right +++ b/tests/vredir.right @@ -5,7 +5,7 @@ foo 3 bar is a function bar () { - exec {v}> $TMPFILE; + exec {v}>> $TMPFILE; echo $v } ./vredir.tests: line 19: v: readonly variable @@ -16,7 +16,7 @@ bar () bar is a function bar () { - exec {v}> $TMPFILE; + exec {v}>> $TMPFILE; echo $v } 10 @@ -34,6 +34,21 @@ EOF echo $v } +11 +line 1 +line 2 +line 3 +bar is a function +bar () +{ + exec {v}<<-EOF +line 1 +line 2 +line 3 +EOF + + echo $v +} 10 foo 1 foo 2 @@ -74,6 +89,9 @@ swizzle () exec {stdin}<&$fd0; exec {stdout}>&$fd1 } +10 11 +10 11 +./vredir4.sub: line 51: ${output}: Bad file descriptor 12 10 a a diff --git a/tests/vredir.tests b/tests/vredir.tests index 2a6cc18a..f2c5e4dd 100644 --- a/tests/vredir.tests +++ b/tests/vredir.tests @@ -16,7 +16,7 @@ TMPFILE=$TMPDIR/foo bar() { -exec {v}>$TMPFILE +exec {v}>>$TMPFILE echo $v } diff --git a/tests/vredir1.sub b/tests/vredir1.sub index 484f313b..d09a0156 100644 --- a/tests/vredir1.sub +++ b/tests/vredir1.sub @@ -25,6 +25,23 @@ bar cat <&$v +type bar +unset -f bar + +bar() +{ +exec {v}<<-EOF + line 1 + line 2 + line 3 +EOF +echo $v +} + +bar + +cat <&$v + type bar exit 0 diff --git a/tests/vredir4.sub b/tests/vredir4.sub index f861bcfc..7a4b091b 100644 --- a/tests/vredir4.sub +++ b/tests/vredir4.sub @@ -32,4 +32,22 @@ echo $line >&$stdout type swizzle +exec {stdin}<&- +exec {stdout}>&- + +stdin=-1 stdout=-1 + +declare -n stdin=input +declare -n stdout=output + +swizzle +echo ${input} ${output} +echo ${stdin} ${stdout} + +exec {stdin}<&- +exec {stdout}>&- + +# this should be an error +echo invalid fd >&${output} + exit 0 diff --git a/tests/vredir7.sub b/tests/vredir7.sub index 0f76f404..bd402d48 100644 --- a/tests/vredir7.sub +++ b/tests/vredir7.sub @@ -33,4 +33,10 @@ echo $line >&$stdout type swizzle +exec {fd[0]}<&- +exec {fd[1]}<&- + +exec {stdin}<&- +exec {stdout}>&- + exit 0