File: errorlogger.h

package info (click to toggle)
cppcheck 2.18.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,132 kB
  • sloc: cpp: 268,935; python: 20,890; ansic: 8,090; sh: 1,045; makefile: 1,008; xml: 1,005; cs: 291
file content (309 lines) | stat: -rw-r--r-- 10,169 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/* -*- C++ -*-
 * Cppcheck - A tool for static C/C++ code analysis
 * Copyright (C) 2007-2025 Cppcheck team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//---------------------------------------------------------------------------
#ifndef errorloggerH
#define errorloggerH
//---------------------------------------------------------------------------

#include "config.h"
#include "errortypes.h"

#include <cstddef>
#include <cstdint>
#include <list>
#include <set>
#include <string>
#include <vector>
#include <map>

class Token;
class TokenList;
enum class ReportType : std::uint8_t;
enum class Color : std::uint8_t;

namespace tinyxml2 {
    class XMLElement;
}

/// @addtogroup Core
/// @{

/**
 * Wrapper for error messages, provided by reportErr()
 */
class CPPCHECKLIB ErrorMessage {
public:
    /**
     * File name and line number.
     * Internally paths are stored with / separator. When getting the filename
     * it is by default converted to native separators.
     */
    class CPPCHECKLIB WARN_UNUSED FileLocation {
    public:
        FileLocation(const std::string &file, int line, unsigned int column);
        FileLocation(const std::string &file, std::string info, int line, unsigned int column);
        FileLocation(const Token* tok, const TokenList* tokenList);
        FileLocation(const Token* tok, std::string info, const TokenList* tokenList);

        /**
         * Return the filename.
         * @param convert If true convert path to native separators.
         * @return filename.
         */
        std::string getfile(bool convert = true) const;

        /**
         * Filename with the whole path (no --rp)
         * @param convert If true convert path to native separators.
         * @return filename.
         */
        std::string getOrigFile(bool convert = true) const;

        /**
         * Set the filename.
         * @param file Filename to set.
         */
        void setfile(std::string file);

        /**
         * @return the location as a string. Format: [file:line]
         */
        std::string stringify(bool addcolumn = false) const;

        unsigned int fileIndex;
        int line; // negative value means "no line"
        unsigned int column;

        const std::string& getinfo() const {
            return mInfo;
        }

    private:
        std::string mOrigFileName;
        std::string mFileName;
        std::string mInfo;
    };

    ErrorMessage(std::list<FileLocation> callStack,
                 std::string file1,
                 Severity severity,
                 const std::string &msg,
                 std::string id, Certainty certainty);
    ErrorMessage(std::list<FileLocation> callStack,
                 std::string file1,
                 Severity severity,
                 const std::string &msg,
                 std::string id,
                 const CWE &cwe,
                 Certainty certainty);
    ErrorMessage(const std::list<const Token*>& callstack,
                 const TokenList* list,
                 Severity severity,
                 std::string id,
                 const std::string& msg,
                 Certainty certainty);
    ErrorMessage(const std::list<const Token*>& callstack,
                 const TokenList* list,
                 Severity severity,
                 std::string id,
                 const std::string& msg,
                 const CWE &cwe,
                 Certainty certainty);
    ErrorMessage(ErrorPath errorPath,
                 const TokenList *tokenList,
                 Severity severity,
                 const char id[],
                 const std::string &msg,
                 const CWE &cwe,
                 Certainty certainty);
    ErrorMessage();
    explicit ErrorMessage(const tinyxml2::XMLElement * errmsg);

    /**
     * Format the error message in XML format
     */
    std::string toXML() const;

    static std::string getXMLHeader(std::string productName, int xmlVersion = 2);
    static std::string getXMLFooter(int xmlVersion);

    /**
     * Format the error message into a string.
     * @param verbose use verbose message
     * @param templateFormat Empty string to use default output format
     * or template to be used. E.g. "{file}:{line},{severity},{id},{message}"
     * @param templateLocation Format Empty string to use default output format
     * or template to be used. E.g. "{file}:{line},{info}"
     * @return formatted string
     */
    std::string toString(bool verbose,
                         const std::string &templateFormat,
                         const std::string &templateLocation) const;

    std::string serialize() const;
    void deserialize(const std::string &data);

