首页 > 代码库 > c# 简易绘制C语言头文件包含关系图
c# 简易绘制C语言头文件包含关系图
最近在做一个项目的移植工作,项目很大,光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。
c# 简易绘制C语言头文件包含关系图
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。