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

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