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