头文件抓取工具关键源代码

85 篇文章 4 订阅

根据h或者cpp文件等中的内容,在指定目录中抓取对应的头文件。

bool CGrabHeaderFilesDlg::CopyCorresSuffixFile(const std::string& strOriPath, const std::string& strNewSuffix, const std::string& strSavePath)
{
	//原来的目录下对应的后缀的文件名
	std::string strCorresOriPath = CStdStr::ReplaceSuffix(strOriPath, strNewSuffix);

	if (!CStdFile::IfAccessFile(strCorresOriPath))
	{
		return false;
	}

	std::string strSavePathT(strSavePath);
	std::string strSaveDir = CStdStr::GetDirOfFile(strSavePathT);
	strSavePathT = CStdStr::ReplaceSuffix(strSavePathT, strNewSuffix);

	//复制文件到目标目录,重复的时候自动重命名
	int nNum = 0;
	if (CStdFile::IfAccessFile(strSavePathT) && !CStdFile::CompareFileDistinct(strCorresOriPath, strSavePathT))
	{
		do
		{
			++nNum;
			strSavePathT = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(strCorresOriPath, false) +
				CStdTpl::ConvertToString(nNum) + CStdStr::GetSuffixOfFile(strCorresOriPath);

		} while (CStdFile::IfAccessFile(strSavePathT));
	}

	return CStdFile::CopyAFile(strCorresOriPath, strSavePathT, true);
}

bool CGrabHeaderFilesDlg::GetIncludeInfo(const std::string& strLine, std::string& strInfo)
{
	std::string strFlag = "#include";
	size_t pos = strLine.find(strFlag);
	if (pos == std::string::npos)
	{
		return false;
	}

	std::string strSub = strLine.substr(pos + strFlag.length());
	if (strSub.length() == 0)
	{
		return false;
	}

	char sep = strSub[0];

	if (sep != '<' && sep != '\"')
	{
		return false;
	}

	size_t pos_o = std::string::npos;

	if (sep == '<')
	{
		pos_o = strSub.find('>', 1);
	}
	else if (sep == '\"')
	{
		pos_o = strSub.find('\"', 1);
	}

	if (pos_o == std::string::npos)
	{
		return false;
	}

	strInfo = strSub.substr(1, pos_o - pos - 1);

	return true;
}


//检查是否存在同名但是内容不同的文件
bool CGrabHeaderFilesDlg::IfSameNameButNotSameContent(std::vector<std::string> vFilePaths)
{
	size_t nFileNum = vFilePaths.size();
	std::map<std::string, std::wstring> mSha1Path;
	TCHAR* szReport = nullptr;
	const size_t nSize = 256;
	CStdTpl::NewSafely(szReport, nSize, true);
	CSHA1 sha1;
	for (size_t i = 0; i < nFileNum; ++i)
	{
		std::string strCurFile = vFilePaths[i];
		sha1.Reset();
		sha1.HashFile(CStdStr::s2ws(strCurFile).c_str()); // Hash in the contents of the file
		sha1.Final();
		memset(szReport, 0, nSize * sizeof(TCHAR));
		sha1.ReportHash(szReport, CSHA1::REPORT_HEX_SHORT); // Get final hash as
		//如果在map中已经存在同名的文件,但是sha1的值不同,则返回false
		std::string strCurName = CStdStr::GetNameOfFile(strCurFile);
		std::map<std::string, std::wstring>::iterator it = mSha1Path.find(strCurName);
		if (it != mSha1Path.end())
		{
			//找到同名的文件,如果hash值不同,则返回false
			if (_tcscmp(it->second.c_str(), szReport) != 0)
			{
				CStdTpl::DelPointerSafely(szReport, true);

				return true;
			}
		}

		mSha1Path.insert(std::make_pair(strCurName, szReport));
	}

	CStdTpl::DelPointerSafely(szReport, true);

	return false;
}


int CGrabHeaderFilesDlg::GrabAllHeadFiles(const std::string& strSrcFilesdDir, const std::string& strFilesInputDir)
{
	std::vector<std::string> vFiles;
	size_t nFileNumInput = getFiles(strFilesInputDir, vFiles, _conf.vSuffixs);

	//检测strFilesInputDir文件夹中是否存在同名但是内容不同的文件,如果存在则返回
	if (IfSameNameButNotSameContent(vFiles))
	{
		CString strTmp[2];
		strTmp[0].LoadString(IDS_STRINGSAMENAMENOTSAMECONTENT);
		strTmp[1].LoadString(IDS_STRING_TIPS);

		MessageBox(strTmp[0], strTmp[1], MB_ICONINFORMATION);

		return -1;
	}

	//创建目标文件夹
	std::string strSaveDir = CStdStr::AddSlashIfNeeded(strSrcFilesdDir) + "autumoon";
	if (_access(strSaveDir.c_str(), 0) != 0 && CStdDir::CreateDir(strSaveDir) == false)
	{
		return -1;
	}

	size_t nDstFileSize = 0, nCurDstFileSize = 0;
	for(;;)
	{
		GrabHeadFiles(strSrcFilesdDir, strFilesInputDir);
		std::vector<std::string> vFiles;
		nCurDstFileSize = getFiles(strSaveDir, vFiles, _conf.vSuffixs);
		if (nCurDstFileSize != nDstFileSize)
		{
			nDstFileSize = nCurDstFileSize;
		}
		else
		{
			break;
		}
	}

	return 0;
}


