|
|
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.