根据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;
}
更多的交流,欢迎留言。