/src/c-toxcore/toxcore/logger.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: GPL-3.0-or-later |
2 | | * Copyright © 2016-2018 The TokTok team. |
3 | | * Copyright © 2013-2015 Tox project. |
4 | | */ |
5 | | |
6 | | /** |
7 | | * Text logging abstraction. |
8 | | */ |
9 | | #include "logger.h" |
10 | | |
11 | | #include <assert.h> |
12 | | #include <stdarg.h> |
13 | | #include <stdio.h> |
14 | | #include <stdlib.h> |
15 | | #include <string.h> |
16 | | |
17 | | #include "ccompat.h" |
18 | | |
19 | | struct Logger { |
20 | | logger_cb *callback; |
21 | | void *context; |
22 | | void *userdata; |
23 | | }; |
24 | | |
25 | | #ifndef NDEBUG |
26 | | static const char *logger_level_name(Logger_Level level) |
27 | 0 | { |
28 | 0 | switch (level) { |
29 | 0 | case LOGGER_LEVEL_TRACE: |
30 | 0 | return "TRACE"; |
31 | | |
32 | 0 | case LOGGER_LEVEL_DEBUG: |
33 | 0 | return "DEBUG"; |
34 | | |
35 | 0 | case LOGGER_LEVEL_INFO: |
36 | 0 | return "INFO"; |
37 | | |
38 | 0 | case LOGGER_LEVEL_WARNING: |
39 | 0 | return "WARNING"; |
40 | | |
41 | 0 | case LOGGER_LEVEL_ERROR: |
42 | 0 | return "ERROR"; |
43 | 0 | } |
44 | | |
45 | 0 | return "<unknown>"; |
46 | 0 | } |
47 | | #endif |
48 | | |
49 | | non_null(1, 3, 5, 6) nullable(7) |
50 | | static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func, |
51 | | const char *message, void *userdata) |
52 | 0 | { |
53 | 0 | #ifndef NDEBUG |
54 | | // GL stands for "global logger". |
55 | 0 | fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message); |
56 | 0 | fprintf(stderr, "Default stderr logger triggered; aborting program\n"); |
57 | 0 | abort(); |
58 | 0 | #endif |
59 | 0 | } |
60 | | |
61 | | static const Logger logger_stderr = { |
62 | | logger_stderr_handler, |
63 | | nullptr, |
64 | | nullptr, |
65 | | }; |
66 | | |
67 | | /* |
68 | | * Public Functions |
69 | | */ |
70 | | |
71 | | Logger *logger_new(void) |
72 | 3.10k | { |
73 | 3.10k | return (Logger *)calloc(1, sizeof(Logger)); |
74 | 3.10k | } |
75 | | |
76 | | void logger_kill(Logger *log) |
77 | 3.10k | { |
78 | 3.10k | free(log); |
79 | 3.10k | } |
80 | | |
81 | | void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata) |
82 | 3.10k | { |
83 | 3.10k | log->callback = function; |
84 | 3.10k | log->context = context; |
85 | 3.10k | log->userdata = userdata; |
86 | 3.10k | } |
87 | | |
88 | | void logger_write(const Logger *log, Logger_Level level, const char *file, int line, const char *func, |
89 | | const char *format, ...) |
90 | 103k | { |
91 | 103k | if (log == nullptr) { |
92 | 0 | log = &logger_stderr; |
93 | 0 | } |
94 | | |
95 | 103k | if (log->callback == nullptr) { |
96 | 0 | return; |
97 | 0 | } |
98 | | |
99 | | // Only pass the file name, not the entire file path, for privacy reasons. |
100 | | // The full path may contain PII of the person compiling toxcore (their |
101 | | // username and directory layout). |
102 | 103k | const char *filename = strrchr(file, '/'); |
103 | 103k | file = filename != nullptr ? filename + 1 : file; |
104 | | #if defined(_WIN32) || defined(__CYGWIN__) |
105 | | // On Windows, the path separator *may* be a backslash, so we look for that |
106 | | // one too. |
107 | | const char *windows_filename = strrchr(file, '\\'); |
108 | | file = windows_filename != nullptr ? windows_filename + 1 : file; |
109 | | #endif |
110 | | |
111 | | // Format message |
112 | 103k | char msg[1024]; |
113 | 103k | va_list args; |
114 | 103k | va_start(args, format); |
115 | 103k | vsnprintf(msg, sizeof(msg), format, args); |
116 | 103k | va_end(args); |
117 | | |
118 | 103k | log->callback(log->context, level, file, line, func, msg, log->userdata); |
119 | 103k | } |