Blender V4.3
clog.c
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
9#include <assert.h>
10#include <stdarg.h>
11#include <stdint.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16/* Disable for small single threaded programs
17 * to avoid having to link with pthreads. */
18#ifdef WITH_CLOG_PTHREADS
19# include "atomic_ops.h"
20# include <pthread.h>
21#endif
22
23/* For 'isatty' to check for color. */
24#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
25# include <sys/time.h>
26# include <unistd.h>
27#endif
28
29#if defined(_MSC_VER)
30# include <Windows.h>
31
32# include <VersionHelpers.h> /* This needs to be included after Windows.h. */
33# include <io.h>
34# if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
35# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
36# endif
37#endif
38
39/* For printing timestamp. */
40#define __STDC_FORMAT_MACROS
41#include <inttypes.h>
42
43/* Only other dependency (could use regular malloc too). */
44#include "MEM_guardedalloc.h"
45
46/* own include. */
47#include "CLG_log.h"
48
49/* Local utility defines */
50#define STREQ(a, b) (strcmp(a, b) == 0)
51#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
52
53#ifdef _WIN32
54# define PATHSEP_CHAR '\\'
55#else
56# define PATHSEP_CHAR '/'
57#endif
58
59/* -------------------------------------------------------------------- */
63typedef struct CLG_IDFilter {
66 char match[0];
68
69typedef struct CLogContext {
74#ifdef WITH_CLOG_PTHREADS
75 pthread_mutex_t types_lock;
76#endif
77
78 /* exclude, include filters. */
79 CLG_IDFilter *filters[2];
83
85 int output;
87
90
92 struct {
93 int level;
95
96 struct {
97 void (*error_fn)(void *file_handle);
98 void (*fatal_fn)(void *file_handle);
99 void (*backtrace_fn)(void *file_handle);
102
105/* -------------------------------------------------------------------- */
111#define CLOG_BUF_LEN_INIT 512
112
119
120static void clg_str_init(CLogStringBuf *cstr, char *buf_stack, uint buf_stack_len)
121{
122 cstr->data = buf_stack;
123 cstr->len_alloc = buf_stack_len;
124 cstr->len = 0;
125 cstr->is_alloc = false;
126}
127
128static void clg_str_free(CLogStringBuf *cstr)
129{
130 if (cstr->is_alloc) {
131 MEM_freeN(cstr->data);
132 }
133}
134
135static void clg_str_reserve(CLogStringBuf *cstr, const uint len)
136{
137 if (len > cstr->len_alloc) {
138 cstr->len_alloc *= 2;
139 if (len > cstr->len_alloc) {
140 cstr->len_alloc = len;
141 }
142
143 if (cstr->is_alloc) {
144 cstr->data = MEM_reallocN(cstr->data, cstr->len_alloc);
145 }
146 else {
147 /* Copy the static buffer. */
148 char *data = MEM_mallocN(cstr->len_alloc, __func__);
149 memcpy(data, cstr->data, cstr->len);
150 cstr->data = data;
151 cstr->is_alloc = true;
152 }
153 }
154}
155
156static void clg_str_append_with_len(CLogStringBuf *cstr, const char *str, const uint len)
157{
158 uint len_next = cstr->len + len;
159 clg_str_reserve(cstr, len_next);
160 char *str_dst = cstr->data + cstr->len;
161 memcpy(str_dst, str, len);
162#if 0 /* no need. */
163 str_dst[len] = '\0';
164#endif
165 cstr->len = len_next;
166}
167
168static void clg_str_append(CLogStringBuf *cstr, const char *str)
169{
170 clg_str_append_with_len(cstr, str, strlen(str));
171}
172
174static void clg_str_vappendf(CLogStringBuf *cstr, const char *format, va_list args)
175{
176 /* Use limit because windows may use '-1' for a formatting error. */
177 const uint len_max = 65535;
178 uint len_avail = cstr->len_alloc - cstr->len;
179 while (true) {
180 va_list args_cpy;
181 va_copy(args_cpy, args);
182 int retval = vsnprintf(cstr->data + cstr->len, len_avail, format, args_cpy);
183 va_end(args_cpy);
184
185 if (retval < 0) {
186 /* Some encoding error happened, not much we can do here, besides skipping/canceling this
187 * message. */
188 break;
189 }
190
191 if ((uint)retval <= len_avail) {
192 /* Copy was successful. */
193 cstr->len += (uint)retval;
194 break;
195 }
196
197 /* `vsnprintf` was not successful, due to lack of allocated space, `retval` contains expected
198 * length of the formatted string, use it to allocate required amount of memory. */
199 uint len_alloc = cstr->len + (uint)retval;
200 if (len_alloc >= len_max) {
201 /* Safe upper-limit, just in case... */
202 break;
203 }
204
206 len_avail = cstr->len_alloc - cstr->len;
207 }
208}
209
212/* -------------------------------------------------------------------- */
224#define COLOR_LEN (COLOR_RESET + 1)
225
226static const char *clg_color_table[COLOR_LEN] = {NULL};
227#ifdef _WIN32
228static DWORD clg_previous_console_mode = 0;
229#endif
230
231static void clg_color_table_init(bool use_color)
232{
233 for (int i = 0; i < COLOR_LEN; i++) {
234 clg_color_table[i] = "";
235 }
236 if (use_color) {
237 clg_color_table[COLOR_DEFAULT] = "\033[1;37m";
238 clg_color_table[COLOR_RED] = "\033[1;31m";
239 clg_color_table[COLOR_GREEN] = "\033[1;32m";
240 clg_color_table[COLOR_YELLOW] = "\033[1;33m";
241 clg_color_table[COLOR_RESET] = "\033[0m";
242 }
243}
244
245static const char *clg_severity_str[CLG_SEVERITY_LEN] = {
246 [CLG_SEVERITY_INFO] = "INFO",
247 [CLG_SEVERITY_WARN] = "WARN",
248 [CLG_SEVERITY_ERROR] = "ERROR",
249 [CLG_SEVERITY_FATAL] = "FATAL",
250};
251
252static const char *clg_severity_as_text(enum CLG_Severity severity)
253{
254 bool ok = (unsigned int)severity < CLG_SEVERITY_LEN;
255 assert(ok);
256 if (ok) {
257 return clg_severity_str[severity];
258 }
259 else {
260 return "INVALID_SEVERITY";
261 }
262}
263
265{
266 assert((unsigned int)severity < CLG_SEVERITY_LEN);
267 enum eCLogColor color = COLOR_DEFAULT;
268 switch (severity) {
270 color = COLOR_DEFAULT;
271 break;
273 color = COLOR_YELLOW;
274 break;
277 color = COLOR_RED;
278 break;
279 default:
280 /* should never get here. */
281 assert(false);
282 }
283 return color;
284}
285
288/* -------------------------------------------------------------------- */
300static bool clg_ctx_filter_check(CLogContext *ctx, const char *identifier)
301{
302 const size_t identifier_len = strlen(identifier);
303 for (uint i = 0; i < 2; i++) {
304 const CLG_IDFilter *flt = ctx->filters[i];
305 while (flt != NULL) {
306 const size_t len = strlen(flt->match);
307 if (STREQ(flt->match, "*") || ((len == identifier_len) && (STREQ(identifier, flt->match)))) {
308 return (bool)i;
309 }
310 if (flt->match[0] == '*' && flt->match[len - 1] == '*') {
311 char *match = MEM_callocN(sizeof(char) * len - 1, __func__);
312 memcpy(match, flt->match + 1, len - 2);
313 const bool success = (strstr(identifier, match) != NULL);
314 MEM_freeN(match);
315 if (success) {
316 return (bool)i;
317 }
318 }
319 else if ((len >= 2) && (STREQLEN(".*", &flt->match[len - 2], 2))) {
320 if (((identifier_len == len - 2) && STREQLEN(identifier, flt->match, len - 2)) ||
321 ((identifier_len >= len - 1) && STREQLEN(identifier, flt->match, len - 1)))
322 {
323 return (bool)i;
324 }
325 }
326 flt = flt->next;
327 }
328 }
329 return false;
330}
331
336static CLG_LogType *clg_ctx_type_find_by_name(CLogContext *ctx, const char *identifier)
337{
338 for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
339 if (STREQ(identifier, ty->identifier)) {
340 return ty;
341 }
342 }
343 return NULL;
344}
345
346static CLG_LogType *clg_ctx_type_register(CLogContext *ctx, const char *identifier)
347{
348 assert(clg_ctx_type_find_by_name(ctx, identifier) == NULL);
349 CLG_LogType *ty = MEM_callocN(sizeof(*ty), __func__);
350 ty->next = ctx->types;
351 ctx->types = ty;
352 strncpy(ty->identifier, identifier, sizeof(ty->identifier) - 1);
353 ty->ctx = ctx;
354 ty->level = ctx->default_type.level;
355
356 if (clg_ctx_filter_check(ctx, ty->identifier)) {
357 ty->flag |= CLG_FLAG_USE;
358 }
359 return ty;
360}
361
363{
364 if (ctx->callbacks.error_fn != NULL) {
365 ctx->callbacks.error_fn(ctx->output_file);
366 }
367}
368
370{
371 if (ctx->callbacks.fatal_fn != NULL) {
372 ctx->callbacks.fatal_fn(ctx->output_file);
373 }
374 fflush(ctx->output_file);
375 abort();
376}
377
379{
380 /* NOTE: we avoid writing to 'FILE', for back-trace we make an exception,
381 * if necessary we could have a version of the callback that writes to file
382 * descriptor all at once. */
384 fflush(ctx->output_file);
385}
386
388{
389 uint64_t tick;
390#if defined(_MSC_VER)
391 tick = GetTickCount64();
392#else
393 struct timeval tv;
394 gettimeofday(&tv, NULL);
395 tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
396#endif
397 return tick;
398}
399
402/* -------------------------------------------------------------------- */
406static void write_timestamp(CLogStringBuf *cstr, const uint64_t timestamp_tick_start)
407{
408 char timestamp_str[64];
409 const uint64_t timestamp = clg_timestamp_ticks_get() - timestamp_tick_start;
410 const uint timestamp_len = snprintf(timestamp_str,
411 sizeof(timestamp_str),
412 "%" PRIu64 ".%03u ",
413 timestamp / 1000,
414 (uint)(timestamp % 1000));
415 clg_str_append_with_len(cstr, timestamp_str, timestamp_len);
416}
417
418static void write_severity(CLogStringBuf *cstr, enum CLG_Severity severity, bool use_color)
419{
420 assert((unsigned int)severity < CLG_SEVERITY_LEN);
421 if (use_color) {
422 enum eCLogColor color = clg_severity_to_color(severity);
423 clg_str_append(cstr, clg_color_table[color]);
424 clg_str_append(cstr, clg_severity_as_text(severity));
426 }
427 else {
428 clg_str_append(cstr, clg_severity_as_text(severity));
429 }
430}
431
432static void write_type(CLogStringBuf *cstr, const CLG_LogType *lg)
433{
434 clg_str_append(cstr, " (");
435 clg_str_append(cstr, lg->identifier);
436 clg_str_append(cstr, "): ");
437}
438
440 const char *file_line,
441 const char *fn,
442 const bool use_basename)
443{
444 uint file_line_len = strlen(file_line);
445 if (use_basename) {
446 uint file_line_offset = file_line_len;
447 while (file_line_offset-- > 0) {
448 if (file_line[file_line_offset] == PATHSEP_CHAR) {
449 file_line_offset++;
450 break;
451 }
452 }
453 file_line += file_line_offset;
454 file_line_len -= file_line_offset;
455 }
456 clg_str_append_with_len(cstr, file_line, file_line_len);
457
458 clg_str_append(cstr, " ");
459 clg_str_append(cstr, fn);
460 clg_str_append(cstr, ": ");
461}
462
464 enum CLG_Severity severity,
465 const char *file_line,
466 const char *fn,
467 const char *message)
468{
469 CLogStringBuf cstr;
470 char cstr_stack_buf[CLOG_BUF_LEN_INIT];
471 clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
472
473 if (lg->ctx->use_timestamp) {
475 }
476
477 write_severity(&cstr, severity, lg->ctx->use_color);
478 write_type(&cstr, lg);
479
480 {
481 write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
482 clg_str_append(&cstr, message);
483 }
484 clg_str_append(&cstr, "\n");
485
486 /* could be optional */
487 int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
488 (void)bytes_written;
489
490 clg_str_free(&cstr);
491
492 if (lg->ctx->callbacks.backtrace_fn) {
494 }
495
496 if (severity == CLG_SEVERITY_FATAL) {
498 }
499}
500
501void CLG_logf(const CLG_LogType *lg,
502 enum CLG_Severity severity,
503 const char *file_line,
504 const char *fn,
505 const char *format,
506 ...)
507{
508 CLogStringBuf cstr;
509 char cstr_stack_buf[CLOG_BUF_LEN_INIT];
510 clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
511
512 if (lg->ctx->use_timestamp) {
514 }
515
516 write_severity(&cstr, severity, lg->ctx->use_color);
517 write_type(&cstr, lg);
518
519 {
520 write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
521
522 va_list ap;
523 va_start(ap, format);
524 clg_str_vappendf(&cstr, format, ap);
525 va_end(ap);
526 }
527 clg_str_append(&cstr, "\n");
528
529 /* could be optional */
530 int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
531 (void)bytes_written;
532
533 clg_str_free(&cstr);
534
535 if (lg->ctx->callbacks.backtrace_fn) {
537 }
538
539 if (severity == CLG_SEVERITY_ERROR) {
541 }
542
543 if (severity == CLG_SEVERITY_FATAL) {
545 }
546}
547
550/* -------------------------------------------------------------------- */
554static void CLG_ctx_output_set(CLogContext *ctx, void *file_handle)
555{
556 ctx->output_file = file_handle;
557 ctx->output = fileno(ctx->output_file);
558#if defined(__unix__) || defined(__APPLE__)
559 ctx->use_color = isatty(ctx->output);
560#elif defined(WIN32)
561 /* As of Windows 10 build 18298 all the standard consoles supports color
562 * like the Linux Terminal do, but it needs to be turned on.
563 * To turn on colors we need to enable virtual terminal processing by passing the flag
564 * ENABLE_VIRTUAL_TERMINAL_PROCESSING into SetConsoleMode.
565 * If the system doesn't support virtual terminal processing it will fail silently and the flag
566 * will not be set. */
567
568 GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &clg_previous_console_mode);
569
570 ctx->use_color = 0;
571 if (IsWindows10OrGreater() && isatty(ctx->output)) {
572 DWORD mode = clg_previous_console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
573 if (SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode)) {
574 ctx->use_color = 1;
575 }
576 }
577#endif
578}
579
581{
582 ctx->use_basename = (bool)value;
583}
584
586{
587 ctx->use_timestamp = (bool)value;
588 if (ctx->use_timestamp) {
590 }
591}
592
594static void CLT_ctx_error_fn_set(CLogContext *ctx, void (*error_fn)(void *file_handle))
595{
596 ctx->callbacks.error_fn = error_fn;
597}
598
600static void CLG_ctx_fatal_fn_set(CLogContext *ctx, void (*fatal_fn)(void *file_handle))
601{
602 ctx->callbacks.fatal_fn = fatal_fn;
603}
604
605static void CLG_ctx_backtrace_fn_set(CLogContext *ctx, void (*backtrace_fn)(void *file_handle))
606{
607 ctx->callbacks.backtrace_fn = backtrace_fn;
608}
609
611 const char *type_match,
612 int type_match_len)
613{
614 if (type_match_len == 0) {
615 return;
616 }
617 CLG_IDFilter *flt = MEM_callocN(sizeof(*flt) + (type_match_len + 1), __func__);
618 flt->next = *flt_list;
619 *flt_list = flt;
620 memcpy(flt->match, type_match, type_match_len);
621 /* no need to null terminate since we calloc'd */
622}
623
625 const char *type_match,
626 int type_match_len)
627{
628 clg_ctx_type_filter_append(&ctx->filters[0], type_match, type_match_len);
629}
630
632 const char *type_match,
633 int type_match_len)
634{
635 clg_ctx_type_filter_append(&ctx->filters[1], type_match, type_match_len);
636}
637
638static void CLG_ctx_level_set(CLogContext *ctx, int level)
639{
640 ctx->default_type.level = level;
641 for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
642 ty->level = level;
643 }
644}
645
647{
648 CLogContext *ctx = MEM_callocN(sizeof(*ctx), __func__);
649#ifdef WITH_CLOG_PTHREADS
650 pthread_mutex_init(&ctx->types_lock, NULL);
651#endif
652 ctx->default_type.level = 1;
653 CLG_ctx_output_set(ctx, stdout);
654
655 return ctx;
656}
657
658static void CLG_ctx_free(CLogContext *ctx)
659{
660#if defined(WIN32)
661 SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), clg_previous_console_mode);
662#endif
663 while (ctx->types != NULL) {
664 CLG_LogType *item = ctx->types;
665 ctx->types = item->next;
666 MEM_freeN(item);
667 }
668
669 while (ctx->refs != NULL) {
670 CLG_LogRef *item = ctx->refs;
671 ctx->refs = item->next;
672 item->type = NULL;
673 }
674
675 for (uint i = 0; i < 2; i++) {
676 while (ctx->filters[i] != NULL) {
677 CLG_IDFilter *item = ctx->filters[i];
678 ctx->filters[i] = item->next;
679 MEM_freeN(item);
680 }
681 }
682#ifdef WITH_CLOG_PTHREADS
683 pthread_mutex_destroy(&ctx->types_lock);
684#endif
685 MEM_freeN(ctx);
686}
687
690/* -------------------------------------------------------------------- */
696/* We could support multiple at once, for now this seems not needed. */
697static struct CLogContext *g_ctx = NULL;
698
699void CLG_init(void)
700{
702
704}
705
706void CLG_exit(void)
707{
709}
710
711void CLG_output_set(void *file_handle)
712{
713 CLG_ctx_output_set(g_ctx, file_handle);
714}
715
720
725
726void CLG_error_fn_set(void (*error_fn)(void *file_handle))
727{
729}
730
731void CLG_fatal_fn_set(void (*fatal_fn)(void *file_handle))
732{
734}
735
736void CLG_backtrace_fn_set(void (*fatal_fn)(void *file_handle))
737{
739}
740
741void CLG_type_filter_exclude(const char *type_match, int type_match_len)
742{
743 CLG_ctx_type_filter_exclude(g_ctx, type_match, type_match_len);
744}
745
746void CLG_type_filter_include(const char *type_match, int type_match_len)
747{
748 CLG_ctx_type_filter_include(g_ctx, type_match, type_match_len);
749}
750
751void CLG_level_set(int level)
752{
753 CLG_ctx_level_set(g_ctx, level);
754}
755
758/* -------------------------------------------------------------------- */
765{
766#ifdef WITH_CLOG_PTHREADS
767 /* Only runs once when initializing a static type in most cases. */
768 pthread_mutex_lock(&g_ctx->types_lock);
769#endif
770 if (clg_ref->type == NULL) {
771 /* Add to the refs list so we can NULL the pointers to 'type' when CLG_exit() is called. */
772 clg_ref->next = g_ctx->refs;
773 g_ctx->refs = clg_ref;
774
776 if (clg_ty == NULL) {
777 clg_ty = clg_ctx_type_register(g_ctx, clg_ref->identifier);
778 }
779#ifdef WITH_CLOG_PTHREADS
780 atomic_cas_ptr((void **)&clg_ref->type, clg_ref->type, clg_ty);
781#else
782 clg_ref->type = clg_ty;
783#endif
784 }
785#ifdef WITH_CLOG_PTHREADS
786 pthread_mutex_unlock(&g_ctx->types_lock);
787#endif
788}
789
791{
792 if (clg_ref->type == NULL) {
793 CLG_logref_init(clg_ref);
794 }
795 return clg_ref->type->ctx->use_color;
796}
797
#define ATTR_PRINTF_FORMAT(format_param, dots_param)
unsigned int uint
CLG_Severity
Definition CLG_log.h:87
@ CLG_SEVERITY_INFO
Definition CLG_log.h:88
@ CLG_SEVERITY_WARN
Definition CLG_log.h:89
@ CLG_SEVERITY_FATAL
Definition CLG_log.h:91
@ CLG_SEVERITY_ERROR
Definition CLG_log.h:90
@ CLG_FLAG_USE
Definition CLG_log.h:84
#define CLG_SEVERITY_LEN
Definition CLG_log.h:93
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE void * atomic_cas_ptr(void **v, void *old, void *_new)
static void CLG_ctx_output_set(CLogContext *ctx, void *file_handle)
Definition clog.c:554
static void write_type(CLogStringBuf *cstr, const CLG_LogType *lg)
Definition clog.c:432
void CLG_logf(const CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn, const char *format,...)
Definition clog.c:501
void CLG_type_filter_exclude(const char *type_match, int type_match_len)
Definition clog.c:741
static void clg_str_vappendf(CLogStringBuf *cstr, const char *format, va_list args)
Definition clog.c:174
static void clg_ctx_fatal_action(CLogContext *ctx)
Definition clog.c:369
void CLG_output_set(void *file_handle)
Definition clog.c:711
static void CLG_ctx_free(CLogContext *ctx)
Definition clog.c:658
void CLG_output_use_basename_set(int value)
Definition clog.c:716
void CLG_exit(void)
Definition clog.c:706
void CLG_log_str(const CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn, const char *message)
Definition clog.c:463
void CLG_error_fn_set(void(*error_fn)(void *file_handle))
Definition clog.c:726
struct CLG_IDFilter CLG_IDFilter
static void clg_ctx_error_action(CLogContext *ctx)
Definition clog.c:362
static CLG_LogType * clg_ctx_type_find_by_name(CLogContext *ctx, const char *identifier)
Definition clog.c:336
void CLG_backtrace_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.c:736
static void CLG_ctx_output_use_timestamp_set(CLogContext *ctx, int value)
Definition clog.c:585
static uint64_t clg_timestamp_ticks_get(void)
Definition clog.c:387
static void clg_str_append_with_len(CLogStringBuf *cstr, const char *str, const uint len)
Definition clog.c:156
struct CLogContext CLogContext
static void write_timestamp(CLogStringBuf *cstr, const uint64_t timestamp_tick_start)
Definition clog.c:406
#define CLOG_BUF_LEN_INIT
Definition clog.c:111
#define STREQLEN(a, b, n)
Definition clog.c:51
void CLG_fatal_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.c:731
static void clg_str_append(CLogStringBuf *cstr, const char *str)
Definition clog.c:168
static const char * clg_color_table[COLOR_LEN]
Definition clog.c:226
static void CLG_ctx_fatal_fn_set(CLogContext *ctx, void(*fatal_fn)(void *file_handle))
Definition clog.c:600
void CLG_type_filter_include(const char *type_match, int type_match_len)
Definition clog.c:746
void CLG_logref_init(CLG_LogRef *clg_ref)
Definition clog.c:764
static void clg_ctx_type_filter_append(CLG_IDFilter **flt_list, const char *type_match, int type_match_len)
Definition clog.c:610
void CLG_level_set(int level)
Definition clog.c:751
static struct CLogContext * g_ctx
Definition clog.c:697
static CLogContext * CLG_ctx_init(void)
Definition clog.c:646
struct CLogStringBuf CLogStringBuf
static void clg_str_free(CLogStringBuf *cstr)
Definition clog.c:128
void CLG_output_use_timestamp_set(int value)
Definition clog.c:721
static void CLG_ctx_output_use_basename_set(CLogContext *ctx, int value)
Definition clog.c:580
static CLG_LogType * clg_ctx_type_register(CLogContext *ctx, const char *identifier)
Definition clog.c:346
void CLG_init(void)
Definition clog.c:699
static void clg_str_init(CLogStringBuf *cstr, char *buf_stack, uint buf_stack_len)
Definition clog.c:120
static void clg_ctx_backtrace(CLogContext *ctx)
Definition clog.c:378
static void CLG_ctx_backtrace_fn_set(CLogContext *ctx, void(*backtrace_fn)(void *file_handle))
Definition clog.c:605
#define PATHSEP_CHAR
Definition clog.c:56
#define COLOR_LEN
Definition clog.c:224
static const char * clg_severity_str[CLG_SEVERITY_LEN]
Definition clog.c:245
static void clg_str_reserve(CLogStringBuf *cstr, const uint len)
Definition clog.c:135
static void CLG_ctx_type_filter_exclude(CLogContext *ctx, const char *type_match, int type_match_len)
Definition clog.c:624
static const char * clg_severity_as_text(enum CLG_Severity severity)
Definition clog.c:252
eCLogColor
Definition clog.c:216
@ COLOR_DEFAULT
Definition clog.c:217
@ COLOR_RED
Definition clog.c:218
@ COLOR_YELLOW
Definition clog.c:220
@ COLOR_GREEN
Definition clog.c:219
@ COLOR_RESET
Definition clog.c:222
static void clg_color_table_init(bool use_color)
Definition clog.c:231
static void CLG_ctx_level_set(CLogContext *ctx, int level)
Definition clog.c:638
int CLG_color_support_get(CLG_LogRef *clg_ref)
Definition clog.c:790
static bool clg_ctx_filter_check(CLogContext *ctx, const char *identifier)
Definition clog.c:300
#define STREQ(a, b)
Definition clog.c:50
static void CLG_ctx_type_filter_include(CLogContext *ctx, const char *type_match, int type_match_len)
Definition clog.c:631
static enum eCLogColor clg_severity_to_color(enum CLG_Severity severity)
Definition clog.c:264
static void write_severity(CLogStringBuf *cstr, enum CLG_Severity severity, bool use_color)
Definition clog.c:418
static void CLT_ctx_error_fn_set(CLogContext *ctx, void(*error_fn)(void *file_handle))
Definition clog.c:594
static void write_file_line_fn(CLogStringBuf *cstr, const char *file_line, const char *fn, const bool use_basename)
Definition clog.c:439
#define NULL
int len
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define str(s)
#define PRIu64
Definition inttypes.h:132
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
unsigned __int64 uint64_t
Definition stdint.h:90
char match[0]
Definition clog.c:66
struct CLG_IDFilter * next
Definition clog.c:64
const char * identifier
Definition CLG_log.h:107
struct CLG_LogRef * next
Definition CLG_log.h:109
CLG_LogType * type
Definition CLG_log.h:108
char identifier[64]
Definition CLG_log.h:98
struct CLG_LogType * next
Definition CLG_log.h:97
enum CLG_LogFlag flag
Definition CLG_log.h:103
struct CLogContext * ctx
Definition CLG_log.h:100
bool use_basename
Definition clog.c:81
void(* fatal_fn)(void *file_handle)
Definition clog.c:98
void(* error_fn)(void *file_handle)
Definition clog.c:97
CLG_LogRef * refs
Definition clog.c:73
bool use_timestamp
Definition clog.c:82
uint64_t timestamp_tick_start
Definition clog.c:89
FILE * output_file
Definition clog.c:86
struct CLogContext::@1410 callbacks
int level
Definition clog.c:93
int output
Definition clog.c:85
void(* backtrace_fn)(void *file_handle)
Definition clog.c:99
bool use_color
Definition clog.c:80
struct CLogContext::@1409 default_type
CLG_IDFilter * filters[2]
Definition clog.c:79
CLG_LogType * types
Definition clog.c:71
bool is_alloc
Definition clog.c:117
char * data
Definition clog.c:114
uint len_alloc
Definition clog.c:116
uint len
Definition clog.c:115
uint len_alloc