# debug.cpp

Go to the documentation of this file.

    00001 /* $Id: debug.cpp 16273 2009-05-10 21:33:55Z rubidium $ */
    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, const char *format, ...)
    00096 {
    00097   char buf[1024];
    00098
    00099   va_list va;
    00100   va_start(va, format);
    00101   vsnprintf(buf, lengthof(buf), format, va);
    00102   va_end(va);
    00103
    00104   debug_print(dbg, buf);
    00105 }
    00106 #endif /* NO_DEBUG_MESSAGES */
    00107
    00108 void SetDebugString(const char *s)
    00109 {
    00110   int v;
    00111   char *end;
    00112   const char *t;
    00113
    00114   /* global debugging level? */
    00115   if (*s >= '0' && *s <= '9') {
    00116     const DebugLevel *i;
    00117
    00118     v = strtoul(s, &end, 0);
    00119     s = end;
    00120
    00121     for (i = debug_level; i != endof(debug_level); ++i) *i->level = v;
    00122   }
    00123
    00124   /* individual levels */
    00125   for (;;) {
    00126     const DebugLevel *i;
    00127     int *p;
    00128
    00129     /* skip delimiters */
    00130     while (*s == ' ' || *s == ',' || *s == '\t') s++;
    00131     if (*s == '\0') break;
    00132
    00133     t = s;
    00134     while (*s >= 'a' && *s <= 'z') s++;
    00135
    00136     /* check debugging levels */
    00137     p = NULL;
    00138     for (i = debug_level; i != endof(debug_level); ++i)
    00139       if (s == t + strlen(i->name) && strncmp(t, i->name, s - t) == 0) {
    00140         p = i->level;
    00141         break;
    00142       }
    00143
    00144     if (*s == '=') s++;
    00145     v = strtoul(s, &end, 0);
    00146     s = end;
    00147     if (p != NULL) {
    00148       *p = v;
    00149     } else {
    00150       ShowInfoF("Unknown debug level '%.*s'", (int)(s - t), t);
    00151       return;
    00152     }
    00153   }
    00154 }
    00155
    00160 const char *GetDebugString()
    00161 {
    00162   const DebugLevel *i;
    00163   static char dbgstr[150];
    00164   char dbgval[20];
    00165
    00166   memset(dbgstr, 0, sizeof(dbgstr));
    00167   i = debug_level;
    00168   snprintf(dbgstr, sizeof(dbgstr), "%s=%d", i->name, *i->level);
    00169
    00170   for (i++; i != endof(debug_level); i++) {
    00171     snprintf(dbgval, sizeof(dbgval), ", %s=%d", i->name, *i->level);
    00172     strecat(dbgstr, dbgval, lastof(dbgstr));
    00173   }
    00174
    00175   return dbgstr;
    00176 }