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