1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://sam.zoy.org/wtfpl/COPYING for more details.
21 # include <sys/types.h>
32 static char *dbgLogFileName
= NULL
;
33 static int dlogFNTouched
= -1;
34 static int dbgLogWriteToScreen
= -1; /* default: no; not touched */
35 static FILE *dlogFile
= NULL
;
37 static int initialized
= 0;
38 static char modulePath
[4096];
47 static void dlogfInit (void) {
50 DWORD len
= GetModuleFileName(NULL
, modulePath
, sizeof(modulePath
)/sizeof(char)-1);
51 for (p
= modulePath
; *p
; p
++) if (*p
== '\\') *p
== '/';
53 if (!len
) { strcpy(modulePath
, "./"); break; }
55 if (modulePath
[len
] == '/') {
57 modulePath
[len
] = '\0';
61 mypid
= GetCurrentProcessId();
63 if (getcwd(modulePath
, sizeof(modulePath
)/sizeof(char)-1)) {
64 if (!modulePath
[0]) strcpy(modulePath
, "/tmp/");
66 if (modulePath
[strlen(modulePath
)-1] != '/') strcat(modulePath
, "/");
68 } else strcpy(modulePath
, "/tmp/");
71 if (dlogFNTouched
< 0) dlogfSetFile("debug.log");
72 if (dbgLogWriteToScreen
< 0) dlogfSetStdErr(0);
77 void dlogfDeinit (void) {
78 if (dlogFile
) fclose(dlogFile
);
83 void dlogfSetStdErr (int doIt
) {
86 SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE
), ENABLE_PROCESSED_INPUT
);
87 SetConsoleMode(GetStdHandle(STD_ERROR_HANDLE
), ENABLE_PROCESSED_OUTPUT
| ENABLE_WRAP_AT_EOL_OUTPUT
);
90 dbgLogWriteToScreen
= doIt
? 1 : 0;
94 void dlogfSetFile (const char *fname
) {
96 if (dbgLogFileName
) free(dbgLogFileName
);
97 dbgLogFileName
= NULL
;
98 if (!fname
|| !fname
[0]) return;
102 if (fname
[0] != '/' && fname
[0] != '\\' && (strlen(fname
) < 3 || fname
[1] != ':')) strcpy(buf
, modulePath
);
104 if (fname
[0] != '/') strcpy(buf
, modulePath
);
107 dbgLogFileName
= malloc((strlen(buf
)+1)*sizeof(char));
108 if (dbgLogFileName
) strcpy(dbgLogFileName
, buf
);
112 #define DBG_TMP_BUF_SIZE 65536
113 static char *fmtBuf (const char *sbuf
, const char *pfx
) {
114 static char buf
[DBG_TMP_BUF_SIZE
*4+1024];
115 const char *p
= sbuf
;
117 size_t left
= sizeof(buf
)-4;
118 int lastWasN
= 0, plen
= strlen(pfx
);
119 strcpy(d
, pfx
); left
-= plen
; d
+= plen
;
120 while (left
> 0 && *p
) {
121 while (*p
== '\r') p
++;
124 *d
++ = '\r'; *d
++ = '\n'; left
-= 2;
128 if (left
< strlen(pfx
)) break; // no room
129 strcpy(d
, pfx
); left
-= plen
; d
+= plen
;
140 if (d
== buf
|| d
[-1] != '\n') strcpy(d
, "\r\n"); else *d
= '\0';
142 if (d
== buf
|| d
[-1] != '\n') strcpy(d
, "\n"); else *d
= '\0';
148 void dlogfVA (const char *fmt
, va_list inap
) {
150 static char buf
[DBG_TMP_BUF_SIZE
+1024];
151 const char *xbuf
= NULL
;
162 if (!initialized
) dlogfInit();
164 memset(buf
, 0, DBG_TMP_BUF_SIZE
);
166 vsnprintf(buf
, DBG_TMP_BUF_SIZE
, fmt
, ap2
);
168 buf
[DBG_TMP_BUF_SIZE
] = '\0';
172 sprintf(timebuf
, "[%05i] %04i/%02i/%02i %02i:%02i:%02i: ",
174 t
.wYear
, t
.wMonth
, t
.wDay
,
175 t
.wHour
, t
.wMinute
, t
.wSecond
179 localtime_r(&t
, &bt
);
180 sprintf(timebuf
, "[%05i] %04i/%02i/%02i %02i:%02i:%02i: ",
182 bt
.tm_year
+1900, bt
.tm_mon
, bt
.tm_mday
,
183 bt
.tm_hour
, bt
.tm_min
, bt
.tm_sec
187 xbuf
= fmtBuf(buf
, timebuf
);
189 if (dbgLogFileName
) {
190 if (!dlogFile
) dlogFile
= fopen(dbgLogFileName
, "ab");
192 fputs(xbuf
, dlogFile
);
197 if (dbgLogWriteToScreen
) {
199 HANDLE oh
= GetStdHandle(STD_ERROR_HANDLE
);
200 if (oh
!= INVALID_HANDLE_VALUE
) WriteConsole(oh
, xbuf
, strlen(xbuf
), &wr
, NULL
);
209 void __attribute__((format(printf
, 1, 2))) dlogf (const char *fmt
, ...) {
217 #endif /* NO_DEBUG_LOG */