OSSP CVS Repository

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

Check-in Number: 1633
Date: 2002-Jan-25 16:25:51 (local)
2002-Jan-25 15:25:51 (UTC)
User:rse
Branch:
Comment: Welcome OSSP ex, another new-born OSSP library. This is the first cut for a C exception handling library. Read ex.pod for details...
Tickets:
Inspections:
Files:
ossp-pkg/ex/Makefile      added-> 1.1
ossp-pkg/ex/README      added-> 1.1
ossp-pkg/ex/TODO      added-> 1.1
ossp-pkg/ex/ex.c      added-> 1.1
ossp-pkg/ex/ex.h      added-> 1.1
ossp-pkg/ex/ex.pod      added-> 1.1
ossp-pkg/ex/ex_test.c      added-> 1.1

ossp-pkg/ex/Makefile -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,23 ----
+ 
+ CC      = /usr/opkg/bin/gcc
+ CFLAGS  = -Wall -O2 -I.
+ LDFLAGS = 
+ AR      = ar
+ RANLIB  = ranlib
+ 
+ all: libex.a ex_test
+ 
+ ex_test: ex_test.o libex.a
+        $(CC) $(LDFLAGS) -o ex_test ex_test.o libex.a
+ 
+ libex.a: ex.o
+        rm -f $@
+        $(AR) cr $@ ex.o
+        $(RANLIB) $@
+ 
+ clean:
+        rm -f ex_test *.a *.o *.core
+ 
+ check: ex_test
+        ./ex_test
+ 


ossp-pkg/ex/README -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1 ----
+ 


ossp-pkg/ex/TODO -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,4 ----
+ - default handler
+ - sigsetjmp (Why can't "real" exceptions be caught?)
+ - pth
+ - disable throwing


ossp-pkg/ex/ex.c -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,29 ----
+ /*
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP ex, an exception library
+ **  which can be found at http://www.ossp.org/pkg/ex/.
+ **
+ **  This program is free software; you can redistribute it and/or
+ **  modify it under the terms of the GNU General Public  License
+ **  as published by the Free Software Foundation; either version
+ **  2.0 of the License, or (at your option) any later version.
+ **
+ **  This program is distributed in the hope that it will be useful,
+ **  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ **  General Public License for more details.
+ **
+ **  You should have received a copy of the GNU General Public License
+ **  along with this file; if not, write to the Free Software
+ **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ **  USA, or contact the OSSP project <ossp@ossp.org>.
+ **
+ **  ex.c: exception handling (compiler part)
+ */
+ 
+ #include "ex.h"
+ 
+ ex_ctx_t __ex_ctx_global;
+ 


ossp-pkg/ex/ex.h -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,134 ----
+ /*
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP ex, an exception library
+ **  which can be found at http://www.ossp.org/pkg/ex/.
+ **
+ **  This program is free software; you can redistribute it and/or
+ **  modify it under the terms of the GNU General Public  License
+ **  as published by the Free Software Foundation; either version
+ **  2.0 of the License, or (at your option) any later version.
+ **
+ **  This program is distributed in the hope that it will be useful,
+ **  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ **  General Public License for more details.
+ **
+ **  You should have received a copy of the GNU General Public License
+ **  along with this file; if not, write to the Free Software
+ **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ **  USA, or contact the OSSP project <ossp@ossp.org>.
+ **
+ **  ex.h: exception handling (pre-processor part)
+ */
+ 
+ #ifndef __TEXAS_H__
+ #define __TEXAS_H__
+ 
+ /* the required ISO-C standard facilities */
+ #include <stdio.h>   /* for NULL */
+ #include <setjmp.h>  /* for jmp_buf, setjmp(3), longjmp(3) */
+ 
+ /* determine how the current function name can be fetched */
+ #if (   defined(__STDC__) \
+      && defined(__STDC_VERSION__) \
+      && __STDC_VERSION__ >= 199901L)
+ #define __TEXAS_FUNC__ __func__      /* ISO C99 compliant */
+ #elif (   defined(__GNUC__) \
+        && defined(__GNUC_MINOR__) \
+        && (   __GNUC__ > 2 \
+            || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)))
+ #define __TEXAS_FUNC__ __FUNCTION__  /* gcc >= 2.8 */
+ #else
+ #define __TEXAS_FUNC__ "#NA#"        /* not available */
+ #endif
+ 
+ /* declare the exception type (public) */
+ typedef struct {
+     /* throw value */
+     void *ex_class;
+     void *ex_object;
+     void *ex_value;
+     /* throw point */
+     char *ex_file; 
+     int   ex_line; 
+     char *ex_func;
+ } ex_t;
+ 
+ /* declare the exception context type (private) */
+ typedef struct {
+     jmp_buf      *ctx_jbprev; /* previous jump buffer */
+     int           ctx_caught; /* flag whether exception was caught */
+     volatile ex_t ctx_ex;     /* the exception temporary storage */
+ } ex_ctx_t;
+ 
+ /* ex context (default requires linking against libex) */
+ #ifndef __ex_ctx
+ #define __ex_ctx (&__ex_ctx_global)
+ extern ex_ctx_t __ex_ctx_global;
+ #endif
+ 
+ /* block for trying execution */
+ #define ex_try \
+     { \
+         jmp_buf *__ex_jbprev; \
+         jmp_buf __ex_jbme; \
+         __ex_jbprev = __ex_ctx->ctx_jbprev; \
+         __ex_ctx->ctx_jbprev = &__ex_jbme; \
+         if (setjmp(__ex_jbme) == 0) { \
+             if (1)
+ 
+ /* block for catching an exception */
+ #define ex_catch(e) \
+             else { \
+             } \
+             __ex_ctx->ctx_caught = 0; \
+         } \
+         else { \
+             __ex_ctx->ctx_caught = 1; \
+         } \
+         __ex_ctx->ctx_jbprev = __ex_jbprev; \
+     } \
+     if (!__ex_ctx->ctx_caught || ((e) = __ex_ctx->ctx_ex, 0)) { \
+     } \
+     else
+ 
+ /* throw a new exception */
+ #define ex_throw(c,o,v) \
+     (__ex_ctx->ctx_jbprev == NULL ? \
+      (abort(), 0) : \
+      ( __ex_ctx->ctx_ex.ex_class  = (void *)(c), \
+        __ex_ctx->ctx_ex.ex_object = (void *)(o), \
+        __ex_ctx->ctx_ex.ex_value  = (void *)(v), \
+        __ex_ctx->ctx_ex.ex_file   = __FILE__, \
+        __ex_ctx->ctx_ex.ex_line   = __LINE__, \
+        __ex_ctx->ctx_ex.ex_func   = __TEXAS_FUNC__, \
+        longjmp(*(__ex_ctx->ctx_jbprev), 1), \
+        0 \
+      ) \
+     )
+ 
+ /* re-throw a caught exception */
+ #define ex_rethrow \
+     (__ex_ctx->ctx_jbprev == NULL ? \
+      (abort(), 0) : \
+      (longjmp(*(__ex_ctx->ctx_jbprev), 1), 0) \
+     )
+ 
+ /* optional namespace mapping */
+ #if !defined(__cplusplus) && !defined(__TEXAS_NO_CXX_NS__)
+ #define try      ex_try
+ #define catch    ex_catch
+ #define throw    ex_throw
+ #define rethrow  ex_rethrow
+ #endif
+ #if !defined(__TEXAS_NO_SIMPLE_NS__)
+ #define Try      ex_try
+ #define Catch    ex_catch
+ #define Throw    ex_throw
+ #define Rethrow  ex_rethrow
+ #endif
+ 
+ #endif /* __TEXAS_H__ */
+ 


