Skip to content

Commit

Permalink
s [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave committed Apr 24, 2024
1 parent 688e140 commit 78807ce
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 39 deletions.
8 changes: 4 additions & 4 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,8 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
}
}

else if (std::strcmp(argv[i], "--cpp-probe") == 0) {
mSettings.cppProbe = true;
else if (std::strcmp(argv[i], "--cpp-header-probe") == 0) {
mSettings.cppHeaderProbe = true;
}

// Show --debug output after the first simplifications
Expand Down Expand Up @@ -894,8 +894,8 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
return Result::Fail;
}

else if (std::strcmp(argv[i], "--no-cpp-probe") == 0) {
mSettings.cppProbe = false;
else if (std::strcmp(argv[i], "--no-cpp-header-probe") == 0) {
mSettings.cppHeaderProbe = false;
}

// Write results in file
Expand Down
4 changes: 2 additions & 2 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static void createDumpFile(const Settings& settings,
case Standards::Language::None:
{
// TODO: error out on unknown language?
const Standards::Language lang = Path::identify(filename, settings.cppProbe);
const Standards::Language lang = Path::identify(filename, settings.cppHeaderProbe);
if (lang == Standards::Language::CPP)
language = " language=\"cpp\"";
else if (lang == Standards::Language::C)
Expand Down Expand Up @@ -420,7 +420,7 @@ unsigned int CppCheck::checkClang(const std::string &path)
mErrorLogger.reportOut(std::string("Checking ") + path + " ...", Color::FgGreen);

// TODO: this ignores the configured language
const bool isCpp = Path::identify(path, mSettings.cppProbe) == Standards::Language::CPP;
const bool isCpp = Path::identify(path, mSettings.cppHeaderProbe) == 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";
Expand Down
22 changes: 14 additions & 8 deletions lib/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <sys/stat.h>
#include <unordered_set>
#include <utility>
Expand Down Expand Up @@ -252,16 +251,23 @@ bool Path::isHeader(const std::string &path)
static bool hasEmacsCppMarker(const char* path)
{
// TODO: identify is called three times for each file
// Preprocessor::loadFiles() -> createDUI()
// Preprocessor::preprocess() -> createDUI()
// TokenList::createTokens() -> TokenList::determineCppC()
std::cout << path << '\n';

FILE *fp = fopen(path, "rt");
if (!fp)
return false;
std::unique_ptr<FILE, decltype(&fclose)> fp_deleter(fp, fclose);
std::string buf(1024, '\0');
// TODO: read first line only
if (fgets(const_cast<char*>(buf.data()), buf.size(), fp) == nullptr)
return false; // failed to read file
{
// TODO: read first line only
const char * const res = fgets(const_cast<char*>(buf.data()), buf.size(), fp);
fclose(fp);
fp = nullptr;
if (!res)
return false; // failed to read file
}
// TODO: replace with regular expression
const auto pos1 = buf.find("-*-");
if (pos1 == std::string::npos)
Expand Down Expand Up @@ -301,15 +307,15 @@ static bool hasEmacsCppMarker(const char* path)
return false; // marker is not a C++ one
}

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

std::string ext = getFilenameExtension(path);
// standard library headers have no extension
if (cppProbe && ext.empty()) {
if (cppHeaderProbe && ext.empty()) {
if (hasEmacsCppMarker(path.c_str())) {
if (header)
*header = true;
Expand All @@ -326,7 +332,7 @@ Standards::Language Path::identify(const std::string &path, bool cppProbe, bool
if (ext == ".h") {
if (header)
*header = true;
if (cppProbe && hasEmacsCppMarker(path.c_str()))
if (cppHeaderProbe && hasEmacsCppMarker(path.c_str()))
return Standards::Language::CPP;
return Standards::Language::C;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,11 @@ class CPPCHECKLIB Path {
/**
* @brief Identify the language based on the file extension
* @param path filename to check. path info is optional
* @param cppProbe check optional Emacs marker to idengtify headers as C++
* @param cppHeaderProbe check optional Emacs marker to identify extension-less and *.h files as C++
* @param header if provided indicates if the file is a header
* @return the language type
*/
static Standards::Language identify(const std::string &path, bool cppProbe, bool *header = nullptr);
static Standards::Language identify(const std::string &path, bool cppHeaderProbe, bool *header = nullptr);

/**
* @brief Get filename without a directory path part.
Expand Down
2 changes: 1 addition & 1 deletion lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
dui.includes = mSettings.userIncludes; // --include
// TODO: use mSettings.standards.stdValue instead
// TODO: error out on unknown language?
const Standards::Language lang = Path::identify(filename, mSettings.cppProbe);
const Standards::Language lang = Path::identify(filename, mSettings.cppHeaderProbe);
if (lang == Standards::Language::CPP) {
dui.std = mSettings.standards.getCPP();
splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, "");
Expand Down
4 changes: 2 additions & 2 deletions lib/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ class CPPCHECKLIB WARN_UNUSED Settings {
/** cppcheck.cfg: About text */
std::string cppcheckCfgAbout;

/** @brief check Emacs marker to detect header files as C++ */
bool cppProbe{};
/** @brief check Emacs marker to detect extension-less and *.h files as C++ */
bool cppHeaderProbe{};

/** @brief Are we running from DACA script? */
bool daca{};
Expand Down
2 changes: 1 addition & 1 deletion lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void TokenList::determineCppC()
// only try to determine if it wasn't enforced
if (mLang == Standards::Language::None) {
ASSERT_LANG(!getSourceFilePath().empty());
mLang = Path::identify(getSourceFilePath(), mSettings ? mSettings->cppProbe : false);
mLang = Path::identify(getSourceFilePath(), mSettings ? mSettings->cppHeaderProbe : false);
// TODO: cannot enable assert as this might occur for unknown extensions
//ASSERT_LANG(mLang != Standards::Language::None);
if (mLang == Standards::Language::None) {
Expand Down
1 change: 1 addition & 0 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ Deprecations:
-

Other:
- added command-line option `--cpp-header-probe` (and `--no-cpp-header-probe`) to probe headers and extension-less files for Emacs marker (see https://trac.cppcheck.net/ticket/10692 for more details)
-
5 changes: 2 additions & 3 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,7 @@ def test_cpp_probe(tmpdir):
'class A {};'
])

args = ['-q', '--template=simple', '--cpp-probe', test_file]
args = ['-q', '--template=simple', '--cpp-header-probe', test_file]
err_lines = [
"{}:1:1: error: Code 'classA{{' is invalid C code. Use --std or --language to configure the language. [syntaxError]".format(test_file)
]
Expand All @@ -1453,7 +1453,6 @@ def test_cpp_probe_2(tmpdir):
'class A {};'
])

# TODO: the probing is performed twice
args = ['-q', '--template=simple', '--cpp-probe', test_file]
args = ['-q', '--template=simple', '--cpp-header-probe', test_file]

assert_cppcheck(args, ec_exp=0, err_exp=[], out_exp=[])
32 changes: 16 additions & 16 deletions test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,10 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(checkLevelNormal);
TEST_CASE(checkLevelExhaustive);
TEST_CASE(checkLevelUnknown);
TEST_CASE(cppProbe);
TEST_CASE(cppProbe2);
TEST_CASE(noCppProbe);
TEST_CASE(noCppProbe2);
TEST_CASE(cppHeaderProbe);
TEST_CASE(cppHeaderProbe2);
TEST_CASE(noCppHeaderProbe);
TEST_CASE(noCppHeaderProbe2);

TEST_CASE(ignorepaths1);
TEST_CASE(ignorepaths2);
Expand Down Expand Up @@ -2607,32 +2607,32 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("cppcheck: error: unknown '--check-level' value 'default'.\n", logger->str());
}

void cppProbe() {
void cppHeaderProbe() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--cpp-probe", "file.cpp"};
const char * const argv[] = {"cppcheck", "--cpp-header-probe", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
ASSERT_EQUALS(true, settings->cppProbe);
ASSERT_EQUALS(true, settings->cppHeaderProbe);
}

void cppProbe2() {
void cppHeaderProbe2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--no-cpp-probe", "--cpp-probe", "file.cpp"};
const char * const argv[] = {"cppcheck", "--no-cpp-header-probe", "--cpp-header-probe", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(4, argv));
ASSERT_EQUALS(true, settings->cppProbe);
ASSERT_EQUALS(true, settings->cppHeaderProbe);
}

void noCppProbe() {
void noCppHeaderProbe() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--no-cpp-probe", "file.cpp"};
const char * const argv[] = {"cppcheck", "--no-cpp-header-probe", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
ASSERT_EQUALS(false, settings->cppProbe);
ASSERT_EQUALS(false, settings->cppHeaderProbe);
}

void noCppProbe2() {
void noCppHeaderProbe2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--cpp-probe", "--no-cpp-probe", "file.cpp"};
const char * const argv[] = {"cppcheck", "--cpp-header-probe", "--no-cpp-header-probe", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(4, argv));
ASSERT_EQUALS(false, settings->cppProbe);
ASSERT_EQUALS(false, settings->cppHeaderProbe);
}

void ignorepaths1() {
Expand Down

0 comments on commit 78807ce

Please sign in to comment.