diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index c53b41e..1e41320 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -70,8 +70,8 @@ jobs: - name: run ccccc on itself run: | echo "require 'premake-export-compile-commands/export-compile-commands'" >> premake-system.lua - premake5 --llvm-root="${{steps.LLVM.outputs.LLVM_ROOT}}" --expand-llvm-config --no-3rd export-compile-commands - ./bin/gmake2/Release/ccccc --template-file=template/ccccc_html/template.tpl project/export-compile-commands/release/compile_commands.json > index.html + premake5 --llvm-root="${{steps.LLVM.outputs.LLVM_ROOT}}" --expand-llvm-config export-compile-commands + ./bin/gmake2/Release/ccccc --template-file=template/ccccc_html/template.tpl --exclude-directory=3rd project/export-compile-commands/release/compile_commands.json > index.html - name: Upload index.html uses: actions/upload-artifact@v4 diff --git a/premake5.lua b/premake5.lua index 4eb5c82..069bad6 100644 --- a/premake5.lua +++ b/premake5.lua @@ -12,11 +12,6 @@ newoption { description = "run llvm-config from premake directly" } -newoption { - trigger = "no-3rd", - description = "don't create 3rd party project" -} - -- tinfo is not part of msys newoption { trigger = "without-tinfo", @@ -29,7 +24,6 @@ end local LLVMRoot = _OPTIONS["llvm-root"] local ExpandLLVMConfig = _OPTIONS["expand-llvm-config"] -local No3rd = _OPTIONS["no-3rd"] if (LLVMRoot == nil or LLVMRoot == "") then -- assume llvm is installed in system @@ -98,7 +92,7 @@ solution "ccccc" filter {} startproject "ccccc_app" -if not No3rd then + -- -------------------------------------- group "3rd" -- -------------------------------------- @@ -110,7 +104,7 @@ if not No3rd then files { "%{ThirdRoot}/mstch/src/**.*", "%{ThirdRoot}/mstch/include/**.*" } includedirs { "%{ThirdRoot}/mstch/src", "%{ThirdRoot}/mstch/include" } -end + -- -------------------------------------- group "ccccc" -- -------------------------------------- diff --git a/src/lib/parameters.cpp b/src/lib/parameters.cpp index 547bdd7..9b2c525 100644 --- a/src/lib/parameters.cpp +++ b/src/lib/parameters.cpp @@ -1,5 +1,5 @@ /* -** Copyright 2012-2022 Joris Dauphin +** Copyright 2012-2024 Joris Dauphin */ /* ** This file is part of CCCCC. @@ -28,12 +28,28 @@ #include #include +#include namespace ccccc { namespace { +bool is_subpath(const std::filesystem::path& path, const std::filesystem::path& base) +{ + const auto rel = std::filesystem::relative(path, base); + return !rel.empty() && rel.native()[0] != '.'; +} + +bool withinDirectories(const std::filesystem::path& filename, + const std::vector& directories) +{ + return std::any_of( + directories.begin(), directories.end(), [&](const std::filesystem::path& directory) { + return is_subpath(filename, directory); + }); +} + void ShowVersion(llvm::raw_ostream& os) { os << "CCCCC version 1.3\n"; @@ -56,8 +72,10 @@ void AddFilesFromDatabase(Parameters& parameters, std::filesystem::path compile_ const unsigned size = clang_CompileCommands_getSize(commands); for (unsigned int i = 0; i != size; ++i) { const CXCompileCommand command = clang_CompileCommands_getCommand(commands, i); - parameters.AddFile( - use_clang::getStringAndDispose(clang_CompileCommand_getFilename(command))); + auto filename = use_clang::getStringAndDispose(clang_CompileCommand_getFilename(command)); + if (!withinDirectories(filename, parameters.GetExcludeDirectories())) { + parameters.AddFile(filename); + } } clang_CompileCommands_dispose(commands); @@ -112,6 +130,11 @@ void Parameters::Parse(const std::filesystem::path& cccccRoot, int argc, char** llvm::cl::init(std::filesystem::current_path().string())}; llvm::cl::alias sourceRootAlias{ "R", llvm::cl::desc("Alias for -source-root"), llvm::cl::aliasopt(sourceRoot)}; + llvm::cl::list excludeDirectories{ + "exclude-directory", + llvm::cl::desc("exclude input files from these directories"), + llvm::cl::value_desc("exclude-directory"), + llvm::cl::cat(cccccCategory)}; llvm::cl::list inputFilenames{ llvm::cl::Positional, llvm::cl::desc(""), llvm::cl::OneOrMore}; @@ -121,6 +144,10 @@ void Parameters::Parse(const std::filesystem::path& cccccRoot, int argc, char** llvm::cl::ParseCommandLineOptions( argc, argv, "Compute metrics from input files and output the report"); + for (const auto& directory : excludeDirectories) { + AddExcludeDirectory(directory); + } + for (const std::filesystem::path f : inputFilenames) { if (f.filename() == "compile_commands.json") { if (GetDatabaseRoot().empty()) { @@ -149,6 +176,7 @@ void Parameters::Parse(const std::filesystem::path& cccccRoot, int argc, char** defines.removeArgument(); includes.removeArgument(); inputFilenames.removeArgument(); + excludeDirectories.removeArgument(); extraOptions.removeArgument(); pch.removeArgument(); sourceRoot.removeArgument(); diff --git a/src/lib/parameters.h b/src/lib/parameters.h index 76d9821..5259275 100644 --- a/src/lib/parameters.h +++ b/src/lib/parameters.h @@ -1,5 +1,5 @@ /* -** Copyright 2012-2022 Joris Dauphin +** Copyright 2012-2024 Joris Dauphin */ /* ** This file is part of CCCCC. @@ -40,6 +40,10 @@ class Parameters void AddExtra(const std::string& extra) { m_extras.push_back(extra); } void SetTemplateFilename(const std::filesystem::path& filename) { m_template = filename; } void SetDatabaseRoot(const std::filesystem::path& directory) { m_databaseRoot = directory; } + void AddExcludeDirectory(const std::filesystem::path& directory) + { + m_excludeDirectories.push_back(directory); + } const std::filesystem::path& GetSourceRoot() const { return m_sourceRoot; } const std::vector& Filenames() const { return m_files; } @@ -49,9 +53,11 @@ class Parameters const std::string& GetPch() const { return m_pch; } const std::filesystem::path& GetTemplateFilename() const { return m_template; } const std::filesystem::path& GetDatabaseRoot() const { return m_databaseRoot; } + const std::vector& GetExcludeDirectories() const { return m_excludeDirectories; } private: std::filesystem::path m_sourceRoot; + std::vector m_excludeDirectories; std::vector m_files; std::vector m_includePaths; std::vector m_defines; diff --git a/test/test_parameters.cpp b/test/test_parameters.cpp index 78b58ce..98b5f4d 100644 --- a/test/test_parameters.cpp +++ b/test/test_parameters.cpp @@ -1,5 +1,5 @@ /* -** Copyright 2012-2022 Joris Dauphin +** Copyright 2012-2024 Joris Dauphin */ /* ** This file is part of CCCCC. @@ -75,6 +75,17 @@ TEST_CASE("PARAMETERS_ADD_PCH") CHECK(pchFile == param.GetPch()); } +TEST_CASE("PARAMETERS_ADD_EXCLUDE_DIRECTORY") +{ + const std::vector directories{"3rd", "submodules"}; + ccccc::Parameters param; + + for (const auto& dir : directories) { + param.AddExcludeDirectory(dir); + } + CHECK(directories == param.GetExcludeDirectories()); +} + TEST_CASE("PARAMETERS_PARSING_SHORT_OPTIONS") { const std::string cccccRoot = "."; @@ -129,11 +140,14 @@ TEST_CASE("PARAMETERS_PARSING_LONG_OPTIONS") const char* extraFlag = "-extra-option"; const char* pchFlag = "-pch"; const char* templateFlag = "-template-file"; + const char* excludeDirFlag = "-exclude-directory"; const std::vector files{"a.c", "a.h"}; const std::vector stringFiles{files[0].string(), files[1].string()}; const std::vector includes{"includeDir1", "includeDir2"}; const std::vector defines{"FOO", "BAR=42"}; const std::vector extras{"-std=c++14"}; + const std::vector dirs{"3rd", "exclude"}; + const std::vector stringDirs{dirs[0].string(), dirs[1].string()}; std::string pchFile = "pchFile"; std::string templateFile = "templateFile"; const char* argv[] = {argv0, @@ -151,6 +165,10 @@ TEST_CASE("PARAMETERS_PARSING_LONG_OPTIONS") includes[1].c_str(), templateFlag, templateFile.c_str(), + excludeDirFlag, + stringDirs[0].c_str(), + excludeDirFlag, + stringDirs[1].c_str(), stringFiles[0].c_str(), stringFiles[1].c_str()}; ccccc::Parameters param; @@ -162,5 +180,6 @@ TEST_CASE("PARAMETERS_PARSING_LONG_OPTIONS") CHECK(defines == param.Defines()); CHECK(extras == param.Extras()); CHECK(pchFile == param.GetPch()); + CHECK(dirs == param.GetExcludeDirectories()); CHECK(templateFile == param.GetTemplateFilename()); }