diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index f2d049364..417c46e5a 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -198,8 +198,6 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty())); if (!fileSettingsRef.empty()) { - // TODO: handle ignored? - // TODO: de-duplicate std::list fileSettings; @@ -1258,8 +1256,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a substituteTemplateFormatStatic(mSettings.templateFormat); substituteTemplateLocationStatic(mSettings.templateLocation); - project.ignorePaths(mIgnoredPaths); - if (mSettings.force || maxconfigs) mSettings.checkAllConfigurations = true; @@ -1270,6 +1266,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.maxConfigs = 1U; if (mSettings.checks.isEnabled(Checks::unusedFunction) && mSettings.jobs > 1 && mSettings.buildDir.empty()) { + // TODO: bail out mLogger.printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); } @@ -1280,6 +1277,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // Print error only if we have "real" command and expect files if (mPathNames.empty() && project.guiProject.pathNames.empty() && project.fileSettings.empty()) { + // TODO: this message differs from the one reported in fillSettingsFromArgs() mLogger.printError("no C or C++ source files found."); return Result::Fail; } @@ -1287,8 +1285,15 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (!project.guiProject.pathNames.empty()) mPathNames = project.guiProject.pathNames; - if (!project.fileSettings.empty()) + if (!project.fileSettings.empty()) { + project.ignorePaths(mIgnoredPaths); + if (project.fileSettings.empty()) { + mLogger.printError("no C or C++ source files found."); + mLogger.printMessage("all paths were ignored"); // TODO: log this differently? + return Result::Fail; + } mFileSettings = project.fileSettings; + } // Use paths _pathnames if no base paths for relative path output are given if (mSettings.basePaths.empty() && mSettings.relativePaths) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index ba2e4170c..3c672f7d8 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -427,7 +427,7 @@ unsigned int CppCheck::check(const std::string &path) { if (mSettings.clang) { if (!mSettings.quiet) - mErrorLogger.reportOut(std::string("Checking ") + path + "...", Color::FgGreen); + mErrorLogger.reportOut(std::string("Checking ") + path + " ...", Color::FgGreen); const std::string lang = Path::isCPP(path) ? "-x c++" : "-x c"; const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, emptyString); diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 266be1351..54a62e2f6 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -40,6 +40,7 @@ #include "json.h" +// TODO: align the exclusion logic with PathMatch void ImportProject::ignorePaths(const std::vector &ipaths) { for (std::list::iterator it = fileSettings.begin(); it != fileSettings.end();) { diff --git a/lib/pathmatch.cpp b/lib/pathmatch.cpp index 882ac03bf..a72a57fe3 100644 --- a/lib/pathmatch.cpp +++ b/lib/pathmatch.cpp @@ -38,6 +38,7 @@ bool PathMatch::match(const std::string &path) const if (path.empty()) return false; + // TODO: align the exclusion logic with ImportProject::ignorePaths() for (std::vector::const_iterator i = mExcludedPaths.cbegin(); i != mExcludedPaths.cend(); ++i) { const std::string excludedPath((!Path::isAbsolute(path) && Path::isAbsolute(*i)) ? Path::getRelativePath(*i, mWorkingDirectory) : *i); diff --git a/test/cli/test-clang-import.py b/test/cli/test-clang-import.py index c4af2ce09..b18ec348e 100644 --- a/test/cli/test-clang-import.py +++ b/test/cli/test-clang-import.py @@ -5,7 +5,7 @@ import os import re import subprocess import pytest -from testutils import cppcheck +from testutils import cppcheck, assert_cppcheck try: subprocess.call(['clang', '--version']) @@ -122,3 +122,14 @@ def test_ast_control_flow(): def test_ast(): check_ast('struct S { int x; }; S* foo() { return new S(); }') +def test_log(tmpdir): + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt'): + pass + + args = ['--clang', test_file] + out_lines = [ + 'Checking {} ...'.format(test_file), + ] + + assert_cppcheck(args, ec_exp=0, err_exp=[], out_exp=out_lines) \ No newline at end of file diff --git a/test/cli/test-helloworld.py b/test/cli/test-helloworld.py index 6c5827293..97632114a 100644 --- a/test/cli/test-helloworld.py +++ b/test/cli/test-helloworld.py @@ -184,7 +184,11 @@ def test_exclude(): prjpath = getRelativeProjectPath() ret, stdout, _ = cppcheck(['-i' + prjpath, '--platform=win64', '--project=' + os.path.join(prjpath, 'helloworld.cppcheck')]) assert ret == 1 - assert stdout == 'cppcheck: error: no C or C++ source files found.\n' + lines = stdout.splitlines() + assert lines == [ + 'cppcheck: error: no C or C++ source files found.', + 'cppcheck: all paths were ignored' + ] def test_build_dir_dump_output(): diff --git a/test/cli/test-more-projects.py b/test/cli/test-more-projects.py index 36e1b2d98..d4e8031fa 100644 --- a/test/cli/test-more-projects.py +++ b/test/cli/test-more-projects.py @@ -157,7 +157,7 @@ def test_project_empty_fields(tmpdir): - + @@ -531,4 +531,109 @@ def test_project_file_ignore(tmpdir): 'cppcheck: Maybe all paths were ignored?' ] + assert_cppcheck(args, ec_exp=1, err_exp=[], out_exp=out_lines) + + +def test_project_file_ignore_2(tmpdir): + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + pass + + project_file = os.path.join(tmpdir, 'test.cppcheck') + with open(project_file, 'wt') as f: + f.write( + """ + + + + + + + +""".format(test_file)) + + args = ['--project={}'.format(project_file)] + out_lines = [ + 'cppcheck: error: could not find or open any of the paths given.', + 'cppcheck: Maybe all paths were ignored?' + ] + + assert_cppcheck(args, ec_exp=1, err_exp=[], out_exp=out_lines) + + +def test_project_file_ignore_3(tmpdir): + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + pass + + project_file = os.path.join(tmpdir, 'test.cppcheck') + with open(project_file, 'wt') as f: + f.write( + """ + + + + + + + +""".format(test_file)) + + args = ['--project={}'.format(project_file)] + out_lines = [ + 'cppcheck: error: could not find or open any of the paths given.', + 'cppcheck: Maybe all paths were ignored?' + ] + + assert_cppcheck(args, ec_exp=1, err_exp=[], out_exp=out_lines) + + +@pytest.mark.xfail +def test_json_file_ignore(tmpdir): + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + pass + + compilation_db = [ + {"directory": str(tmpdir), + "command": "c++ -o bug1.o -c bug1.cpp", + "file": "test.cpp", + "output": "test.o"} + ] + + project_file = os.path.join(tmpdir, 'test.json') + with open(project_file, 'wt') as f: + f.write(json.dumps(compilation_db)) + + args = ['-itest.cpp', '--project={}'.format(project_file)] + out_lines = [ + 'cppcheck: error: no C or C++ source files found.', + 'cppcheck: all paths were ignored' + ] + + assert_cppcheck(args, ec_exp=1, err_exp=[], out_exp=out_lines) + + +def test_json_file_ignore_2(tmpdir): + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + pass + + compilation_db = [ + {"directory": str(tmpdir), + "command": "c++ -o bug1.o -c bug1.cpp", + "file": "test.cpp", + "output": "test.o"} + ] + + project_file = os.path.join(tmpdir, 'test.json') + with open(project_file, 'wt') as f: + f.write(json.dumps(compilation_db)) + + args = ['-i{}'.format(test_file), '--project={}'.format(project_file)] + out_lines = [ + 'cppcheck: error: no C or C++ source files found.', + 'cppcheck: all paths were ignored' + ] + assert_cppcheck(args, ec_exp=1, err_exp=[], out_exp=out_lines) \ No newline at end of file