/[ascend]/trunk/base/generic/utilities/error.h
ViewVC logotype

Contents of /trunk/base/generic/utilities/error.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 427 - (show annotations) (download) (as text)
Tue Apr 4 04:13:34 2006 UTC (15 years, 7 months ago) by johnpye
File MIME type: text/x-chdr
File size: 9876 byte(s)
tentative: Disabled ascDynaload functions when DYNAMIC_PACKAGES is not defined. 
Altered error.[ch] so that MS VC++ variadic macros are used when available. 
Disabled Windows MessageBox in ascPanic, so that compilation of base engine is possible with the Platform SDK.
Added SConscript files to build FORTRAN components.
Removed some autoconf-related stuff from the pygtk/interface directory.
1 #ifndef ASC_ERROR_H
2 #define ASC_ERROR_H
3 /**
4 This file provides error reporting to a callback function via
5 ASCEND's FPRINTF(ASCERR,...) syntax. It is anticipated that
6 this would gradually be expanded to including richer reporting
7 of errors with severity and source file name and line numbers.
8
9 Usage:
10 error_reporter_start(<error-severity>,<filepath>,<linenumber>);
11 FPRINTF(ASCERR,"half of ");
12 FPRINTF(ASCERR,"your message");
13 error_reporter_end_flush();
14
15 or:
16 error_reporter_start(<error-severity>,<filepath>,<linenumber>
17 ,"format string %s %d etc",<printf-args>,...");
18
19 The first form allows you to use multiple FPRINTF statements to
20 generate your error message. The second form assumes that your
21 entire message will be contained in a single statement.
22
23 Error severities are
24 ASC_(USER|PROG)_(NOTE|WARNING|ERROR)
25 and ASC_USER_SUCCESS
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31
32 /**
33 ascConfig defines ASC_FPRINTF etc, the routines to provide
34 default 'real' printf behaviour on this platform. (As
35 opposed to the sneaky stuff that FPRINTF does in this header)
36 */
37 #include <utilities/ascConfig.h>
38 #include <utilities/ascPrint.h>
39
40 /**
41 FPRINTF(ASCERR,...) messages will by default be treated
42 by the error_reporter as ASC_PROG_NOTE messages. These will
43 gradually need to be replaced with error_severity_t values
44 that accurately reflect the nature of the error.
45 */
46 #define FPRINTF fprintf_error_reporter
47 #define FPUTC fputc_error_reporter
48 #define PUTC fputc_error_reporter
49 #define FFLUSH fflush_error_reporter
50
51 /*
52 By default, don't use coloured output on any terminals. We will reintroduce
53 this later, hopefully. It should be done using CURSES, instead of directly
54 using xterm codes. But that brings its own problems on MinGW and Windows...
55 */
56
57 #ifdef USE_XTERM_COLOR_CODES
58 /** XTERM colour codes used to distinguish between errors of different types.
59
60 @TODO some runtime testing to determine if these should be used or not
61 depending on TERM env var.
62 */
63 # define ERR_RED "\033[31;1m"
64 # define ERR_GRN "\033[32;2m"
65 # define ERR_BLU "\033[34;1m"
66 # define ERR_BRN "\033[33;1m"
67 # define ERR_NORM "\033[0m"
68 # define ERR_BOLD "\033[1m"
69 #else
70 # define ERR_RED ""
71 # define ERR_GRN ""
72 # define ERR_BLU ""
73 # define ERR_BRN ""
74 # define ERR_NORM ""
75 # define ERR_BOLD ""
76 #endif
77
78 /**
79 Error severity codes. This will be used to visually
80 the seriousness of errors. ASC_PROG_ERRORs for example
81 might be red, or be highlighted with a (!) icon, etc.
82 */
83 typedef enum error_severity_enum{
84 ASC_USER_SUCCESS=0
85 ,ASC_USER_NOTE=1 /**< a note to the user */
86 ,ASC_USER_WARNING /**< the user has done something bad but tolerable */
87 ,ASC_USER_ERROR /**< the user has done something wrong */
88 ,ASC_PROG_NOTE /**< a note for the programmer */
89 ,ASC_PROG_WARNING /**< the program encounters an unexpected state */
90 ,ASC_PROG_ERROR /**< the program has failed but can ignore and continue (maybe) */
91 ,ASC_PROG_FATAL /**< fatal error, program will exit */
92 } error_severity_t;
93
94
95 /**
96 Variadic macros to allow nice succint logging and error reporting
97 calls from C dialects that support them (GCC, C99 and others)
98
99 If you don't support variadic macros, you will still get the messages
100 but without the file/function/line number.
101 */
102 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
103 # define ERROR_REPORTER_DEBUG(args...) error_reporter(ASC_PROG_NOTE, __FILE__, __LINE__, __func__, ##args)
104 # define ERROR_REPORTER_HERE(SEV,args...) error_reporter(SEV,__FILE__, __LINE__, __func__, ##args)
105 # define ERROR_REPORTER_NOLINE(SEV,args...) error_reporter(SEV, NULL, 0, NULL, ##args)
106 # define CONSOLE_DEBUG(args...) (fprintf(stderr, ERR_BOLD "%s:%d (%s): ", __FILE__,__LINE__,__func__) + \
107 fprintf(stderr, ##args) + \
108 fprintf(stderr, ERR_NORM "\n"))
109
110 # define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,__func__);
111
112 #elif defined(HAVE_C99)
113 # define ERROR_REPORTER_DEBUG(...) error_reporter(ASC_PROG_NOTE,__FILE__,__LINE__,__func__,## __VA_ARGS__)
114 # define ERROR_REPORTER_HERE(SEV,...) error_reporter(SEV,__FILE__,__LINE__,__func__, ## __VA_ARGS__)
115 # define ERROR_REPORTER_NOLINE(SEV,...) error_reporter(SEV,NULL,0,NULL, ## __VA_ARGS__)
116 # define CONSOLE_DEBUG(...) (fprintf(stderr, ERR_BOLD "%s:%d (%s): ", __FILE__,__LINE__,__func__) + \
117 fprintf(stderr, ##__VA_ARGS__) + \
118 fprintf(stderr, ERR_NORM "\n"))
119
120 #define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,__FUNCTION__);
121 # define ERROR_REPORTER_DEBUG(...) error_reporter(ASC_PROG_NOTE,__FILE__,__LINE__,__FUNCTION__,## __VA_ARGS__)
122 # define ERROR_REPORTER_HERE(SEV,...) error_reporter(SEV,__FILE__,__LINE__,__FUNCTION__, ## __VA_ARGS__)
123 # define ERROR_REPORTER_NOLINE(SEV,...) error_reporter(SEV,NULL,0,NULL, ## __VA_ARGS__)
124 # define CONSOLE_DEBUG(...) (fprintf(stderr, ERR_BOLD "%s:%d (%s): ", __FILE__,__LINE__,__FUNCTION__) + \
125 fprintf(stderr, ##__VA_ARGS__) + \
126 fprintf(stderr, ERR_NORM "\n"))
127
128 #elif defined(_MSC_VER) && _MSC_VER >= 1310 /* Microsoft Visual C++ 2003 or newer */
129
130 #else /* workaround for compilers without variadic macros: last resort */
131 # define NO_VARIADIC_MACROS
132 # define ERROR_REPORTER_DEBUG error_reporter_note_no_line
133 # define ERROR_REPORTER_HERE error_reporter_here
134 # define ERROR_REPORTER_NOLINE error_reporter_noline
135 # define CONSOLE_DEBUG console_debug
136 # define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,"[function?]");
137 int error_reporter_note_no_line(const char *fmt,...);
138 int error_reporter_here(const error_severity_t sev, const char *fmt,...);
139 int error_reporter_noline(const error_severity_t sev, const char *fmt,...);
140 int console_debug(const char *fmt,...);
141 #endif
142
143 #define ERROR_REPORTER_START_NOLINE(SEV) error_reporter_start(SEV,NULL,0,NULL);
144
145 #define ERROR_REPORTER_STAT(sev,stat,msg) \
146 error_reporter(sev,Asc_ModuleFileName(stat->mod),stat->linenum,NULL,msg)
147
148 /** An alias for ASC_PROG_ERROR */
149 #define ASC_PROG_ERR ASC_PROG_ERROR
150
151 #define ERROR_REPORTER_MAX_MSG 4096 /* no particular reason */
152
153 typedef struct{
154 unsigned char iscaching; /** set to true for fprintf_error_reporter to do its work */
155 error_severity_t sev;
156 const char *filename;
157 int line;
158 const char *func;
159 char msg[ERROR_REPORTER_MAX_MSG];
160 } error_reporter_meta_t;
161
162 /**
163 This is the drop-in replacement for Asc_FPrintf. Anythin you attempt
164 to print to stderr will be captured and passed to the error_reporter_callback
165 function for handling.
166 */
167 int fprintf_error_reporter(FILE *file, const char *fmt, ...);
168
169 /**
170 If file!=stderr, this will do the usual thing. If file==stderr, it will output
171 the character via fprintf_error_reporter.
172 */
173 int fputc_error_reporter(int c, FILE *file); /* just calls fprintf_error_reporter */
174
175 /**
176 This replaces the standard 'fflush' of Asc_FFlush. If file!=stderr, it will
177 call the standard fflush. If file==stderr, it will call error_reporter_end_flush.
178 */
179 int fflush_error_reporter(FILE *file);
180
181 /**
182 Start a cached error report. This means that multiple frprintf_error_reporter calls will
183 be stored in a global string until an error_reporter_end_flush is encountered.
184 */
185 int error_reporter_start(const error_severity_t sev, const char *filename, const int line, const char *func);
186
187 /**
188 Output the contents of the checked global string as an error report
189 */
190 int error_reporter_end_flush();
191
192 /**
193 This #define saves you typing the list of arguments in your
194 callback function declarations.
195 */
196 #define ERROR_REPORTER_CALLBACK_ARGS \
197 const error_severity_t sev \
198 , const char *filename \
199 , const int line \
200 , const char *funcname \
201 , const char *fmt \
202 , const va_list args
203
204 /*
205 In you have functions which pass-through callback parameters,
206 this #define ensures that if their ordering/naming changes,
207 you won't have to go hunting and change stuff.
208 */
209 #define ERROR_REPORTER_CALLBACK_VARS \
210 sev, filename, line, funcname, fmt, args
211
212 /*
213 Define the type of the function pointer to be used for all
214 error reporting functions. The final argument is a va_list.
215 You should use 'vsnprintf' of 'vfprintf' to output your
216 message to the desired file or string, see <stdio.h> for these.
217 */
218 typedef int (*error_reporter_callback_t)(
219 ERROR_REPORTER_CALLBACK_ARGS
220 );
221
222 typedef int (*ErrorReporter_fptr_t)(
223 const error_severity_t sev
224 , const char *errfile
225 , const int errline
226 , const char *errfunc
227 , const char *fmt
228 , ...
229 );
230
231 #ifdef ASC_USE_IMPORTED_ERROR_REPORTER
232 /*
233 If we're using a 'imported error reporter' then this means that we're in
234 a different DLL to the main ASCEND code. In that case, we will have a
235 pointer to our error reporter function, which will be back in the main
236 DLL in fact. We need this header file to refer to that global-variable
237 function pointer instead of assuming that the function is here locally.
238 */
239 static ErrorReporter_fptr_t g_ErrorReporter_fptr;
240 # define error_reporter (*g_ErrorReporter_fptr)
241 #else
242
243 /**
244 Use this function directly for 'richer' reporting of
245 of error messages.
246
247 @return follows the style of fprintf
248 */
249 DLEXPORT int error_reporter(
250 const error_severity_t sev
251 , const char *errfile
252 , const int errline
253 , const char *errfunc
254 , const char *fmt
255 , ...
256 );
257
258 #endif
259
260 /**
261 This format of the error reporter is useful if you must call it
262 from another variable-argument-list function.
263 */
264 int va_error_reporter(ERROR_REPORTER_CALLBACK_ARGS);
265
266 /**
267 Set error reporting callback function using this
268 function. If left unset, errors will be printed
269 to standard error, which is effectively what the
270 hitherto FPRINTF has done.
271 */
272 void error_reporter_set_callback(
273 const error_reporter_callback_t new_callback
274 );
275
276 #endif /* ASC_ERROR_H */

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22