[nemiver/follow-fork-mode: 10/35] Support original-location attr on pending breakpoints.



commit 0f8719286729a54103bce86e514d3a3bce62d0b5
Author: Dodji Seketeli <dodji redhat com>
Date:   Sat Apr 10 12:48:28 2010 +0200

    Support original-location attr on pending breakpoints.
    
    	* src/common/nmv-str-utils.h (extract_path_and_line_num_from_location):
    	Remove use of UString in the declaration.
    	(chomp): Turn this into a template.
    	* src/common/nmv-str-utils.cc (extract_path_and_line_num_from_location):
    	Adjust and make it much more robust.
    	* src/dbgengine/nmv-gdbmi-parser.cc (GDBMIParser::parse_breakpoint):
    	Adjust to recent (GDB 7?) behaviour wrt PENDING breakpoints.
    	Now, the original location is in the original-location
    	attribute.

 src/common/nmv-str-utils.cc       |   57 +++++++++++++++++++----
 src/common/nmv-str-utils.h        |   34 ++++++++++++--
 src/dbgengine/nmv-gdbmi-parser.cc |   89 +++++++++----------------------------
 tests/test-gdbmi.cc               |    8 +++
 4 files changed, 105 insertions(+), 83 deletions(-)
---
diff --git a/src/common/nmv-str-utils.cc b/src/common/nmv-str-utils.cc
index 4b91c67..f814b87 100644
--- a/src/common/nmv-str-utils.cc
+++ b/src/common/nmv-str-utils.cc
@@ -33,18 +33,55 @@ NEMIVER_BEGIN_NAMESPACE (str_utils)
 using nemiver::common::UString;
 using namespace nemiver::common;
 
+// Return true if a_str is a location string of the form
+// "filename:number", where number is string of digits.
+// Keep in mind that filename can also be a path that contains ':'
+// itself. So this function tries hard to make sure what follows the ':'
+// is a real number and ends the string.
 bool
-extract_path_and_line_num_from_location (const UString &a_location,
-                                         UString &a_file_path,
-                                         unsigned &a_line_num)
+extract_path_and_line_num_from_location (const std::string &a_str,
+                                         std::string &a_filename,
+                                         std::string &a_line_num)
 {
-    vector<UString> strs = a_location.split (":");
-    if (strs.empty ())
-        return false;
-    a_file_path = strs[0];
-    if (strs.size () > 1 && !strs[1].empty ())
-        a_line_num = std::atoi (strs[1].c_str ());
-    return true;
+    std::string filename;
+    std::string::size_type colon_pos;
+    bool result = false;
+    if ((colon_pos = a_str.find_last_of (":"))
+        == std::string::npos) {
+        // The string has no ':' character. Let's bail out.
+    } else {
+        // Is what comes after the comma a legit number?
+        bool is_number = true;
+        std::string::size_type str_len = colon_pos;
+
+        if (colon_pos + 1 >= a_str.length ())
+            is_number = false;
+        // Loop to make sure the thing after the ':' is an actual
+        // number.
+        std::string::size_type i;
+        for (i = colon_pos + 1; i < a_str.length (); ++i) {
+            if (!isdigit (a_str[i])) {
+                is_number = false;
+                break;
+            }
+        }
+        bool number_is_at_end_of_str = (i >= a_str.length ());
+
+        if (is_number && number_is_at_end_of_str) {
+            string file_name, line_num;
+
+            for (string::size_type i = 0; i < str_len; ++i)
+                a_filename.push_back (a_str[i]);
+
+            for (string::size_type i = colon_pos + 1; i < a_str.length (); ++i)
+                a_line_num.push_back (a_str[i]);
+            result = true;
+        } else {
+            // Bail out because the ':' is either not a legit number or
+            // not at the end of the string.
+        }
+    }
+    return result;
 }
 
 size_t
diff --git a/src/common/nmv-str-utils.h b/src/common/nmv-str-utils.h
index 68d45a4..b901902 100644
--- a/src/common/nmv-str-utils.h
+++ b/src/common/nmv-str-utils.h
@@ -32,10 +32,9 @@ NEMIVER_BEGIN_NAMESPACE (str_utils)
 using nemiver::common::UString;
 
 bool
-extract_path_and_line_num_from_location (const UString &a_location,
-                                         UString &a_file_path,
-                                         unsigned &a_line_num);
-
+extract_path_and_line_num_from_location (const std::string &a_location,
+                                         std::string &a_file_path,
+                                         std::string &a_line_num);
 size_t hexa_to_int (const string &a_hexa_str);
 std::string int_to_string (size_t an_int);
 vector<UString> split (const UString &a_string, const UString &a_delim);
