/[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 913 - (show annotations) (download) (as text)
Sat Oct 28 03:55:19 2006 UTC (13 years, 5 months ago) by johnpye
File MIME type: text/x-chdr
File size: 9868 byte(s)
Added test for SUNDIALS version (2.2.1 and 2.3.0-pre are preferred)
Fixed silly warning message about ignored return values from CONSOLE_DEBUG on GCC.
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 @file
20 This file provides error reporting to a callback function via
21 ASCEND's FPRINTF(ASCERR,...) syntax. It is anticipated that
22 this would gradually be expanded to including richer reporting
23 of errors with severity and source file name and line numbers.
24
25 Usage:
26 error_reporter_start(<error-severity>,<filepath>,<linenumber>);
27 FPRINTF(ASCERR,"half of ");
28 FPRINTF(ASCERR,"your message");
29 error_reporter_end_flush();
30
31 or:
32 error_reporter_start(<error-severity>,<filepath>,<linenumber>
33 ,"format string %s %d etc",<printf-args>,...");
34
35 The first form allows you to use multiple FPRINTF statements to
36 generate your error message. The second form assumes that your
37 entire message will be contained in a single statement.
38
39 Error severities are
40 ASC_(USER|PROG)_(NOTE|WARNING|ERROR)
41 and ASC_USER_SUCCESS
42 *//*
43 by John Pye
44 2005
45 */
46 #ifndef ASC_ERROR_H
47 #define ASC_ERROR_H
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <stdarg.h>
52
53 /**
54 ascConfig defines ASC_FPRINTF etc, the routines to provide
55 default 'real' printf behaviour on this platform. (As
56 opposed to the sneaky stuff that FPRINTF does in this header)
57 */
58 #include <utilities/ascConfig.h>
59 #include <utilities/ascPrint.h>
60
61 /**
62 FPRINTF(ASCERR,...) messages will by default be treated
63 by the error_reporter as ASC_PROG_NOTE messages. These will
64 gradually need to be replaced with error_severity_t values
65 that accurately reflect the nature of the error.
66 */
67 #define FPRINTF fprintf_error_reporter
68 #define FPUTC fputc_error_reporter
69 #define PUTC fputc_error_reporter
70 #define FFLUSH fflush_error_reporter
71
72 /*
73 By default, don't use coloured output on any terminals. We will reintroduce
74 this later, hopefully. It should be done using CURSES, instead of directly
75 using xterm codes. But that brings its own problems on MinGW and Windows...
76 */
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...) ((void)(color_on(stderr,"0;34") + \
107 fprintf(stderr, "%s:%d ",__FILE__,__LINE__) + \
108 color_on(stderr,"0;31") + \
109 fprintf(stderr, "(%s)", __func__) + \
110 color_on(stderr,"0;34") + \
111 fprintf(stderr, ": ") + \
112 fprintf(stderr, ##args) + \
113 fprintf(stderr, "\n") + color_off(stderr)))
114
115 # define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,__func__);
116
117 #elif defined(HAVE_C99)
118 # define ERROR_REPORTER_DEBUG(...) error_reporter(ASC_PROG_NOTE,__FILE__,__LINE__,__func__,## __VA_ARGS__)
119 # define ERROR_REPORTER_HERE(SEV,...) error_reporter(SEV,__FILE__,__LINE__,__func__, ## __VA_ARGS__)
120 # define ERROR_REPORTER_NOLINE(SEV,...) error_reporter(SEV,NULL,0,NULL, ## __VA_ARGS__)
121 # define CONSOLE_DEBUG(...) (color_on(stderr,"0;34") + fprintf(stderr, "%s:%d (%s): ", __FILE__,__LINE__,__func__) + \
122 fprintf(stderr, ##__VA_ARGS__) + \
123 fprintf(stderr, "\n") + color_off(stderr))
124
125 #elif defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual C++ 2005 or newer */
126 # define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,__FUNCTION__);
127 # define ERROR_REPORTER_DEBUG(...) error_reporter(ASC_PROG_NOTE,__FILE__,__LINE__,__FUNCTION__, __VA_ARGS__)
128 # define ERROR_REPORTER_HERE(SEV,...) error_reporter(SEV,__FILE__,__LINE__,__FUNCTION__, __VA_ARGS__)
129 # define ERROR_REPORTER_NOLINE(SEV,...) error_reporter(SEV,NULL,0,NULL, __VA_ARGS__)
130 # define CONSOLE_DEBUG(...) (fprintf(stderr, "%s:%d (%s): ", __FILE__,__LINE__,__FUNCTION__) + \
131 fprintf(stderr, __VA_ARGS__) + \
132 fprintf(stderr, "\n"))
133 #else /* workaround for compilers without variadic macros: last resort */
134 # define NO_VARIADIC_MACROS
135 # define ERROR_REPORTER_DEBUG error_reporter_note_no_line
136 # define ERROR_REPORTER_HERE error_reporter_here
137 # define ERROR_REPORTER_NOLINE error_reporter_noline
138 # define CONSOLE_DEBUG console_debug
139 # define ERROR_REPORTER_START_HERE(SEV) error_reporter_start(SEV,__FILE__,__LINE__,"[function?]");
140 ASC_DLLSPEC(int) error_reporter_note_no_line(const char *fmt,...);
141 ASC_DLLSPEC(int) error_reporter_here(const error_severity_t sev, const char *fmt,...);
142 ASC_DLLSPEC(int) error_reporter_noline(const error_severity_t sev, const char *fmt,...);
143 ASC_DLLSPEC(int) console_debug(const char *fmt,...);
144 #endif
145
146 #define ERROR_REPORTER_START_NOLINE(SEV) error_reporter_start(SEV,NULL,0,NULL);
147
148 #define ERROR_REPORTER_STAT(sev,stat,msg) \
149 error_reporter(sev,Asc_ModuleFileName(stat->mod),stat->linenum,NULL,msg)
150
151 /** An alias for ASC_PROG_ERROR */
152 #define ASC_PROG_ERR ASC_PROG_ERROR
153
154 #define ERROR_REPORTER_MAX_MSG 4096 /* no particular reason */
155
156 typedef struct{
157 unsigned char iscaching; /** set to true for fprintf_error_reporter to do its work */
158 error_severity_t sev;
159 const char *filename;
160 int line;
161 const char *func;
162 char msg[ERROR_REPORTER_MAX_MSG];
163 } error_reporter_meta_t;
164
165 /**
166 This is the drop-in replacement for Asc_FPrintf. Anythin you attempt
167 to print to stderr will be captured and passed to the error_reporter_callback
168 function for handling.
169 */
170 ASC_DLLSPEC(int) fprintf_error_reporter(FILE *file, const char *fmt, ...);
171
172 /**
173 If file!=stderr, this will do the usual thing. If file==stderr, it will output
174 the character via fprintf_error_reporter.
175 */
176 ASC_DLLSPEC(int) fputc_error_reporter(int c, FILE *file); /* just calls fprintf_error_reporter */
177
178 /**
179 This replaces the standard 'fflush' of Asc_FFlush. If file!=stderr, it will
180 call the standard fflush. If file==stderr, it will call error_reporter_end_flush.
181 */
182 ASC_DLLSPEC(int) fflush_error_reporter(FILE *file);
183
184 /**
185 Start a cached error report. This means that multiple frprintf_error_reporter calls will
186 be stored in a global string until an error_reporter_end_flush is encountered.
187 */
188 ASC_DLLSPEC(int) error_reporter_start(const error_severity_t sev, const char *filename, const int line, const char *func);
189
190 /**
191 Output the contents of the checked global string as an error report
192 */
193 ASC_DLLSPEC(int) error_reporter_end_flush();
194
195 /**
196 This #define saves you typing the list of arguments in your
197 callback function declarations.
198 */
199 #define ERROR_REPORTER_CALLBACK_ARGS \
200 const error_severity_t sev \
201 , const char *filename \
202 , const int line \
203 , const char *funcname \
204 , const char *fmt \
205 , const va_list args
206
207 /*
208 In you have functions which pass-through callback parameters,
209 this #define ensures that if their ordering/naming changes,
210 you won't have to go hunting and change stuff.
211 */
212 #define ERROR_REPORTER_CALLBACK_VARS \
213 sev, filename, line, funcname, fmt, args
214
215 /*
216 Define the type of the function pointer to be used for all
217 error reporting functions. The final argument is a va_list.
218 You should use 'vsnprintf' of 'vfprintf' to output your
219 message to the desired file or string, see <stdio.h> for these.
220 */
221 typedef int (*error_reporter_callback_t)(
222 ERROR_REPORTER_CALLBACK_ARGS
223 );
224
225 typedef int (*ErrorReporter_fptr_t)(
226 const error_severity_t sev
227 , const char *errfile
228 , const int errline
229 , const char *errfunc
230 , const char *fmt
231 , ...
232 );
233
234 /**
235 Use this function directly for 'richer' reporting of
236 of error messages.
237
238 @return follows the style of fprintf
239 */
240 ASC_DLLSPEC(int) error_reporter(
241 const error_severity_t sev
242 , const char *errfile
243 , const int errline
244 , const char *errfunc
245 , const char *fmt
246 , ...
247 );
248
249 /**
250 This format of the error reporter is useful if you must call it
251 from another variable-argument-list function.
252 */
253 ASC_DLLSPEC(int) va_error_reporter(ERROR_REPORTER_CALLBACK_ARGS);
254
255 /**
256 Set error reporting callback function using this
257 function. If left unset, errors will be printed
258 to standard error, which is effectively what the
259 hitherto FPRINTF has done.
260 */
261 ASC_DLLSPEC(void) error_reporter_set_callback(
262 const error_reporter_callback_t new_callback
263 );
264
265 #endif /* ASC_ERROR_H */

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