55 #include <unordered_set>
63 static bool addFilesToList(
const std::string& fileList, std::vector<std::string>& pathNames)
67 if (fileList ==
"-") {
70 infile.open(fileList);
71 if (!infile.is_open())
75 if (files && *files) {
78 while (std::getline(*files, fileName)) {
80 if (!fileName.empty()) {
81 pathNames.emplace_back(std::move(fileName));
90 std::ifstream files(fileList);
94 while (std::getline(files, pathName)) {
95 if (!pathName.empty()) {
103 pathNames.emplace_back(std::move(pathName));
111 static bool addPathsToSet(
const std::string& fileName, std::set<std::string>& set)
113 std::list<std::string> templist;
116 set.insert(templist.cbegin(), templist.cend());
125 std::cout << outmsg << std::endl;
133 void reportProgress(
const std::string & ,
const char [],
const std::size_t )
override
140 , mSettings(settings)
141 , mSuppressions(suppressions)
178 std::cout <<
"(information) Couldn't find path given by -I '" << path <<
'\'' << std::endl;
186 const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](
const std::string& i) {
187 return Path::isHeader2(i);
194 const std::vector<std::string>& pathnamesRef =
getPathNames();
198 assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty()));
200 if (!fileSettingsRef.empty()) {
203 std::list<FileSettings> fileSettings;
206 std::copy_if(fileSettingsRef.cbegin(), fileSettingsRef.cend(), std::back_inserter(fileSettings), [&](
const FileSettings &fs) {
207 return matchglobs(mSettings.fileFilters, fs.filename());
209 if (fileSettings.empty()) {
215 fileSettings = fileSettingsRef;
221 std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(
mFileSettings), [&](
const FileSettings &fs) {
222 return !mSettings.library.markupFile(fs.filename()) || !mSettings.library.processMarkupAfterCode(fs.filename());
225 std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(
mFileSettings), [&](
const FileSettings &fs) {
226 return mSettings.library.markupFile(fs.filename()) && mSettings.library.processMarkupAfterCode(fs.filename());
235 if (!pathnamesRef.empty()) {
236 std::list<FileWithDetails> filesResolved;
240 const bool caseSensitive =
false;
242 const bool caseSensitive =
true;
246 const PathMatch matcher(ignored, caseSensitive);
247 for (
const std::string &pathname : pathnamesRef) {
255 if (filesResolved.empty()) {
258 if (!ignored.empty())
265 auto it = filesResolved.begin();
266 while (it != filesResolved.end()) {
267 const std::string& name = it->path();
269 filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](
const FileWithDetails& entry) {
270 return entry.path() == name;
271 }), filesResolved.end());
276 std::list<FileWithDetails> files;
278 std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](
const FileWithDetails& entry) {
279 return matchglobs(mSettings.fileFilters, entry.path());
287 files = std::move(filesResolved);
292 return !mSettings.library.markupFile(entry.path()) || !mSettings.library.processMarkupAfterCode(entry.path());
296 return mSettings.library.markupFile(entry.path()) && mSettings.library.processMarkupAfterCode(entry.path());
323 for (
int i = 1; i < argc; i++) {
325 if (std::strcmp(argv[i],
"--doc") == 0) {
326 std::ostringstream doc;
329 const std::string& name(it->name());
330 const std::string info(it->classInfo());
331 if (!name.empty() && !info.empty())
332 doc <<
"## " << name <<
" ##\n"
341 if (std::strcmp(argv[i],
"--errorlist") == 0) {
345 XMLErrorMessagesLogger xmlLogger;
354 if (std::strcmp(argv[i],
"-h") == 0 || std::strcmp(argv[i],
"--help") == 0) {
359 if (std::strcmp(argv[i],
"--version") == 0) {
369 bool maxconfigs =
false;
373 bool executorAuto =
true;
374 int8_t logMissingInclude{0};
376 for (
int i = 1; i < argc; i++) {
377 if (argv[i][0] ==
'-') {
379 if (std::strncmp(argv[i],
"-D", 2) == 0) {
383 if (std::strcmp(argv[i],
"-D") == 0) {
385 if (i >= argc || argv[i][0] ==
'-') {
394 define = 2 + argv[i];
398 if (define.find(
'=') == std::string::npos)
409 else if (std::strcmp(argv[i],
"-E") == 0) {
415 else if (std::strncmp(argv[i],
"-I", 2) == 0) {
419 if (std::strcmp(argv[i],
"-I") == 0) {
421 if (i >= argc || argv[i][0] ==
'-') {
443 else if (std::strncmp(argv[i],
"-U", 2) == 0) {
447 if (std::strcmp(argv[i],
"-U") == 0) {
449 if (i >= argc || argv[i][0] ==
'-') {
464 else if (std::strncmp(argv[i],
"--addon=", 8) == 0)
467 else if (std::strncmp(argv[i],
"--addon-python=", 15) == 0)
471 else if (std::strcmp(argv[i],
"--check-config") == 0)
475 else if (std::strncmp(argv[i],
"--check-level=", 14) == 0) {
477 const std::string level_s(argv[i] + 14);
478 if (level_s ==
"normal")
480 else if (level_s ==
"exhaustive")
491 else if (std::strcmp(argv[i],
"--check-library") == 0) {
495 else if (std::strncmp(argv[i],
"--check-version=", 16) == 0) {
498 const std::string actualVersion =
getVersion();
499 const std::string wantedVersion = argv[i] + 16;
500 if (actualVersion != wantedVersion) {
506 else if (std::strncmp(argv[i],
"--checkers-report=", 18) == 0)
509 else if (std::strncmp(argv[i],
"--checks-max-time=", 18) == 0) {
514 else if (std::strcmp(argv[i],
"--clang") == 0) {
518 else if (std::strncmp(argv[i],
"--clang=", 8) == 0) {
523 else if (std::strncmp(argv[i],
"--config-exclude=",17) ==0) {
527 else if (std::strncmp(argv[i],
"--config-excludes-file=", 23) == 0) {
529 const std::string cfgExcludesFile(23 + argv[i]);
531 mLogger.
printError(
"unable to open config excludes file at '" + cfgExcludesFile +
"'");
536 else if (std::strncmp(argv[i],
"--cppcheck-build-dir=", 21) == 0) {
548 else if (std::strcmp(argv[i],
"--debug") == 0 ||
549 std::strcmp(argv[i],
"--debug-normal") == 0)
553 else if (std::strcmp(argv[i],
"--debug-simplified") == 0)
557 else if (std::strcmp(argv[i],
"--debug-template") == 0)
561 else if (std::strcmp(argv[i],
"--debug-warnings") == 0)
564 else if (std::strncmp(argv[i],
"--disable=", 10) == 0) {
566 if (!errmsg.empty()) {
570 if (std::string(argv[i] + 10).find(
"missingInclude") != std::string::npos) {
576 else if (std::strcmp(argv[i],
"--dump") == 0)
579 else if (std::strncmp(argv[i],
"--enable=", 9) == 0) {
580 const std::string enable_arg = argv[i] + 9;
582 if (!errmsg.empty()) {
587 if (enable_arg.find(
"style") != std::string::npos) {
592 if (enable_arg.find(
"information") != std::string::npos && logMissingInclude == 0) {
596 if (enable_arg.find(
"missingInclude") != std::string::npos) {
602 else if (std::strncmp(argv[i],
"--error-exitcode=", 17) == 0) {
608 else if (std::strcmp(argv[i],
"--exception-handling") == 0) {
609 #if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
612 mLogger.
printError(
"Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled.");
618 else if (std::strncmp(argv[i],
"--exception-handling=", 21) == 0) {
619 #if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
620 const std::string exceptionOutfilename = argv[i] + 21;
621 if (exceptionOutfilename !=
"stderr" && exceptionOutfilename !=
"stdout") {
628 mLogger.
printError(
"Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled.");
633 else if (std::strncmp(argv[i],
"--executor=", 11) == 0) {
634 const std::string type = 11 + argv[i];
635 if (type ==
"auto") {
639 else if (type ==
"thread") {
640 #if defined(HAS_THREADING_MODEL_THREAD)
641 executorAuto =
false;
644 mLogger.
printError(
"executor type 'thread' cannot be used as Cppcheck has not been built with a respective threading model.");
648 else if (type ==
"process") {
649 #if defined(HAS_THREADING_MODEL_FORK)
650 executorAuto =
false;
653 mLogger.
printError(
"executor type 'process' cannot be used as Cppcheck has not been built with a respective threading model.");
664 else if (std::strncmp(argv[i],
"--exitcode-suppressions=", 24) == 0) {
666 std::string filename = 24 + argv[i];
668 std::ifstream f(filename);
674 if (!errmsg.empty()) {
681 else if (std::strncmp(argv[i],
"--file-filter=", 14) == 0) {
682 const char *filter = argv[i] + 14;
683 if (std::strcmp(filter,
"-") == 0) {
694 else if (std::strncmp(argv[i],
"--file-list=", 12) == 0) {
696 const std::string fileList = argv[i] + 12;
704 else if (std::strcmp(argv[i],
"-f") == 0 || std::strcmp(argv[i],
"--force") == 0)
707 else if (std::strcmp(argv[i],
"--fsigned-char") == 0)
710 else if (std::strcmp(argv[i],
"--funsigned-char") == 0)
714 else if (std::strncmp(argv[i],
"-i", 2) == 0) {
718 if (std::strcmp(argv[i],
"-i") == 0) {
720 if (i >= argc || argv[i][0] ==
'-') {
746 else if (std::strncmp(argv[i],
"--include=", 10) == 0) {
750 else if (std::strncmp(argv[i],
"--includes-file=", 16) == 0) {
752 const std::string includesFile(16 + argv[i]);
760 else if (std::strcmp(argv[i],
"--inconclusive") == 0)
764 else if (std::strcmp(argv[i],
"--inline-suppr") == 0)
768 else if (std::strncmp(argv[i],
"-j", 2) == 0) {
769 std::string numberString;
772 if (std::strcmp(argv[i],
"-j") == 0) {
774 if (i >= argc || argv[i][0] ==
'-') {
779 numberString = argv[i];
784 numberString = argv[i]+2;
788 if (!
strToInt(numberString, tmp, &err)) {
808 else if (std::strncmp(argv[i],
"-l", 2) == 0) {
809 #ifdef HAS_THREADING_MODEL_FORK
810 std::string numberString;
813 if (std::strcmp(argv[i],
"-l") == 0) {
815 if (i >= argc || argv[i][0] ==
'-') {
820 numberString = argv[i];
825 numberString = argv[i]+2;
829 if (!
strToInt(numberString, tmp, &err)) {
835 mLogger.
printError(
"Option -l cannot be used as Cppcheck has not been built with fork threading model.");
841 else if (std::strncmp(argv[i],
"--language=", 11) == 0 || std::strcmp(argv[i],
"-x") == 0) {
847 if (i >= argc || argv[i][0] ==
'-') {
856 else if (str ==
"c++")
865 else if (std::strncmp(argv[i],
"--library=", 10) == 0) {
870 else if (std::strncmp(argv[i],
"--max-configs=", 14) == 0) {
885 else if (std::strncmp(argv[i],
"--max-ctu-depth=", 16) == 0) {
891 else if (std::strncmp(argv[i],
"--output-file=", 14) == 0)
896 else if (std::strncmp(argv[i],
"--performance-valueflow-max-time=", 33) == 0) {
901 else if (std::strncmp(argv[i],
"--performance-valueflow-max-if-count=", 37) == 0) {
907 else if (std::strncmp(argv[i],
"--platform=", 11) == 0) {
908 const std::string platform(11+argv[i]);
911 const std::vector<std::string> paths = {argv[0]};
920 if (platform ==
"unix32-unsigned")
922 else if (platform ==
"unix64-unsigned")
927 else if (std::strncmp(argv[i],
"--plist-output=", 15) == 0) {
934 std::string message(
"plist folder does not exist: '");
935 message += plistOutput;
947 const std::set<std::string> valid{
961 if (std::strcmp(argv[i],
"--premium=safety") == 0)
965 const std::string p(argv[i] + 10);
966 if (!valid.count(p) && !
startsWith(p,
"cert-c-int-precision=")) {
971 if (p ==
"misra-c-2012" || p ==
"misra-c-2023")
982 else if (std::strncmp(argv[i],
"--project=", 10) == 0) {
990 std::string projectFile = argv[i]+10;
998 std::copy(excludedPaths.cbegin(), excludedPaths.cend(), std::back_inserter(
mIgnoredPaths));
1003 if (!platform.empty()) {
1005 const std::vector<std::string> paths = {projectFile, argv[0]};
1013 if (!projectFileGui.empty()) {
1015 projectFile = projectFileGui;
1025 mLogger.
printError(
"failed to open project '" + projectFile +
"'. The file does not exist.");
1029 mLogger.
printError(
"failed to load project '" + projectFile +
"'. The format is unknown.");
1033 mLogger.
printError(
"failed to load project '" + projectFile +
"'. An error occurred.");
1039 else if (std::strncmp(argv[i],
"--project-configuration=", 24) == 0) {
1046 else if (std::strcmp(argv[i],
"-q") == 0 || std::strcmp(argv[i],
"--quiet") == 0)
1050 else if (std::strcmp(argv[i],
"-rp") == 0 || std::strcmp(argv[i],
"--relative-paths") == 0)
1052 else if (std::strncmp(argv[i],
"-rp=", 4) == 0 || std::strncmp(argv[i],
"--relative-paths=", 17) == 0) {
1054 if (argv[i][argv[i][3]==
'='?4:17] != 0) {
1055 std::string paths = argv[i]+(argv[i][3]==
'='?4:17);
1057 const std::string::size_type pos = paths.find(
';');
1058 if (pos == std::string::npos) {
1063 paths.erase(0, pos + 1);
1066 mLogger.
printError(
"no paths specified for the '" + std::string(argv[i]) +
"' option.");
1072 else if (std::strcmp(argv[i],
"--report-progress") == 0) {
1076 else if (std::strncmp(argv[i],
"--report-progress=", 18) == 0) {
1084 else if (std::strncmp(argv[i],
"--rule=", 7) == 0) {
1086 Settings::Rule rule;
1087 rule.pattern = 7 + argv[i];
1089 if (rule.pattern.empty()) {
1094 mSettings.rules.emplace_back(std::move(rule));
1096 mLogger.
printError(
"Option --rule cannot be used as Cppcheck has not been built with rules support.");
1102 else if (std::strncmp(argv[i],
"--rule-file=", 12) == 0) {
1106 const std::string ruleFile = argv[i] + 12;
1107 tinyxml2::XMLDocument doc;
1108 const tinyxml2::XMLError err = doc.LoadFile(ruleFile.c_str());
1109 if (err == tinyxml2::XML_SUCCESS) {
1110 const tinyxml2::XMLElement *node = doc.FirstChildElement();
1112 if (node && strcmp(node->Value(),
"rules") == 0)
1113 node = node->FirstChildElement(
"rule");
1114 for (; node && strcmp(node->Value(),
"rule") == 0; node = node->NextSiblingElement()) {
1115 Settings::Rule rule;
1117 for (
const tinyxml2::XMLElement *subnode = node->FirstChildElement(); subnode; subnode = subnode->NextSiblingElement()) {
1118 const char *
const subtext = subnode->GetText();
1119 if (std::strcmp(subnode->Name(),
"tokenlist") == 0) {
1122 else if (std::strcmp(subnode->Name(),
"pattern") == 0) {
1125 else if (std::strcmp(subnode->Name(),
"message") == 0) {
1126 for (
const tinyxml2::XMLElement *msgnode = subnode->FirstChildElement(); msgnode; msgnode = msgnode->NextSiblingElement()) {
1127 const char *
const msgtext = msgnode->GetText();
1128 if (std::strcmp(msgnode->Name(),
"severity") == 0) {
1131 else if (std::strcmp(msgnode->Name(),
"id") == 0) {
1134 else if (std::strcmp(msgnode->Name(),
"summary") == 0) {
1138 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - unknown element '" + msgnode->Name() +
"' encountered in 'message'.");
1144 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - unknown element '" + subnode->Name() +
"' encountered in 'rule'.");
1149 if (rule.pattern.empty()) {
1150 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - a rule is lacking a pattern.");
1154 if (rule.id.empty()) {
1155 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - a rule is lacking an id.");
1159 if (rule.tokenlist.empty()) {
1160 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - a rule is lacking a tokenlist.");
1164 if (rule.tokenlist !=
"normal" && rule.tokenlist !=
"define" && rule.tokenlist !=
"raw") {
1165 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - a rule is using the unsupported tokenlist '" + rule.tokenlist +
"'.");
1170 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' - a rule has an invalid severity.");
1174 mSettings.rules.emplace_back(std::move(rule));
1177 mLogger.
printError(
"unable to load rule-file '" + ruleFile +
"' (" + tinyxml2::XMLDocument::ErrorIDToName(err) +
").");
1181 mLogger.
printError(
"Option --rule-file cannot be used as Cppcheck has not been built with rules support.");
1187 else if (std::strcmp(argv[i],
"--safety") == 0)
1191 else if (std::strncmp(argv[i],
"--showtime=", 11) == 0) {
1192 const std::string showtimeMode = argv[i] + 11;
1193 if (showtimeMode ==
"file")
1195 else if (showtimeMode ==
"file-total")
1197 else if (showtimeMode ==
"summary")
1199 else if (showtimeMode ==
"top5") {
1201 mLogger.
printMessage(
"--showtime=top5 is deprecated and will be removed in Cppcheck 2.14. Please use --showtime=top5_file or --showtime=top5_summary instead.");
1203 else if (showtimeMode ==
"top5_file")
1205 else if (showtimeMode ==
"top5_summary")
1207 else if (showtimeMode ==
"none")
1209 else if (showtimeMode.empty()) {
1214 mLogger.
printError(
"unrecognized --showtime mode: '" + showtimeMode +
"'. Supported modes: file, file-total, summary, top5, top5_file, top5_summary.");
1220 else if (std::strncmp(argv[i],
"--std=", 6) == 0) {
1221 const std::string std = argv[i] + 6;
1223 if (std::strncmp(std.c_str(),
"c++", 3) == 0) {
1226 else if (std::strncmp(std.c_str(),
"c", 1) == 0) {
1235 else if (std::strncmp(argv[i],
"--suppress=", 11) == 0) {
1236 const std::string suppression = argv[i]+11;
1238 if (!errmsg.empty()) {
1245 else if (std::strncmp(argv[i],
"--suppressions-list=", 20) == 0) {
1246 std::string filename = argv[i]+20;
1247 std::ifstream f(filename);
1249 std::string message(
"couldn't open the file: \"");
1250 message += filename;
1252 if (std::count(filename.cbegin(), filename.cend(),
',') > 0 ||
1253 std::count(filename.cbegin(), filename.cend(),
'.') > 1) {
1257 message +=
"\nIf you want to pass two files, you can do it e.g. like this:";
1258 message +=
"\n cppcheck --suppressions-list=a.txt --suppressions-list=b.txt file.cpp";
1265 if (!errmsg.empty()) {
1271 else if (std::strncmp(argv[i],
"--suppress-xml=", 15) == 0) {
1272 const char * filename = argv[i] + 15;
1274 if (!errmsg.empty()) {
1281 else if (std::strncmp(argv[i],
"--template=", 11) == 0) {
1286 mSettings.
templateFormat =
"{bold}{file}:{line}:{column}: {magenta}warning:{default} {message} [{id}]{reset}\\n{code}";
1290 mSettings.
templateFormat =
"{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]";
1299 mSettings.
templateFormat =
"{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}";
1303 mSettings.
templateFormat =
"{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]";
1309 else if (std::strncmp(argv[i],
"--template-location=", 20) == 0) {
1315 else if (std::strncmp(argv[i],
"--template-max-time=", 20) == 0) {
1320 else if (std::strncmp(argv[i],
"--typedef-max-time=", 19) == 0) {
1325 else if (std::strncmp(argv[i],
"--valueflow-max-iterations=", 27) == 0) {
1330 else if (std::strcmp(argv[i],
"-v") == 0 || std::strcmp(argv[i],
"--verbose") == 0)
1334 else if (std::strcmp(argv[i],
"--xml") == 0)
1338 else if (std::strncmp(argv[i],
"--xml-version=", 14) == 0) {
1354 std::string message(
"unrecognized command line option: \"");
1367 if (logMissingInclude == 1)
1368 mLogger.
printMessage(
"'--enable=information' will no longer implicitly enable 'missingInclude' starting with 2.16. Please enable it explicitly if you require it.");
1379 mSettings.
templateFormat =
"{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}";
1398 mLogger.
printMessage(
"unusedFunction check can't be used with '-j' option. Disabling unusedFunction check.");
1402 mLogger.
printError(
"--project cannot be used in conjunction with source files.");
1436 "https://cppcheck.sourceforge.io/manual.pdf" :
1437 "https://files.cppchecksolutions.com/manual.pdf");
1439 std::ostringstream oss;
1440 oss <<
"Cppcheck - A tool for static C/C++ code analysis\n"
1443 " cppcheck [OPTIONS] [files or paths]\n"
1445 "If a directory is given instead of a filename, *.cpp, *.cxx, *.cc, *.c++, *.c, *.ipp,\n"
1446 "*.ixx, *.tpp, and *.txx files are checked recursively from the given directory.\n\n"
1448 " --addon=<addon>\n"
1449 " Execute addon. i.e. --addon=misra. If options must be\n"
1450 " provided a json configuration is needed.\n"
1451 " --addon-python=<python interpreter>\n"
1452 " You can specify the python interpreter either in the\n"
1453 " addon json files or through this command line option.\n"
1454 " If not present, Cppcheck will try \"python3\" first and\n"
1455 " then \"python\".\n"
1456 " --cppcheck-build-dir=<dir>\n"
1457 " Cppcheck work folder. Advantages:\n"
1458 " * whole program analysis\n"
1459 " * faster analysis; Cppcheck will reuse the results if\n"
1460 " the hash for a file is unchanged.\n"
1461 " * some useful debug information, i.e. commands used to\n"
1462 " execute clang/clang-tidy/addons.\n"
1463 " --check-config Check cppcheck configuration. The normal code\n"
1464 " analysis is disabled by this flag.\n"
1465 " --check-level=<level>\n"
1466 " Configure how much checking you want:\n"
1467 " * normal: Cppcheck uses some compromises in the checking so\n"
1468 " the checking will finish in reasonable time.\n"
1469 " * exhaustive: deeper analysis that you choose when you can\n"
1471 " The default choice is 'normal'.\n"
1472 " --check-library Show information messages when library files have\n"
1473 " incomplete info.\n"
1474 " --checkers-report=<file>\n"
1475 " Write a report of all the active checkers to the given file.\n"
1476 " --clang=<path> Experimental: Use Clang parser instead of the builtin Cppcheck\n"
1477 " parser. Takes the executable as optional parameter and\n"
1478 " defaults to `clang`. Cppcheck will run the given Clang\n"
1479 " executable, import the Clang AST and convert it into\n"
1480 " Cppcheck data. After that the normal Cppcheck analysis is\n"
1481 " used. You must have the executable in PATH if no path is\n"
1483 " --config-exclude=<dir>\n"
1484 " Path (prefix) to be excluded from configuration\n"
1485 " checking. Preprocessor configurations defined in\n"
1486 " headers (but not sources) matching the prefix will not\n"
1487 " be considered for evaluation.\n"
1488 " --config-excludes-file=<file>\n"
1489 " A file that contains a list of config-excludes\n"
1490 " --disable=<id> Disable individual checks.\n"
1491 " Please refer to the documentation of --enable=<id>\n"
1492 " for further details.\n"
1493 " --dump Dump xml data for each translation unit. The dump\n"
1494 " files have the extension .dump and contain ast,\n"
1495 " tokenlist, symboldatabase, valueflow.\n"
1496 " -D<ID> Define preprocessor symbol. Unless --max-configs or\n"
1497 " --force is used, Cppcheck will only check the given\n"
1498 " configuration when -D is used.\n"
1499 " Example: '-DDEBUG=1 -D__cplusplus'.\n"
1500 " -E Print preprocessor output on stdout and don't do any\n"
1501 " further processing.\n"
1502 " --enable=<id> Enable additional checks. The available ids are:\n"
1504 " Enable all checks. It is recommended to only\n"
1505 " use --enable=all when the whole program is\n"
1506 " scanned, because this enables unusedFunction.\n"
1508 " Enable warning messages\n"
1510 " Enable all coding style checks. All messages\n"
1511 " with the severities 'style', 'warning',\n"
1512 " 'performance' and 'portability' are enabled.\n"
1514 " Enable performance messages\n"
1516 " Enable portability messages\n"
1518 " Enable information messages\n"
1519 " * unusedFunction\n"
1520 " Check for unused functions. It is recommended\n"
1521 " to only enable this when the whole program is\n"
1523 " * missingInclude\n"
1524 " Warn if there are missing includes.\n"
1525 " Several ids can be given if you separate them with\n"
1526 " commas. See also --std\n"
1527 " --error-exitcode=<n> If errors are found, integer [n] is returned instead of\n"
1528 " the default '0'. '" << EXIT_FAILURE <<
"' is returned\n"
1529 " if arguments are not valid or if no input files are\n"
1530 " provided. Note that your operating system can modify\n"
1531 " this value, e.g. '256' can become '0'.\n"
1532 " --errorlist Print a list of all the error messages in XML format.\n"
1533 " --exitcode-suppressions=<file>\n"
1534 " Used when certain messages should be displayed but\n"
1535 " should not cause a non-zero exitcode.\n"
1536 " --file-filter=<str> Analyze only those files matching the given filter str\n"
1537 " Can be used multiple times\n"
1538 " Example: --file-filter=*bar.cpp analyzes only files\n"
1539 " that end with bar.cpp.\n"
1540 " --file-list=<file> Specify the files to check in a text file. Add one\n"
1541 " filename per line. When file is '-,' the file list will\n"
1542 " be read from standard input.\n"
1543 " -f, --force Force checking of all configurations in files. If used\n"
1544 " together with '--max-configs=', the last option is the\n"
1545 " one that is effective.\n"
1546 " --fsigned-char Treat char type as signed.\n"
1547 " --funsigned-char Treat char type as unsigned.\n"
1548 " -h, --help Print this help.\n"
1549 " -I <dir> Give path to search for include files. Give several -I\n"
1550 " parameters to give several paths. First given path is\n"
1551 " searched for contained header files first. If paths are\n"
1552 " relative to source files, this is not needed.\n"
1553 " --includes-file=<file>\n"
1554 " Specify directory paths to search for included header\n"
1555 " files in a text file. Add one include path per line.\n"
1556 " First given path is searched for contained header\n"
1557 " files first. If paths are relative to source files,\n"
1558 " this is not needed.\n"
1559 " --include=<file>\n"
1560 " Force inclusion of a file before the checked file.\n"
1561 " -i <dir or file> Give a source file or source file directory to exclude\n"
1562 " from the check. This applies only to source files so\n"
1563 " header files included by source files are not matched.\n"
1564 " Directory name is matched to all parts of the path.\n"
1565 " --inconclusive Allow that Cppcheck reports even though the analysis is\n"
1567 " There are false positives with this option. Each result\n"
1568 " must be carefully investigated before you know if it is\n"
1570 " --inline-suppr Enable inline suppressions. Use them by placing one or\n"
1571 " more comments, like: '// cppcheck-suppress warningId'\n"
1572 " on the lines before the warning to suppress.\n"
1573 " -j <jobs> Start <jobs> threads to do the checking simultaneously.\n"
1574 " -l <load> Specifies that no new threads should be started if\n"
1575 " there are other threads running and the load average is\n"
1576 " at least <load>.\n"
1577 " --language=<language>, -x <language>\n"
1578 " Forces cppcheck to check all files as the given\n"
1579 " language. Valid values are: c, c++\n"
1580 " --library=<cfg> Load file <cfg> that contains information about types\n"
1581 " and functions. With such information Cppcheck\n"
1582 " understands your code better and therefore you\n"
1583 " get better results. The std.cfg file that is\n"
1584 " distributed with Cppcheck is loaded automatically.\n"
1585 " For more information about library files, read the\n"
1587 " --max-configs=<limit>\n"
1588 " Maximum number of configurations to check in a file\n"
1589 " before skipping it. Default is '12'. If used together\n"
1590 " with '--force', the last option is the one that is\n"
1592 " --max-ctu-depth=N Max depth in whole program analysis. The default value\n"
1593 " is 2. A larger value will mean more errors can be found\n"
1594 " but also means the analysis will be slower.\n"
1595 " --output-file=<file> Write results to file, rather than standard error.\n"
1596 " --platform=<type>, --platform=<file>\n"
1597 " Specifies platform specific types and sizes. The\n"
1598 " available builtin platforms are:\n"
1600 " 32 bit unix variant\n"
1602 " 64 bit unix variant\n"
1604 " 32 bit Windows ASCII character encoding\n"
1606 " 32 bit Windows UNICODE character encoding\n"
1610 " 8 bit AVR microcontrollers\n"
1612 " Elbrus e1c+ architecture\n"
1614 " 8 bit PIC microcontrollers\n"
1615 " Baseline and mid-range architectures\n"
1616 " * pic8-enhanced\n"
1617 " 8 bit PIC microcontrollers\n"
1618 " Enhanced mid-range and high end (PIC18) architectures\n"
1620 " 16 bit PIC microcontrollers\n"
1622 " 32 bit MIPS microcontrollers\n"
1624 " Type sizes of host system are assumed, but no\n"
1625 " further assumptions.\n"
1627 " Unknown type sizes\n"
1628 " --plist-output=<path>\n"
1629 " Generate Clang-plist output files in folder.\n";
1633 " --premium=<option>\n"
1634 " Coding standards:\n"
1635 " * autosar Autosar (partial)\n"
1636 " * cert-c-2016 Cert C 2016 checking\n"
1637 " * cert-c++-2016 Cert C++ 2016 checking\n"
1638 " * misra-c-2012 Misra C 2012\n"
1639 " * misra-c-2023 Misra C 2023\n"
1640 " * misra-c++-2008 Misra C++ 2008\n"
1642 " * bughunting Soundy analysis\n"
1643 " * cert-c-int-precision=BITS Integer precision to use in Cert C analysis.\n"
1644 " * safety Safe mode\n";
1648 " --project=<file> Run Cppcheck on project. The <file> can be a Visual\n"
1649 " Studio Solution (*.sln), Visual Studio Project\n"
1650 " (*.vcxproj), compile database (compile_commands.json),\n"
1651 " or Borland C++ Builder 6 (*.bpr). The files to analyse,\n"
1652 " include paths, defines, platform and undefines in\n"
1653 " the specified file will be used.\n"
1654 " --project-configuration=<config>\n"
1655 " If used together with a Visual Studio Solution (*.sln)\n"
1656 " or Visual Studio Project (*.vcxproj) you can limit\n"
1657 " the configuration cppcheck should check.\n"
1658 " For example: '--project-configuration=Release|Win32'\n"
1659 " -q, --quiet Do not show progress reports.\n"
1660 " Note that this option is not mutually exclusive with --verbose.\n"
1661 " -rp=<paths>, --relative-paths=<paths>\n"
1662 " Use relative paths in output. When given, <paths> are\n"
1663 " used as base. You can separate multiple paths by ';'.\n"
1664 " Otherwise path where source files are searched is used.\n"
1665 " We use string comparison to create relative paths, so\n"
1666 " using e.g. ~ for home folder does not work. It is\n"
1667 " currently only possible to apply the base paths to\n"
1668 " files that are on a lower level in the directory tree.\n"
1669 " --report-progress Report progress messages while checking a file (single job only).\n"
1670 " --rule=<rule> Match regular expression.\n"
1671 " --rule-file=<file> Use given rule file. For more information, see:\n"
1672 " http://sourceforge.net/projects/cppcheck/files/Articles/\n"
1673 " --showtime=<mode> Show timing information.\n"
1674 " The available modes are:\n"
1676 " Show nothing (default)\n"
1678 " Show for each processed file\n"
1680 " Show total time only for each processed file\n"
1682 " Show a summary at the end\n"
1684 " Show the top 5 for each processed file\n"
1686 " Show the top 5 summary at the end\n"
1688 " Alias for top5_file (deprecated)\n"
1689 " --std=<id> Set standard.\n"
1690 " The available options are:\n"
1692 " C code is C89 compatible\n"
1694 " C code is C99 compatible\n"
1696 " C code is C11 compatible (default)\n"
1698 " C++ code is C++03 compatible\n"
1700 " C++ code is C++11 compatible\n"
1702 " C++ code is C++14 compatible\n"
1704 " C++ code is C++17 compatible\n"
1706 " C++ code is C++20 compatible (default)\n"
1707 " --suppress=<spec> Suppress warnings that match <spec>. The format of\n"
1709 " [error id]:[filename]:[line]\n"
1710 " The [filename] and [line] are optional. If [error id]\n"
1711 " is a wildcard '*', all error ids match.\n"
1712 " --suppressions-list=<file>\n"
1713 " Suppress warnings listed in the file. Each suppression\n"
1714 " is in the same format as <spec> above.\n"
1715 " --suppress-xml=<file>\n"
1716 " Suppress warnings listed in a xml file. XML file should\n"
1717 " follow the manual.pdf format specified in section.\n"
1718 " `6.4 XML suppressions` .\n"
1719 " --template='<text>' Format the error messages. Available fields:\n"
1720 " {file} file name\n"
1721 " {line} line number\n"
1722 " {column} column number\n"
1723 " {callstack} show a callstack. Example:\n"
1724 " [file.c:1] -> [file.c:100]\n"
1725 " {inconclusive:text} if warning is inconclusive, text\n"
1727 " {severity} severity\n"
1728 " {message} warning message\n"
1729 " {id} warning id\n"
1730 " {cwe} CWE id (Common Weakness Enumeration)\n"
1731 " {code} show the real code\n"
1733 " \\n insert newline\n"
1734 " \\r insert carriage return\n"
1735 " Example formats:\n"
1736 " '{file}:{line},{severity},{id},{message}' or\n"
1737 " '{file}({line}):({severity}) {message}' or\n"
1738 " '{callstack} {message}'\n"
1739 " Pre-defined templates: gcc (default), cppcheck1 (old default), vs, edit.\n"
1741 " --template-location='<text>'\n"
1742 " Format error message location. If this is not provided\n"
1743 " then no extra location info is shown.\n"
1744 " Available fields:\n"
1745 " {file} file name\n"
1746 " {line} line number\n"
1747 " {column} column number\n"
1748 " {info} location info\n"
1749 " {code} show the real code\n"
1751 " \\n insert newline\n"
1752 " \\r insert carriage return\n"
1753 " Example format (gcc-like):\n"
1754 " '{file}:{line}:{column}: note: {info}\\n{code}'\n"
1755 " -U<ID> Undefine preprocessor symbol. Use -U to explicitly\n"
1756 " hide certain #ifdef <ID> code paths from checking.\n"
1757 " Example: '-UDEBUG'\n"
1758 " -v, --verbose Output more detailed error information.\n"
1759 " Note that this option is not mutually exclusive with --quiet.\n"
1760 " --version Print out version number.\n"
1761 " --xml Write results in xml format to error stream (stderr).\n"
1764 " # Recursively check the current folder. Print the progress on the screen and\n"
1765 " # write errors to a file:\n"
1766 " cppcheck . 2> err.txt\n"
1768 " # Recursively check ../myproject/ and don't print progress:\n"
1769 " cppcheck --quiet ../myproject/\n"
1771 " # Check test.cpp, enable all checks:\n"
1772 " cppcheck --enable=all --inconclusive --library=posix test.cpp\n"
1774 " # Check f.cpp and search include files from inc1/ and inc2/:\n"
1775 " cppcheck -I inc1/ -I inc2/ f.cpp\n"
1777 "For more information:\n"
1778 " " << manualUrl <<
"\n"
1780 "Many thanks to the 3rd party libraries we use:\n"
1781 " * tinyxml2 -- loading project/library/ctu files.\n"
1782 " * picojson -- loading compile database.\n"
1783 " * pcre -- rules.\n"
1784 " * qt -- used in GUI\n";
1793 if (*extraVersion !=
'\0')
1794 return std::string(
"Cppcheck ") +
CppCheck::version() +
" ("+ extraVersion +
')';
1811 std::string msg =
"Failed to load library configuration file '" + std::string(filename) +
"'. ";
1816 msg +=
"File not found";
1822 msg +=
"Unexpected element";
1825 msg +=
"Missing attribute";
1828 msg +=
"Bad attribute value";
1831 msg +=
"File is of unsupported format version";
1834 msg +=
"Duplicate platform type";
1837 msg +=
"Platform type redefined";
1840 msg +=
"Duplicate define";
1844 msg +=
" '" + err.
reason +
"'";
1854 const std::string msg(
"Failed to load std.cfg. Your Cppcheck installation is broken, please re-install.");
1856 const std::string details(
"The Cppcheck binary was compiled with FILESDIR set to \""
1857 FILESDIR
"\" and will therefore search for "
1858 "std.cfg in " FILESDIR
"/cfg.");
1861 const std::string details(
"The Cppcheck binary was compiled without FILESDIR set. Either the "
1862 "std.cfg should be available in " + cfgfolder +
" or the FILESDIR "
1863 "should be configured.");
1870 for (
const auto& lib : settings.
libraries) {
1881 for (
const std::string &addon: settings.
addons) {
1884 if (!failedToGetAddonInfo.empty()) {
1889 settings.
addonInfos.emplace_back(std::move(addonInfo));
1897 if (!cfgErr.empty()) {
Interface class that cppcheck uses to communicate with the checks.
static std::list< Check * > & instances()
List of registered check classes.
virtual void printMessage(const std::string &message)=0
print a regular message
virtual void printError(const std::string &message)=0
print an error message
virtual void printRaw(const std::string &message)=0
print to the output
bool parseNumberArg(const char *const arg, std::size_t offset, T &num, bool mustBePositive=false)
CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions)
The constructor.
const std::vector< std::string > & getPathNames() const
Return the path names user gave to command line.
bool tryLoadLibrary(Library &destination, const std::string &basepath, const char *filename)
Tries to load a library and prints warning/error messages.
std::vector< std::string > mPathNames
void printHelp() const
Print help text to the console.
bool loadLibraries(Settings &settings)
Load libraries.
std::string getVersion() const
Get Cppcheck version.
std::list< FileSettings > mFileSettings
bool fillSettingsFromArgs(int argc, const char *const argv[])
Parse command line args and fill settings and file lists from there.
Suppressions & mSuppressions
std::list< FileWithDetails > mFiles
std::vector< std::string > mIgnoredPaths
bool isCppcheckPremium() const
Result parseFromArgs(int argc, const char *const argv[])
Parse given command line.
bool loadAddons(Settings &settings)
Load addons.
const std::vector< std::string > & getIgnoredPaths() const
Return a list of paths user wants to ignore.
const std::list< FileSettings > & getFileSettings() const
Return the file settings read from command line.
static void setExceptionOutput(FILE *exceptionOutput)
static void getErrorMessages(ErrorLogger &errorlogger)
Call all "getErrorMessages" in all registered Check classes.
static const char * version()
Returns current version number as a string.
static const char * extraVersion()
Returns extra version info as a string.
This is an interface, which the class responsible of error logging should implement.
virtual void reportErr(const ErrorMessage &msg)=0
Information about found errors and warnings is directed here.
virtual void reportOut(const std::string &outmsg, Color c=Color::Reset)=0
Information about progress is directed here.
virtual void reportProgress(const std::string &filename, const char stage[], const std::size_t value)
Report progress to client.
Wrapper for error messages, provided by reportErr()
static std::string getXMLFooter()
static std::string getXMLHeader(std::string productName)
std::string toXML() const
Format the error message in XML format.
static std::string recursiveAddFiles(std::list< FileWithDetails > &files, const std::string &path, const PathMatch &ignored)
Recursively add source files to a map.
Importing project settings.
std::list< std::string > excludedPaths
std::list< FileSettings > fileSettings
struct ImportProject::@6 guiProject
void ignorePaths(const std::vector< std::string > &ipaths)
std::string analyzeAllVsConfigs
void selectOneVsConfig(Platform::Type platform)
void ignoreOtherConfigs(const std::string &cfg)
Type import(const std::string &filename, Settings *settings=nullptr)
std::vector< std::string > pathNames
std::list< std::string > libraries
Library definitions handling.
const std::set< std::string > & markupExtensions() const
@ DUPLICATE_PLATFORM_TYPE
@ PLATFORM_TYPE_REDEFINED
Error load(const char exename[], const char path[])
Simple path matching for ignoring paths in CLI.
static std::string simplifyPath(std::string originalPath)
Simplify path "foo/bar/.." => "foo".
static std::string fromNativeSeparators(std::string path)
Convert path to use internal path separators.
static std::string removeQuotationMarks(std::string path)
Remove quotation marks (") from the path.
static std::string getCurrentExecutablePath(const char *fallback)
Returns the absolute path to the current executable.
static std::string toNativeSeparators(std::string path)
Convert path to use native separators.
static std::string getPathFromFilename(const std::string &filename)
Lookup the path part from a filename (e.g., '/tmp/a.h' -> '/tmp/', 'a.h' -> '')
static bool isDirectory(const std::string &path)
Checks if a given path is a directory.
This is just a container for general settings so that we don't need to pass individual values to func...
std::set< std::string > userUndefs
undefines given by the user
static void terminate(bool t=true)
Request termination of checking.
bool debugtemplate
Is –debug-template given?
static std::string loadCppcheckCfg(Settings &settings, Suppressions &suppressions)
bool quiet
Is –quiet given?
bool checkLibrary
Check for incomplete info in library files?
std::string addEnabled(const std::string &str)
Enable extra checks by id.
bool preprocessOnly
Using -E for debugging purposes.
std::set< std::string > configExcludePaths
include paths excluded from checking the configuration
int exitCode
If errors are found, this value is returned from main().
std::size_t valueFlowMaxIterations
the maximum iterations of valueflow (–valueflow-max-iterations=T)
bool checkAllConfigurations
check all configurations (false if -D or –max-configs is used
std::vector< std::string > basePaths
Paths used as base for conversion to relative paths.
int loadAverage
Load average value.
int maxCtuDepth
–max-ctu-depth
int reportProgress
–report-progress
Suppressions supprs
suppressions
std::string plistOutput
plist output (–plist-output=<dir>)
std::string templateFormat
The output format in which the errors are printed in text mode, e.g.
std::string clangExecutable
Custom Clang executable.
Standards::Language enforcedLang
Name of the language that is enforced.
SimpleEnableGroup< Checks > checks
bool xml
write XML results (–xml)
bool checkConfiguration
Is the 'configuration checking' wanted?
bool relativePaths
Use relative paths in output.
std::unordered_set< std::string > addons
addons, either filename of python/json file or json data
bool safety
Safety certified behavior Show checkers report when Cppcheck finishes Make cppcheck checking more str...
std::size_t typedefMaxTime
The maximum time in seconds for the typedef simplification.
std::string removeEnabled(const std::string &str)
Disable extra checks by id.
std::string buildDir
–cppcheck-build-dir.
std::string templateLocation
The output format in which the error locations are printed in text mode, e.g.
std::string cppcheckCfgProductName
cppcheck.cfg: Custom product name
std::string userDefines
defines given by the user
std::vector< AddonInfo > addonInfos
the loaded addons infos
std::string premiumArgs
Extra arguments for Cppcheck Premium addon.
bool inlineSuppressions
Is –inline-suppr given?
void setCheckLevel(CheckLevel level)
int performanceValueFlowMaxTime
Experimental: –performance-valueflow-max-time=T.
int xml_version
XML version (–xml-version=..)
int performanceValueFlowMaxIfCount
–performance-valueflow-max-if-count=C
int checksMaxTime
The maximum time in seconds for the checks of a single file.
std::string outputFile
write results (–output-file=<file>)
bool useSingleJob() const
static ExecutorType defaultExecutor()
unsigned int jobs
How many processes/threads should do checking at the same time.
bool debugnormal
Is –debug-normal given?
bool force
Force checking the files with "too many" configurations (–force).
bool daca
Are we running from DACA script?
bool verbose
Is –verbose given?
std::list< std::string > libraries
–library=
std::list< std::string > includePaths
List of include paths, e.g.
SimpleEnableGroup< Certainty > certainty
SHOWTIME_MODES showtime
show timing information (–showtime=file|summary|top5)
std::list< std::string > userIncludes
forced includes given by the user
int maxConfigs
Maximum number of configurations to check before bailing.
SimpleEnableGroup< Severity > severity
std::size_t templateMaxTime
The maximum time in seconds for the template instantiation.
bool debugSimplified
Is –debug-simplified given?
std::string checkersReportFilename
–checkers-report=<filename> : Generate report of executed checkers
std::vector< std::string > fileFilters
List of –file-filter for analyzing special files.
std::string addonPython
Path to the python interpreter to be used to run addons.
bool debugwarnings
Is –debug-warnings given?
Standards standards
Struct contains standards settings.
bool isEnabled(T flag) const
std::string addSuppressionLine(const std::string &line)
Don't show the given error.
std::string parseXmlFile(const char *filename)
Don't show errors listed in the file.
std::string parseFile(std::istream &istr)
Don't show errors listed in the file.
static bool addIncludePathsToList(const std::string &fileList, std::list< std::string > &pathNames)
static bool addFilesToList(const std::string &fileList, std::vector< std::string > &pathNames)
static bool addPathsToSet(const std::string &fileName, std::set< std::string > &set)
void substituteTemplateFormatStatic(std::string &templateFormat)
replaces the static parts of the location template
void substituteTemplateLocationStatic(std::string &templateLocation)
replaces the static parts of the location template
Severity severityFromString(const std::string &severity)
@ none
No severity (default value).
@ information
Checking information.
std::string getAddonInfo(const std::string &fileName, const std::string &exename)
std::string getCPP() const
enum Standards::cppstd_t cpp
SuppressionList nofail
suppress exitcode
SuppressionList nomsg
suppress message (–suppressions)
bool startsWith(const std::string &str, const char start[], std::size_t startlen)
bool strToInt(const std::string &str, T &num, std::string *err=nullptr)
bool endsWith(const std::string &str, char c)
static T * empty_if_null(T *p)