Catch preprocessor errors possibly issued during loading files (#2430)

* Also catch preprocessor errors possibly issued during loading files

Currently only errors that are issued during preprocessing are caught.

* Bump simplecpp, implement suggestions

Use return value checking instead of catching an exception for calling
Preprocessor::loadFiles().
Handle new enum value simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND
where the corresponding enum is used in Cppcheck.

* Use "noloc" location if an explicit include can not be opened
This commit is contained in:
Sebastian 2019-12-09 19:16:55 +01:00 committed by GitHub
parent d538315268
commit 95696ead23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 23 deletions

View File

@ -2426,8 +2426,16 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
continue;
std::ifstream fin(filename.c_str());
if (!fin.is_open())
if (!fin.is_open()) {
if (outputList) {
simplecpp::Output err(fileNumbers);
err.type = simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND;
err.location = Location(fileNumbers);
err.msg = "Can not open include file '" + filename + "' that is explicitly included.";
outputList->push_back(err);
}
continue;
}
TokenList *tokenlist = new TokenList(fin, fileNumbers, filename, outputList);
if (!tokenlist->front()) {

View File

@ -167,7 +167,8 @@ namespace simplecpp {
INCLUDE_NESTED_TOO_DEEPLY,
SYNTAX_ERROR,
PORTABILITY_BACKSLASH,
UNHANDLED_CHAR_ERROR
UNHANDLED_CHAR_ERROR,
EXPLICIT_INCLUDE_NOT_FOUND
} type;
Location location;
std::string msg;

View File

@ -275,6 +275,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
case simplecpp::Output::SYNTAX_ERROR:
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
err = true;
break;
case simplecpp::Output::WARNING:
@ -299,7 +300,8 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
}
}
preprocessor.loadFiles(tokens1, files);
if (!preprocessor.loadFiles(tokens1, files))
return mExitCode;
if (!mSettings.plistOutput.empty()) {
std::string filename2;

View File

@ -559,6 +559,7 @@ static bool hasErrors(const simplecpp::OutputList &outputList)
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
case simplecpp::Output::SYNTAX_ERROR:
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
return true;
case simplecpp::Output::WARNING:
case simplecpp::Output::MISSING_HEADER:
@ -569,12 +570,36 @@ static bool hasErrors(const simplecpp::OutputList &outputList)
return false;
}
void Preprocessor::handleErrors(const simplecpp::OutputList& outputList, bool throwError)
{
const bool showerror = (!mSettings.userDefines.empty() && !mSettings.force);
reportOutput(outputList, showerror);
if (throwError) {
for (const simplecpp::Output& output : outputList) {
switch (output.type) {
case simplecpp::Output::ERROR:
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
case simplecpp::Output::SYNTAX_ERROR:
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
throw output;
case simplecpp::Output::WARNING:
case simplecpp::Output::MISSING_HEADER:
case simplecpp::Output::PORTABILITY_BACKSLASH:
break;
};
}
}
}
void Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files)
bool Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files)
{
const simplecpp::DUI dui = createDUI(mSettings, emptyString, files[0]);
mTokenLists = simplecpp::load(rawtokens, files, dui, nullptr);
simplecpp::OutputList outputList;
mTokenLists = simplecpp::load(rawtokens, files, dui, &outputList);
handleErrors(outputList, false);
return !hasErrors(outputList);
}
void Preprocessor::removeComments()
@ -614,23 +639,7 @@ simplecpp::TokenList Preprocessor::preprocess(const simplecpp::TokenList &tokens
simplecpp::TokenList tokens2(files);
simplecpp::preprocess(tokens2, tokens1, files, mTokenLists, dui, &outputList, &macroUsage);
const bool showerror = (!mSettings.userDefines.empty() && !mSettings.force);
reportOutput(outputList, showerror);
if (throwError && hasErrors(outputList)) {
for (const simplecpp::Output &output : outputList) {
switch (output.type) {
case simplecpp::Output::ERROR:
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
case simplecpp::Output::SYNTAX_ERROR:
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
throw output;
case simplecpp::Output::WARNING:
case simplecpp::Output::MISSING_HEADER:
case simplecpp::Output::PORTABILITY_BACKSLASH:
break;
};
}
}
handleErrors(outputList, throwError);
tokens2.removeComments();
@ -717,6 +726,9 @@ void Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
error(out.location.file(), out.location.line, out.msg);
break;
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
error(emptyString, 0, out.msg);
break;
};
}
}

View File

@ -98,7 +98,9 @@ public:
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
void loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
void handleErrors(const simplecpp::OutputList &outputList, bool throwError);
bool loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
void removeComments();