Skip to content

Commit fdf161f

Browse files
authored
Merge pull request #80 from firewave/verbose
Added `Show Cppcheck XML Output` action to show the latest XML output - refs #53
2 parents 6bec888 + 2657c13 commit fdf161f

5 files changed

Lines changed: 74 additions & 15 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ Deployment.
6060

6161
## Releases
6262

63+
### 1.6.3 - 20XX-XX-XX
64+
65+
- Added `Show Cppcheck XML Output` action to show the latest XML output.
66+
6367
### 1.6.2 - 2022-01-25
6468

6569
- Fixed `NullPointerException` with Cppcheck < 1.89 caused by missing `column` attribute in XML result.

resources/META-INF/plugin.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<idea-plugin>
22
<id>com.github.johnthagen.cppcheck</id>
33
<name>cppcheck</name>
4-
<version>1.6.2</version>
4+
<version>1.6.3</version>
55
<vendor email="johnthagen@gmail.com" url="http://github.com/johnthagen">johnthagen</vendor>
66

77
<description><![CDATA[
@@ -60,7 +60,7 @@
6060
]]></description>
6161

6262
<change-notes><![CDATA[
63-
- Fixed `NullPointerException` with Cppcheck < 1.89 caused by missing 'column' attribute in XML result.
63+
- Added `Show Cppcheck XML Output` action to show the latest XML output.
6464
]]>
6565
</change-notes>
6666

@@ -85,6 +85,8 @@
8585

8686
<actions>
8787
<!-- Add your actions here -->
88+
<action id="com.github.johnthagen.cppcheck.ShowOutputAction" class="com.github.johnthagen.cppcheck.ShowOutputAction"
89+
text="Show Cppcheck XML Output" description="Show the raw Cppcheck --xml output of the latest analysis"/>
8890
</actions>
8991

9092
</idea-plugin>

src/com/github/johnthagen/cppcheck/CppCheckInspectionImpl.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.intellij.openapi.progress.ProgressIndicator;
1515
import com.intellij.openapi.progress.ProgressManager;
1616
import com.intellij.openapi.util.TextRange;
17+
import com.intellij.openapi.vfs.VirtualFile;
1718
import com.intellij.psi.PsiFile;
1819
import com.intellij.util.DocumentUtil;
1920
import com.intellij.util.execution.ParametersListUtil;
@@ -55,7 +56,7 @@ private static ProblemHighlightType severityToHighlightType(@NotNull final Strin
5556
}
5657

5758
// TODO: make configurable
58-
private static final boolean VERBOSE_LOG = false;
59+
private static final int VERBOSE_LOG = 0;
5960
private static final String INCONCLUSIVE_TEXT = ":inconclusive";
6061

