最近在做一个项目的移植工作,项目很大,光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文件内容:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Jonce
  7. {
  8. struct CType
  9. {
  10. public string FullPath;
  11. public string FileName;
  12. public List<string> IncludeList;
  13. }
  14. }

该类型用于描述每个代码文件。

CFileHelper.cs文件内容:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. namespace Jonce
  7. {
  8. class CFileHelper
  9. {
  10. private List<string> fileList = new List<string>();
  11. /// <summary>
  12. /// 获取及分析所有C代码文件
  13. /// </summary>
  14. /// <param name="path">C项目路径</param>
  15. /// <returns></returns>
  16. public List<CType> GetAllCFile(string path)
  17. {
  18. List<CType> retList = new List<CType>();
  19.  
  20. getAllByPath(path);
  21. //过滤出所有文件中的代码文件
  22. //分析引用,并存入List<CType>结构内
  23. foreach (string item in fileList)
  24. {
  25. string extension = Path.GetExtension(item).ToLower();
  26. if (extension == ".c" || extension == ".h" || extension == ".cpp")
  27. {
  28. CType cType = new CType();
  29. cType.FullPath = item;
  30. cType.FileName = Path.GetFileName(item);
  31. //获取C文件中include引用的头文件
  32. cType.IncludeList = SourceHelper.GetIncludeFile(SourceHelper.RemoveComments(item));
  33. retList.Add(cType);
  34. }
  35. }
  36.  
  37. return retList;
  38. }
  39. //获取指定目录下的所有文件
  40. private void getAllByPath(string path)
  41. {
  42. if (path.EndsWith("\\"))
  43. {
  44. fileList.Add(path);
  45. }
  46. else
  47. {
  48. fileList.Add(path + "\\");
  49. }
  50.  
  51. string[] dirs = Directory.GetDirectories(path);
  52. fileList.AddRange(Directory.GetFiles(path));
  53. foreach (string dir in dirs)
  54. {
  55. getAllByPath(dir.ToString());
  56. }
  57. }
  58. }
  59. }

SourceHelper.cs文件内容:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Windows.Forms;
  7. using System.Text.RegularExpressions;
  8. namespace Jonce
  9. {
  10. class SourceHelper
  11. {
  12. /// <summary>
  13. /// 去掉代码文件中的注释
  14. /// </summary>
  15. /// <param name="filePath">文件全路径</param>
  16. /// <returns>文件前1M内容(去掉注释)</returns>
  17. public static string RemoveComments(string filePath)
  18. {
  19. string retStr = "";
  20. //1M缓冲区
  21. char[] buffer = new char[1024 * 1024];
  22. using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
  23. {
  24. using (StreamReader sr = new StreamReader(fs, Encoding.Default))
  25. {
  26. try
  27. {
  28. //string fileStr = sr.ReadToEnd();
  29. //读取文件。只读取<=1M内容
  30. sr.Read(buffer, 0, buffer.Length);
  31. //字符数组转换为字符串,进行正则匹配
  32. string fileStr = new string(buffer);
  33. //正则表达式,匹配多行注释和单行注释
  34. string regStr = @"/\*[\s\S]*?\*/|//.*";
  35. //去掉多行注释
  36. retStr = Regex.Replace(fileStr, regStr, "");
  37.  
  38. }
  39. catch (Exception ex)
  40. {
  41. MessageBox.Show(ex.ToString(), "ERR");
  42. }
  43.  
  44. }
  45.  
  46. }
  47. return retStr;
  48. }
  49. /// <summary>
  50. /// 获取C文件中include引用的头文件
  51. /// </summary>
  52. /// <param name="fileStr">文件全路径</param>
  53. /// <returns>头文件List集合</returns>
  54. public static List<string> GetIncludeFile(string fileStr)
  55. {
  56. List<string> headFileList = new List<string>();
  57. //匹配include语句
  58. string regStr1 = @"#\s*include\s(""|<).*";
  59. //匹配头文件
  60. string regStr2 = @"\w+\.(h|H)\b";
  61.  
  62. Match mc1 = Regex.Match(fileStr, regStr1);
  63. while (mc1.Success)
  64. {
  65. Match mc2 = Regex.Match(mc1.ToString(), regStr2);
  66. if (mc2.Success)
  67. {
  68. headFileList.Add(mc2.ToString());
  69. }
  70. mc1 = mc1.NextMatch();
  71. }
  72. return headFileList;
  73. }
  74. }
  75. }

