首页 > 学院 > 开发设计 > 正文

c# 简易绘制C语言头文件包含关系图

2019-11-17 02:50:21
字体:
来源:转载
供稿:网友

c# 简易绘制C语言头文件包含关系图

最近在做一个项目的移植工作,项目很大,光c文件大约有1800多。由于某些需要,想要对某些代码文件引用的.h文件进行分析。

网上找了好久,暂无发现类似的工具。

正好,今天放假,就做了这么个工具。

好了,废话不多说了,先上图。

QQ截图20141012191057

由于是自己做的个demo,所以只是先注重大体功能上的实现,细节上还有很多不足。比如没有使用多线程,去除代码文件中注释的地方还有个漏洞(文件读取1M导致的,不过几乎没影响),还有循环绘制node的地方(逻辑上稍微修改下更好)。

后面奉上代码,大家可以自己根据需求继续修改,也可以凑合这么用。

言归正传。

树形关系呈现上使用了DotNetBar中的TreeGX控件。下载地址:

http://down2.cr173.com/soft1/DotNetBarSetup.zip

先setup,再patcher。

装好后,先添加引用,然后在工具箱中添加treeGX。

QQ截图20141012200812

没错,项目名Jonce,“穷死”。好名字。

界面布局。

QQ截图20141012202708

其实整个流程很简单,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();
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表