]> git.cworth.org Git - apitrace/blob - log.cpp
Inline the HTML style sheet.
[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='apitrace.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     gzflush(g_gzFile, Z_SYNC_FLUSH);
237 }
238
239 void BeginArg(const char *type, const char *name) {
240     Indent(2);
241     BeginTag("arg", "type", type, "name", name);
242 }
243
244 void EndArg(void) {
245     EndTag("arg");
246     NewLine();
247 }
248
249 void BeginReturn(const char *type) {
250     Indent(2);
251     BeginTag("ret", "type", type);
252 }
253
254 void EndReturn(void) {
255     EndTag("ret");
256     NewLine();
257 }
258
259 void BeginElement(const char *type, const char *name) {
260     BeginTag("elem", "type", type, "name", name);
261 }
262
263 void BeginElement(const char *type) {
264     BeginTag("elem", "type", type);
265 }
266
267 void EndElement(void) {
268     EndTag("elem");
269 }
270
271 void BeginReference(const char *type, const void *addr) {
272     char saddr[256];
273     snprintf(saddr, sizeof(saddr), "%p", addr);
274     BeginTag("ref", "type", type, "addr", saddr);
275 }
276
277 void EndReference(void) {
278     EndTag("ref");
279 }
280
281 void DumpString(const char *str) {
282     const unsigned char *p = (const unsigned char *)str;
283     Log::Text("\"");
284     unsigned char c;
285     while((c = *p++) != 0) {
286         if(c == '\"')
287             Text("\\\"");
288         else if(c == '\\')
289             Text("\\\\");
290         else if(c >= 0x20 && c <= 0x7e)
291             TextChar(c);
292         else if(c == '\t')
293             Text("\\t");
294         else if(c == '\r')
295             Text("\\r");
296         else if(c == '\n')
297             Text("\\n");
298         else {
299             unsigned char octal0 = c & 0x7;
300             unsigned char octal1 = (c >> 3) & 0x7;
301             unsigned char octal2 = (c >> 3) & 0x7;
302             if(octal2)
303                 TextF("\\%u%u%u", octal2, octal1, octal0);
304             else if(octal1)
305                 TextF("\\%u%u", octal1, octal0);
306             else
307                 TextF("\\%u", octal0);
308         }
309     }
310     Log::Text("\"");
311 }
312
313 } /* namespace Log */