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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 222 - (show annotations) (download) (as text)
Fri Jan 27 04:23:20 2006 UTC (14 years, 10 months ago) by johnpye
File MIME type: text/x-csrc
File size: 6850 byte(s)
Updating for Jerry's new error_reporter syntax, bug #179
1 #include <string.h>
2
3 #include "error.h"
4
5 /* Don't use the XTERM colour coldes in Windows: */
6 #ifndef __WIN32__
7 #define TEST_DEFAULT_FPRINTF
8 #endif
9
10 #ifdef TEST_DEFAULT_FPRINTF
11 /** XTERM colour codes used to distinguish between errors of different types.
12
13 @TODO some runtime testing to determine if these should be used or not
14 depending on TERM env var.
15 */
16 # define ERR_RED "\033[31;1m"
17 # define ERR_GRN "\033[32;2m"
18 # define ERR_BLU "\033[34;1m"
19 # define ERR_BRN "\033[33;1m"
20 # define ERR_NORM "\033[0m"
21 #else
22 # define ERR_RED ""
23 # define ERR_GRN ""
24 # define ERR_BLU ""
25 # define ERR_BRN ""
26 # define ERR_NORM ""
27 #endif
28
29 /**
30 Global variable which stores the pointer to the callback
31 function being used.
32 */
33 static error_reporter_callback_t g_error_reporter_callback;
34
35 /**
36 Global variable which holds cached error info for
37 later output
38 */
39 static error_reporter_meta_t g_error_reporter_cache;
40
41 /**
42 Default error reporter. To use this error reporter, set
43 the callback pointer to NULL.
44 */
45 int error_reporter_default_callback(ERROR_REPORTER_CALLBACK_ARGS){
46 char *sevmsg="";
47 char *endtxt="\n";
48 int res=0;
49 switch(sev){
50 case ASC_PROG_FATAL: sevmsg = ERR_RED "PROGRAM FATAL ERROR: " ERR_NORM; break;
51 case ASC_PROG_ERROR: sevmsg = ERR_RED "PROGRAM ERROR: " ERR_NORM; break;
52 case ASC_PROG_WARNING: sevmsg = "PROGRAM WARNING: "; break;
53 case ASC_PROG_NOTE: sevmsg = ERR_GRN; endtxt=ERR_NORM; break; /* default, keep unembellished for now */
54 case ASC_USER_ERROR: sevmsg = ERR_RED "ERROR: " ERR_NORM; break;
55 case ASC_USER_WARNING: sevmsg = ERR_BRN "WARNING: " ERR_NORM; break;
56 case ASC_USER_NOTE: sevmsg = "NOTE: "; break;
57 case ASC_USER_SUCCESS: sevmsg = ERR_GRN "SUCCESS: " ERR_NORM; break;
58 }
59
60 res = ASC_FPRINTF(ASCERR,sevmsg);
61 if(filename!=NULL){
62 res += ASC_FPRINTF(ASCERR,"%s:",filename);
63 }
64 if(line!=0){
65 res += ASC_FPRINTF(ASCERR,"%d:",line);
66 }
67 if(funcname!=NULL){
68 res += ASC_FPRINTF(ASCERR,"%s:",funcname);
69 }
70 if ((filename!=NULL) || (line!=0) || (funcname!=NULL)){
71 res += ASC_FPRINTF(ASCERR," ");
72 }
73
74 res += ASC_VFPRINTF(ASCERR,fmt,args);
75 res += ASC_FPRINTF(ASCERR,endtxt);
76
77 return res;
78 }
79
80 /*--------------------------
81 REPORT the error
82 */
83 int
84 va_error_reporter(
85 const error_severity_t sev
86 , const char *errfile
87 , const int errline
88 , const char *errfunc
89 , const char *fmt
90 , const va_list args
91 ){
92 extern error_reporter_callback_t g_error_reporter_callback;
93 int res;
94
95 if(g_error_reporter_callback==NULL){
96 /* fprintf(stderr,"CALLING VFPRINTF\n"); */
97 res = error_reporter_default_callback(sev,errfile,errline,errfunc,fmt,args);
98 }else{
99 /* fprintf(stderr,"CALLING G_ERROR_REPORTER_CALLBACK\n"); */
100 res = g_error_reporter_callback(sev,errfile,errline,errfunc,fmt,args);
101 }
102
103 return res;
104 }
105
106 /*----------------------------
107 DROP-IN replacements for stdio.h / ascPrint.h
108 */
109
110 /**
111 This function performs caching of the error text if the flag is set
112 */
113 int
114 fprintf_error_reporter(FILE *file, const char *fmt, ...){
115 va_list args;
116 extern error_reporter_meta_t g_error_reporter_cache;
117 char *msg;
118 int len;
119 int res;
120
121 /* fprintf(stderr,"ENTERED FPRINTF_ERROR_REPORTER\n"); */
122
123 va_start(args,fmt);
124 if(file==stderr){
125 if(g_error_reporter_cache.iscaching){
126 msg = g_error_reporter_cache.msg;
127 len = strlen(msg);
128 res = vsnprintf(msg+len,ERROR_REPORTER_MAX_MSG-len,fmt,args);
129 if(len+res+1>=ERROR_REPORTER_MAX_MSG){
130 snprintf(msg+ERROR_REPORTER_MAX_MSG-16,15,"... (truncated)");
131 ASC_FPRINTF(stderr,"TRUNCATED MESSAGE, FULL MESSAGE FOLLOWS:\n----------START----------\n");
132 ASC_VFPRINTF(stderr,fmt,args);
133 ASC_FPRINTF(stderr,"\n-----------END----------\n");
134 }
135 }else{
136 /* Not caching: output all in one go as a ASC_PROG_NOTE */
137 res = va_error_reporter(ASC_PROG_NOTE,NULL,0,NULL,fmt,args);
138 }
139 }else{
140 res = ASC_VFPRINTF(file,fmt,args);
141 }
142
143 va_end(args);
144
145 return res;
146 }
147
148 int
149 fputc_error_reporter(int c, FILE *file){
150 if(file!=stderr){
151 return ASC_FPUTC(c,file);
152 }else if(fprintf_error_reporter(file,"%c",c) == 1){
153 return c;
154 }else{
155 return EOF;
156 }
157 }
158
159 int
160 fflush_error_reporter(FILE *file){
161 if(file!=stderr){
162 return ASC_FFLUSH(file);
163 }else{
164 return error_reporter_end_flush();
165 }
166 }
167
168 /*----------------------------
169 CACHING of multiple-FPRINTF error messages
170 */
171
172 int
173 error_reporter_start(const error_severity_t sev, const char *filename, const int line, const char *func){
174
175 extern error_reporter_meta_t g_error_reporter_cache;
176 if(g_error_reporter_cache.iscaching){
177 error_reporter_end_flush();
178 }
179 g_error_reporter_cache.iscaching = 1;
180 *(g_error_reporter_cache.msg) = '\0';
181 g_error_reporter_cache.sev = sev;
182 g_error_reporter_cache.filename = filename;
183 g_error_reporter_cache.line = line;
184 g_error_reporter_cache.func = func;
185
186 return 1;
187 }
188
189 int
190 error_reporter_end_flush(){
191 extern error_reporter_meta_t g_error_reporter_cache;
192
193 error_reporter(
194 g_error_reporter_cache.sev
195 ,g_error_reporter_cache.filename
196 ,g_error_reporter_cache.line
197 ,g_error_reporter_cache.func
198 ,g_error_reporter_cache.msg
199 );
200 g_error_reporter_cache.iscaching = 0;
201
202 return 0; /* output must be compatible with fflush */
203 }
204
205 /*--------------------------
206 REPORT the error
207 */
208 int
209 error_reporter(
210 const error_severity_t sev
211 , const char *errfile
212 , const int errline
213 , const char *errfunc
214 , const char *fmt
215 , ...
216 ){
217 int res;
218 va_list args;
219
220 va_start(args,fmt);
221 res = va_error_reporter(sev,errfile,errline,errfunc,fmt,args);
222 va_end(args);
223
224 return res;
225 }
226
227 #if !(defined(__GNUC__) && !defined(__STRICT_ANSI__)) && !defined(HAVE_C99)
228 /* Following are only required on compilers without variadic macros: */
229
230 int error_reporter_note_no_line(const char *fmt,...){
231 int res;
232 va_list args;
233
234 va_start(args,fmt);
235 res = va_error_reporter(ASC_PROG_NOTE,"unknown-file",0,fmt,args);
236 va_end(args);
237
238 return res;
239 }
240
241 /**
242 Error reporter 'here' function for compilers not supporting
243 variadic macros.
244 */
245 int error_reporter_here(const error_severity_t sev, const char *fmt,...){
246 int res;
247 va_list args;
248
249 va_start(args,fmt);
250 res = va_error_reporter(sev,"unknown-file",0,fmt,args);
251 va_end(args);
252
253 return res;
254 }
255
256
257 /**
258 Error reporter 'no line' function for compilers not supporting
259 variadic macros.
260 */
261 int error_reporter_noline(const error_severity_t sev, const char *fmt,...){
262 int res;
263 va_list args;
264
265 va_start(args,fmt);
266 res = va_error_reporter(sev,NULL,0,fmt,args);
267 va_end(args);
268
269 return res;
270 }
271
272 int console_debug(const char *fmt,...){
273 int res;
274 va_list args;
275
276 va_start(args,fmt);
277 res = Asc_VFPrintf(ASCERR,fmt,args);
278 va_end(args);
279
280 return res;
281 }
282 #endif
283
284 /*-------------------------
285 SET the callback function
286 */
287 void
288 error_reporter_set_callback(
289 const error_reporter_callback_t new_callback
290 ){
291 extern error_reporter_callback_t g_error_reporter_callback;
292 g_error_reporter_callback = new_callback;
293 }
294

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