Implement support for passing multiple file filters (#3479)

This commit is contained in:
Leon De Andrade 2021-11-23 22:51:45 +01:00 committed by GitHub
parent b80e24231b
commit 5b52f4946a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 26 additions and 16 deletions

View File

@ -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=<str> 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=<file> Specify the files to check in a text file. Add one\n"

View File

@ -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<ImportProject::FileSettings> 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<std::string, std::size_t> newMap;
for (std::map<std::string, std::size_t>::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;

View File

@ -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<std::string> fileFilters =
settings ? settings->fileFilters : std::vector<std::string>();
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<std::string, std::string, cppcheck::stricmp> 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<std::string> &fileFilters)
{
std::map<std::string,std::string,cppcheck::stricmp> 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<std::s
}
}
void ImportProject::importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::string &fileFilter)
void ImportProject::importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::vector<std::string> &fileFilters)
{
variables["ProjectDir"] = Path::simplifyPath(Path::getPathFromFilename(filename));
@ -718,7 +719,7 @@ void ImportProject::importVcxproj(const std::string &filename, std::map<std::str
for (const std::string &c : compileList) {
const std::string cfilename = Path::simplifyPath(Path::isAbsolute(c) ? c : Path::getPathFromFilename(filename) + c);
if (!fileFilter.empty() && !matchglob(fileFilter, cfilename))
if (!fileFilters.empty() && !matchglobs(fileFilters, cfilename))
continue;
for (const ProjectConfiguration &p : projectConfigurationList) {

View File

@ -109,8 +109,8 @@ protected:
void importCompileCommands(std::istream &istr);
bool importCppcheckGuiProject(std::istream &istr, Settings *settings);
private:
void importSln(std::istream &istr, const std::string &path, const std::string &fileFilter);
void importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::string &fileFilter);
void importSln(std::istream &istr, const std::string &path, const std::vector<std::string> &fileFilters);
void importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::vector<std::string> &fileFilters);
void importBcb6Prj(const std::string &projectFilename);
void setRelativePaths(const std::string &filename);

View File

@ -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<std::string> fileFilters;
/** @brief Force checking the files with "too many" configurations (--force). */
bool force;

View File

@ -112,3 +112,9 @@ bool matchglob(const std::string& pattern, const std::string& name)
n++;
}
}
bool matchglobs(const std::vector<std::string> &patterns, const std::string &name) {
return std::any_of(begin(patterns), end(patterns), [&name](const std::string &pattern) {
return matchglob(pattern, name);
});
}

View File

@ -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<std::string> &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