X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=trace_model.cpp;h=403c78ea0382c38d08fe5fdb4caef20fcfb0cb08;hb=83a1e15744d6aa49514a9b7a5c0354c3d3b059cf;hp=8f102247c5e879a703d7f13836a248c00474117e;hpb=501f286cc204a80469885da32c1ca87640ad91fc;p=apitrace diff --git a/trace_model.cpp b/trace_model.cpp index 8f10224..403c78e 100644 --- a/trace_model.cpp +++ b/trace_model.cpp @@ -24,160 +24,253 @@ **************************************************************************/ +#include "formatter.hpp" #include "trace_model.hpp" namespace Trace { -void Void::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 Const::visit(Visitor &visitor) { - visitor.visit(this); -} - -void Array::visit(Visitor &visitor) { - visitor.visit(this); -} - +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); } class Dumper : public Visitor { -public: - std::ostream &os; - - Dumper() : os(std::cout) {} - - Dumper(std::ostream &_os) : os(_os) {} - - void visit(Void *node) { - } +protected: + std::ostream &os; + Formatter::Formatter *formatter; + Formatter::Attribute *normal; + Formatter::Attribute *bold; + Formatter::Attribute *italic; + Formatter::Attribute *red; + Formatter::Attribute *pointer; + Formatter::Attribute *literal; - void visit(Bool *node) { - os << (node->value ? "true" : "false"); - } - - void visit(SInt *node) { - os << node->value; - } - - void visit(UInt *node) { - os << node->value; - } +public: + Dumper(std::ostream &_os) : os(_os) { + formatter = Formatter::defaultFormatter(); + normal = formatter->normal(); + bold = formatter->bold(); + italic = formatter->italic(); + red = formatter->color(Formatter::RED); + pointer = formatter->color(Formatter::GREEN); + literal = formatter->color(Formatter::BLUE); + } + + ~Dumper() { + delete normal; + delete bold; + delete italic; + delete red; + delete pointer; + delete literal; + delete formatter; + } + + void visit(Null *) { + os << "NULL"; + } + + void visit(Bool *node) { + os << literal << (node->value ? "true" : "false") << normal; + } + + void visit(SInt *node) { + os << literal << node->value << normal; + } + + void visit(UInt *node) { + os << literal << node->value << normal; + } + + void visit(Float *node) { + os << literal << node->value << normal; + } + + void visit(String *node) { + os << literal << '"' << node->value << '"' << normal; + } + + void visit(Enum *node) { + os << literal << node->name << normal; + } + + void visit(Bitmask *bitmask) { + unsigned long long value = bitmask->value; + const Bitmask::Signature *sig = bitmask->sig; + bool first = true; + for (Bitmask::Signature::const_iterator it = sig->begin(); value != 0 && it != sig->end(); ++it) { + assert(it->second); + if ((value & it->second) == it->second) { + if (!first) { + os << " | "; + } + os << literal << it->first << normal; + value &= ~it->second; + first = false; + } + } + if (value || first) { + if (!first) { + os << " | "; + } + os << literal << "0x" << std::hex << value << std::dec << normal; + } + } + + void visit(Struct *s) { + const char *sep = ""; + os << "{"; + for (unsigned i = 0; i < s->members.size(); ++i) { + os << sep << italic << s->sig->member_names[i] << normal << " = "; + _visit(s->members[i]); + sep = ", "; + } + os << "}"; + } + + void visit(Array *array) { + if (array->values.size() == 1) { + os << "&"; + _visit(array->values[0]); + } + else { + const char *sep = ""; + os << "{"; + for (std::vector::iterator it = array->values.begin(); it != array->values.end(); ++it) { + os << sep; + _visit(*it); + sep = ", "; + } + os << "}"; + } + } + + void visit(Blob *blob) { + 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 << "("; + for (unsigned i = 0; i < call->args.size(); ++i) { + os << sep << italic << call->sig->arg_names[i] << normal << " = "; + _visit(call->args[i]); + sep = ", "; + } + os << ")"; + if (call->ret) { + os << " = "; + _visit(call->ret); + } + os << "\n"; + } +}; - void visit(Float *node) { - os << node->value; - } - void visit(String *node) { - os << '"' << node->value << '"'; - } +std::ostream & operator <<(std::ostream &os, Value *value) { + Dumper d(os); + if (value) { + value->visit(d); + } + return os; +} - void visit(Const *node) { - os << node->name; - } - void visit(Array *node) { - const char *sep = ""; - os << "{"; - for (std::vector::iterator it = node->values.begin(); it != node->values.end(); ++it) { - os << sep; - (*it)->visit(*this); - sep = ", "; - } - os << "}"; - } -}; +static inline const Value *unwrap(const Value *node) { + const Enum *c = dynamic_cast(node); + if (c) + return c->value; + return node; +} -std::ostream & operator <<(std::ostream &os, Value *value) { - Dumper d(os); - if (value) { - value->visit(d); - } - return os; +Value::operator bool(void) const { + const Bool *b = dynamic_cast(unwrap(this)); + if (b) + return b->value; + assert(0); + return false; } - -static const Value *unwrap(const Value &node) { - const Const *c = dynamic_cast(&node); - if (c) - return c->value; - return &node; +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; } -signed long long asSInt(const Value &node) { - const SInt *sint = dynamic_cast(unwrap(node)); - if (sint) - return sint->value; - const UInt *uint = dynamic_cast(unwrap(node)); - 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; } -unsigned long long asUInt(const Value &node) { - const UInt *uint = dynamic_cast(unwrap(node)); - 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; -double asFloat(const Value &node) { - const Float *fl = dynamic_cast(unwrap(node)); - assert(fl); - return fl->value; +const Value & Value::operator[](size_t index) const { + const Array *array = dynamic_cast(unwrap(this)); + if (array) { + if (index < array->values.size()) { + return *array->values[index]; + } + } + return null; } -static Void void_; +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; +} -Value & Call::arg(const char *name) { - for (std::list::iterator it = args.begin(); it != args.end(); ++it) { - if (it->first == name) { - return *it->second; - } - } - return void_; +const char * Value::string(void) const { + const String *string = dynamic_cast(unwrap(this)); + if (string) + return string->value.c_str(); + const Null *null = dynamic_cast(unwrap(this)); + if (null) + return NULL; + assert(0); + return NULL; } std::ostream & operator <<(std::ostream &os, Call &call) { - const char *sep = ""; - os << call.name << "("; - for (std::list::iterator it = call.args.begin(); it != call.args.end(); ++it) { - os << sep << it->first << " = " << it->second; - sep = ", "; - } - os << ")"; - if (call.ret) { - os << " = " << call.ret; - } - os << "\n"; - return os; + Dumper d(os); + d.visit(&call); + return os; }