From 96fc5e800a1437a433c963267cd1c9d4de266438 Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Sun, 8 Apr 2007 01:35:42 +0000 Subject: Merge in workers/20812 for exception handling using "always" block. --- Functions/Exceptions/.distfiles | 4 ++++ Functions/Exceptions/catch | 41 +++++++++++++++++++++++++++++++++++++++++ Functions/Exceptions/throw | 30 ++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 Functions/Exceptions/.distfiles create mode 100644 Functions/Exceptions/catch create mode 100644 Functions/Exceptions/throw (limited to 'Functions') diff --git a/Functions/Exceptions/.distfiles b/Functions/Exceptions/.distfiles new file mode 100644 index 000000000..8b697438c --- /dev/null +++ b/Functions/Exceptions/.distfiles @@ -0,0 +1,4 @@ +DISTFILES_SRC=' +.distfiles +catch throw +' diff --git a/Functions/Exceptions/catch b/Functions/Exceptions/catch new file mode 100644 index 000000000..6afd664da --- /dev/null +++ b/Functions/Exceptions/catch @@ -0,0 +1,41 @@ +# Catch an exception. Returns 0 if the exception in question was caught. +# The first argument gives the exception to catch, which may be a +# pattern. +# This must be within an always-block. A typical set of handlers looks +# like: +# { +# # try block; something here throws exceptions +# } always { +# if catch MyExcept; then +# # Handler code goes here. +# print Handling exception MyExcept +# elif catch *; then +# # This is the way to implement a catch-all. +# print Handling any other exception +# fi +# } +# As with other languages, exceptions do not need to be handled +# within an always block and may propagate to a handler further up the +# call chain. +# +# It is possible to throw an exception from within the handler by +# using "throw". +# +# The shell variable $CAUGHT is set to the last exception caught, +# which is useful if the argument to "catch" was a pattern. +# +# Use "function" keyword in case catch is already an alias. +function catch { + if [[ $TRY_BLOCK_ERROR -gt 0 && $EXCEPTION = ${~1} ]]; then + (( TRY_BLOCK_ERROR = 0 )) + typeset -g CAUGHT="$EXCEPTION" + unset EXCEPTION + return 0 + fi + + return 1 +} +# Never use globbing with "catch". +alias catch="noglob catch" + +catch "$@" diff --git a/Functions/Exceptions/throw b/Functions/Exceptions/throw new file mode 100644 index 000000000..5c7326999 --- /dev/null +++ b/Functions/Exceptions/throw @@ -0,0 +1,30 @@ +# Throw an exception. +# The first argument is a string giving the exception. Other arguments +# are ignored. +# +# This is designed to be called somewhere inside a "try-block", i.e. +# some code of the form: +# { +# # try-block +# } always { +# # always-block +# } +# although as normal with exceptions it might be hidden deep inside +# other code. Note, however, that it must be code running within the +# current shell; with shells, unlike other languages, it is quite easy +# to miss points at which the shell forks. +# +# If there is nothing to catch an exception, this behaves like any +# other shell error, aborting to the command prompt or abandoning a +# script. + +# The following must not be local. +typeset -g EXCEPTION="$1" +readonly THROW +if (( TRY_BLOCK_ERROR == 0 )); then + # We are throwing an exception from the middle of an always-block. + # We can do this by restoring the error status from the try-block. + (( TRY_BLOCK_ERROR = 1 )) +fi +# Raise an error, but don't show an error message. +THROW= 2>/dev/null -- cgit 1.4.1