file = NULL;
next_call_no = 0;
version = 0;
- m_supportsSeeking = false;
}
if (!file->open(filename, File::Read)) {
return false;
}
- m_supportsSeeking = file->supportsOffsets();
version = read_uint();
if (version > TRACE_VERSION) {
}
deleteAll(calls);
- deleteAll(functions);
- deleteAll(structs);
- deleteAll(enums);
- deleteAll(bitmasks);
-}
+ // Delete all signature data. Signatures are mere structures which don't
+ // own their own memory, so we need to destroy all data we created here.
-Call *Parser::parse_call(void) {
- do {
- int c = read_byte();
- switch(c) {
- case Trace::EVENT_ENTER:
- parse_enter();
- break;
- case Trace::EVENT_LEAVE:
- return parse_leave();
- default:
- std::cerr << "error: unknown event " << c << "\n";
- exit(1);
- case -1:
- for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
- std::cerr << "warning: incomplete call " << (*it)->name() << "\n";
- std::cerr << **it << "\n";
+ for (FunctionMap::iterator it = functions.begin(); it != functions.end(); ++it) {
+ FunctionSigState *sig = *it;
+ if (sig) {
+ delete [] sig->name;
+ for (unsigned arg = 0; arg < sig->num_args; ++arg) {
+ delete [] sig->arg_names[arg];
}
- return NULL;
+ delete [] sig->arg_names;
+ delete sig;
}
- } while(true);
+ }
+ functions.clear();
+
+ for (StructMap::iterator it = structs.begin(); it != structs.end(); ++it) {
+ StructSigState *sig = *it;
+ if (sig) {
+ delete [] sig->name;
+ for (unsigned member = 0; member < sig->num_members; ++member) {
+ delete [] sig->member_names[member];
+ }
+ delete [] sig->member_names;
+ delete sig;
+ }
+ }
+ structs.clear();
+
+ for (EnumMap::iterator it = enums.begin(); it != enums.end(); ++it) {
+ EnumSigState *sig = *it;
+ if (sig) {
+ delete [] sig->name;
+ delete sig;
+ }
+ }
+ enums.clear();
+
+ for (BitmaskMap::iterator it = bitmasks.begin(); it != bitmasks.end(); ++it) {
+ BitmaskSigState *sig = *it;
+ if (sig) {
+ for (unsigned flag = 0; flag < sig->num_flags; ++flag) {
+ delete [] sig->flags[flag].name;
+ }
+ delete [] sig->flags;
+ delete sig;
+ }
+ }
+ bitmasks.clear();
}
-Call * Parser::scan_call()
-{
- assert(m_supportsSeeking);
+void Parser::getBookmark(ParseBookmark &bookmark) {
+ bookmark.offset = file->currentOffset();
+ bookmark.next_call_no = next_call_no;
+}
+
+
+void Parser::setBookmark(const ParseBookmark &bookmark) {
+ file->setCurrentOffset(bookmark.offset);
+ next_call_no = bookmark.next_call_no;
+
+ // Simply ignore all pending calls
+ deleteAll(calls);
+}
+
+
+Call *Parser::parse_call(Mode mode) {
do {
int c = read_byte();
switch(c) {
case Trace::EVENT_ENTER:
- scan_enter();
+ parse_enter(mode);
break;
case Trace::EVENT_LEAVE:
- return scan_leave();
+ return parse_leave(mode);
default:
std::cerr << "error: unknown event " << c << "\n";
exit(1);
}
return NULL;
}
- } while (true);
+ } while(true);
}
}
-void Parser::parse_enter(void) {
+void Parser::parse_enter(Mode mode) {
FunctionSig *sig = parse_function_sig();
Call *call = new Call(sig);
call->no = next_call_no++;
- if (parse_call_details(call)) {
- calls.push_back(call);
- } else {
- delete call;
- }
-}
-
-
-void Parser::scan_enter(void) {
- FunctionSig *sig = parse_function_sig();
-
- Call *call = new Call(sig);
- call->no = next_call_no++;
-
- if (scan_call_details(call)) {
+ if (parse_call_details(call, mode)) {
calls.push_back(call);
} else {
delete call;
}
-Call *Parser::parse_leave(void) {
+Call *Parser::parse_leave(Mode mode) {
unsigned call_no = read_uint();
Call *call = NULL;
for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
return NULL;
}
- if (parse_call_details(call)) {
+ if (parse_call_details(call, mode)) {
return call;
} else {
delete call;
}
-Call *Parser::scan_leave(void) {
- unsigned call_no = read_uint();
- Call *call = NULL;
- for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
- if ((*it)->no == call_no) {
- call = *it;
- calls.erase(it);
- break;
- }
- }
- if (!call) {
- return NULL;
- }
-
- if (scan_call_details(call)) {
- return call;
- } else {
- delete call;
- return NULL;
- }
-}
-
-
-bool Parser::parse_call_details(Call *call) {
- do {
- int c = read_byte();
- switch(c) {
- case Trace::CALL_END:
- return true;
- case Trace::CALL_ARG:
- parse_arg(call);
- break;
- case Trace::CALL_RET:
- call->ret = parse_value();
- break;
- default:
- std::cerr << "error: ("<<call->name()<< ") unknown call detail "
- << c << "\n";
- exit(1);
- case -1:
- return false;
- }
- } while(true);
-}
-
-
-bool Parser::scan_call_details(Call *call) {
+bool Parser::parse_call_details(Call *call, Mode mode) {
do {
int c = read_byte();
switch(c) {
case Trace::CALL_END:
return true;
case Trace::CALL_ARG:
- scan_arg(call);
+ parse_arg(call, mode);
break;
case Trace::CALL_RET:
- scan_value();
+ call->ret = parse_value(mode);
break;
default:
std::cerr << "error: ("<<call->name()<< ") unknown call detail "
}
-void Parser::parse_arg(Call *call) {
+void Parser::parse_arg(Call *call, Mode mode) {
unsigned index = read_uint();
- Value *value = parse_value();
- if (index >= call->args.size()) {
- call->args.resize(index + 1);
+ Value *value = parse_value(mode);
+ if (value) {
+ if (index >= call->args.size()) {
+ call->args.resize(index + 1);
+ }
+ call->args[index] = value;
}
- call->args[index] = value;
-}
-
-
-void Parser::scan_arg(Call *call) {
- skip_uint(); /* index */
- scan_value(); /* value */
}