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:
parent
d538315268
commit
95696ead23
|
@ -2426,8 +2426,16 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::ifstream fin(filename.c_str());
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
TokenList *tokenlist = new TokenList(fin, fileNumbers, filename, outputList);
|
TokenList *tokenlist = new TokenList(fin, fileNumbers, filename, outputList);
|
||||||
if (!tokenlist->front()) {
|
if (!tokenlist->front()) {
|
||||||
|
|
|
@ -167,7 +167,8 @@ namespace simplecpp {
|
||||||
INCLUDE_NESTED_TOO_DEEPLY,
|
INCLUDE_NESTED_TOO_DEEPLY,
|
||||||
SYNTAX_ERROR,
|
SYNTAX_ERROR,
|
||||||
PORTABILITY_BACKSLASH,
|
PORTABILITY_BACKSLASH,
|
||||||
UNHANDLED_CHAR_ERROR
|
UNHANDLED_CHAR_ERROR,
|
||||||
|
EXPLICIT_INCLUDE_NOT_FOUND
|
||||||
} type;
|
} type;
|
||||||
Location location;
|
Location location;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
|
@ -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::INCLUDE_NESTED_TOO_DEEPLY:
|
||||||
case simplecpp::Output::SYNTAX_ERROR:
|
case simplecpp::Output::SYNTAX_ERROR:
|
||||||
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
||||||
|
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
|
||||||
err = true;
|
err = true;
|
||||||
break;
|
break;
|
||||||
case simplecpp::Output::WARNING:
|
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()) {
|
if (!mSettings.plistOutput.empty()) {
|
||||||
std::string filename2;
|
std::string filename2;
|
||||||
|
|
|
@ -559,6 +559,7 @@ static bool hasErrors(const simplecpp::OutputList &outputList)
|
||||||
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
|
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
|
||||||
case simplecpp::Output::SYNTAX_ERROR:
|
case simplecpp::Output::SYNTAX_ERROR:
|
||||||
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
||||||
|
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
|
||||||
return true;
|
return true;
|
||||||
case simplecpp::Output::WARNING:
|
case simplecpp::Output::WARNING:
|
||||||
case simplecpp::Output::MISSING_HEADER:
|
case simplecpp::Output::MISSING_HEADER:
|
||||||
|
@ -569,12 +570,36 @@ static bool hasErrors(const simplecpp::OutputList &outputList)
|
||||||
return false;
|
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]);
|
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()
|
void Preprocessor::removeComments()
|
||||||
|
@ -614,23 +639,7 @@ simplecpp::TokenList Preprocessor::preprocess(const simplecpp::TokenList &tokens
|
||||||
simplecpp::TokenList tokens2(files);
|
simplecpp::TokenList tokens2(files);
|
||||||
simplecpp::preprocess(tokens2, tokens1, files, mTokenLists, dui, &outputList, ¯oUsage);
|
simplecpp::preprocess(tokens2, tokens1, files, mTokenLists, dui, &outputList, ¯oUsage);
|
||||||
|
|
||||||
const bool showerror = (!mSettings.userDefines.empty() && !mSettings.force);
|
handleErrors(outputList, throwError);
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens2.removeComments();
|
tokens2.removeComments();
|
||||||
|
|
||||||
|
@ -717,6 +726,9 @@ void Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
|
||||||
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
|
||||||
error(out.location.file(), out.location.line, out.msg);
|
error(out.location.file(), out.location.line, out.msg);
|
||||||
break;
|
break;
|
||||||
|
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
|
||||||
|
error(emptyString, 0, out.msg);
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,9 @@ public:
|
||||||
|
|
||||||
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
|
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();
|
void removeComments();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue