Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: $Revision: 1.6.2.16 $; site ada-uts.UUCP Path: utzoo!watmath!clyde!cbosgd!cbdkc1!desoto!cord!pierce!bentley!hoxna!houxm!mhuxt!mhuxr!ulysses!allegra!mit-eddie!think!ada-uts!richw From: richw@ada-uts.UUCP Newsgroups: net.lang.c Subject: Re: Exception Handling? Impossible! Message-ID: <10200004@ada-uts.UUCP> Date: Fri, 23-Aug-85 19:15:00 EDT Article-I.D.: ada-uts.10200004 Posted: Fri Aug 23 19:15:00 1985 Date-Received: Tue, 27-Aug-85 06:46:28 EDT References: <10200002@ada-uts.UUCP> Lines: 145 Nf-ID: #R:ada-uts:10200002:ada-uts:10200004:000:3644 Nf-From: ada-uts!richw Aug 23 19:15:00 1985 I think I've figured out how to improve upon my first try (the original note) based on Robert Stroud's mentioning a stack for setjmp/longjmp environments. ALL of the problems (except for the fairly trivial #5) which I mentioned in the first note seem to be taken care of now. I also fixed a problem not realized originally (i.e. why a stack is needed instead of a single environment...) IN ANY CASE, my new test files (test.c and add.c) and the files which encapsulate the exception handling mechanism (exceptions.{c,h}) follow. I'm not claiming the mechanism is bug-free!! I still haven't read (or found) the papers suggested, so I'm still kinda "wingin'-it"... I DO know that THIS test case seems to work. Again, I'd love comments... -- Rich Wagner P.S. Because I use a funny terminal, I can't directly type left and right-square-brackets. In the following code, these are represented by [ and ], respectively. P.P.S. Many thanks to Robert Stroud !! ------------------------------------------------------------------------- /********* exceptions.h *********/ #include #include typedef char *Exception; extern jmp_buf _env_stack[]; extern int _env_index, _bad_index; extern Exception _exc; #define Begin { if (_env_index == _bad_index) {\ fflush(stdout);\ fprintf(stderr, "Handlers nested to deeply\n");\ exit(1);}\ if (!setjmp(_env_stack[_env_index++])) { #define Except _env_index--; #define When(e) } else if (_exc == e) {\ _env_index--; #define Others } else if (1) {\ _env_index--; #define End } else {\ fflush(stdout);\ fprintf(stderr,"Unhandled Exception: %s\n",_exc);\ exit(1);\ } } #define raise(e) {_exc = e; longjmp(_env_stack[_env_index-1],1); } ------------------------------------------------------------------------- /********* exceptions.c *********/ #include #define STACK_SIZE 50 jmp_buf _env_stack[STACK_SIZE]; int _env_index = 0; int _bad_index = STACK_SIZE; char *_exc; ------------------------------------------------------------------------- /********* test.c *********/ #include #include "exceptions.h" extern Exception overflow; extern Exception underflow; main() { int x; Begin fprintf(stderr, "Calling add(4,1)\n"); x = add(4,1); fprintf(stderr, "After call to add(4,1)\n"); Except When(overflow) fprintf(stderr, "Overflow caught but not expected\n"); End; Begin fprintf(stderr, "Calling add(4,7) -- expect overflow\n"); x = add(4,7); fprintf(stderr, "After call to add(4,7)\n"); fprintf(stderr, "Expected exception not raised"); Except When(overflow) fprintf(stderr, "Overflow caught\n"); End; Begin fprintf(stderr, "Calling add(-4,-7) -- expect underflow\n"); x = add(-4,-7); fprintf(stderr, "After call to add(-4,-7)\n"); fprintf(stderr, "Expected exception not raised"); Except When(overflow) fprintf(stderr, "Overflow caught but not expected\n"); End; fprintf(stderr, "Last line of main\n"); } ------------------------------------------------------------------------- /********* add.c *********/ #include "exceptions.h" Exception overflow = "Overflow"; Exception underflow = "Underflow"; static my_add(a, b) int a, b; { a += b; if (a >= 10) raise(overflow); if (a <= -10) raise(underflow); return (a); } add(a, b) int a, b; { Begin return my_add(a,b); Except When(overflow) raise(overflow); When(underflow) raise(underflow); End; }