diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 7d198f582f3..e644001aedd 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -659,8 +659,23 @@ unsigned int CppCheck::check(const std::string &path, const std::string &content return checkFile(Path::simplifyPath(path), emptyString, &iss); } +void CppCheck::fileNotFoundError(const std::string& filename) +{ + mErrorLogger.reportErr(ErrorMessage({ErrorMessage::FileLocation(filename, 0, 0)}, + filename, + Severity::error, + "File not found", + "fileNotFound", + Certainty::normal)); + mExitCode = 1; +} + unsigned int CppCheck::check(const ImportProject::FileSettings &fs) { + if (!Path::isFile(fs.filename)) { + fileNotFoundError(fs.filename); + return mExitCode; + } CppCheck temp(mErrorLogger, mUseGlobalSuppressions, mExecuteCommand); temp.mSettings = mSettings; if (!temp.mSettings.userDefines.empty()) @@ -1715,6 +1730,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) cppcheck.purgedConfigurationMessage(emptyString,emptyString); cppcheck.mTooManyConfigs = true; cppcheck.tooManyConfigsError(emptyString,0U); + cppcheck.fileNotFoundError("missing.c"); // TODO: add functions to get remaining error messages // call all "getErrorMessages" in all registered Check classes diff --git a/lib/cppcheck.h b/lib/cppcheck.h index fbe73eea1a8..a5374dba45b 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -152,6 +152,9 @@ class CPPCHECKLIB CppCheck : ErrorLogger { /** @brief There has been an internal error => Report information message */ void internalError(const std::string &filename, const std::string &msg); + /** If check is called with a file that does not exist, this critical error message should be reported */ + void fileNotFoundError(const std::string& filename); + /** * @brief Check a file using stream * @param filename file name diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index c13dee7e7d9..baf9579fba2 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -42,6 +42,7 @@ const std::set ErrorLogger::mCriticalErrorIds{ "cppcheckError", "cppcheckLimit", + "fileNotFound", "internalAstError", "instantiationError", "internalError", diff --git a/test/cli/test-proj2.py b/test/cli/test-proj2.py index 868d832ddf0..e152a819723 100644 --- a/test/cli/test-proj2.py +++ b/test/cli/test-proj2.py @@ -153,3 +153,13 @@ def test_gui_project_loads_absolute_vs_solution_2(): ret, stdout, stderr = cppcheck(['--project=test.cppcheck']) assert ret == 0, stdout assert stderr == ERR_A + ERR_B + +def test_vs_project_missing_file(): + with open('proj2/proj2.vcxproj', 'rt') as fin: + s = fin.read() + with open('proj2/test.vcxproj', 'wt') as fout: + fout.write(s.replace('a.c', 'a_missing.c')) + ret, stdout, stderr = cppcheck(['--project=proj2/test.vcxproj', '--file-filter=*/a*'], status_report=True) + assert 'proj2/a/a_missing.c:0:0: error: File not found [fileNotFound]' in stderr + assert 'There was critical errors' in stdout + os.remove('proj2/test.vcxproj') diff --git a/test/cli/testutils.py b/test/cli/testutils.py index 1e53c65db48..d58212c0607 100644 --- a/test/cli/testutils.py +++ b/test/cli/testutils.py @@ -63,7 +63,7 @@ def lookup_cppcheck_exe(): # Run Cppcheck with args -def cppcheck(args, env=None): +def cppcheck(args, env=None, status_report=False): exe = lookup_cppcheck_exe() assert exe is not None, 'no cppcheck binary found' @@ -72,6 +72,6 @@ def cppcheck(args, env=None): comm = p.communicate() stdout = comm[0].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n') stderr = comm[1].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n') - if stdout.find('\nActive checkers:') > 0: + if (not status_report) and stdout.find('\nActive checkers:') > 0: stdout = stdout[:1 + stdout.find('\nActive checkers:')] return p.returncode, stdout, stderr diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 60726a425ea..2a2899644f3 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -45,6 +45,7 @@ class TestCppcheck : public TestFixture { void run() override { TEST_CASE(getErrorMessages); + TEST_CASE(testMissingSourceFile); } void getErrorMessages() const { @@ -76,6 +77,14 @@ class TestCppcheck : public TestFixture { ASSERT(foundPurgedConfiguration); ASSERT(foundTooManyConfigs); } + + void testMissingSourceFile() { + CppCheck cppcheck(*this, false, nullptr); + ImportProject::FileSettings fileSettings; + fileSettings.filename = "missing.cpp"; + cppcheck.check(fileSettings); + ASSERT_EQUALS("[missing.cpp:0]: (error) File not found\n", errout.str()); + } }; REGISTER_TEST(TestCppcheck)