X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=cli%2Fcli_pickle.cpp;h=3a9129f8782d0f4a1dc7b2d81616c37c0654e273;hb=3801952b80cd7a7160f6410518f6e3740d461b60;hp=8fdcd448afb9f4cafec24dffc187f0b4fb27e0f0;hpb=589a579c395bd9d49e82cd94d7c20faaa550f400;p=apitrace diff --git a/cli/cli_pickle.cpp b/cli/cli_pickle.cpp index 8fdcd44..3a9129f 100644 --- a/cli/cli_pickle.cpp +++ b/cli/cli_pickle.cpp @@ -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; }