码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2014-10-12 22:50:08      阅读:470      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   io   os   使用   ar   

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

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

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

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

bubuko.com,布布扣

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

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

言归正传。

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

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

先setup,再patcher。

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

bubuko.com,布布扣

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

界面布局。

bubuko.com,布布扣

其实整个流程很简单,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语言头文件包含关系图

标签:des   style   blog   http   color   io   os   使用   ar   

原文地址:http://www.cnblogs.com/geeking/p/4021044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!