int CGrabHeaderFilesDlg::GrabHeadFiles(const std::string& strSrcFilesdDir, const std::string& strFilesInputDir)
{
	std::string strSaveDir = CStdStr::AddSlashIfNeeded(strSrcFilesdDir) + "autumoon";

	std::map<std::string, std::string> mFilesNeed;
	std::vector<std::string> vFilesRead, vContentInFile;
	size_t nFileNum = getFiles(strSrcFilesdDir, vFilesRead, _conf.vSuffixs);
	for (size_t i = 0; i < nFileNum; ++i)
	{
		const std::string& strCurFile = vFilesRead[i];
		vContentInFile.clear();
		size_t nLines = CStdFile::ParseTXTFile(strCurFile, vContentInFile);
		for (size_t line = 0; line < nLines; ++line)
		{
			//对每一行进行判断,如果存在#include 则取其后面的文件
			std::string sLine = vContentInFile[line];
			sLine = CStdStr::Trim(sLine);
			sLine = CStdStr::ReplaceAllDistinct(sLine, "\t","");
			sLine = CStdStr::ReplaceAllDistinct(sLine, " ","");
			//寻找<>或者""中的内容,需要考虑相对路径,绝对路径,以及只有文件名
			size_t pos = sLine.find("#include");
			if (pos != std::string::npos)
			{
				//此时可能存在需要包含的文件
				std::string strInfo;
				if (GetIncludeInfo(sLine, strInfo))
				{
					strInfo = CStdStr::RepalceAll(strInfo, "/", "\\");
					strInfo = CStdStr::RepalceAll(strInfo, "..\\", "");
					strInfo = CStdStr::RepalceAll(strInfo, ".\\", "");
					mFilesNeed.insert(std::make_pair(strInfo, sLine));
				}
			}
		}
	}

	//对于vFilesNeed中的每一个info,在目标文件中遍历寻找
	std::vector<std::string> vFilesInput;
	size_t nInputNum = getFiles(strFilesInputDir, vFilesInput, _conf.vSuffixs);
	size_t nNeedNum = mFilesNeed.size();
	size_t nSpecNum = _conf.vSuffixs.size();
	for (std::map<std::string, std::string>::iterator it = mFilesNeed.begin();
		it != mFilesNeed.end(); ++it)
	{
		std::string strCurInfo = CStdStr::ToUpperLower(it->first);
		for (size_t j = 0; j < nInputNum; ++j)
		{
			std::string strCurFile = CStdStr::ToUpperLower(vFilesInput[j]);
			//文件名必须相同并且相对路径必须相同或者绝对路径必须相同
			size_t pos = strCurFile.find(strCurInfo);
			if (CStdStr::GetNameOfFile(strCurFile) == CStdStr::GetNameOfFile(strCurInfo) && pos != std::string::npos)
			{
				std::string strTest = strCurFile.substr(pos);
				if (strTest == strCurInfo)
				{
					//则该文件是需要的文件
					std::string strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + vFilesInput[j].substr(pos);
					//复制文件到目标目录,重复的时候自动重命名
					int nNum = 0;
					if (CStdFile::IfAccessFile(strSavePath) && !CStdFile::CompareFileDistinct(strCurFile, strSavePath))
					{
						do
						{
							++nNum;
							strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(strCurFile, false) +
								CStdTpl::ConvertToString(nNum) + CStdStr::GetSuffixOfFile(strCurFile);

						} while (CStdFile::IfAccessFile(strSavePath));
					}
					CStdFile::CopyAFile(strCurFile, strSavePath, true);
					//如果存在对应的cpp文件,或者c文件,则一并拷贝
					if (_conf.bNeedCppFile)
					{
						for (size_t p = 0; p < nSpecNum; ++p)
						{
							std::string strCurSpec = _conf.vSuffixs[p];
							size_t ppos = strCurSpec.find('.');
							if (ppos != std::string::npos)
							{
								strCurSpec = strCurSpec.substr(ppos);
								CopyCorresSuffixFile(strCurFile, strCurSpec.c_str(), strSavePath);
							}
						}
					}
				}
			}
		}
	}

	return 0;
}

更多的交流,欢迎留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值