diff options
Diffstat (limited to 'src/cppcheckplus/control/Main.java')
-rw-r--r-- | src/cppcheckplus/control/Main.java | 917 |
1 files changed, 917 insertions, 0 deletions
diff --git a/src/cppcheckplus/control/Main.java b/src/cppcheckplus/control/Main.java new file mode 100644 index 0000000..4c84eac --- /dev/null +++ b/src/cppcheckplus/control/Main.java | |||
@@ -0,0 +1,917 @@ | |||
1 | package cppcheckplus.control; | ||
2 | |||
3 | import cppcheckplus.menu.MyMenuBar; | ||
4 | import cppcheckplus.outlookpanel.MyOutlookPanel; | ||
5 | import cppcheckplus.outlookpanel.MyOutlookPanelListItem; | ||
6 | import cppcheckplus.shortcut.MyShortcutPanel; | ||
7 | import cppcheckplus.shortcut.MyTree; | ||
8 | import cppcheckplus.tab.MyTabPage; | ||
9 | import cppcheckplus.tab.MyTabPage1; | ||
10 | import cppcheckplus.tab.MyTabPanel; | ||
11 | import cppcheckplus.tab.MyTabPanel1; | ||
12 | import cppcheckplus.text.FileTools; | ||
13 | import cppcheckplus.text.MyPanel; | ||
14 | import cppcheckplus.text.MyTextPanel; | ||
15 | import cppcheckplus.text.MyTextPanel1; | ||
16 | import cppcheckplus.text.ViewPanel; | ||
17 | import cppcheckplus.text.creatTable; | ||
18 | import java.awt.BorderLayout; | ||
19 | import java.awt.TextArea; | ||
20 | import java.awt.event.ActionEvent; | ||
21 | import java.awt.event.ActionListener; | ||
22 | import java.awt.event.MouseAdapter; | ||
23 | import java.awt.event.MouseEvent; | ||
24 | import java.io.BufferedReader; | ||
25 | import java.io.File; | ||
26 | import java.io.IOException; | ||
27 | import java.io.InputStream; | ||
28 | import java.io.InputStreamReader; | ||
29 | import java.io.UnsupportedEncodingException; | ||
30 | import java.nio.charset.StandardCharsets; | ||
31 | import java.nio.file.Files; | ||
32 | import java.nio.file.Path; | ||
33 | import java.nio.file.Paths; | ||
34 | import javax.swing.BorderFactory; | ||
35 | import javax.swing.JComponent; | ||
36 | import javax.swing.JFileChooser; | ||
37 | import javax.swing.JFrame; | ||
38 | import javax.swing.JList; | ||
39 | import javax.swing.JOptionPane; | ||
40 | import javax.swing.JTextArea; | ||
41 | import javax.swing.SwingUtilities; | ||
42 | import javax.swing.event.ListSelectionEvent; | ||
43 | import javax.swing.event.ListSelectionListener; | ||
44 | import javax.swing.plaf.TabbedPaneUI; | ||
45 | import javax.xml.parsers.ParserConfigurationException; | ||
46 | |||
47 | |||
48 | // 构造界面和各个工具的调用逻辑 | ||
49 | public class Main extends JFrame { | ||
50 | //private String target = "";// dump文件路径 | ||
51 | public static final int SUCCESS = 0; // 表示程序执行成功 | ||
52 | public static final String COMMAND = "java.exe -version"; // 要执行的语句 | ||
53 | public static final String SUCCESS_MESSAGE = "程序执行成功!"; | ||
54 | public static final String ERROR_MESSAGE = "程序执行出错:"; | ||
55 | public static final String ENTERWindows = "\r\n"; | ||
56 | public static final String ENTERLinux = "\n"; | ||
57 | // XML配置文件路径 | ||
58 | private final String menuBarXML; | ||
59 | private final String outlookPanelXML; | ||
60 | private final String settingsXML; | ||
61 | private final String stdclangXML; | ||
62 | // 界面组件 | ||
63 | private final MyContentPanel contentPanel; | ||
64 | private final MyMenuBar menubar; | ||
65 | private final JFileChooser jfc = new JFileChooser();// 文件选择器 | ||
66 | private final JFileChooser jfsettings = new JFileChooser();// 配置设定 | ||
67 | public MyTabPanel tabPanel; | ||
68 | // 编辑代码的面板 | ||
69 | public MyTextPanel testCode; | ||
70 | public String src = ""; // 目标源文件或目录的路径 | ||
71 | public String cppcheckPath = null; | ||
72 | public String flawfinderPath = null; | ||
73 | public String paracppcheck = null; | ||
74 | public String paraflawfinder = null; | ||
75 | public creatTable ct = new creatTable(); | ||
76 | private MyOutlookPanel outlookPanel; | ||
77 | private MyTabPanel1 tabPanel2; | ||
78 | private MyShortcutPanel shortcutPanel; | ||
79 | private MyTree tree; | ||
80 | // 标记是否修改了工具路径 | ||
81 | private boolean changedpathcpp = false; | ||
82 | private boolean changedpathflaw = false; | ||
83 | private MyTextPanel1 testPanel; | ||
84 | private ViewPanel viewPanel; | ||
85 | // 显示代码和检查进程的文本区域 | ||
86 | private JTextArea textCode;// 显示代码内容 | ||
87 | private TextArea textCheck;// 显示检查进度输出 | ||
88 | // 各工具的面板 | ||
89 | private MyTextPanel1 flawfinderPanel; | ||
90 | private MyTextPanel1 cppcheckPanel; | ||
91 | private MyTextPanel1 clangPanel; | ||
92 | // 各工具的检测结果 | ||
93 | private TextArea flawfinderResult;//flawfinder检测结果 | ||
94 | private TextArea cppcheckResult;//cppcheck检测结果 | ||
95 | private TextArea clangResult;//clang检测结果 | ||
96 | // 文件操作相关 | ||
97 | private File result; // 存储打开的文件 | ||
98 | private File report; // 导出报告时选择的文件 | ||
99 | private File direct; // 存储打开的目录 | ||
100 | private String tmpFileName = "";//tmp文件名 | ||
101 | //private static String inputResult = "inputResult.txt"; | ||
102 | //private static String errorResult = "errorResult.txt"; | ||
103 | private Main ui; | ||
104 | private final String projectPath; | ||
105 | |||
106 | // 构造函数:初始化各个组件,加载配置文件,建立界面布局 | ||
107 | public Main() { | ||
108 | projectPath = System.getProperty("user.dir"); | ||
109 | // 文件选择器初始目录 | ||
110 | jfc.setCurrentDirectory(new File("d://")); | ||
111 | jfsettings.setCurrentDirectory(new File("d://")); | ||
112 | |||
113 | // 配置文件路径 | ||
114 | menuBarXML = "cppcheckplus/control/menubar.xml"; | ||
115 | outlookPanelXML = "cppcheckplus/control/outlook.xml"; | ||
116 | settingsXML = "cppcheckplus/control/settings.xml"; | ||
117 | stdclangXML = "cppcheckplus/control/stdclang.xml"; | ||
118 | |||
119 | MyContorlUtil.loadToolsRoad(settingsXML, this);// 加载工具路径设置到当前对象中 | ||
120 | ct.initSTDClang(stdclangXML);// 设置clang配置 | ||
121 | |||
122 | // 加载菜单栏,注册事件监听 | ||
123 | menubar = MyContorlUtil.loadMenuBar(menuBarXML, new ActionListener() { | ||
124 | public void actionPerformed(ActionEvent e) { | ||
125 | String command = e.getActionCommand(); | ||
126 | switch (command) { | ||
127 | case "OnMenuOpen": | ||
128 | // 打开文件 | ||
129 | jfc.setFileSelectionMode(0);// 设定只能选择到文件 | ||
130 | int state = jfc.showOpenDialog(null); | ||
131 | if (state == 1) { | ||
132 | return; // 撤销选择则返回 | ||
133 | } else { | ||
134 | result = jfc.getSelectedFile();// result为选择到的文件 | ||
135 | src = result.getAbsolutePath(); | ||
136 | // 读取文件内容并显示到代码区 | ||
137 | textCode.setText(FileTools.readFile(result)); | ||
138 | // 如果代码标签页不存在,则创建一个 | ||
139 | if (!tabPanel.isSelectTabComponents("代码")) { | ||
140 | tabPanel.addTab("代码", testCode); | ||
141 | tabPanel.isSelectTabComponents("代码"); | ||
142 | } | ||
143 | } | ||
144 | break; | ||
145 | case "onMenuLoad": | ||
146 | // 加载目录:选择目录并更新目录树 | ||
147 | jfc.setFileSelectionMode(1);// 只能选择到文件夹 | ||
148 | // int state = jfc.showOpenDialog(null); | ||
149 | if (jfc.showOpenDialog(null) == 1) { | ||
150 | return; | ||
151 | } | ||
152 | direct = jfc.getSelectedFile();// 选择到的目录 | ||
153 | src = direct.getAbsolutePath(); | ||
154 | tree.setRootDir(direct);// 更新目录树 | ||
155 | break; | ||
156 | case "onMenuSave": | ||
157 | // 保存文件 | ||
158 | if (result != null) { | ||
159 | FileTools.writeFile(result, textCode.getText()); | ||
160 | } | ||
161 | break; | ||
162 | case "onMenuClose": | ||
163 | // 关闭程序 | ||
164 | System.exit(0); | ||
165 | break; | ||
166 | case "onMenuClean": | ||
167 | // 清空:清空代码、检查结果、进度信息,重置参数 | ||
168 | textCode.setText(""); | ||
169 | flawfinderResult.setText(""); | ||
170 | cppcheckResult.setText(""); | ||
171 | clangResult.setText(""); | ||
172 | viewPanel.clearTable(); | ||
173 | ct.clearall(); | ||
174 | textCheck.setText(""); | ||
175 | paracppcheck = "--enable=all"; | ||
176 | break; | ||
177 | case "onMenuExport": | ||
178 | // 导出:将检查结果导出到xml文件 | ||
179 | JFileChooser dialog = new JFileChooser(); | ||
180 | dialog.setDialogTitle("另存为"); | ||
181 | dialog.setFileSelectionMode(JFileChooser.FILES_ONLY); | ||
182 | dialog.setDialogType(JFileChooser.SAVE_DIALOG); | ||
183 | int r = dialog.showSaveDialog(ui); | ||
184 | if (r == JFileChooser.APPROVE_OPTION) { | ||
185 | report = dialog.getSelectedFile(); | ||
186 | FileTools.writeFile(report, ct.results); | ||
187 | } else { | ||
188 | JOptionPane.showMessageDialog(null, "路径错误", | ||
189 | "提示", 2); | ||
190 | } | ||
191 | break; | ||
192 | case "onCppcheck": | ||
193 | // cppcheck检查 | ||
194 | if (src != null && src.length() != 0) { | ||
195 | if (paracppcheck != null && | ||
196 | paracppcheck.length() != 0) { | ||
197 | new Thread() { | ||
198 | public void run() { | ||
199 | execute(src, paracppcheck); | ||
200 | } | ||
201 | }.start(); | ||
202 | } else { | ||
203 | JOptionPane.showMessageDialog(null, "参数错误", | ||
204 | "提示", 2); | ||
205 | } | ||
206 | } else { | ||
207 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
208 | "提示", 2); | ||
209 | } | ||
210 | break; | ||
211 | case "onClang": | ||
212 | // clang/clang-tidy检查 | ||
213 | if (src != null && src.length() != 0) { | ||
214 | new Thread() { | ||
215 | public void run() { | ||
216 | execute2(src); | ||
217 | } | ||
218 | }.start(); | ||
219 | } else { | ||
220 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
221 | "提示", 2); | ||
222 | } | ||
223 | break; | ||
224 | case "onFlawfinder": | ||
225 | // flawfinder检查 | ||
226 | if (src != null && src.length() != 0) { | ||
227 | new Thread() { | ||
228 | public void run() { | ||
229 | tmpFileName = "tmp" + "src" + ".csv"; | ||
230 | execute3(src, paraflawfinder, tmpFileName); | ||
231 | } | ||
232 | }.start(); | ||
233 | } else { | ||
234 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
235 | "提示", 2); | ||
236 | } | ||
237 | break; | ||
238 | case "onMenuAbout": | ||
239 | // 关于:显示软件信息 | ||
240 | JOptionPane.showMessageDialog(null, "cppcheckplus", | ||
241 | "提示", 2); | ||
242 | break; | ||
243 | case "onOrderType": | ||
244 | // 按类型排序:生成表格并按类型排序 | ||
245 | ct.makeTable(); | ||
246 | ct.ord(2); | ||
247 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
248 | viewPanel = new ViewPanel(ct.results); | ||
249 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
250 | tabPanel.isSelectTabComponents("结果"); | ||
251 | } else { | ||
252 | viewPanel.update(ct.results); | ||
253 | } | ||
254 | break; | ||
255 | case "onOrderLevel": | ||
256 | // 按级别排序 | ||
257 | ct.makeTable(); | ||
258 | ct.ord(3); | ||
259 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
260 | viewPanel = new ViewPanel(ct.results); | ||
261 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
262 | tabPanel.isSelectTabComponents("结果"); | ||
263 | } else { | ||
264 | viewPanel.update(ct.results); | ||
265 | } | ||
266 | break; | ||
267 | case "onOrderFile": | ||
268 | // 按文件排序 | ||
269 | ct.makeTable(); | ||
270 | ct.ord(1); | ||
271 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
272 | viewPanel = new ViewPanel(ct.results); | ||
273 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
274 | tabPanel.isSelectTabComponents("结果"); | ||
275 | } else { | ||
276 | viewPanel.update(ct.results); | ||
277 | } | ||
278 | break; | ||
279 | case "onSetCppcheckRoad": | ||
280 | // cppcheck路径 | ||
281 | jfsettings.setFileSelectionMode(0);// 设定只能选择到文件 | ||
282 | // int state = jfsettings.showOpenDialog(null); | ||
283 | if (jfsettings.showOpenDialog(null) == 1) { | ||
284 | return; // 撤销则返回 | ||
285 | } else { | ||
286 | File cppcheckFile = jfsettings.getSelectedFile(); | ||
287 | String cppcheckPathTemp = | ||
288 | cppcheckFile.getAbsolutePath(); | ||
289 | MyContorlUtil.fixSettingPath(settingsXML, | ||
290 | "cppcheck", cppcheckPathTemp); | ||
291 | changedpathcpp = true; | ||
292 | } | ||
293 | break; | ||
294 | case "onSetFlawfinderRoad": | ||
295 | // flawfinder路径 | ||
296 | jfsettings.setFileSelectionMode(0);// 设定只能选择到文件 | ||
297 | // int state = jfsettings.showOpenDialog(null); | ||
298 | if (jfsettings.showOpenDialog(null) == 1) { | ||
299 | return;// 撤销则返回 | ||
300 | } else { | ||
301 | File flawfinderFile = jfsettings.getSelectedFile(); | ||
302 | String flawfinderPathTemp = | ||
303 | flawfinderFile.getAbsolutePath(); | ||
304 | MyContorlUtil.fixSettingPath(settingsXML, | ||
305 | "flawfinder", flawfinderPathTemp); | ||
306 | changedpathflaw = true; | ||
307 | } | ||
308 | break; | ||
309 | } | ||
310 | } | ||
311 | }); | ||
312 | |||
313 | // 初始化主内容面板 | ||
314 | contentPanel = new MyContentPanel(); | ||
315 | try { | ||
316 | initSwing(); | ||
317 | } catch (UnsupportedEncodingException e1) { | ||
318 | e1.printStackTrace(); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | public static void main(String[] args) throws ParserConfigurationException { | ||
323 | |||
324 | SwingUtilities.invokeLater(new Runnable() { | ||
325 | public void run() { | ||
326 | MyContorlUtil.setupLookAndFeel(); | ||
327 | Main ui = new Main(); | ||
328 | ui.setVisible(true); | ||
329 | } | ||
330 | }); | ||
331 | } | ||
332 | |||
333 | private void execute(String src, String para) { | ||
334 | if (changedpathcpp) { | ||
335 | MyContorlUtil.loadToolsRoad(settingsXML, this); | ||
336 | changedpathcpp = false; | ||
337 | } | ||
338 | |||
339 | // 路径未配置,直接返回 | ||
340 | if (cppcheckPath == null) { | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | Runtime runtime = Runtime.getRuntime(); | ||
345 | Process p = null; | ||
346 | Runtime runtime1 = Runtime.getRuntime(); | ||
347 | Process p1 = null; | ||
348 | try { | ||
349 | // 指定模板执行cppcheck,格式化输出信息 | ||
350 | p = runtime.exec(String.format(cppcheckPath + | ||
351 | " --template=\"cppcheck${file}${line}${severity}${id}${message}${cwe}\" %s %s", | ||
352 | para, src)); | ||
353 | final InputStream is1 = p.getInputStream(); | ||
354 | final InputStream is2 = p.getErrorStream(); | ||
355 | |||
356 | // 不使用模板,捕获错误信息 | ||
357 | p1 = | ||
358 | runtime.exec(String.format(cppcheckPath + " %s %s", para, src)); | ||
359 | System.out.printf(cppcheckPath + " %s %s%n", para, src); | ||
360 | final InputStream is11 = p1.getInputStream(); | ||
361 | final InputStream is21 = p1.getErrorStream(); | ||
362 | |||
363 | // 处理标准输出 | ||
364 | new Thread() { | ||
365 | @SuppressWarnings("resource") | ||
366 | public void run() { | ||
367 | |||
368 | BufferedReader br1 = | ||
369 | new BufferedReader(new InputStreamReader(is1)); | ||
370 | //StringBuilder l1 = new StringBuilder(); | ||
371 | try { | ||
372 | |||
373 | String line1 = null; | ||
374 | int i = 0; | ||
375 | textCheck.setText(""); | ||
376 | while ((line1 = br1.readLine()) != null) { | ||
377 | i++; | ||
378 | textCheck.append(i + " " + line1 + ENTERWindows); | ||
379 | } | ||
380 | } catch (Exception e) { | ||
381 | e.printStackTrace(); | ||
382 | System.out.println("inputError"); | ||
383 | } finally { | ||
384 | try { | ||
385 | //textCheck.setText(new String(l1.toString().getBytes(), "utf-8")); | ||
386 | is1.close(); | ||
387 | } catch (IOException e) { | ||
388 | e.printStackTrace(); | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | }.start(); | ||
393 | |||
394 | // 处理错误流 | ||
395 | new Thread() { | ||
396 | public void run() { | ||
397 | BufferedReader br2 = | ||
398 | new BufferedReader(new InputStreamReader(is2)); | ||
399 | StringBuilder l2 = new StringBuilder(); | ||
400 | try { | ||
401 | String line2 = null; | ||
402 | while ((line2 = br2.readLine()) != null) { | ||
403 | ct.toRowsOfCppcheckResult(line2); | ||
404 | } | ||
405 | } catch (Exception e) { | ||
406 | e.printStackTrace(); | ||
407 | } finally { | ||
408 | try { | ||
409 | is2.close(); | ||
410 | } catch (IOException e) { | ||
411 | e.printStackTrace(); | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | }.start(); | ||
416 | |||
417 | // 第二次的错误流 | ||
418 | new Thread() { | ||
419 | public void run() { | ||
420 | BufferedReader br2 = | ||
421 | new BufferedReader(new InputStreamReader(is21)); | ||
422 | StringBuilder l2 = new StringBuilder(); | ||
423 | cppcheckResult.setText(""); | ||
424 | try { | ||
425 | String line2 = null; | ||
426 | int i = 0; | ||
427 | while ((line2 = br2.readLine()) != null) { | ||
428 | l2.append(i + " " + line2 + ENTERWindows); | ||
429 | i++; | ||
430 | } | ||
431 | } catch (Exception e) { | ||
432 | e.printStackTrace(); | ||
433 | } finally { | ||
434 | try { | ||
435 | cppcheckResult.setText( | ||
436 | new String(l2.toString().getBytes(), | ||
437 | StandardCharsets.UTF_8)); | ||
438 | is21.close(); | ||
439 | } catch (IOException e) { | ||
440 | e.printStackTrace(); | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | }.start(); | ||
445 | |||
446 | // 等待两个进程结束 | ||
447 | int exitCode = p.waitFor(); | ||
448 | int exitCode1 = p1.waitFor(); | ||
449 | if (exitCode == SUCCESS) { | ||
450 | System.out.println(SUCCESS_MESSAGE); | ||
451 | |||
452 | } else { | ||
453 | System.err.println(ERROR_MESSAGE + exitCode); | ||
454 | } | ||
455 | p.destroy(); | ||
456 | p1.destroy(); | ||
457 | } catch (Exception e) { | ||
458 | try { | ||
459 | // 出现异常则关闭相关流 | ||
460 | p.getErrorStream().close(); | ||
461 | p.getInputStream().close(); | ||
462 | p.getOutputStream().close(); | ||
463 | p1.getErrorStream().close(); | ||
464 | p1.getInputStream().close(); | ||
465 | p1.getOutputStream().close(); | ||
466 | } catch (Exception ee) { | ||
467 | } | ||
468 | } | ||
469 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
470 | try { | ||
471 | ct.makeTable(); | ||
472 | viewPanel = new ViewPanel(ct.results); | ||
473 | } catch (Exception e1) { | ||
474 | e1.printStackTrace(); | ||
475 | System.out.println("图表生成错误"); | ||
476 | } | ||
477 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
478 | tabPanel.isSelectTabComponents("结果"); | ||
479 | } else { | ||
480 | try { | ||
481 | ct.makeTable(); | ||
482 | viewPanel.update(ct.results); | ||
483 | } catch (Exception e1) { | ||
484 | e1.printStackTrace(); | ||
485 | System.out.println("图表生成错误"); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | |||
490 | private void execute2(String src) { | ||
491 | // clamh-tidy 检查 | ||
492 | Runtime runtime = Runtime.getRuntime(); | ||
493 | Process p = null; | ||
494 | try { | ||
495 | // 修改为执行 clang-tidy | ||
496 | String path = "C:\\MinGW\\include"; // FIXME: 需要修改为自己的路径 | ||
497 | Path srcPath = Paths.get(src); | ||
498 | String execable; | ||
499 | if (Files.isDirectory(srcPath)) { | ||
500 | // 是目录,则检查这个目录下所有cpp文件 | ||
501 | execable = String.format( | ||
502 | "clang-tidy %s\\*.cpp --checks=* --header-filter=%s -- -std=c++17 -I %s", | ||
503 | src, src, path); | ||
504 | } else { | ||
505 | // 是文件,直接执行 | ||
506 | execable = String.format( | ||
507 | "clang-tidy %s --checks=* --header-filter=%s -- -std=c++17 -I %s", | ||
508 | src, src, path); | ||
509 | } | ||
510 | //String execable1 = String.format("clang-tidy %s --checks=* --header-filter=%s -- -std=c++17 -I %s", src, src, path); | ||
511 | //String execable2 = String.format("clang-tidy %s\\*.cpp --checks=* --header-filter=%s -- -std=c++17 -I %s", src,src, path); | ||
512 | //String execable = String.format("clang-tidy %s\\*.cpp --checks='*,misc-no-delete-this,-llvmlibc-restrict-system-libc-headers,-modernize-use-trailing-return-type' -- -std=c++17 -I %s", src, path); | ||
513 | System.out.println(execable); | ||
514 | |||
515 | // 执行 | ||
516 | p = runtime.exec(execable); // -- 表示之后是源文件 | ||
517 | final InputStream is1 = p.getInputStream(); // 标准输出流 | ||
518 | final InputStream is2 = p.getErrorStream(); // clang-tidy 的错误流 | ||
519 | |||
520 | // 处理标准输出 | ||
521 | new Thread() { | ||
522 | public void run() { | ||
523 | BufferedReader br1 = | ||
524 | new BufferedReader(new InputStreamReader(is1)); | ||
525 | StringBuilder l1 = new StringBuilder(); | ||
526 | try { | ||
527 | String line1 = null; | ||
528 | while ((line1 = br1.readLine()) != null) { | ||
529 | // 只处理包含源文件路径的行 | ||
530 | if (line1.contains(src)) { | ||
531 | l1.append(line1).append(ENTERWindows); | ||
532 | // 如果有需要,可以将标准输出进行处理 | ||
533 | ct.toRowsOfClang(line1); | ||
534 | } | ||
535 | } | ||
536 | } catch (Exception e) { | ||
537 | e.printStackTrace(); | ||
538 | } finally { | ||
539 | try { | ||
540 | is1.close(); | ||
541 | } catch (IOException e) { | ||
542 | e.printStackTrace(); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | }.start(); | ||
547 | |||
548 | // FIXME: 这一部分是否必要? | ||
549 | //new Thread() { | ||
550 | // | ||
551 | // | ||
552 | // public void run() { | ||
553 | // BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); | ||
554 | // StringBuilder l2 = new StringBuilder(); | ||
555 | // try { | ||
556 | // String line2 = null; | ||
557 | // int i = 0; | ||
558 | // clangResult.setText(""); | ||
559 | // while ((line2 = br2.readLine()) != null) { | ||
560 | // l2.append(i + " " + line2 + ENTERWindows); | ||
561 | // ct.toRowsOfClang(line2); // 可能需要根据 clang-tidy 的输出格式进行调整 | ||
562 | // i++; | ||
563 | // } | ||
564 | // } catch (Exception e) { | ||
565 | // e.printStackTrace(); | ||
566 | // System.out.println("inputError"); | ||
567 | // } finally { | ||
568 | // try { | ||
569 | // clangResult.setText(l2.substring(0, l2.length())); | ||
570 | // is2.close(); | ||
571 | // } catch (IOException e) { | ||
572 | // e.printStackTrace(); | ||
573 | // } | ||
574 | // } | ||
575 | // } | ||
576 | //}.start(); | ||
577 | |||
578 | int exitCode = p.waitFor(); | ||
579 | if (exitCode == SUCCESS) { | ||
580 | System.out.println(SUCCESS_MESSAGE); | ||
581 | |||
582 | } else { | ||
583 | System.err.println(ERROR_MESSAGE + exitCode); | ||
584 | } | ||
585 | |||
586 | // 为什么需要关闭两次? | ||
587 | p.destroy(); | ||
588 | p.destroy(); | ||
589 | } catch (Exception e) { | ||
590 | try { | ||
591 | p.getInputStream().close(); | ||
592 | p.getOutputStream().close(); | ||
593 | p.getErrorStream().close(); | ||
594 | } catch (Exception ee) { | ||
595 | } | ||
596 | } | ||
597 | |||
598 | // 更新或者创建结果标签页,显示结果 | ||
599 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
600 | try { | ||
601 | ct.makeTable(); | ||
602 | viewPanel = new ViewPanel(ct.results); | ||
603 | } catch (Exception e1) { | ||
604 | e1.printStackTrace(); | ||
605 | System.out.println("图表生成错误"); | ||
606 | } | ||
607 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
608 | tabPanel.isSelectTabComponents("结果"); | ||
609 | } else { | ||
610 | try { | ||
611 | ct.makeTable(); | ||
612 | viewPanel.update(ct.results); | ||
613 | } catch (Exception e1) { | ||
614 | e1.printStackTrace(); | ||
615 | System.out.println("图表生成错误"); | ||
616 | } | ||
617 | } | ||
618 | } | ||
619 | |||
620 | private void execute3(String src, String para, String tmpFileName) { | ||
621 | // flawfinder | ||
622 | if (changedpathflaw) { | ||
623 | MyContorlUtil.loadToolsRoad(settingsXML, this); | ||
624 | changedpathflaw = false; | ||
625 | } | ||
626 | |||
627 | if (flawfinderPath == null) { | ||
628 | return; | ||
629 | } | ||
630 | Runtime runtime = Runtime.getRuntime(); | ||
631 | Process p = null; | ||
632 | Runtime runtime2 = Runtime.getRuntime(); | ||
633 | Process p2 = null; | ||
634 | try { | ||
635 | |||
636 | // 两个参数数组,一个是csv格式,一个是传入的参数 | ||
637 | String[] arguments = | ||
638 | new String[] {"python", flawfinderPath, "--csv", src}; | ||
639 | String[] arguments2 = | ||
640 | new String[] {"python", flawfinderPath, para, src}; | ||
641 | |||
642 | p = runtime.exec(arguments); | ||
643 | p2 = runtime.exec(arguments2); | ||
644 | final InputStream is1 = p.getInputStream(); | ||
645 | final InputStream is2 = p2.getInputStream(); | ||
646 | System.out.println(arguments2[1]); | ||
647 | |||
648 | // csv结果添加到表格 | ||
649 | new Thread() { | ||
650 | public void run() { | ||
651 | BufferedReader br1 = | ||
652 | new BufferedReader(new InputStreamReader(is1)); | ||
653 | try { | ||
654 | String line1 = null; | ||
655 | while ((line1 = br1.readLine()) != null) { | ||
656 | ct.toRowsOfflawfinder(line1); | ||
657 | } | ||
658 | } catch (Exception e) { | ||
659 | e.printStackTrace(); | ||
660 | } finally { | ||
661 | try { | ||
662 | is1.close(); | ||
663 | } catch (IOException e) { | ||
664 | e.printStackTrace(); | ||
665 | } | ||
666 | } | ||
667 | } | ||
668 | }.start(); | ||
669 | |||
670 | // 普通结果显示在文本框 | ||
671 | new Thread() { | ||
672 | public void run() { | ||
673 | //flawfinder result | ||
674 | BufferedReader br1 = | ||
675 | new BufferedReader(new InputStreamReader(is2)); | ||
676 | StringBuilder l1 = new StringBuilder(); | ||
677 | flawfinderResult.setText(""); | ||
678 | try { | ||
679 | String line1 = null; | ||
680 | while ((line1 = br1.readLine()) != null) { | ||
681 | l1.append(line1 + ENTERWindows); | ||
682 | } | ||
683 | } catch (Exception e) { | ||
684 | e.printStackTrace(); | ||
685 | } finally { | ||
686 | try { | ||
687 | flawfinderResult.setText( | ||
688 | l1.substring(0, l1.length())); | ||
689 | is2.close(); | ||
690 | } catch (IOException e) { | ||
691 | e.printStackTrace(); | ||
692 | } | ||
693 | } | ||
694 | } | ||
695 | }.start(); | ||
696 | |||
697 | int exitCode = p.waitFor(); | ||
698 | int exitCode2 = p2.waitFor(); | ||
699 | if (exitCode == SUCCESS) { | ||
700 | System.out.println(SUCCESS_MESSAGE); | ||
701 | } else { | ||
702 | System.err.println(ERROR_MESSAGE + exitCode); | ||
703 | } | ||
704 | p.destroy(); | ||
705 | p2.destroy(); | ||
706 | } catch (Exception e) { | ||
707 | try { | ||
708 | p.getErrorStream().close(); | ||
709 | p.getInputStream().close(); | ||
710 | p.getOutputStream().close(); | ||
711 | p2.getErrorStream().close(); | ||
712 | p2.getInputStream().close(); | ||
713 | p2.getOutputStream().close(); | ||
714 | } catch (Exception ee) { | ||
715 | } | ||
716 | } | ||
717 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
718 | try { | ||
719 | ct.makeTable(); | ||
720 | viewPanel = new ViewPanel(ct.results); | ||
721 | } catch (Exception e1) { | ||
722 | e1.printStackTrace(); | ||
723 | System.out.println("图表生成错误"); | ||
724 | } | ||
725 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
726 | tabPanel.isSelectTabComponents("结果"); | ||
727 | } else { | ||
728 | try { | ||
729 | ct.makeTable(); | ||
730 | viewPanel.update(ct.results); | ||
731 | } catch (Exception e1) { | ||
732 | e1.printStackTrace(); | ||
733 | System.out.println("图表生成错误"); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | } | ||
738 | |||
739 | private void initSwing() throws UnsupportedEncodingException { | ||
740 | setTitle("Cppcheckplus"); | ||
741 | setDefaultCloseOperation(3); // 关闭窗口时退出程序 | ||
742 | setSize(1024, 768); | ||
743 | |||
744 | // 设置窗口图标 | ||
745 | setIconImage(MyContorlUtil.getImage("control/images/logo2.png")); | ||
746 | setContentPane(contentPanel); | ||
747 | // 菜单栏在最上方 | ||
748 | contentPanel.add(menubar, "North"); | ||
749 | |||
750 | // 除却菜单栏之外的面板 | ||
751 | //JPanel centerPane = new JPanel(new BorderLayout()); | ||
752 | |||
753 | // 中间区域,除了菜单栏之外的所有内容 | ||
754 | MyPanel centerPane = new MyPanel(new BorderLayout()); | ||
755 | centerPane.setOpaque(true); | ||
756 | //centerPane.setBackground(MyContorlUtil.CONTENT_PANE_BACKGROUND3); | ||
757 | //centerPane.setBackground(MyContorlUtil.getImage("control/images/logo2.png")); | ||
758 | centerPane.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); | ||
759 | contentPanel.add(centerPane, "Center"); | ||
760 | |||
761 | // 初始化各个标签页、侧边栏、目录树 | ||
762 | initTab(); | ||
763 | initTab2(); | ||
764 | initOutlookPanel(); | ||
765 | try { | ||
766 | initShortcutPanel(); | ||
767 | } catch (UnsupportedEncodingException e) { | ||
768 | // TODO Auto-generated catch block | ||
769 | e.printStackTrace(); | ||
770 | } | ||
771 | initTree(); | ||
772 | |||
773 | // 面板加入布局 | ||
774 | centerPane.add(outlookPanel, "West"); | ||
775 | centerPane.add(tabPanel, "Center"); | ||
776 | centerPane.add(shortcutPanel, "East"); | ||
777 | |||
778 | // 底部添加第二个标签页面板,用于显示检查结果 | ||
779 | contentPanel.add(tabPanel2, BorderLayout.SOUTH); | ||
780 | } | ||
781 | |||
782 | private void initTree() { | ||
783 | tree = shortcutPanel.mytree; | ||
784 | // 点击目录树节点,显示对应文件内容 | ||
785 | tree.setCode(textCode, this); | ||
786 | } | ||
787 | |||
788 | private void initOutlookPanel() { | ||
789 | outlookPanel = new MyOutlookPanel(new ActionListener() { | ||
790 | @Override | ||
791 | public void actionPerformed(ActionEvent e) { | ||
792 | String command = e.getActionCommand(); | ||
793 | System.out.println("Head:" + command); | ||
794 | } | ||
795 | |||
796 | }, new ListSelectionListener() { | ||
797 | @Override | ||
798 | public void valueChanged(ListSelectionEvent e) { | ||
799 | boolean adjust = e.getValueIsAdjusting(); | ||
800 | if (!adjust) { | ||
801 | JList list = (JList) e.getSource(); | ||
802 | Object[] selectionValues = list.getSelectedValues(); | ||
803 | MyOutlookPanelListItem item = | ||
804 | (MyOutlookPanelListItem) selectionValues[0]; | ||
805 | String command = item.getActionCommand(); | ||
806 | if (command.equals("Chart2")) { | ||
807 | // 如果TabPanel不存在就create,否则就切换 | ||
808 | if (!tabPanel.isSelectTabComponents("结果")) { | ||
809 | try { | ||
810 | ct.makeTable(); | ||
811 | viewPanel = new ViewPanel(ct.results); | ||
812 | } catch (Exception e1) { | ||
813 | e1.printStackTrace(); | ||
814 | System.out.println("图表生成错误"); | ||
815 | } | ||
816 | tabPanel.addTab("结果", createPage(viewPanel)); | ||
817 | tabPanel.isSelectTabComponents("结果"); | ||
818 | } | ||
819 | } else if (command.equals("Map")) { | ||
820 | // 代码标签页 | ||
821 | if (!tabPanel.isSelectTabComponents("代码")) { | ||
822 | tabPanel.addTab("代码", testCode); | ||
823 | tabPanel.isSelectTabComponents("代码"); | ||
824 | } | ||
825 | } else if (command.equals("Process")) { | ||
826 | // 进度 | ||
827 | if (!tabPanel.isSelectTabComponents("进度")) { | ||
828 | tabPanel.addTab("进度", textCheck); | ||
829 | tabPanel.isSelectTabComponents("进度"); | ||
830 | } | ||
831 | } | ||
832 | } | ||
833 | } | ||
834 | |||
835 | }); | ||
836 | // 根据XML配置文件加载Outlook面板内容 | ||
837 | MyContorlUtil.loadOutlookPanel(outlookPanelXML, outlookPanel); | ||
838 | } | ||
839 | |||
840 | private void initTab() { | ||
841 | tabPanel = new MyTabPanel(); | ||
842 | tabPanel.addMouseListener(new MouseAdapter() { | ||
843 | private boolean isMaximized() { | ||
844 | return outlookPanel.isShrinked(); | ||
845 | } | ||
846 | |||
847 | public void mouseClicked(MouseEvent e) { | ||
848 | if (e.getClickCount() > 1) { | ||
849 | TabbedPaneUI ui = tabPanel.getUI(); | ||
850 | int tabIndex = | ||
851 | ui.tabForCoordinate(tabPanel, e.getX(), e.getY()); | ||
852 | if (tabIndex != -1) { | ||
853 | boolean maxed = isMaximized(); | ||
854 | outlookPanel.setShrink(!maxed); | ||
855 | shortcutPanel.setShrink(!maxed); | ||
856 | } | ||
857 | } | ||
858 | } | ||
859 | }); | ||
860 | |||
861 | testCode = new MyTextPanel(); | ||
862 | testPanel = new MyTextPanel1(); | ||
863 | viewPanel = new ViewPanel(); | ||
864 | textCode = testCode.getTextArea(); | ||
865 | textCheck = testPanel.getTextArea(); | ||
866 | } | ||
867 | |||
868 | private void initTab2() { | ||
869 | tabPanel2 = new MyTabPanel1(); | ||
870 | tabPanel2.addMouseListener(new MouseAdapter() { | ||
871 | private boolean isMaximized() { | ||
872 | return outlookPanel.isShrinked(); | ||
873 | } | ||
874 | |||
875 | public void mouseClicked(MouseEvent e) { | ||
876 | if (e.getClickCount() > 1) { | ||
877 | TabbedPaneUI ui = tabPanel2.getUI(); | ||
878 | int tabIndex = | ||
879 | ui.tabForCoordinate(tabPanel2, e.getX(), e.getY()); | ||
880 | if (tabIndex != -1) { | ||
881 | boolean maxed = isMaximized(); | ||
882 | outlookPanel.setShrink(!maxed); | ||
883 | shortcutPanel.setShrink(!maxed); | ||
884 | } | ||
885 | } | ||
886 | } | ||
887 | }); | ||
888 | |||
889 | flawfinderPanel = new MyTextPanel1(); | ||
890 | cppcheckPanel = new MyTextPanel1(); | ||
891 | clangPanel = new MyTextPanel1(); | ||
892 | flawfinderResult = flawfinderPanel.getTextArea(); | ||
893 | cppcheckResult = cppcheckPanel.getTextArea(); | ||
894 | clangResult = clangPanel.getTextArea(); | ||
895 | |||
896 | tabPanel2.addTab("cppcheck", createPage1(cppcheckPanel)); | ||
897 | tabPanel2.addTab("Clang", createPage1(clangPanel)); | ||
898 | tabPanel2.addTab("flawfinder", createPage1(flawfinderPanel)); | ||
899 | } | ||
900 | |||
901 | private MyTabPage1 createPage1(JComponent pageContent) { | ||
902 | MyTabPage1 page = new MyTabPage1(pageContent); | ||
903 | return page; | ||
904 | } | ||
905 | |||
906 | private MyTabPage createPage(JComponent pageContent) { | ||
907 | MyTabPage page = new MyTabPage(pageContent); | ||
908 | return page; | ||
909 | } | ||
910 | |||
911 | //改造成目录树 | ||
912 | private void initShortcutPanel() throws UnsupportedEncodingException { | ||
913 | shortcutPanel = new MyShortcutPanel(); | ||
914 | shortcutPanel.setTitle( | ||
915 | new String("项目".getBytes(), StandardCharsets.UTF_8)); | ||
916 | } | ||
917 | } | ||