ossp-pkg/ex/ex.pod -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,220 ----
+ ##
+ ##  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ ##  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ ##
+ ##  This file is part of OSSP ex, an exception library
+ ##  which can be found at http://www.ossp.org/pkg/ex/.
+ ##
+ ##  This program is free software; you can redistribute it and/or
+ ##  modify it under the terms of the GNU General Public  License
+ ##  as published by the Free Software Foundation; either version
+ ##  2.0 of the License, or (at your option) any later version.
+ ##
+ ##  This program is distributed in the hope that it will be useful,
+ ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ##  General Public License for more details.
+ ##
+ ##  You should have received a copy of the GNU General Public License
+ ##  along with this file; if not, write to the Free Software
+ ##  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ##  USA, or contact the OSSP project <ossp@ossp.org>.
+ ##
+ ##  ex.pod: exception library manual page
+ ##
+ 
+ =pod
+ 
+ =head1 NAME
+ 
+ B<OSSP ex> - Exception Library
+ 
+ =head1 SYNOPSIS
+ 
+ B<ex_t> I<variable>;
+ 
+ B<ex_try> { ... } B<ex_catch> (I<variable>) { ... }
+ 
+ B<ex_throw>(I<class>, I<object>, I<value>);
+ 
+ B<ex_rethrow>;
+ 
+ =head1 DESCRIPTION
+ 
+ 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
+ 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
+ nested sub-routine to a parent routine. All intermediate routines
+ no longer have to make sure that the exceptional return codes from
+ sub-routines are correctly passed back to the parent.
+ 
+ =head2 EXCEPTIONS
+ 
+ An exception is a triple E<lt>I<class>,I<object>,I<value>E<gt> where
+ I<class> identifies the class of the exception thrower, I<object>
+ identifies the particular class instance of the exception thrower, and
+ I<value> is the exceptional return code the thrower wants to send to the
+ catcher. All three parts are of type C<void *> internally, but every
+ value can be used which can be (automatically) casted to a C<void *>.
+ Exceptions are created on-the-fly by the B<ex_throw> command.
+ 
+ =head2 APPLICATION PROGRAMMER INTERFACE (API)
+ 
+ The B<OSSP ex> API consists of four different elements:
+ 
+ =over 4
+ 
+ =item B<ex_t> I<variable>;
+ 
+ This is the declaration of an exception variable. It is usually never
+ initialized manually. Instead it is initialized by an B<ex_catch> block
+ and just used read-only inside the block. Such a variable of type
+ B<ex_t> consists of six attributes:
+ 
+ =over 2
+ 
+ =item C<void *>I<ex_class>
+ 
+ This is the I<class> argument of the B<ex_throw> call which created
+ the exception. This globally and uniquely identifies the class of
+ I<ex_value>. Usually this is a pointer to a static object (variable,
+ structure or function) which identifies the thrower.
+ 
+ =item C<void *>I<ex_object>
+ 
+ This is the I<object> argument of the B<ex_throw> call which created
+ the exception. This globally and uniquely identifies the class instance
+ of I<ex_value> (in case multiple instances exists). Usually this a
+ pointer to a dynamic object (structure) which identifiers the particular
+ instance of the thrower.
+ 
+ =item C<void *>I<ex_value>
+ 
+ This is the I<value> argument of the B<ex_throw> call which created the
+ exception. This is the exceptional return code which uniquely identifies
+ the type of exception. Usually this is the value which is C<return>ed
+ if no exceptions would be thrown. In the simple case this is just a
+ numerical return code. In the complex case this can be a pointer to an
+ arbitrary complex data structure describing the exception.
+ 
+ =item C<char *>I<ex_file> 
+ 
+ This is the file name of the source where the B<ex_throw> call
+ was performed. It is provided as an additional information about
+ the throw point and is intended mainly for tracing and debugging
+ purposes.
+ 
+ =item C<int> I<ex_line>
+ 
+ This is the line number inside the source file name where the
+ B<ex_throw> call was performed. It is provided as an additional
+ information about the throw point and is intended mainly for tracing and
+ debugging purposes.
+ 
+ =item C<char *>I<ex_func>
+ 
+ This is the function name (if determinable, else "C<#NA#>") inside
+ the source file name where the B<ex_throw> call was performed. It is
+ provided as an additional information about the throw point and is
+ intended mainly for tracing and debugging purposes.
+ 
+ =back
+ 
+ =item B<ex_try> { ... } 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
+ 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
+ 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
+ allowed to jump into it via C<goto> or C<longjmp>(3) or out of it via
+ C<return>, C<goto> or C<longjmp>(3) because there is some hidden setup
+ and cleanup that needs to be done by B<OSSP ex> regardless of whether an
+ exception is caught. Jumping into an B<ex_try> clause would avoid doing
+ the setup, and jumping out of it would avoid doing the cleanup. In both
+ cases the result is a broken exception facility.
+ 
+ The B<ex_catch> block is a regular ISO-C language block without any
+ restrictions.
+ 
+ =item B<ex_throw>(I<class>, I<object>, I<value>);
+ 
+ This is second main construct. It builds an exception from the supplied
+ arguments and throws it. If an B<ex_try>/B<ex_catch> clause exists in
+ the dynamic scope of the B<ex_throw> call, this exception is copied into
+ the I<variable> of B<ex_catch> and the program control flow is continued
+ in the B<ex_catch> block. If no B<ex_try>/B<ex_catch> clause exists in
+ the dynamic scope of the B<ex_throw> call, the program C<abort>(3)s. The
+ B<ex_throw> can be performed everywhere, including inside B<ex_try> and
+ B<ex_catch> blocks.
+ 
+ =item B<ex_rethrow>;
+ 
+ This is only valid within an B<ex_catch> block and re-throws
+ the current exception (in I<variable>). It is similar to the
+ call B<ex_throw>(I<variable>.ex_class, I<variable>.ex_object,
+ 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.
+ 
+ =back
+ 
+ =head1 EXAMPLE
+ 
+  #include "ex.h"
+ 
+  ex_t e;
+ 
+  ex_try {
+      ...
+      ex_throw (..., ..., 123);
+      ...
+  }
+  ex_catch (e) {
+      ...
+      if ((int)e->ex_value == 123)
+          ...
+      else if ((int)e->ex_value == 456)
+          ...
+      else
+          ex_rethrow;
+      ...
+  }
+ 
+ =head1 SEE ALSO
+ 
+ C++ try/catch/throw language directives;
+ setjmp(3), longjmp(3), sigsetjmp(3), siglongjmp(3).
+ 
+ =head1 HISTORY
+ 
+ B<OSSP ex> was invented in January 2002 by Ralf S. Engelschall for use
+ inside the OSSP project. Its creation was prompted by the requirement to
+ reduce the error handling inside B<OSSP lmtp2nntp>. The implementation
+ is partly derived from B<cexcept> 2.0.0, a similar library written 2000
+ by Adam M. Costello E<lt>amc@cs.berkeley.eduE<gt> and Cosmin Truta
+ E<lt>cosmin@cs.toronto.eduE<gt>.
+ 
+ =head1 AUTHORS
+ 
+  Ralf S. Engelschall
+  rse@engelschall.com
+  www.engelschall.com
+ 
+ =cut
+ 


ossp-pkg/ex/ex_test.c -> 1.1

*** /dev/null    Sat Nov 23 00:53:44 2024
--- -    Sat Nov 23 00:54:11 2024
***************
*** 0 ****
--- 1,104 ----
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <time.h>
+ 
+ #include "ex.h"
+ 
+ /* === foo.h === */
+ 
+ typedef enum {
+     FOO_OK = 0,
+     FOO_ERR_1,
+     FOO_ERR_2,
+     FOO_ERR_3
+ } foo_rc_t;
+ 
+ #define FOO_TEXAS
+ 
+ #ifdef FOO_TEXAS
+ 
+ #include "ex.h"
+ #define FOO_ERR(err) \
+      (ex_throw(FOO_CLASS, NULL, FOO_ERR_##err), FOO_ERR_##err)
+ #else
+ #define FOO_ERR(err) \
+      (FOO_ERR_##err)
+ #endif
+ 
+ #define FOO_EX2RC(e) \
+     ((foo_rc_t)((e)->ex_value))
+ #define FOO_CLASS (&foo_class)
+ extern int foo_class;
+ 
+ foo_rc_t foo_func(void);
+ 
+ /* === foo.c === */
+ 
+ int foo_class;
+ 
+ static int foo_sub(void)
+ {
+     fprintf(stderr, "mark4\n");
+     if (random() % 2)
+         return FOO_OK;
+     return FOO_ERR(1);
+ }
+ 
+ foo_rc_t foo_func(void)
+ {
+     fprintf(stderr, "mark3\n");
+     foo_sub();
+     if (random() % 2)
+         return FOO_OK;
+     return FOO_ERR(2);
+ }
+ 
+ /* === test.c === */
+ 
+ int main(int argc, char *argv[])
+ {
+     srandom((unsigned int)time(NULL));
+     ex_t e;
+     
+     fprintf(stderr, "main-0\n");
+     for (;;) {
+         fprintf(stderr, "main-1\n");
+         try {
+             fprintf(stderr, "main-2\n");
+             foo_func();
+             fprintf(stderr, "main-3\n");
+             for (;;) {
+                 fprintf(stderr, "main-4\n");
+                 try {
+                     fprintf(stderr, "main-5\n");
+                     foo_func();
+                     fprintf(stderr, "main-6\n");
+                 }
+                 catch (e) {
+                     fprintf(stderr, "main-7\n");
+                     fprintf(stderr, "  %s@%s:%d class=0x%lx object=0x%lx value=0x%lx\n", 
+                             e.ex_func, e.ex_file, e.ex_line, (long)e.ex_class, (long)e.ex_object, (long)e.ex_value);
+                     if (e.ex_class == FOO_CLASS && (foo_rc_t)(e.ex_value) == FOO_ERR_1)
+                         fprintf(stderr, "  exception handling\n");
+                     else {
+                         fprintf(stderr, "  exception rethrowing\n");
+                         ex_rethrow;
+                     }
+                     fprintf(stderr, "main-8\n");
+                 }
+                 fprintf(stderr, "main-9\n");
+             }
+             fprintf(stderr, "main-10\n");
+         }
+         catch (e) {
+             fprintf(stderr, "main-11\n");
+             fprintf(stderr, "   %s@%s:%d class=0x%lx object=0x%lx value=0x%lx\n", 
+                     e.ex_func, e.ex_file, e.ex_line, (long)e.ex_class, (long)e.ex_object, (long)e.ex_value);
+             fprintf(stderr, "main-12\n");
+         }
+     }
+     fprintf(stderr, "main-0\n");
+     return 0;
+ }
+ 

CVSTrac 2.0.1