diff --git a/core/word_eval.py b/core/word_eval.py index bfa22f8931..ea4efd2977 100644 --- a/core/word_eval.py +++ b/core/word_eval.py @@ -434,8 +434,11 @@ def _ApplyPrefixOp(self, val, op_id): # TODO: There can be empty placeholder values in the array. length = len(val.strs) return runtime.Str(str(length)) + elif op_id == Id.VSub_Bang: + # Treat the value of the variable as a variable name. + return self.mem.GetVar(val.s) else: - raise NotImplementedError(op_id) + raise AssertionError(op_id) def _ApplyOtherSuffixOp(self, val, op): diff --git a/spec/var-ref.test.sh b/spec/var-ref.test.sh index ecefce9395..079ba3dcb2 100755 --- a/spec/var-ref.test.sh +++ b/spec/var-ref.test.sh @@ -4,6 +4,30 @@ # # http://stackoverflow.com/questions/16461656/bash-how-to-pass-array-as-an-argument-to-a-function +### var ref ${!a} +a=b +b=c +echo ref ${!a} ${a} +# Woah mksh has a completely different behavior -- var name, not var ref. +# stdout: ref c b +# BUG mksh stdout: ref a b +# N-I dash/zsh stdout-json: "" + +### declare -n and ${!a} +declare -n a +a=b +b=c +echo ${!a} ${a} +# stdout: b c +# N-I mksh stdout: a b + +### Bad var ref with ${!a} +#set -o nounset +a='bad var name' +echo ref ${!a} +echo status=$? +# stdout-json: "ref\nstatus=0\n" +# BUG mksh stdout-json: "ref a\nstatus=0\n" ### pass array by reference show_value() { local -n array=$1 @@ -42,20 +66,3 @@ caller # BUG mksh stdout-json: "" # BUG mksh status: 1 -### Var ref with ${!a} -a=b -b=c -echo ref ${!a} -# Woah mksh has a completely different behavior -- var name, not var ref. -# stdout: ref c -# BUG mksh stdout: ref a -# N-I dash/zsh stdout-json: "" - -### Bad var ref with ${!a} -#set -o nounset -a='bad var name' -echo ref ${!a} -# Woah even dash implements this! -# stdout-json: "ref\n" -# BUG mksh stdout: ref a -# N-I dash/zsh stdout-json: "" diff --git a/test/spec.sh b/test/spec.sh index b179a60feb..9cf47d0de2 100755 --- a/test/spec.sh +++ b/test/spec.sh @@ -452,7 +452,8 @@ extended-glob() { # ${!var} syntax -- oil should replace this with associative arrays. var-ref() { - sh-spec spec/var-ref.test.sh $BASH $MKSH "$@" + sh-spec spec/var-ref.test.sh --osh-failures-allowed 4 \ + $BASH $MKSH $OSH "$@" } let() {