]> git.cworth.org Git - apitrace/blobdiff - log.cpp
Split glxapi.
[apitrace] / log.cpp
diff --git a/log.cpp b/log.cpp
index 2dc3775ecf2aba7eb891c87d376e9c732a25c0f3..719666fb21a7df211d2a1102e513f323ed2c6cae 100644 (file)
--- a/log.cpp
+++ b/log.cpp
  **************************************************************************/
 
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include <map>
+
 #include <zlib.h>
 
 #include "os.hpp"
 #include "log.hpp"
+#include "trace_format.hpp"
 
 
 namespace Log {
@@ -40,412 +44,281 @@ namespace Log {
 
 static gzFile g_gzFile = NULL;
 static void _Close(void) {
-    if(g_gzFile != NULL) {
-        gzclose(g_gzFile);
-        g_gzFile = NULL;
-    }
-}
-
-static void _Open(const char *szName, const char *szExtension) {
-    _Close();
-    
-    static unsigned dwCounter = 0;
-
-    char szProcessName[PATH_MAX];
-    char szFileName[PATH_MAX];
-
-    OS::GetProcessName(szProcessName, PATH_MAX);
-
-    for(;;) {
-        FILE *file;
-        
-        if(dwCounter)
-            snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s.gz", szProcessName, szName, dwCounter, szExtension);
-        else
-            snprintf(szFileName, PATH_MAX, "%s.%s.%s.gz", szProcessName, szName, szExtension);
-        
-        file = fopen(szFileName, "rb");
-        if(file == NULL)
-            break;
-        
-        fclose(file);
-        
-        ++dwCounter;
-    }
-
-    fprintf(stderr, "Logging to %s\n", szFileName);
-    g_gzFile = gzopen(szFileName, "wb");
-}
-
-static inline void _ReOpen(void) {
-    /* XXX */
-}
-
-static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
-    if(g_gzFile == NULL)
-        return;
-    
-    gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
-}
-
-static inline void Write(const char *szText) {
-    Write(szText, strlen(szText));
-}
-
-static inline void Write(char c) 
-{
-    Write(&c, 1);
-}
-
-static inline void
-WriteF(const char *format, ...) 
-{
-    char szBuffer[4096];
-    va_list ap;
-    va_start(ap, format);
-    vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
-    va_end(ap);
-    Write(szBuffer);
-}
-
-static inline void 
-Escape(wchar_t c) 
-{
-    switch(c) {
-    case '&':
-        Write("&amp;");
-        break;
-    case '<':
-        Write("&lt;");
-        break;
-    case '>':
-        Write("&gt;");
-        break;
-    case '"':
-        Write("&quot;");
-        break;
-    case '\'':
-        Write("&apos;");
-        break;
-    case '\t':
-        Write("&#09;");
-        break;
-    case '\r':
-        Write("&#13;");
-        break;
-    case '\n':
-        Write("&#10;");
-        break;
-    default:
-        if (c >= 0x20 && c <= 0x7e) {
-            Write((char)c);
-        } else {
-            Write('.');
-        }
-    }
+   if(g_gzFile != NULL) {
+      gzclose(g_gzFile);
+      g_gzFile = NULL;
+   }
+}
+
+static void _Open(const char *szExtension) {
+   _Close();
+   
+   static unsigned dwCounter = 0;
+
+   char szFileName[PATH_MAX];
+   const char *lpFileName;
+
+   lpFileName = getenv("TRACE_PATH");
+   if (lpFileName) {
+       strncpy(szFileName, lpFileName, PATH_MAX);
+   }
+   else {
+       char szProcessName[PATH_MAX];
+       char szCurrentDir[PATH_MAX];
+       OS::GetProcessName(szProcessName, PATH_MAX);
+       OS::GetCurrentDir(szCurrentDir, PATH_MAX);
+
+       for(;;) {
+          FILE *file;
+          
+          if (dwCounter)
+             snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension);
+          else
+             snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension);
+          
+          file = fopen(szFileName, "rb");
+          if(file == NULL)
+             break;
+          
+          fclose(file);
+          
+          ++dwCounter;
+       }
+   }
+
+   OS::DebugMessage("apitrace: tracing to %s\n", szFileName);
+
+   g_gzFile = gzopen(szFileName, "wb");
+}
+
+static inline void Write(const void *sBuffer, size_t dwBytesToWrite) {
+   if (g_gzFile == NULL)
+      return;
+   
+   gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
 }
 
 static inline void 