6162
@NotNull
@@ -65,10 +66,11 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
6566
@NotNull final String cppcheckOutput,
6667
@NotNull final String sourceFileName) throws IOException, SAXException, ParserConfigurationException {
6768

68-
if (VERBOSE_LOG) {
69+
final VirtualFile vFile = psiFile.getVirtualFile();
70+
if (VERBOSE_LOG >= 1) {
6971
// TODO: provide XML output via a "Show Cppcheck output" action - event log messages are truncated
70-
CppcheckNotification.send("execution output for " + psiFile.getVirtualFile().getCanonicalPath(),
71-
cppcheckOutput,
72+
CppcheckNotification.send("finished analysis for " + vFile.getCanonicalPath(),
73+
"",
7274
NotificationType.INFORMATION);
7375
}
7476

@@ -127,7 +129,7 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
127129
}
128130

129131
// suppress this warning for headers until Cppcheck handles them in a better way
130-
if (SupportedExtensions.isHeaderFile(psiFile.getVirtualFile()) && id.equals("unusedStructMember")) {
132+
if (SupportedExtensions.isHeaderFile(vFile) && id.equals("unusedStructMember")) {
131133
continue;
132134
}
133135

@@ -150,7 +152,7 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
150152

151153
// ignore entries without location e.g. missingIncludeSystem
152154
if (location == null) {
153-
CppcheckNotification.send("no location for " + psiFile.getVirtualFile().getCanonicalPath(),
155+
CppcheckNotification.send("no location for " + vFile.getCanonicalPath(),
154156
id + " " + severity + " " + inconclusive + " " + errorMessage,
155157
NotificationType.ERROR);
156158
continue;
@@ -167,6 +169,12 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
167169
column = Integer.parseInt(columnAttr.getNodeValue());
168170
}
169171

172+
if (VERBOSE_LOG >= 4) {
173+
CppcheckNotification.send(id + " for " + vFile.getCanonicalPath(),
174+
id + " " + severity + " " + inconclusive + " " + errorMessage + " " + fileName + " " + lineNumber + " " + column,
175+
NotificationType.INFORMATION);
176+
}
177+
170178
// If a file #include's header files, Cppcheck will also run on the header files and print
171179
// any errors. These errors don't apply to the current file and should not be drawn. They can
172180
// be distinguished by checking the file name.
@@ -176,7 +184,7 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
176184

177185
// Cppcheck error
178186
if (lineNumber <= 0 || lineNumber > document.getLineCount()) {
179-
CppcheckNotification.send("line number out-of-bounds for " + psiFile.getVirtualFile().getCanonicalPath(),
187+
CppcheckNotification.send("line number out-of-bounds for " + vFile.getCanonicalPath(),
180188
id + " " + severity + " " + inconclusive + " " + errorMessage + " " + fileName + " " + lineNumber + " " + column,
181189
NotificationType.ERROR);
182190
continue;
@@ -201,20 +209,27 @@ public static List<ProblemDescriptor> parseOutput(@NotNull final PsiFile psiFile
201209

202210
private static final int TIMEOUT_MS = 60 * 1000;
203211

204-
public static String executeCommandOnFile(@NotNull final String command,
212+
public static String executeCommandOnFile(@NotNull final VirtualFile vFile,
213+
@NotNull final String command,
205214
@NotNull final String options,
206-
@NotNull final String filePath,
215+
@NotNull final File filePath,
207216
final String cppcheckMisraPath) throws CppcheckError, ExecutionException {
208217
final GeneralCommandLine cmd = new GeneralCommandLine()
209218
.withExePath(command)
210219
.withParameters(ParametersListUtil.parse(options))
211-
.withParameters(ParametersListUtil.parse("\"" + filePath + "\""));
220+
.withParameters(ParametersListUtil.parse("\"" + filePath.getAbsolutePath() + "\""));
212221

213222
// Need to be able to get python from the system env
214223
if (cppcheckMisraPath != null && !cppcheckMisraPath.isEmpty()) {
215224
cmd.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.SYSTEM);
216225
}
217226

227+
if (VERBOSE_LOG >= 2) {
228+
CppcheckNotification.send("options for " + vFile.getCanonicalPath(),
229+
cmd.getCommandLineString(),
230+
NotificationType.INFORMATION);
231+
}
232+
218233
final CapturingProcessHandler processHandler = new CapturingProcessHandler(cmd);
219234
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
220235
final ProcessOutput output = processHandler.runProcessWithProgressIndicator(

src/com/github/johnthagen/cppcheck/CppcheckInspection.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@
1919
import javax.xml.parsers.ParserConfigurationException;
2020
import java.io.File;
2121
import java.io.IOException;
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
2224
import java.util.List;
2325

2426
class CppcheckInspection extends LocalInspectionTool {
27+
final static Path LATEST_RESULT_FILE = Paths.get(FileUtil.getTempDirectory(), "clion-cppcheck-latest.xml");
28+
2529
@Nullable
2630
@Override
2731
public ProblemDescriptor[] checkFile(@NotNull final PsiFile file,
@@ -57,14 +61,17 @@ public ProblemDescriptor[] checkFile(@NotNull final PsiFile file,
5761
tempFile = FileUtil.createTempFile(RandomStringUtils.randomAlphanumeric(8) + "_", vFile.getName(), true);
5862
FileUtil.writeToFile(tempFile, document.getText());
5963
final String cppcheckOutput =
60-
CppCheckInspectionImpl.executeCommandOnFile(cppcheckPath, prependIncludeDir(cppcheckOptions, vFile),
61-
tempFile.getAbsolutePath(), cppcheckMisraPath);
64+
CppCheckInspectionImpl.executeCommandOnFile(vFile, cppcheckPath, prependIncludeDir(cppcheckOptions, vFile),
65+
tempFile, cppcheckMisraPath);
66+
67+
// store the output of the latest analysis
68+
FileUtil.writeToFile(LATEST_RESULT_FILE.toFile(), cppcheckOutput);
6269

6370
final List<ProblemDescriptor> descriptors = CppCheckInspectionImpl.parseOutput(file, manager, document, cppcheckOutput,
6471
tempFile.getName());
6572
return descriptors.toArray(new ProblemDescriptor[0]);
6673
} catch (final ExecutionException | CppcheckError | IOException | SAXException | ParserConfigurationException ex) {
67-
CppcheckNotification.send("execution failed for " + file.getVirtualFile().getCanonicalPath(),
74+
CppcheckNotification.send("execution failed for " + vFile.getCanonicalPath(),
6875
ex.getClass().getSimpleName() + ": " + ex.getMessage(),
6976
NotificationType.ERROR);
7077
} finally {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.github.johnthagen.cppcheck;
2+
3+
import com.intellij.openapi.actionSystem.AnAction;
4+
import com.intellij.openapi.actionSystem.AnActionEvent;
5+
import com.intellij.openapi.fileEditor.FileEditorManager;
6+
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
7+
import com.intellij.openapi.project.Project;
8+
import com.intellij.openapi.vfs.LocalFileSystem;
9+
import com.intellij.openapi.vfs.VirtualFile;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
import static com.github.johnthagen.cppcheck.CppcheckInspection.LATEST_RESULT_FILE;
13+
14+
public class ShowOutputAction extends AnAction {
15+
@Override
16+
public void actionPerformed(@NotNull final AnActionEvent anActionEvent) {
17+
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(LATEST_RESULT_FILE.toFile());
18+
if (vFile == null) {
19+
return;
20+
}
21+
22+
final Project project = anActionEvent.getProject();
23+
if (project == null) {
24+
return;
25+
}
26+
27+
// TODO: make it possible to view the output for the currently open file
28+
// TODO: find a way to display this without writing to the file system
29+
FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, vFile), true);
30+
}
31+
}

0 commit comments

Comments
 (0)