Infrastructure: Split the files into subdirectories.
[mLib] / exc.h
diff --git a/exc.h b/exc.h
deleted file mode 100644 (file)
index cd3f1c5..0000000
--- a/exc.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*-c-*-
- *
- * Structured exception handling in C
- *
- * (c) 1998 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the mLib utilities library.
- *
- * mLib is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * mLib 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 Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with mLib; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef MLIB_EXC_H
-#define MLIB_EXC_H
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-#include <setjmp.h>
-
-/*----- Quick documentation -----------------------------------------------*
- *
- * This header file provides some exception handling facilities in C
- * programs.  It modifies the syntax of the language slightly, using the
- * preprocessor.
- *
- * The `throw' expression returns no value.  It has the syntax:
- *
- *   THROW ( expr , expr )
- *
- * The first expression must have type compatible with unsigned integer; it
- * identifies an `exception type'.  The second must have type compatible
- * with pointer to void; it contains the `exception data'.  Control is
- * passed to the current exception handler.
- *
- * The `RETHROW' expression, valid only within an exception handler, causes
- * the current exception to be thrown again.
- *
- * A `try' statement has the syntax:
- *
- *   TRY stat CATCH stat END_TRY;
- *
- * The first statement is called the `test'; the second is the `handler'.
- * During execution of the test, the handler is added to a stack of
- * active exception handlers; the topmost handler on this stack is called
- * the `current' handler.  When execution of the test completes, the
- * corresponding handler is removed from the stack.
- *
- * The test statement may complete in one of these ways:
- *
- *   * Normal completion -- control reaches the end of the statement
- *     normally.
- *
- *   * Throwing an exception -- an exception is thrown when the handler is
- *     the current exception handler.
- *
- *   * By executing a `break' statement.
- *
- *   * By executing the expression `EXIT_TRY' and transferring control to
- *     a point outside the entire `try' statement (e.g., executing a `goto'
- *     or `return' statement).
- *
- * Any other attempt to leave the test causes undefined behaviour.
- *
- * If an exception is thrown while the handler is the current exception
- * handler, it is given control.  The variables `exc_type' and `exc_val'
- * denote the exception type and value respectively -- they are passed
- * unchanged from the `throw' expression which caused the exception.
- * A handler is deactivated before it is invoked; if it causes an
- * exception to be thrown (and does not contain a nested `try' statement)
- * control will be passed to an earlier active handler.
- *
- * Control is passed to handlers using the `longjmp' function.
- *
- * Example:
- *
- *   TRY {
- *     ... something dangerous ...
- *   } CATCH switch (exc_type) {
- *     case EXC_INTERESTING:
- *      ... handle exception ...
- *      break;
- *     default:
- *      ... do tidying up ...
- *      RETHROW;
- *   } END_TRY;
- */
-
-/*----- Exception type allocation -----------------------------------------*
- *
- * Nobody allocates exception types, so we'll just have to try to get along
- * without too many collisions.  An exception type is an unsigned long,
- * which gives us four bytes.  The top two bytes identify the library which
- * `owns' the exception, with special values zero meaning `defined as part
- * of the system' and 0xFFFF providing a shared space of types which can
- * be used by anyone as long as they don't get seen by anyone else.
- *
- * The lower byte pair encodes a type number, and a value which defines
- * the type of the value field (see below).
- */
-
-/* --- Type of an exception --- */
-
-typedef unsigned long exc_extype;
-
-/* --- Build a byte pair from two characters --- *
- *
- * Note the icky casting to handle signed chars.
- */
-
-#define EXC_PAIR(x, y) (((unsigned long)(unsigned char)(x) << 8) |     \
-                       (unsigned long)(unsigned char)(y))
-
-/* --- Allocate an exception number --- */
-
-#define EXC_ALLOC(owner, type) (((unsigned long)(owner) << 16) |       \
-                               (unsigned long)(type))
-
-/* --- Special owner codes --- */
-
-#define EXC_GLOBAL 0u                  /* The global space defined here */
-#define EXC_SHARED 0xFFFFu             /* The shared space for everyone */
-#define EXC_MLIB EXC_PAIR('m', 'L')    /* Space for mLib exceptions */
-
-/*----- Exception values --------------------------------------------------*
- *
- * Exception values can have several different types.  This is a mess, and
- * C doesn't handle it too well, but we can try.  I'll encode the value type
- * as part of the exception type, in the top bits of the bottom byte.  Messy?
- * You betcha.
- */
-
-/* --- Encoding a value type in an extype --- */
-
-#define EXC_TYPECODE(t, w) (((w) & ~0xC0u) | ((t) & 0xC0u))
-
-/* --- The various value types --- */
-
-#define EXC_NOVAL 0x00u                        /* No interesting value */
-#define EXC_INTVAL 0x40u               /* Integer value */
-#define EXC_PTRVAL 0x80u               /* Arbitrary pointer value */
-#define EXC_STRVAL 0xC0u               /* Pointer to character string */
-
-/* --- Allocating exceptions with appropriate types --- */
-
-#define EXC_ALLOCN(o, t) EXC_TYPECODE(EXC_NOVAL,  EXC_ALLOC(o, t))
-#define EXC_ALLOCI(o, t) EXC_TYPECODE(EXC_INTVAL, EXC_ALLOC(o, t))
-#define EXC_ALLOCP(o, t) EXC_TYPECODE(EXC_PTRVAL, EXC_ALLOC(o, t))
-#define EXC_ALLOCS(o, t) EXC_TYPECODE(EXC_STRVAL, EXC_ALLOC(o, t))
-
-/* --- A union representing the type --- */
-
-typedef union exc_exval {
-  int i;
-  void *p;
-  char *s;
-} exc_exval;
-
-/*----- Predefined exceptions ---------------------------------------------*/
-
-/* --- @EXC_NOMEM@ --- *
- *
- * Value:      ---
- *
- * Meaning:    An attempt to allocate memory failed.
- */
-
-#define EXC_NOMEM EXC_ALLOCN(EXC_GLOBAL, 0u)
-
-/* --- @EXC_ERRNO@ --- *
- *
- * Value:      @int errno@ = the error raised
- *
- * Meaning:    Some kind of OS error occurred.
- */
-
-#define EXC_ERRNO EXC_ALLOCI(EXC_GLOBAL, 1u)
-
-/* --- @EXC_OSERROR@ --- *
- *
- * Value:      @os_error *e@ = pointer to error block
- *
- * Meaning:    For RISC OS programmers only: alternative way of propagating
- *             errors.
- */
-
-#define EXC_OSERROR EXC_ALLOCP(EXC_GLOBAL, 1u)
-
-/* --- @EXC_SIGNAL@ --- *
- *
- * Value:      @int sig@ = signal number
- *
- * Meaning:    Report the raising of a signal.
- */
-
-#define EXC_SIGNAL EXC_ALLOCI(EXC_GLOBAL, 2u)
-
-/* --- @EXC_FAIL@ --- *
- *
- * Value:      @const char *p@ = pointer to expanatory string
- *
- * Meaning:    Miscellaneous error.
- */
-
-#define EXC_FAIL EXC_ALLOCS(EXC_GLOBAL, 0xFFu)
-
-/*----- An exception handler block ----------------------------------------*/
-
-/* --- Try to think of this as being opaque --- */
-
-typedef struct __exc_hnd {
-  struct __exc_hnd *next;              /* Pointer to next record down */
-  exc_extype type;                     /* Type of this exception */
-  exc_exval val;                       /* Value of this exception */
-  jmp_buf buf;                         /* Jump buffer when exceptions hit */
-} __exc_hnd;
-
-/*----- Global variables --------------------------------------------------*/
-
-extern __exc_hnd *__exc_list;          /* List of active handlers */
-
-/*----- Macros ------------------------------------------------------------*/
-
-/* --- References to current exception type and value --- */
-
-#define exc_type (__exc_ec.type)
-#define exc_val (__exc_ec.val)
-#define exc_i (__exc_ec.val.i)
-#define exc_p (__exc_ec.val.p)
-#define exc_s (__exc_ec.val.s)
-
-/* --- How it actually works --- *
- *
- * A `try' block is contained within a block which provides an exception
- * handler buffer in automatic storage.  This block is a loop, to allow
- * `break' to escape from it.  It adds the handler buffer to the top of a
- * list, and does a `setjmp' to allow a return here following an exception.
- * The `setjmp' returns zero for the `try' section, and nonzero if there's
- * an exception to `catch'.  It looks a little like this:
- *
- *   do {
- *     __exc_hnd h;
- *     add_handler(&h);
- *     if (!setjmp(h.buf)) {
- *      do <try code> while (0);
- *      remove_handler(&h);
- *     } else
- *      <catch code>
- *   } while (0)
- *
- * Everything else is ugly hacking to make things work.
- */
-
-/* --- Trying things which may cause exceptions --- */
-
-#define TRY do {                                                       \
-  volatile __exc_hnd __exc_ec;                                         \
-  __exc_ec.next = __exc_list;                                          \
-  __exc_list = (__exc_hnd *)&__exc_ec;                                 \
-  if (!setjmp(*(jmp_buf *)&__exc_ec.buf /* very nasty! */ )) { do
-
-#define EXIT_TRY do __exc_list = __exc_ec.next; while (0)
-#define CATCH while (0); EXIT_TRY; } else
-
-#define END_TRY } while (0)
-
-/* --- Raising exceptions --- */
-
-#define THROW __exc_throw
-#define RETHROW __exc_rethrow(__exc_ec.type, __exc_ec.val)
-
-/*----- Functions ---------------------------------------------------------*/
-
-/* --- @exc_uncaught@ --- *
- *
- * Arguments:  @void (*proc)(exc_extype type, exc_exval val) = new handler
- *
- * Returns:    Pointer to the old handler value.
- *
- * Use:                Sets the handler for uncaught exceptions.
- */
-
-typedef void (*exc__uncaught)(exc_extype /*type*/, exc_exval /*val*/);
-extern exc__uncaught exc_uncaught(exc__uncaught /*proc*/);
-
-/* --- @__exc_throw@ --- *
- *
- * Arguments:  @exc_extype type@ = type of exception to throw
- *
- * Returns:    Doesn't
- *
- * Use:                NOT FOR USER CONSUMPTION.  Reads an appropriate exception
- *             value and throws an exception.
- */
-
-extern void __exc_throw(exc_extype /*type*/, ...);
-
-/* --- @__exc_rethrow@ --- *
- *
- * Arguments:  @exc_extype type@ = type of exception to throw
- *             @exc_exval val@ = value of exception to throw
- *
- * Returns:    Doesn't
- *
- * Use:                NOT FOR USER CONSUMPTION.  Does the donkey-work of raising
- *             an exception.
- */
-
-extern void __exc_rethrow(exc_extype /*type*/, exc_exval /*val*/);
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif