|
|
1.1 ! root 1: /* ! 2: * Error-handling for an application. ! 3: */ ! 4: ! 5: /* ! 6: *-IMPORTS: ! 7: * <sys/compat.h> ! 8: * CONST ! 9: * USE_PROTO ! 10: * ARGS () ! 11: * <setjmp.h> ! 12: * longjmp () ! 13: * <stdarg.h> ! 14: * va_list ! 15: * va_start () ! 16: * va_end () ! 17: * <stdio.h> ! 18: * stderr ! 19: * fprintf () ! 20: * putc () ! 21: * vfprintf () ! 22: * <stdlib.h> ! 23: * EXIT_FAILURE ! 24: * exit () ! 25: */ ! 26: ! 27: #include <sys/compat.h> ! 28: #include <setjmp.h> ! 29: #include <stdarg.h> ! 30: #include <stdio.h> ! 31: #include <stdlib.h> ! 32: ! 33: #include "ehand.h" ! 34: ! 35: ! 36: /* ! 37: * Some ancient systems do not define EXIT_SUCCESS or EXIT_FAILURE. ! 38: */ ! 39: ! 40: #ifndef EXIT_FAILURE ! 41: #define EXIT_FAILURE 1 ! 42: #endif ! 43: ! 44: ! 45: ehand_t * estack_base; ! 46: ! 47: ! 48: /* ! 49: * Report an error, but do not throw to a handler. ! 50: */ ! 51: ! 52: #if USE_PROTO ! 53: void (report_error) (CONST char * fmt, ...) ! 54: #else ! 55: void ! 56: report_error ARGS ((fmt)) ! 57: CONST char * fmt; ! 58: #endif ! 59: { ! 60: va_list args; ! 61: ! 62: va_start (args, fmt); ! 63: (void) fprintf (stderr, "ERROR : "); ! 64: (void) vfprintf (stderr, fmt, args); ! 65: va_end (args); ! 66: ! 67: putc ('\n', stderr); ! 68: } ! 69: ! 70: ! 71: /* ! 72: * Throw an error - write out an error report and throw to the last installed ! 73: * handler (or call exit () if there is no installed handler). ! 74: */ ! 75: ! 76: #if USE_PROTO ! 77: NO_RETURN void (throw_error) (CONST char * fmt, ...) ! 78: #else ! 79: NO_RETURN void ! 80: throw_error ARGS ((fmt)) ! 81: CONST char * fmt; ! 82: #endif ! 83: { ! 84: va_list args; ! 85: ! 86: va_start (args, fmt); ! 87: (void) fprintf (stderr, "ERROR : "); ! 88: (void) vfprintf (stderr, fmt, args); ! 89: va_end (args); ! 90: ! 91: putc ('\n', stderr); ! 92: ! 93: if (estack_base == NULL) ! 94: exit (EXIT_FAILURE); ! 95: ! 96: longjmp (estack_base->eh_buf, -1); ! 97: } ! 98: ! 99: ! 100: /* ! 101: * This function can be called when the code to pop the current exception ! 102: * handler detects that the stack base is not where it should be (implying ! 103: * that an inner function did not pop its handler). ! 104: */ ! 105: ! 106: #if USE_PROTO ! 107: void (error_error) (CONST char * file, int line) ! 108: #else ! 109: void ! 110: error_error ARGS ((file, line)) ! 111: CONST char * file; ! 112: int line; ! 113: #endif ! 114: { ! 115: fprintf (stderr, "FATAL ERROR : Exception handler nesting error "); ! 116: fprintf (stderr, "detected in file\n '%s' at line %d\n", file, line); ! 117: ! 118: exit (EXIT_FAILURE); ! 119: } ! 120: ! 121: ! 122: /* ! 123: * Chain to the next error-handler in the stack of error handlers after the ! 124: * handler passed to us. ! 125: */ ! 126: ! 127: #if USE_PROTO ! 128: void (chain_error) (ehand_t * err) ! 129: #else ! 130: void ! 131: chain_error ARGS ((err)) ! 132: ehand_t * err; ! 133: #endif ! 134: { ! 135: if (err != estack_base) ! 136: error_error ("chain_error, " __FILE__, __LINE__); ! 137: ! 138: if ((estack_base = err->eh_next) == NULL) ! 139: exit (EXIT_FAILURE); ! 140: ! 141: longjmp (estack_base->eh_buf, -1); ! 142: } ! 143:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.