Skip to content

Commit 3e0fd09

Browse files
committed
added Path::identify() and deprecated flawed Path::isCPP(), Path::isC() and Path::isHeader()
1 parent 7c7ccdf commit 3e0fd09

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
@@ -449,7 +449,7 @@ validateRules:
449449

450450
###### Build
451451

452-
$(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
452+
$(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
453453
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp
454454

455455
$(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/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h
@@ -563,22 +563,22 @@ $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.
563563
$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/valueptr.h lib/vfvalue.h
564564
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp
565565

566-
$(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
566+
$(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
567567
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp
568568

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

572-
$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/utils.h
572+
$(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
573573
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp
574574

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

578-
$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
578+
$(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
579579
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathmatch.cpp
580580

581-
$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/path.h lib/platform.h
581+
$(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
582582
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp
583583

584584
$(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/timer.h lib/utils.h
@@ -596,7 +596,7 @@ $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/conf
596596
$(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/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
597597
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp
598598

599-
$(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
599+
$(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
600600
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp
601601

602602
$(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/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/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
@@ -641,7 +641,7 @@ cli/cppcheckexecutorsig.o: cli/cppcheckexecutorsig.cpp cli/cppcheckexecutor.h cl
641641
cli/executor.o: cli/executor.cpp cli/executor.h
642642
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp
643643

644-
cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/utils.h
644+
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
645645
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/filelister.cpp
646646

647647
cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h
@@ -758,7 +758,7 @@ test/testoptions.o: test/testoptions.cpp lib/check.h lib/color.h lib/config.h li
758758
test/testother.o: test/testother.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.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/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
759759
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp
760760

761-
test/testpath.o: test/testpath.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/path.h lib/suppressions.h test/fixture.h
761+
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
762762
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp
763763

764764
test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/pathmatch.h lib/suppressions.h test/fixture.h

cli/cppcheckexecutor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
132132
// Output a warning for the user if he tries to exclude headers
133133
const std::vector<std::string>& ignored = parser.getIgnoredPaths();
134134
const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](const std::string& i) {
135-
return Path::isHeader(i);
135+
bool header;
136+
Path::identify(i, &header);
137+
return header;
136138
});
137139
if (warn) {
138140
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
@@ -955,7 +955,9 @@ void ResultsTree::recheckSelectedFiles()
955955
askFileDir(currentFile);
956956
return;
957957
}
958-
if (Path::isHeader(currentFile.toStdString())) {
958+
bool header = false;
959+
Path::identify(currentFile.toStdString(), &header);
960+
if (header) {
959961
if (!data[FILE0].toString().isEmpty() && !selectedItems.contains(data[FILE0].toString())) {
960962
selectedItems<<((!mCheckPath.isEmpty() && (data[FILE0].toString().indexOf(mCheckPath) != 0)) ? (mCheckPath + "/" + data[FILE0].toString()) : data[FILE0].toString());
961963
if (!selectedItems.contains(fileNameWithCheckPath))

gui/resultsview.cpp

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

401401
const QString file0 = data["file0"].toString();
402-
if (!file0.isEmpty() && Path::isHeader(data["file"].toString().toStdString()))
403-
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by")).arg(QDir::toNativeSeparators(file0));
402+
if (!file0.isEmpty()) {
403+
bool header = false;
404+
Path::identify(data["file"].toString().toStdString(), &header);
405+
if (header)
406+
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by")).arg(QDir::toNativeSeparators(file0));
407+
}
404408

405409
if (data["cwe"].toInt() > 0)
406410
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
@@ -79,6 +79,17 @@
7979
# define UNUSED
8080
#endif
8181

82+
// deprecated
83+
#if defined(__GNUC__) \
84+
|| defined(__clang__) \
85+
|| defined(__CPPCHECK__)
86+
# define DEPRECATED __attribute__((deprecated))
87+
#elif defined(_MSC_VER)
88+
# define DEPRECATED __declspec(deprecated)
89+
#else
90+
# define DEPRECATED
91+
#endif
92+
8293
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
8394

8495
#include <string>

lib/cppcheck.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,11 @@ static void createDumpFile(const Settings& settings,
269269
language = " language=\"cpp\"";
270270
break;
271271
case Settings::Language::None:
272-
if (Path::isCPP(filename))
272+
// TODO: error out on unknown language?
273+
const Settings::Language lang = Path::identify(filename);
274+
if (lang == Settings::Language::CPP)
273275
language = " language=\"cpp\"";
274-
else if (Path::isC(filename))
276+
else if (lang == Settings::Language::C)
275277
language = " language=\"c\"";
276278
break;
277279
}
@@ -456,7 +458,9 @@ unsigned int CppCheck::check(const std::string &path)
456458
if (!mSettings.quiet)
457459
mErrorLogger.reportOut(std::string("Checking ") + path + "...", Color::FgGreen);
458460

459-
const std::string lang = Path::isCPP(path) ? "-x c++" : "-x c";
461+
const bool isCpp = Path::identify(path) == Settings::Language::CPP;
462+
463+
const std::string langOpt = isCpp ? "-x c++" : "-x c";
460464
const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, emptyString);
461465
const std::string clangcmd = analyzerInfo + ".clang-cmd";
462466
const std::string clangStderr = analyzerInfo + ".clang-stderr";
@@ -469,8 +473,8 @@ unsigned int CppCheck::check(const std::string &path)
469473
}
470474
#endif
471475

472-
std::string flags(lang + " ");
473-
if (Path::isCPP(path) && !mSettings.standards.stdValue.empty())
476+
std::string flags(langOpt + " ");
477+
if (isCpp && !mSettings.standards.stdValue.empty())
474478
flags += "-std=" + mSettings.standards.stdValue + " ";
475479

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

lib/path.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <algorithm>
2727
#include <cstdlib>
2828
#include <fstream>
29+
#include <unordered_set>
2930
#include <utility>
3031

3132
#ifndef _WIN32
@@ -167,6 +168,18 @@ std::string Path::getRelativePath(const std::string& absolutePath, const std::ve
167168
return absolutePath;
168169
}
169170

171+
static const std::unordered_set<std::string> cpp_src_exts = {
172+
".cpp", ".cxx", ".cc", ".c++", ".tpp", ".txx", ".ipp", ".ixx"
173+
};
174+
175+
static const std::unordered_set<std::string> c_src_exts = {
176+
".c", ".cl"
177+
};
178+
179+
static const std::unordered_set<std::string> header_exts = {
180+
".h", ".hpp", ".h++", ".hxx", ".hh"
181+
};
182+
170183
bool Path::isC(const std::string &path)
171184
{
172185
// In unix, ".C" is considered C++ file
@@ -194,7 +207,8 @@ bool Path::isCPP(const std::string &path)
194207

195208
bool Path::acceptFile(const std::string &path, const std::set<std::string> &extra)
196209
{
197-
return !Path::isHeader(path) && (Path::isCPP(path) || Path::isC(path) || extra.find(getFilenameExtension(path)) != extra.end());
210+
bool header = false;
211+
return (identify(path, &header) != Settings::Language::None && !header) || extra.find(getFilenameExtension(path)) != extra.end();
198212
}
199213

200214
bool Path::isHeader(const std::string &path)
@@ -203,6 +217,33 @@ bool Path::isHeader(const std::string &path)
203217
return (extension.compare(0, 2, ".h") == 0);
204218
}
205219

220+
Settings::Language Path::identify(const std::string &path, bool *header)
221+
{
222+
if (header)
223+
*header = false;
224+
225+
std::string ext = getFilenameExtension(path);
226+
if (ext == ".C")
227+
return Settings::Language::CPP;
228+
if (c_src_exts.find(ext) != c_src_exts.end())
229+
return Settings::Language::C;
230+
if (!caseInsensitiveFilesystem())
231+
strTolower(ext);
232+
if (ext == ".h") {
233+
if (header)
234+
*header = true;
235+
return Settings::Language::C; // treat as C for now
236+
}
237+
if (cpp_src_exts.find(ext) != cpp_src_exts.end())
238+
return Settings::Language::CPP;
239+
if (header_exts.find(ext) != header_exts.end()) {
240+
if (header)
241+
*header = true;
242+
return Settings::Language::CPP;
243+
}
244+
return Settings::Language::None;
245+
}
246+
206247
std::string Path::getAbsoluteFilePath(const std::string& filePath)
207248
{
208249
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>
@@ -150,22 +151,33 @@ class CPPCHECKLIB Path {
150151
* @brief Identify language based on file extension.
151152
* @param path filename to check. path info is optional
152153
* @return true if extension is meant for C files
154+
* @deprecated does not account for headers - use @identify() instead
153155
*/
154-
static bool isC(const std::string &path);
156+
static DEPRECATED bool isC(const std::string &path);
155157

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

163166
/**
164167
* @brief Is filename a header based on file extension
165168
* @param path filename to check. path info is optional
166169
* @return true if filename extension is meant for headers
170+
* @deprecated returns only heuristic result - use @identify() instead
167171
*/
168-
static bool isHeader(const std::string &path);
172+
static DEPRECATED bool isHeader(const std::string &path);
173+
174+
/**
175+
* @brief Identify the language based on the file extension
176+
* @param path filename to check. path info is optional
177+
* @param header if provided indicates if the file is a header
178+
* @return the language type
179+
*/
180+
static Settings::Language identify(const std::string &path, bool *header = nullptr);
169181

170182
/**
171183
* @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
@@ -622,9 +622,11 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
622622
dui.includePaths = mSettings.includePaths; // -I
623623
dui.includes = mSettings.userIncludes; // --include
624624
// TODO: use mSettings.standards.stdValue instead
625-
if (Path::isCPP(filename))
625+
// TODO: error out on unknown language?
626+
const Settings::Language lang = Path::identify(filename);
627+
if (lang == Settings::Language::CPP)
626628
dui.std = mSettings.standards.getCPP();
627-
else
629+
else if (lang == Settings::Language::C)
628630
dui.std = mSettings.standards.getC();
629631
return dui;
630632
}

lib/tokenlist.cpp

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

118118
void TokenList::determineCppC()
119119
{
120-
if (!mSettings) {
121-
mIsC = Path::isC(getSourceFilePath());
122-
mIsCpp = Path::isCPP(getSourceFilePath());
123-
} else {
124-
mIsC = mSettings->enforcedLang == Settings::Language::C || (mSettings->enforcedLang == Settings::Language::None && Path::isC(getSourceFilePath()));
125-
mIsCpp = mSettings->enforcedLang == Settings::Language::CPP || (mSettings->enforcedLang == Settings::Language::None && Path::isCPP(getSourceFilePath()));
126-
}
120+
Settings::Language lang;
121+
if (mSettings && mSettings->enforcedLang != Settings::Language::None)
122+
lang = mSettings->enforcedLang;
123+
else
124+
lang = Path::identify(getSourceFilePath());
125+
126+
mIsC = lang == Settings::Language::C;
127+
mIsCpp = lang == Settings::Language::CPP;
127128

128129
if (mIsCpp) {
129130
//mKeywords.insert("bool"); // type

0 commit comments

Comments
 (0)