Skip to content

Commit 6401271

Browse files
committed
Add CLI support for ignoring paths.
Add support for giving list of ignored paths from CLI. This way user can define paths one doesn't want to check (like generated code). This first simple implementation only does exact matching, no support for wildcards etc. And matching is always agains dir names. If the filtered dir name is part of the checked filename then the file is ignored. Ticket danmar#1690 (Ability to exclude files and directories from checks)
1 parent 8298c07 commit 6401271

9 files changed

Lines changed: 480 additions & 78 deletions

File tree

cli/cli.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ SOURCES += main.cpp \
1717
filelister.cpp \
1818
filelister_unix.cpp \
1919
filelister_win32.cpp \
20+
pathmatch.cpp \
2021
threadexecutor.cpp
22+
2123
HEADERS += cppcheckexecutor.h \
2224
cmdlineparser.h \
2325
filelister.h \
2426
filelister_unix.h \
2527
filelister_win32.h \
28+
pathmatch.h \
2629
threadexecutor.h
2730

2831
CONFIG(release, debug|release) {

cli/cmdlineparser.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,41 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
327327
AddFilesToList(12 + argv[i], _pathnames);
328328
}
329329

330+
// Ignored paths
331+
else if (strncmp(argv[i], "-i", 2) == 0)
332+
{
333+
std::string path;
334+
335+
// "-i path/"
336+
if (strcmp(argv[i], "-i") == 0)
337+
{
338+
++i;
339+
if (i >= argc)
340+
{
341+
PrintMessage("cppcheck: argument to '-i' is missing");
342+
return false;
343+
}
344+
path = argv[i];
345+
}
346+
347+
// "-Ipath/"
348+
else
349+
{
350+
path = 2 + argv[i];
351+
}
352+
353+
if (!path.empty())
354+
{
355+
path = Path::fromNativeSeparators(path);
356+
357+
// If path doesn't end with / or \, add it
358+
if (path[path.length()-1] != '/')
359+
path += '/';
360+
361+
_ignoredPaths.push_back(path);
362+
}
363+
}
364+
330365
// Report progress
331366
else if (strcmp(argv[i], "--report-progress") == 0)
332367
{
@@ -589,6 +624,9 @@ void CmdLineParser::PrintHelp()
589624
" -I [dir] Give include path. Give several -I parameters to give\n"
590625
" several paths. First given path is checked first. If\n"
591626
" paths are relative to source files, this is not needed\n"
627+
" -i [dir] Give path to ignore. Give several -i parameters to ignore\n"
628+
" several paths. If any part of the checked path matches the\n"
629+
" given dir the path is ignored and not checked.\n"
592630
" --inline-suppr Enable inline suppressions. Use them by placing one or\n"
593631
" more comments, like: // cppcheck-suppress warningId\n"
594632
" on the lines before the warning to suppress.\n"

cli/cmdlineparser.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ class CmdLineParser
9292
return _exitAfterPrint;
9393
}
9494

95+
/**
96+
* Return a list of paths user wants to ignore.
97+
*/
98+
std::vector<std::string> GetIgnoredPaths() const
99+
{
100+
return _ignoredPaths;
101+
}
102+
95103
protected:
96104

97105
/**
@@ -111,6 +119,7 @@ class CmdLineParser
111119
bool _showErrorMessages;
112120
bool _exitAfterPrint;
113121
std::vector<std::string> _pathnames;
122+
std::vector<std::string> _ignoredPaths;
114123
};
115124

116125
/// @}

cli/cppcheckexecutor.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "cmdlineparser.h"
2626
#include "filelister.h"
2727
#include "path.h"
28+
#include "pathmatch.h"
2829

2930
CppCheckExecutor::CppCheckExecutor()
3031
{
@@ -87,20 +88,40 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
8788
std::vector<std::string>::const_iterator iter;
8889
for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
8990
getFileLister()->recursiveAddFiles(filenames, Path::toNativeSeparators(iter->c_str()));
90-
91-
for (iter = filenames.begin(); iter != filenames.end(); ++iter)
92-
cppcheck->addFile(*iter);
9391
}
9492

95-
if (filenames.empty())
93+
if (!filenames.empty())
94+
{
95+
PathMatch matcher(parser.GetIgnoredPaths());
96+
// Ignore files
97+
std::vector<std::string>::iterator iter = filenames.end();
98+
do
99+
{
100+
--iter;
101+
if (matcher.Match(*iter))
102+
filenames.erase(iter);
103+
}
104+
while (iter != filenames.begin());
105+
}
106+
else
96107
{
97108
std::cout << "cppcheck: error: could not find or open any of the paths given." << std::endl;
98109
return false;
99110
}
100-
else
111+
112+
if (!filenames.empty())
101113
{
114+
std::vector<std::string>::iterator iter;
115+
for (iter = filenames.begin(); iter != filenames.end(); ++iter)
116+
cppcheck->addFile(*iter);
117+
102118
return true;
103119
}
120+
else
121+
{
122+
std::cout << "cppcheck: error: no files to check - all paths ignored." << std::endl;
123+
return false;
124+
}
104125
}
105126

106127
int CppCheckExecutor::check(int argc, const char* const argv[])

cli/pathmatch.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "pathmatch.h"
20+
21+
PathMatch::PathMatch(const std::vector<std::string> &masks)
22+
: _masks(masks)
23+
{
24+
}
25+
26+
bool PathMatch::Match(const std::string &path)
27+
{
28+
std::vector<std::string>::const_iterator iterMask;
29+
for (iterMask = _masks.begin(); iterMask != _masks.end(); ++iterMask)
30+
{
31+
std::string findpath(path);
32+
if (findpath[findpath.length() - 1] != '/')
33+
findpath = RemoveFilename(findpath);
34+
35+
if (findpath.find(*iterMask) != std::string::npos)
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
std::string PathMatch::RemoveFilename(const std::string &path)
42+
{
43+
const size_t ind = path.find_last_of('/');
44+
return path.substr(0, ind + 1);
45+
}

cli/pathmatch.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef PATHMATCH_H
20+
#define PATHMATCH_H
21+
22+
#include <string>
23+
#include <vector>
24+
25+
/// @addtogroup CLI
26+
/// @{
27+
28+
/**
29+
* @brief Simple path matching for ignoring paths in CLI.
30+
*/
31+
class PathMatch
32+
{
33+
public:
34+
35+
/**
36+
* The constructor.
37+
* @param masks List of masks.
38+
*/
39+
PathMatch(const std::vector<std::string> &masks);
40+
41+
/**
42+
* @brief Match path against list of masks.
43+
* @param path Path to match.
44+
* @return true if any of the masks match the path, false otherwise.
45+
*/
46+
bool Match(const std::string &path);
47+
48+
protected:
49+
50+
/**
51+
* @brief Remove filename part from the path.
52+
* @param path Path to edit.
53+
* @return path without filename part.
54+
*/
55+
std::string RemoveFilename(const std::string &path);
56+
57+
private:
58+
std::vector<std::string> _masks;
59+
};
60+
61+
/// @}
62+
63+
#endif // PATHMATCH_H

0 commit comments

Comments
 (0)