OSSP CVS Repository

ossp - Check-in [1695]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1695
Date: 2002-Jan-30 11:33:36 (local)
2002-Jan-30 10:33:36 (UTC)
User:rse
Branch:
Comment: add ex_cleanup clause to ex_try/ex_catch, modelled after Java's "finally"
Tickets:
Inspections:
Files:
ossp-pkg/ex/ex.h      1.11 -> 1.12     24 inserted, 3 deleted
ossp-pkg/ex/ex.pod      1.9 -> 1.10     17 inserted, 14 deleted
ossp-pkg/ex/ex_test.c      1.6 -> 1.7     30 inserted, 0 deleted

ossp-pkg/ex/ex.h 1.11 -> 1.12

--- ex.h 2002/01/29 20:10:53     1.11
+++ ex.h 2002/01/30 10:33:36     1.12
@@ -96,17 +96,19 @@
     __ex_mctx_t  *ctx_mctx;     /* permanent machine context of enclosing try/catch */
     int           ctx_disabled; /* permanent flag whether exception handling is disabled */
     int           ctx_caught;   /* temporary flag whether exception was caught */
+    int           ctx_cleanup;  /* temporary flag whether cleanup block was present */
     volatile ex_t ctx_ex;       /* temporary exception storage */
 } ex_ctx_t;
 
 /* the static and dynamic initializers for a context structure */
 #define EX_CTX_INITIALIZER \
-    { NULL, 0, 0, { NULL, NULL, NULL, NULL, 0, NULL } }
+    { NULL, 0, 0, 0, { NULL, NULL, NULL, NULL, 0, NULL } }
 #define EX_CTX_INITIALIZE(ctx) \
     do { \
         (ctx)->ctx_mctx         = NULL; \
         (ctx)->ctx_disabled     = 0;    \
         (ctx)->ctx_caught       = 0;    \
+        (ctx)->ctx_cleanup      = 0;    \
         (ctx)->ctx_ex.ex_class  = NULL; \
         (ctx)->ctx_ex.ex_object = NULL; \
         (ctx)->ctx_ex.ex_value  = NULL; \
@@ -133,11 +135,12 @@
         __ex_mctx_t __ex_mctx_me; \
         __ex_mctx_en = __ex_ctx_ptr->ctx_mctx; \
         __ex_ctx_ptr->ctx_mctx = &__ex_mctx_me; \
+        __ex_ctx_ptr->ctx_cleanup = 0; \
         if (__ex_mctx_save(&__ex_mctx_me)) { \
             if (1)
 
-/* the block for catching an exception */
-#define ex_catch(e) \
+/* the optional(!) block for cleanup */
+#define ex_cleanup \
             else { \
             } \
             __ex_ctx_ptr->ctx_caught = 0; \
@@ -147,6 +150,24 @@
             __ex_ctx_ptr->ctx_caught = 1; \
         } \
         __ex_ctx_ptr->ctx_mctx = __ex_mctx_en; \
+        __ex_ctx()->ctx_cleanup = 1; \
+        if (1) { \
+            if (1)
+
+/* the block for catching an exception */
+#define ex_catch(e) \
+            else { \
+            } \
+            if (!(__ex_ctx()->ctx_cleanup)) \
+                __ex_ctx_ptr->ctx_caught = 0; \
+        } \
+        else { \
+            if (!(__ex_ctx()->ctx_cleanup)) { \
+                __ex_mctx_restored(&__ex_mctx_me); \
+                __ex_ctx_ptr->ctx_caught = 1; \
+            } \
+        } \
+        __ex_ctx_ptr->ctx_mctx = __ex_mctx_en; \
     } \
     if (   !(__ex_ctx()->ctx_caught) \
         || ((e) = __ex_ctx()->ctx_ex, 0)) { \


ossp-pkg/ex/ex.pod 1.9 -> 1.10

--- ex.pod       2002/01/29 20:10:53     1.9
+++ ex.pod       2002/01/30 10:33:36     1.10
@@ -36,13 +36,13 @@
 
 B<ex_t> I<variable>;
 
-B<ex_try> { ... } B<ex_catch> (I<variable>) { ... }
+B<ex_try> {...} [B<ex_cleanup> {...}] B<ex_catch> (I<variable>) {...}
 
 B<ex_throw>(I<class>, I<object>, I<value>);
 
 B<ex_rethrow>;
 
-B<ex_shield> { ... };
+B<ex_shield> {...};
 
 if (B<ex_catching>) ...
 
@@ -53,7 +53,7 @@
 B<OSSP ex> is a small ISO-C++ style exception handling library for use
 in the ISO-C language. It allows you to use the paradigm of throwing
 and catching exceptions in order to reduce the amount of error handling
-code in without making your program less robust. This is achieved
+code without making your program less robust. This is achieved
 by directly transferring exceptional return codes (and the program
 control flow) from the location where it was raised (throw point) to
 the location where it is handled (catch point) - usually from a deeply
@@ -133,22 +133,25 @@
 
 =back
 
-=item B<ex_try> { ... } B<ex_catch> (I<variable>) { ... }
+=item B<ex_try> {...} [B<ex_cleanup> {...}] B<ex_catch> (I<variable>) {...}
 
 This is the main construct provided by B<OSSP ex>. It is modeled after
 the ISO-C++ C<try>-C<catch> construct which in turn is very similar to
 an ISO-C C<if>-C<else> construct. It consists of an B<ex_try> block
 which forms the dynamic scope of the exception handling (i.e. exceptions
-thrown there are or from routines called from there are catched) and a
+directly thrown there or thrown from subroutines are catched), an
+optional B<ex_cleanup> block for performing cleanup sequences and a
 B<ex_catch> block where the caught exceptions are handled.
 
