From 45d308d631a6113cd9b12dea2d92cdac9a576ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8rtveit?= Date: Tue, 13 Feb 2018 15:51:34 +0100 Subject: [PATCH] Fixed file parsing under Windows, fixed PC-lint parser, added detection of MISRA errors for PC-lint --- README.md | 1 + .../bjurr/violations/lib/ViolationsApi.java | 7 +- .../violations/lib/parsers/PCLintParser.java | 137 ++++++++++++------ .../se/bjurr/violations/lib/PCLintTest.java | 48 +++++- src/test/resources/pclint/pclint.txt | 19 ++- 5 files changed, 153 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index b478742a..02acb509 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ It supports: * [_JCReport_](https://github.com/jCoderZ/fawkez/wiki/JcReport) * [_Klocwork_](http://www.klocwork.com/products-services/klocwork/static-code-analysis) * [_MyPy_](https://pypi.python.org/pypi/mypy-lang) + * [_PCLint_](http://www.gimpel.com/html/pcl.htm) PC-Lint using the same output format as the Jenkins warnings plugin, [_details here_](https://wiki.jenkins.io/display/JENKINS/PcLint+options) * [_PerlCritic_](https://github.com/Perl-Critic) * [_PiTest_](http://pitest.org/) * [_PyDocStyle_](https://pypi.python.org/pypi/pydocstyle) diff --git a/src/main/java/se/bjurr/violations/lib/ViolationsApi.java b/src/main/java/se/bjurr/violations/lib/ViolationsApi.java index 544778a7..4190aeb7 100644 --- a/src/main/java/se/bjurr/violations/lib/ViolationsApi.java +++ b/src/main/java/se/bjurr/violations/lib/ViolationsApi.java @@ -84,8 +84,13 @@ public List violations() { return foundViolations; } + private String makeWindowsFriendly(String regularExpression) + { + return regularExpression.replace("/", "(?:/|\\\\)"); + } + public ViolationsApi withPattern(String regularExpression) { - pattern = regularExpression; + pattern = makeWindowsFriendly(regularExpression); return this; } } diff --git a/src/main/java/se/bjurr/violations/lib/parsers/PCLintParser.java b/src/main/java/se/bjurr/violations/lib/parsers/PCLintParser.java index d1f2e81f..e1a94957 100644 --- a/src/main/java/se/bjurr/violations/lib/parsers/PCLintParser.java +++ b/src/main/java/se/bjurr/violations/lib/parsers/PCLintParser.java @@ -9,6 +9,7 @@ import static se.bjurr.violations.lib.util.ViolationParserUtils.getLines; import static se.bjurr.violations.lib.util.ViolationParserUtils.getParts; +import java.util.regex.*; import java.util.ArrayList; import java.util.List; import se.bjurr.violations.lib.model.SEVERITY; @@ -16,48 +17,96 @@ public class PCLintParser implements ViolationsParser { - @Override - public List parseReportOutput(String string) throws Exception { - List violations = new ArrayList<>(); - List lines = getLines(string); - for (String line : lines) { - List parts = - getParts( - line, - "^(.+)\\(", - "^([\\d]+)\\): ", - "^(Error|Warning|Info|Note) ", - "^([\\d]+): ", - "^(.*)$"); - if (parts.isEmpty()) { - continue; - } - String filename = parts.get(0); - Integer lineNumber = parseInt(parts.get(1)); - SEVERITY severity = toSeverity(parts.get(2)); - String rule = parts.get(3); - String message = parts.get(4); - violations.add( // - violationBuilder() // - .setParser(PCLINT) // - .setStartLine(lineNumber) // - .setFile(filename) // - .setRule(rule) // - .setSeverity(severity) // - .setMessage(message) // - .build() // - ); - } - return violations; - } - - public SEVERITY toSeverity(String severity) { - if (severity.equals("Error")) { - return ERROR; - } - if (severity.equals("Warning")) { - return WARN; - } - return INFO; - } + @Override + public List parseReportOutput(String string) throws Exception { + List violations = new ArrayList<>(); + List lines = getLines(string); + System.out.println(lines.size()); + Pattern misraPattern = Pattern.compile("\\[MISRA.*\\]"); + for (String line : lines) { + Matcher misraMatcher = misraPattern.matcher(line); + if (misraMatcher.find()) { + parseMisraViolation(line, violations); + } else { + parseGeneralViolation(line, violations); + } + } + return violations; + } + + private void parseMisraViolation(String line, List violations) { + List parts = getParts(line, + "^([^\\(]+)\\(", + "^([\\d]+)\\): ", + "^(?:Error|Warning|Info|Note) [\\d]+: ([^\\[]*)", + "^\\[(.*),", + "(mandatory|required|advisory)\\]", + "^(.*)$"); + if (parts.isEmpty()) { + return; + } + String filename = parts.get(0); + Integer lineNumber = parseInt(parts.get(1)); + + String severityString = parts.get(4); + SEVERITY severity = toMisraSeverity(severityString); + String rule = parts.get(3) + ", " + severityString; + String message = parts.get(2) + " " + parts.get(5); + violations.add( // + violationBuilder() // + .setParser(PCLINT) // + .setStartLine(lineNumber) // + .setFile(filename) // + .setRule(rule) // + .setSeverity(severity) // + .setMessage(message) // + .build() // + ); + } + + private void parseGeneralViolation(String line, List violations) { + List parts = getParts(line, + "^([^\\(]+)\\(", + "^([\\d]+)\\): ", + "^(Error|Warning|Info|Note) ", + "^([\\d]+): ", "^(.*)$"); + if (parts.isEmpty()) { + return; + } + String filename = parts.get(0); + Integer lineNumber = parseInt(parts.get(1)); + SEVERITY severity = toSeverity(parts.get(2)); + String rule = parts.get(3); + String message = parts.get(4); + violations.add( // + violationBuilder() // + .setParser(PCLINT) // + .setStartLine(lineNumber) // + .setFile(filename) // + .setRule(rule) // + .setSeverity(severity) // + .setMessage(message) // + .build() // + ); + } + + private SEVERITY toSeverity(String severity) { + if (severity.equals("Error")) { + return ERROR; + } + if (severity.equals("Warning")) { + return WARN; + } + return INFO; + } + + private SEVERITY toMisraSeverity(String severity) { + if (severity.equals("mandatory")) { + return ERROR; + } + if (severity.equals("required")) { + return WARN; + } + return INFO; + } } diff --git a/src/test/java/se/bjurr/violations/lib/PCLintTest.java b/src/test/java/se/bjurr/violations/lib/PCLintTest.java index 103ca795..130a2a3b 100644 --- a/src/test/java/se/bjurr/violations/lib/PCLintTest.java +++ b/src/test/java/se/bjurr/violations/lib/PCLintTest.java @@ -18,7 +18,7 @@ public class PCLintTest { @Test public void testThatViolationsCanBeParsed() { String rootFolder = getRootFolder(); - + List actual = violationsApi() // .withPattern(".*/pclint/.*\\.txt$") // @@ -27,7 +27,7 @@ public void testThatViolationsCanBeParsed() { .violations(); assertThat(actual) // - .hasSize(7); + .hasSize(8); assertThat(actual.get(0)) // .isEqualTo( // @@ -37,7 +37,7 @@ public void testThatViolationsCanBeParsed() { .setStartLine(84) // .setRule("9029") // .setMessage( - "Mismatched essential type categories for binary operator [MISRA 2012 Rule 10.4, required] (Note 9029)") // + "Mismatched essential type categories for binary operator") // .setSeverity(INFO) // .build() // ); @@ -50,7 +50,7 @@ public void testThatViolationsCanBeParsed() { .setStartLine(73) // .setRule("534") // .setMessage( - "Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\\UST3\\qse30\\HAL\\hal_ext.h, module C:\\UST3\\qse30\\Drivers\\drvADC.c) [MISRA 2012 Directive 4.7, required], [MISRA 2012 Rule 17.7, required] (Warning 534)") // + "Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\\UST3\\qse30\\HAL\\hal_ext.h, module C:\\UST3\\qse30\\Drivers\\drvADC.c)") // .setSeverity(WARN) // .build() // ); @@ -62,8 +62,8 @@ public void testThatViolationsCanBeParsed() { .setStartLine(134) // .setRule("818") // .setMessage( - "Pointer parameter 'txFrame' (line 100) could be declared as pointing to const [MISRA 2012 Rule 8.13, advisory] (Info 818)") // - .setSeverity(ERROR) // + "Pointer parameter 'txFrame' (line 100) could be declared as pointing to const") // + .setSeverity(INFO) // .build() // ); assertThat(actual.get(6)) // @@ -74,9 +74,43 @@ public void testThatViolationsCanBeParsed() { .setStartLine(123) // .setRule("48") // .setMessage( - "Bad type [MISRA 2012 Rule 10.1, required] (Error 48)") // + "Bad type") // .setSeverity(ERROR) // .build() // ); } + + @Test + public void testThatSeverityAndRulenumberFromMisraTakesPrecedence() { + String rootFolder = getRootFolder(); + + List actual = violationsApi() // + .withPattern(".*/pclint/.*\\.txt$") // + .inFolder(rootFolder) // + .findAll(PCLINT) // + .violations(); + + Violation violation = actual.get(1); + + assertThat(violation.getRule().get()) + .isEqualTo("MISRA 2012 Rule 10.4, mandatory"); + assertThat(violation.getSeverity()) + .isEqualTo(ERROR); + + violation = actual.get(2); + + assertThat(violation.getRule().get()) + .isEqualTo("MISRA 2012 Rule 1.3, required"); + assertThat(violation.getSeverity()) + .isEqualTo(WARN); + + violation = actual.get(7); + + assertThat(violation.getRule().get()) + .isEqualTo("MISRA 2012 Rule 10.1, advisory"); + assertThat(violation.getSeverity()) + .isEqualTo(INFO); + assertThat(violation.getMessage()) + .isEqualTo("Bad type (Error 48)"); + } } diff --git a/src/test/resources/pclint/pclint.txt b/src/test/resources/pclint/pclint.txt index da993ec7..6ae722d0 100644 --- a/src/test/resources/pclint/pclint.txt +++ b/src/test/resources/pclint/pclint.txt @@ -1,14 +1,14 @@ PC-lint for C/C++ (NT) Vers. 9.00L, Copyright Gimpel Software 1985-2014 --- Module: C:\UST3\qse30\Drivers\drvADC.c (C) -C:\UST3\qse30\Drivers\drvADC.c(84): Note 9029: Mismatched essential type categories for binary operator [MISRA 2012 Rule 10.4, required] (Note 9029) +C:\UST3\qse30\Drivers\drvADC.c(84): Note 9029: Mismatched essential type categories for binary operator --- Module: C:\UST3\qse30\Drivers\drvCAN.c (C) -C:\UST3\qse30\Drivers\drvCAN.c(68): Note 9029: Mismatched essential type categories for binary operator [MISRA 2012 Rule 10.4, required] (Note 9029) -C:\UST3\qse30\Drivers\drvCAN.c(72): Note 931: Both sides have side effects [MISRA 2012 Rule 1.3, required], [MISRA 2012 Rule 13.2, required] (Note 931) -C:\UST3\qse30\Drivers\drvCAN.c(73): Warning 534: Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\UST3\qse30\HAL\hal_ext.h, module C:\UST3\qse30\Drivers\drvADC.c) [MISRA 2012 Directive 4.7, required], [MISRA 2012 Rule 17.7, required] (Warning 534) -C:\UST3\qse30\Drivers\drvCAN.c(128): Warning 534: Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\UST3\qse30\HAL\hal_ext.h, module C:\UST3\qse30\Drivers\drvADC.c) [MISRA 2012 Directive 4.7, required], [MISRA 2012 Rule 17.7, required] (Warning 534) -C:\UST3\qse30\Drivers\drvCAN.c(134): Info 818: Pointer parameter 'txFrame' (line 100) could be declared as pointing to const [MISRA 2012 Rule 8.13, advisory] (Info 818) +C:\UST3\qse30\Drivers\drvCAN.c(68): Note 9029: Mismatched essential type categories for binary operator [MISRA 2012 Rule 10.4, mandatory] (Note 9029) +C:\UST3\qse30\Drivers\drvCAN.c(72): Note 931: Both sides have side effects [MISRA 2012 Rule 1.3, required] +C:\UST3\qse30\Drivers\drvCAN.c(73): Warning 534: Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\UST3\qse30\HAL\hal_ext.h, module C:\UST3\qse30\Drivers\drvADC.c) +C:\UST3\qse30\Drivers\drvCAN.c(128): Warning 534: Ignoring return value of function 'PIC_CAN_Transmit(can_frame_t *)' (compare with line 68, file C:\UST3\qse30\HAL\hal_ext.h, module C:\UST3\qse30\Drivers\drvADC.c) +C:\UST3\qse30\Drivers\drvCAN.c(134): Info 818: Pointer parameter 'txFrame' (line 100) could be declared as pointing to const --- Module: C:\UST3\qse30\Drivers\drvNTC.c (C) @@ -18,4 +18,9 @@ C:\UST3\qse30\Drivers\drvCAN.c(134): Info 818: Pointer parameter 'txFrame' (line --- Module: C:\UST3\qse30\Modules\COMM\J1939\Broadcast\dm13.c (C) -C:\UST3\qse30\Modules\COMM\J1939\Broadcast\dm13.c(123): Error 48: Bad type [MISRA 2012 Rule 10.1, required] (Error 48) \ No newline at end of file +C:\UST3\qse30\Modules\COMM\J1939\Broadcast\dm13.c(123): Error 48: Bad type +C:\UST3\qse30\Modules\COMM\J1939\Broadcast\dm13.c(123): Error 48: Bad type [MISRA 2012 Rule 10.1, advisory] (Error 48) + + + +