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

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