Skip to content

Commit d50c451

Browse files
committed
added Path::identify() and deprecated flawed Path::isCPP(), Path::isC() and Path::isHeader()
1 parent 30ca8e1 commit d50c451

11 files changed

Lines changed: 240 additions & 30 deletions

File tree

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/ad
467467
$(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
468468
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp
469469

470-
$(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
470+
$(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
471471
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp
472472

473473
$(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
@@ -599,13 +599,13 @@ $(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astuti
599599
$(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/utils.h
600600
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/mathlib.cpp
601601

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

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

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

611611
$(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
@@ -662,7 +662,7 @@ cli/cppcheckexecutorsig.o: cli/cppcheckexecutorsig.cpp cli/cppcheckexecutor.h cl
662662
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
663663
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp
664664

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

668668
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

cli/cmdlineparser.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
185185
// Output a warning for the user if he tries to exclude headers
186186
const std::vector<std::string>& ignored = getIgnoredPaths();
187187
const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](const std::string& i) {
188-
return Path::isHeader(i);
188+
bool header;
189+
Path::identify(i, &header);
190+
return header;
189191
});
190192
if (warn) {
191193
mLogger.printMessage("filename exclusion does not apply to header (.h and .hpp) files.");

gui/resultstree.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,9 @@ void ResultsTree::recheckSelectedFiles()
962962
askFileDir(currentFile);
963963
return;
964964
}
965-
if (Path::isHeader(currentFile.toStdString())) {
965+
bool header = false;
966+
Path::identify(currentFile.toStdString(), &header);
967+
if (header) {
966968
if (!data[FILE0].toString().isEmpty() && !selectedItems.contains(data[FILE0].toString())) {
967969
selectedItems<<((!mCheckPath.isEmpty() && (data[FILE0].toString().indexOf(mCheckPath) != 0)) ? (mCheckPath + "/" + data[FILE0].toString()) : data[FILE0].toString());
968970
if (!selectedItems.contains(fileNameWithCheckPath))

gui/resultsview.cpp

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

464464
const QString file0 = data["file0"].toString();
465-
if (!file0.isEmpty() && Path::isHeader(data["file"].toString().toStdString()))
466-
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by"), QDir::toNativeSeparators(file0));
465+
if (!file0.isEmpty()) {
466+
bool header = false;
467+
Path::identify(data["file"].toString().toStdString(), &header);
468+
if (header)
469+
formattedMsg += QString("\n\n%1: %2").arg(tr("First included by"), QDir::toNativeSeparators(file0));
470+
}
467471

468472
if (data["cwe"].toInt() > 0)
469473
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
@@ -110,6 +110,17 @@
110110
# define WARN_UNUSED
111111
#endif
112112

113+
// deprecated
114+
#if defined(__GNUC__) \
115+
|| defined(__clang__) \
116+
|| defined(__CPPCHECK__)
117+
# define DEPRECATED __attribute__((deprecated))
118+
#elif defined(_MSC_VER)
119+
# define DEPRECATED __declspec(deprecated)
120+
#else
121+
# define DEPRECATED
122+
#endif
123+
113124
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
114125

115126
#include <string>

lib/cppcheck.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,11 @@ static void createDumpFile(const Settings& settings,
195195
language = " language=\"cpp\"";
196196
break;
197197
case Standards::Language::None:
198-
if (Path::isCPP(filename))
198+
// TODO: error out on unknown language?
199+
const Standards::Language lang = Path::identify(filename);
200+
if (lang == Standards::Language::CPP)
199201
language = " language=\"cpp\"";
200-
else if (Path::isC(filename))
202+
else if (lang == Standards::Language::C)
201203
language = " language=\"c\"";
202204
break;
203205
}
@@ -429,7 +431,8 @@ unsigned int CppCheck::checkClang(const std::string &path)
429431
mErrorLogger.reportOut(std::string("Checking ") + path + " ...", Color::FgGreen);
430432

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

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

450453
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 <sys/stat.h>
29+
#include <unordered_set>
2930
#include <utility>
3031

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

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

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

226240
bool Path::isHeader(const std::string &path)
@@ -229,6 +243,33 @@ bool Path::isHeader(const std::string &path)
229243
return startsWith(extension, ".h");
230244
}
231245

246+
Standards::Language Path::identify(const std::string &path, bool *header)
247+
{
248+
if (header)
249+
*header = false;
250+
251+
std::string ext = getFilenameExtension(path);
252+
if (ext == ".C")
253+
return Standards::Language::CPP;
254+
if (c_src_exts.find(ext) != c_src_exts.end())
255+
return Standards::Language::C;
256+
if (!caseInsensitiveFilesystem())
257+
strTolower(ext);
258+
if (ext == ".h") {
259+
if (header)
260+
*header = true;
261+
return Standards::Language::C; // treat as C for now
262+
}
263+
if (cpp_src_exts.find(ext) != cpp_src_exts.end())
264+
return Standards::Language::CPP;
265+
if (header_exts.find(ext) != header_exts.end()) {
266+
if (header)
267+
*header = true;
268+
return Standards::Language::CPP;
269+
}
270+
return Standards::Language::None;
271+
}
272+
232273
std::string Path::getAbsoluteFilePath(const std::string& filePath)
233274
{
234275
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 "standards.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 Standards::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
@@ -730,11 +730,13 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
730730
dui.includePaths = mSettings.includePaths; // -I
731731
dui.includes = mSettings.userIncludes; // --include
732732
// TODO: use mSettings.standards.stdValue instead
733-
if (Path::isCPP(filename)) {
733+
// TODO: error out on unknown language?
734+
const Standards::Language lang = Path::identify(filename);
735+
if (lang == Standards::Language::CPP) {
734736
dui.std = mSettings.standards.getCPP();
735737
splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, "");
736738
}
737-
else {
739+
else if (lang == Standards::Language::C) {
738740
dui.std = mSettings.standards.getC();
739741
splitcfg(mSettings.platform.getLimitsDefines(Standards::getC(dui.std)), dui.defines, "");
740742
}

lib/tokenlist.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,7 @@ void TokenList::determineCppC()
8585
{
8686
// only try to determine it if it wasn't enforced
8787
if (mLang == Standards::Language::None) {
88-
if (Path::isC(getSourceFilePath()))
89-
mLang = Standards::Language::C;
90-
else if (Path::isCPP(getSourceFilePath()))
91-
mLang = Standards::Language::CPP;
88+
mLang = Path::identify(getSourceFilePath());
9289
}
9390
}
9491

0 commit comments

Comments
 (0)