最近在做一個項目的移植工作,項目很大,光c文件大約有1800多。由於某些需要,想要對某些代碼文件引用的.h文件進行分析。
網上找了好久,暫無發現類似的工具。
正好,今天放假,就做了這麼個工具。
好了,廢話不多說了,先上圖。
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。
這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#include<stdio.h>
struct STU //定義一個結構體
{
int num;
}stu;
int main()
{
struct STU *p; //定義一個結構體指針
p=stu; //p指向stu這個結構體變量
stu.num=100; //給結構體成員num附個初值
printf("%d",p->num); //輸出stu中的num的值
return;
}
看到了吧,->的作法就是在引用結構體中的變量!!
形式如:p->結構體成員(如p->num)
他的作用相當於stu.num或(*p).num
不知道這樣解釋你明不明白、、、、、不懂了call我,O(∩_∩)O~
望采納。
這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#include<stdio.h>
struct STU //定義一個結構體
{
int num;
}stu;
int main()
{
struct STU *p; //定義一個結構體指針
p=stu; //p指向stu這個結構體變量
stu.num=100; //給結構體成員num附個初值
printf("%d",p->num); //輸出stu中的num的值
return;
}
看到了吧,->的作法就是在引用結構體中的變量!!
形式如:p->結構體成員(如p->num)
他的作用相當於stu.num或(*p).num
不知道這樣解釋你明不明白、、、、、不懂了call我,O(∩_∩)O~
望采納。