Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/ad
$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp

$(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/utils.h
$(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp

$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h
Expand Down Expand Up @@ -599,13 +599,13 @@ $(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astuti
$(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/mathlib.cpp

$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/utils.h
$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/standards.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp

$(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp

$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/standards.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathmatch.cpp

$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h
Expand Down Expand Up @@ -662,7 +662,7 @@ cli/cppcheckexecutorsig.o: cli/cppcheckexecutorsig.cpp cli/cppcheckexecutor.h cl
cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp

cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/standards.h lib/utils.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/filelister.cpp

cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/errortypes.h lib/filesettings.h lib/platform.h lib/standards.h lib/utils.h
Expand Down
2 changes: 1 addition & 1 deletion cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
// Output a warning for the user if he tries to exclude headers
const std::vector<std::string>& ignored = getIgnoredPaths();
const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](const std::string& i) {
return Path::isHeader(i);
return Path::isHeader2(i);
});
if (warn) {
mLogger.printMessage("filename exclusion does not apply to header (.h and .hpp) files.");
Expand Down
2 changes: 1 addition & 1 deletion gui/resultstree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ void ResultsTree::recheckSelectedFiles()
askFileDir(currentFile);
return;
}
if (Path::isHeader(currentFile.toStdString())) {
if (Path::isHeader2(currentFile.toStdString())) {
if (!data[FILE0].toString().isEmpty() && !selectedItems.contains(data[FILE0].toString())) {
selectedItems<<((!mCheckPath.isEmpty() && (data[FILE0].toString().indexOf(mCheckPath) != 0)) ? (mCheckPath + "/" + data[FILE0].toString()) : data[FILE0].toString());
if (!selectedItems.contains(fileNameWithCheckPath))
Expand Down
2 changes: 1 addition & 1 deletion gui/resultsview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ void ResultsView::updateDetails(const QModelIndex &index)
QString formattedMsg = message;

const QString file0 = data["file0"].toString();
if (!file0.isEmpty() && Path::isHeader(data["file"].toString().toStdString()))
if (!file0.isEmpty() && Path::isHeader2(data["file"].toString().toStdString()))
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by"), QDir::toNativeSeparators(file0));

if (data["cwe"].toInt() > 0)
Expand Down
11 changes: 11 additions & 0 deletions lib/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@
# define WARN_UNUSED
#endif

// deprecated
#if defined(__GNUC__) \
|| defined(__clang__) \
|| defined(__CPPCHECK__)
# define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
# define DEPRECATED __declspec(deprecated)
#else
# define DEPRECATED
#endif

#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type

#include <string>
Expand Down
13 changes: 8 additions & 5 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,11 @@ static void createDumpFile(const Settings& settings,
language = " language=\"cpp\"";
break;
case Standards::Language::None:
if (Path::isCPP(filename))
// TODO: error out on unknown language?
const Standards::Language lang = Path::identify(filename);
if (lang == Standards::Language::CPP)
language = " language=\"cpp\"";
else if (Path::isC(filename))
else if (lang == Standards::Language::C)
language = " language=\"c\"";
break;
}
Expand Down Expand Up @@ -429,7 +431,8 @@ unsigned int CppCheck::checkClang(const std::string &path)
mErrorLogger.reportOut(std::string("Checking ") + path + " ...", Color::FgGreen);

// TODO: this ignores the configured language
const std::string lang = Path::isCPP(path) ? "-x c++" : "-x c";
const bool isCpp = Path::identify(path) == Standards::Language::CPP;
const std::string langOpt = isCpp ? "-x c++" : "-x c";
const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, emptyString);
const std::string clangcmd = analyzerInfo + ".clang-cmd";
const std::string clangStderr = analyzerInfo + ".clang-stderr";
Expand All @@ -442,9 +445,9 @@ unsigned int CppCheck::checkClang(const std::string &path)
}
#endif

std::string flags(lang + " ");
std::string flags(langOpt + " ");
// TODO: does not apply C standard
if (Path::isCPP(path) && !mSettings.standards.stdValue.empty())
if (isCpp && !mSettings.standards.stdValue.empty())
flags += "-std=" + mSettings.standards.stdValue + " ";

for (const std::string &i: mSettings.includePaths)
Expand Down
53 changes: 52 additions & 1 deletion lib/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <algorithm>
#include <cstdlib>
#include <sys/stat.h>
#include <unordered_set>
#include <utility>

#include <simplecpp.h>
Expand Down Expand Up @@ -193,6 +194,18 @@ std::string Path::getRelativePath(const std::string& absolutePath, const std::ve
return absolutePath;
}

static const std::unordered_set<std::string> cpp_src_exts = {
".cpp", ".cxx", ".cc", ".c++", ".tpp", ".txx", ".ipp", ".ixx"
};

static const std::unordered_set<std::string> c_src_exts = {
".c", ".cl"
};

static const std::unordered_set<std::string> header_exts = {
".h", ".hpp", ".h++", ".hxx", ".hh"
};

bool Path::isC(const std::string &path)
{
// In unix, ".C" is considered C++ file
Expand Down Expand Up @@ -220,15 +233,53 @@ bool Path::isCPP(const std::string &path)

bool Path::acceptFile(const std::string &path, const std::set<std::string> &extra)
{
return !Path::isHeader(path) && (Path::isCPP(path) || Path::isC(path) || extra.find(getFilenameExtension(path)) != extra.end());
bool header = false;
return (identify(path, &header) != Standards::Language::None && !header) || extra.find(getFilenameExtension(path)) != extra.end();
}

// cppcheck-suppress unusedFunction
bool Path::isHeader(const std::string &path)
{
const std::string extension = getFilenameExtensionInLowerCase(path);
return startsWith(extension, ".h");
}

Standards::Language Path::identify(const std::string &path, bool *header)
{
// cppcheck-suppress uninitvar - TODO: FP
if (header)
*header = false;

std::string ext = getFilenameExtension(path);
if (ext == ".C")
return Standards::Language::CPP;
if (c_src_exts.find(ext) != c_src_exts.end())
return Standards::Language::C;
// cppcheck-suppress knownConditionTrueFalse - TODO: FP
if (!caseInsensitiveFilesystem())
strTolower(ext);
if (ext == ".h") {
if (header)
*header = true;
return Standards::Language::C; // treat as C for now
}
if (cpp_src_exts.find(ext) != cpp_src_exts.end())
return Standards::Language::CPP;
if (header_exts.find(ext) != header_exts.end()) {
if (header)
*header = true;
return Standards::Language::CPP;
}
return Standards::Language::None;
}

bool Path::isHeader2(const std::string &path)
{
bool header;
(void)Path::identify(path, &header);
return header;
}

std::string Path::getAbsoluteFilePath(const std::string& filePath)
{
std::string absolute_path;
Expand Down
25 changes: 22 additions & 3 deletions lib/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//---------------------------------------------------------------------------

#include "config.h"
#include "standards.h"

#include <set>
#include <string>
Expand Down Expand Up @@ -156,22 +157,40 @@ class CPPCHECKLIB Path {
* @brief Identify language based on file extension.
* @param path filename to check. path info is optional
* @return true if extension is meant for C files
* @deprecated does not account for headers - use @identify() instead
*/
static bool isC(const std::string &path);
static DEPRECATED bool isC(const std::string &path);

/**
* @brief Identify language based on file extension.
* @param path filename to check. path info is optional
* @return true if extension is meant for C++ files
* @deprecated returns true for some header extensions - use @identify() instead
*/
static bool isCPP(const std::string &path);
static DEPRECATED bool isCPP(const std::string &path);

/**
* @brief Is filename a header based on file extension
* @param path filename to check. path info is optional
* @return true if filename extension is meant for headers
* @deprecated returns only heuristic result - use @identify() or @isHeader2() instead
*/
static bool isHeader(const std::string &path);
static DEPRECATED bool isHeader(const std::string &path);

/**
* @brief Is filename a header based on file extension
Comment thread
danmar marked this conversation as resolved.
* @param path filename to check. path info is optional
* @return true if filename extension is meant for headers
*/
static bool isHeader2(const std::string &path);

/**
* @brief Identify the language based on the file extension
* @param path filename to check. path info is optional
* @param header if provided indicates if the file is a header
* @return the language type
*/
static Standards::Language identify(const std::string &path, bool *header = nullptr);

/**
* @brief Get filename without a directory path part.
Expand Down
6 changes: 4 additions & 2 deletions lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,11 +730,13 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
dui.includePaths = mSettings.includePaths; // -I
dui.includes = mSettings.userIncludes; // --include
// TODO: use mSettings.standards.stdValue instead
if (Path::isCPP(filename)) {
// TODO: error out on unknown language?
const Standards::Language lang = Path::identify(filename);
if (lang == Standards::Language::CPP) {
dui.std = mSettings.standards.getCPP();
splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, "");
}
else {
else if (lang == Standards::Language::C) {
dui.std = mSettings.standards.getC();
splitcfg(mSettings.platform.getLimitsDefines(Standards::getC(dui.std)), dui.defines, "");
}
Expand Down
16 changes: 8 additions & 8 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4156,7 +4156,7 @@ void VariableMap::addVariable(const std::string& varname, bool globalNamespace)
it->second = ++mVarId;
}

static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap, bool executableScope, bool cpp, bool c)
static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap, bool executableScope)
{
const Token* const tok1 = *tok;
Token* tok2 = *tok;
Expand All @@ -4174,14 +4174,14 @@ static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap
tok2 = tok2->linkAt(1)->next();
continue;
}
if (cpp && Token::Match(tok2, "namespace|public|private|protected"))
if (tok2->isCpp() && Token::Match(tok2, "namespace|public|private|protected"))
return false;
if (cpp && Token::simpleMatch(tok2, "decltype (")) {
if (tok2->isCpp() && Token::simpleMatch(tok2, "decltype (")) {
typeCount = 1;
tok2 = tok2->linkAt(1)->next();
continue;
}
if (Token::Match(tok2, "struct|union|enum") || (!c && Token::Match(tok2, "class|typename"))) {
if (Token::Match(tok2, "struct|union|enum") || (tok2->isCpp() && Token::Match(tok2, "class|typename"))) {
hasstruct = true;
typeCount = 0;
singleNameCount = 0;
Expand All @@ -4197,8 +4197,8 @@ static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap
++typeCount;
++singleNameCount;
}
} else if (!c && ((TemplateSimplifier::templateParameters(tok2) > 0) ||
Token::simpleMatch(tok2, "< >") /* Ticket #4764 */)) {
} else if (tok2->isCpp() && ((TemplateSimplifier::templateParameters(tok2) > 0) ||
Token::simpleMatch(tok2, "< >") /* Ticket #4764 */)) {
const Token *start = *tok;
if (Token::Match(start->previous(), "%or%|%oror%|&&|&|^|+|-|*|/"))
return false;
Expand Down Expand Up @@ -4263,7 +4263,7 @@ static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap
}
}

if (cpp && tok3 && Token::simpleMatch(tok3->previous(), "] (") &&
if (tok3 && tok3->isCpp() && Token::simpleMatch(tok3->previous(), "] (") &&
(Token::simpleMatch(tok3->link(), ") {") || Token::Match(tok3->link(), ") . %name%")))
isLambdaArg = true;
}
Expand Down Expand Up @@ -4683,7 +4683,7 @@ void Tokenizer::setVarIdPass1()
}

try { /* Ticket #8151 */
decl = setVarIdParseDeclaration(&tok2, variableMap, scopeStack.top().isExecutable, isCPP(), isC());
decl = setVarIdParseDeclaration(&tok2, variableMap, scopeStack.top().isExecutable);
} catch (const Token * errTok) {
syntaxError(errTok);
}
Expand Down
5 changes: 1 addition & 4 deletions lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ void TokenList::determineCppC()
{
// only try to determine it if it wasn't enforced
if (mLang == Standards::Language::None) {
if (Path::isC(getSourceFilePath()))
mLang = Standards::Language::C;
else if (Path::isCPP(getSourceFilePath()))
mLang = Standards::Language::CPP;
mLang = Path::identify(getSourceFilePath());
}
}

Expand Down
Loading