void File::Preprocess(FileHeap& headerHeap, FileHeap& sourceHeap)
{
GW::SYSTEM::GFile gFile;
gFile.Create();
// iterate through the raw data and read line by line until we found an include
for (auto iter = std::sregex_iterator(rawData.begin(), rawData.end(), REGEX::PoundInclude); iter != std::sregex_iterator(); ++iter)
{
std::smatch match = *iter;
std::string lineString = match.str(0);
std::string includeDirectory, includeFileName;
size_t index = lineString.find_last_of("/");
// there is a file directory
if (index != std::string::npos)
{
#if defined (_WIN32)
includeDirectory = path + '\\' + lineString.substr(lineString.find_first_of("\"") + 1, index - lineString.find_first_of("\"") - 1);
#elif defined(__APPLE__) || defined(__linux__)
includeDirectory = path + '/' + lineString.substr(lineString.find_first_of("\"") + 1, index - lineString.find_first_of("\"") - 1);
#endif
includeFileName = lineString.substr(index + 1, lineString.find_last_of("\"") - index - 1);
gFile.SetCurrentWorkingDirectory(includeDirectory.data());
std::string temp; temp.resize(260);
gFile.GetCurrentWorkingDirectory(const_cast<char*>(temp.data()), 260);
includeDirectory.clear();
#if defined (_WIN32)
includeDirectory = temp.substr(0, temp.find_last_of('\\'));
#elif defined(__APPLE__) || defined(__linux__)
includeDirectory = temp.substr(0, temp.find_last_of('/'));
#endif
}
// the file directory is in the same directory as this file
else
{
index = lineString.find_first_of("\"");
includeDirectory = path;
includeFileName = lineString.substr(index + 1, lineString.find_last_of("\"") - index - 1);
}
// reset the working directory back to this files path
gFile.SetCurrentWorkingDirectory(path.data());
std::string ext = GetFileExtension(includeFileName);
if (ext == "h")
{
auto headerFile = headerHeap.Find(includeFileName);
if (!headerFile)
includeFiles.push_back(headerHeap.Create(includeDirectory, includeFileName));
else
includeFiles.push_back(headerFile);
}
else if (ext == "hpp")
{
auto sourceFile = sourceHeap.Find(includeFileName);
if (!sourceFile)
includeFiles.push_back(sourceHeap.Create(includeDirectory, includeFileName));
else
includeFiles.push_back(sourceFile);
}
}
for (size_t i = 0; i < includeFiles.size(); ++i)
{
includeFiles[i]->Preprocess(headerHeap, sourceHeap);
}
auto RetriveFileName = [](const std::string& fileName) -> std::string
{
std::string truncatedName;
size_t index = fileName.find_last_of("/");
// there is a file directory, if thats the case, we just want the name of the file and remove the last "
if (index != std::string::npos)
{
truncatedName = fileName.substr(fileName.find_last_of("/") + 1);
truncatedName.erase(truncatedName.size() - 1);
}
else // there is no directory for this file, remove the #include and ""
{
truncatedName = fileName.substr(fileName.find_first_of("\"") + 1);
truncatedName.erase(truncatedName.size() - 1);
}
return truncatedName;
};
std::string newRawData = rawData; // i need a place holder for rawData is because regex_iter will become invalid if original content were modified
for (auto iter = std::sregex_iterator(rawData.begin(), rawData.end(), REGEX::PoundInclude); iter != std::sregex_iterator(); ++iter)
{
std::smatch match = *iter;
std::string lineString = match.str(0);
std::string truncatedString = RetriveFileName(lineString);
std::regex regex(lineString);
auto headerFile = headerHeap.Find(truncatedString);
if (headerFile)
{
if (headerFile->isExternalFile)
{
std::string substitution = lineString + "\t// This file might be an external library file that is not part of Gateware!";
newRawData = std::regex_replace(newRawData, regex, substitution);
continue;
}
else
{
++headerFile->dependencyCount;
std::string substitution = "";
//std::string substitution = "\b"; // Produce weird characters...idk why
newRawData = std::regex_replace(newRawData, regex, substitution);
continue;
}
}
auto sourceFile = sourceHeap.Find(truncatedString);
if (sourceFile)
newRawData = std::regex_replace(newRawData, regex, sourceFile->GetRawData());
}
rawData = std::move(newRawData);
}
No comments:
Post a Comment