]> git.cworth.org Git - apitrace/blobdiff - cli/cli_pickle.cpp
Update downloads link.
[apitrace] / cli / cli_pickle.cpp
index 8fdcd448afb9f4cafec24dffc187f0b4fb27e0f0..3a9129f8782d0f4a1dc7b2d81616c37c0654e273 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) {
@@ -110,13 +145,21 @@ public:
     }
 
     void visit(Blob *node) {
-        writer.writeString((const char *)node->buf, node->size);
+        writer.writeByteArray(node->buf, node->size);
     }
 
     void visit(Pointer *node) {
         writer.writeInt(node->value);
     }
 
+    void visit(Repr *r) {
+        if (symbolic) {
+            _visit(r->humanValue);
+        } else {
+            _visit(r->machineValue);
+        }
+    }
+
     void visit(Call *call) {
         writer.beginTuple();
 
@@ -157,6 +200,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 +210,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 +223,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,22 +245,25 @@ command(int argc, char *argv[])
     }
 
     os::setBinaryMode(stdout);
+    
+    std::cout.sync_with_stdio(false);
+
+    PickleWriter writer(std::cout);
+    PickleVisitor visitor(writer, symbolic);
 
     for (int i = optind; i < argc; ++i) {
         trace::Parser parser;
 
         if (!parser.open(argv[i])) {
-            std::cerr << "error: failed to open " << argv[i] << "\n";
             return 1;
         }
 
         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;
         }