]> git.cworth.org Git - apitrace/blobdiff - common/trace_parser.cpp
Introduce call flags.
[apitrace] / common / trace_parser.cpp
index d7b20d2c450faaab61cc986c6c046b72df5a4caa..1a1139d0f05a68a9253cfe900dd2a603caa4f652 100644 (file)
 
 #include <assert.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "trace_file.hpp"
-#include "trace_snappyfile.hpp"
 #include "trace_parser.hpp"
 
 
 #define TRACE_VERBOSE 0
 
 
-namespace Trace {
+namespace trace {
 
 
 Parser::Parser() {
     file = NULL;
     next_call_no = 0;
     version = 0;
+
+    glGetErrorSig = NULL;
 }
 
 
@@ -53,13 +55,8 @@ Parser::~Parser() {
 
 bool Parser::open(const char *filename) {
     assert(!file);
-    if (File::isZLibCompressed(filename)) {
-        file = new ZLibFile;
-    } else {
-        file = new SnappyFile;
-    }
-
-    if (!file->open(filename, File::Read)) {
+    file = File::createForRead(filename);
+    if (!file) {
         return false;
     }
 
@@ -148,6 +145,8 @@ void Parser::close(void) {
         }
     }
     bitmasks.clear();
+
+    next_call_no = 0;
 }
 
 
@@ -168,20 +167,26 @@ void Parser::setBookmark(const ParseBookmark &bookmark) {
 
 Call *Parser::parse_call(Mode mode) {
     do {
+        Call *call;
         int c = read_byte();
-        switch(c) {
-        case Trace::EVENT_ENTER:
+        switch (c) {
+        case trace::EVENT_ENTER:
             parse_enter(mode);
             break;
-        case Trace::EVENT_LEAVE:
-            return parse_leave(mode);
+        case trace::EVENT_LEAVE:
+            call = parse_leave(mode);
+            adjust_call_flags(call);
+            return call;
         default:
             std::cerr << "error: unknown event " << c << "\n";
             exit(1);
         case -1:
-            for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
-                std::cerr << "warning: incomplete call " << (*it)->name() << "\n";
-                std::cerr << **it << "\n";
+            if (!calls.empty()) {
+                call = calls.front();
+                call->flags |= CALL_FLAG_INCOMPLETE;
+                calls.pop_front();
+                adjust_call_flags(call);
+                return call;
             }
             return NULL;
         }
@@ -203,7 +208,8 @@ T *lookup(std::vector<T *> &map, size_t index) {
 }
 
 
-FunctionSig *Parser::parse_function_sig(void) {
+Parser::FunctionSigFlags *
+Parser::parse_function_sig(void) {
     size_t id = read_uint();
 
     FunctionSigState *sig = lookup(functions, id);
@@ -219,12 +225,25 @@ FunctionSig *Parser::parse_function_sig(void) {
             arg_names[i] = read_string();
         }
         sig->arg_names = arg_names;
+        sig->flags = lookupCallFlags(sig->name);
         sig->offset = file->currentOffset();
         functions[id] = sig;
+
+        /**
+         * Note down the signature of special functions for future reference.
+         *
+         * NOTE: If the number of comparisons increases we should move this to a
+         * separate function and use bisection.
+         */
+        if (sig->num_args == 0 &&
+            strcmp(sig->name, "glGetError") == 0) {
+            glGetErrorSig = sig;
+        }
+
     } else if (file->currentOffset() < sig->offset) {
         /* skip over the signature */
         skip_string(); /* name */
-        int num_args = read_uint();
+        unsigned num_args = read_uint();
         for (unsigned i = 0; i < num_args; ++i) {
              skip_string(); /*arg_name*/
         }
@@ -329,9 +348,9 @@ BitmaskSig *Parser::parse_bitmask_sig() {
 
 
 void Parser::parse_enter(Mode mode) {
-    FunctionSig *sig = parse_function_sig();
+    FunctionSigFlags *sig = parse_function_sig();
 
-    Call *call = new Call(sig);
+    Call *call = new Call(sig, sig->flags);
 
     call->no = next_call_no++;
 
@@ -369,13 +388,13 @@ Call *Parser::parse_leave(Mode mode) {
 bool Parser::parse_call_details(Call *call, Mode mode) {
     do {
         int c = read_byte();
-        switch(c) {
-        case Trace::CALL_END:
+        switch (c) {
+        case trace::CALL_END:
             return true;
-        case Trace::CALL_ARG:
+        case trace::CALL_ARG:
             parse_arg(call, mode);
             break;
-        case Trace::CALL_RET:
+        case trace::CALL_RET:
             call->ret = parse_value(mode);
             break;
         default:
@@ -389,6 +408,21 @@ bool Parser::parse_call_details(Call *call, Mode mode) {
 }
 
 
+/**
+ * Make adjustments to this particular call flags.
+ *
+ * NOTE: This is called per-call so no string comparisons should be done here.
+ * All name comparisons should be done when the signature is parsed instead.
+ */
+void Parser::adjust_call_flags(Call *call) {
+    // Mark glGetError() = GL_NO_ERROR as verbose
+    if (call->sig == glGetErrorSig &&
+        call->ret &&
+        call->ret->toSInt() == 0) {
+        call->flags |= CALL_FLAG_VERBOSE;
+    }
+}
+
 void Parser::parse_arg(Call *call, Mode mode) {
     unsigned index = read_uint();
     Value *value = parse_value(mode);
@@ -405,47 +439,47 @@ Value *Parser::parse_value(void) {
     int c;
     Value *value;
     c = read_byte();
-    switch(c) {
-    case Trace::TYPE_NULL:
+    switch (c) {
+    case trace::TYPE_NULL:
         value = new Null;
         break;
-    case Trace::TYPE_FALSE:
+    case trace::TYPE_FALSE:
         value = new Bool(false);
         break;
-    case Trace::TYPE_TRUE:
+    case trace::TYPE_TRUE:
         value = new Bool(true);
         break;
-    case Trace::TYPE_SINT:
+    case trace::TYPE_SINT:
         value = parse_sint();
         break;
-    case Trace::TYPE_UINT:
+    case trace::TYPE_UINT:
         value = parse_uint();
         break;
-    case Trace::TYPE_FLOAT:
+    case trace::TYPE_FLOAT:
         value = parse_float();
         break;
-    case Trace::TYPE_DOUBLE:
+    case trace::TYPE_DOUBLE:
         value = parse_double();
         break;
-    case Trace::TYPE_STRING:
+    case trace::TYPE_STRING:
         value = parse_string();
         break;
-    case Trace::TYPE_ENUM:
+    case trace::TYPE_ENUM:
         value = parse_enum();
         break;
-    case Trace::TYPE_BITMASK:
+    case trace::TYPE_BITMASK:
         value = parse_bitmask();
         break;
-    case Trace::TYPE_ARRAY:
+    case trace::TYPE_ARRAY:
         value = parse_array();
         break;
-    case Trace::TYPE_STRUCT:
+    case trace::TYPE_STRUCT:
         value = parse_struct();
         break;
-    case Trace::TYPE_BLOB:
+    case trace::TYPE_BLOB:
         value = parse_blob();
         break;
-    case Trace::TYPE_OPAQUE:
+    case trace::TYPE_OPAQUE:
         value = parse_opaque();
         break;
     default:
@@ -466,42 +500,42 @@ Value *Parser::parse_value(void) {
 
 void Parser::scan_value(void) {
     int c = read_byte();
-    switch(c) {
-    case Trace::TYPE_NULL:
-    case Trace::TYPE_FALSE:
-    case Trace::TYPE_TRUE:
+    switch (c) {
+    case trace::TYPE_NULL:
+    case trace::TYPE_FALSE:
+    case trace::TYPE_TRUE:
         break;
-    case Trace::TYPE_SINT:
+    case trace::TYPE_SINT:
         scan_sint();
         break;
-    case Trace::TYPE_UINT:
+    case trace::TYPE_UINT:
         scan_uint();
         break;
-    case Trace::TYPE_FLOAT:
+    case trace::TYPE_FLOAT:
         scan_float();
         break;
-    case Trace::TYPE_DOUBLE:
+    case trace::TYPE_DOUBLE:
         scan_double();
         break;
-    case Trace::TYPE_STRING:
+    case trace::TYPE_STRING:
         scan_string();
         break;
-    case Trace::TYPE_ENUM:
+    case trace::TYPE_ENUM:
         scan_enum();
         break;
-    case Trace::TYPE_BITMASK:
+    case trace::TYPE_BITMASK:
         scan_bitmask();
         break;
-    case Trace::TYPE_ARRAY:
+    case trace::TYPE_ARRAY:
         scan_array();
         break;
-    case Trace::TYPE_STRUCT:
+    case trace::TYPE_STRUCT:
         scan_struct();
         break;
-    case Trace::TYPE_BLOB:
+    case trace::TYPE_BLOB:
         scan_blob();
         break;
-    case Trace::TYPE_OPAQUE:
+    case trace::TYPE_OPAQUE:
         scan_opaque();
         break;
     default:
@@ -548,7 +582,7 @@ void Parser::scan_float() {
 Value *Parser::parse_double() {
     double value;
     file->read(&value, sizeof value);
-    return new Float(value);
+    return new Double(value);
 }
 
 
@@ -728,4 +762,4 @@ inline void Parser::skip_byte(void) {
 }
 
 
-} /* namespace Trace */
+} /* namespace trace */