diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 9fd88d281..2c38cd67b 100644 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -2426,8 +2426,16 @@ std::map 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()) { diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index 7f44d3087..577711af5 100644 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -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; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 258df343d..8f2756168 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -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; diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index e5107c466..33882e53c 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -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 &files) +bool Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector &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, ¯oUsage); - 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; }; } } diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 86505d575..8b63a212c 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -98,7 +98,9 @@ public: std::set getConfigs(const simplecpp::TokenList &tokens) const; - void loadFiles(const simplecpp::TokenList &rawtokens, std::vector &files); + void handleErrors(const simplecpp::OutputList &outputList, bool throwError); + + bool loadFiles(const simplecpp::TokenList &rawtokens, std::vector &files); void removeComments();