Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/logging.c
Parent Directory
|
Revision Log
Revision 1166 -
(hide annotations)
(download)
(as text)
Tue Nov 20 16:12:08 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 8177 byte(s)
Tue Nov 20 16:12:08 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 8177 byte(s)
Replace all assert statements with a custom error message that explains the cause and suggests a solution.
1 | amb | 520 | /*************************************** |
2 | Functions to handle logging functions. | ||
3 | |||
4 | Part of the Routino routing software. | ||
5 | ******************/ /****************** | ||
6 | amb | 982 | This file Copyright 2008-2012 Andrew M. Bishop |
7 | amb | 520 | |
8 | This program is free software: you can redistribute it and/or modify | ||
9 | it under the terms of the GNU Affero General Public License as published by | ||
10 | the Free Software Foundation, either version 3 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU Affero General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Affero General Public License | ||
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | ***************************************/ | ||
21 | |||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdarg.h> | ||
25 | amb | 804 | #include <stdlib.h> |
26 | #include <string.h> | ||
27 | #include <errno.h> | ||
28 | amb | 982 | #include <sys/time.h> |
29 | amb | 520 | |
30 | #include "logging.h" | ||
31 | |||
32 | |||
33 | amb | 680 | /* Global variables */ |
34 | |||
35 | amb | 520 | /*+ The option to print the output in a way that allows logging to a file. +*/ |
36 | int option_loggable=0; | ||
37 | |||
38 | amb | 982 | /*+ The option to print timestamps with the output. +*/ |
39 | amb | 1019 | int option_logtime=0; |
40 | amb | 982 | |
41 | |||
42 | amb | 520 | /* Local functions */ |
43 | |||
44 | static void vfprintf_first(FILE *file,const char *format,va_list ap); | ||
45 | static void vfprintf_middle(FILE *file,const char *format,va_list ap); | ||
46 | static void vfprintf_last(FILE *file,const char *format,va_list ap); | ||
47 | |||
48 | amb | 982 | |
49 | amb | 520 | /* Local variables */ |
50 | |||
51 | amb | 982 | /*+ The time that printf_first was called. +*/ |
52 | static struct timeval start_time; | ||
53 | |||
54 | amb | 648 | /*+ The length of the string printed out last time. +*/ |
55 | amb | 520 | static int printed_length=0; |
56 | |||
57 | amb | 804 | /*+ The file handle for the error log file. +*/ |
58 | static FILE *errorlogfile; | ||
59 | amb | 520 | |
60 | amb | 804 | |
61 | amb | 520 | /*++++++++++++++++++++++++++++++++++++++ |
62 | amb | 680 | Print the first message in an overwriting sequence (to stdout). |
63 | amb | 520 | |
64 | const char *format The format string. | ||
65 | |||
66 | ... The other arguments. | ||
67 | ++++++++++++++++++++++++++++++++++++++*/ | ||
68 | |||
69 | void printf_first(const char *format, ...) | ||
70 | { | ||
71 | va_list ap; | ||
72 | |||
73 | amb | 982 | if(option_logtime) |
74 | gettimeofday(&start_time,NULL); | ||
75 | |||
76 | amb | 520 | if(option_loggable) |
77 | return; | ||
78 | |||
79 | va_start(ap,format); | ||
80 | |||
81 | vfprintf_first(stdout,format,ap); | ||
82 | |||
83 | va_end(ap); | ||
84 | } | ||
85 | |||
86 | |||
87 | /*++++++++++++++++++++++++++++++++++++++ | ||
88 | amb | 680 | Print the middle message in an overwriting sequence (to stdout). |
89 | amb | 520 | |
90 | const char *format The format string. | ||
91 | |||
92 | ... The other arguments. | ||
93 | ++++++++++++++++++++++++++++++++++++++*/ | ||
94 | |||
95 | void printf_middle(const char *format, ...) | ||
96 | { | ||
97 | va_list ap; | ||
98 | |||
99 | if(option_loggable) | ||
100 | return; | ||
101 | |||
102 | va_start(ap,format); | ||
103 | |||
104 | vfprintf_middle(stdout,format,ap); | ||
105 | |||
106 | va_end(ap); | ||
107 | } | ||
108 | |||
109 | |||
110 | /*++++++++++++++++++++++++++++++++++++++ | ||
111 | amb | 680 | Print the last message in an overwriting sequence (to stdout). |
112 | amb | 520 | |
113 | const char *format The format string. | ||
114 | |||
115 | ... The other arguments. | ||
116 | ++++++++++++++++++++++++++++++++++++++*/ | ||
117 | |||
118 | void printf_last(const char *format, ...) | ||
119 | { | ||
120 | va_list ap; | ||
121 | |||
122 | va_start(ap,format); | ||
123 | |||
124 | vfprintf_last(stdout,format,ap); | ||
125 | |||
126 | va_end(ap); | ||
127 | } | ||
128 | |||
129 | |||
130 | /*++++++++++++++++++++++++++++++++++++++ | ||
131 | amb | 680 | Print the first message in an overwriting sequence to a specified file. |
132 | amb | 520 | |
133 | FILE *file The file to write to. | ||
134 | |||
135 | const char *format The format string. | ||
136 | |||
137 | ... The other arguments. | ||
138 | ++++++++++++++++++++++++++++++++++++++*/ | ||
139 | |||
140 | void fprintf_first(FILE *file,const char *format, ...) | ||
141 | { | ||
142 | va_list ap; | ||
143 | |||
144 | amb | 982 | if(option_logtime) |
145 | gettimeofday(&start_time,NULL); | ||
146 | |||
147 | amb | 520 | if(option_loggable) |
148 | return; | ||
149 | |||
150 | va_start(ap,format); | ||
151 | |||
152 | vfprintf_first(file,format,ap); | ||
153 | |||
154 | va_end(ap); | ||
155 | } | ||
156 | |||
157 | |||
158 | /*++++++++++++++++++++++++++++++++++++++ | ||
159 | amb | 680 | Print the middle message in an overwriting sequence to a specified file. |
160 | amb | 520 | |
161 | FILE *file The file to write to. | ||
162 | |||
163 | const char *format The format string. | ||
164 | |||
165 | ... The other arguments. | ||
166 | ++++++++++++++++++++++++++++++++++++++*/ | ||
167 | |||
168 | void fprintf_middle(FILE *file,const char *format, ...) | ||
169 | { | ||
170 | va_list ap; | ||
171 | |||
172 | if(option_loggable) | ||
173 | return; | ||
174 | |||
175 | va_start(ap,format); | ||
176 | |||
177 | vfprintf_middle(file,format,ap); | ||
178 | |||
179 | va_end(ap); | ||
180 | } | ||
181 | |||
182 | |||
183 | /*++++++++++++++++++++++++++++++++++++++ | ||
184 | amb | 680 | Print the last message in an overwriting sequence to a specified file. |
185 | amb | 520 | |
186 | FILE *file The file to write to. | ||
187 | |||
188 | const char *format The format string. | ||
189 | |||
190 | ... The other arguments. | ||
191 | ++++++++++++++++++++++++++++++++++++++*/ | ||
192 | |||
193 | void fprintf_last(FILE *file,const char *format, ...) | ||
194 | { | ||
195 | va_list ap; | ||
196 | |||
197 | va_start(ap,format); | ||
198 | |||
199 | vfprintf_last(file,format,ap); | ||
200 | |||
201 | va_end(ap); | ||
202 | } | ||
203 | |||
204 | |||
205 | /*++++++++++++++++++++++++++++++++++++++ | ||
206 | amb | 680 | Do the work to print the first message in an overwriting sequence. |
207 | amb | 520 | |
208 | FILE *file The file to write to. | ||
209 | |||
210 | const char *format The format string. | ||
211 | |||
212 | va_list ap The other arguments. | ||
213 | ++++++++++++++++++++++++++++++++++++++*/ | ||
214 | |||
215 | static void vfprintf_first(FILE *file,const char *format,va_list ap) | ||
216 | { | ||
217 | int retval; | ||
218 | |||
219 | amb | 982 | if(option_logtime) |
220 | fprintf_elapsed_time(file,&start_time); | ||
221 | |||
222 | amb | 520 | retval=vfprintf(file,format,ap); |
223 | fflush(file); | ||
224 | |||
225 | if(retval>0) | ||
226 | printed_length=retval; | ||
227 | } | ||
228 | |||
229 | |||
230 | /*++++++++++++++++++++++++++++++++++++++ | ||
231 | amb | 680 | Do the work to print the middle message in an overwriting sequence. |
232 | amb | 520 | |
233 | FILE *file The file to write to. | ||
234 | |||
235 | const char *format The format string. | ||
236 | |||
237 | va_list ap The other arguments. | ||
238 | ++++++++++++++++++++++++++++++++++++++*/ | ||
239 | |||
240 | static void vfprintf_middle(FILE *file,const char *format,va_list ap) | ||
241 | { | ||
242 | int retval; | ||
243 | |||
244 | putchar('\r'); | ||
245 | amb | 982 | |
246 | if(option_logtime) | ||
247 | fprintf_elapsed_time(file,&start_time); | ||
248 | |||
249 | amb | 520 | retval=vfprintf(file,format,ap); |
250 | fflush(file); | ||
251 | |||
252 | if(retval>0) | ||
253 | amb | 648 | { |
254 | int new_printed_length=retval; | ||
255 | |||
256 | while(retval++<printed_length) | ||
257 | putchar(' '); | ||
258 | |||
259 | printed_length=new_printed_length; | ||
260 | } | ||
261 | amb | 520 | } |
262 | |||
263 | |||
264 | /*++++++++++++++++++++++++++++++++++++++ | ||
265 | amb | 680 | Do the work to print the last message in an overwriting sequence. |
266 | amb | 520 | |
267 | FILE *file The file to write to. | ||
268 | |||
269 | const char *format The format string. | ||
270 | |||
271 | va_list ap The other arguments. | ||
272 | ++++++++++++++++++++++++++++++++++++++*/ | ||
273 | |||
274 | static void vfprintf_last(FILE *file,const char *format,va_list ap) | ||
275 | { | ||
276 | int retval; | ||
277 | |||
278 | if(!option_loggable) | ||
279 | putchar('\r'); | ||
280 | amb | 982 | |
281 | if(option_logtime) | ||
282 | fprintf_elapsed_time(file,&start_time); | ||
283 | |||
284 | amb | 520 | retval=vfprintf(file,format,ap); |
285 | |||
286 | if(retval>0) | ||
287 | while(retval++<printed_length) | ||
288 | putchar(' '); | ||
289 | |||
290 | putchar('\n'); | ||
291 | fflush(file); | ||
292 | } | ||
293 | amb | 804 | |
294 | |||
295 | /*++++++++++++++++++++++++++++++++++++++ | ||
296 | amb | 982 | Print the elapsed time without a following newline. |
297 | |||
298 | FILE *file The file to print to. | ||
299 | |||
300 | struct timeval *start The start time from which the elapsed time is to be printed. | ||
301 | ++++++++++++++++++++++++++++++++++++++*/ | ||
302 | |||
303 | void fprintf_elapsed_time(FILE *file,struct timeval *start) | ||
304 | { | ||
305 | struct timeval finish,elapsed; | ||
306 | |||
307 | gettimeofday(&finish,NULL); | ||
308 | |||
309 | elapsed.tv_sec =finish.tv_sec -start->tv_sec; | ||
310 | elapsed.tv_usec=finish.tv_usec-start->tv_usec; | ||
311 | if(elapsed.tv_usec<0) | ||
312 | { | ||
313 | elapsed.tv_sec -=1; | ||
314 | elapsed.tv_usec+=1000000; | ||
315 | } | ||
316 | |||
317 | fprintf(file,"[%2ld:%02ld.%03ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec/10000); | ||
318 | } | ||
319 | |||
320 | |||
321 | /*++++++++++++++++++++++++++++++++++++++ | ||
322 | amb | 804 | Create the error log file. |
323 | |||
324 | const char *filename The name of the file to create. | ||
325 | |||
326 | int append The option to append to an existing file. | ||
327 | ++++++++++++++++++++++++++++++++++++++*/ | ||
328 | |||
329 | void open_errorlog(const char *filename,int append) | ||
330 | { | ||
331 | errorlogfile=fopen(filename,append?"a":"w"); | ||
332 | |||
333 | if(!errorlogfile) | ||
334 | { | ||
335 | fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno)); | ||
336 | exit(EXIT_FAILURE); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | |||
341 | /*++++++++++++++++++++++++++++++++++++++ | ||
342 | Close the error log file. | ||
343 | ++++++++++++++++++++++++++++++++++++++*/ | ||
344 | |||
345 | void close_errorlog(void) | ||
346 | { | ||
347 | if(errorlogfile) | ||
348 | fclose(errorlogfile); | ||
349 | } | ||
350 | |||
351 | |||
352 | /*++++++++++++++++++++++++++++++++++++++ | ||
353 | Log a message to the error log file. | ||
354 | |||
355 | const char *format The format string. | ||
356 | |||
357 | ... The other arguments. | ||
358 | ++++++++++++++++++++++++++++++++++++++*/ | ||
359 | |||
360 | void logerror(const char *format, ...) | ||
361 | { | ||
362 | va_list ap; | ||
363 | |||
364 | if(!errorlogfile) | ||
365 | return; | ||
366 | |||
367 | va_start(ap,format); | ||
368 | |||
369 | vfprintf(errorlogfile,format,ap); | ||
370 | |||
371 | va_end(ap); | ||
372 | } | ||
373 | amb | 1166 | |
374 | |||
375 | /*++++++++++++++++++++++++++++++++++++++ | ||
376 | Log a fatal error and exit | ||
377 | |||
378 | const char *message The error message. | ||
379 | |||
380 | const char *file The file in which the error occured. | ||
381 | |||
382 | int line The line number in the file at which the error occured. | ||
383 | ++++++++++++++++++++++++++++++++++++++*/ | ||
384 | |||
385 | void _logassert(const char *message,const char *file,int line) | ||
386 | { | ||
387 | fprintf(stderr,"Routino Fatal Error (%s:%d): %s\n",file,line,message); | ||
388 | |||
389 | exit(EXIT_FAILURE); | ||
390 | } |