/src/liblouis/liblouis/logging.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* liblouis Braille Translation and Back-Translation Library |
2 | | |
3 | | Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com |
4 | | Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com |
5 | | |
6 | | This file is part of liblouis. |
7 | | |
8 | | liblouis is free software: you can redistribute it and/or modify it |
9 | | under the terms of the GNU Lesser General Public License as published |
10 | | by the Free Software Foundation, either version 2.1 of the License, or |
11 | | (at your option) any later version. |
12 | | |
13 | | liblouis is distributed in the hope that it will be useful, but |
14 | | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | Lesser General Public License for more details. |
17 | | |
18 | | You should have received a copy of the GNU Lesser General Public |
19 | | License along with liblouis. If not, see <http://www.gnu.org/licenses/>. |
20 | | */ |
21 | | |
22 | | /** |
23 | | * @file |
24 | | * @brief Logging |
25 | | */ |
26 | | |
27 | | #include <config.h> |
28 | | |
29 | | #include <stddef.h> |
30 | | #include <stdlib.h> |
31 | | #include <stdio.h> |
32 | | #include <stdarg.h> |
33 | | #include <string.h> |
34 | | |
35 | | #include "internal.h" |
36 | | |
37 | | void EXPORT_CALL |
38 | 375 | _lou_logWidecharBuf(logLevels level, const char *msg, const widechar *wbuf, int wlen) { |
39 | | /* When calculating output size: |
40 | | * Each wdiechar is represented in hex, thus needing two bytes for each |
41 | | * byte in the widechar (sizeof(widechar) * 2) |
42 | | * Allow space for the "0x%X " formatting (+ 3) |
43 | | * Number of characters in widechar buffer (wlen * ) |
44 | | * Give space for additional message (+ strlen(msg)) |
45 | | * Remember the null terminator (+ 1) |
46 | | */ |
47 | 375 | int logBufSize = (wlen * ((sizeof(widechar) * 3) + 3)) + 3 + (int)strlen(msg); |
48 | 375 | char *logMsg = malloc(logBufSize); |
49 | 375 | char *p = logMsg; |
50 | 375 | const char *formatString; |
51 | 375 | int i = 0; |
52 | 375 | if (sizeof(widechar) == 2) |
53 | 375 | formatString = "0x%04X "; |
54 | 0 | else |
55 | 0 | formatString = "0x%08X "; |
56 | 2.64k | for (i = 0; i < (int)strlen(msg); i++) logMsg[i] = msg[i]; |
57 | 375 | p += strlen(msg); |
58 | 297k | for (i = 0; i < wlen; i++) { |
59 | 297k | p += sprintf(p, formatString, wbuf[i]); |
60 | 297k | } |
61 | 375 | *p = '~'; |
62 | 375 | p++; |
63 | 375 | *p = ' '; |
64 | 375 | p++; |
65 | 297k | for (i = 0; i < wlen; i++) { |
66 | 297k | if (wbuf[i] & 0xff00) |
67 | 165k | *p = ' '; |
68 | 132k | else |
69 | 132k | *p = (char)wbuf[i]; |
70 | 297k | p++; |
71 | 297k | } |
72 | 375 | *p = '\0'; |
73 | 375 | _lou_logMessage(level, "%s", logMsg); |
74 | 375 | free(logMsg); |
75 | 375 | } |
76 | | |
77 | | static void EXPORT_CALL |
78 | 0 | defaultLogCallback(logLevels level, const char *message) { |
79 | 0 | lou_logPrint("%s", |
80 | 0 | message); // lou_logPrint takes formatting, protect against % in message |
81 | 0 | } |
82 | | |
83 | | static logcallback logCallbackFunction = defaultLogCallback; |
84 | | void EXPORT_CALL |
85 | 1 | lou_registerLogCallback(logcallback callback) { |
86 | 1 | if (callback == NULL) |
87 | 0 | logCallbackFunction = defaultLogCallback; |
88 | 1 | else |
89 | 1 | logCallbackFunction = callback; |
90 | 1 | } |
91 | | |
92 | | static logLevels logLevel = LOU_LOG_INFO; |
93 | | void EXPORT_CALL |
94 | 0 | lou_setLogLevel(logLevels level) { |
95 | 0 | logLevel = level; |
96 | 0 | } |
97 | | |
98 | | void EXPORT_CALL |
99 | 212k | _lou_logMessage(logLevels level, const char *format, ...) { |
100 | 212k | if (format == NULL) return; |
101 | 212k | if (level < logLevel) return; |
102 | 211k | if (logCallbackFunction != NULL) { |
103 | | #ifdef _WIN32 |
104 | | double f = 2.3; // Needed to force VC++ runtime floating point support |
105 | | #endif |
106 | 211k | char *s; |
107 | 211k | size_t len; |
108 | 211k | va_list argp; |
109 | 211k | va_start(argp, format); |
110 | 211k | len = vsnprintf(0, 0, format, argp); |
111 | 211k | va_end(argp); |
112 | 211k | if ((s = malloc(len + 1)) != 0) { |
113 | 211k | va_start(argp, format); |
114 | 211k | vsnprintf(s, len + 1, format, argp); |
115 | 211k | va_end(argp); |
116 | 211k | logCallbackFunction(level, s); |
117 | 211k | free(s); |
118 | 211k | } |
119 | 211k | } |
120 | 211k | } |
121 | | |
122 | 0 | #define FILENAMESIZE 256 |
123 | | |
124 | | static FILE *logFile = NULL; |
125 | | static char initialLogFileName[FILENAMESIZE] = ""; |
126 | | |
127 | | void EXPORT_CALL |
128 | 0 | lou_logFile(const char *fileName) { |
129 | 0 | if (logFile) { |
130 | 0 | fclose(logFile); |
131 | 0 | logFile = NULL; |
132 | 0 | } |
133 | 0 | if (fileName == NULL || fileName[0] == 0 || strlen(fileName) >= FILENAMESIZE) return; |
134 | 0 | if (initialLogFileName[0] == 0) strcpy(initialLogFileName, fileName); |
135 | 0 | logFile = fopen(fileName, "a"); |
136 | 0 | if (logFile == NULL && initialLogFileName[0] != 0) |
137 | 0 | logFile = fopen(initialLogFileName, "a"); |
138 | 0 | if (logFile == NULL) { |
139 | 0 | fprintf(stderr, "Cannot open log file %s\n", fileName); |
140 | 0 | logFile = stderr; |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | | void EXPORT_CALL |
145 | 0 | lou_logPrint(const char *format, ...) { |
146 | 0 | #ifndef __SYMBIAN32__ |
147 | 0 | va_list argp; |
148 | 0 | if (format == NULL) return; |
149 | 0 | if (logFile == NULL) logFile = fopen(initialLogFileName, "a"); |
150 | 0 | if (logFile == NULL) logFile = stderr; |
151 | 0 | va_start(argp, format); |
152 | 0 | vfprintf(logFile, format, argp); |
153 | 0 | fprintf(logFile, "\n"); |
154 | 0 | fflush(logFile); |
155 | 0 | va_end(argp); |
156 | 0 | #endif |
157 | 0 | } |
158 | | |
159 | | /* Close the log file */ |
160 | | void EXPORT_CALL |
161 | 407 | lou_logEnd(void) { |
162 | 407 | if (logFile != NULL && logFile != stderr) fclose(logFile); |
163 | 407 | logFile = NULL; |
164 | 407 | } |