Skip to content

Commit cdf14d9

Browse files
committed
added Path::identify() and deprecated flawed Path::isCPP(), Path::isC() and Path::isHeader()
1 parent 6930844 commit cdf14d9

11 files changed

Lines changed: 251 additions & 37 deletions

File tree

Makefile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ validateRules:
455455

456456
###### Build
457457

458-
$(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/importproject.h lib/path.h lib/platform.h lib/suppressions.h lib/utils.h
458+
$(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/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
459459
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp
460460

461461
$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.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/valueptr.h lib/vfvalue.h
@@ -572,22 +572,22 @@ $(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.
572572
$(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h
573573
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp
574574

575-
$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
575+
$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/importproject.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/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
576576
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp
577577

578578
$(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/utils.h
579579
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/mathlib.cpp
580580

581-
$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/utils.h
581+
$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
582582
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp
583583

584584
$(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
585585
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp
586586

587-
$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
587+
$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
588588
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathmatch.cpp
589589

590-
$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/path.h lib/platform.h
590+
$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
591591
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp
592592

593593
$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
@@ -605,7 +605,7 @@ $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/conf
605605
$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
606606
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp
607607

608-
$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/mathlib.h lib/path.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
608+
$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
609609
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp
610610

611611
$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.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
@@ -650,7 +650,7 @@ cli/cppcheckexecutorsig.o: cli/cppcheckexecutorsig.cpp cli/cppcheckexecutor.h cl
650650
cli/executor.o: cli/executor.cpp cli/executor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
651651
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp
652652

653-
cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
653+
cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
654654
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/filelister.cpp
655655

656656
cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h
@@ -779,7 +779,7 @@ test/testoptions.o: test/testoptions.cpp lib/check.h lib/color.h lib/config.h li
779779
test/testother.o: test/testother.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
780780
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp
781781

782-
test/testpath.o: test/testpath.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
782+
test/testpath.o: test/testpath.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h
783783
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp
784784

785785
test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h

cli/cppcheckexecutor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ bool CppCheckExecutor::parseFromArgs(Settings &settings, int argc, const char* c
151151
// Output a warning for the user if he tries to exclude headers
152152
const std::vector<std::string>& ignored = parser.getIgnoredPaths();
153153
const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](const std::string& i) {
154-
return Path::isHeader(i);
154+
bool header;
155+
Path::identify(i, &header);
156+
return header;
155157
});
156158
if (warn) {
157159
std::cout << "cppcheck: filename exclusion does not apply to header (.h and .hpp) files." << std::endl;

gui/resultstree.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,9 @@ void ResultsTree::recheckSelectedFiles()
950950
askFileDir(currentFile);
951951
return;
952952
}
953-
if (Path::isHeader(currentFile.toStdString())) {
953+
bool header = false;
954+
Path::identify(currentFile.toStdString(), &header);
955+
if (header) {
954956
if (!data[FILE0].toString().isEmpty() && !selectedItems.contains(data[FILE0].toString())) {
955957
selectedItems<<((!mCheckPath.isEmpty() && (data[FILE0].toString().indexOf(mCheckPath) != 0)) ? (mCheckPath + "/" + data[FILE0].toString()) : data[FILE0].toString());
956958
if (!selectedItems.contains(fileNameWithCheckPath))

gui/resultsview.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,12 @@ void ResultsView::updateDetails(const QModelIndex &index)
418418
QString formattedMsg = message;
419419

420420
const QString file0 = data["file0"].toString();
421-
if (!file0.isEmpty() && Path::isHeader(data["file"].toString().toStdString()))
422-
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by")).arg(QDir::toNativeSeparators(file0));
421+
if (!file0.isEmpty()) {
422+
bool header = false;
423+
Path::identify(data["file"].toString().toStdString(), &header);
424+
if (header)
425+
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by")).arg(QDir::toNativeSeparators(file0));
426+
}
423427

424428
if (data["cwe"].toInt() > 0)
425429
formattedMsg.prepend("CWE: " + QString::number(data["cwe"].toInt()) + "\n");

lib/config.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@
8686
# define WARN_UNUSED
8787
#endif
8888

89+
// deprecated
90+
#if defined(__GNUC__) \
91+
|| defined(__clang__) \
92+
|| defined(__CPPCHECK__)
93+
# define DEPRECATED __attribute__((deprecated))
94+
#elif defined(_MSC_VER)
95+
# define DEPRECATED __declspec(deprecated)
96+
#else
97+
# define DEPRECATED
98+
#endif
99+
89100
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
90101

91102
#include <string>

lib/cppcheck.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,11 @@ static void createDumpFile(const Settings& settings,
292292
language = " language=\"cpp\"";
293293
break;
294294
case Settings::Language::None:
295-
if (Path::isCPP(filename))
295+
// TODO: error out on unknown language?
296+
const Settings::Language lang = Path::identify(filename);
297+
if (lang == Settings::Language::CPP)
296298
language = " language=\"cpp\"";
297-
else if (Path::isC(filename))
299+
else if (lang == Settings::Language::C)
298300
language = " language=\"c\"";
299301
break;
300302
}
@@ -476,7 +478,9 @@ unsigned int CppCheck::check(const std::string &path)
476478
if (!mSettings.quiet)
477479
mErrorLogger.reportOut(std::string("Checking ") + path + "...", Color::FgGreen);
478480

479-
const std::string lang = Path::isCPP(path) ? "-x c++" : "-x c";
481+
const bool isCpp = Path::identify(path) == Settings::Language::CPP;
482+
483+
const std::string langOpt = isCpp ? "-x c++" : "-x c";
480484
const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, emptyString);
481485
const std::string clangcmd = analyzerInfo + ".clang-cmd";
482486
const std::string clangStderr = analyzerInfo + ".clang-stderr";
@@ -489,8 +493,8 @@ unsigned int CppCheck::check(const std::string &path)
489493
}
490494
#endif
491495

492-
std::string flags(lang + " ");
493-
if (Path::isCPP(path) && !mSettings.standards.stdValue.empty())
496+
std::string flags(langOpt + " ");
497+
if (isCpp && !mSettings.standards.stdValue.empty())
494498
flags += "-std=" + mSettings.standards.stdValue + " ";
495499

496500
for (const std::string &i: mSettings.includePaths)

lib/path.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <cstdlib>
2828
#include <fstream>
2929
#include <sys/stat.h>
30+
#include <unordered_set>
3031
#include <utility>
3132

3233
#include <simplecpp.h>
@@ -192,6 +193,18 @@ std::string Path::getRelativePath(const std::string& absolutePath, const std::ve
192193
return absolutePath;
193194
}
194195

196+
static const std::unordered_set<std::string> cpp_src_exts = {
197+
".cpp", ".cxx", ".cc", ".c++", ".tpp", ".txx", ".ipp", ".ixx"
198+
};
199+
200+
static const std::unordered_set<std::string> c_src_exts = {
201+
".c", ".cl"
202+
};
203+
204+
static const std::unordered_set<std::string> header_exts = {
205+
".h", ".hpp", ".h++", ".hxx", ".hh"
206+
};
207+
195208
bool Path::isC(const std::string &path)
196209
{
197210
// In unix, ".C" is considered C++ file
@@ -219,7 +232,8 @@ bool Path::isCPP(const std::string &path)
219232

220233
bool Path::acceptFile(const std::string &path, const std::set<std::string> &extra)
221234
{
222-
return !Path::isHeader(path) && (Path::isCPP(path) || Path::isC(path) || extra.find(getFilenameExtension(path)) != extra.end());
235+
bool header = false;
236+
return (identify(path, &header) != Settings::Language::None && !header) || extra.find(getFilenameExtension(path)) != extra.end();
223237
}
224238

225239
bool Path::isHeader(const std::string &path)
@@ -228,6 +242,33 @@ bool Path::isHeader(const std::string &path)
228242
return (extension.compare(0, 2, ".h") == 0);
229243
}
230244

245+
Settings::Language Path::identify(const std::string &path, bool *header)
246+
{
247+
if (header)
248+
*header = false;
249+
250+
std::string ext = getFilenameExtension(path);
251+
if (ext == ".C")
252+
return Settings::Language::CPP;
253+
if (c_src_exts.find(ext) != c_src_exts.end())
254+
return Settings::Language::C;
255+
if (!caseInsensitiveFilesystem())
256+
strTolower(ext);
257+
if (ext == ".h") {
258+
if (header)
259+
*header = true;
260+
return Settings::Language::C; // treat as C for now
261+
}
262+
if (cpp_src_exts.find(ext) != cpp_src_exts.end())
263+
return Settings::Language::CPP;
264+
if (header_exts.find(ext) != header_exts.end()) {
265+
if (header)
266+
*header = true;
267+
return Settings::Language::CPP;
268+
}
269+
return Settings::Language::None;
270+
}
271+
231272
std::string Path::getAbsoluteFilePath(const std::string& filePath)
232273
{
233274
std::string absolute_path;

lib/path.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//---------------------------------------------------------------------------
2323

2424
#include "config.h"
25+
#include "settings.h"
2526

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

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

169172
/**
170173
* @brief Is filename a header based on file extension
171174
* @param path filename to check. path info is optional
172175
* @return true if filename extension is meant for headers
176+
* @deprecated returns only heuristic result - use @identify() instead
173177
*/
174-
static bool isHeader(const std::string &path);
178+
static DEPRECATED bool isHeader(const std::string &path);
179+
180+
/**
181+
* @brief Identify the language based on the file extension
182+
* @param path filename to check. path info is optional
183+
* @param header if provided indicates if the file is a header
184+
* @return the language type
185+
*/
186+
static Settings::Language identify(const std::string &path, bool *header = nullptr);
175187

176188
/**
177189
* @brief Get filename without a directory path part.

lib/preprocessor.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,11 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
619619
dui.includePaths = mSettings.includePaths; // -I
620620
dui.includes = mSettings.userIncludes; // --include
621621
// TODO: use mSettings.standards.stdValue instead
622-
if (Path::isCPP(filename))
622+
// TODO: error out on unknown language?
623+
const Settings::Language lang = Path::identify(filename);
624+
if (lang == Settings::Language::CPP)
623625
dui.std = mSettings.standards.getCPP();
624-
else
626+
else if (lang == Settings::Language::C)
625627
dui.std = mSettings.standards.getC();
626628
dui.clearIncludeCache = mSettings.clearIncludeCache;
627629
return dui;

lib/tokenlist.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ void TokenList::deallocateTokens()
8282

8383
void TokenList::determineCppC()
8484
{
85-
if (!mSettings) {
86-
mIsC = Path::isC(getSourceFilePath());
87-
mIsCpp = Path::isCPP(getSourceFilePath());
88-
} else {
89-
mIsC = mSettings->enforcedLang == Settings::Language::C || (mSettings->enforcedLang == Settings::Language::None && Path::isC(getSourceFilePath()));
90-
mIsCpp = mSettings->enforcedLang == Settings::Language::CPP || (mSettings->enforcedLang == Settings::Language::None && Path::isCPP(getSourceFilePath()));
91-
}
85+
Settings::Language lang;
86+
if (mSettings && mSettings->enforcedLang != Settings::Language::None)
87+
lang = mSettings->enforcedLang;
88+
else
89+
lang = Path::identify(getSourceFilePath());
90+
91+
mIsC = lang == Settings::Language::C;
92+
mIsCpp = lang == Settings::Language::CPP;
9293
}
9394

9495
int TokenList::appendFileIfNew(std::string fileName)

0 commit comments

Comments
 (0)