1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 /*********************************************************************
4 * Clustal Omega - Multiple sequence alignment
6 * Copyright (C) 2010 University College Dublin
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.
13 * This file is part of Clustal-Omega.
15 ********************************************************************/
33 /* a default standard logger */
39 LogVfprintf(FILE *prFP, char *pcFmt, va_list rVArgList);
41 LogWarn(FILE *prFP, char *pcFmt, va_list rVArgList);
43 LogError(FILE *prFP, char *pcFmt, va_list rVArgList);
45 LogCritical(FILE *prFP, char *pcFmt, va_list rVArgList);
47 LogFatal(FILE *prFP, char *pcFmt, va_list rVArgList);
49 LogForcedDebug(FILE *prFP, char *pcFmt, va_list rVArgList);
55 * @brief Plain, default print function
57 * Newline character is automatically appended to message.
61 LogVfprintf(FILE *prFP, char *pcFmt, va_list rVArgList)
64 vfprintf(prFP, pcFmt, rVArgList);
71 /* end of LogVfprintf() */
80 LogWarn(FILE *prFP, char *pcFmt, va_list rVArgList)
82 fprintf(prFP, "WARNING: ");
83 LogVfprintf(prFP, pcFmt, rVArgList);
85 /* end of LogWarn() */
94 LogError(FILE *prFP, char *pcFmt, va_list rVArgList)
96 fprintf(prFP, "ERROR: ");
97 LogVfprintf(prFP, pcFmt, rVArgList);
99 /* end of LogError() */
108 LogCritical(FILE *prFP, char *pcFmt, va_list rVArgList)
110 fprintf(prFP, "CRITICAL ERROR: ");
111 LogVfprintf(prFP, pcFmt, rVArgList);
113 /* end of LogCritical() */
118 * @brief Will also exit!
121 LogFatal(FILE *prFP, char *pcFmt, va_list rVArgList)
123 fprintf(prFP, "FATAL: ");
124 LogVfprintf(prFP, pcFmt, rVArgList);
128 /* end of LogFatal() */
137 LogForcedDebug(FILE *prFP, char *pcFmt, va_list rVArgList)
139 fprintf(prFP, "FORCED DEBUG: ");
140 LogVfprintf(prFP, pcFmt, rVArgList);
142 /* end of LogForcedDebug() */
148 * @brief Sets up default function pointers
152 LogDefaultSetup(log_t *log)
154 log->iLogLevelEnabled = LOG_WARN;
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;
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;
172 /* end of LogDefaultSetup() */
177 * @brief Log to certain level
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)?
186 Log(log_t *prLog, int iLevel, char *pcFmt, ...)
189 void (*prFunc) (FILE *prFP, char *pcFormat, va_list rVArgList);
192 assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
194 /* fprintf(stderr, "DEBUG: iLevel=%d and iLogLevelEnabled=%d\n", iLevel, prLog->iLogLevelEnabled); */
196 /* return if below current loglevel */
197 if (iLevel < prLog->iLogLevelEnabled) {
201 prFunc = prLog->prFunc[iLevel];
202 prFP = prLog->prFP[iLevel];
204 /* return if muted */
205 if (NULL == prFunc) {
209 va_start(rVArgList, pcFmt);
210 prFunc(prFP, pcFmt, rVArgList);
219 * @brief Change file pointer for certain level
223 LogSetFP(log_t *prLog, int iLevel, FILE *prFP)
225 assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
227 prLog->prFP[iLevel] = prFP;
229 /* end of LogSetFP() */
235 * @brief Return file pointer for certain level
239 LogGetFP(log_t *prLog, int iLevel)
241 assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
243 return prLog->prFP[iLevel];
245 /* end of LogGetFP() */
253 * @brief Change file pointer for all levels
257 LogSetFPForAll(log_t *prLog, FILE *prFP)
261 for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
262 prLog->prFP[iAux] = prFP;
265 /* end of LogSetFP() */
271 * @brief Mute certain level (i.e set the corresponding function to NULL)
275 LogMute(log_t *prLog, int iLevel)
277 assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
279 prLog->prFunc[iLevel] = NULL;
281 /* end of LogMute() */
286 * @brief Mute all channels
290 LogMuteAll(log_t *prLog)
294 for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
295 LogMute(prLog, iAux);
298 /* end of LogMuteAll() */
307 LogFuncOverwrite(log_t *prLog, int iLevel,
308 void (*Func) (FILE *prFP, char *pcFormat, va_list rVArgList))
310 assert(iLevel>=0 && iLevel<=LOG_NUM_LEVELS);
312 prLog->prFunc[iLevel] = Func;
315 /* end of LogFuncOverwrite() */
322 #define TEXT "Lorem ipsum dolor sit amet"
325 PrintSomeTextToAll(log_t *prLog) {
327 for (iAux=0; iAux<LOG_NUM_LEVELS; iAux++) {
328 Log(prLog, iAux, TEXT);
334 main(int argc, char**argv) {
338 char *pcTmpFileName = "schmock.txt";
340 prFP = fopen(pcTmpFileName, "w");
343 LogDefaultSetup(&prLog);
344 LogDefaultSetup(&pr2ndLog);
346 printf("Printing to log:\n");
347 PrintSomeTextToAll(&prLog);
350 printf("Printing to pr2ndLog:\n");
351 PrintSomeTextToAll(&prLog);
356 printf("Changing second log's FP to write to '%s'\n", pcTmpFileName);
357 LogSetFPForAll(&pr2ndLog, prFP);
359 printf("Printing to pr2ndLog:\n");
360 PrintSomeTextToAll(&pr2ndLog);
364 printf("Changing Info() to new function (Fatal()) in log:\n");
365 LogFuncOverwrite(&prLog, LOG_INFO, &LogFatal);
367 printf("Printing to log:\n");
368 PrintSomeTextToAll(&prLog);