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 **************************************************************************/
43 #define PATH_MAX _MAX_PATH
46 #define snprintf _snprintf
49 #define vsnprintf _vsnprintf
60 static gzFile g_gzFile = NULL;
61 static char g_szFileName[PATH_MAX];
64 static CRITICAL_SECTION CriticalSection;
67 static void _Close(void) {
68 if(g_gzFile != NULL) {
72 DeleteCriticalSection(&CriticalSection);
77 static void _Open(const char *szName, const char *szExtension) {
80 static unsigned dwCounter = 0;
82 char szProcessPath[PATH_MAX];
87 GetModuleFileNameA(NULL, szProcessPath, sizeof(szProcessPath)/sizeof(szProcessPath[0]));
89 lpProcessName = strrchr(szProcessPath, '\\');
90 lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
91 lpProcessExt = strrchr(lpProcessName, '.');
95 // http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
103 snprintf(g_szFileName, PATH_MAX, "%s.%s.%u.%s.gz", lpProcessName, szName, dwCounter, szExtension);
105 snprintf(g_szFileName, PATH_MAX, "%s.%s.%s.gz", lpProcessName, szName, szExtension);
107 file = fopen(g_szFileName, "rb");
116 g_gzFile = gzopen(g_szFileName, "wb");
118 InitializeCriticalSection(&CriticalSection);
122 static inline void _ReOpen(void) {
126 static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
130 gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
133 static inline void Write(const char *szText) {
134 Write(szText, strlen(szText));
137 static inline void Write(char c)
143 WriteF(const char *format, ...)
147 va_start(ap, format);
148 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
178 Escape(const char *s)
181 while((c = *s++) != 0) {
187 EscapeF(const char *format, ...)
191 va_start(ap, format);
192 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
198 Indent(unsigned level) {
199 for(unsigned i = 0; i < level; ++i)
209 Tag(const char *name) {
216 BeginTag(const char *name) {
223 BeginTag(const char *name,
224 const char *attr1, const char *value1) {
235 BeginTag(const char *name,
236 const char *attr1, const char *value1,
237 const char *attr2, const char *value2) {
252 BeginTag(const char *name,
253 const char *attr1, const char *value1,
254 const char *attr2, const char *value2,
255 const char *attr3, const char *value3) {
274 EndTag(const char *name) {
280 void Open(const char *name) {
282 Write("<?xml version='1.0' encoding='UTF-8'?>");
284 Write("<?xml-stylesheet type='text/xsl' href='apitrace.xsl'?>");
300 void Text(const char *text) {
304 void TextF(const char *format, ...) {
307 va_start(ap, format);
308 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
313 void BeginCall(const char *function) {
315 EnterCriticalSection(&CriticalSection);
318 BeginTag("call", "name", function);
326 gzflush(g_gzFile, Z_SYNC_FLUSH);
328 LeaveCriticalSection(&CriticalSection);
332 void BeginArg(const char *type, const char *name) {
334 BeginTag("arg", "type", type, "name", name);
342 void BeginReturn(const char *type) {
344 BeginTag("ret", "type", type);
347 void EndReturn(void) {
352 void BeginElement(const char *type, const char *name) {
353 BeginTag("elem", "type", type, "name", name);
356 void BeginElement(const char *type) {
357 BeginTag("elem", "type", type);
360 void EndElement(void) {
364 void BeginReference(const char *type, const void *addr) {
366 snprintf(saddr, sizeof(saddr), "%p", addr);
367 BeginTag("ref", "type", type, "addr", saddr);
370 void EndReference(void) {
374 void DumpString(const char *str) {
375 const unsigned char *p = (const unsigned char *)str;
382 while((c = *p++) != 0) {
387 else if(c >= 0x20 && c <= 0x7e)
396 unsigned char octal0 = c & 0x7;
397 unsigned char octal1 = (c >> 3) & 0x7;
398 unsigned char octal2 = (c >> 3) & 0x7;
400 WriteF("\\%u%u%u", octal2, octal1, octal0);
402 WriteF("\\%u%u", octal1, octal0);
404 WriteF("\\%u", octal0);
410 void DumpWString(const wchar_t *str) {
411 const wchar_t *p = str;
418 while((c = *p++) != 0) {
423 else if(c >= 0x20 && c <= 0x7e)
432 unsigned octal0 = c & 0x7;
433 unsigned octal1 = (c >> 3) & 0x7;
434 unsigned octal2 = (c >> 3) & 0x7;
436 WriteF("\\%u%u%u", octal2, octal1, octal0);
438 WriteF("\\%u%u", octal1, octal0);
440 WriteF("\\%u", octal0);
446 } /* namespace Log */