slouken@5221
|
1 |
/*
|
slouken@5221
|
2 |
SDL - Simple DirectMedia Layer
|
slouken@5262
|
3 |
Copyright (C) 1997-2011 Sam Lantinga
|
slouken@5221
|
4 |
|
slouken@5221
|
5 |
This library is free software; you can redistribute it and/or
|
slouken@5221
|
6 |
modify it under the terms of the GNU Lesser General Public
|
slouken@5221
|
7 |
License as published by the Free Software Foundation; either
|
slouken@5221
|
8 |
version 2.1 of the License, or (at your option) any later version.
|
slouken@5221
|
9 |
|
slouken@5221
|
10 |
This library is distributed in the hope that it will be useful,
|
slouken@5221
|
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
slouken@5221
|
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
slouken@5221
|
13 |
Lesser General Public License for more details.
|
slouken@5221
|
14 |
|
slouken@5221
|
15 |
You should have received a copy of the GNU Lesser General Public
|
slouken@5221
|
16 |
License along with this library; if not, write to the Free Software
|
slouken@5221
|
17 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
slouken@5221
|
18 |
|
slouken@5221
|
19 |
Sam Lantinga
|
slouken@5221
|
20 |
slouken@libsdl.org
|
slouken@5221
|
21 |
*/
|
slouken@5221
|
22 |
#include "SDL_config.h"
|
slouken@5221
|
23 |
|
slouken@5221
|
24 |
/* Simple log messages in SDL */
|
slouken@5221
|
25 |
|
slouken@5221
|
26 |
#include "SDL_log.h"
|
slouken@5221
|
27 |
|
slouken@5221
|
28 |
#if HAVE_STDIO_H
|
slouken@5221
|
29 |
#include <stdio.h>
|
slouken@5221
|
30 |
#endif
|
slouken@5221
|
31 |
|
slouken@5221
|
32 |
#if defined(__WIN32__)
|
slouken@5221
|
33 |
#include "core/windows/SDL_windows.h"
|
slouken@5221
|
34 |
#elif defined(__ANDROID__)
|
slouken@5221
|
35 |
#include <android/log.h>
|
slouken@5221
|
36 |
#endif
|
slouken@5221
|
37 |
|
slouken@5221
|
38 |
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
|
slouken@5221
|
39 |
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
|
slouken@5221
|
40 |
|
slouken@5221
|
41 |
typedef struct SDL_LogLevel
|
slouken@5221
|
42 |
{
|
slouken@5221
|
43 |
int category;
|
slouken@5221
|
44 |
SDL_LogPriority priority;
|
slouken@5221
|
45 |
struct SDL_LogLevel *next;
|
slouken@5221
|
46 |
} SDL_LogLevel;
|
slouken@5221
|
47 |
|
slouken@5235
|
48 |
/* The default log output function */
|
slouken@5235
|
49 |
static void SDL_LogOutput(void *userdata,
|
slouken@5235
|
50 |
int category, SDL_LogPriority priority,
|
slouken@5235
|
51 |
const char *message);
|
slouken@5235
|
52 |
|
slouken@5221
|
53 |
static SDL_LogLevel *SDL_loglevels;
|
slouken@5221
|
54 |
static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
slouken@5221
|
55 |
static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
|
slouken@5235
|
56 |
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
|
slouken@5235
|
57 |
static void *SDL_log_userdata = NULL;
|
slouken@5221
|
58 |
|
slouken@5221
|
59 |
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
|
slouken@5235
|
60 |
NULL,
|
slouken@5221
|
61 |
"VERBOSE",
|
slouken@5221
|
62 |
"DEBUG",
|
slouken@5221
|
63 |
"INFO",
|
slouken@5221
|
64 |
"WARN",
|
slouken@5221
|
65 |
"ERROR",
|
slouken@5221
|
66 |
"CRITICAL"
|
slouken@5221
|
67 |
};
|
slouken@5221
|
68 |
|
slouken@5221
|
69 |
#ifdef __ANDROID__
|
slouken@5221
|
70 |
static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = {
|
slouken@5221
|
71 |
"APP",
|
slouken@5221
|
72 |
"ERROR",
|
slouken@5221
|
73 |
"SYSTEM",
|
slouken@5221
|
74 |
"AUDIO",
|
slouken@5221
|
75 |
"VIDEO",
|
slouken@5221
|
76 |
"RENDER",
|
slouken@5221
|
77 |
"INPUT"
|
slouken@5221
|
78 |
};
|
slouken@5221
|
79 |
|
slouken@5221
|
80 |
static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
|
slouken@5221
|
81 |
ANDROID_LOG_VERBOSE,
|
slouken@5221
|
82 |
ANDROID_LOG_DEBUG,
|
slouken@5221
|
83 |
ANDROID_LOG_INFO,
|
slouken@5221
|
84 |
ANDROID_LOG_WARN,
|
slouken@5221
|
85 |
ANDROID_LOG_ERROR,
|
slouken@5221
|
86 |
ANDROID_LOG_FATAL
|
slouken@5221
|
87 |
};
|
slouken@5221
|
88 |
#endif /* __ANDROID__ */
|
slouken@5221
|
89 |
|
slouken@5221
|
90 |
|
slouken@5221
|
91 |
void
|
slouken@5221
|
92 |
SDL_LogSetAllPriority(SDL_LogPriority priority)
|
slouken@5221
|
93 |
{
|
slouken@5221
|
94 |
SDL_LogLevel *entry;
|
slouken@5221
|
95 |
|
slouken@5221
|
96 |
for (entry = SDL_loglevels; entry; entry = entry->next) {
|
slouken@5221
|
97 |
entry->priority = priority;
|
slouken@5221
|
98 |
}
|
slouken@5221
|
99 |
SDL_application_priority = SDL_default_priority = priority;
|
slouken@5221
|
100 |
}
|
slouken@5221
|
101 |
|
slouken@5221
|
102 |
void
|
slouken@5221
|
103 |
SDL_LogSetPriority(int category, SDL_LogPriority priority)
|
slouken@5221
|
104 |
{
|
slouken@5221
|
105 |
SDL_LogLevel *entry;
|
slouken@5221
|
106 |
|
slouken@5221
|
107 |
for (entry = SDL_loglevels; entry; entry = entry->next) {
|
slouken@5221
|
108 |
if (entry->category == category) {
|
slouken@5221
|
109 |
entry->priority = priority;
|
slouken@5221
|
110 |
return;
|
slouken@5221
|
111 |
}
|
slouken@5221
|
112 |
}
|
slouken@5221
|
113 |
|
slouken@5221
|
114 |
/* Create a new entry */
|
slouken@5221
|
115 |
entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry));
|
slouken@5221
|
116 |
if (entry) {
|
slouken@5221
|
117 |
entry->category = category;
|
slouken@5221
|
118 |
entry->priority = priority;
|
slouken@5221
|
119 |
entry->next = SDL_loglevels;
|
slouken@5221
|
120 |
SDL_loglevels = entry;
|
slouken@5221
|
121 |
}
|
slouken@5221
|
122 |
}
|
slouken@5221
|
123 |
|
slouken@5221
|
124 |
SDL_LogPriority
|
slouken@5221
|
125 |
SDL_LogGetPriority(int category)
|
slouken@5221
|
126 |
{
|
slouken@5221
|
127 |
SDL_LogLevel *entry;
|
slouken@5221
|
128 |
|
slouken@5221
|
129 |
for (entry = SDL_loglevels; entry; entry = entry->next) {
|
slouken@5221
|
130 |
if (entry->category == category) {
|
slouken@5221
|
131 |
return entry->priority;
|
slouken@5221
|
132 |
}
|
slouken@5221
|
133 |
}
|
slouken@5221
|
134 |
|
slouken@5221
|
135 |
if (category == SDL_LOG_CATEGORY_APPLICATION) {
|
slouken@5221
|
136 |
return SDL_application_priority;
|
slouken@5221
|
137 |
} else {
|
slouken@5221
|
138 |
return SDL_default_priority;
|
slouken@5221
|
139 |
}
|
slouken@5221
|
140 |
}
|
slouken@5221
|
141 |
|
slouken@5221
|
142 |
void
|
slouken@5221
|
143 |
SDL_LogResetPriorities(void)
|
slouken@5221
|
144 |
{
|
slouken@5221
|
145 |
SDL_LogLevel *entry;
|
slouken@5221
|
146 |
|
slouken@5221
|
147 |
while (SDL_loglevels) {
|
slouken@5221
|
148 |
entry = SDL_loglevels;
|
slouken@5221
|
149 |
SDL_loglevels = entry->next;
|
slouken@5221
|
150 |
SDL_free(entry);
|
slouken@5221
|
151 |
}
|
slouken@5221
|
152 |
|
slouken@5221
|
153 |
SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
slouken@5221
|
154 |
SDL_default_priority = DEFAULT_PRIORITY;
|
slouken@5221
|
155 |
}
|
slouken@5221
|
156 |
|
slouken@5221
|
157 |
void
|
slouken@5221
|
158 |
SDL_Log(const char *fmt, ...)
|
slouken@5221
|
159 |
{
|
slouken@5221
|
160 |
va_list ap;
|
slouken@5221
|
161 |
|
slouken@5221
|
162 |
va_start(ap, fmt);
|
slouken@5221
|
163 |
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap);
|
slouken@5221
|
164 |
va_end(ap);
|
slouken@5221
|
165 |
}
|
slouken@5221
|
166 |
|
slouken@5221
|
167 |
void
|
slouken@5221
|
168 |
SDL_LogVerbose(int category, const char *fmt, ...)
|
slouken@5221
|
169 |
{
|
slouken@5221
|
170 |
va_list ap;
|
slouken@5221
|
171 |
|
slouken@5221
|
172 |
va_start(ap, fmt);
|
slouken@5221
|
173 |
SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap);
|
slouken@5221
|
174 |
va_end(ap);
|
slouken@5221
|
175 |
}
|
slouken@5221
|
176 |
|
slouken@5221
|
177 |
void
|
slouken@5221
|
178 |
SDL_LogInfo(int category, const char *fmt, ...)
|
slouken@5221
|
179 |
{
|
slouken@5221
|
180 |
va_list ap;
|
slouken@5221
|
181 |
|
slouken@5221
|
182 |
va_start(ap, fmt);
|
slouken@5221
|
183 |
SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap);
|
slouken@5221
|
184 |
va_end(ap);
|
slouken@5221
|
185 |
}
|
slouken@5221
|
186 |
|
slouken@5221
|
187 |
void
|
slouken@5221
|
188 |
SDL_LogWarn(int category, const char *fmt, ...)
|
slouken@5221
|
189 |
{
|
slouken@5221
|
190 |
va_list ap;
|
slouken@5221
|
191 |
|
slouken@5221
|
192 |
va_start(ap, fmt);
|
slouken@5221
|
193 |
SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap);
|
slouken@5221
|
194 |
va_end(ap);
|
slouken@5221
|
195 |
}
|
slouken@5221
|
196 |
|
slouken@5221
|
197 |
void
|
slouken@5221
|
198 |
SDL_LogError(int category, const char *fmt, ...)
|
slouken@5221
|
199 |
{
|
slouken@5221
|
200 |
va_list ap;
|
slouken@5221
|
201 |
|
slouken@5221
|
202 |
va_start(ap, fmt);
|
slouken@5221
|
203 |
SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap);
|
slouken@5221
|
204 |
va_end(ap);
|
slouken@5221
|
205 |
}
|
slouken@5221
|
206 |
|
slouken@5221
|
207 |
void
|
slouken@5221
|
208 |
SDL_LogCritical(int category, const char *fmt, ...)
|
slouken@5221
|
209 |
{
|
slouken@5221
|
210 |
va_list ap;
|
slouken@5221
|
211 |
|
slouken@5221
|
212 |
va_start(ap, fmt);
|
slouken@5221
|
213 |
SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap);
|
slouken@5221
|
214 |
va_end(ap);
|
slouken@5221
|
215 |
}
|
slouken@5221
|
216 |
|
slouken@5221
|
217 |
void
|
slouken@5221
|
218 |
SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...)
|
slouken@5221
|
219 |
{
|
slouken@5221
|
220 |
va_list ap;
|
slouken@5221
|
221 |
|
slouken@5221
|
222 |
va_start(ap, fmt);
|
slouken@5221
|
223 |
SDL_LogMessageV(category, priority, fmt, ap);
|
slouken@5221
|
224 |
va_end(ap);
|
slouken@5221
|
225 |
}
|
slouken@5221
|
226 |
|
slouken@5221
|
227 |
#ifdef __ANDROID__
|
slouken@5221
|
228 |
static const char *
|
slouken@5221
|
229 |
GetCategoryPrefix(int category)
|
slouken@5221
|
230 |
{
|
slouken@5221
|
231 |
if (category < SDL_LOG_CATEGORY_RESERVED1) {
|
slouken@5221
|
232 |
return SDL_category_prefixes[category];
|
slouken@5221
|
233 |
}
|
slouken@5221
|
234 |
if (category < SDL_LOG_CATEGORY_CUSTOM) {
|
slouken@5221
|
235 |
return "RESERVED";
|
slouken@5221
|
236 |
}
|
slouken@5221
|
237 |
return "CUSTOM";
|
slouken@5221
|
238 |
}
|
slouken@5221
|
239 |
#endif /* __ANDROID__ */
|
slouken@5221
|
240 |
|
slouken@5221
|
241 |
void
|
slouken@5221
|
242 |
SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
|
slouken@5221
|
243 |
{
|
slouken@5223
|
244 |
char *message;
|
slouken@5221
|
245 |
|
slouken@5235
|
246 |
/* Nothing to do if we don't have an output function */
|
slouken@5235
|
247 |
if (!SDL_log_function) {
|
slouken@5235
|
248 |
return;
|
slouken@5235
|
249 |
}
|
slouken@5235
|
250 |
|
slouken@5221
|
251 |
/* Make sure we don't exceed array bounds */
|
slouken@5221
|
252 |
if (priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) {
|
slouken@5221
|
253 |
return;
|
slouken@5221
|
254 |
}
|
slouken@5221
|
255 |
|
slouken@5221
|
256 |
/* See if we want to do anything with this message */
|
slouken@5221
|
257 |
if (priority < SDL_LogGetPriority(category)) {
|
slouken@5221
|
258 |
return;
|
slouken@5221
|
259 |
}
|
slouken@5221
|
260 |
|
slouken@5223
|
261 |
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
|
slouken@5223
|
262 |
if (!message) {
|
slouken@5223
|
263 |
return;
|
slouken@5223
|
264 |
}
|
slouken@5223
|
265 |
SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
|
slouken@5235
|
266 |
SDL_log_function(SDL_log_userdata, category, priority, message);
|
slouken@5235
|
267 |
SDL_stack_free(message);
|
slouken@5235
|
268 |
}
|
slouken@5221
|
269 |
|
slouken@5235
|
270 |
static void
|
slouken@5235
|
271 |
SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
slouken@5235
|
272 |
const char *message)
|
slouken@5235
|
273 |
{
|
slouken@5221
|
274 |
#if defined(__WIN32__)
|
slouken@5223
|
275 |
/* Way too many allocations here, urgh */
|
slouken@5221
|
276 |
{
|
slouken@5223
|
277 |
char *output;
|
slouken@5223
|
278 |
size_t length;
|
slouken@5221
|
279 |
LPTSTR tstr;
|
slouken@5221
|
280 |
|
slouken@5223
|
281 |
length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1;
|
slouken@5223
|
282 |
output = SDL_stack_alloc(char, length);
|
slouken@5223
|
283 |
SDL_snprintf(output, length, "%s: %s", SDL_priority_prefixes[priority], message);
|
slouken@5221
|
284 |
tstr = WIN_UTF8ToString(output);
|
slouken@5221
|
285 |
OutputDebugString(tstr);
|
slouken@5221
|
286 |
SDL_free(tstr);
|
slouken@5223
|
287 |
SDL_stack_free(output);
|
slouken@5221
|
288 |
}
|
slouken@5221
|
289 |
#elif defined(__ANDROID__)
|
slouken@5221
|
290 |
{
|
slouken@5221
|
291 |
char tag[32];
|
slouken@5221
|
292 |
|
slouken@5221
|
293 |
SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
|
slouken@5221
|
294 |
__android_log_write(SDL_android_priority[priority], tag, message);
|
slouken@5221
|
295 |
}
|
slouken@5221
|
296 |
#endif
|
slouken@5221
|
297 |
#if HAVE_STDIO_H
|
slouken@5221
|
298 |
fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
slouken@5221
|
299 |
#endif
|
slouken@5235
|
300 |
}
|
slouken@5235
|
301 |
|
slouken@5235
|
302 |
void
|
slouken@5235
|
303 |
SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
|
slouken@5235
|
304 |
{
|
slouken@5235
|
305 |
if (callback) {
|
slouken@5235
|
306 |
*callback = SDL_log_function;
|
slouken@5235
|
307 |
}
|
slouken@5235
|
308 |
if (userdata) {
|
slouken@5235
|
309 |
*userdata = SDL_log_userdata;
|
slouken@5235
|
310 |
}
|
slouken@5235
|
311 |
}
|
slouken@5235
|
312 |
|
slouken@5235
|
313 |
void
|
slouken@5235
|
314 |
SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata)
|
slouken@5235
|
315 |
{
|
slouken@5235
|
316 |
SDL_log_function = callback;
|
slouken@5235
|
317 |
SDL_log_userdata = userdata;
|
slouken@5221
|
318 |
}
|
slouken@5221
|
319 |
|
slouken@5221
|
320 |
/* vi: set ts=4 sw=4 expandtab: */
|