Bump simplecpp. Preprocessor: Warn about missing includes
This commit is contained in:
parent
f50f024873
commit
b2f1b95e38
|
@ -48,6 +48,9 @@ const simplecpp::TokenString ELSE("else");
|
|||
const simplecpp::TokenString ELIF("elif");
|
||||
const simplecpp::TokenString ENDIF("endif");
|
||||
|
||||
const simplecpp::TokenString PRAGMA("pragma");
|
||||
const simplecpp::TokenString ONCE("once");
|
||||
|
||||
template<class T> std::string toString(T t) {
|
||||
std::ostringstream ostr;
|
||||
ostr << t;
|
||||
|
@ -1279,6 +1282,8 @@ simplecpp::TokenList simplecpp::preprocess(const simplecpp::TokenList &rawtokens
|
|||
std::list<TokenList *> includes;
|
||||
std::stack<const Token *> includetokenstack;
|
||||
|
||||
std::set<std::string> pragmaOnce;
|
||||
|
||||
TokenList output(files);
|
||||
for (const Token *rawtok = rawtokens.cbegin(); rawtok || !includetokenstack.empty();) {
|
||||
if (rawtok == nullptr) {
|
||||
|
@ -1322,18 +1327,21 @@ simplecpp::TokenList simplecpp::preprocess(const simplecpp::TokenList &rawtokens
|
|||
}
|
||||
} catch (const std::runtime_error &) {
|
||||
}
|
||||
} else if (rawtok->str == INCLUDE) {
|
||||
if (ifstates.top() == TRUE) {
|
||||
const std::string header(rawtok->next->str.substr(1U, rawtok->next->str.size() - 2U));
|
||||
const std::string header2 = getFileName(filedata, rawtok->location.file(), header, dui);
|
||||
if (!header2.empty()) {
|
||||
includetokenstack.push(gotoNextLine(rawtok));
|
||||
const TokenList *includetokens = filedata.find(header2)->second;
|
||||
rawtok = includetokens ? includetokens->cbegin() : 0;
|
||||
continue;
|
||||
} else {
|
||||
// TODO: Write warning message
|
||||
}
|
||||
} else if (ifstates.top() == TRUE && rawtok->str == INCLUDE) {
|
||||
const std::string header(rawtok->next->str.substr(1U, rawtok->next->str.size() - 2U));
|
||||
const std::string header2 = getFileName(filedata, rawtok->location.file(), header, dui);
|
||||
if (!header2.empty() && pragmaOnce.find(header2) == pragmaOnce.end()) {
|
||||
includetokenstack.push(gotoNextLine(rawtok));
|
||||
const TokenList *includetokens = filedata.find(header2)->second;
|
||||
rawtok = includetokens ? includetokens->cbegin() : 0;
|
||||
continue;
|
||||
} else {
|
||||
simplecpp::Output output(files);
|
||||
output.type = Output::Type::MISSING_INCLUDE;
|
||||
output.location = rawtok->location;
|
||||
output.msg = "Header not found: " + rawtok->next->str;
|
||||
if (outputList)
|
||||
outputList->push_back(output);
|
||||
}
|
||||
} else if (rawtok->str == IF || rawtok->str == IFDEF || rawtok->str == IFNDEF || rawtok->str == ELIF) {
|
||||
bool conditionIsTrue;
|
||||
|
@ -1425,6 +1433,8 @@ simplecpp::TokenList simplecpp::preprocess(const simplecpp::TokenList &rawtokens
|
|||
if (sameline(rawtok, tok))
|
||||
macros.erase(tok->str);
|
||||
}
|
||||
} else if (ifstates.top() == TRUE && rawtok->str == PRAGMA && rawtok->next && rawtok->next->str == ONCE && sameline(rawtok,rawtok->next)) {
|
||||
pragmaOnce.insert(rawtok->location.file());
|
||||
}
|
||||
rawtok = gotoNextLine(rawtok);
|
||||
continue;
|
||||
|
|
|
@ -123,8 +123,9 @@ private:
|
|||
struct Output {
|
||||
Output(const std::vector<std::string> &files) : type(ERROR), location(files) {}
|
||||
enum Type {
|
||||
ERROR, /* error */
|
||||
WARNING /* warning */
|
||||
ERROR, /* #error */
|
||||
WARNING, /* #warning */
|
||||
MISSING_INCLUDE
|
||||
} type;
|
||||
Location location;
|
||||
std::string msg;
|
||||
|
|
|
@ -121,6 +121,9 @@ unsigned int CppCheck::processFile(const std::string& filename, std::istream& fi
|
|||
}
|
||||
|
||||
if (_settings.checkConfiguration) {
|
||||
for (std::set<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
|
||||
(void)preprocessor.getcode(tokens1, *it, files, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -512,11 +512,21 @@ std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std
|
|||
|
||||
bool showerror = (!_settings.userDefines.empty() && !_settings.force);
|
||||
for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
|
||||
if (it->type == simplecpp::Output::ERROR) {
|
||||
switch (it->type) {
|
||||
case simplecpp::Output::ERROR:
|
||||
if (it->msg.compare(0,6,"#error")!=0 || showerror)
|
||||
error(it->location.file(), it->location.line, it->msg);
|
||||
return "";
|
||||
case simplecpp::Output::WARNING:
|
||||
break;
|
||||
case simplecpp::Output::MISSING_INCLUDE: {
|
||||
const std::string::size_type pos1 = it->msg.find_first_of("<\"");
|
||||
const std::string::size_type pos2 = it->msg.find_first_of(">\"", pos1 + 1U);
|
||||
if (pos1 < pos2 && pos2 != std::string::npos)
|
||||
missingInclude(it->location.file(), it->location.line, it->msg.substr(pos1+1, pos2-pos1-1), it->msg[pos1] == '\"' ? UserHeader : SystemHeader);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// directive list..
|
||||
|
@ -649,10 +659,20 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string
|
|||
inlineSuppressions(tokens1);
|
||||
|
||||
for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
|
||||
if (it->type == simplecpp::Output::ERROR) {
|
||||
switch (it->type) {
|
||||
case simplecpp::Output::ERROR:
|
||||
error(it->location.file(), it->location.line, it->msg);
|
||||
return "";
|
||||
case simplecpp::Output::WARNING:
|
||||
break;
|
||||
case simplecpp::Output::MISSING_INCLUDE: {
|
||||
const std::string::size_type pos1 = it->msg.find_first_of("<\"");
|
||||
const std::string::size_type pos2 = it->msg.find_first_of(">\"", pos1 + 1U);
|
||||
if (pos1 < pos2 && pos2 != std::string::npos)
|
||||
missingInclude(it->location.file(), it->location.line, it->msg.substr(pos1+1, pos2-pos1-1), it->msg[pos1] == '\"' ? UserHeader : SystemHeader);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
return getcode(tokens1, cfg, files, filedata.find("#file") != std::string::npos);
|
||||
|
|
Loading…
Reference in New Issue