Blender V5.0
CLG_log.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2018-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
30
31#pragma once
32
33#ifdef __GNUC__
34# define _CLOG_ATTR_NONNULL(args...) __attribute__((nonnull(args)))
35#else
36# define _CLOG_ATTR_NONNULL(...)
37#endif
38
39#ifdef __GNUC__
40# define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param) \
41 __attribute__((format(printf, format_param, dots_param)))
42#else
43# define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param)
44#endif
45
46#define STRINGIFY_ARG(x) "" #x
47#define STRINGIFY_APPEND(a, b) "" a #b
48#define STRINGIFY(x) STRINGIFY_APPEND("", x)
49
50struct CLogContext;
51
53 /* Similar to assert. This logs the message, then a stack trace and abort. */
55 /* An error we can recover from, should not happen. */
57 /* General warnings (which aren't necessary to show to users). */
59 /* Information about devices, files, configuration, user operations. */
61 /* Debugging information for developers. */
63 /* Very verbose code execution tracing. */
65};
66#define CLG_LEVEL_LEN (CLG_LEVEL_TRACE + 1)
67
68/* Each logger ID has one of these. */
77
78struct CLG_LogRef {
79 CLG_LogRef(const char *identifier);
80
81 const char *identifier;
84};
85
86void CLG_log_str(const CLG_LogType *lg,
87 enum CLG_Level level,
88 const char *file_line,
89 const char *fn,
90 const char *message) _CLOG_ATTR_NONNULL(1, 3, 4, 5);
91void CLG_logf(const CLG_LogType *lg,
92 enum CLG_Level level,
93 const char *file_line,
94 const char *fn,
95 const char *format,
97void CLG_log_raw(const CLG_LogType *lg, const char *message);
98
99/* Main initializer and destructor (per session, not logger). */
100void CLG_init();
101void CLG_exit();
102
103void CLG_output_set(void *file_handle);
104void CLG_output_use_source_set(int value);
105void CLG_output_use_basename_set(int value);
106void CLG_output_use_timestamp_set(int value);
107void CLG_output_use_memory_set(int value);
108void CLG_error_fn_set(void (*error_fn)(void *file_handle));
109void CLG_fatal_fn_set(void (*fatal_fn)(void *file_handle));
110void CLG_backtrace_fn_set(void (*fatal_fn)(void *file_handle));
111
112void CLG_type_filter_include(const char *type_match, int type_match_len);
113void CLG_type_filter_exclude(const char *type_match, int type_match_len);
114
115void CLG_level_set(CLG_Level level);
116
117void CLG_logref_init(CLG_LogRef *clg_ref);
118
119void CLG_logref_register(CLG_LogRef *clg_ref);
120void CLG_logref_list_all(void (*callback)(const char *identifier, void *user_data),
121 void *user_data);
122
124
125/* When true, quiet any NOCHECK logs that would otherwise be printed regardless of log filters
126 * and levels. This is used so command line tools can control output without unnecessary noise.
127 *
128 * Note this does not silence log filters and levels that have been explicitly enabled. */
129void CLG_quiet_set(bool quiet);
130bool CLG_quiet_get();
131
132inline CLG_LogRef::CLG_LogRef(const char *identifier)
133 : identifier(identifier), type(nullptr), next(nullptr)
134{
136}
137
139#define CLG_LOGREF_DECLARE_GLOBAL(var, id) \
140 static CLG_LogRef _static_##var = {id}; \
141 CLG_LogRef *var = &_static_##var
142
144#define CLOG_ENSURE(clg_ref) \
145 ((clg_ref)->type ? (clg_ref)->type : (CLG_logref_init(clg_ref), (clg_ref)->type))
146
147#define CLOG_CHECK(clg_ref, verbose_level, ...) \
148 ((void)CLOG_ENSURE(clg_ref), ((clg_ref)->type->level >= verbose_level))
149
150#define CLOG_AT_LEVEL(clg_ref, verbose_level, ...) \
151 { \
152 const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
153 if (_lg_ty->level >= verbose_level) { \
154 CLG_logf(_lg_ty, verbose_level, __FILE__ ":" STRINGIFY(__LINE__), __func__, __VA_ARGS__); \
155 } \
156 } \
157 ((void)0)
158
159#define CLOG_AT_LEVEL_NOCHECK(clg_ref, verbose_level, ...) \
160 { \
161 const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
162 if (!CLG_quiet_get() || _lg_ty->level >= verbose_level) { \
163 CLG_logf(_lg_ty, verbose_level, __FILE__ ":" STRINGIFY(__LINE__), __func__, __VA_ARGS__); \
164 } \
165 } \
166 ((void)0)
167
168#define CLOG_STR_AT_LEVEL(clg_ref, verbose_level, str) \
169 { \
170 const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
171 if (_lg_ty->level >= verbose_level) { \
172 CLG_log_str(_lg_ty, verbose_level, __FILE__ ":" STRINGIFY(__LINE__), __func__, str); \
173 } \
174 } \
175 ((void)0)
176
177#define CLOG_STR_AT_LEVEL_NOCHECK(clg_ref, verbose_level, str) \
178 { \
179 const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
180 if (!CLG_quiet_get() || _lg_ty->level >= verbose_level) { \
181 CLG_log_str(_lg_ty, verbose_level, __FILE__ ":" STRINGIFY(__LINE__), __func__, str); \
182 } \
183 } \
184 ((void)0)
185
186/* Log with format string. */
187#define CLOG_FATAL(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_FATAL, __VA_ARGS__)
188#define CLOG_ERROR(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_ERROR, __VA_ARGS__)
189#define CLOG_WARN(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_WARN, __VA_ARGS__)
190#define CLOG_INFO(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_INFO, __VA_ARGS__)
191#define CLOG_DEBUG(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_DEBUG, __VA_ARGS__)
192#define CLOG_TRACE(clg_ref, ...) CLOG_AT_LEVEL(clg_ref, CLG_LEVEL_TRACE, __VA_ARGS__)
193
194/* Log single string. */
195#define CLOG_STR_FATAL(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_FATAL, str)
196#define CLOG_STR_ERROR(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_ERROR, str)
197#define CLOG_STR_WARN(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_WARN, str)
198#define CLOG_STR_INFO(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_INFO, str)
199#define CLOG_STR_DEBUG(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_DEBUG, str)
200#define CLOG_STR_TRACE(clg_ref, str) CLOG_STR_AT_LEVEL(clg_ref, CLG_LEVEL_TRACE, str)
201
202/* Log regardless of filters and levels, for a few important messages like blend save and load.
203 * Only #CLG_quiet_set will silence these. */
204#define CLOG_INFO_NOCHECK(clg_ref, format, ...) \
205 CLOG_AT_LEVEL_NOCHECK(clg_ref, CLG_LEVEL_INFO, format, __VA_ARGS__)
206#define CLOG_STR_INFO_NOCHECK(clg_ref, str) CLOG_STR_AT_LEVEL_NOCHECK(clg_ref, CLG_LEVEL_INFO, str)
void CLG_type_filter_exclude(const char *type_match, int type_match_len)
Definition clog.cc:925
bool CLG_quiet_get()
Definition clog.cc:945
void CLG_output_set(void *file_handle)
Definition clog.cc:885
void CLG_output_use_basename_set(int value)
Definition clog.cc:895
void CLG_exit()
Definition clog.cc:880
void void CLG_logf(const CLG_LogType *lg, enum CLG_Level level, const char *file_line, const char *fn, const char *format,...) _CLOG_ATTR_NONNULL(1
void CLG_output_use_memory_set(int value)
Definition clog.cc:905
void CLG_log_raw(const CLG_LogType *lg, const char *message)
Definition clog.cc:700
void CLG_log_str(const CLG_LogType *lg, enum CLG_Level level, const char *file_line, const char *fn, const char *message) _CLOG_ATTR_NONNULL(1
void CLG_error_fn_set(void(*error_fn)(void *file_handle))
Definition clog.cc:910
void CLG_level_set(CLG_Level level)
Definition clog.cc:935
void CLG_output_use_source_set(int value)
Definition clog.cc:890
void CLG_backtrace_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.cc:920
#define _CLOG_ATTR_NONNULL(...)
Definition CLG_log.h:36
void CLG_fatal_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.cc:915
void CLG_logref_list_all(void(*callback)(const char *identifier, void *user_data), void *user_data)
Definition clog.cc:969
void CLG_logref_register(CLG_LogRef *clg_ref)
Definition clog.cc:958
void CLG_type_filter_include(const char *type_match, int type_match_len)
Definition clog.cc:930
void CLG_logref_init(CLG_LogRef *clg_ref)
Definition clog.cc:984
#define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param)
Definition CLG_log.h:43
CLG_Level
Definition CLG_log.h:52
@ CLG_LEVEL_ERROR
Definition CLG_log.h:56
@ CLG_LEVEL_DEBUG
Definition CLG_log.h:62
@ CLG_LEVEL_INFO
Definition CLG_log.h:60
@ CLG_LEVEL_FATAL
Definition CLG_log.h:54
@ CLG_LEVEL_WARN
Definition CLG_log.h:58
@ CLG_LEVEL_TRACE
Definition CLG_log.h:64
void CLG_output_use_timestamp_set(int value)
Definition clog.cc:900
void CLG_quiet_set(bool quiet)
Definition clog.cc:940
int CLG_color_support_get(CLG_LogRef *clg_ref)
Definition clog.cc:1006
void CLG_init()
Definition clog.cc:873
format
const char * identifier
Definition CLG_log.h:81
CLG_LogRef(const char *identifier)
Definition CLG_log.h:132
struct CLG_LogRef * next
Definition CLG_log.h:83
CLG_LogType * type
Definition CLG_log.h:82
char identifier[64]
Definition CLG_log.h:71
CLG_Level level
Definition CLG_log.h:75
struct CLG_LogType * next
Definition CLG_log.h:70
struct CLogContext * ctx
Definition CLG_log.h:73