为代码文件的include关系生成Mermaid图

目标

类似《为代码中的类继承关系生成Mermaid图》
我想为代码文件的include关系生成Mermaid图。
为了排除不感兴趣的其他文件,我将从一个“根文件”出发,找出其include的文件,再递归依次找出他们的include文件。

概括思路

  1. 递归的方式找到一个文件夹下的所有代码文件,记为files
  2. 遍历files,读取每一行line
  3. 对于line做下面处理:(1)先看是否包含 #include ,如果不包含则跳过。(2)然后截取两个引号之间的字符串作为文件路径,处理后变为文件名。这样便能最终得到所有include关系数据
  4. 最后,根据include关系数据,从一个“根文件”出发,找出其include的文件,再递归依次找出他们的include文件。然后用Mermaid的格式打印出这些关系。

具体代码

#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <io.h>
#include <map>

using namespace std;

//递归地方式找到所有的文件
void GetFilesInFolder_recursion(string folder, vector<string>& files)
{
	_finddata_t fileInfo;	//储存得到的文件信息
	//找第一个
	auto findResult = _findfirst((folder + "\\*").c_str(), &fileInfo);
	if (findResult == -1)
	{
		_findclose(findResult);
		return;
	}
	//找之后的
	do
	{
		string fileName = fileInfo.name;
		if ((fileInfo.attrib == _A_NORMAL) || (fileInfo.attrib == _A_ARCH))  //是文件
		{
			files.push_back(folder + "/" + fileName);
		}
		else if (fileInfo.attrib == _A_SUBDIR)//是文件夹
		{
			if (fileName == ".")	//跳过得到的这个路径
				continue;
			if (fileName == "..")	//跳过得到的这个路径
				continue;
			GetFilesInFolder_recursion(folder + "/" + fileName, files);
		}
	} while (_findnext(findResult, &fileInfo) == 0);

	_findclose(findResult);
}

//将路径转换为文件名
string GetFileNameFromPath(string filePath)
{
	//最后一个斜杠的位置:
	const int LastSlashIndex = filePath.find_last_of('/');
	
	if (LastSlashIndex == -1)//没找到
		return filePath;
	else
		return filePath.substr(LastSlashIndex + 1, filePath.size() - LastSlashIndex);
}

//递归的方式收集所有文件
void ColectIncludeFile_recursion(map<string, vector<string>>& InlcudeRelationships, const string fileName, set<string >& Collection)
{
	Collection.insert(fileName);
	for (string includeFile : InlcudeRelationships[fileName])
		ColectIncludeFile_recursion(InlcudeRelationships, includeFile, Collection);
}

int main()
{
	//搜寻的文件夹:
	const string Folder = "D:/0_WorkSpace/UnrealEngine-release/Engine/Shaders/Private";
	//查询的文件:
	const string RootFileName = "MaterialTemplate.ush";

	//包含关系:
	map<string, vector<string>> InlcudeRelationships;	

	//找到所有文件:
	vector<string> files;
	GetFilesInFolder_recursion(Folder, files);

	//收集所有的信息
	for (auto filePath : files)
	{
		//cout << "读取文件" << filePath << endl;
		
		//读取文件
		fstream fileStream(filePath);

		//文件名
		const string fileName = GetFileNameFromPath(filePath);

		//一行的内容字符串
		char line[1024] = { 0 };

		//读取每一行
		while (fileStream.getline(line, 1024))
		{
			//转换为std::string类型
			string content = line;

			if (content.find("#include")!=-1)//如果存在include字样
			{
				//cout <<  content << endl;

				//第一个引号的位置:
				const int FirstIndex = content.find_first_of('"');
				//第二个引号的位置:
				const int SecondIndex = content.find_last_of('"');
				//文件路径就是两个引号之间的内容
				const string includePath = content.substr(FirstIndex + 1, SecondIndex - FirstIndex - 1);
				//cout << includePath << endl;

				//文件名字
				const string IncludeFile = GetFileNameFromPath(includePath);
				//cout << IncludeFile << endl;

				//添加进一个关系:
				InlcudeRelationships[fileName].push_back(IncludeFile);
			}
		}
	}

	//递归收集出所有Include关系
	set<string > Collection;
	ColectIncludeFile_recursion(InlcudeRelationships, RootFileName, Collection);

	//打印出所有的关系
	for (string f : Collection)
		for (string include : InlcudeRelationships[f])
			cout << f << "-->" << include << endl;
}

使用时:

  • main()中的Folder变量设置为所有相关代码所在的文件夹。
  • main()中的RootFileName变量设置为想要查询的“根”文件。

试用

尝试打印出UE4的shader文件中,MaterialTemplate.ush所include的文件关系:

Common.ush-->Platform.ush
Common.ush-->GeneratedUniformBuffers.ush
Common.ush-->CommonViewUniformBuffer.ush
Common.ush-->InstancedStereo.ush
Common.ush-->Definitions.usf
Common.ush-->FastMath.ush
Common.ush-->Random.ush
DeferredShadingCommon.ush-->ShadingCommon.ush
DeferredShadingCommon.ush-->LightAccumulator.ush
DeferredShadingCommon.ush-->SceneTexturesCommon.ush
InstancedStereo.ush-->View.ush
InstancedStereo.ush-->InstancedView.ush
InstancedStereo.ush-->GeneratedInstancedStereo.ush
MaterialTemplate.ush-->SceneTexturesCommon.ush
MaterialTemplate.ush-->Random.ush
MaterialTemplate.ush-->SobolRandom.ush
MaterialTemplate.ush-->MonteCarlo.ush
MaterialTemplate.ush-->Material.ush
MaterialTemplate.ush-->DepthOfFieldCommon.ush
MaterialTemplate.ush-->CircleDOFCommon.ush
MaterialTemplate.ush-->GlobalDistanceFieldShared.ush
MaterialTemplate.ush-->SceneData.ush
MaterialTemplate.ush-->SpeedTreeCommon.ush
MaterialTemplate.ush-->VirtualTextureCommon.ush
MaterialTemplate.ush-->MinMaterialTexCoords.ush
MaterialTemplate.ush-->AtmosphereCommon.ush
MaterialTemplate.ush-->SkyAtmosphereCommon.ush
MaterialTemplate.ush-->PaniniProjection.ush
MaterialTemplate.ush-->DeferredShadingCommon.ush
MonteCarlo.ush-->Common.ush
SceneTexturesCommon.ush-->Common.ush
SpeedTreeCommon.ush-->SpeedTreeData.ush
VirtualTextureCommon.ush-->Common.ush
VirtualTextureCommon.ush-->Random.ush

生成Mermaid图:

Common.ush
Platform.ush
GeneratedUniformBuffers.ush
CommonViewUniformBuffer.ush
InstancedStereo.ush
Definitions.usf
FastMath.ush
Random.ush
DeferredShadingCommon.ush
ShadingCommon.ush
LightAccumulator.ush
SceneTexturesCommon.ush
View.ush
InstancedView.ush
GeneratedInstancedStereo.ush
MaterialTemplate.ush
SobolRandom.ush
MonteCarlo.ush
Material.ush
DepthOfFieldCommon.ush
CircleDOFCommon.ush
GlobalDistanceFieldShared.ush
SceneData.ush
SpeedTreeCommon.ush
VirtualTextureCommon.ush
MinMaterialTexCoords.ush
AtmosphereCommon.ush
SkyAtmosphereCommon.ush
PaniniProjection.ush
SpeedTreeData.ush
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值