[gedit] externaltools: Fix link parsing for gcc output.



commit 9f102d29b3cd57efe34d427e19651002c2cd962c
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Sun Oct 9 23:45:59 2011 +0200

    externaltools: Fix link parsing for gcc output.
    
    New gcc compilers add column information, if this is the case this
    info is taken into account and passed to the loaded file.
    Kudos to Paolo Borelli for helping on fixing this too.

 plugins/externaltools/tools/linkparsing.py      |   23 ++++++++++++++++----
 plugins/externaltools/tools/linkparsing_test.py |   25 ++++++++++++-----------
 plugins/externaltools/tools/outputpanel.py      |    2 +-
 3 files changed, 32 insertions(+), 18 deletions(-)
---
diff --git a/plugins/externaltools/tools/linkparsing.py b/plugins/externaltools/tools/linkparsing.py
index 27b9ba8..ef76cd5 100644
--- a/plugins/externaltools/tools/linkparsing.py
+++ b/plugins/externaltools/tools/linkparsing.py
@@ -26,21 +26,23 @@ class Link:
     string that should be marked as a link.
     """
 
-    def __init__(self, path, line_nr, start, end):
+    def __init__(self, path, line_nr, col_nr, start, end):
         """
         path -- the path of the file (that could be extracted)
         line_nr -- the line nr of the specified file
+        col_nr -- the col nr of the specific file
         start -- the index within the string that the link starts at
         end -- the index within the string where the link ends at
         """
         self.path    = path
         self.line_nr = int(line_nr)
+        self.col_nr  = int(col_nr)
         self.start   = start
         self.end     = end
 
     def __repr__(self):
-        return "%s[%s](%s:%s)" % (self.path, self.line_nr,
-                                  self.start, self.end)
+        return "%s[%s][%s](%s:%s)" % (self.path, self.line_nr, self.col_nr,
+                                      self.start, self.end)
 
 class LinkParser:
     """
@@ -137,11 +139,20 @@ class RegexpLinkParser(AbstractLinkParser):
     def parse(self, text):
         links = []
         for m in re.finditer(self.re, text):
+            groups = m.groups()
+
             path = m.group("pth")
             line_nr = m.group("ln")
             start = m.start("lnk")
             end = m.end("lnk")
-            link = Link(path, line_nr, start, end)
+
+            # some regexes may have a col group
+            if len(groups) > 3 and groups[3] != None:
+                col_nr = m.group("col")
+            else:
+                col_nr = 0
+
+            link = Link(path, line_nr, col_nr, start, end)
             links.append(link)
 
         return links
@@ -154,9 +165,11 @@ class RegexpLinkParser(AbstractLinkParser):
 REGEXP_STANDARD = r"""
 ^
 (?P<lnk>
-    (?P<pth> .*[a-z0-9] )
+    (?P<pth> [^\:\n]* )
     \:
     (?P<ln> \d+)
+    \:?
+    (?P<col> \d+)?
 )
 \:\s"""
 
diff --git a/plugins/externaltools/tools/linkparsing_test.py b/plugins/externaltools/tools/linkparsing_test.py
index 609e3b2..25c866e 100644
--- a/plugins/externaltools/tools/linkparsing_test.py
+++ b/plugins/externaltools/tools/linkparsing_test.py
@@ -27,9 +27,10 @@ class LinkParserTest(unittest.TestCase):
     def assert_link_count(self, links, expected_count):
         self.assertEquals(len(links), expected_count, 'incorrect nr of links')
 
-    def assert_link(self, actual, path, line_nr):
+    def assert_link(self, actual, path, line_nr, col_nr=0):
         self.assertEquals(actual.path, path, "incorrect path")
         self.assertEquals(actual.line_nr, line_nr, "incorrect line nr")
+        self.assertEquals(actual.col_nr, col_nr, "incorrect col nr")
 
     def assert_link_text(self, text, link, link_text):
         self.assertEquals(text[link.start:link.end], link_text,
@@ -38,27 +39,27 @@ class LinkParserTest(unittest.TestCase):
     def test_parse_gcc_simple_test_with_real_output(self):
         gcc_output = """
 test.c: In function 'f':
-test.c:5: warning: passing argument 1 of 'f' makes integer from pointer without a cast
-test.c:3: note: expected 'int' but argument is of type 'char *'
+test.c:5:6: warning: passing argument 1 of 'f' makes integer from pointer without a cast
+test.c:3:7: note: expected 'int' but argument is of type 'char *'
 test.c: In function 'main':
-test.c:11: warning: initialization makes pointer from integer without a cast
-test.c:12: warning: initialization makes integer from pointer without a cast
-test.c:13: error: too few arguments to function 'f'
-test.c:14: error: expected ';' before 'return'
+test.c:11:10: warning: initialization makes pointer from integer without a cast
+test.c:12:11: warning: initialization makes integer from pointer without a cast
+test.c:13:12: error: too few arguments to function 'f'
+test.c:14:13: error: expected ';' before 'return'
 """
         links = self.p.parse(gcc_output)
         self.assert_link_count(links, 6)
         lnk = links[2]
-        self.assert_link(lnk, "test.c", 11)
-        self.assert_link_text(gcc_output, lnk, "test.c:11")
+        self.assert_link(lnk, "test.c", 11, 10)
+        self.assert_link_text(gcc_output, lnk, "test.c:11:10")
 
     def test_parse_gcc_one_line(self):
-        line = "/tmp/myfile.c:1212: error: ..."
+        line = "/tmp/myfile.c:1212:12: error: ..."
         links = self.p.parse(line)
         self.assert_link_count(links, 1)
         lnk = links[0]
-        self.assert_link(lnk, "/tmp/myfile.c", 1212)
-        self.assert_link_text(line, lnk, "/tmp/myfile.c:1212")
+        self.assert_link(lnk, "/tmp/myfile.c", 1212, 12)
+        self.assert_link_text(line, lnk, "/tmp/myfile.c:1212:12")
 
     def test_parse_gcc_empty_string(self):
         links = self.p.parse("")
diff --git a/plugins/externaltools/tools/outputpanel.py b/plugins/externaltools/tools/outputpanel.py
index ad47d9b..afb41d2 100644
--- a/plugins/externaltools/tools/outputpanel.py
+++ b/plugins/externaltools/tools/outputpanel.py
@@ -232,7 +232,7 @@ class OutputPanel(UniqueById):
         gfile = self.file_lookup.lookup(link.path)
 
         if gfile:
-            Gedit.commands_load_location(self.window, gfile, None, link.line_nr, -1)
+            Gedit.commands_load_location(self.window, gfile, None, link.line_nr, link.col_nr)
             GObject.idle_add(self.idle_grab_focus)
 
 # ex:ts=4:et:



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