]> git.cworth.org Git - apitrace/blobdiff - common/trace_dump.cpp
Replace dynamic_cast with virtual functions.
[apitrace] / common / trace_dump.cpp
index 6b2fdc30aa96e53affe20aabbe67e7f62583362c..6e67e08ab53e0f2585d5a1e952b9d00bae220b02 100644 (file)
@@ -24,6 +24,8 @@
  **************************************************************************/
 
 
+#include <limits>
+
 #include "formatter.hpp"
 #include "trace_dump.hpp"
 
@@ -73,7 +75,7 @@ public:
     }
 
     void visit(Null *) {
-        os << "NULL";
+        os << literal << "NULL" << normal;
     }
 
     void visit(Bool *node) {
@@ -89,11 +91,15 @@ public:
     }
 
     void visit(Float *node) {
+        std::streamsize oldPrecision = os.precision(std::numeric_limits<float>::digits10 + 1);
         os << literal << node->value << normal;
+        os.precision(oldPrecision);
     }
 
     void visit(Double *node) {
+        std::streamsize oldPrecision = os.precision(std::numeric_limits<double>::digits10 + 1);
         os << literal << node->value << normal;
+        os.precision(oldPrecision);
     }
 
     void visit(String *node) {
@@ -129,12 +135,10 @@ public:
     }
 
     void visit(Enum *node) {
-        const EnumSig *sig = node->sig;
-        for (const EnumValue *it = sig->values; it != sig->values + sig->num_values; ++it) {
-            if (it->value == node->value) {
-                os << literal << it->name << normal;
-                return;
-            }
+        const EnumValue *it = node->lookup();
+        if (it) {
+            os << literal << it->name << normal;
+            return;
         }
         os << literal << node->value << normal;
     }
@@ -143,7 +147,8 @@ public:
         unsigned long long value = bitmask->value;
         const BitmaskSig *sig = bitmask->sig;
         bool first = true;
-        for (const BitmaskFlag *it = sig->flags; value != 0 && it != sig->flags + sig->num_flags; ++it) {
+        for (const BitmaskFlag *it = sig->flags; it != sig->flags + sig->num_flags; ++it) {
+            assert(it->value || first);
             if ((it->value && (value & it->value) == it->value) ||
                 (!it->value && value == 0)) {
                 if (!first) {
@@ -153,6 +158,9 @@ public:
                 value &= ~it->value;
                 first = false;
             }
+            if (value == 0) {
+                break;
+            }
         }
         if (value || first) {
             if (!first) {
@@ -162,14 +170,32 @@ public:
         }
     }
 
-    void visit(Struct *s) {
-        const char *sep = "";
-        os << "{";
+    const char *
+    visitMembers(Struct *s, const char *sep = "") {
         for (unsigned i = 0; i < s->members.size(); ++i) {
-            os << sep << italic << s->sig->member_names[i] << normal << " = ";
-            _visit(s->members[i]);
+            const char *memberName = s->sig->member_names[i];
+            Value *memberValue = s->members[i];
+
+            if (!memberName || !*memberName) {
+                // Anonymous structure
+                Struct *memberStruct = memberValue->toStruct();
+                assert(memberStruct);
+                if (memberStruct) {
+                    sep = visitMembers(memberStruct, sep);
+                    continue;
+                }
+            }
+
+            os << sep << italic << memberName << normal << " = ",
+            _visit(memberValue);
             sep = ", ";
         }
+        return sep;
+    }
+
+    void visit(Struct *s) {
+        os << "{";
+        visitMembers(s);
         os << "}";
     }
 
@@ -198,8 +224,43 @@ public:
         os << pointer << "0x" << std::hex << p->value << std::dec << normal;
     }
 
+    void visit(Repr *r) {
+        _visit(r->humanValue);
+    }
+
+    void visit(StackFrame *frame) {
+        if (frame->module != NULL) {
+            os << frame->module << " ";
+        }
+        if (frame->function != NULL) {
+            os << "at " << frame->function << "() ";
+        }
+        if (frame->filename != NULL) {
+            os << "at " << frame->filename;
+            if (frame->linenumber >= 0) {
+                os << ":" << frame->linenumber << " ";
+            }
+        }
+        else {
+            if (frame->offset >= 0) {
+                os << "[" << "0x" << std::hex << frame->offset << std::dec << "]";
+            }
+        }
+    }
+
+    void visit(Backtrace & backtrace) {
+        for (int i = 0; i < backtrace.size(); i ++) {
+            visit(backtrace[i]);
+            os << "\n";
+        }
+    }
+
     void visit(Call *call) {
         CallFlags callFlags = call->flags;
+        
+        if (!(dumpFlags & DUMP_FLAG_NO_CALL_NO)) {
+            os << call->no << " ";
+        }
 
         if (callFlags & CALL_FLAG_NON_REPRODUCIBLE) {
             os << strike;
@@ -217,8 +278,8 @@ public:
             if (!(dumpFlags & DUMP_FLAG_NO_ARG_NAMES)) {
                 os << italic << call->sig->arg_names[i] << normal << " = ";
             }
-            if (call->args[i]) {
-                _visit(call->args[i]);
+            if (call->args[i].value) {
+                _visit(call->args[i].value);
             } else {
                os << "?";
             }
@@ -237,6 +298,10 @@ public:
         
         os << "\n";
 
+        if (call->backtrace != NULL) {
+            os << bold << red << "Backtrace:\n" << normal;
+            visit(*call->backtrace);
+        }
         if (callFlags & CALL_FLAG_END_FRAME) {
             os << "\n";
         }
@@ -252,7 +317,6 @@ void dump(Value *value, std::ostream &os, DumpFlags flags) {
 
 void dump(Call &call, std::ostream &os, DumpFlags flags) {
     Dumper d(os, flags);
-    os << call.no << " ";
     d.visit(&call);
 }