]> git.cworth.org Git - apitrace/blobdiff - log.cpp
Pass-through TAB and CR characters.
[apitrace] / log.cpp
diff --git a/log.cpp b/log.cpp
index bab893fab560ba098ac5cbd48c93cd08a57a73cf..c917fe3e751d85ffae719e862cac7d1e332d9fba 100644 (file)
--- a/log.cpp
+++ b/log.cpp
@@ -1,21 +1,27 @@
-/****************************************************************************
+/**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc.
+ * Copyright 2007-2009 VMware, Inc.
+ * All Rights Reserved.
  *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  *
- ****************************************************************************/
+ **************************************************************************/
 
 
 #include <stdarg.h>
@@ -23,6 +29,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <windows.h>
+
 #include <zlib.h>
 
 #include "log.hpp"
@@ -46,11 +54,13 @@ namespace Log {
 
 static gzFile g_gzFile = NULL;
 static char g_szFileName[PATH_MAX];
+static CRITICAL_SECTION CriticalSection;
 
 static void _Close(void) {
     if(g_gzFile != NULL) {
         gzclose(g_gzFile);
         g_gzFile = NULL;
+        DeleteCriticalSection(&CriticalSection);
     }
 }
 
@@ -59,13 +69,25 @@ static void _Open(const char *szName, const char *szExtension) {
     
     static unsigned dwCounter = 0;
 
+    char szProcessPath[PATH_MAX];
+    char *lpProcessName;
+    char *lpProcessExt;
+
+    GetModuleFileNameA(NULL, szProcessPath, sizeof(szProcessPath)/sizeof(szProcessPath[0]));
+
+    lpProcessName = strrchr(szProcessPath, '\\');
+    lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
+    lpProcessExt = strrchr(lpProcessName, '.');
+    if(lpProcessExt)
+       *lpProcessExt = '\0';
+
     for(;;) {
         FILE *file;
         
         if(dwCounter)
-            snprintf(g_szFileName, PATH_MAX, "%s.%u.%s.gz", szName, dwCounter, szExtension);
+            snprintf(g_szFileName, PATH_MAX, "%s.%s.%u.%s.gz", lpProcessName, szName, dwCounter, szExtension);
         else
-            snprintf(g_szFileName, PATH_MAX, "%s.%s.gz", szName, szExtension);
+            snprintf(g_szFileName, PATH_MAX, "%s.%s.%s.gz", lpProcessName, szName, szExtension);
         
         file = fopen(g_szFileName, "rb");
         if(file == NULL)
@@ -77,6 +99,7 @@ static void _Open(const char *szName, const char *szExtension) {
     }
 
     g_gzFile = gzopen(g_szFileName, "wb");
+    InitializeCriticalSection(&CriticalSection);
 }
 
 static inline void _ReOpen(void) {
@@ -223,16 +246,39 @@ void TextF(const char *format, ...) {
     Text(szBuffer);
 }
 
+static LARGE_INTEGER frequency = {0};
+static LARGE_INTEGER startcounter;
+
 void BeginCall(const char *function) {
+    EnterCriticalSection(&CriticalSection); 
     Indent(1);
     BeginTag("call", "name", function);
     NewLine();
+
+    if(!frequency.QuadPart)
+       QueryPerformanceFrequency(&frequency);
+    
+    QueryPerformanceCounter(&startcounter);
 }
 
 void EndCall(void) {
+    LARGE_INTEGER endcounter;
+    LONGLONG usecs;
+
+    QueryPerformanceCounter(&endcounter);
+    usecs = (endcounter.QuadPart - startcounter.QuadPart)*1000000/frequency.QuadPart;
+
+    Indent(2);
+    BeginTag("duration");
+    TextF("%llu", usecs);
+    EndTag("duration");
+    NewLine();
+
     Indent(1);
     EndTag("call");
     NewLine();
+    gzflush(g_gzFile, Z_SYNC_FLUSH);
+    LeaveCriticalSection(&CriticalSection); 
 }
 
 void BeginArg(const char *type, const char *name) {
@@ -279,6 +325,10 @@ void EndReference(void) {
 
 void DumpString(const char *str) {
     const unsigned char *p = (const unsigned char *)str;
+    if (!str) {
+        Log::Text("L\"");
+        return;
+    }
     Log::Text("\"");
     unsigned char c;
     while((c = *p++) != 0) {
@@ -289,11 +339,11 @@ void DumpString(const char *str) {
         else if(c >= 0x20 && c <= 0x7e)
             TextChar(c);
         else if(c == '\t')
-            Text("\\t");
+            Text("&#09;");
         else if(c == '\r')
-            Text("\\r");
+            Text("&#13;");
         else if(c == '\n')
-            Text("\\n");
+            Text("&#10;");
         else {
             unsigned char octal0 = c & 0x7;
             unsigned char octal1 = (c >> 3) & 0x7;
@@ -309,4 +359,40 @@ void DumpString(const char *str) {
     Log::Text("\"");
 }
 
+void DumpWString(const wchar_t *str) {
+    const wchar_t *p = str;
+    if (!str) {
+        Log::Text("L\"");
+        return;
+    }
+    Log::Text("L\"");
+    wchar_t c;
+    while((c = *p++) != 0) {
+        if(c == '\"')
+            Text("\\\"");
+        else if(c == '\\')
+            Text("\\\\");
+        else if(c >= 0x20 && c <= 0x7e)
+            TextChar((char)c);
+        else if(c == '\t')
+            Text("&#09;");
+        else if(c == '\r')
+            Text("&#13;");
+        else if(c == '\n')
+            Text("&#10;");
+        else {
+            unsigned octal0 = c & 0x7;
+            unsigned octal1 = (c >> 3) & 0x7;
+            unsigned octal2 = (c >> 3) & 0x7;
+            if(octal2)
+                TextF("\\%u%u%u", octal2, octal1, octal0);
+            else if(octal1)
+                TextF("\\%u%u", octal1, octal0);
+            else
+                TextF("\\%u", octal0);
+        }
+    }
+    Log::Text("\"");
+}
+
 } /* namespace Log */