1 // This file is part of Visual D
2 //
3 // Visual D integrates the D programming language into Visual Studio
4 // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
8 
9 module vdc.logger;
10 
11 import std.stdio;
12 import std.datetime;
13 import std.conv;
14 import std.string;
15 import std.array;
16 
17 extern(Windows) void OutputDebugStringA(const char* lpOutputString);
18 extern(Windows) uint GetCurrentThreadId();
19 
20 import core.sys.windows.windows;
21 
22 __gshared int   gLogIndent = 0;
23 __gshared bool  gLogFirst = true;
24 __gshared const string gLogFile = "c:/tmp/parser.log";
25 
26 //debug version = enableLog;
27 
28 version(enableLog) {
29 
30     struct LogIndent
31     {
32         this(int n)
33         {
34             indent = n;
35             gLogIndent += indent;
36         }
37         ~this()
38         {
39             gLogIndent -= indent;
40         }
41         int indent;
42     }
43 
44     mixin template logIndent(int n = 1)
45     {
46         LogIndent indent = LogIndent(n);
47     }
48 
49     class logSync {}
50 
51     void logInfo(...)
52     {
53         auto buffer = new char[17 + 1];
54         SysTime now = Clock.currTime();
55         uint tid = GetCurrentThreadId();
56         auto len = sprintf(buffer.ptr, "%02d:%02d:%02d - %04x - ",
57                            now.hour, now.minute, now.second, tid);
58         string s = to!string(buffer[0..len]);
59         s ~= replicate(" ", gLogIndent);
60 
61         void putc(dchar c)
62         {
63             s ~= c;
64         }
65 
66         try {
67             std.format.doFormat(&putc, _arguments, _argptr);
68         }
69         catch(Exception e)
70         {
71             string msg = e.toString();
72             s ~= " EXCEPTION";
73         }
74 
75         log_string(s);
76     }
77 
78     void log_string(string s)
79     {
80         s ~= "\n";
81         if(gLogFile.length == 0)
82             OutputDebugStringA(toStringz(s));
83         else
84             synchronized(typeid(logSync))
85             {
86                 if(gLogFirst)
87                 {
88                     gLogFirst = false;
89                     s = "\n" ~ replicate("=", 80) ~ "\n" ~ s;
90                 }
91                 std.file.append(gLogFile, s);
92             }
93     }
94 }
95 else
96 {
97     import core.vararg;
98 
99     struct LogIndent
100     {
101         this(int n)
102         {
103         }
104     }
105     void logInfo(...)
106     {
107     }
108     void log_string(string s)
109     {
110     }
111 }