This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 19/22] Add checkers/ianal.py


This patch is a demo of handling code metrics and metadata ("info" results
in Firehose terminology).

It adds a standalone tool harness which scans the main input file
looking for "Copyright" lines, returning information on them as
firehose JSON.

When sent through GCC's diagnostic subsystem by checker.cc, these
"info" results are emitted as notes, e.g.:

../../src/checkers/test-sources/cpychecker-demo.c:2:4: note: I am not a lawyer [not-a-lawyer:copyright-line]
    Copyright 2011 David Malcolm <dmalcolm@redhat.com>
    ^~~~~~~~~
../../src/checkers/test-sources/cpychecker-demo.c:3:4: note: I am not a lawyer [not-a-lawyer:copyright-line]
    Copyright 2011 Red Hat, Inc.
    ^~~~~~~~~

and they're captured in the generated binary by the watermarking code.

checkers/ChangeLog:
	* ianal.py: New file.
---
 checkers/ianal.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100755 checkers/ianal.py

diff --git a/checkers/ianal.py b/checkers/ianal.py
new file mode 100755
index 0000000..a918f41
--- /dev/null
+++ b/checkers/ianal.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+#   Copyright 2017 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2017 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+
+from firehose.model import Analysis, Generator, Metadata, Info, \
+    Location, Message, Range, Point
+
+from checker import Checker, CheckerTests, make_file, tool_main
+
+class NotALawyer(Checker):
+    """
+    Checker subclass that looks for "Copyright" lines, as a demo
+    of handling "info" results.
+    """
+    name = 'not-a-lawyer'
+
+    def raw_invoke(self, gccinv, sourcefile):
+        results = []
+        file_ = make_file(sourcefile)
+        with open(sourcefile) as f:
+            for lineidx, line in enumerate(f):
+                m = re.match('.*(Copyright).*', line)
+                if m:
+                    start, end = m.span(1)
+                    linenum = lineidx + 1
+                    range_ = Range(start=Point(linenum, start + 1),
+                                   end=Point(linenum, end))
+                    location = Location(file_, None, range_=range_)
+                    info = Info(infoid='copyright-line',
+                                location=location,
+                                message=Message('I am not a lawyer'),
+                                customfields=None)
+                    results.append(info)
+        metadata = Metadata(generator=Generator(self.name), sut=None,
+                            file_=file_, stats=None)
+        analysis = Analysis(metadata, results)
+        return analysis
+
+class NotALawyerTests(CheckerTests):
+    def make_tool(self):
+        return self.make_tool_from_class(NotALawyer)
+
+    def verify_basic_metadata(self, analysis, sourcefile):
+        # Verify basic metadata:
+        self.assert_metadata(analysis, 'not-a-lawyer', sourcefile)
+
+    def test_basic(self):
+        analysis = self.invoke('test-sources/cpychecker-demo.c')
+        self.assertEqual(len(analysis.results), 2)
+        r0 = analysis.results[0]
+        self.assertIsInstance(r0, Info)
+        self.assertEqual(r0.infoid, 'copyright-line')
+        self.assertEqual(r0.location.file.givenpath,
+                         'test-sources/cpychecker-demo.c')
+        self.assertEqual(r0.message.text, 'I am not a lawyer')
+        self.assertEqual(r0.location.range_.start.line, 2)
+        self.assertEqual(r0.location.range_.start.column, 4)
+        self.assertEqual(r0.location.range_.end.line, 2)
+        self.assertEqual(r0.location.range_.end.column, 12)
+
+if __name__ == '__main__':
+    sys.exit(tool_main(sys.argv, NotALawyer))
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]