最近在做一個項目的移植工作,項目很大,光c文件大約有1800多。由于某些需要,想要對某些代碼文件引用的.h文件進行分析。
網上找了好久,暫無發現類似的工具。
正好,今天放假,就做了這么個工具。
好了,廢話不多說了,先上圖。
由于是自己做的個demo,所以只是先注重大體功能上的實現,細節上還有很多不足。比如沒有使用多線程,去除代碼文件中注釋的地方還有個漏洞(文件讀取1M導致的,不過幾乎沒影響),還有循環繪制node的地方(邏輯上稍微修改下更好)。
后面奉上代碼,大家可以自己根據需求繼續修改,也可以湊合這么用。
言歸正傳。
樹形關系呈現上使用了DotNetBar中的TreeGX控件。下載地址:
http://down2.cr173.com/soft1/DotNetBarSetup.zip先setup,再patcher。
裝好后,先添加引用,然后在工具箱中添加treeGX。
沒錯,項目名Jonce,“窮死”。好名字。
界面布局。
其實整個流程很簡單,1獲取指定目錄下的所有代碼文件;2分析出文件中#include包含的文件;3繪制node節點
CType.cs文件內容:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Jonce{ struct CType { public string FullPath; public string FileName; public List<string> IncludeList; }}
該類型用于描述每個代碼文件。
CFileHelper.cs文件內容:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;namespace Jonce{ class CFileHelper { PRivate List<string> fileList = new List<string>(); /// <summary> /// 獲取及分析所有C代碼文件 /// </summary> /// <param name="path">C項目路徑</param> /// <returns></returns> public List<CType> GetAllCFile(string path) { List<CType> retList = new List<CType>(); getAllByPath(path); //過濾出所有文件中的代碼文件 //分析引用,并存入List<CType>結構內 foreach (string item in fileList) { string extension = Path.GetExtension(item).ToLower(); if (extension == ".c" || extension == ".h" || extension == ".cpp") { CType cType = new CType(); cType.FullPath = item; cType.FileName = Path.GetFileName(item); //獲取C文件中include引用的頭文件 cType.IncludeList = SourceHelper.GetIncludeFile(SourceHelper.RemoveComments(item)); retList.Add(cType); } } return retList; } //獲取指定目錄下的所有文件 private void getAllByPath(string path) { if (path.EndsWith("//")) { fileList.Add(path); } else { fileList.Add(path + "//"); } string[] dirs = Directory.GetDirectories(path); fileList.AddRange(Directory.GetFiles(path)); foreach (string dir in dirs) { getAllByPath(dir.ToString()); } } }}
SourceHelper.cs文件內容:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Windows.Forms;using System.Text.RegularExpressions;namespace Jonce{ class SourceHelper { /// <summary> /// 去掉代碼文件中的注釋 /// </summary> /// <param name="filePath">文件全路徑</param> /// <returns>文件前1M內容(去掉注釋)</returns> public static string RemoveComments(string filePath) { string retStr = ""; //1M緩沖區 char[] buffer = new char[1024 * 1024]; using (FileStream fs = new FileStream(filePath, FileMode.Open, Fileaccess.Read)) { using (StreamReader sr = new StreamReader(fs, Encoding.Default)) { try { //string fileStr = sr.ReadToEnd(); //讀取文件。只讀取<=1M內容 sr.Read(buffer, 0, buffer.Length); //字符數組轉換為字符串,進行正則匹配 string fileStr = new string(buffer); //正則表達式,匹配多行注釋和單行注釋 string regStr = @"//*[/s/S]*?/*/|//.*"; //去掉多行注釋 retStr = Regex.Replace(fileStr, regStr, ""); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "ERR"); } } } return retStr; } /// <summary> /// 獲取C文件中include引用的頭文件 /// </summary> /// <param name="fileStr">文件全路徑</param> /// <returns>頭文件List集合</returns> public static List<string> GetIncludeFile(string fileStr) { List<string> headFileList = new List<string>(); //匹配include語句 string regStr1 = @"#/s*include/s(""|<).*"; //匹配頭文件 string regStr2 = @"/w+/.(h|H)/b"; Match mc1 = Regex.Match(fileStr, regStr1); while (mc1.Success) { Match mc2 = Regex.Match(mc1.ToString(), regStr2); if (mc2.Success) { headFileList.Add(mc2.ToString()); } mc1 = mc1.NextMatch(); } return headFileList; } }}
Form1.cs內容:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.IO;using DevComponents.Tree;namespace Jonce{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //選取目錄 FolderBrowserDialog fbd = new FolderBrowserDialog(); if (fbd.ShowDialog()==DialogResult.OK) { string path = fbd.SelectedPath; CFileHelper fileHelper = new CFileHelper(); //獲取及分析所有C代碼文件 List<CType> cTypeList = fileHelper.GetAllCFile(path); //treeGX.Node節點用style ElementStyle style = new ElementStyle(); //節點文字顏色設置 style.TextColor = Color.Blue; foreach (CType item in cTypeList) { if (Path.GetExtension(item.FullPath).ToLower() == ".c") { Node cNode = new Node(); cNode.Name = item.FileName; cNode.Text = item.FileName; cNode.Style = style; cNode.NodeDoubleClick += cNode_NodeDoubleClick; this.node1.Nodes.Add(cNode); loopDraw(cTypeList, item.FileName, ref cNode); } } //this.node1.ExpandAll(); this.node1.Text = path; //刷新treeGX this.treeGX1.Refresh(); } } void cNode_NodeDoubleClick(object sender, EventArgs e) { Node node = sender as Node; node.Expand();
|
新聞熱點
疑難解答