-Escape(const char *s)
-{
-    unsigned char c;
-    while((c = *s++) != 0) {
-        Escape(c);
-    }
+WriteByte(char c) {
+   Write(&c, 1);
 }
 
-static inline void 
-Escape(const wchar_t *s)
-{
-    unsigned char c;
-    while((c = *s++) != 0) {
-        Escape(c);
-    }
-}
+void inline 
+WriteUInt(unsigned long long value) {
+   char buf[2 * sizeof value];
+   unsigned len;
 
-static inline void
-EscapeF(const char *format, ...)
-{
-    char szBuffer[4096];
-    va_list ap;
-    va_start(ap, format);
-    vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
-    va_end(ap);
-    Escape(szBuffer);
-}
+   len = 0;
+   do {
+      assert(len < sizeof buf);
+      buf[len] = 0x80 | (value & 0x7f);
+      value >>= 7;
+      ++len;
+   } while (value);
 
-static inline void 
-Indent(unsigned level) {
-    for(unsigned i = 0; i < level; ++i)
-        Write("\t");
-}
+   assert(len);
+   buf[len - 1] &= 0x7f;
 
-static inline void 
-NewLine(void) {
-    Write("\r\n");
+   Write(buf, len);
 }
 
 static inline void 
-Tag(const char *name) {
-    Write("<");
-    Write(name);
-    Write("/>");
+WriteFloat(float value) {
+   assert(sizeof value == 4);
+   Write((const char *)&value, sizeof value);
 }
 
 static inline void 
-BeginTag(const char *name) {
-    Write("<");
-    Write(name);
-    Write(">");
+WriteDouble(double value) {
+   assert(sizeof value == 8);
+   Write((const char *)&value, sizeof value);
 }
 
 static inline void 
-BeginTag(const char *name, 
-         const char *attr1, const char *value1) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\">");
+WriteString(const char *str) {
+   size_t len = strlen(str);
+   WriteUInt(len);
+   Write(str, len);
 }
 
-static inline void 
-BeginTag(const char *name, 
-         const char *attr1, const char *value1,
-         const char *attr2, const char *value2) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\" ");
-    Write(attr2);
-    Write("=\"");
-    Escape(value2);
-    Write("\">");
-}
+typedef std::map<const char *, size_t> namemap;
+static namemap names;
 
 static inline void 
-BeginTag(const char *name, 
-              const char *attr1, const char *value1,
-              const char *attr2, const char *value2,
-              const char *attr3, const char *value3) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\" ");
-    Write(attr2);
-    Write("=\"");
-    Escape(value2);
-    Write("\" ");
-    Write(attr3);
-    Write("=\"");
-    Escape(value3);
-    Write("\">");
-}
-
-static inline void
-EndTag(const char *name) {
-    Write("</");
-    Write(name);
-    Write(">");
-}
-
-void Open(const char *name) {
-    _Open(name, "xml");
-    Write("<?xml version='1.0' encoding='UTF-8'?>");
-    NewLine();
-    Write("<?xml-stylesheet type='text/xsl' href='apitrace.xsl'?>");
-    NewLine();
-    BeginTag("trace");
-    NewLine();
-}
-
-void ReOpen(void) {
-    _ReOpen();
+WriteName(const char *name) {
+   namemap::iterator it = names.find(name);
+   if (it == names.end()) {
+       size_t name_id = names.size();
+       WriteUInt(name_id);
+       WriteString(name);
+       names[name] = name_id;
+   } else {
+       WriteUInt(it->second);
+   }
+}
+
+void Open(void) {
+    if (!g_gzFile) {
+        _Open("trace");
+        WriteUInt(TRACE_VERSION);
+    }
 }
 
 void Close(void) {
-    EndTag("trace");
-    NewLine();
-    _Close();
+   _Close();
 }
 
-void BeginCall(const char *function) {
-    OS::AcquireMutex();
-    Indent(1);
-    BeginTag("call", "name", function);
-    NewLine();
-}
+static unsigned call_no = 0;
 
-void EndCall(void) {
-    Indent(1);
-    EndTag("call");
-    NewLine();
-    gzflush(g_gzFile, Z_SYNC_FLUSH);
-    OS::ReleaseMutex();
+unsigned BeginEnter(const char *function) {
+   OS::AcquireMutex();
+   Open();
+   WriteByte(Trace::EVENT_ENTER);
+   WriteName(function);
+   return call_no++;
 }
 
-void BeginArg(const char *type, const char *name) {
-    Indent(2);
-    BeginTag("arg", "type", type, "name", name);
+void EndEnter(void) {
+   WriteByte(Trace::CALL_END);
+   gzflush(g_gzFile, Z_SYNC_FLUSH);
+   OS::ReleaseMutex();
 }
 
-void EndArg(void) {
-    EndTag("arg");
-    NewLine();
+void BeginLeave(unsigned call) {
+   OS::AcquireMutex();
+   WriteByte(Trace::EVENT_LEAVE);
+   WriteUInt(call);
 }
 
-void BeginReturn(const char *type) {
-    Indent(2);
-    BeginTag("ret", "type", type);
+void EndLeave(void) {
+   WriteByte(Trace::CALL_END);
+   gzflush(g_gzFile, Z_SYNC_FLUSH);
+   OS::ReleaseMutex();
 }
 
-void EndReturn(void) {
-    EndTag("ret");
-    NewLine();
+void BeginArg(unsigned index, const char *name) {
+   WriteByte(Trace::CALL_ARG);
+   WriteUInt(index);
+   WriteName(name);
 }
 
-void BeginArray(const char *type, size_t length)
-{
-    BeginTag("array", "type", type);
+void BeginReturn(void) {
+   WriteByte(Trace::CALL_RET);
 }
 
-void EndArray(void)
-{
-    EndTag("array");
+void BeginArray(size_t length) {
+   WriteByte(Trace::TYPE_ARRAY);
+   WriteUInt(length);
 }
 
-void BeginElement(const char *type)
-{
-    BeginTag("elem", "type", type);
+void BeginStruct(size_t length) {
+   WriteByte(Trace::TYPE_STRUCT);
+   WriteUInt(length);
 }
 
-void EndElement(void)
-{
-    EndTag("elem");
+void BeginMember(const char *name) {
+   WriteName(name);
 }
 
-void BeginStruct(const char *type)
-{
-    BeginTag("struct", "type", type);
+void BeginBitmask(void) {
+   WriteByte(Trace::TYPE_BITMASK);
 }
 
-void EndStruct(void)
-{
-    EndTag("struct");
+void EndBitmask(void) {
+   WriteByte(Trace::TYPE_NULL);
 }
 
-void BeginMember(const char *type, const char *name)
-{
-    BeginTag("member", "type", type, "name", name);
+void LiteralBool(bool value) {
+   WriteByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE);
 }
 
-void EndMember(void)
-{
-    EndTag("member");
+void LiteralSInt(signed long long value) {
+   if (value < 0) {
+      WriteByte(Trace::TYPE_SINT);
+      WriteUInt(-value);
+   } else {
+      WriteByte(Trace::TYPE_UINT);
+      WriteUInt(value);
+   }
 }
 
-void BeginBitmask(const char *type)
-{
-    BeginTag("bitmask");
+void LiteralUInt(unsigned long long value) {
+   WriteByte(Trace::TYPE_UINT);
+   WriteUInt(value);
 }
 
-void EndBitmask(void)
-{
-    EndTag("bitmask");
+void LiteralFloat(float value) {
+   WriteByte(Trace::TYPE_FLOAT);
+   WriteFloat(value);
 }
 
-void BeginReference(const char *type, const void *addr)
-{
-    char saddr[256];
-    snprintf(saddr, sizeof(saddr), "%p", addr);
-    BeginTag("ref", "type", type, "addr", saddr);
+void LiteralFloat(double value) {
+   WriteByte(Trace::TYPE_DOUBLE);
+   WriteDouble(value);
 }
 
-void EndReference(void)
-{
-    EndTag("ref");
+void LiteralString(const char *str) {
+   if (!str) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_STRING);
+   WriteString(str);
 }
 
-void LiteralBool(bool value)
-{
-    BeginTag("bool");
-    WriteF("%u", value ? 0 : 1);
-    EndTag("bool");
+void LiteralString(const char *str, size_t len) {
+   if (!str) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_STRING);
+   WriteUInt(len);
+   Write(str, len);
 }
 
-void LiteralSInt(signed long long value)
-{
-    BeginTag("int");
-    WriteF("%lli", value);
-    EndTag("int");
+void LiteralWString(const wchar_t *str) {
+   if (!str) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_STRING);
+   WriteString("<wide-string>");
 }
-
-void LiteralUInt(unsigned long long value)
-{
-    BeginTag("uint");
-    WriteF("%llu", value);
-    EndTag("uint");
+   
+void LiteralBlob(const void *data, size_t size) {
+   if (!data) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_BLOB);
+   WriteUInt(size);
+   if (size) {
+      Write(data, size);
+   }
 }
 
-void LiteralFloat(double value)
-{
-    BeginTag("float");
-    WriteF("%f", value);
-    EndTag("float");
+void LiteralNamedConstant(const char *name, long long value) {
+   WriteByte(Trace::TYPE_CONST);
+   WriteName(name);
+   LiteralSInt(value);
 }
 
-void LiteralString(const char *str)
-{
-    if (!str) {
-        LiteralNull();
-        return;
-    }
-    BeginTag("string");
-    Escape(str);
-    EndTag("string");
+void LiteralNull(void) {
+   WriteByte(Trace::TYPE_NULL);
 }
 
-void LiteralWString(const wchar_t *str)
-{
-    if (!str) {
-        LiteralNull();
-        return;
-    }
-    BeginTag("wstring");
-    Escape(str);
-    EndTag("wstring");
-}
-    
-void LiteralNamedConstant(const char *str)
-{
-    BeginTag("const");
-    Escape(str);
-    EndTag("const");
-}
-
-void LiteralOpaque(const void *addr)
-{
-    char saddr[256];
-    if (!addr) {
-        LiteralNull();
-        return;
-    }
-    snprintf(saddr, sizeof(saddr), "%p", addr);
-    BeginTag("opaque", "addr", saddr);
-    EndTag("opaque");
+void LiteralOpaque(const void *addr) {
+   if (!addr) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_OPAQUE);
+   WriteUInt((size_t)addr);
 }
 
-void LiteralNull(void)
-{
-    Tag("null");
+void Abort(void) {
+    Close();
+    OS::Abort();
 }
 
 } /* namespace Log */