102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
log.c
Go to the documentation of this file.
1#include <dttr_log.h>
2
3#include <stdarg.h>
4#include <stdio.h>
5#include <time.h>
6
7#define MAX_CALLBACKS 32
8
9typedef struct {
10 log_LogFn fn;
11 void *udata;
12 int level;
14
15static int current_log_level = LOG_TRACE;
17static int callback_count;
18
19static const char *level_to_string(int level) {
20 switch (level) {
21 case LOG_TRACE:
22 return "TRACE";
23 case LOG_DEBUG:
24 return "DEBUG";
25 case LOG_INFO:
26 return "INFO";
27 case LOG_WARN:
28 return "WARN";
29 case LOG_ERROR:
30 return "ERROR";
31 case LOG_FATAL:
32 return "FATAL";
33 default:
34 return "UNKNOWN";
35 }
36}
37
38static void init_event(log_Event *ev, void *udata) {
39 if (!ev->time) {
40 time_t t = time(NULL);
41 ev->time = localtime(&t);
42 }
43
44 ev->udata = udata;
45}
46
47static void stderr_callback(log_Event *ev) {
48 char buf[16];
49 buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
50 fprintf(
51 ev->udata,
52 "%s %-5s %s:%d: ",
53 buf,
54 level_to_string(ev->level),
55 ev->file,
56 ev->line
57 );
58 vfprintf(ev->udata, ev->fmt, ev->ap);
59 fprintf(ev->udata, "\n");
60 fflush(ev->udata);
61}
62
63static void file_callback(log_Event *ev) {
64 char buf[64];
65 buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
66 fprintf(
67 ev->udata,
68 "%s %-5s %s:%d: ",
69 buf,
70 level_to_string(ev->level),
71 ev->file,
72 ev->line
73 );
74 vfprintf(ev->udata, ev->fmt, ev->ap);
75 fprintf(ev->udata, "\n");
76 fflush(ev->udata);
77}
78
79bool DTTR_Log_IsEnabled(int log_level) {
80 if (log_level >= current_log_level) {
81 return true;
82 }
83
84 for (int i = 0; i < callback_count; i++) {
85 if (log_level >= callbacks[i].level) {
86 return true;
87 }
88 }
89
90 return false;
91}
92
94 int log_level,
95 const char *file,
96 int line,
97 const char *fmt,
98 va_list args
99) {
100 log_Event ev = {
101 .fmt = fmt,
102 .file = file,
103 .line = line,
104 .level = log_level,
105 };
106
107 if (log_level >= current_log_level) {
108 init_event(&ev, stderr);
109 va_copy(ev.ap, args);
110 stderr_callback(&ev);
111 va_end(ev.ap);
112 }
113
114 for (int i = 0; i < callback_count; i++) {
116 if (log_level >= cb->level) {
117 init_event(&ev, cb->udata);
118 va_copy(ev.ap, args);
119 cb->fn(&ev);
120 va_end(ev.ap);
121 }
122 }
123}
124
125void DTTR_Log(int level, const char *file, int line, const char *fmt, ...) {
126 if (!DTTR_Log_IsEnabled(level)) {
127 return;
128 }
129
130 va_list args;
131 va_start(args, fmt);
132 dttr_vlog_unchecked(level, file, line, fmt, args);
133 va_end(args);
134}
135
136void DTTR_Log_Unchecked(int level, const char *file, int line, const char *fmt, ...) {
137 va_list args;
138 va_start(args, fmt);
139 dttr_vlog_unchecked(level, file, line, fmt, args);
140 va_end(args);
141}
142
143void DTTR_Log_SetLevel(int log_level) {
144 current_log_level = log_level;
145}
146
147static int add_log_callback(log_LogFn fn, void *udata, int level) {
148 if (!fn || callback_count >= MAX_CALLBACKS) {
149 return -1;
150 }
151
153 .fn = fn,
154 .udata = udata,
155 .level = level,
156 };
157
158 return 0;
159}
160
161int DTTR_Log_AddFP(FILE *fp, int level) {
162 return add_log_callback(file_callback, fp, level);
163}
void * cb
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
static int add_log_callback(log_LogFn fn, void *udata, int level)
Definition log.c:147
void DTTR_Log(int level, const char *file, int line, const char *fmt,...)
Definition log.c:125
static int current_log_level
Definition log.c:15
static void init_event(log_Event *ev, void *udata)
Definition log.c:38
bool DTTR_Log_IsEnabled(int log_level)
Definition log.c:79
static void file_callback(log_Event *ev)
Definition log.c:63
static const char * level_to_string(int level)
Definition log.c:19
void DTTR_Log_Unchecked(int level, const char *file, int line, const char *fmt,...)
Definition log.c:136
static void stderr_callback(log_Event *ev)
Definition log.c:47
static int callback_count
Definition log.c:17
static log_callback callbacks[MAX_CALLBACKS]
Definition log.c:16
static void dttr_vlog_unchecked(int log_level, const char *file, int line, const char *fmt, va_list args)
Definition log.c:93
void DTTR_Log_SetLevel(int log_level)
Definition log.c:143
int DTTR_Log_AddFP(FILE *fp, int level)
Definition log.c:161
#define MAX_CALLBACKS
Definition log.c:7
int level
Definition log.c:12
void * udata
Definition log.c:11
log_LogFn fn
Definition log.c:10