Wrapper for Clustal Omega.
[jabaws.git] / binaries / src / clustalo / src / clustal / log.c
1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4;  indent-tabs-mode: nil -*- */
2
3 /*********************************************************************
4  * Clustal Omega - Multiple sequence alignment
5  *
6  * Copyright (C) 2010 University College Dublin
7  *
8  * Clustal-Omega is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This file is part of Clustal-Omega.
14  *
15  ********************************************************************/
16
17 /*
18  *  RCS $Id$
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <assert.h>
30
31 #include "log.h"
32
33 /* a default standard logger */
34 log_t rLog;
35
36
37
38 void
39 LogVfprintf(FILE *prFP, char *pcFmt, va_list rVArgList);
40 void
41 LogWarn(FILE *prFP, char *pcFmt, va_list rVArgList);
42 void
43 LogError(FILE *prFP, char *pcFmt, va_list rVArgList);
44 void
45 LogCritical(FILE *prFP, char *pcFmt, va_list rVArgList);
46 void
47 LogFatal(FILE *prFP, char *pcFmt, va_list rVArgList);
48 void
49 LogForcedDebug(FILE *prFP, char *pcFmt, va_list rVArgList);
50
51
52
53
54 /**
55  * @brief Plain, default print function
56  *
57  * Newline character is automatically appended to message.
58  *
59  */
60 void
61 LogVfprintf(FILE *prFP, char *pcFmt, va_list rVArgList)
62 {
63         /* print prefix */
64     vfprintf(prFP, pcFmt, rVArgList);
65     fprintf(prFP,"\n");
66
67 #ifndef NDEBUG
68     fflush(prFP);
69 #endif
70 }
71 /* end of LogVfprintf() */
72
73
74
75 /**
76  * @brief 
77  *
78  */
79 void
80 LogWarn(FILE *prFP, char *pcFmt, va_list rVArgList)
81 {
82         fprintf(prFP, "WARNING: ");
83     LogVfprintf(prFP, pcFmt, rVArgList);
84 }
85 /* end of LogWarn() */
86
87
88
89 /**
90  * @brief 
91  *
92  */
93 void
94 LogError(FILE *prFP, char *pcFmt, va_list rVArgList)
95 {
96         fprintf(prFP, "ERROR: ");
97     LogVfprintf(prFP, pcFmt, rVArgList);
98 }
99 /* end of LogError() */
100
101
102
103 /**
104  * @brief 
105  *
106  */
107 void
108 LogCritical(FILE *prFP, char *pcFmt, va_list rVArgList)
109 {
110         fprintf(prFP, "CRITICAL ERROR: ");
111     LogVfprintf(prFP, pcFmt, rVArgList);
112 }
113 /* end of LogCritical() */
114
115
116
117 /**
118  * @brief Will also exit!
119  */
120 void
121 LogFatal(FILE *prFP, char *pcFmt, va_list rVArgList)
122 {
123         fprintf(prFP, "FATAL: ");
124     LogVfprintf(prFP, pcFmt, rVArgList);
125     
126     exit(EXIT_FAILURE);
127 }
128 /* end of LogFatal() */
129
130
131
132 /**
133  * @brief 
134  *
135  */
136 void
137 LogForcedDebug(FILE *prFP, char *pcFmt, va_list rVArgList)
138 {
139         fprintf(prFP, "FORCED DEBUG: ");
140     LogVfprintf(prFP, pcFmt, rVArgList);
141 }
142 /* end of LogForcedDebug() */
143
144
145
146 /**
147  *
148  * @brief Sets up default function pointers
149  *
150  */
151 void
152 LogDefaultSetup(log_t *log)
153 {
154     log->iLogLevelEnabled = LOG_WARN;
155
156         log->prFP[LOG_DEBUG] = stdout;
157         log->prFP[LOG_INFO] = stdout;
158         log->prFP[LOG_WARN] = stderr;
159         log->prFP[LOG_ERROR] = stderr;
160         log->prFP[LOG_CRITICAL] = stderr;
161         log->prFP[LOG_FATAL] = stderr;
162         log->prFP[LOG_FORCED_DEBUG] = stderr;
163
164         log->prFunc[LOG_DEBUG] = &LogVfprintf;
165         log->prFunc[LOG_INFO] = &LogVfprintf;
166         log->prFunc[LOG_WARN] = &LogWarn;
167         log->prFunc[LOG_ERROR] = &LogError;
168         log->prFunc[LOG_CRITICAL] = &LogCritical;
169         log->prFunc[LOG_FATAL] = &LogFatal;
170         log->prFunc[LOG_FORCED_DEBUG] = &LogForcedDebug;
171 }
172 /* end of LogDefaultSetup() */
173
174
175
176 /**
177  * @brief Log to certain level
178  *
179  * See also comp.lang.c FAQ list ยท Question 15.12
180  * http://c-faq.com/varargs/handoff.html How can I write a function which
181  * takes a variable number of arguments and passes them to some other function
182  * (which takes a variable number of arguments)?
183  *
184  */
185 void
186 Log(log_t *prLog, int iLevel, char *pcFmt, ...) 
187 {
188         va_list rVArgList;
189     void (*prFunc) (FILE *prFP, char *pcFormat, va_list rVArgList);
190         FILE *prFP;
191
192         assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
193
194     /* fprintf(stderr, "DEBUG: iLevel=%d and iLogLevelEnabled=%d\n", iLevel, prLog->iLogLevelEnabled); */
195
196         /* return if below current loglevel */
197         if (iLevel < prLog->iLogLevelEnabled) {
198                 return;
199         }
200
201         prFunc = prLog->prFunc[iLevel];
202         prFP = prLog->prFP[iLevel];
203
204         /* return if muted */
205         if (NULL == prFunc) {
206                 return;
207         }
208
209         va_start(rVArgList, pcFmt);
210         prFunc(prFP, pcFmt, rVArgList);
211         va_end(rVArgList);
212 }
213 /* end of Log() */
214
215
216
217 /**
218  *
219  * @brief Change file pointer for certain level
220  *
221  */
222 void
223 LogSetFP(log_t *prLog, int iLevel, FILE *prFP)
224 {
225         assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
226
227         prLog->prFP[iLevel] = prFP;
228 }
229 /* end of LogSetFP() */
230
231
232
233 /**
234  *
235  * @brief Return file pointer for certain level
236  *
237  */
238 FILE *
239 LogGetFP(log_t *prLog, int iLevel)
240 {
241         assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
242
243         return prLog->prFP[iLevel];
244 }
245 /* end of LogGetFP() */
246
247
248
249
250
251 /**
252  *
253  * @brief Change file pointer for all levels
254  *
255  */
256 void
257 LogSetFPForAll(log_t *prLog, FILE *prFP)
258 {
259         int iAux;
260
261         for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
262                 prLog->prFP[iAux] = prFP;
263         }
264 }
265 /* end of LogSetFP() */
266
267
268
269 /**
270  *
271  * @brief Mute certain level (i.e set the corresponding function to NULL)
272  *
273  */
274 void
275 LogMute(log_t *prLog, int iLevel)
276 {
277         assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
278
279         prLog->prFunc[iLevel] = NULL;
280 }
281 /* end of LogMute() */
282
283
284 /**
285  *
286  * @brief Mute all channels
287  *
288  */
289 void
290 LogMuteAll(log_t *prLog)
291 {
292         int iAux;
293
294         for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
295                 LogMute(prLog, iAux);
296         }
297 }
298 /* end of LogMuteAll() */
299
300
301
302 /**
303  * @brief
304  *
305  */
306 void
307 LogFuncOverwrite(log_t *prLog, int iLevel, 
308                  void (*Func) (FILE *prFP, char *pcFormat, va_list rVArgList))
309 {
310         assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
311
312     prLog->prFunc[iLevel] = Func;
313
314 }
315 /* end of LogFuncOverwrite() */
316
317
318
319 #ifdef LOG_TEST
320
321
322 #define TEXT "Lorem ipsum dolor sit amet"
323
324 void
325 PrintSomeTextToAll(log_t *prLog) {
326         int iAux;
327         for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
328                 Log(prLog, iAux, TEXT);
329         }
330 }
331
332
333 int
334 main(int argc, char**argv) {
335         log_t prLog;
336         log_t pr2ndLog;
337         FILE *prFP;
338         char *pcTmpFileName = "schmock.txt";
339
340         prFP = fopen(pcTmpFileName, "w");
341
342          
343         LogDefaultSetup(&prLog);
344         LogDefaultSetup(&pr2ndLog);
345
346         printf("Printing to log:\n");
347         PrintSomeTextToAll(&prLog);
348         printf("---\n");
349
350         printf("Printing to pr2ndLog:\n");
351         PrintSomeTextToAll(&prLog);
352         printf("---\n");
353
354
355         
356         printf("Changing second log's FP to write to '%s'\n", pcTmpFileName);
357         LogSetFPForAll(&pr2ndLog, prFP);
358
359         printf("Printing to pr2ndLog:\n");
360         PrintSomeTextToAll(&pr2ndLog);
361         printf("---\n");
362
363
364         printf("Changing Info() to new function (Fatal()) in log:\n");
365     LogFuncOverwrite(&prLog, LOG_INFO, &LogFatal);
366
367         printf("Printing to log:\n");
368         PrintSomeTextToAll(&prLog);
369         printf("---\n");
370
371
372    
373         fclose(prFP);
374
375         return 0;
376 }
377
378
379 #endif