}
-Call *Parser::parse_call(void) {
+Call *Parser::parse_call(Mode mode) {
do {
int c = read_byte();
switch(c) {
case Trace::EVENT_ENTER:
- parse_enter();
+ parse_enter(mode);
break;
case Trace::EVENT_LEAVE:
- return parse_leave();
+ return parse_leave(mode);
default:
std::cerr << "error: unknown event " << c << "\n";
exit(1);
}
-Call * Parser::scan_call()
-{
- do {
- int c = read_byte();
- switch(c) {
- case Trace::EVENT_ENTER:
- scan_enter();
- break;
- case Trace::EVENT_LEAVE:
- return scan_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";
- }
- return NULL;
- }
- } while (true);
-}
-
-
/**
* Helper function to lookup an ID in a vector, resizing the vector if it doesn't fit.
*/
}
-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)) {
+ if (parse_call_details(call, mode)) {
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)) {
- calls.push_back(call);
- } else {
- delete call;
- }
-}
-
-
-Call *Parser::parse_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 (parse_call_details(call)) {
- return call;
- } else {
- delete call;
- return NULL;
- }
-}
-
-
-Call *Parser::scan_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 (scan_call_details(call)) {
+ if (parse_call_details(call, mode)) {
return call;
} else {
delete call;
}
-bool Parser::parse_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:
- parse_arg(call);
+ parse_arg(call, mode);
break;
case Trace::CALL_RET:
- call->ret = parse_value();
+ call->ret = parse_value(mode);
break;
default:
std::cerr << "error: ("<<call->name()<< ") unknown call detail "
}
-bool Parser::scan_call_details(Call *call) {
- do {
- int c = read_byte();
- switch(c) {
- case Trace::CALL_END:
- return true;
- case Trace::CALL_ARG:
- scan_arg(call);
- break;
- case Trace::CALL_RET:
- scan_value();
- break;
- default:
- std::cerr << "error: ("<<call->name()<< ") unknown call detail "
- << c << "\n";
- exit(1);
- case -1:
- return false;
- }
- } while(true);
-}
-
-
-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 */
}
protected:
File *file;
+ enum Mode {
+ FULL = 0,
+ SCAN,
+ SKIP
+ };
+
typedef std::list<Call *> CallList;
CallList calls;
void close(void);
- Call *parse_call(void);
+ Call *parse_call(void) {
+ return parse_call(FULL);
+ }
bool supportsOffsets() const
{
return file->percentRead();
}
- Call *scan_call();
+ Call *scan_call() {
+ return parse_call(SCAN);
+ }
protected:
+ Call *parse_call(Mode mode);
+
FunctionSig *parse_function_sig(void);
StructSig *parse_struct_sig();
EnumSig *parse_enum_sig();
BitmaskSig *parse_bitmask_sig();
+
+ Call *parse_Call(Mode mode);
- void parse_enter(void);
- void scan_enter(void);
+ void parse_enter(Mode mode);
- Call *parse_leave(void);
- Call *scan_leave(void);
+ Call *parse_leave(Mode mode);
- bool parse_call_details(Call *call);
- bool scan_call_details(Call *call);
+ bool parse_call_details(Call *call, Mode mode);
- void parse_arg(Call *call);
- void scan_arg(Call *call);
+ void parse_arg(Call *call, Mode mode);
Value *parse_value(void);
void scan_value(void);
+ inline Value *parse_value(Mode mode) {
+ if (mode == FULL) {
+ return parse_value();
+ } else {
+ scan_value();
+ return NULL;
+ }
+ }
Value *parse_sint();
void scan_sint();