X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=trace_model.cpp;h=c74aaaeee998d3c6afdf51543cd1ab8652e0886f;hb=c97fadc5c37a0464c59165d9bb1b85ca494b7d63;hp=2e20b243852b3a4475a967fbd9581edb7fa52000;hpb=19828970d2187334cae82f239f788b9f3a3912c6;p=apitrace diff --git a/trace_model.cpp b/trace_model.cpp index 2e20b24..c74aaae 100644 --- a/trace_model.cpp +++ b/trace_model.cpp @@ -31,17 +31,116 @@ namespace Trace { -void Null::visit(Visitor &visitor) { visitor.visit(this); } -void Bool::visit(Visitor &visitor) { visitor.visit(this); } -void SInt::visit(Visitor &visitor) { visitor.visit(this); } -void UInt::visit(Visitor &visitor) { visitor.visit(this); } -void Float::visit(Visitor &visitor) { visitor.visit(this); } -void String::visit(Visitor &visitor) { visitor.visit(this); } -void Enum::visit(Visitor &visitor) { visitor.visit(this); } -void Bitmask::visit(Visitor &visitor) { visitor.visit(this); } -void Struct::visit(Visitor &visitor) { visitor.visit(this); } -void Array::visit(Visitor &visitor) { visitor.visit(this); } -void Blob::visit(Visitor &visitor) { visitor.visit(this); } +Call::~Call() { + for (unsigned i = 0; i < args.size(); ++i) { + delete args[i]; + } + + if (ret) { + delete ret; + } +} + + +Struct::~Struct() { + for (std::vector::iterator it = members.begin(); it != members.end(); ++it) { + delete *it; + } +} + + +Array::~Array() { + for (std::vector::iterator it = values.begin(); it != values.end(); ++it) { + delete *it; + } +} + +Blob::~Blob() { + // TODO: Don't leak blobs. Blobs are often bound and accessed during many + // calls, so we can't delete them here. + //delete [] buf; +} + + +// bool cast +Null ::operator bool(void) const { return false; } +Bool ::operator bool(void) const { return value; } +SInt ::operator bool(void) const { return value != 0; } +UInt ::operator bool(void) const { return value != 0; } +Float ::operator bool(void) const { return value != 0; } +String ::operator bool(void) const { return true; } +Enum ::operator bool(void) const { return static_cast(*sig->second); } +Struct ::operator bool(void) const { return true; } +Array ::operator bool(void) const { return true; } +Blob ::operator bool(void) const { return true; } +Pointer::operator bool(void) const { return value != 0; } + + +// signed integer cast +Value ::operator signed long long (void) const { assert(0); return 0; } +Null ::operator signed long long (void) const { return 0; } +Bool ::operator signed long long (void) const { return static_cast(value); } +SInt ::operator signed long long (void) const { return value; } +UInt ::operator signed long long (void) const { assert(static_cast(value) >= 0); return static_cast(value); } +Float ::operator signed long long (void) const { return static_cast(value); } +Enum ::operator signed long long (void) const { return static_cast(*sig->second); } + + +// unsigned integer cast +Value ::operator unsigned long long (void) const { assert(0); return 0; } +Null ::operator unsigned long long (void) const { return 0; } +Bool ::operator unsigned long long (void) const { return static_cast(value); } +SInt ::operator unsigned long long (void) const { assert(value >= 0); return static_cast(value); } +UInt ::operator unsigned long long (void) const { return value; } +Float ::operator unsigned long long (void) const { return static_cast(value); } +Enum ::operator unsigned long long (void) const { return static_cast(*sig->second); } + + +// floating point cast +Value ::operator double (void) const { assert(0); return 0; } +Null ::operator double (void) const { return 0; } +Bool ::operator double (void) const { return static_cast(value); } +SInt ::operator double (void) const { return static_cast(value); } +UInt ::operator double (void) const { return static_cast(value); } +Float ::operator double (void) const { return value; } +Enum ::operator double (void) const { return static_cast(*sig->second); } + + +// blob cast +void * Value ::blob(void) const { assert(0); return NULL; } +void * Null ::blob(void) const { return NULL; } +void * Blob ::blob(void) const { return buf; } +void * Pointer::blob(void) const { assert(value < 0x100000ULL); return (void *)value; } + + +// virtual Value::visit() +void Null ::visit(Visitor &visitor) { visitor.visit(this); } +void Bool ::visit(Visitor &visitor) { visitor.visit(this); } +void SInt ::visit(Visitor &visitor) { visitor.visit(this); } +void UInt ::visit(Visitor &visitor) { visitor.visit(this); } +void Float ::visit(Visitor &visitor) { visitor.visit(this); } +void String ::visit(Visitor &visitor) { visitor.visit(this); } +void Enum ::visit(Visitor &visitor) { visitor.visit(this); } +void Bitmask::visit(Visitor &visitor) { visitor.visit(this); } +void Struct ::visit(Visitor &visitor) { visitor.visit(this); } +void Array ::visit(Visitor &visitor) { visitor.visit(this); } +void Blob ::visit(Visitor &visitor) { visitor.visit(this); } +void Pointer::visit(Visitor &visitor) { visitor.visit(this); } + + +void Visitor::visit(Null *) { assert(0); } +void Visitor::visit(Bool *) { assert(0); } +void Visitor::visit(SInt *) { assert(0); } +void Visitor::visit(UInt *) { assert(0); } +void Visitor::visit(Float *) { assert(0); } +void Visitor::visit(String *) { assert(0); } +void Visitor::visit(Enum *node) { _visit(node->sig->second); } +void Visitor::visit(Bitmask *node) { visit(static_cast(node)); } +void Visitor::visit(Struct *) { assert(0); } +void Visitor::visit(Array *) { assert(0); } +void Visitor::visit(Blob *) { assert(0); } +void Visitor::visit(Pointer *) { assert(0); } + class Dumper : public Visitor { @@ -97,11 +196,39 @@ public: } void visit(String *node) { - os << literal << '"' << node->value << '"' << normal; + os << literal << "\""; + for (std::string::const_iterator it = node->value.begin(); it != node->value.end(); ++it) { + unsigned char c = (unsigned char) *it; + if (c == '\"') + os << "\\\""; + else if (c == '\\') + os << "\\\\"; + else if (c >= 0x20 && c <= 0x7e) + os << c; + else if (c == '\t') { + os << "\t"; + } else if (c == '\r') { + // Ignore carriage-return + } else if (c == '\n') { + // Reset formatting so that it looks correct with 'less -R' + os << normal << '\n' << literal; + } else { + unsigned octal0 = c & 0x7; + unsigned octal1 = (c >> 3) & 0x7; + unsigned octal2 = (c >> 3) & 0x7; + os << "\\"; + if (octal2) + os << octal2; + if (octal1) + os << octal1; + os << octal0; + } + } + os << "\"" << normal; } void visit(Enum *node) { - os << literal << node->name << normal; + os << literal << node->sig->first << normal; } void visit(Bitmask *bitmask) { @@ -123,7 +250,7 @@ public: if (!first) { os << " | "; } - os << literal << std::hex << value << std::dec << normal; + os << literal << "0x" << std::hex << value << std::dec << normal; } } @@ -159,6 +286,10 @@ public: os << pointer << "blob(" << blob->size << ")" << normal; } + void visit(Pointer *p) { + os << pointer << "0x" << std::hex << p->value << std::dec << normal; + } + void visit(Call *call) { const char *sep = ""; os << bold << call->sig->name << normal << "("; @@ -189,45 +320,11 @@ std::ostream & operator <<(std::ostream &os, Value *value) { static inline const Value *unwrap(const Value *node) { const Enum *c = dynamic_cast(node); if (c) - return c->value; + return c->sig->second; return node; } -Value::operator bool(void) const { - const Bool *b = dynamic_cast(unwrap(this)); - if (b) - return b->value; - assert(0); - return false; -} - -Value::operator signed long long(void) const { - const SInt *sint = dynamic_cast(unwrap(this)); - if (sint) - return sint->value; - const UInt *uint = dynamic_cast(unwrap(this)); - if (uint) - return uint->value; - assert(0); - return 0; -} - -Value::operator unsigned long long(void) const { - const UInt *uint = dynamic_cast(unwrap(this)); - if (uint) - return uint->value; - assert(0); - return 0; -} - - -Value::operator double(void) const { - const Float *fl = dynamic_cast(unwrap(this)); - assert(fl); - return fl->value; -} - static Null null; const Value & Value::operator[](size_t index) const { @@ -240,17 +337,6 @@ const Value & Value::operator[](size_t index) const { return null; } -void * Value::blob(void) const { - const Blob *blob = dynamic_cast(unwrap(this)); - if (blob) - return blob->buf; - const Null *null = dynamic_cast(unwrap(this)); - if (null) - return NULL; - assert(0); - return NULL; -} - const char * Value::string(void) const { const String *string = dynamic_cast(unwrap(this)); if (string) @@ -264,6 +350,7 @@ const char * Value::string(void) const { std::ostream & operator <<(std::ostream &os, Call &call) { Dumper d(os); + os << call.no << " "; d.visit(&call); return os; }