Coverage Report

Created: 2025-07-18 06:55

/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
}