-The B<ex_trx> and B<ex_catch> cannot be used seperately, they work only
-in combination. In contrast to ISO-C++ there is only one B<ex_catch>
-block and not multiple ones (all B<OSSP ex> exceptions are of the
-same ISO-C type B<ex_t>). If an exception is caught, it is stored in
-I<variable> for inspection (or re-throwing) inside the B<ex_catch>
-block. Although declared outside, the I<variable> is only valid
-within the B<ex_catch> block. But it can be re-used in following
+# CONTROL FLOW FIXME!
+
+The B<ex_try>, B<ex_cleanup> and B<ex_catch> cannot be used seperately,
+they work only in combination. In contrast to ISO-C++ there is only
+one B<ex_catch> block and not multiple ones (all B<OSSP ex> exceptions
+are of the same ISO-C type B<ex_t>). If an exception is caught, it
+is stored in I<variable> for inspection (or re-throwing) inside the
+B<ex_catch> block. Although declared outside, the I<variable> is only
+valid within the B<ex_catch> block. But it can be re-used in following
 B<ex_try>/B<ex_catch> constructs, of course.
 
 The B<ex_try> block is a regular ISO-C language block, but it is not
@@ -182,7 +185,7 @@
 I<variable>.ex_value) but with the difference that the C<ex_file>,
 C<ex_line> and C<ex_func> elements of the thrown exception are kept.
 
-=item B<ex_shield> { ... }
+=item B<ex_shield> {...}
 
 This directive executes its block while shielding against the throwing
 of exceptions, i.e., in the dynamic scope of B<ex_shield> any
@@ -232,7 +235,7 @@
 
 This is called by the epilog of B<ex_try> to perform additional
 operations at the new (restored) machine context after an exception was
-cought. Usually this is a no-operation macro.
+caught. Usually this is a no-operation macro.
 
 =item B<__ex_mctx_restore>(I<mctx>)
 


ossp-pkg/ex/ex_test.c 1.6 -> 1.7

--- ex_test.c    2002/01/26 22:45:37     1.6
+++ ex_test.c    2002/01/30 10:33:36     1.7
@@ -140,6 +140,35 @@
         ts_test_fail(TS_CTX, "unexpected catching scope");
 }
 
+TS_TEST(test_cleanup)
+{
+    ex_t ex;
+    volatile int v1;
+    int cleanup;
+
+    ts_test_check(TS_CTX, "cleanup handling");
+
+    v1 = 1234;
+    cleanup = 0;
+    ex_try {
+        v1 = 5678;
+        ex_throw(1, 2, 3);
+    }
+    ex_cleanup {
+        if (v1 != 5678)
+            ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
+        cleanup = 1;
+    }
+    ex_catch (ex) {
+        if (v1 != 5678)
+            ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
+        if (!(ex.ex_class == (void *)1 && ex.ex_object == (void *)2 && ex.ex_value == (void *)3))
+            ts_test_fail(TS_CTX, "unexpected exception contents");
+    }
+    if (!cleanup)
+        ts_test_fail(TS_CTX, "ex_cleanup not executed");
+}
+
 int main(int argc, char *argv[])
 {
     ts_suite_t *ts;
@@ -150,6 +179,7 @@
     ts_suite_test(ts, test_value,       "exception value passing");
     ts_suite_test(ts, test_variables,   "variable value preservation");
     ts_suite_test(ts, test_shield,      "exception shielding");
+    ts_suite_test(ts, test_cleanup,     "cleanup handling");
     n = ts_suite_run(ts);
     ts_suite_free(ts);
     return n;

CVSTrac 2.0.1