# debug.cpp

Go to the documentation of this file.

    00001 /* $Id: debug.cpp 15299 2009-01-31 20:16:06Z smatz $ */
    00002
    00005 #include "stdafx.h"
    00006 #include <stdio.h>
    00007 #include <stdarg.h>
    00008 #include "console_func.h"
    00009 #include "debug.h"
    00010 #include "string_func.h"
    00011 #include "network/core/core.h"
    00012 #include "fileio_func.h"
    00013
    00014 #if defined(ENABLE_NETWORK)
    00015 SOCKET _debug_socket = INVALID_SOCKET;
    00016 #endif /* ENABLE_NETWORK */
    00017
    00018 int _debug_ai_level;
    00019 int _debug_driver_level;
    00020 int _debug_grf_level;
    00021 int _debug_map_level;
    00022 int _debug_misc_level;
    00023 int _debug_ms_level;
    00024 int _debug_net_level;
    00025 int _debug_sprite_level;
    00026 int _debug_oldloader_level;
    00027 int _debug_ntp_level;
    00028 int _debug_npf_level;
    00029 int _debug_yapf_level;
    00030 int _debug_freetype_level;
    00031 int _debug_sl_level;
    00032 int _debug_station_level;
    00033 int _debug_gamelog_level;
    00034 int _debug_desync_level;
    00035
    00036
    00037 struct DebugLevel {
    00038   const char *name;
    00039   int *level;
    00040 };
    00041
    00042 #define DEBUG_LEVEL(x) { #x, &_debug_##x##_level }
    00043   static const DebugLevel debug_level[] = {
    00044   DEBUG_LEVEL(ai),
    00045   DEBUG_LEVEL(driver),
    00046   DEBUG_LEVEL(grf),
    00047   DEBUG_LEVEL(map),
    00048   DEBUG_LEVEL(misc),
    00049   DEBUG_LEVEL(ms),
    00050   DEBUG_LEVEL(net),
    00051   DEBUG_LEVEL(sprite),
    00052   DEBUG_LEVEL(oldloader),
    00053   DEBUG_LEVEL(ntp),
    00054   DEBUG_LEVEL(npf),
    00055   DEBUG_LEVEL(yapf),
    00056   DEBUG_LEVEL(freetype),
    00057   DEBUG_LEVEL(sl),
    00058   DEBUG_LEVEL(station),
    00059   DEBUG_LEVEL(gamelog),
    00060   DEBUG_LEVEL(desync),
    00061   };
    00062 #undef DEBUG_LEVEL
    00063
    00064 #if !defined(NO_DEBUG_MESSAGES)
    00065
    00066 static void debug_print(const char *dbg, const char *buf)
    00067 {
    00068 #if defined(ENABLE_NETWORK)
    00069   if (_debug_socket != INVALID_SOCKET) {
    00070     char buf2[1024 + 32];
    00071
    00072     snprintf(buf2, lengthof(buf2), "dbg: [%s] %s\n", dbg, buf);
    00073     send(_debug_socket, buf2, (int)strlen(buf2), 0);
    00074   } else
    00075 #endif /* ENABLE_NETWORK */
    00076   if (strcmp(dbg, "desync") != 0) {
    00077 #if defined(WINCE)
    00078     /* We need to do OTTD2FS twice, but as it uses a static buffer, we need to store one temporary */
    00079     TCHAR tbuf[512];
    00080     _sntprintf(tbuf, sizeof(tbuf), _T("%s"), OTTD2FS(dbg));
    00081     NKDbgPrintfW(_T("dbg: [%s] %s\n"), tbuf, OTTD2FS(buf));
    00082 #else
    00083     fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
    00084 #endif
    00085     IConsoleDebug(dbg, buf);
    00086   } else {
    00087     static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
    00088     if (f == NULL) return;
    00089
    00090     fprintf(f, "%s", buf);
    00091     fflush(f);
    00092   }
    00093 }
    00094
    00095 void CDECL debug(const char *dbg, ...)
    00096 {
    00097   va_list va;
    00098   va_start(va, dbg);
    00099   const char *s;
    00100   char buf[1024];
    00101
    00102   s = va_arg(va, const char*);
    00103   vsnprintf(buf, lengthof(buf), s, va);
    00104   va_end(va);
    00105
    00106   debug_print(dbg, buf);
    00107 }
    00108 #endif /* NO_DEBUG_MESSAGES */
    00109
    00110 void SetDebugString(const char *s)
    00111 {
    00112   int v;
    00113   char *end;
    00114   const char *t;
    00115
    00116   /* global debugging level? */
    00117   if (*s >= '0' && *s <= '9') {
    00118     const DebugLevel *i;
    00119
    00120     v = strtoul(s, &end, 0);
    00121     s = end;
    00122
    00123     for (i = debug_level; i != endof(debug_level); ++i) *i->level = v;
    00124   }
    00125
    00126   /* individual levels */
    00127   for (;;) {
    00128     const DebugLevel *i;
    00129     int *p;
    00130
    00131     /* skip delimiters */
    00132     while (*s == ' ' || *s == ',' || *s == '\t') s++;
    00133     if (*s == '\0') break;
    00134
    00135     t = s;
    00136     while (*s >= 'a' && *s <= 'z') s++;
    00137
    00138     /* check debugging levels */
    00139     p = NULL;
    00140     for (i = debug_level; i != endof(debug_level); ++i)
    00141       if (s == t + strlen(i->name) && strncmp(t, i->name, s - t) == 0) {
    00142         p = i->level;
    00143         break;
    00144       }
    00145
    00146     if (*s == '=') s++;
    00147     v = strtoul(s, &end, 0);
    00148     s = end;
    00149     if (p != NULL) {
    00150       *p = v;
    00151     } else {
    00152       ShowInfoF("Unknown debug level '%.*s'", s - t, t);
    00153       return;
    00154     }
    00155   }
    00156 }
    00157
    00162 const char *GetDebugString()
    00163 {
    00164   const DebugLevel *i;
    00165   static char dbgstr[150];
    00166   char dbgval[20];
    00167
    00168   memset(dbgstr, 0, sizeof(dbgstr));
    00169   i = debug_level;
    00170   snprintf(dbgstr, sizeof(dbgstr), "%s=%d", i->name, *i->level);
    00171
    00172   for (i++; i != endof(debug_level); i++) {
    00173     snprintf(dbgval, sizeof(dbgval), ", %s=%d", i->name, *i->level);
    00174     strecat(dbgstr, dbgval, lastof(dbgstr));
    00175   }
    00176
    00177   return dbgstr;
    00178 }