Implement support for passing multiple file filters (#3479)
This commit is contained in:
parent
b80e24231b
commit
5b52f4946a
|
@ -362,7 +362,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
|
|
||||||
// use a file filter
|
// use a file filter
|
||||||
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0)
|
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
|
// file list specified
|
||||||
else if (std::strncmp(argv[i], "--file-list=", 12) == 0)
|
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"
|
" Used when certain messages should be displayed but\n"
|
||||||
" should not cause a non-zero exitcode.\n"
|
" should not cause a non-zero exitcode.\n"
|
||||||
" --file-filter=<str> Analyze only those files matching the given filter str\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"
|
" Example: --file-filter=*bar.cpp analyzes only files\n"
|
||||||
" that end with bar.cpp.\n"
|
" that end with bar.cpp.\n"
|
||||||
" --file-list=<file> Specify the files to check in a text file. Add one\n"
|
" --file-list=<file> Specify the files to check in a text file. Add one\n"
|
||||||
|
|
|
@ -167,12 +167,12 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
#else
|
#else
|
||||||
const bool caseSensitive = true;
|
const bool caseSensitive = true;
|
||||||
#endif
|
#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
|
// filter only for the selected filenames from all project files
|
||||||
std::list<ImportProject::FileSettings> newList;
|
std::list<ImportProject::FileSettings> newList;
|
||||||
|
|
||||||
for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) {
|
for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) {
|
||||||
if (matchglob(mSettings->fileFilter, fsetting.filename)) {
|
if (matchglobs(mSettings->fileFilters, fsetting.filename)) {
|
||||||
newList.emplace_back(fsetting);
|
newList.emplace_back(fsetting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,10 +198,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
if (!ignored.empty())
|
if (!ignored.empty())
|
||||||
std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl;
|
std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl;
|
||||||
return false;
|
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;
|
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)
|
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;
|
newMap[i->first] = i->second;
|
||||||
}
|
}
|
||||||
mFiles = newMap;
|
mFiles = newMap;
|
||||||
|
|
|
@ -195,19 +195,20 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings
|
||||||
if (!mPath.empty() && !endsWith(mPath,'/'))
|
if (!mPath.empty() && !endsWith(mPath,'/'))
|
||||||
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")) {
|
if (endsWith(filename, ".json")) {
|
||||||
importCompileCommands(fin);
|
importCompileCommands(fin);
|
||||||
setRelativePaths(filename);
|
setRelativePaths(filename);
|
||||||
return ImportProject::Type::COMPILE_DB;
|
return ImportProject::Type::COMPILE_DB;
|
||||||
} else if (endsWith(filename, ".sln")) {
|
} else if (endsWith(filename, ".sln")) {
|
||||||
importSln(fin, mPath, fileFilter);
|
importSln(fin, mPath, fileFilters);
|
||||||
setRelativePaths(filename);
|
setRelativePaths(filename);
|
||||||
return ImportProject::Type::VS_SLN;
|
return ImportProject::Type::VS_SLN;
|
||||||
} else if (endsWith(filename, ".vcxproj")) {
|
} else if (endsWith(filename, ".vcxproj")) {
|
||||||
std::map<std::string, std::string, cppcheck::stricmp> variables;
|
std::map<std::string, std::string, cppcheck::stricmp> variables;
|
||||||
importVcxproj(filename, variables, emptyString, fileFilter);
|
importVcxproj(filename, variables, emptyString, fileFilters);
|
||||||
setRelativePaths(filename);
|
setRelativePaths(filename);
|
||||||
return ImportProject::Type::VS_VCXPROJ;
|
return ImportProject::Type::VS_VCXPROJ;
|
||||||
} else if (endsWith(filename, ".bpr")) {
|
} 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;
|
std::map<std::string,std::string,cppcheck::stricmp> variables;
|
||||||
variables["SolutionDir"] = path;
|
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));
|
std::string vcxproj(line.substr(pos1+1, pos-pos1+7));
|
||||||
if (!Path::isAbsolute(vcxproj))
|
if (!Path::isAbsolute(vcxproj))
|
||||||
vcxproj = path + 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));
|
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) {
|
for (const std::string &c : compileList) {
|
||||||
const std::string cfilename = Path::simplifyPath(Path::isAbsolute(c) ? c : Path::getPathFromFilename(filename) + c);
|
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;
|
continue;
|
||||||
|
|
||||||
for (const ProjectConfiguration &p : projectConfigurationList) {
|
for (const ProjectConfiguration &p : projectConfigurationList) {
|
||||||
|
|
|
@ -109,8 +109,8 @@ protected:
|
||||||
void importCompileCommands(std::istream &istr);
|
void importCompileCommands(std::istream &istr);
|
||||||
bool importCppcheckGuiProject(std::istream &istr, Settings *settings);
|
bool importCppcheckGuiProject(std::istream &istr, Settings *settings);
|
||||||
private:
|
private:
|
||||||
void importSln(std::istream &istr, const std::string &path, 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::string &fileFilter);
|
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 importBcb6Prj(const std::string &projectFilename);
|
||||||
|
|
||||||
void setRelativePaths(const std::string &filename);
|
void setRelativePaths(const std::string &filename);
|
||||||
|
|
|
@ -193,8 +193,8 @@ public:
|
||||||
Default value is 0. */
|
Default value is 0. */
|
||||||
int exitCode;
|
int exitCode;
|
||||||
|
|
||||||
/** @brief --file-filter for analyzing special files */
|
/** @brief List of --file-filter for analyzing special files */
|
||||||
std::string fileFilter;
|
std::vector<std::string> fileFilters;
|
||||||
|
|
||||||
/** @brief Force checking the files with "too many" configurations (--force). */
|
/** @brief Force checking the files with "too many" configurations (--force). */
|
||||||
bool force;
|
bool force;
|
||||||
|
|
|
@ -112,3 +112,9 @@ bool matchglob(const std::string& pattern, const std::string& name)
|
||||||
n++;
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -152,6 +152,8 @@ CPPCHECKLIB bool isValidGlobPattern(const std::string& pattern);
|
||||||
|
|
||||||
CPPCHECKLIB bool matchglob(const std::string& pattern, const std::string& name);
|
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)
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
// Use the nonneg macro when you want to assert that a variable/argument is not negative
|
// Use the nonneg macro when you want to assert that a variable/argument is not negative
|
||||||
|
|
Loading…
Reference in New Issue