pattern: Fixed pragma once memory corruption
This commit is contained in:
parent
c1b4c4e42a
commit
99f8efac9a
@ -22,10 +22,15 @@ namespace hex::pl {
|
|||||||
std::optional<std::string> preprocess(const std::string &code, bool initialRun = true);
|
std::optional<std::string> preprocess(const std::string &code, bool initialRun = true);
|
||||||
|
|
||||||
void addPragmaHandler(const std::string &pragmaType, const std::function<bool(const std::string &)> &function);
|
void addPragmaHandler(const std::string &pragmaType, const std::function<bool(const std::string &)> &function);
|
||||||
|
void removePragmaHandler(const std::string &pragmaType);
|
||||||
void addDefaultPragmaHandlers();
|
void addDefaultPragmaHandlers();
|
||||||
|
|
||||||
const std::optional<PatternLanguageError> &getError() { return this->m_error; }
|
const std::optional<PatternLanguageError> &getError() { return this->m_error; }
|
||||||
|
|
||||||
|
bool shouldOnlyIncludeOnce() {
|
||||||
|
return this->m_onlyIncludeOnce;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[noreturn]] static void throwPreprocessorError(const std::string &error, u32 lineNumber) {
|
[[noreturn]] static void throwPreprocessorError(const std::string &error, u32 lineNumber) {
|
||||||
throw PatternLanguageError(lineNumber, "Preprocessor: " + error);
|
throw PatternLanguageError(lineNumber, "Preprocessor: " + error);
|
||||||
@ -39,6 +44,8 @@ namespace hex::pl {
|
|||||||
std::set<fs::path> m_onceIncludedFiles;
|
std::set<fs::path> m_onceIncludedFiles;
|
||||||
|
|
||||||
std::optional<PatternLanguageError> m_error;
|
std::optional<PatternLanguageError> m_error;
|
||||||
|
|
||||||
|
bool m_onlyIncludeOnce = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -79,18 +79,19 @@ namespace hex::pl {
|
|||||||
throwPreprocessorError(hex::format("{0}: No such file or directory", includeFile.c_str()), lineNumber);
|
throwPreprocessorError(hex::format("{0}: No such file or directory", includeFile.c_str()), lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldInclude = true;
|
Preprocessor preprocessor;
|
||||||
this->addPragmaHandler("once", [&, includePath, this](const std::string &value) {
|
preprocessor.addDefaultPragmaHandlers();
|
||||||
auto [iter, added] = this->m_onceIncludedFiles.insert(includePath);
|
preprocessor.m_defines = this->m_defines;
|
||||||
if (!added) shouldInclude = false;
|
preprocessor.m_onceIncludedFiles = this->m_onceIncludedFiles;
|
||||||
return value.empty();
|
|
||||||
});
|
auto preprocessedInclude = preprocessor.preprocess(file.readString(), true);
|
||||||
|
|
||||||
auto preprocessedInclude = this->preprocess(file.readString(), false);
|
|
||||||
if (!preprocessedInclude.has_value())
|
if (!preprocessedInclude.has_value())
|
||||||
throw this->m_error;
|
throw *preprocessor.m_error;
|
||||||
|
|
||||||
if (shouldInclude) {
|
if (preprocessor.shouldOnlyIncludeOnce()) {
|
||||||
|
auto [iter, added] = this->m_onceIncludedFiles.insert(includePath);
|
||||||
|
if (added) {
|
||||||
auto content = preprocessedInclude.value();
|
auto content = preprocessedInclude.value();
|
||||||
|
|
||||||
std::replace(content.begin(), content.end(), '\n', ' ');
|
std::replace(content.begin(), content.end(), '\n', ' ');
|
||||||
@ -98,6 +99,10 @@ namespace hex::pl {
|
|||||||
|
|
||||||
output += content;
|
output += content;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_defines = preprocessor.m_defines;
|
||||||
|
this->m_onceIncludedFiles = preprocessor.m_onceIncludedFiles;
|
||||||
} else if (code.substr(offset, 6) == "define") {
|
} else if (code.substr(offset, 6) == "define") {
|
||||||
offset += 6;
|
offset += 6;
|
||||||
|
|
||||||
@ -234,6 +239,10 @@ namespace hex::pl {
|
|||||||
this->m_pragmaHandlers[pragmaType] = function;
|
this->m_pragmaHandlers[pragmaType] = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preprocessor::removePragmaHandler(const std::string &pragmaType) {
|
||||||
|
this->m_pragmaHandlers.erase(pragmaType);
|
||||||
|
}
|
||||||
|
|
||||||
void Preprocessor::addDefaultPragmaHandlers() {
|
void Preprocessor::addDefaultPragmaHandlers() {
|
||||||
this->addPragmaHandler("MIME", [](const std::string &value) {
|
this->addPragmaHandler("MIME", [](const std::string &value) {
|
||||||
return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r');
|
return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r');
|
||||||
@ -241,7 +250,9 @@ namespace hex::pl {
|
|||||||
this->addPragmaHandler("endian", [](const std::string &value) {
|
this->addPragmaHandler("endian", [](const std::string &value) {
|
||||||
return value == "big" || value == "little" || value == "native";
|
return value == "big" || value == "little" || value == "native";
|
||||||
});
|
});
|
||||||
this->addPragmaHandler("once", [](const std::string &value) {
|
this->addPragmaHandler("once", [this](const std::string &value) {
|
||||||
|
this->m_onlyIncludeOnce = true;
|
||||||
|
|
||||||
return value.empty();
|
return value.empty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user