[nemiver] Fix MI parsing error with Archer (Closes: #575660)
- From: Dodji Seketeli <dodji src gnome org>
- To: svn-commits-list gnome org
- Subject: [nemiver] Fix MI parsing error with Archer (Closes: #575660)
- Date: Wed, 18 Mar 2009 05:16:14 -0400 (EDT)
commit 069522f162a859762b1183eec0e0b89a70241033
Author: Dodji Seketeli <dodji redhat com>
Date: Wed Mar 18 10:08:13 2009 +0100
Fix MI parsing error with Archer (Closes: #575660)
* src/dbgengine/nmv-gdbmi-parser.cc(GDBMIParser::parse_threads_list):
Parse the new "current-thread-id" RESULT even though we don't use it
for now. Be more robust wrt unknown RESULT entries as well.
* tests/test-gdbmi.cc: Add new test.
---
src/dbgengine/nmv-gdbmi-parser.cc | 134 ++++++++++++++++++++----------------
tests/test-gdbmi.cc | 5 ++
2 files changed, 79 insertions(+), 60 deletions(-)
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index 802a991..741051b 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -5096,71 +5096,85 @@ GDBMIParser::parse_threads_list (UString::size_type a_from,
}
GDBMIResultSafePtr gdbmi_result;
- if (!parse_gdbmi_result (cur, cur, gdbmi_result)) {
- LOG_PARSING_ERROR2 (cur);
- return false;
- }
- if (RAW_CHAR_AT (cur) != ',') {
- LOG_PARSING_ERROR2 (cur);
- return false;
- }
- ++cur;
- CHECK_END2 (cur);
-
- if (gdbmi_result->variable () != "thread-ids") {
- LOG_ERROR ("expected gdbmi variable 'thread-ids', got: '"
- << gdbmi_result->variable () << "\'");
- return false;
- }
- THROW_IF_FAIL (gdbmi_result->value ());
- THROW_IF_FAIL ((gdbmi_result->value ()->content_type ()
- == GDBMIValue::TUPLE_TYPE)
- ||
- (gdbmi_result->value ()->content_type ()
- == GDBMIValue::EMPTY_TYPE));
-
- GDBMITupleSafePtr gdbmi_tuple;
- if (gdbmi_result->value ()->content_type ()
- != GDBMIValue::EMPTY_TYPE) {
- gdbmi_tuple = gdbmi_result->value ()->get_tuple_content ();
- THROW_IF_FAIL (gdbmi_tuple);
- }
-
- list<GDBMIResultSafePtr> result_list;
- if (gdbmi_tuple) {
- result_list = gdbmi_tuple->content ();
- }
- list<GDBMIResultSafePtr>::const_iterator it;
- int thread_id=0;
std::list<int> thread_ids;
- for (it = result_list.begin (); it != result_list.end (); ++it) {
- THROW_IF_FAIL (*it);
- if ((*it)->variable () != "thread-id") {
- LOG_ERROR ("expected a gdbmi value with variable name 'thread-id'"
- ". Got '" << (*it)->variable () << "'");
+ unsigned int num_threads = 0, current_thread_id = 0;
+
+ // We loop, parsing GDB/MI RESULT constructs and ',' until we reach '\n'
+ while (true) {
+ if (!parse_gdbmi_result (cur, cur, gdbmi_result)) {
+ LOG_PARSING_ERROR2 (cur);
return false;
}
- THROW_IF_FAIL ((*it)->value ()
- && ((*it)->value ()->content_type ()
- == GDBMIValue::STRING_TYPE));
- thread_id = atoi ((*it)->value ()->get_string_content ().c_str ());
- THROW_IF_FAIL (thread_id);
- thread_ids.push_back (thread_id);
- }
+ if (gdbmi_result->variable () == "thread-ids") {
+ // We've got a RESULT which variable is "thread-ids", we expect
+ // the value to be tuple of RESULTs of the form
+ // thread-id="<thread-id>"
+ THROW_IF_FAIL (gdbmi_result->value ());
+ THROW_IF_FAIL ((gdbmi_result->value ()->content_type ()
+ == GDBMIValue::TUPLE_TYPE)
+ ||
+ (gdbmi_result->value ()->content_type ()
+ == GDBMIValue::EMPTY_TYPE));
+
+ GDBMITupleSafePtr gdbmi_tuple;
+ if (gdbmi_result->value ()->content_type ()
+ != GDBMIValue::EMPTY_TYPE) {
+ gdbmi_tuple = gdbmi_result->value ()->get_tuple_content ();
+ THROW_IF_FAIL (gdbmi_tuple);
+ }
- if (!parse_gdbmi_result (cur, cur, gdbmi_result)) {
- LOG_PARSING_ERROR2 (cur);
- return false;
- }
- if (gdbmi_result->variable () != "number-of-threads") {
- LOG_PARSING_ERROR2 (cur);
- return false;
+ list<GDBMIResultSafePtr> result_list;
+ if (gdbmi_tuple) {
+ result_list = gdbmi_tuple->content ();
+ }
+ list<GDBMIResultSafePtr>::const_iterator it;
+ int thread_id=0;
+ for (it = result_list.begin (); it != result_list.end (); ++it) {
+ THROW_IF_FAIL (*it);
+ if ((*it)->variable () != "thread-id") {
+ LOG_ERROR ("expected a gdbmi value with "
+ "variable name 'thread-id'. "
+ "Got '" << (*it)->variable () << "'");
+ return false;
+ }
+ THROW_IF_FAIL ((*it)->value ()
+ && ((*it)->value ()->content_type ()
+ == GDBMIValue::STRING_TYPE));
+ thread_id = atoi ((*it)->value ()->get_string_content ().c_str ());
+ THROW_IF_FAIL (thread_id);
+ thread_ids.push_back (thread_id);
+ }
+ } else if (gdbmi_result->variable () == "number-of-threads") {
+ // We've got a RESULT which variable is "number-of-threads",
+ // we expect the result to be a string which is the number of threads.
+ THROW_IF_FAIL (gdbmi_result->value ()
+ && gdbmi_result->value ()->content_type ()
+ == GDBMIValue::STRING_TYPE);
+ num_threads =
+ atoi (gdbmi_result->value ()->get_string_content ().c_str ());
+ } else if (gdbmi_result->variable () == "current-thread-id") {
+ // If we've got a RESULT which variable is "current-thread-id",
+ // expect the result to be a string which is the id of the current
+ // thread.
+ current_thread_id =
+ atoi (gdbmi_result->value ()->get_string_content ().c_str ());
+ } else {
+ // Let's consume the unknown RESULT which we might have gotten for
+ // now.
+ LOG_ERROR ("Got an unknown RESULT which variable is '"
+ << gdbmi_result->variable ()
+ << "'. Ignoring it thus.");
+ }
+ SKIP_BLANK2 (cur);
+ if (RAW_CHAR_AT (cur) == '\n') {
+ break;
+ }
+ if (RAW_CHAR_AT (cur) == ',') {
+ ++cur;
+ CHECK_END2 (cur);
+ }
+ SKIP_BLANK2 (cur);
}
- THROW_IF_FAIL (gdbmi_result->value ()
- && gdbmi_result->value ()->content_type ()
- == GDBMIValue::STRING_TYPE);
- unsigned int num_threads =
- atoi (gdbmi_result->value ()->get_string_content ().c_str ());
if (num_threads != thread_ids.size ()) {
LOG_ERROR ("num_threads: '"
diff --git a/tests/test-gdbmi.cc b/tests/test-gdbmi.cc
index 09c3ddf..2561e61 100644
--- a/tests/test-gdbmi.cc
+++ b/tests/test-gdbmi.cc
@@ -47,6 +47,7 @@ static const char *gv_output_record2=
"^done,value=\"{tree (int, int, int, tree, tree)} 0x483c2f <build_template_parm_index>\"\n"
"(gdb)";
+static const char *gv_output_record3="^done,thread-ids={thread-id=\"1\"},current-thread-id=\"1\",number-of-threads=\"1\"\n";
//the partial result of a gdbmi command: -stack-list-argument 1 command
//this command is used to implement IDebugger::list_frames_arguments()
@@ -268,6 +269,10 @@ test_output_record ()
parser.push_input (gv_output_record2);
is_ok = parser.parse_output_record (0, to, output);
BOOST_REQUIRE (is_ok) ;
+
+ parser.push_input (gv_output_record3);
+ is_ok = parser.parse_output_record (0, to, output);
+ BOOST_REQUIRE (is_ok) ;
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]