]> git.cworth.org Git - apitrace/blob - log.cpp
Basic support for tracing d3d7.
[apitrace] / log.cpp
1 /****************************************************************************
2  *
3  * Copyright 2008 Tungsten Graphics, Inc.
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 <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <zlib.h>
27
28 #include "log.hpp"
29
30
31 #ifdef WIN32
32 #ifndef PATH_MAX
33 #define PATH_MAX _MAX_PATH
34 #endif
35 #ifndef snprintf
36 #define snprintf _snprintf
37 #endif
38 #ifndef vsnprintf
39 #define vsnprintf _vsnprintf
40 #endif
41 #endif
42
43
44 namespace Log {
45
46
47 static gzFile g_gzFile = NULL;
48 static char g_szFileName[PATH_MAX];
49
50 static void _Close(void) {
51     if(g_gzFile != NULL) {
52         gzclose(g_gzFile);
53         g_gzFile = NULL;
54     }
55 }
56
57 static void _Open(const char *szName, const char *szExtension) {
58     _Close();
59     
60     static unsigned dwCounter = 0;
61
62     for(;;) {
63         FILE *file;
64         
65         if(dwCounter)
66             snprintf(g_szFileName, PATH_MAX, "%s.%u.%s.gz", szName, dwCounter, szExtension);
67         else
68             snprintf(g_szFileName, PATH_MAX, "%s.%s.gz", szName, szExtension);
69         
70         file = fopen(g_szFileName, "rb");
71         if(file == NULL)
72             break;
73         
74         fclose(file);
75         
76         ++dwCounter;
77     }
78
79     g_gzFile = gzopen(g_szFileName, "wb");
80 }
81
82 static inline void _ReOpen(void) {
83     /* XXX */
84 }
85
86 static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
87     if(g_gzFile == NULL)
88         return;
89     
90     gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
91 }
92
93 static inline void Write(const char *szText) {
94     Write(szText, strlen(szText));
95 }
96
97 static inline void 
98 Escape(const char *s) {
99     /* FIXME */
100     Write(s);
101 }
102
103 static inline void 
104 Indent(unsigned level) {
105     for(unsigned i = 0; i < level; ++i)
106         Write("\t");
107 }
108
109 static inline void 
110 NewLine(void) {
111     Write("\r\n");
112 }
113
114 static inline void 
115 Tag(const char *name) {
116     Write("<");
117     Write(name);
118     Write("/>");
119 }
120
121 static inline void 
122 BeginTag(const char *name) {
123     Write("<");
124     Write(name);
125     Write(">");
126 }
127
128 static inline void 
129 BeginTag(const char *name, 
130          const char *attr1, const char *value1) {
131     Write("<");
132     Write(name);
133     Write(" ");
134     Write(attr1);
135     Write("=\"");
136     Escape(value1);
137     Write("\">");
138 }
139
140 static inline void 
141 BeginTag(const char *name, 
142          const char *attr1, const char *value1,
143          const char *attr2, const char *value2) {
144     Write("<");
145     Write(name);
146     Write(" ");
147     Write(attr1);
148     Write("=\"");
149     Escape(value1);
150     Write("\" ");
151     Write(attr2);
152     Write("=\"");
153     Escape(value2);
154     Write("\">");
155 }
156
157 static inline void 
158 BeginTag(const char *name, 
159               const char *attr1, const char *value1,
160               const char *attr2, const char *value2,
161               const char *attr3, const char *value3) {
162     Write("<");
163     Write(name);
164     Write(" ");
165     Write(attr1);
166     Write("=\"");
167     Escape(value1);
168     Write("\" ");
169     Write(attr2);
170     Write("=\"");
171     Escape(value2);
172     Write("\" ");
173     Write(attr3);
174     Write("=\"");
175     Escape(value3);
176     Write("\">");
177 }
178
179 static inline void
180 EndTag(const char *name) {
181     Write("</");
182     Write(name);
183     Write(">");
184 }
185
186 void Open(const char *name) {
187     _Open(name, "xml");
188     Write("<?xml version='1.0' encoding='UTF-8'?>");
189     NewLine();
190     Write("<?xml-stylesheet type='text/xsl' href='d3dtrace.xsl'?>");
191     NewLine();
192     BeginTag("trace");
193     NewLine();
194 }
195
196 void ReOpen(void) {
197     _ReOpen();
198 }
199
200 void Close(void) {
201     EndTag("trace");
202     NewLine();
203     _Close();
204 }
205
206 void Text(const char *text) {
207     Escape(text);
208 }
209
210 static void TextChar(char c) {
211     char szText[2];
212     szText[0] = c;
213     szText[1] = 0;
214     Text(szText);
215 }
216
217 void TextF(const char *format, ...) {
218     char szBuffer[4196];
219     va_list ap;
220     va_start(ap, format);
221     vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
222     va_end(ap);
223     Text(szBuffer);
224 }
225
226 void BeginCall(const char *function) {
227     Indent(1);
228     BeginTag("call", "name", function);
229     NewLine();
230 }
231
232 void EndCall(void) {
233     Indent(1);
234     EndTag("call");
235     NewLine();
236 }
237
238 void BeginArg(const char *type, const char *name) {
239     Indent(2);
240     BeginTag("arg", "type", type, "name", name);
241 }
242
243 void EndArg(void) {
244     EndTag("arg");
245     NewLine();
246 }
247
248 void BeginReturn(const char *type) {
249     Indent(2);
250     BeginTag("ret", "type", type);
251 }
252
253 void EndReturn(void) {
254     EndTag("ret");
255     NewLine();
256 }
257
258 void BeginElement(const char *type, const char *name) {
259     BeginTag("elem", "type", type, "name", name);
260 }
261
262 void BeginElement(const char *type) {
263     BeginTag("elem", "type", type);
264 }
265
266 void EndElement(void) {
267     EndTag("elem");
268 }
269
270 void BeginReference(const char *type, const void *addr) {
271     char saddr[256];
272     snprintf(saddr, sizeof(saddr), "%p", addr);
273     BeginTag("ref", "type", type, "addr", saddr);
274 }
275
276 void EndReference(void) {
277     EndTag("ref");
278 }
279
280 void DumpString(const char *str) {
281     const unsigned char *p = (const unsigned char *)str;
282     Log::Text("\"");
283     unsigned char c;
284     while((c = *p++) != 0) {
285         if(c == '\"')
286             Text("\\\"");
287         else if(c == '\\')
288             Text("\\\\");
289         else if(c >= 0x20 && c <= 0x7e)
290             TextChar(c);
291         else if(c == '\t')
292             Text("\\t");
293         else if(c == '\r')
294             Text("\\r");
295         else if(c == '\n')
296             Text("\\n");
297         else {
298             unsigned char octal0 = c & 0x7;
299             unsigned char octal1 = (c >> 3) & 0x7;
300             unsigned char octal2 = (c >> 3) & 0x7;
301             if(octal2)
302                 TextF("\\%u%u%u", octal2, octal1, octal0);
303             else if(octal1)
304                 TextF("\\%u%u", octal1, octal0);
305             else
306                 TextF("\\%u", octal0);
307         }
308     }
309     Log::Text("\"");
310 }
311
312 } /* namespace Log */