typedef std::map<unsigned, Call *> callmap;
callmap calls;
+ typedef std::map<size_t, Call::Signature *> FunctionMap;
+ FunctionMap functions;
+
+ typedef std::map<size_t, Enum *> EnumMap;
+ EnumMap enums;
+
+ typedef std::map<size_t, Bitmask::Signature *> BitmaskMap;
+ BitmaskMap bitmasks;
+
unsigned next_call_no;
public:
}
void parse_enter(void) {
- Call *call = new Call;
+ size_t id = read_uint();
+
+ Call::Signature *sig;
+ FunctionMap::const_iterator it = functions.find(id);
+ if (it == functions.end()) {
+ sig = new Call::Signature;
+ sig->name = read_string();
+ unsigned size = read_uint();
+ for (unsigned i = 0; i < size; ++i) {
+ sig->arg_names.push_back(read_string());
+ }
+ functions[id] = sig;
+ } else {
+ sig = it->second;
+ }
+ assert(sig);
+
+ Call *call = new Call(sig);
call->no = next_call_no++;
- call->name = read_name();
+
parse_call_details(call);
calls[call->no] = call;
}
void parse_arg(Call *call) {
unsigned index = read_uint();
- std::string name = read_name();
Value *value = parse_value();
if (index >= call->args.size()) {
call->args.resize(index + 1);
}
- call->args[index] = Arg(name, value);
+ call->args[index] = value;
}
Value *parse_value(void) {
return parse_double();
case Trace::TYPE_STRING:
return parse_string();
- case Trace::TYPE_CONST:
- return parse_const();
+ case Trace::TYPE_ENUM:
+ return parse_enum();
case Trace::TYPE_BITMASK:
return parse_bitmask();
case Trace::TYPE_ARRAY:
return new String(read_string());
}
- Value *parse_const() {
- std::string name = read_name();
- Value *value = parse_value();
- return new Const(name, value);
+ Value *parse_enum() {
+ size_t id = read_uint();
+ Enum *sig;
+ EnumMap::const_iterator it = enums.find(id);
+ if (it == enums.end()) {
+ std::string name = read_string();
+ Value *value = parse_value();
+ sig = new Enum(name, value);
+ enums[id] = sig;
+ } else {
+ sig = it->second;
+ }
+ assert(sig);
+ return sig;
}
Value *parse_bitmask() {
- unsigned long long value = 0;
- int c;
- do {
- c = read_byte();
- switch(c) {
- case Trace::TYPE_SINT:
- value |= -(signed long long)read_uint();
- break;
- case Trace::TYPE_UINT:
- value |= read_uint();
- break;
- case Trace::TYPE_CONST:
- read_name();
- 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);
+ size_t id = read_uint();
+ Bitmask::Signature *sig;
+ BitmaskMap::const_iterator it = bitmasks.find(id);
+ if (it == bitmasks.end()) {
+ size_t size = read_uint();
+ sig = new Bitmask::Signature(size);
+ for (Bitmask::Signature::iterator it = sig->begin(); it != sig->end(); ++it) {
+ it->first = read_string();
+ it->second = read_uint();
+ assert(it->second);
+ }
+ bitmasks[id] = sig;
+ } else {
+ sig = it->second;
+ }
+ assert(sig);
+
+ unsigned long long value = read_uint();
+
+ return new Bitmask(sig, value);
}
Value *parse_array(void) {