1 /**************************************************************************
3 * Copyright 2007-2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
41 static gzFile g_gzFile = NULL;
42 static void _Close(void) {
43 if(g_gzFile != NULL) {
49 static void _Open(const char *szName, const char *szExtension) {
52 static unsigned dwCounter = 0;
54 char szProcessName[PATH_MAX];
55 char szFileName[PATH_MAX];
57 OS::GetProcessName(szProcessName, PATH_MAX);
63 snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s.gz", szProcessName, szName, dwCounter, szExtension);
65 snprintf(szFileName, PATH_MAX, "%s.%s.%s.gz", szProcessName, szName, szExtension);
67 file = fopen(szFileName, "rb");
76 fprintf(stderr, "Logging to %s\n", szFileName);
77 g_gzFile = gzopen(szFileName, "wb");
80 static inline void _ReOpen(void) {
84 static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
88 gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
91 static inline void Write(const char *szText) {
92 Write(szText, strlen(szText));
95 static inline void Write(char c)
101 WriteF(const char *format, ...)
105 va_start(ap, format);
106 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
136 Escape(const char *s)
139 while((c = *s++) != 0) {
145 EscapeF(const char *format, ...)
149 va_start(ap, format);
150 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
156 Indent(unsigned level) {
157 for(unsigned i = 0; i < level; ++i)
167 Tag(const char *name) {
174 BeginTag(const char *name) {
181 BeginTag(const char *name,
182 const char *attr1, const char *value1) {
193 BeginTag(const char *name,
194 const char *attr1, const char *value1,
195 const char *attr2, const char *value2) {
210 BeginTag(const char *name,
211 const char *attr1, const char *value1,
212 const char *attr2, const char *value2,
213 const char *attr3, const char *value3) {
232 EndTag(const char *name) {
238 void Open(const char *name) {
240 Write("<?xml version='1.0' encoding='UTF-8'?>");
242 Write("<?xml-stylesheet type='text/xsl' href='apitrace.xsl'?>");
258 void Text(const char *text) {
262 void TextF(const char *format, ...) {
265 va_start(ap, format);
266 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
271 void BeginCall(const char *function) {
274 BeginTag("call", "name", function);
282 gzflush(g_gzFile, Z_SYNC_FLUSH);
286 void BeginArg(const char *type, const char *name) {
288 BeginTag("arg", "type", type, "name", name);
296 void BeginReturn(const char *type) {
298 BeginTag("ret", "type", type);
301 void EndReturn(void) {
306 void BeginElement(const char *type, const char *name) {
307 BeginTag("elem", "type", type, "name", name);
310 void BeginElement(const char *type) {
311 BeginTag("elem", "type", type);
314 void EndElement(void) {
318 void BeginReference(const char *type, const void *addr) {
320 snprintf(saddr, sizeof(saddr), "%p", addr);
321 BeginTag("ref", "type", type, "addr", saddr);
324 void EndReference(void) {
328 void DumpString(const char *str) {
329 const unsigned char *p = (const unsigned char *)str;
336 while((c = *p++) != 0) {
341 else if(c >= 0x20 && c <= 0x7e)
350 unsigned char octal0 = c & 0x7;
351 unsigned char octal1 = (c >> 3) & 0x7;
352 unsigned char octal2 = (c >> 3) & 0x7;
354 WriteF("\\%u%u%u", octal2, octal1, octal0);
356 WriteF("\\%u%u", octal1, octal0);
358 WriteF("\\%u", octal0);
364 void DumpWString(const wchar_t *str) {
365 const wchar_t *p = str;
372 while((c = *p++) != 0) {
377 else if(c >= 0x20 && c <= 0x7e)
386 unsigned octal0 = c & 0x7;
387 unsigned octal1 = (c >> 3) & 0x7;
388 unsigned octal2 = (c >> 3) & 0x7;
390 WriteF("\\%u%u%u", octal2, octal1, octal0);
392 WriteF("\\%u%u", octal1, octal0);
394 WriteF("\\%u", octal0);
400 } /* namespace Log */