X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=trace_parser.hpp;h=15b0ccb9b03f0964b5ce1c5418488e23bfb5afe7;hb=3176ebeffe825a5f998b13755c09cfa312b0e8d3;hp=54796b59cc39e4291286bda57467df36cd2b6f27;hpb=f6592d7c0ca5bd095e8b8826e0a29f62865e4d34;p=apitrace diff --git a/trace_parser.hpp b/trace_parser.hpp index 54796b5..15b0ccb 100644 --- a/trace_parser.hpp +++ b/trace_parser.hpp @@ -27,246 +27,177 @@ #define _TRACE_PARSER_HPP_ -#include - #include +#include +#include -#include - +#include "trace_file.hpp" #include "trace_format.hpp" #include "trace_model.hpp" namespace Trace { - class Parser { protected: - gzFile file; + File *file; + + typedef std::list CallList; + CallList calls; + + typedef std::vector FunctionMap; + FunctionMap functions; + + typedef std::vector StructMap; + StructMap structs; + + typedef std::vector EnumMap; + EnumMap enums; + + typedef std::vector BitmaskMap; + BitmaskMap bitmasks; + + typedef std::set TraceOffsets; + TraceOffsets m_callSigOffsets; + TraceOffsets m_structSigOffsets; + TraceOffsets m_enumSigOffsets; + TraceOffsets m_bitmaskSigOffsets; + + typedef std::map CallNumOffsets; + CallNumOffsets m_callNumOffsets; + + bool m_supportsSeeking; + + unsigned next_call_no; + public: - Parser() { - file = NULL; - } - - bool parse(const char *filename) { - unsigned long long version; - - file = gzopen(filename, "rb"); - if (!file) { - return false; - } - - version = read_uint(); - if (version != TRACE_VERSION) { - std::cerr << "error: unsupported format version" << version << "\n"; - return false; - } - - while (!gzeof(file)) { - parse_call(); - } - - return true; - } - - void parse_call(void) { - Call call; - call.name = read_string(); - int c; - do { - c = gzgetc(file); - if (c == Trace::CALL_END || c == -1) { - break; - } - switch(c) { - case Trace::CALL_END: - return; - case Trace::CALL_ARG: - call.args.push_back(parse_arg()); - break; - case Trace::CALL_RET: - call.ret = parse_value(); - break; - default: - std::cerr << "error: unknown call detail " << c << "\n"; - assert(0); - break; - } - } while(true); - handle_call(call); - } - - virtual void handle_call(Call &call) { - std::cout << call; - } - - Arg parse_arg(void) { - std::string name = read_string(); - Value *value = parse_value(); - return Arg(name, value); - } - - Value *parse_value(void) { - int c; - c = gzgetc(file); - switch(c) { - case Trace::TYPE_NULL: - return new Null; - case Trace::TYPE_FALSE: - return new Bool(false); - case Trace::TYPE_TRUE: - return new Bool(true); - case Trace::TYPE_SINT: - return parse_sint(); - case Trace::TYPE_UINT: - return parse_uint(); - case Trace::TYPE_FLOAT: - return parse_float(); - case Trace::TYPE_DOUBLE: - return parse_double(); - case Trace::TYPE_STRING: - return parse_string(); - case Trace::TYPE_CONST: - return parse_const(); - case Trace::TYPE_BITMASK: - return parse_bitmask(); - case Trace::TYPE_ARRAY: - return parse_array(); - case Trace::TYPE_BLOB: - return parse_blob(); - case Trace::TYPE_POINTER: - return parse_pointer(); - case Trace::TYPE_OPAQUE: - return parse_opaque(); - default: - std::cerr << "error: unknown type " << c << "\n"; - assert(0); - return NULL; - } - } - - Value *parse_bool() { - int c; - c = gzgetc(file); - return new Bool(c); - } - - Value *parse_sint() { - return new SInt(-read_uint()); - } - - Value *parse_uint() { - return new UInt(read_uint()); - } - - Value *parse_float() { - float value; - gzread(file, &value, sizeof value); - return new Float(value); - } - - Value *parse_double() { - double value; - gzread(file, &value, sizeof value); - return new Float(value); - } - - Value *parse_string() { - return new String(read_string()); - } - - Value *parse_const() { - std::string name = read_string(); - Value *value = parse_value(); - return new Const(name, value); - } - - Value *parse_bitmask() { - unsigned long long value = 0; - int c; - do { - c = gzgetc(file); - switch(c) { - case Trace::TYPE_SINT: - value |= -read_uint(); - break; - case Trace::TYPE_UINT: - value |= read_uint(); - break; - case Trace::TYPE_CONST: - read_string(); - break; - case Trace::TYPE_NULL: - goto done; - default: - std::cerr << "error: uexpected type " << c << "\n"; - assert(0); - return NULL; - } - } while(true); -done: - return new UInt(value); - } - - Value *parse_array(void) { - size_t len = read_uint(); - Array *array = new Array(len); - for (size_t i = 0; i < len; ++i) { - array->values[i] = parse_value(); - } - return array; - } - - Value *parse_blob(void) { - size_t size = read_uint(); - Blob *blob = new Blob(size); - if (size) { - gzread(file, blob->buf, size); - } - return blob; - } - - Value *parse_pointer() { - unsigned long long addr; - Value *value; - addr = read_uint(); - value = parse_value(); - if (!value) - value = new UInt(addr); - return value; - } - - Value *parse_opaque() { - unsigned long long addr; - addr = read_uint(); - /* XXX */ - return new UInt(addr); - } - - std::string read_string(void) { - size_t len = read_uint(); - char * buf = new char[len]; - gzread(file, buf, len); - std::string value(buf, len); - delete [] buf; - return value; - } - - unsigned long long read_uint(void) { - unsigned long long value = 0; - int c; - unsigned shift = 0; - do { - c = gzgetc(file); - if (c == -1) { - break; - } - value |= (unsigned long long)(c & 0x7f) << shift; - shift += 7; - } while(c & 0x80); - return value; - } + unsigned long long version; + + Parser(); + + ~Parser(); + + bool open(const char *filename); + + void close(void); + + Call *parse_call(void); + + bool supportsOffsets() const + { + return file->supportsOffsets(); + } + + File::Offset currentOffset() + { + return file->currentOffset(); + } + + void setCurrentOffset(const File::Offset &offset) + { + file->setCurrentOffset(offset); + } + + bool callWithSignature(const File::Offset &offset) const; + bool structWithSignature(const File::Offset &offset) const; + bool enumWithSignature(const File::Offset &offset) const; + bool bitmaskWithSignature(const File::Offset &offset) const; + + unsigned currentCallNumber() const + { + return next_call_no; + } + + void setCurrentCallNumber(unsigned num) + { + next_call_no = num; + } + + int percentRead() + { + return file->percentRead(); + } + + Call *scan_call(); + +protected: + void parse_enter(void); + + Call *parse_leave(void); + + bool parse_call_details(Call *call); + + void parse_arg(Call *call); + + Value *parse_value(void); + + Value *parse_sint(); + + Value *parse_uint(); + + Value *parse_float(); + + Value *parse_double(); + + Value *parse_string(); + + Value *parse_enum(); + + Value *parse_bitmask(); + + Value *parse_array(void); + + Value *parse_blob(void); + + Value *parse_struct(); + + Value *parse_opaque(); + + const char * read_string(void); + + unsigned long long read_uint(void); + + inline int read_byte(void); + +protected: + void scan_enter(void); + + Call *scan_leave(void); + + bool scan_call_details(Call *call); + + void scan_arg(Call *call); + + void scan_value(void); + + void scan_sint(); + + void scan_uint(); + + void scan_float(); + + void scan_double(); + + void scan_string(); + + void scan_enum(); + + void scan_bitmask(); + + void scan_array(void); + + void scan_blob(void); + + void scan_struct(); + + void scan_opaque(); + + void skip_string(void); + + void skip_uint(void); + + inline void skip_byte(void); };