Form1.cs内容:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;
  10. using DevComponents.Tree;
  11. namespace Jonce
  12. {
  13. public partial class Form1 : Form
  14. {
  15. public Form1()
  16. {
  17. InitializeComponent();
  18. }
  19.  
  20. private void button1_Click(object sender, EventArgs e)
  21. {
  22. //选取目录
  23. FolderBrowserDialog fbd = new FolderBrowserDialog();
  24. if (fbd.ShowDialog()==DialogResult.OK)
  25. {
  26. string path = fbd.SelectedPath;
  27. CFileHelper fileHelper = new CFileHelper();
  28. //获取及分析所有C代码文件
  29. List<CType> cTypeList = fileHelper.GetAllCFile(path);
  30. //treeGX.Node节点用style
  31. ElementStyle style = new ElementStyle();
  32. //节点文字颜色设置
  33. style.TextColor = Color.Blue;
  34. foreach (CType item in cTypeList)
  35. {
  36. if (Path.GetExtension(item.FullPath).ToLower() == ".c")
  37. {
  38. Node cNode = new Node();
  39. cNode.Name = item.FileName;
  40. cNode.Text = item.FileName;
  41. cNode.Style = style;
  42. cNode.NodeDoubleClick += cNode_NodeDoubleClick;
  43. this.node1.Nodes.Add(cNode);
  44. loopDraw(cTypeList, item.FileName, ref cNode);
  45. }
  46. }
  47. //this.node1.ExpandAll();
  48. this.node1.Text = path;
  49. //刷新treeGX
  50. this.treeGX1.Refresh();
  51. }
  52.  
  53. }
  54.  
  55. void cNode_NodeDoubleClick(object sender, EventArgs e)
  56. {
  57. Node node = sender as Node;
  58. node.Expand();
  59. //node.ExpandAll();
  60. //throw new NotImplementedException();
  61. }
  62. private void loopDraw(List<CType> cTypeList, string fileName,ref Node node)
  63. {
  64. foreach (CType item in cTypeList)
  65. {
  66. if (item.FileName==fileName)
  67. {
  68. foreach (string strItem in item.IncludeList)
  69. {
  70. Node incNode = new Node();
  71. incNode.Name = strItem;
  72. incNode.Text = strItem;
  73. incNode.NodeDoubleClick += cNode_NodeDoubleClick;
  74. node.Nodes.Add(incNode);
  75. loopDraw(cTypeList, strItem, ref incNode);
  76. }
  77. }
  78. }
  79. }
  80.  
  81. private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
  82. {
  83. if (comboBox1.SelectedItem==null)
  84. {
  85. return;
  86. }
  87. //DevComponents.Tree.eNodeLayout layout = (DevComponents.Tree.eNodeLayout)Enum.Parse(typeof(DevComponents.Tree.eNodeLayout), comboBox1.SelectedItem.ToString());
  88. DevComponents.Tree.eMapFlow mapFlow = (DevComponents.Tree.eMapFlow)Enum.Parse(typeof(DevComponents.Tree.eMapFlow), comboBox1.SelectedItem.ToString());
  89. if (treeGX1.MapLayoutFlow != mapFlow)
  90. {
  91. treeGX1.MapLayoutFlow = mapFlow;
  92. treeGX1.RecalcLayout();
  93. treeGX1.Refresh();
  94. }
  95. }
  96.  
  97. private void button2_Click(object sender, EventArgs e)
  98. {
  99. this.node1.ExpandAll();
  100. treeGX1.Refresh();
  101.  
  102. }
  103.  
  104. private void button3_Click(object sender, EventArgs e)
  105. {
  106. this.node1.Nodes.Clear();
  107. treeGX1.Refresh();
  108.  
  109. }
  110. }
  111. }

 

以上就是所有代码,大家可以自己重新搭建一个。

当然,如果谁csdn下载积分多的,也可以下载整个项目:http://download.csdn.net/detail/geeking/8030119

只要两个下载积分。本来想免费发的,可是我的积分一个也没有了,很多资源都没法下。shit,积分制度就是shit。

