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