]> git.cworth.org Git - apitrace/blob - log.cpp
Have logging methods as regular functions.
[apitrace] / log.cpp
1 /****************************************************************************
2  *
3  * Copyright 2008 Jose Fonseca
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  ****************************************************************************/
19
20
21 #include <stdio.h>
22
23 #include "log.hpp"
24
25
26 namespace Log {
27
28
29 static HANDLE g_hFile = INVALID_HANDLE_VALUE;
30 static TCHAR g_szFileName[MAX_PATH];
31
32 static void _Close(void) {
33     if(g_hFile != INVALID_HANDLE_VALUE) {
34         CloseHandle(g_hFile);
35         g_hFile = INVALID_HANDLE_VALUE;
36     }
37 }
38
39 static void _Open(const TCHAR *szName, const TCHAR *szExtension) {
40     _Close();
41     
42     DWORD dwCounter = 0;
43     do {
44         if(dwCounter)
45             _sntprintf(g_szFileName, MAX_PATH, TEXT("%s.%u.%s"), szName, dwCounter, szExtension);
46         else
47             _sntprintf(g_szFileName, MAX_PATH, TEXT("%s.%s"), szName, szExtension);
48
49         g_hFile = CreateFile(g_szFileName,
50                              GENERIC_WRITE,
51                              FILE_SHARE_WRITE,
52                              NULL,
53                              CREATE_NEW,
54                              FILE_ATTRIBUTE_NORMAL,
55                              NULL);
56         ++dwCounter;
57     } while(g_hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS);
58 }
59
60 static void _ReOpen(void) {
61     _Close();
62     
63     g_hFile = CreateFile(g_szFileName,
64                          GENERIC_WRITE,
65                          FILE_SHARE_WRITE,
66                          NULL,
67                          OPEN_EXISTING,
68                          FILE_ATTRIBUTE_NORMAL,
69                          NULL);
70 }
71
72 static void Write(const char *szText) {
73     if(g_hFile == INVALID_HANDLE_VALUE)
74         return;
75     
76     DWORD dwBytesToWrite = (DWORD)strlen(szText);
77     DWORD dwBytesWritten = 0;
78     
79     while (dwBytesWritten < dwBytesToWrite) {
80         OVERLAPPED overlapped;
81         memset(&overlapped, 0, sizeof(OVERLAPPED));
82
83         /* Write to end of file */
84         overlapped.Offset = 0xffffffff;
85         overlapped.OffsetHigh = 0xffffffff;
86         
87         if(WriteFile(g_hFile,
88                      szText + dwBytesWritten,
89                      dwBytesToWrite - dwBytesWritten,
90                      &dwBytesWritten,
91                      &overlapped) == FALSE) {
92             _Close();
93             _Open(TEXT("extra"), TEXT("xml"));
94             return;
95         }
96     }
97 }
98
99
100 void Open(const TCHAR *szName) {
101     _Open(szName, TEXT("xml"));
102     Write("<?xml version='1.0' encoding='UTF-8'?>");
103     NewLine();
104     Write("<?xml-stylesheet type='text/xsl' href='d3dtrace.xsl'?>");
105     NewLine();
106     Write("<trace>");
107     NewLine();
108 }
109
110 void ReOpen(void) {
111     _ReOpen();
112 }
113
114 void Close(void) {
115     Write("</trace>");
116     NewLine();
117     _Close();
118 }
119
120 static void Escape(const char *s) {
121     /* FIXME */
122     Write(s);
123 }
124
125 void NewLine(void) {
126     Write("\r\n");
127 }
128
129 void Tag(const char *name) {
130     Write("<");
131     Write(name);
132     Write("/>");
133 }
134
135 void BeginTag(const char *name) {
136     Write("<");
137     Write(name);
138     Write(">");
139 }
140
141 void BeginTag(const char *name, 
142               const char *attr1, const char *value1) {
143     Write("<");
144     Write(name);
145     Write(" ");
146     Write(attr1);
147     Write("=\"");
148     Escape(value1);
149     Write("\">");
150 }
151
152 void BeginTag(const char *name, 
153               const char *attr1, const char *value1,
154               const char *attr2, const char *value2) {
155     Write("<");
156     Write(name);
157     Write(" ");
158     Write(attr1);
159     Write("=\"");
160     Escape(value1);
161     Write("\" ");
162     Write(attr2);
163     Write("=\"");
164     Escape(value2);
165     Write("\">");
166 }
167
168 void EndTag(const char *name) {
169     Write("</");
170     Write(name);
171     Write(">");
172 }
173
174 void Text(const char *text) {
175     Escape(text);
176 }
177
178 void TextF(const char *format, ...) {
179     char szBuffer[4196];
180     va_list ap;
181     va_start(ap, format);
182     vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
183     va_end(ap);
184     Escape(szBuffer);
185 }
186
187 void BeginCall(const char *function) {
188     Write("\t");
189     BeginTag("call", "name", function);
190     NewLine();
191 }
192
193 void EndCall(void) {
194     Write("\t");
195     EndTag("call");
196     NewLine();
197 }
198
199 void BeginParam(const char *name, const char *type) {
200     Write("\t\t");
201     BeginTag("param", "name", name, "type", type);
202 }
203
204 void EndParam(void) {
205     EndTag("param");
206     NewLine();
207 }
208
209 void BeginReturn(const char *type) {
210     Write("\t\t");
211     BeginTag("return", "type", type);
212 }
213
214 void EndReturn(void) {
215     EndTag("return");
216     NewLine();
217 }
218
219
220 } /* namespace Log */