]> git.cworth.org Git - apitrace/blobdiff - trace_parser.cpp
Implement trace saving.
[apitrace] / trace_parser.cpp
index a7268af288f4248710fed201efd517e2c04103a9..d7b20d2c450faaab61cc986c6c046b72df5a4caa 100644 (file)
@@ -98,10 +98,56 @@ void Parser::close(void) {
     }
 
     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.
+
+    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];
+            }
+            delete [] sig->arg_names;
+            delete sig;
+        }
+    }
+    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();
 }
 
 
@@ -114,18 +160,21 @@ void Parser::getBookmark(ParseBookmark &bookmark) {
 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(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);
@@ -140,30 +189,6 @@ Call *Parser::parse_call(void) {
 }
 
 
-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.
  */
@@ -303,28 +328,14 @@ BitmaskSig *Parser::parse_bitmask_sig() {
 }
 
 
-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;
@@ -332,7 +343,7 @@ void Parser::scan_enter(void) {
 }
 
 
-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) {
@@ -346,7 +357,7 @@ Call *Parser::parse_leave(void) {
         return NULL;
     }
 
-    if (parse_call_details(call)) {
+    if (parse_call_details(call, mode)) {
         return call;
     } else {
         delete call;
@@ -355,63 +366,17 @@ Call *Parser::parse_leave(void) {
 }
 
 
-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 "
@@ -424,19 +389,15 @@ bool Parser::scan_call_details(Call *call) {
 }
 
 
-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 */
 }