home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1995 by Oracle Corporation. All Rights Reserved.
- *
- * yse.h - OMX Exception Handling
- *
- * DESCRIPTION
- * The exception handling mechanism provides the ability to throw and
- * catch exceptional conditions. The paradigm supported here is intended
- * to be consistent with C++ behavior, in that some value (possibly
- * structured) is thrown by one routine and caught by another routine
- * with an established handler.
- */
-
- #ifndef YSE_ORACLE
- #define YSE_ORACLE
-
- #ifndef SYSX_ORACLE
- #include <sysx.h>
- #endif
- #ifndef YS_ORACLE
- #include <ys.h>
- #endif
-
- EXTC_START
-
- /*
- * Protected Regions
- *
- * SYNOPSIS
- * yseTry yseTry
- * statement statement
- * { yseCatch[Obj] yseFinally
- * statement } statement
- * [ yseCatchAll yseEnd
- * statement ]
- * yseEnd
- *
- * DESCRIPTION
- * A protected region and associated handlers are bracketed by yseTry/yseEnd
- * primitives. Any exception that occurs within the TRY region may be caught
- * by one of the associated CATCH handlers. If no exception occurs when
- * executing the TRY region, execution continues immediately following
- * yseEnd.
- *
- * A CATCH handler may catch a specific exception or it may catch all
- * exceptions. A catch handler for a specific exception takes an exid
- * argument, which must be a valid system identifier (see ysid.h).
- * yseCatch(exid) will catch exid exceptions. yseCatchObj(exid, exty, exobj)
- * will also catch exid exceptions. Additionally, it will declare a variable
- * name exobj of type exty that is local to the handler. The value of exobj
- * will be initialized to the value of the object that was thrown with the
- * exception. If no object was thrown, the variable will remain
- * uninitialized. If the type exty differs from the type of the object
- * thrown, the results are unpredictable.
- *
- * yseCatchAll will catch any exception, and if present, must be the last
- * handler in the sequence. Within yseCatchAll, the name yseExid may be
- * used to refer to the caught exception, and yseExobj to refer to the
- * exception object.
- *
- * If an exception is not caught by any CATCH handler, the exception is
- * automatically rethrown to the next TRY block in the dynamic scope. If
- * an exception is not caught and there are no more possible handlers, the
- * exception mechanism will panic.
- *
- * Within a catch handler, it is possible to rethrow the current exception
- * (with associated object, if any) using yseRethrow.
- *
- * An alternative form of protected region uses a FINALLY section instead
- * of CATCH handlers. In this case, the statement bracketed by yseFinally
- * and yseEnd will be executed whether or not an exception occurs in the
- * TRY region. If an exception did occur, control will immediately transfer
- * to the FINALLY section. Then, following the FINALLY section, the
- * exception will automatically be rethrown.
- *
- * WARNINGS
- * It is an error to leave a TRY, CATCH, or FINALLY region through any
- * means other than a thrown exception or falling through the end. Do
- * not use return or goto within such a region.
- *
- * Local variables used within a protected region should be marked
- * volatile to ensure that the variables contain a predictable value
- * in the handler.
- */
- #define yseTry \
- { ysefr ysed; yseInf(&ysed); if (!syseSet(ysed.jb)) {
- #define yseEnd \
- } yseTrf(&ysed); }
- #define yseCatch(exid) \
- } else if (ysidEq((exid), ysed.id)) { ysed.rth = FALSE;
- #define yseCatchObj(exid, exty, exobj) \
- } else if (ysidEq((exid), ysed.id)) { exty exobj; ysed.rth = FALSE; \
- yseSetObj(&ysed, (dvoid *) &exobj, sizeof(exty));
- #define yseCatchAll \
- } else { ysed.rth = FALSE;
- #define yseFinally \
- } { ysed.liv = TRUE;
- #define yseRethrow yseRethrower(&ysed)
- #define yseExid ysed.id
- #define yseExobj ysed.obj
-
- /*
- * yseGetLoc - get location where exception was raised
- *
- * SYNOPSIS
- * void yseGetLoc(CONST char **fn, sword *lineno);
- *
- * DESCRIPTION
- * Within a CATCH handler, yseGetLoc() may be called to get the
- * location in the program from which the exception was thrown.
- * The location is specified in terms of filename and line number
- * and is intended for debugging purposes only.
- */
- #define yseGetLoc(f, l) (*(f) = ysed.fn, *(l) = ysed.lineno)
-
- /*
- * yseThrow, yseThrowObj - throw an exception
- *
- * SYNOPSIS
- * void yseThrow(CONST ysid *exid);
- * void yseThrowObj(CONST ysid *exid, <l-value> obj);
- *
- * DESCRIPTION
- * yseThrow() and yseThrowObj() throw an exception. The exception
- * may be caught by a dynamically scoped CATCH region. yseThrowObj()
- * may be used to throw a value along with the exception. This value
- * is copied and made available to a catch handler declared with
- * yseCatchObj(). To understand exactly what this copying implies,
- * throwing the value obj is exactly equivalent to the C statement
- * "return obj" in all respects related to the way obj is treated, with
- * the caveat that obj must be an l-value.
- */
- #define yseThrow(exid) \
- yseThrower((exid), (dvoid *) 0, (size_t) 0, __FILE__, __LINE__)
- #define yseThrowObj(exid, obj) \
- yseThrower((exid), (dvoid *) &(obj), sizeof(obj), __FILE__, __LINE__)
-
- /*
- * ysepf, ysePanic, yseSetPanic - Panic Functions
- *
- * DESCRIPTION
- * When a catastrophic failure occurs, and the current thread of execution
- * is not recoverable, a routine may panic, thus causing a sort of software
- * trap, by calling ysePanic(). The exception that is causing the death
- * should be passed to the routine. By default, a panic will cause the
- * process to abort, possibly with some additional system information
- * recorded for analysis. However, this may be overridden by installing
- * a user-defined panic routine using yseSetPanic(). yseSetPanic() will
- * install pfunc as the panic routine. It will return the previously
- * installed panic routine if was one or a null pointer otherwise. The
- * ptr value will be passed to the panic routine when it is invoked.
- *
- * A user-defined panic routine should generally perform application-
- * specific cleanup. The routine may exit either by throwing an exception
- * or return. The former style is recommended since it allows handlers to
- * perform cleanup in a consistent fashion. If the routine simply returns,
- * then the default process abort action will be taken.
- */
- typedef void (*ysepf)(CONST ysid *exid, dvoid *ptr);
- void ysePanic(CONST ysid *exid);
- ysepf yseSetPanic(ysepf pfunc, dvoid *ptr);
-
- /*
- * PRIVATE DECLARATIONS
- */
- typedef struct ysefr ysefr; /* exception frame */
-
- void yseInf(ysefr *fr);
- void yseTrf(ysefr *fr);
- void yseThrower(CONST ysid *exid, dvoid *obj, size_t objsz,
- CONST char *fn, sword lineno);
- void yseRethrower(ysefr *fr);
- void yseSetObj(ysefr *fr, dvoid *obj, size_t objsz);
- #define yseTrigger(evt) \
- ysTrigger(evt, ysed.id, ysed.obj, ysmGetSize(ysed.obj))
-
-
- /* DISABLE check_naming */
- struct ysefr
- {
- ysefr *prev; /* previous frame */
- sysejb jb; /* jump buffer */
- CONST ysid *id; /* exception identifier */
- dvoid *obj; /* exception argument */
- boolean rth; /* true if exception should be rethrown */
- boolean liv; /* true if an exception occurred in the frame */
- CONST char *fn; /* filename of thrower */
- sword lineno; /* line number of thrower */
- };
- /* ENABLE check_naming */
-
- EXTC_END
- #endif /* YSE_ORACLE */
-