在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近在做一个项目的移植工作,项目很大,光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(); //node.ExpandAll(); //throw new NotImplementedException(); } private void loopDraw(List<CType> cTypeList, string fileName,ref Node node) { foreach (CType item in cTypeList) { if (item.FileName==fileName) { foreach (string strItem in item.IncludeList) { Node incNode = new Node(); incNode.Name = strItem; incNode.Text = strItem; incNode.NodeDoubleClick += cNode_NodeDoubleClick; node.Nodes.Add(incNode); loopDraw(cTypeList, strItem, ref incNode); } } } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox1.SelectedItem==null) { return; } //DevComponents.Tree.eNodeLayout layout = (DevComponents.Tree.eNodeLayout)Enum.Parse(typeof(DevComponents.Tree.eNodeLayout), comboBox1.SelectedItem.ToString()); DevComponents.Tree.eMapFlow mapFlow = (DevComponents.Tree.eMapFlow)Enum.Parse(typeof(DevComponents.Tree.eMapFlow), comboBox1.SelectedItem.ToString()); if (treeGX1.MapLayoutFlow != mapFlow) { treeGX1.MapLayoutFlow = mapFlow; treeGX1.RecalcLayout(); treeGX1.Refresh(); } } private void button2_Click(object sender, EventArgs e) { this.node1.ExpandAll(); treeGX1.Refresh(); } private void button3_Click(object sender, EventArgs e) { this.node1.Nodes.Clear(); treeGX1.Refresh(); } } }
以上就是所有代码,大家可以自己重新搭建一个。 当然,如果谁csdn下载积分多的,也可以下载整个项目:http://download.csdn.net/detail/geeking/8030119 只要两个下载积分。本来想免费发的,可是我的积分一个也没有了,很多资源都没法下。shit,积分制度就是shit。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论