@@ -45,7 +44,32 @@ UString join (const vector<UString> &a_elements,
 UString join (vector<UString>::const_iterator &a_from,
               vector<UString>::const_iterator &a_to,
               const UString &a_delim=" ");
-void chomp (UString &a_string);
+
+template<typename S>
+void
+chomp (S &a_string)
+{
+    if (!a_string.size ()) {return;}
+
+    Glib::ustring::size_type i = 0;
+
+    // remove the ws from the beginning of the string.
+    while (!a_string.empty () && isspace (a_string.at (0))) {
+        a_string.erase (0, 1);
+    }
+
+    // remove the ws from the end of the string.
+    i = a_string.size ();
+    if (!i) {return;}
+    --i;
+    while (i > 0 && isspace (a_string.at (i))) {
+        a_string.erase (i, 1);
+        i = a_string.size ();
+        if (!i) {return;}
+        --i;
+    }
+    if (i == 0 && isspace (a_string.at (i))) {a_string.erase (0, 1);}
+}
 
 UString::size_type get_number_of_lines (const UString &a_string);
 
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index a9f2efa..09379eb 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -2089,15 +2089,14 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
     }
     ++cur;
 
-    if (attrs["addr"] == "<PENDING>") {
-        UString pending = attrs["pending"];
-        if (pending == "") {
-            LOG_PARSING_ERROR2 (cur);
-            return false;
-        }
+    UString pending = attrs["pending"];
+    if (pending.empty ())
+        pending = attrs["original-location"];
+    if (!pending.empty ()) {
         LOG_D ("got pending breakpoint: '" << pending << "'",
                GDBMI_OUTPUT_DOMAIN);
-        vector<UString> str_tab;
+        bool is_file_location = false;
+        string filename, line_num;
         // pending contains either the name of the function the breakpoint
         // has been set on, or the filename:linenumber location of the
         // breakpoint.
@@ -2108,59 +2107,15 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
         // Bear in mind that ':' can also be part of the path name. So we
         // really need to detect if the last ':' is the separator betwen
         // path and line number.
-        std::string::size_type colon_pos;
-        if ((colon_pos = pending.raw ().find_last_of (":"))
-            == std::string::npos) {
-            str_tab.push_back (pending);
-        } else {
-            // Is what comes after the comma a legit number?
-            bool is_number = true;
-            std::string::size_type str_len = colon_pos;
-
-            if (colon_pos + 1 >= pending.raw ().length ())
-                is_number = false;
-            // Loop to make sure the thing after the ':' is an actual
-            // number.
-            std::string::size_type i;
-            for (i = colon_pos + 1;
-                 i < pending.raw ().length ();
-                 ++i) {
-                if (!isdigit (pending.raw ()[i])) {
-                    is_number = false;
-                    break;
-                }
-            }
-            bool number_is_at_end_of_pending = (i >= pending.raw ().length ());
-
-            if (is_number && number_is_at_end_of_pending) {
-                string file_name, line_num;
-
-                for (string::size_type i = 0; i < str_len; ++i)
-                    file_name.push_back (pending.raw ()[i]);
-
-                for (string::size_type i = colon_pos + 1;
-                     i < pending.raw ().length ();
-                     ++i)
-                    line_num.push_back (pending.raw ()[i]);
-
-                str_tab.push_back (file_name);
-                str_tab.push_back (line_num);
-            } else {
-                str_tab.push_back (pending);
-            }
-        }
-
-        // from now on, if str_tab.size () == 2 then it contains
-        // the filename and line number of the breakpoint.
-        // if it str_tab.size () == 1 then it contains the function name
-        // the breakpoint was set on.
-        // Otherwise an error occured
-        if (str_tab.size () > 1) {
-            LOG_D ("filepath: '" << str_tab[0] << "'", GDBMI_OUTPUT_DOMAIN);
-            LOG_D ("linenum: '" << str_tab[1] << "'", GDBMI_OUTPUT_DOMAIN);
-        }
-        if (str_tab.size () == 2) {
-            string path = Glib::locale_from_utf8 (str_tab[0]);
+        is_file_location =
+            str_utils::extract_path_and_line_num_from_location (pending.raw (),
+                                                                filename,
+                                                                line_num);
+
+        if (is_file_location) {
+            LOG_D ("filepath: '" << filename << "'", GDBMI_OUTPUT_DOMAIN);
+            LOG_D ("linenum: '" << line_num << "'", GDBMI_OUTPUT_DOMAIN);
+            string path = Glib::locale_from_utf8 (filename);
             if (Glib::path_is_absolute (path)) {
                 attrs["file"] = Glib::locale_to_utf8
                                         (Glib::path_get_basename (path));
@@ -2168,12 +2123,9 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
             } else {
                 attrs["file"] = Glib::locale_to_utf8 (path);;
             }
-            attrs["line"] = str_tab[1];
-        } else if (str_tab.size () == 1) {
-            attrs["func"] = str_tab[0];
+            attrs["line"] = line_num;
         } else {
-            LOG_PARSING_ERROR2 (cur);
-            return false;
+            attrs["func"] = pending;
         }
     }
 
@@ -2218,14 +2170,15 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
         && a_bkpt.file_name ().empty ()
         && (iter = attrs.find ("original-location")) != null_iter) {
         UString location = iter->second;
-        UString file_path;
-        unsigned line_num = 0;
+        string file_path;
+        string line_num_str;
         str_utils::extract_path_and_line_num_from_location (location,
                                                             file_path,
-                                                            line_num);
+                                                            line_num_str);
         // Line number must be present otherwise, that means
         // what was encoded in the "original-location" RESULT wasn't
         // "filepath:line-number"
+        unsigned line_num = atoi (line_num_str.c_str ());
         if (!file_path.empty () && line_num) {
             a_bkpt.file_full_name (file_path);
             a_bkpt.line (line_num);
diff --git a/tests/test-gdbmi.cc b/tests/test-gdbmi.cc
index a9d738f..db503f4 100644
--- a/tests/test-gdbmi.cc
+++ b/tests/test-gdbmi.cc
@@ -150,6 +150,9 @@ static const char* gv_breakpoint_table3 =
 static const char* gv_breakpoint_table4 =
 "BreakpointTable={nr_rows=\"2\",nr_cols=\"6\",hdr=[{width=\"7\",alignment=\"-1\",col_name=\"number\",colhdr=\"Num\"},{width=\"14\",alignment=\"-1\",col_name=\"type\",colhdr=\"Type\"},{width=\"4\",alignment=\"-1\",col_name=\"disp\",colhdr=\"Disp\"},{width=\"3\",alignment=\"-1\",col_name=\"enabled\",colhdr=\"Enb\"},{width=\"18\",alignment=\"-1\",col_name=\"addr\",colhdr=\"Address\"},{width=\"40\",alignment=\"2\",col_name=\"what\",colhdr=\"What\"}],body=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x000000000040aca0\",func=\"main\",file=\"main.cpp\",fullname=\"/home/philip/nemiver:temp/main.cpp\",line=\"77\",times=\"1\",original-location=\"main\"},bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"/home/philip/nemiver:temp/main.cpp:78\",times=\"0\",original-location=\"/home/philip/nemiver:temp/main.cpp:78\"}]}";
 
+static const char* gv_breakpoint_table5 =
+"BreakpointTable={nr_rows=\"2\",nr_cols=\"6\",hdr=[{width=\"7\",alignment=\"-1\",col_name=\"number\",colhdr=\"Num\"},{width=\"14\",alignment=\"-1\",col_name=\"type\",colhdr=\"Type\"},{width=\"4\",alignment=\"-1\",col_name=\"disp\",colhdr=\"Disp\"},{width=\"3\",alignment=\"-1\",col_name=\"enabled\",colhdr=\"Enb\"},{width=\"18\",alignment=\"-1\",col_name=\"addr\",colhdr=\"Address\"},{width=\"40\",alignment=\"2\",col_name=\"what\",colhdr=\"What\"}],body=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x000000000040cb85\",func=\"main(int, char**)\",file=\"main.cc\",fullname=\"/home/dodji/devel/git/nemiver-branches.git/asm-support/src/main.cc\",line=\"489\",times=\"1\",original-location=\"main\"},bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",file=\"nmv-dbg-perspective.cc\",line=\"4143\",times=\"0\",original-location=\"/home/dodji/devel/git/nemiver-branches.git/asm-support/src/persp/dbgperspective/nmv-dbg-perspecti
 ve.cc:4143\"}]}";
+
 static const char* gv_breakpoint0 =
 "bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<MULTIPLE>\",times=\"0\",original-location=\"/home/dodji/devel/srcs/test.cc:36\"}";
 
@@ -818,6 +821,11 @@ test_breakpoint_table ()
     BOOST_REQUIRE_EQUAL (breakpoints[2].file_full_name (),
                          "/home/philip/nemiver:temp/main.cpp");
     BOOST_REQUIRE_EQUAL (breakpoints[2].line (), 78);
+
+    cur = 0, cur = 0, breakpoints.clear ();
+    parser.push_input (gv_breakpoint_table5);
+    parser.set_mode (GDBMIParser::BROKEN_MODE);
+    BOOST_REQUIRE (parser.parse_breakpoint_table (cur, cur, breakpoints));
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]