Permalink
Browse files

Documentation and rethinking of error conditions.

- fold an ad hoc test into test/runtime-errors.sh
- Rename directory spec/errors to spec/parse-errors
  • Loading branch information...
Andy Chu
Andy Chu committed Aug 17, 2018
1 parent 5bd633d commit 5e4025d7d2407808c052e7dcff2bf5706d986300
View
@@ -1078,6 +1078,10 @@ def _Dispatch(self, node, fork_external):
for arm in node.arms:
for pat_word in arm.pat_list:
# NOTE: Is it OK that we're evaluating these as we go?
# TODO: case "$@") shouldn't succeed? That's a type error?
# That requires strict-array?
pat_val = self.word_ev.EvalWordToString(pat_word, do_fnmatch=True)
#log('Matching word %r against pattern %r', to_match, pat_val.s)
if libc.fnmatch(pat_val.s, to_match):
View
@@ -1,24 +1,122 @@
List of Fatal Runtime Errors
----------------------------
List of Errors in the OSH Interpreter
-------------------------------------
Parse Error:
Can be determined statically
spec/parse-errors.test.sh
TODO: See test/runtime-errors.sh. Merge them here.
Fatal Error:
terminates the interpreter unconditionally, e.g. divide by zero does this in
bash.
Non-fatal error:
terminates the current builtin and exits 1
Strict modes:
Turns non-fatal errors into fatal errors.
set -o errexit
Turns things that are not errors at all into fatal errors
set -o nounset
set -o failglob
- Should we have a table of errors for metaprogramming?
- assign each one of these a code, and decide what to do based on a table?
- based on spec tests?
### Problem in bash: Context affects a lot
echo $(( 1 / 0 ))
echo 'after-$(())
(( 1 / 0 ))
echo 'after-$(())
### Arith Eval
Divide by zero: $(( 1 / 0 ))
^
Maybe: integer overflow. But we want big numbers.
Type errors between integers and strings:
x=foo
$(( x * 2 )) # doesn't make sense, except in bash's crazy world.
Invalid hex constant:
x=0xabcg
echo $(( x * 2 )) (fatal in bash)
### Bool Eval
regcomp parse error:
x=$(cat invalid-syntax.txt)
[[ foo =~ $x ]]
### Word Eval
IMPORTANT: Command sub error $(exit 1)
User-requested error: ${undef?error}
set -o nounset
set -o errexit
set -o pipefail
pipefail might need some fanciness for ${PIPESTATUS}
set -o failglob
failglob: might need PWD diagnostic
def _EmptyStrOrError(self, val, token=None):
# calls `e_die()`
Variants:
nounset: index out of bounds
nounset: index out of bounds ${a[3]}
I guess same diagnostic?
In bash you can set an index out of bounds, like
b[2]=9
Might want to have a mode for this?
set -o failglob
TODO: not implemented
might need PWD diagnostic
Redirects:
Redirect to empty filename/descriptor ( or array)
{ break; }
^~~~~~ break only invalid inside loop, etc.
NotImplementedError
- e.g for var ref ${!a}
- bash associative arrays? I think we want most of that
- $"" ?
- |& not yet done
- ;;& for case -- although parsing it is all of the work I guess
- some could be parse time errors too though?
- String Slicing and String Length require valid utf-8 characters
s=$(cat invalid.txt)
echo ${#s} # code points
echo ${s:1:3} # code opints
- Slicing: Index is negative. ${foo: -4} and ${foo: 1 : -4} aren't supported
right now, unlike bash and zsh.
### Command Exec
IMPORTANT: subshell error ( exit 1 )
set -o errexit -- turns NON-FATAL error into FATAL error.
set -o pipefail
pipefail might need some fanciness for ${PIPESTATUS}
Trying to set readonly variable:
readonly foo=bar
@@ -32,16 +130,11 @@ Trying to redeclare a variable? That can also be parse time.
local x=1
local x=2
Divide by zero: $(( 1 / 0 ))
^
Maybe: integer overflow. But we want big numbers.
Type errors between Str and StrArray:
Type errors between Str and StrArray: -- strict-array controls this
EvalWordToString calls e_die()`
echo foo > "$@"
^-- # Should have what it evaluated to?
# This could be static too
^-- # Should have what it evaluated to? # This could be static too
case "$@" in
"$@") echo bad;;
@@ -50,11 +143,19 @@ Type errors between Str and StrArray:
${undef:-"$@"} is OK, but ${var%"$@"} doesn't make sense really.
${v/"$@"/"$@"}
Type errors between integers and strings:
x = foo
$(( x * 2 )) # doesn't make sense, except in bash's crazy world.
LHS evaluation:
s='abc'
s[1]=X # invalid because it's a string, not an array
Invalid descriptor:
fd=$(cat invalid.txt)
echo foo 2>& $fd
#### Builtins
Builtin has too many arguments -- but this falls under the errexit rule
cd foo bar baz
@@ -64,6 +165,9 @@ Builtin has too many arguments -- but this falls under the errexit rule
Although we might want to highlight the extra args.
### Syscall Failures
Fatal error from system calls:
fork() could fail in theory
@@ -73,23 +177,7 @@ Some are not failures:
cd /ff chdir() # exit code 1
cat <nonexistent # This is just exit code 1
Redirects:
Redirect to empty filename/descriptor ( or array)
{ break; }
^~~~~~ break only invalid inside loop, etc.
NotImplementedError
- e.g for var ref ${!a}
- bash associative arrays? I think we want most of that
- $"" ?
- |& not yet done
- ;;& for case -- although parsing it is all of the work I guess
- some could be parse time errors too though?
### Interpreter Failures
Runtime: Stack Too Deep (catch infinite recursion)
Out of memory: should not happen with OSH, but maybe with Oil
@@ -104,7 +192,7 @@ so var=xx makes this invalid. hex/octal/decimal have this problem.
Parse Time Errors
-----------------
regcomp() errors.
regcomp() errors (sometimes at parse time; other times at runtime)
Need to show stack trace for "source" like Python. Prototype this.
@@ -115,6 +203,3 @@ $((echo hi))
Arith Invalid token

This file was deleted.

Oops, something went wrong.
File renamed without changes.
File renamed without changes.
View
@@ -135,6 +135,48 @@ control_flow() {
echo 'SHOULD NOT GET HERE'
}
ambiguous_redirect() {
echo foo > "$@"
echo 'ambiguous redirect not fatal unless errexit'
set -o errexit
echo foo > "$@"
echo 'should not get here'
}
# bash semantics.
ambiguous_redirect_context() {
# Problem: A WORD cannot fail. Only a COMMAND can fail.
# http://stackoverflow.com/questions/29532904/bash-subshell-errexit-semantics
# https://groups.google.com/forum/?fromgroups=#!topic/gnu.bash.bug/NCK_0GmIv2M
# http://unix.stackexchange.com/questions/23026/how-can-i-get-bash-to-exit-on-backtick-failure-in-a-similar-way-to-pipefail
echo $(echo hi > "$@")
echo 'ambiguous is NOT FATAL in command sub'
echo
foo=$(echo hi > "$@")
echo $foo
echo 'ambiguous is NOT FATAL in assignment in command sub'
echo
set -o errexit
# This is strict-errexit!
echo $(echo hi > "$@")
echo 'ambiguous is NOT FATAL in command sub, even if errexit'
echo
# OK this one works. Because the exit code of the assignment is the exit
# code of the RHS?
echo 'But when the command sub is in an assignment, it is fatal'
foo=$(echo hi > "$@")
echo $foo
echo 'SHOULD NOT REACH HERE'
}
#
# WORD ERRORS
#
@@ -170,6 +212,17 @@ divzero_var() {
echo 'SHOULD NOT GET HERE'
}
divzero_dparen() {
(( 1 / 0 ))
echo 'Divide by zero in dparen is non-fatal unless errexit!'
set -o errexit
(( 1 / 0 ))
echo 'SHOULD NOT GET HERE'
}
# Only dash flags this as an error.
string_to_int_arith() {
local x='ZZZ'

0 comments on commit 5e4025d

Please sign in to comment.