aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-07-14 23:35:18 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-07-14 23:35:18 +0300
commit8d4894458790db74d795e874c298b0810aca7746 (patch)
treeef5a30b144afdc0980bb2a2ccfc8ced68b526963
parent439316ca0f68a32663e8bffdcb6b6f0e9e6d091f (diff)
downloadmailfromd-8d4894458790db74d795e874c298b0810aca7746.tar.gz
mailfromd-8d4894458790db74d795e874c298b0810aca7746.tar.bz2
Document try-catch and dclex
* NEWS: Update. * doc/mailfromd.texi: Document try-catch and dclex. * doc/upgrade.texi : Update. * doc/values.texi (MIN_EXCEPTION, MAX_EXCEPTION): New values.
-rw-r--r--NEWS8
-rw-r--r--doc/mailfromd.texi265
-rw-r--r--doc/upgrade.texi4
-rw-r--r--doc/values.texi2
4 files changed, 183 insertions, 96 deletions
diff --git a/NEWS b/NEWS
index ac9f77b9..97114f01 100644
--- a/NEWS
+++ b/NEWS
@@ -168,6 +168,10 @@ identifier may then be used in `catch' and `throw' statements, e.g.:
throw myerror "My error encountered"
+For a detailed discussion, see the manual, subsection 4.18.2
+"User-defined Exceptions".
+FIXME: Before release, check if the subsection number is right.
+
** The try-catch construct
This version introduces a `try-catch' construct similar to that used
@@ -193,6 +197,10 @@ STMTLIST-2.
The `try-catch' construct allows a better and more flexible error
recovery.
+For a detailed discussion, see the manual, subsection 4.18.3
+"Exception Handling".
+FIXME: Before release, check if the subsection number is right.
+
** Handling of stderr in open("|...")
If open call is used to start external program (i.e. its argument
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 30bfc8db..92dbfa5b 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -248,6 +248,12 @@ Statements
@c Conditionals
@c Exception handlers
+Exceptional Conditions
+
+* Built-in Exceptions::
+* User-defined Exceptions::
+* Catch and Throw::
+
Modules
* module structure:: Declaring Modules
@@ -4991,8 +4997,9 @@ lookup fails, @samp{$1} will contain the message sender's @acronym{IP} address
enclosed in square brackets (e.g. @samp{[127.0.0.1]}).
@item @code{number};
-Socket address family. Include @file{status.mfh} to get symbolic
-definitions for the address families. Supported families are:
+Socket address family. You need to require the @samp{status} module
+to get symbolic definitions for the address families. Supported
+families are:
@cindex FAMILY_STDIO
@cindex FAMILY_UNIX
@@ -7094,19 +7101,31 @@ return a boolean value. However, when querying the Domain Name
System, it may fail to get a definite result. For example, the @acronym{DNS}
server can be down or temporary unavailable. In other words,
@code{primitive_hasmx} can be in a situation when, instead of returning
-@samp{yes} or @samp{no}, it has to return @samp{don't know}. That is
-exactly then when it signals an @dfn{exception}.
+@samp{yes} or @samp{no}, it has to return @samp{don't know}. It has
+no way of doing so, therefore it signals an @dfn{exception}.
-@anchor{status.mfh}
+@anchor{status.mf}
@cindex exception types
-@cindex @file{status.mfh}, header file
+@cindex @file{status.mf}, module
@cindex exceptions, symbolic names
- Exceptions are identified by @dfn{exception types}, the decimal
-numbers associated with them. The header file @file{status.mfh}
-defines @dfn{symbolic exception names} for each of these. The
+ Each exception is identified by @dfn{exception type}, an integer
+number associated with it.
+
+@menu
+* Built-in Exceptions::
+* User-defined Exceptions::
+* Catch and Throw::
+@end menu
+
+@node Built-in Exceptions
+@subsection Built-in Exceptions
+The numbers from @value{MIN_EXCEPTION} to @value{MAX_EXCEPTION} are
+reserved for @dfn{built-in exceptions}. The module @file{status.mf}
+defines @dfn{symbolic exception names} for each of these. The
following table summarizes all the exception types implemented by
@command{mailfromd} version @value{VERSION}:
+@anchor{exception names}
@table @code
@cindex e_dbfailure, exception type
@item e_dbfailure
@@ -7224,6 +7243,39 @@ was not found. @xref{figure-poll-wrapper}, for an illustration on
how these can be used. For consistency with other exception codes,
these can be spelled as @code{e_success} and @code{e_not_found}.
+@node User-defined Exceptions
+@subsection User-defined Exceptions
+@kwindex dclex
+ You can define your own exception types using the @code{dclex}
+statement:
+
+@smallexample
+dclex @var{type}
+@end smallexample
+
+In this statement, @var{type} must be a valid @acronym{MFL}
+identifier, not used for another constant (@pxref{Constants}).
+The @code{dclex} statement defines a new exception identified by
+the constant @var{type} and allocates a new exception number for it.
+
+The @var{type} can subsequently be used in @code{throw} and
+@code{catch} statements, for example:
+
+@smallexample
+dclex myrange
+
+number fact(number val)
+ returns number
+do
+ if val < 0
+ throw myrange "fact argument is out of range"
+ fi
+ @dots{}
+done
+@end smallexample
+
+@node Catch and Throw
+@subsection Exception Handling
@cindex exceptions, default handling
@cindex default exception handling
Normally when an exception is signalled, the program execution is
@@ -7233,15 +7285,21 @@ to the logging channel (@pxref{Logging and Debugging}). However, the
user can intercept any exception by installing his own
exception-handling routines.
+@cindex @code{try} statement
@cindex @code{catch} statement
+@cindex try-catch construct
@cindex exception-handling routines
@cindex exception handlers
@kwindex catch
- An exception-handling routine is introduced by @code{catch}
+ An exception-handling routine is introduced by a @dfn{try-catch}
statement, which has the following syntax:
@smallexample
@group
+try
+do
+ @var{stmtlist}
+done
catch @var{exception-list}
do
@var{handler-body}
@@ -7250,99 +7308,102 @@ done
@end smallexample
@noindent
-where @var{exception-list} is the list of exception types, separated
-by the word @code{or}. A special form @samp{*}, which stands for
-all exceptions, is allowed as well. The @var{handler-body} is the list of
-statements comprising the handler body. For example, the code below
-installs a handler for exceptions 2 (@samp{e_failure}) and 3
-(@samp{e_temp_failure}):
+where @var{stmtlist} and @var{handler-body} are sequences of
+@acronym{MFL} statements and @var{exception-list} is the list of
+exception types, separated by the word @code{or}. A special
+@var{exception-list} @samp{*} is allowed and means all exceptions.
-@smallexample
-@group
-catch 2 or 3
-do
- @dots{}
-done
-@end group
-@end smallexample
+This construct works as follows. First, the statements from
+@var{stmtlist} are executed. If the execution finishes
+successfully, control is passed to the first statement after the
+@samp{catch} block. Otherwise, if an exception is signalled and this
+exception is listed in @var{exception-list}, the execution is passed to the
+@var{handler-body}. If the exception is not listed in
+@var{exception-list}, it is handled as usual.
-@noindent
-@anchor{exception symbolic names}
-@cindex @file{status.mfh}, usage
- However, using numeric exception codes is not convenient and is not
-in fact recommended. We recommend to use exception symbolic names
-instead. These are declared in the header file @file{status.mfh}, which
-should be included in your startup script. Using this approach, the
-above code snippet will look like:
+ The following example shows a @samp{try-catch} construct used for
+handling seventual exceptions, signalled by @code{primitive_hasmx}.
@smallexample
@group
-#include <status.mfh>
-
+try
+do
+ if primitive_hasmx(domainpart($f))
+ accept
+ else
+ reject
+ fi
+done
catch e_failure or e_temp_failure
do
- @dots{}
+ echo "primitive_hasmx failed"
+ continue
done
@end group
@end smallexample
-
+
@cindex scope of exception handlers
@cindex scope of a @code{catch}
@cindex @code{catch} scope
@cindex exception handler scope
- The @code{catch} statement can appear anywhere inside a function or
+ The @samp{try-catch} statement can appear anywhere inside a function or
a handler, but it cannot appear outside of them. It can also be nested
-within another @code{catch}. Each exception redefined by a catch
-remains in force until either another catch appears further in the
-same function or handler that redefines it or an end of the containing
-block is encountered, whichever occurs first. Upon exit from a
+within another @samp{try-catch}, in either of its parts. Upon exit from a
function or milter handler, all exceptions are restored to the state
they had when it has been entered.
+@cindex catch, standalone
+@cindex standalone catch
+ A @code{catch} block can be used alone, without preceding @code{try}
+part. Such a construct is called a @dfn{standalone catch}. It is
+mostly useful for setting global exception handlers in a @code{begin}
+statement (@pxref{begin/end}). When used within a usual function or
+handler, the exception handlers set by a standalone catch
+remain in force until either another standalone catch appears further
+in the same function or handler, or an end of the function is
+encountered, whichever occurs first.
+
+ A standalone catch defined within a function must return from
+it by executing @code{return} statement. If it does not do that
+explicitly, the default value of 1 is returned. A standalone catch
+defined within a milter handler must end execution with any of the
+following actions: @code{accept}, @code{continue}, @code{discard},
+@code{reject}, @code{tempfail}. By default, @code{continue} is
+used.
+
+ It is not recommended to mix @samp{try-catch} constructs and
+standalone catches. If a standalone catch appears within a
+@samp{try-catch} statement, its scope of visibility is undefined.
+
@cindex returning from a catch
@cindex returning from an exception handler
@cindex @code{catch}, returning from
@cindex exception handler, returning from
@cindex @code{catch} arguments
@cindex arguments, @code{catch}
- Upon entry to a @code{catch} code, it receives two positional
-arguments, which can be referenced in @var{handler-body} as @code{$1}
+ Upon entry to a @var{handler-body}, two implicit positional arguments
+are defined, which can be referenced in @var{handler-body} as @code{$1}
and @code{$2}. The first argument gives the numeric code of the
exception that has occurred. The second argument is a textual string
-containing a human-readable description of the exception. A
-@code{catch} defined within a function must return from
-it by executing @code{return} statement. If it does not do that
-explicitly, the default value of 1 is returned. A @code{catch}
-defined within a milter handler must end execution with any of the
-following actions: @code{accept}, @code{continue}, @code{discard},
-@code{reject}, @code{tempfail}. By default, @code{continue} is
-used.
+containing a human-readable description of the exception.
- The following example shows an @code{envfrom} handler that catches
-eventual exceptions, signaled by @code{primitive_hasmx}. The handler
-accepts the message if the sender domain has any @samp{MX} records, rejects
-them if it does not, and continues execution if an exception occurs.
-In the latter case, a log message is also issued:
+ The following is an improved version of the previous example, which
+uses these parameters to supply more information about the failure:
@smallexample
-@group
-#include <status.mfh>
-
-prog envfrom
+try
do
- catch e_failure or e_temp_failure
- do
- echo "Caught exception $1: $2"
- continue
- done
-
if primitive_hasmx(domainpart($f))
accept
else
reject
fi
done
-@end group
+catch e_failure or e_temp_failure
+do
+ echo "Caught exception $1: $2"
+ continue
+done
@end smallexample
@cindex @code{hasmx}, definition of the function
@@ -7352,28 +7413,42 @@ false if it does not or if an exception occurs @footnote{This function is
part of the @code{mailfromd} library, @xref{hasmx}.}.
@smallexample
-@group
-func hasmx (s) returns n
+func hasmx (string s)
+ returns number
do
+ try
+ do
+ return primitive_hasmx(domainpart(s))
+ done
catch *
do
return 0
done
- return primitive_hasmx(domainpart($1))
done
-@end group
@end smallexample
+ The same function can written using standalone @code{catch}:
+
+@smallexample
+func hasmx (string s)
+ returns number
+do
+ catch *
+ do
+ return 0
+ done
+ return primitive_hasmx(domainpart(s))
+done
+@end smallexample
+
+
@cindex @code{catch}, accessing variables from
@cindex variables, accessing from @code{catch}
@cindex accessing variables from @code{catch}
All variables remain visible within @code{catch} body, with the
-exception of positional arguments of the enclosing function or
-handler. So, if you wish to access function arguments from a
-@code{catch}, define your function using new style
-(@pxref{User-defined}) declaration. To access positional
-arguments of a handler, you will have to assign them to local
-variables prior to installing a catch, e.g.:
+exception of positional arguments of the enclosing handler. To access
+positional arguments of a handler from the @code{catch} body, assign
+them to local variables prior to the @samp{try-catch} construct, e.g.:
@smallexample
@group
@@ -7381,13 +7456,16 @@ prog header
do
string hname $1
string hvalue $2
+ try
+ do
+ @dots{}
+ done
catch *
do
echo "Exception $1 while processing header %hname: %hvalue"
echo $2
tempfail
done
- @dots{}
@end group
@end smallexample
@@ -7396,24 +7474,21 @@ do
@cindex raising exceptions
@kwindex throw
You can also generate (or @dfn{raise}) exceptions explicitly in the
-filter code, using @code{throw} statement:
+code, using @code{throw} statement:
@smallexample
throw @var{excode} @var{descr}
@end smallexample
- The arguments correspond exactly to the positional arguments of the
+ The arguments correspond exactly to the positional parameters of the
@code{catch} statement: @var{excode} gives the numeric code of the
exception, @var{descr} gives its textual description. This statement
can be used in complex scripts to create non-local exits from deeply
nested statements. @FIXME{Elaborate on that.}
- Notice several limitations of @code{throw}: first, the @var{excode}
-argument must be an immediate value, you cannot use an expression in
-its place. Secondly, its range is limited to exception codes,
-described in @ref{status.mfh}. In other words, you cannot (yet)
-invent your own exception types. @FIXME{This is fixed in the
-@samp{mtax-cleanup} branch.}
+ Notice, that the the @var{excode} argument must be an immediate
+value: an exception identifier (either built-in one or one declared
+previously using a @code{dclex} statement).
@node Polling
@section Sender Verification Tests
@@ -7446,10 +7521,18 @@ done
@code{catch}, for example thus:
@smallexample
-#include <status.mfh>
+require status
prog envfrom
do
+ try
+ do
+ if stdpoll($1, ehlo_domain, mailfrom_address) == 0
+ accept
+ else
+ reject 550 5.1.0 "Sender validity not confirmed"
+ fi
+ done
catch e_failure or e_temp_failure
do
switch $1
@@ -7460,12 +7543,6 @@ do
tempfail 450 4.1.0 "Try again later"
done
done
-
- if stdpoll($1, ehlo_domain, mailfrom_address) == 0
- accept
- else
- reject 550 5.1.0 "Sender validity not confirmed"
- fi
done
@end smallexample
@@ -7555,7 +7632,7 @@ done
@noindent
The @var{condition} is either a function call or a special @code{poll}
statement (see below). The values used in @code{when} branches are
-normally symbolic exception names (@pxref{exception symbolic names}).
+normally symbolic exception names (@pxref{exception names}).
When the compiler processes the @code{on} statement it does the
following:
diff --git a/doc/upgrade.texi b/doc/upgrade.texi
index d95fdad4..929dff86 100644
--- a/doc/upgrade.texi
+++ b/doc/upgrade.texi
@@ -278,7 +278,7 @@ variables, which remained unnoticed in previous releases.
To minimize chances of name clashes, all symbolic exception codes has
been renamed by prefixing them with the @samp{e_}, thus, e.g. @code{divzero}
became @code{e_divzero}, etc. The @code{ioerr} exception code is renamed to
-@code{e_io}. @xref{status.mfh}, for a full list of the new exception codes.
+@code{e_io}. @xref{status.mf}, for a full list of the new exception codes.
@cindex @code{OLD_EXCEPTION_CODES}, preprocessor symbol
For consistency, the following most often used codes are available without
@@ -386,7 +386,7 @@ non-blocking syslog}.
predefined symbolic names for exception codes (previous versions used
the @samp{&} prefix to dereference them). Instead, it relies on
constants defined in the include file @file{status.mfh}
-(@pxref{status.mfh}).
+(@pxref{status.mf}).
However, the script files from 3.1 series will still work, but
the following warning messages will be displayed:
diff --git a/doc/values.texi b/doc/values.texi
index ca2ef0ef..3991640d 100644
--- a/doc/values.texi
+++ b/doc/values.texi
@@ -9,3 +9,5 @@
@set GACOPYZ_READ_TIMEOUT 10 seconds
@set GACOPYZ_EOM_TIMEOUT 5 minutes
@set GACOPYZ_CONNECT_TIMEOUT 5 minutes
+@set MIN_EXCEPTION 0
+@set MAX_EXCEPTION 16

Return to:

Send suggestions and report system problems to the System administrator.