]> git.cworth.org Git - apitrace/commitdiff
Diff with symbolic names.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Fri, 16 Mar 2012 08:21:29 +0000 (08:21 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Fri, 16 Mar 2012 08:21:29 +0000 (08:21 +0000)
cli/cli_pickle.cpp
common/pickle.hpp
common/trace_dump.cpp
common/trace_model.hpp
scripts/tracediff2.py

index 8fdcd448afb9f4cafec24dffc187f0b4fb27e0f0..e3222dbbdc37500119a857df908c36a90244ea05 100644 (file)
@@ -47,10 +47,12 @@ class PickleVisitor : public trace::Visitor
 {
 protected:
     PickleWriter &writer;
+    bool symbolic;
 
 public:
-    PickleVisitor(PickleWriter &_writer) :
-        writer(_writer) {
+    PickleVisitor(PickleWriter &_writer, bool _symbolic) :
+        writer(_writer),
+        symbolic(_symbolic) {
     }
 
     void visit(Null *node) {
@@ -82,23 +84,56 @@ public:
     }
 
     void visit(Enum *node) {
-        // TODO: keep symbolic name
+        if (symbolic) {
+            const EnumValue *it = node->lookup();
+            if (it) {
+                writer.writeString(it->name);
+                return;
+            }
+        }
         writer.writeInt(node->value);
     }
 
     void visit(Bitmask *node) {
-        // TODO: keep symbolic name
-        writer.writeInt(node->value);
+        if (symbolic) {
+            unsigned long long value = node->value;
+            const BitmaskSig *sig = node->sig;
+            writer.beginList();
+            for (const BitmaskFlag *it = sig->flags; it != sig->flags + sig->num_flags; ++it) {
+                if ((it->value && (value & it->value) == it->value) ||
+                    (!it->value && value == 0)) {
+                    writer.writeString(it->name);
+                    value &= ~it->value;
+                }
+                if (value == 0) {
+                    break;
+                }
+            }
+            if (value) {
+                writer.writeInt(value);
+            }
+            writer.endList();
+        } else {
+            writer.writeInt(node->value);
+        }
     }
 
     void visit(Struct *node) {
-        writer.beginDict();
-        for (unsigned i = 0; i < node->sig->num_members; ++i) {
-            writer.beginItem(node->sig->member_names[i]);
-            _visit(node->members[i]);
-            writer.endItem();
+        if (false) {
+            writer.beginDict();
+            for (unsigned i = 0; i < node->sig->num_members; ++i) {
+                writer.beginItem(node->sig->member_names[i]);
+                _visit(node->members[i]);
+                writer.endItem();
+            }
+            writer.endDict();
+        } else {
+            writer.beginTuple();
+            for (unsigned i = 0; i < node->sig->num_members; ++i) {
+                _visit(node->members[i]);
+            }
+            writer.endTuple();
         }
-        writer.endDict();
     }
 
     void visit(Array *node) {
@@ -157,6 +192,7 @@ usage(void)
         << synopsis << "\n"
         "\n"
         "    -h, --help           show this help message and exit\n"
+        "    -s, --symbolic       dump symbolic names\n"
         "    --calls=CALLSET      only dump specified calls\n"
     ;
 }
@@ -166,11 +202,12 @@ enum {
 };
 
 const static char *
-shortOptions = "h";
+shortOptions = "hs";
 
 const static struct option
 longOptions[] = {
     {"help", no_argument, 0, 'h'},
+    {"symbolic", no_argument, 0, 's'},
     {"calls", required_argument, 0, CALLS_OPT},
     {0, 0, 0, 0}
 };
@@ -178,12 +215,17 @@ longOptions[] = {
 static int
 command(int argc, char *argv[])
 {
+    bool symbolic;
+
     int opt;
     while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
         switch (opt) {
         case 'h':
             usage();
             return 0;
+        case 's':
+            symbolic = true;
+            break;
         case CALLS_OPT:
             calls = trace::CallSet(optarg);
             break;
@@ -195,6 +237,9 @@ command(int argc, char *argv[])
     }
 
     os::setBinaryMode(stdout);
+    
+    PickleWriter writer(std::cout);
+    PickleVisitor visitor(writer, symbolic);
 
     for (int i = optind; i < argc; ++i) {
         trace::Parser parser;
@@ -207,10 +252,9 @@ command(int argc, char *argv[])
         trace::Call *call;
         while ((call = parser.parse_call())) {
             if (calls.contains(*call)) {
-                PickleWriter writer(std::cout);
-                PickleVisitor visitor(writer);
-                
+                writer.begin();
                 visitor.visit(call);
+                writer.end();
             }
             delete call;
         }
index f333960a7adefb31a57d48165c2da5ac753bdb6e..736025b2a1cd8b3ee6583e8bfac336b30edad876 100644 (file)
@@ -106,13 +106,15 @@ private:
 
 public:
     PickleWriter(std::ostream &_os) :
-        os(_os)
-    {
+        os(_os) {
+    }
+
+    inline void begin() {
         os.put(PROTO);
         os.put(2);
     }
 
-    ~PickleWriter() {
+    inline void end() {
         os.put(STOP);
     }
 
index c55bbb1ca324e776ad67b5cef5f72cb64376ed1e..0f7ee3656e76288ccd12caca37ec5e62394ce76b 100644 (file)
@@ -129,12 +129,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 +141,7 @@ 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) {
             if ((it->value && (value & it->value) == it->value) ||
                 (!it->value && value == 0)) {
                 if (!first) {
@@ -153,6 +151,9 @@ public:
                 value &= ~it->value;
                 first = false;
             }
+            if (value == 0) {
+                break;
+            }
         }
         if (value || first) {
             if (!first) {
index 7973026cd9b07884af719feefd3b7ed72ed1a2cc..a2fd97f4a68b2c9a425ec0196d51f292641ef581 100644 (file)
@@ -228,6 +228,17 @@ public:
     void visit(Visitor &visitor);
 
     const EnumSig *sig;
+
+    const EnumValue *
+    lookup() {
+        // TODO: use a std::map
+        for (const EnumValue *it = sig->values; it != sig->values + sig->num_values; ++it) {
+            if (it->value == value) {
+                return it;
+            }
+        }
+        return NULL;
+    }
 };
 
 
index 001f3226aaed5f117ad400e8a2f90cc2e8cc2ffb..168c7cef16e03327a34c66e53486c3d1b3763cb4 100755 (executable)
@@ -63,6 +63,7 @@ def readtrace(trace):
         args = [
             options.apitrace,
             'pickle',
+            '--symbolic',
             '--calls=' + options.calls,
             trace
         ],
@@ -129,10 +130,11 @@ class SDiffer:
             b_call = self.b[blo + i]
             assert a_call.functionName == b_call.functionName
             assert len(a_call.args) == len(b_call.args)
-            self.equal_prefix()
+            self.replace_prefix()
             self.highlighter.bold(True)
             self.highlighter.write(b_call.functionName)
             self.highlighter.bold(False)
+            self.highlighter.write('(')
             sep = ''
             for j in xrange(len(b_call.args)):
                 self.highlighter.write(sep)
@@ -206,6 +208,9 @@ class SDiffer:
 
     def normal_suffix(self):
         self.highlighter.normal()
+    
+    def replace_prefix(self):
+        self.highlighter.write('| ')
 
 
 def main():