From b035ba624cd47d5751cdb2c44732b27ec5a21537 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 10 Mar 2025 11:44:52 +0000 Subject: [PATCH 1/4] Fix #11: Add conversion of case insensitive input to real path --- config.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++---- config.h | 3 ++- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/config.cpp b/config.cpp index 5f8de8a..ba47e4f 100644 --- a/config.cpp +++ b/config.cpp @@ -135,6 +135,49 @@ static std::filesystem::path normalizePath(const std::filesystem::path path) return result; } +std::string Config::matchFilenameFromCompileCommand() +{ + auto path = findFile(m_cppcheck, "compile_commands.json"); + + if (path.empty()) + return "Failed to find 'compile_commands.json' in any parent directory of cppcheck"; + + // Read compile_commands file + std::ifstream ifs(path); + if (ifs.fail()) + return std::strerror(errno); + + const std::string text(std::istreambuf_iterator(ifs), {}); + + // Parse JSON + picojson::value compileCommands; + const std::string err = picojson::parse(compileCommands, text); + if (!err.empty()) { + return err; + } + + if (!compileCommands.is()) + return "Compilation database is not a JSON array"; + + for (const picojson::value &fileInfo : compileCommands.get()) { + picojson::object obj = fileInfo.get(); + + if (obj.count("file") && obj["file"].is()) { + const std::string file = obj["file"].get(); + + // TODO should we warn if the file is not found? + std::error_code err; + if (std::filesystem::equivalent(file, m_filename, err)) { + m_filename = file; + return ""; + } + } + + } + + return "File not found"; +} + std::string Config::parseArgs(int argc, char **argv) { (void) argc; @@ -170,12 +213,12 @@ std::string Config::parseArgs(int argc, char **argv) return error; } if (m_configPath.empty()) - m_configPath = findConfig(m_filename); + m_configPath = findFile(m_filename, "run-cppcheck-config.json"); if (m_configPath.empty()) return "Failed to find 'run-cppcheck-config.json' in any parent directory of analyzed file"; - const std::string err = load(m_configPath); + std::string err = load(m_configPath); if (!err.empty()) return "Failed to load '" + m_configPath.string() + "': " + err; @@ -185,11 +228,16 @@ std::string Config::parseArgs(int argc, char **argv) if (m_filename.is_relative()) m_filename = normalizePath(std::filesystem::current_path() / m_filename); + err = matchFilenameFromCompileCommand(); + if (!err.empty()) + return + "Failed to find matching file in compile_commands.json: " + err; + return ""; } // Find config file by recursively searching parent directories of input file -std::filesystem::path Config::findConfig(const std::filesystem::path &input_path) +std::filesystem::path Config::findFile(const std::filesystem::path &input_path, const std::string &filename) { auto path = input_path; @@ -198,7 +246,7 @@ std::filesystem::path Config::findConfig(const std::filesystem::path &input_path do { path = path.parent_path(); - const auto config_path = path / "run-cppcheck-config.json"; + const auto config_path = path / filename; if (std::filesystem::exists(config_path)) return config_path; diff --git a/config.h b/config.h index 4d9d237..2fa9fff 100644 --- a/config.h +++ b/config.h @@ -42,8 +42,9 @@ class Config { } private: - static std::filesystem::path findConfig(const std::filesystem::path &input_path); + static std::filesystem::path findFile(const std::filesystem::path &input_path, const std::string &filename); static std::string getDefaultLogFilePath(std::filesystem::path &path); + std::string matchFilenameFromCompileCommand(); std::filesystem::path m_projectFilePath; std::filesystem::path m_logFilePath; From fa0bf8a271c78851dd1791ce32c78ccaa3f01bfb Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 10 Mar 2025 11:53:19 +0000 Subject: [PATCH 2/4] Nits --- config.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/config.cpp b/config.cpp index ba47e4f..0546c4a 100644 --- a/config.cpp +++ b/config.cpp @@ -137,13 +137,8 @@ static std::filesystem::path normalizePath(const std::filesystem::path path) std::string Config::matchFilenameFromCompileCommand() { - auto path = findFile(m_cppcheck, "compile_commands.json"); - - if (path.empty()) - return "Failed to find 'compile_commands.json' in any parent directory of cppcheck"; - // Read compile_commands file - std::ifstream ifs(path); + std::ifstream ifs(m_projectFilePath); if (ifs.fail()) return std::strerror(errno); From 77dad57cdc33cf487646b9e227b70fcae64d10ce Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 10 Mar 2025 12:37:32 +0000 Subject: [PATCH 3/4] Nits 2 --- config.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.cpp b/config.cpp index 0546c4a..c968474 100644 --- a/config.cpp +++ b/config.cpp @@ -137,6 +137,9 @@ static std::filesystem::path normalizePath(const std::filesystem::path path) std::string Config::matchFilenameFromCompileCommand() { + if (m_projectFilePath.empty() || m_projectFilePath.extension() != ".json") + return ""; + // Read compile_commands file std::ifstream ifs(m_projectFilePath); if (ifs.fail()) From c546eedcc6f6ba2a52156bc0889cb8a24a1d97e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 10 Mar 2025 13:18:58 +0000 Subject: [PATCH 4/4] Nits 3 --- config.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/config.cpp b/config.cpp index c968474..cad32b1 100644 --- a/config.cpp +++ b/config.cpp @@ -173,7 +173,7 @@ std::string Config::matchFilenameFromCompileCommand() } - return "File not found"; + return ""; } std::string Config::parseArgs(int argc, char **argv) @@ -227,9 +227,10 @@ std::string Config::parseArgs(int argc, char **argv) m_filename = normalizePath(std::filesystem::current_path() / m_filename); err = matchFilenameFromCompileCommand(); + + // Only warn if compile_commands.json is corrupted if (!err.empty()) - return - "Failed to find matching file in compile_commands.json: " + err; + return "Failed to process compile_commands.json: " + err; return ""; }