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
|