blob: bcf7c81f89e4a40f91dbbd37792428b908bd9c13 [file] [log] [blame]
/* liblouis Braille Translation and Back-Translation Library
Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
This file is part of liblouis.
liblouis is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.
liblouis is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Logging
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "internal.h"
void EXPORT_CALL
_lou_logWidecharBuf(logLevels level, const char *msg, const widechar *wbuf, int wlen) {
/* When calculating output size:
* Each wdiechar is represented in hex, thus needing two bytes for each
* byte in the widechar (sizeof(widechar) * 2)
* Allow space for the "0x%X " formatting (+ 3)
* Number of characters in widechar buffer (wlen * )
* Give space for additional message (+ strlen(msg))
* Remember the null terminator (+ 1)
*/
int logBufSize = (wlen * ((sizeof(widechar) * 3) + 3)) + 3 + (int)strlen(msg);
char *logMsg = malloc(logBufSize);
char *p = logMsg;
const char *formatString;
int i = 0;
if (sizeof(widechar) == 2)
formatString = "0x%04X ";
else
formatString = "0x%08X ";
for (i = 0; i < (int)strlen(msg); i++) logMsg[i] = msg[i];
p += strlen(msg);
for (i = 0; i < wlen; i++) {
p += sprintf(p, formatString, wbuf[i]);
}
*p = '~';
p++;
*p = ' ';
p++;
for (i = 0; i < wlen; i++) {
if (wbuf[i] & 0xff00)
*p = ' ';
else
*p = (char)wbuf[i];
p++;
}
*p = '\0';
_lou_logMessage(level, "%s", logMsg);
free(logMsg);
}
static void EXPORT_CALL
defaultLogCallback(logLevels level, const char *message) {
lou_logPrint("%s",
message); // lou_logPrint takes formatting, protect against % in message
}
static logcallback logCallbackFunction = defaultLogCallback;
void EXPORT_CALL
lou_registerLogCallback(logcallback callback) {
if (callback == NULL)
logCallbackFunction = defaultLogCallback;
else
logCallbackFunction = callback;
}
static logLevels logLevel = LOU_LOG_INFO;
void EXPORT_CALL
lou_setLogLevel(logLevels level) {
logLevel = level;
}
void EXPORT_CALL
_lou_logMessage(logLevels level, const char *format, ...) {
if (format == NULL) return;
if (level < logLevel) return;
if (logCallbackFunction != NULL) {
#ifdef _WIN32
double f = 2.3; // Needed to force VC++ runtime floating point support
#endif
char *s;
size_t len;
va_list argp;
va_start(argp, format);
len = vsnprintf(0, 0, format, argp);
va_end(argp);
if ((s = malloc(len + 1)) != 0) {
va_start(argp, format);
vsnprintf(s, len + 1, format, argp);
va_end(argp);
logCallbackFunction(level, s);
free(s);
}
}
}
static FILE *logFile = NULL;
static char initialLogFileName[256] = "";
void EXPORT_CALL
lou_logFile(const char *fileName) {
if (logFile) {
fclose(logFile);
logFile = NULL;
}
if (fileName == NULL || fileName[0] == 0) return;
if (initialLogFileName[0] == 0) strcpy(initialLogFileName, fileName);
logFile = fopen(fileName, "a");
if (logFile == NULL && initialLogFileName[0] != 0)
logFile = fopen(initialLogFileName, "a");
if (logFile == NULL) {
fprintf(stderr, "Cannot open log file %s\n", fileName);
logFile = stderr;
}
}
void EXPORT_CALL
lou_logPrint(const char *format, ...) {
#ifndef __SYMBIAN32__
va_list argp;
if (format == NULL) return;
if (logFile == NULL) logFile = fopen(initialLogFileName, "a");
if (logFile == NULL) logFile = stderr;
va_start(argp, format);
vfprintf(logFile, format, argp);
fprintf(logFile, "\n");
fflush(logFile);
va_end(argp);
#endif
}
/* Close the log file */
void EXPORT_CALL
lou_logEnd(void) {
if (logFile != NULL && logFile != stderr) fclose(logFile);
logFile = NULL;
}