Coverage Report

Created: 2023-09-25 06:15

/src/cppcheck/lib/suppressions.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Cppcheck - A tool for static C/C++ code analysis
3
 * Copyright (C) 2007-2023 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 suppressionsH
20
#define suppressionsH
21
//---------------------------------------------------------------------------
22
23
#include "config.h"
24
25
#include <cstddef>
26
#include <istream>
27
#include <list>
28
#include <string>
29
#include <utility>
30
#include <vector>
31
32
/// @addtogroup Core
33
/// @{
34
35
class Tokenizer;
36
class ErrorMessage;
37
class ErrorLogger;
38
enum class Certainty;
39
40
/** @brief class for handling suppressions */
41
class CPPCHECKLIB Suppressions {
42
public:
43
44
    struct CPPCHECKLIB ErrorMessage {
45
        std::size_t hash;
46
        std::string errorId;
47
        void setFileName(std::string s);
48
0
        const std::string &getFileName() const {
49
0
            return mFileName;
50
0
        }
51
        int lineNumber;
52
        Certainty certainty;
53
        std::string symbolNames;
54
55
        static Suppressions::ErrorMessage fromErrorMessage(const ::ErrorMessage &msg);
56
    private:
57
        std::string mFileName;
58
    };
59
60
    struct CPPCHECKLIB Suppression {
61
0
        Suppression() = default;
62
0
        Suppression(std::string id, std::string file, int line=NO_LINE) : errorId(std::move(id)), fileName(std::move(file)), lineNumber(line) {}
63
64
0
        bool operator<(const Suppression &other) const {
65
0
            if (errorId != other.errorId)
66
0
                return errorId < other.errorId;
67
0
            if (lineNumber < other.lineNumber)
68
0
                return true;
69
0
            if (fileName != other.fileName)
70
0
                return fileName < other.fileName;
71
0
            if (symbolName != other.symbolName)
72
0
                return symbolName < other.symbolName;
73
0
            if (hash != other.hash)
74
0
                return hash < other.hash;
75
0
            if (thisAndNextLine != other.thisAndNextLine)
76
0
                return thisAndNextLine;
77
0
            return false;
78
0
        }
79
80
        /**
81
         * Parse inline suppression in comment
82
         * @param comment the full comment text
83
         * @param errorMessage output parameter for error message (wrong suppression attribute)
84
         * @return true if it is a inline comment.
85
         */
86
        bool parseComment(std::string comment, std::string *errorMessage);
87
88
        bool isSuppressed(const ErrorMessage &errmsg) const;
89
90
        bool isMatch(const ErrorMessage &errmsg);
91
92
        std::string getText() const;
93
94
0
        bool isLocal() const {
95
0
            return !fileName.empty() && fileName.find_first_of("?*") == std::string::npos;
96
0
        }
97
98
0
        bool isSameParameters(const Suppression &other) const {
99
0
            return errorId == other.errorId &&
100
0
                   fileName == other.fileName &&
101
0
                   lineNumber == other.lineNumber &&
102
0
                   symbolName == other.symbolName &&
103
0
                   hash == other.hash &&
104
0
                   thisAndNextLine == other.thisAndNextLine;
105
0
        }
106
107
        std::string errorId;
108
        std::string fileName;
109
        int lineNumber = NO_LINE;
110
        std::string symbolName;
111
        std::size_t hash{};
112
        bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something
113
        bool matched{};
114
        bool checked{}; // for inline suppressions, checked or not
115
116
        enum { NO_LINE = -1 };
117
    };
118
119
    /**
120
     * @brief Don't show errors listed in the file.
121
     * @param istr Open file stream where errors can be read.
122
     * @return error message. empty upon success
123
     */
124
    std::string parseFile(std::istream &istr);
125
126
    /**
127
     * @brief Don't show errors listed in the file.
128
     * @param filename file name
129
     * @return error message. empty upon success
130
     */
131
    std::string parseXmlFile(const char *filename);
132
133
    /**
134
     * Parse multi inline suppression in comment
135
     * @param comment the full comment text
136
     * @param errorMessage output parameter for error message (wrong suppression attribute)
137
     * @return empty vector if something wrong.
138
     */
139
    static std::vector<Suppression> parseMultiSuppressComment(const std::string &comment, std::string *errorMessage);
140
141
    /**
142
     * @brief Don't show the given error.
143
     * @param line Description of error to suppress (in id:file:line format).
144
     * @return error message. empty upon success
145
     */
146
    std::string addSuppressionLine(const std::string &line);
147
148
    /**
149
     * @brief Don't show this error. File and/or line are optional. In which case
150
     * the errorId alone is used for filtering.
151
     * @param suppression suppression details
152
     * @return error message. empty upon success
153
     */
154
    std::string addSuppression(Suppression suppression);
155
156
    /**
157
     * @brief Combine list of suppressions into the current suppressions.
158
     * @param suppressions list of suppression details
159
     * @return error message. empty upon success
160
     */
161
    std::string addSuppressions(std::list<Suppression> suppressions);
162
163
    /**
164
     * @brief Returns true if this message should not be shown to the user.
165
     * @param errmsg error message
166
     * @param global use global suppressions
167
     * @return true if this error is suppressed.
168
     */
169
    bool isSuppressed(const ErrorMessage &errmsg, bool global = true);
170
171
    /**
172
     * @brief Returns true if this message should not be shown to the user.
173
     * @param errmsg error message
174
     * @return true if this error is suppressed.
175
     */
176
    bool isSuppressed(const ::ErrorMessage &errmsg);
177
178
    /**
179
     * @brief Create an xml dump of suppressions
180
     * @param out stream to write XML to
181
     */
182
    void dump(std::ostream &out) const;
183
184
    /**
185
     * @brief Returns list of unmatched local (per-file) suppressions.
186
     * @return list of unmatched suppressions
187
     */
188
    std::list<Suppression> getUnmatchedLocalSuppressions(const std::string &file, const bool unusedFunctionChecking) const;
189
190
    /**
191
     * @brief Returns list of unmatched global (glob pattern) suppressions.
192
     * @return list of unmatched suppressions
193
     */
194
    std::list<Suppression> getUnmatchedGlobalSuppressions(const bool unusedFunctionChecking) const;
195
196
    /**
197
     * @brief Returns list of all suppressions.
198
     * @return list of suppressions
199
     */
200
    const std::list<Suppression> &getSuppressions() const;
201
202
    /**
203
     * @brief Marks Inline Suppressions as checked if source line is in the token stream
204
     */
205
    void markUnmatchedInlineSuppressionsAsChecked(const Tokenizer &tokenizer);
206
207
    /**
208
     * Report unmatched suppressions
209
     * @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
210
     * @return true is returned if errors are reported
211
     */
212
    static bool reportUnmatchedSuppressions(const std::list<Suppressions::Suppression> &unmatched, ErrorLogger &errorLogger);
213
214
private:
215
    /** @brief List of error which the user doesn't want to see. */
216
    std::list<Suppression> mSuppressions;
217
};
218
219
/// @}
220
//---------------------------------------------------------------------------
221
#endif // suppressionsH