diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 42f51d486..de4daa963 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -362,7 +362,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // use a file filter else if (std::strncmp(argv[i], "--file-filter=", 14) == 0) - mSettings->fileFilter = argv[i] + 14; + mSettings->fileFilters.push_back(argv[i] + 14); // file list specified else if (std::strncmp(argv[i], "--file-list=", 12) == 0) @@ -1055,6 +1055,7 @@ void CmdLineParser::printHelp() " Used when certain messages should be displayed but\n" " should not cause a non-zero exitcode.\n" " --file-filter= Analyze only those files matching the given filter str\n" + " Can be used multiple times\n" " Example: --file-filter=*bar.cpp analyzes only files\n" " that end with bar.cpp.\n" " --file-list= Specify the files to check in a text file. Add one\n" diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 1be14b26a..fd47d59c4 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -167,12 +167,12 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c #else const bool caseSensitive = true; #endif - if (!mSettings->project.fileSettings.empty() && !mSettings->fileFilter.empty()) { + if (!mSettings->project.fileSettings.empty() && !mSettings->fileFilters.empty()) { // filter only for the selected filenames from all project files std::list newList; for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) { - if (matchglob(mSettings->fileFilter, fsetting.filename)) { + if (matchglobs(mSettings->fileFilters, fsetting.filename)) { newList.emplace_back(fsetting); } } @@ -198,10 +198,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (!ignored.empty()) std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl; return false; - } else if (!mSettings->fileFilter.empty() && settings.project.fileSettings.empty()) { + } else if (!mSettings->fileFilters.empty() && settings.project.fileSettings.empty()) { std::map newMap; for (std::map::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i) - if (matchglob(mSettings->fileFilter, i->first)) { + if (matchglobs(mSettings->fileFilters, i->first)) { newMap[i->first] = i->second; } mFiles = newMap; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 4ce6ac4f0..d86d9450f 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -195,19 +195,20 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings if (!mPath.empty() && !endsWith(mPath,'/')) mPath += '/'; - const std::string fileFilter = settings ? settings->fileFilter : std::string(); + const std::vector fileFilters = + settings ? settings->fileFilters : std::vector(); if (endsWith(filename, ".json")) { importCompileCommands(fin); setRelativePaths(filename); return ImportProject::Type::COMPILE_DB; } else if (endsWith(filename, ".sln")) { - importSln(fin, mPath, fileFilter); + importSln(fin, mPath, fileFilters); setRelativePaths(filename); return ImportProject::Type::VS_SLN; } else if (endsWith(filename, ".vcxproj")) { std::map variables; - importVcxproj(filename, variables, emptyString, fileFilter); + importVcxproj(filename, variables, emptyString, fileFilters); setRelativePaths(filename); return ImportProject::Type::VS_VCXPROJ; } else if (endsWith(filename, ".bpr")) { @@ -447,7 +448,7 @@ void ImportProject::importCompileCommands(std::istream &istr) } } -void ImportProject::importSln(std::istream &istr, const std::string &path, const std::string &fileFilter) +void ImportProject::importSln(std::istream &istr, const std::string &path, const std::vector &fileFilters) { std::map variables; variables["SolutionDir"] = path; @@ -465,7 +466,7 @@ void ImportProject::importSln(std::istream &istr, const std::string &path, const std::string vcxproj(line.substr(pos1+1, pos-pos1+7)); if (!Path::isAbsolute(vcxproj)) vcxproj = path + vcxproj; - importVcxproj(Path::fromNativeSeparators(vcxproj), variables, emptyString, fileFilter); + importVcxproj(Path::fromNativeSeparators(vcxproj), variables, emptyString, fileFilters); } } @@ -658,7 +659,7 @@ static void loadVisualStudioProperties(const std::string &props, std::map &variables, const std::string &additionalIncludeDirectories, const std::string &fileFilter) +void ImportProject::importVcxproj(const std::string &filename, std::map &variables, const std::string &additionalIncludeDirectories, const std::vector &fileFilters) { variables["ProjectDir"] = Path::simplifyPath(Path::getPathFromFilename(filename)); @@ -718,7 +719,7 @@ void ImportProject::importVcxproj(const std::string &filename, std::map &variables, const std::string &additionalIncludeDirectories, const std::string &fileFilter); + void importSln(std::istream &istr, const std::string &path, const std::vector &fileFilters); + void importVcxproj(const std::string &filename, std::map &variables, const std::string &additionalIncludeDirectories, const std::vector &fileFilters); void importBcb6Prj(const std::string &projectFilename); void setRelativePaths(const std::string &filename); diff --git a/lib/settings.h b/lib/settings.h index b245557cd..5d1c62b31 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -193,8 +193,8 @@ public: Default value is 0. */ int exitCode; - /** @brief --file-filter for analyzing special files */ - std::string fileFilter; + /** @brief List of --file-filter for analyzing special files */ + std::vector fileFilters; /** @brief Force checking the files with "too many" configurations (--force). */ bool force; diff --git a/lib/utils.cpp b/lib/utils.cpp index cb0de92c7..7f5c8c5ed 100644 --- a/lib/utils.cpp +++ b/lib/utils.cpp @@ -112,3 +112,9 @@ bool matchglob(const std::string& pattern, const std::string& name) n++; } } + +bool matchglobs(const std::vector &patterns, const std::string &name) { + return std::any_of(begin(patterns), end(patterns), [&name](const std::string &pattern) { + return matchglob(pattern, name); + }); +} diff --git a/lib/utils.h b/lib/utils.h index 41edc3a51..ec473342b 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -152,6 +152,8 @@ CPPCHECKLIB bool isValidGlobPattern(const std::string& pattern); CPPCHECKLIB bool matchglob(const std::string& pattern, const std::string& name); +CPPCHECKLIB bool matchglobs(const std::vector &patterns, const std::string &name); + #define UNUSED(x) (void)(x) // Use the nonneg macro when you want to assert that a variable/argument is not negative