c# 简易绘制C语言头文件包含关系图的更多相关文章

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

    老规矩,先上图 节点样式说明: 1.粉色圆角,说明该节点下有循环引用 2.黄色菱形,说明该节点代表的文件在项目目录下未找到. 3.红色圆角,说明循环引用(从开始到最终,这种感情没变过,没有谁..... ...

  2. 利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图

    作为一名linux系统下的C语言开发,日常工作中经常遇到两个问题: 一是分析代码过程中,各种数据结构互相关联,只通过代码很难理清系统中所有结构体的整体架构,影响代码消化的效率; 二是多层头文件嵌套包含 ...

  3. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  4. c头文件包含关系--记今天调试的郁闷经历

    c头文件包含关系--记今天调试的郁闷经历 彭会锋 2016-08-05  21:54:08 c头文件的包含

  5. 嵌入式C语言头文件的建立与使用

    如何正确编写 C 语言头文件和与之相关联的 c 源程序文件,这首先就要了解它们的各自功能. 要理解 C 文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程. 一般说来编译器会做以下几 ...

  6. 51单片机C语言学习笔记6:51单片机C语言头文件及其使用

    很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这个是在头文件中用sfr定义的,现在定义好了的是这样的 sfr P1 ...

  7. C语言头文件

    最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是比 ...

  8. C++标准库头文件名字和C语言头文件名字的区别

    1.C++版本的C标准库头文件,一般是cname,而C语言头文件一般是name.h 2.命名为cname的头文件中定义的名字都是从std中来的,而如果是name.h则不是这样的. 3.与是用name. ...

  9. C语言头文件的使用(转载)

    C语言头文件的使用 ——by janders 转载请注名作者和出处,谢谢! C语言中的.h文件和我认识由来已久,其使用方法虽不十分复杂,但我却是经过了几个月的“不懂”时期,几年的“一知半解”时期才逐渐 ...

随机推荐

  1. Fedora 中多显示器环境下的工作区切换

    [Dual monitor workspaces] 默认情况下,fedora中 Gnome 桌面环境在切换工作去的时候,只会在 Primary display 上切换, 其他显示器保持不变.如果要实现 ...

  2. JS内置对象-String对象、Date日期对象、Array数组对象、Math对象

    一.JavaScript中的所有事物都是对象:字符串.数组.数值.函数... 1.每个对象带有属性和方法 JavaScript允许自定义对象 2.自定义对象 a.定义并创建对象实例 b.使用函数来定义 ...

  3. 12.SolrCloud原理

    转载自http://blog.csdn.net/u011026968/article/details/50336709 内容涉及:SolrCloud的基础知识.架构.索引创建和更新.查询.故障恢复.负 ...

  4. canvas实例_在线画图工具

    fadsfklasdjfklasjdklfjasdlk;fjasd;lfjaskl;dfjal

  5. BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)

    Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏- ...

  6. android studio 导入module作为lib使用

    1.将 android module导入 android project 中  2.在要作为lib导入的module 的build.gradle文件中添加一行 “apply plugin: ‘andr ...

  7. Thinkphp5.0分页和跳页

    后台查询商品或者会员量需要用到分页展示列表,当页数比较多的时候为了体高用户体验度,需要添加一个跳页也就是手动输入页码数进行快速跳转指定页面.由于手动编写分页比较麻烦,又想使用TP5自带的分页,但是TP ...

  8. 理解RHEL上安装oracle的配置参数 :/etc/security/limits.conf, /etc/profile, /etc/pam.d/login

    无论安装什么版本的Oracle,在安装之前,都需要配置 /etc/pam.d/login   /etc/profile   /etc/security/limits.conf这三个文件 那这三个文件究 ...

  9. Jmeter性能测试-分布式压力测试

    作为一个测试行业的菜鸟,由于投身于一个小公司,包揽所有的测试.刚开始的功能测试到接口测试,稳定性测试,兼容性测试等,一般由于是小项目所以对于性能有所忽略,也没怎么涉及,公司接了个大项目,后期对于性能上 ...

  10. nano,pico文本编辑器,debian执行crontab -e

    debian执行crontab -e的时候出现: Edit this file to introduce tasks to be run by cron.## Each task to run has ...