1 /************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1996,1997 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* */
34 /* Author: Richard Caley (rjc@cstr.ed.ac.uk) */
35 /* Date: Thu Aug 14 1997 */
36 /* -------------------------------------------------------------------- */
37 /* Fatal error calls. */
38 /* */
39 /*************************************************************************/
40
41 #ifndef __EST_ERROR_H__
42 #define __EST_ERROR_H__
43
44 /* may get included from C */
45 #ifdef __cplusplus
46 #include <cstdarg>
47 #include <cstdio>
48 #else
49 #include <stdarg.h>
50 #include <stdio.h>
51 #endif
52
53 #include <setjmp.h>
54 #include "EST_unix.h"
55
56
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60
61 #define MAX_ERROR_MESSAGE_LENGTH 1024
62
63 typedef void (*EST_error_handler)(const char *format, ...);
64 extern const char *EST_error_where;
65 extern char *EST_error_message;
66
67 extern EST_error_handler EST_bug_func;
68 extern EST_error_handler EST_error_func;
69 extern EST_error_handler EST_sys_error_func;
70 extern EST_error_handler EST_warning_func;
71 extern EST_error_handler old_error_function;
72 extern EST_error_handler old_sys_error_function;
73
74 extern FILE *EST_error_stream;
75 extern FILE *EST_warning_stream;
76
77 extern jmp_buf *est_errjmp;
78 extern long errjmp_ok;
79
80 extern void EST_errors_default();
81 extern void EST_errors_quiet();
82
83 void EST_quiet_error_fn(const char *format, ...);
84 void EST_quiet_sys_error_fn(const char *format, ...);
85
86
87 #define _rxp_S_(X) #X
88 #define _rxp_s_(X) _rxp_S_(X)
89
90 #define EST_bug (EST_error_where = __FILE__ ", line " _rxp_s_(__LINE__)),\
91 (*EST_bug_func)
92
93 #if defined(EST_DEBUGGING)
94 #define EST_exit(N) abort()
95 #define EST_error (EST_error_where = __FILE__ ", line " _rxp_s_(__LINE__)),\
96 (*EST_error_func)
97 #define EST_warning (EST_error_where = __FILE__ ", line " _rxp_s_(__LINE__)),\
98 (*EST_warning_func)
99 #define EST_sys_error (EST_error_where = __FILE__ ", line " _rxp_s_(__LINE__)),\
100 (*EST_sys_error_func)
101 #else
102
103 #define EST_exit(N) exit(N)
104 #define EST_error (EST_error_where = NULL),\
105 (*EST_error_func)
106 #define EST_warning (EST_error_where = NULL),\
107 (*EST_warning_func)
108 #define EST_sys_error (EST_error_where = NULL),\
109 (*EST_sys_error_func)
110 #endif
111
112 #define est_error_throw() (est_errjmp ? longjmp(*est_errjmp,1) : (void)EST_exit(-1))
113 #define est_error() est_error_throw()
114
115 #define CATCH_ERRORS_SKEL( INIT,CLEANUP) \
116 { \
117 INIT \
118 jmp_buf *old_errjmp = est_errjmp; \
119 int old_errjmp_ok = errjmp_ok; \
120 errjmp_ok =1; \
121 est_errjmp = (jmp_buf *)malloc(sizeof(jmp_buf)); \
122 int jmp_val = setjmp(*est_errjmp); \
123 if (jmp_val) { free(est_errjmp); est_errjmp = old_errjmp; errjmp_ok = old_errjmp_ok; CLEANUP} \
124 if (jmp_val)
125
126 #define CATCH_ERRORS() \
127 CATCH_ERRORS_SKEL(\
128 const int est_err_quiet=0; \
129 , \
130 ;)
131
132 #define CATCH_ERRORS_QUIET() \
133 CATCH_ERRORS_SKEL(\
134 const int est_err_quiet=1; \
135 EST_error_handler old_error_function=EST_error_func; \
136 EST_error_handler old_sys_error_function=EST_sys_error_func; \
137 EST_error_func = EST_quiet_error_fn; \
138 EST_sys_error_func = EST_quiet_sys_error_fn; \
139 , \
140 EST_error_func=old_error_function; \
141 EST_sys_error_func=old_sys_error_function; \
142 )
143
144 #define END_CATCH_ERRORS() \
145 free(est_errjmp); \
146 est_errjmp = old_errjmp; \
147 errjmp_ok = old_errjmp_ok; \
148 if (est_err_quiet) { \
149 EST_error_func=old_error_function; \
150 EST_sys_error_func=old_sys_error_function; \
151 } \
152 } while (0)
153
154 /** Defines the attitude of a call to possible fatal errors.
155 * Passing one of these values to a function tells it how much
156 * care it needs to take to avoid calls to EST_error.
157 *
158 * These need snappier names.
159 * the numbers are their for historical reasons
160 */
161 enum EST_error_behaviour
162 {
163 /** Function will not normally return an error unless something
164 * really bad has gone wrong. For feature lookup, will return
165 * default value if feature doesn't exist
166 */
167 est_errors_checked = 0,
168
169 /** Function will throw errors when feature doesn't exist.
170 */
171 est_errors_allowed = 1,
172
173 /** No fatal errors allowed. Function must catch all EST_error calls.
174 * Will *always* return a default value.
175 */
176 est_errors_never = 2
177 };
178
179 #ifdef __cplusplus
180 }
181
182 #include "EST_String.h"
183
184 /* These are used to pass values into error functions inside */
185 /* templates. For classes we can define a function cast to EST_String, */
186 /* but we need the basic versions. */
187
error_name(const EST_String val)188 inline const char *error_name(const EST_String val) {return val;}
error_name(const void * val)189 inline const char *error_name(const void *val) {return EST_String::cat("<<ptr:", EST_String::Number((long)val, 16), ">>");}
error_name(const EST_Regex val)190 inline const char *error_name(const EST_Regex val) {return val.tostring();}
error_name(int val)191 inline const char *error_name(int val) {return EST_String::Number(val);}
error_name(long val)192 inline const char *error_name(long val) {return EST_String::Number(val);}
error_name(float val)193 inline const char *error_name(float val) {return EST_String::Number(val);}
error_name(double val)194 inline const char *error_name(double val) {return EST_String::Number(val);}
error_name(char val)195 inline const char *error_name(char val) {return EST_String::FromChar(val);}
196
197 #endif
198
199 #endif
200