From owner-freebsd-java Wed Nov 3 18:13:30 1999 Delivered-To: freebsd-java@freebsd.org Received: from bubba.whistle.com (bubba.whistle.com [207.76.205.7]) by hub.freebsd.org (Postfix) with ESMTP id 838F514CCA for ; Wed, 3 Nov 1999 18:10:19 -0800 (PST) (envelope-from archie@whistle.com) Received: (from archie@localhost) by bubba.whistle.com (8.9.2/8.9.2) id SAA82085 for freebsd-java@freebsd.org; Wed, 3 Nov 1999 18:10:19 -0800 (PST) From: Archie Cobbs Message-Id: <199911040210.SAA82085@bubba.whistle.com> Subject: try { } catch { } finally { } in C! To: freebsd-java@freebsd.org Date: Wed, 3 Nov 1999 18:10:18 -0800 (PST) X-Mailer: ELM [version 2.4ME+ PL54 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-java@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Did you know that try { } catch { } finally { } is possible from C? Well, GNU C anyway.. Example (using the header file included below): #include #include #include #include #include #include "trycatch.h" int func() { int r = (int)random() % 32; if (r > 16) { printf("func() throwing %d\n", 7); THROW(7); } printf("func() returning %d\n", r); return r; } int main() { int r = 123; srandom(time(NULL)); TRY { int y; printf("main() try #1\n"); printf("main() calling func()\n"); y = func(); printf("func() returned %d\n", r); y = (int)random() % 32; if (y > 20) { printf("main() throwing %d\n", -y); THROW(-y); } printf("main() end of try part\n"); printf("main() RETURN()'ing %d\n", r); RETURN(r); } CATCH(int, x) { printf("main() start of catch, x=%d\n", x); } FINALLY { printf("main() start of finally, r=%d\n", r); } ENDTRY; printf("main() returning\n"); return(0); } -Archie ___________________________________________________________________________ Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com /* This is a per-thread global variable */ jmp_buf _tryJmpBuf; /* This precedes the TRY block */ #define TRY { \ __label__ _finallyLabel; \ volatile jmp_buf _tryJmpBufSave; \ void *_finallyReturn = NULL; \ int _thrownValue; \ \ memcpy((void *)&_tryJmpBufSave, \ _tryJmpBuf, sizeof(jmp_buf)); \ if ((_thrownValue = setjmp(_tryJmpBuf)) == 0) /* This precedes the CATCH block */ #define CATCH(type, var) \ else { \ type var = (type) _thrownValue; \ \ memcpy(&_tryJmpBuf, (void *)&_tryJmpBufSave, \ sizeof(jmp_buf)); \ if ((_thrownValue = setjmp(_tryJmpBuf)) == 0) { /* Use this instead of CATCH() when you don't want to catch anything */ #define NOCATCH() { \ if (0) { /* This precedes the FINALLY block */ #define FINALLY } else { \ memcpy(&_tryJmpBuf, (void *)&_tryJmpBufSave,\ sizeof(jmp_buf)); \ } \ } \ (void)&&_finallyLabel; /* avoid gcc warning */ \ _finallyLabel: /* This is requried after the FINALLY block */ #define ENDTRY if (_thrownValue != 0) \ THROW(_thrownValue); \ if (_finallyReturn != NULL) \ goto *_finallyReturn; \ } /* Throw an exception 't' which must be castable to type int */ #define THROW(t) do { \ int value = (int) t; \ assert(value != 0); \ longjmp(_tryJmpBuf, value); \ } while (0) /* For use only within TRY or CATCH blocks (not FINALLY) */ #define RETURN(x...) do { \ __label__ _returnLabel; \ _finallyReturn = &&_returnLabel; \ goto _finallyLabel; \ _returnLabel: \ return x; \ } while (0) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-java" in the body of the message