4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file debug.cpp Handling of printing debug messages. */
14 #include "console_func.h"
16 #include "string_func.h"
17 #include "fileio_func.h"
18 #include "settings_type.h"
22 #if defined(ENABLE_NETWORK)
23 #include "network/network_admin.h"
24 SOCKET _debug_socket
= INVALID_SOCKET
;
25 #endif /* ENABLE_NETWORK */
28 int _debug_driver_level
;
31 int _debug_misc_level
;
33 int _debug_sprite_level
;
34 int _debug_oldloader_level
;
36 int _debug_yapf_level
;
37 int _debug_freetype_level
;
39 int _debug_gamelog_level
;
40 int _debug_desync_level
;
41 int _debug_console_level
;
43 uint32 _realtime_tick
= 0;
50 #define DEBUG_LEVEL(x) { #x, &_debug_##x##_level }
51 static const DebugLevel debug_level
[] = {
59 DEBUG_LEVEL(oldloader
),
62 DEBUG_LEVEL(freetype
),
70 #if !defined(NO_DEBUG_MESSAGES)
73 * Internal function for outputting the debug line.
74 * @param dbg Debug category.
75 * @param buf Text line to output.
77 static void debug_print(const char *dbg
, const char *buf
)
79 #if defined(ENABLE_NETWORK)
80 if (_debug_socket
!= INVALID_SOCKET
) {
83 snprintf(buf2
, lengthof(buf2
), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg
, buf
);
84 send(_debug_socket
, buf2
, (int)strlen(buf2
), 0);
87 #endif /* ENABLE_NETWORK */
88 if (strcmp(dbg
, "desync") != 0) {
90 /* We need to do OTTD2FS twice, but as it uses a static buffer, we need to store one temporary */
92 _sntprintf(tbuf
, sizeof(tbuf
), _T("%s"), OTTD2FS(dbg
));
93 NKDbgPrintfW(_T("dbg: [%s] %s\n"), tbuf
, OTTD2FS(buf
));
95 fprintf(stderr
, "%sdbg: [%s] %s\n", GetLogPrefix(), dbg
, buf
);
98 NetworkAdminConsole(dbg
, buf
);
99 #endif /* ENABLE_NETWORK */
100 IConsoleDebug(dbg
, buf
);
102 static FILE *f
= FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR
);
103 if (f
== NULL
) return;
105 fprintf(f
, "%s%s\n", GetLogPrefix(), buf
);
111 * Output a debug line.
112 * @note Do not call directly, use the #DEBUG macro instead.
113 * @param dbg Debug category.
114 * @param format Text string a la printf, with optional arguments.
116 void CDECL
debug(const char *dbg
, const char *format
, ...)
121 va_start(va
, format
);
122 vsnprintf(buf
, lengthof(buf
), format
, va
);
125 debug_print(dbg
, buf
);
127 #endif /* NO_DEBUG_MESSAGES */
130 * Set debugging levels by parsing the text in \a s.
131 * For setting individual levels a string like \c "net=3,grf=6" should be used.
132 * If the string starts with a number, the number is used as global debugging level.
133 * @param s Text describing the wanted debugging levels.
135 void SetDebugString(const char *s
)
141 /* global debugging level? */
142 if (*s
>= '0' && *s
<= '9') {
145 v
= strtoul(s
, &end
, 0);
148 for (i
= debug_level
; i
!= endof(debug_level
); ++i
) *i
->level
= v
;
151 /* individual levels */
156 /* skip delimiters */
157 while (*s
== ' ' || *s
== ',' || *s
== '\t') s
++;
158 if (*s
== '\0') break;
161 while (*s
>= 'a' && *s
<= 'z') s
++;
163 /* check debugging levels */
165 for (i
= debug_level
; i
!= endof(debug_level
); ++i
) {
166 if (s
== t
+ strlen(i
->name
) && strncmp(t
, i
->name
, s
- t
) == 0) {
173 v
= strtoul(s
, &end
, 0);
178 ShowInfoF("Unknown debug level '%.*s'", (int)(s
- t
), t
);
185 * Print out the current debug-level.
186 * Just return a string with the values of all the debug categories.
187 * @return string with debug-levels
189 const char *GetDebugString()
192 static char dbgstr
[150];
195 memset(dbgstr
, 0, sizeof(dbgstr
));
197 snprintf(dbgstr
, sizeof(dbgstr
), "%s=%d", i
->name
, *i
->level
);
199 for (i
++; i
!= endof(debug_level
); i
++) {
200 snprintf(dbgval
, sizeof(dbgval
), ", %s=%d", i
->name
, *i
->level
);
201 strecat(dbgstr
, dbgval
, lastof(dbgstr
));
208 * Get the prefix for logs; if show_date_in_logs is enabled it returns
209 * the date, otherwise it returns nothing.
210 * @return the prefix for logs (do not free), never NULL
212 const char *GetLogPrefix()
214 static char _log_prefix
[24];
215 if (_settings_client
.gui
.show_date_in_logs
) {
216 time_t cur_time
= time(NULL
);
217 strftime(_log_prefix
, sizeof(_log_prefix
), "[%Y-%m-%d %H:%M:%S] ", localtime(&cur_time
));