    std::list<FileLocation> callStack;
    std::string id;

    /** For GUI rechecking; source file (not header) */
    std::string file0;

    Severity severity;
    CWE cwe;
    Certainty certainty;

    /** remark from REMARK comment */
    std::string remark;

    /** misra/autosar/certc classification/level */
    std::string classification;

    /** misra/autosar/certc guideline */
    std::string guideline;

    /** Warning hash */
    std::size_t hash;

    /** set short and verbose messages */
    void setmsg(const std::string &msg);

    /** Short message (single line short message) */
    const std::string &shortMessage() const {
        return mShortMessage;
    }

    /** Verbose message (may be the same as the short message) */
    // cppcheck-suppress unusedFunction - used by GUI only
    const std::string &verboseMessage() const {
        return mVerboseMessage;
    }

    /** Symbol names */
    const std::string &symbolNames() const {
        return mSymbolNames;
    }

    static ErrorMessage fromInternalError(const InternalError &internalError, const TokenList *tokenList, const std::string &filename, const std::string& msg = "");

private:
    static std::string fixInvalidChars(const std::string& raw);

    /** Short message */
    std::string mShortMessage;

    /** Verbose message */
    std::string mVerboseMessage;

    /** symbol names */
    std::string mSymbolNames;
};

/**
 * @brief This is an interface, which the class responsible of error logging
 * should implement.
 */
class CPPCHECKLIB ErrorLogger {
public:
    ErrorLogger() = default;
    virtual ~ErrorLogger() = default;

    /**
     * Information about progress is directed here.
     * Override this to receive the progress messages.
     *
     * @param outmsg Message to show e.g. "Checking main.cpp..."
     */
    virtual void reportOut(const std::string &outmsg, Color c) = 0;

    /**
     * Information about found errors and warnings is directed
     * here. Override this to receive the errormessages.
     *
     * @param msg Location and other information about the found error.
     */
    virtual void reportErr(const ErrorMessage &msg) = 0;

    /**
     * Information about file metrics reported by addons.
     *
     * @param metric The file metric to report, as an XML object.
     */
    virtual void reportMetric(const std::string &metric) = 0;

    /**
     * Report progress to client
     * @param filename main file that is checked
     * @param stage for example preprocess / tokenize / simplify / check
     * @param value progress value (0-100)
     */
    virtual void reportProgress(const std::string &filename, const char stage[], const std::size_t value) {
        (void)filename;
        (void)stage;
        (void)value;
    }

    static std::string callStackToString(const std::list<ErrorMessage::FileLocation> &callStack, bool addcolumn = false);

    /**
     * Convert XML-sensitive characters into XML entities
     * @param str The input string containing XML-sensitive characters
     * @return The output string containing XML entities
     */
    static std::string toxml(const std::string &str);

    static std::string plistHeader(const std::string &version, const std::vector<std::string> &files);
    static std::string plistData(const ErrorMessage &msg);
    static const char *plistFooter() {
        return " </array>\r\n"
               "</dict>\r\n"
               "</plist>";
    }

    static bool isCriticalErrorId(const std::string& id) {
        return mCriticalErrorIds.count(id) != 0;
    }

private:
    static const std::set<std::string> mCriticalErrorIds;
};

/** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */
std::string replaceStr(std::string s, const std::string &from, const std::string &to);

/** replaces the static parts of the location template **/
CPPCHECKLIB void substituteTemplateFormatStatic(std::string& templateFormat);

/** replaces the static parts of the location template **/
CPPCHECKLIB void substituteTemplateLocationStatic(std::string& templateLocation);

/** Get a classification string from the given guideline and reporttype */
CPPCHECKLIB std::string getClassification(const std::string &guideline, ReportType reportType);

/** Get a guidline string froM the given error id, reporttype, mapping and severity */
CPPCHECKLIB std::string getGuideline(const std::string &errId, ReportType reportType,
                                     const std::map<std::string, std::string> &guidelineMapping,
                                     Severity severity);

/** Get a map from cppcheck error ids to guidlines matching the given report type */
CPPCHECKLIB std::map<std::string, std::string> createGuidelineMapping(ReportType reportType);

/// @}
//---------------------------------------------------------------------------
#endif // errorloggerH